summaryrefslogtreecommitdiff
path: root/src/charon
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2008-07-09 21:02:41 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2008-07-09 21:02:41 +0000
commitdb67c87db3c9089ea8d2e14f617bf3d9e2af261f (patch)
tree665c0caea83d34c11c1517c4c57137bb58cba6fb /src/charon
parent1c088a8b6237ec67f63c23f97a0f2dc4e99af869 (diff)
downloadvyos-strongswan-db67c87db3c9089ea8d2e14f617bf3d9e2af261f.tar.gz
vyos-strongswan-db67c87db3c9089ea8d2e14f617bf3d9e2af261f.zip
[svn-upgrade] Integrating new upstream version, strongswan (4.2.4)
Diffstat (limited to 'src/charon')
-rw-r--r--src/charon/Makefile.am146
-rw-r--r--src/charon/Makefile.in1089
-rw-r--r--src/charon/bus/bus.c61
-rw-r--r--src/charon/bus/bus.h66
-rw-r--r--src/charon/bus/listeners/file_logger.c9
-rw-r--r--src/charon/bus/listeners/file_logger.h35
-rw-r--r--src/charon/bus/listeners/sys_logger.c9
-rw-r--r--src/charon/bus/listeners/sys_logger.h35
-rw-r--r--src/charon/config/attributes/attribute_manager.c145
-rw-r--r--src/charon/config/attributes/attribute_manager.h82
-rw-r--r--src/charon/config/attributes/attribute_provider.h60
-rw-r--r--src/charon/config/backend.h75
-rw-r--r--src/charon/config/backend_manager.c366
-rw-r--r--src/charon/config/backend_manager.h75
-rw-r--r--src/charon/config/backends/backend.h105
-rw-r--r--src/charon/config/backends/local_backend.c322
-rw-r--r--src/charon/config/backends/local_backend.h60
-rw-r--r--src/charon/config/backends/sqlite_backend.c309
-rw-r--r--src/charon/config/backends/writeable_backend.h64
-rw-r--r--src/charon/config/child_cfg.c199
-rw-r--r--src/charon/config/child_cfg.h149
-rw-r--r--src/charon/config/credentials/local_credential_store.c1620
-rw-r--r--src/charon/config/credentials/local_credential_store.h63
-rw-r--r--src/charon/config/ike_cfg.c110
-rw-r--r--src/charon/config/ike_cfg.h87
-rw-r--r--src/charon/config/peer_cfg.c320
-rw-r--r--src/charon/config/peer_cfg.h291
-rw-r--r--src/charon/config/proposal.c520
-rw-r--r--src/charon/config/proposal.h165
-rw-r--r--src/charon/config/traffic_selector.c39
-rw-r--r--src/charon/config/traffic_selector.h105
-rw-r--r--src/charon/control/controller.c (renamed from src/charon/control/interface_manager.c)175
-rw-r--r--src/charon/control/controller.h (renamed from src/charon/control/interface_manager.h)120
-rw-r--r--src/charon/control/interfaces/dbus_interface.c427
-rw-r--r--src/charon/control/interfaces/interface.h59
-rwxr-xr-xsrc/charon/control/interfaces/stroke_interface.c1818
-rw-r--r--src/charon/credentials/auth_info.c571
-rw-r--r--src/charon/credentials/auth_info.h185
-rw-r--r--src/charon/credentials/credential_manager.c1540
-rw-r--r--src/charon/credentials/credential_manager.h207
-rw-r--r--src/charon/credentials/credential_set.h103
-rw-r--r--src/charon/credentials/sets/auth_info_wrapper.c215
-rw-r--r--src/charon/credentials/sets/auth_info_wrapper.h55
-rw-r--r--src/charon/credentials/sets/cert_cache.c332
-rw-r--r--src/charon/credentials/sets/cert_cache.h73
-rw-r--r--src/charon/credentials/sets/ocsp_response_wrapper.c149
-rw-r--r--src/charon/credentials/sets/ocsp_response_wrapper.h55
-rw-r--r--src/charon/daemon.c245
-rw-r--r--src/charon/daemon.h434
-rw-r--r--src/charon/encoding/generator.c9
-rw-r--r--src/charon/encoding/generator.h45
-rw-r--r--src/charon/encoding/message.c545
-rw-r--r--src/charon/encoding/message.h129
-rw-r--r--src/charon/encoding/parser.c121
-rw-r--r--src/charon/encoding/parser.h52
-rw-r--r--src/charon/encoding/payloads/auth_payload.c12
-rw-r--r--src/charon/encoding/payloads/auth_payload.h51
-rw-r--r--src/charon/encoding/payloads/cert_payload.c221
-rw-r--r--src/charon/encoding/payloads/cert_payload.h144
-rw-r--r--src/charon/encoding/payloads/certreq_payload.c201
-rw-r--r--src/charon/encoding/payloads/certreq_payload.h104
-rw-r--r--src/charon/encoding/payloads/configuration_attribute.c9
-rw-r--r--src/charon/encoding/payloads/configuration_attribute.h54
-rw-r--r--src/charon/encoding/payloads/cp_payload.c9
-rw-r--r--src/charon/encoding/payloads/cp_payload.h49
-rw-r--r--src/charon/encoding/payloads/delete_payload.c9
-rw-r--r--src/charon/encoding/payloads/delete_payload.h44
-rw-r--r--src/charon/encoding/payloads/eap_payload.c9
-rw-r--r--src/charon/encoding/payloads/eap_payload.h60
-rw-r--r--src/charon/encoding/payloads/encodings.c9
-rw-r--r--src/charon/encoding/payloads/encodings.h33
-rw-r--r--src/charon/encoding/payloads/encryption_payload.c69
-rw-r--r--src/charon/encoding/payloads/encryption_payload.h70
-rw-r--r--src/charon/encoding/payloads/endpoint_notify.c69
-rw-r--r--src/charon/encoding/payloads/endpoint_notify.h105
-rw-r--r--src/charon/encoding/payloads/id_payload.c9
-rw-r--r--src/charon/encoding/payloads/id_payload.h58
-rw-r--r--src/charon/encoding/payloads/ike_header.c31
-rw-r--r--src/charon/encoding/payloads/ike_header.h103
-rw-r--r--src/charon/encoding/payloads/ke_payload.c9
-rw-r--r--src/charon/encoding/payloads/ke_payload.h61
-rw-r--r--src/charon/encoding/payloads/nonce_payload.c9
-rw-r--r--src/charon/encoding/payloads/nonce_payload.h43
-rw-r--r--src/charon/encoding/payloads/notify_payload.c89
-rw-r--r--src/charon/encoding/payloads/notify_payload.h101
-rw-r--r--src/charon/encoding/payloads/payload.c22
-rw-r--r--src/charon/encoding/payloads/payload.h73
-rw-r--r--src/charon/encoding/payloads/proposal_substructure.c69
-rw-r--r--src/charon/encoding/payloads/proposal_substructure.h113
-rw-r--r--src/charon/encoding/payloads/sa_payload.c9
-rw-r--r--src/charon/encoding/payloads/sa_payload.h76
-rw-r--r--src/charon/encoding/payloads/traffic_selector_substructure.c9
-rw-r--r--src/charon/encoding/payloads/traffic_selector_substructure.h83
-rw-r--r--src/charon/encoding/payloads/transform_attribute.c9
-rw-r--r--src/charon/encoding/payloads/transform_attribute.h64
-rw-r--r--src/charon/encoding/payloads/transform_substructure.c37
-rw-r--r--src/charon/encoding/payloads/transform_substructure.h100
-rw-r--r--src/charon/encoding/payloads/ts_payload.c9
-rw-r--r--src/charon/encoding/payloads/ts_payload.h78
-rw-r--r--src/charon/encoding/payloads/unknown_payload.c9
-rw-r--r--src/charon/encoding/payloads/unknown_payload.h40
-rw-r--r--src/charon/encoding/payloads/vendor_id_payload.c9
-rw-r--r--src/charon/encoding/payloads/vendor_id_payload.h43
-rw-r--r--src/charon/kernel/kernel_interface.c509
-rw-r--r--src/charon/kernel/kernel_interface.h144
-rw-r--r--src/charon/network/packet.c11
-rw-r--r--src/charon/network/packet.h55
-rw-r--r--src/charon/network/receiver.c54
-rw-r--r--src/charon/network/receiver.h33
-rw-r--r--src/charon/network/sender.c31
-rw-r--r--src/charon/network/sender.h34
-rw-r--r--src/charon/network/socket-raw.c12
-rw-r--r--src/charon/network/socket.c12
-rw-r--r--src/charon/network/socket.h66
-rw-r--r--src/charon/plugins/eap_aka/Makefile.am11
-rw-r--r--src/charon/plugins/eap_aka/Makefile.in496
-rw-r--r--src/charon/plugins/eap_aka/eap_aka.c (renamed from src/charon/sa/authenticators/eap/eap_aka.c)357
-rw-r--r--src/charon/plugins/eap_aka/eap_aka.h (renamed from src/charon/sa/authenticators/eap/eap_aka.h)98
-rw-r--r--src/charon/plugins/eap_aka/eap_aka_plugin.c52
-rw-r--r--src/charon/plugins/eap_aka/eap_aka_plugin.h49
-rw-r--r--src/charon/plugins/eap_identity/Makefile.am10
-rw-r--r--src/charon/plugins/eap_identity/Makefile.in499
-rw-r--r--src/charon/plugins/eap_identity/eap_identity.c (renamed from src/charon/sa/authenticators/eap/eap_identity.c)28
-rw-r--r--src/charon/plugins/eap_identity/eap_identity.h (renamed from src/charon/sa/authenticators/eap/eap_identity.h)34
-rw-r--r--src/charon/plugins/eap_identity/eap_identity_plugin.c48
-rw-r--r--src/charon/plugins/eap_identity/eap_identity_plugin.h (renamed from src/charon/control/interfaces/dbus_interface.h)54
-rw-r--r--src/charon/plugins/eap_md5/Makefile.am10
-rw-r--r--src/charon/plugins/eap_md5/Makefile.in495
-rw-r--r--src/charon/plugins/eap_md5/eap_md5.c (renamed from src/charon/sa/authenticators/eap/eap_md5.c)100
-rw-r--r--src/charon/plugins/eap_md5/eap_md5.h (renamed from src/charon/sa/authenticators/eap/eap_md5.h)40
-rw-r--r--src/charon/plugins/eap_md5/eap_md5_plugin.c52
-rw-r--r--src/charon/plugins/eap_md5/eap_md5_plugin.h49
-rw-r--r--src/charon/plugins/eap_sim/Makefile.am13
-rw-r--r--src/charon/plugins/eap_sim/Makefile.in508
-rw-r--r--src/charon/plugins/eap_sim/eap_sim.c (renamed from src/charon/sa/authenticators/eap/eap_sim.c)116
-rw-r--r--src/charon/plugins/eap_sim/eap_sim.h (renamed from src/charon/sa/authenticators/eap/eap_sim.h)43
-rw-r--r--src/charon/plugins/eap_sim/eap_sim_file.c (renamed from src/charon/sa/authenticators/eap/sim/eap_sim_file.c)11
-rw-r--r--src/charon/plugins/eap_sim/eap_sim_plugin.c52
-rw-r--r--src/charon/plugins/eap_sim/eap_sim_plugin.h49
-rw-r--r--src/charon/plugins/medcli/Makefile.am12
-rw-r--r--src/charon/plugins/medcli/Makefile.in502
-rw-r--r--src/charon/plugins/medcli/medcli_config.c370
-rw-r--r--src/charon/plugins/medcli/medcli_config.h (renamed from src/charon/config/backends/sqlite_backend.h)55
-rw-r--r--src/charon/plugins/medcli/medcli_creds.c242
-rw-r--r--src/charon/plugins/medcli/medcli_creds.h55
-rw-r--r--src/charon/plugins/medcli/medcli_listener.c112
-rw-r--r--src/charon/plugins/medcli/medcli_listener.h55
-rw-r--r--src/charon/plugins/medcli/medcli_plugin.c111
-rw-r--r--src/charon/plugins/medcli/medcli_plugin.h49
-rw-r--r--src/charon/plugins/medsrv/Makefile.am11
-rw-r--r--src/charon/plugins/medsrv/Makefile.in500
-rw-r--r--src/charon/plugins/medsrv/medsrv_config.c147
-rw-r--r--src/charon/plugins/medsrv/medsrv_config.h55
-rw-r--r--src/charon/plugins/medsrv/medsrv_creds.c162
-rw-r--r--src/charon/plugins/medsrv/medsrv_creds.h55
-rw-r--r--src/charon/plugins/medsrv/medsrv_plugin.c101
-rw-r--r--src/charon/plugins/medsrv/medsrv_plugin.h49
-rw-r--r--src/charon/plugins/smp/Makefile.am10
-rw-r--r--src/charon/plugins/smp/Makefile.in495
-rw-r--r--src/charon/plugins/smp/smp.c (renamed from src/charon/control/interfaces/xml_interface.c)121
-rw-r--r--src/charon/plugins/smp/smp.h (renamed from src/charon/control/interfaces/xml_interface.h)57
-rw-r--r--src/charon/plugins/sql/Makefile.am17
-rw-r--r--src/charon/plugins/sql/Makefile.in549
-rw-r--r--src/charon/plugins/sql/pool.c726
-rw-r--r--src/charon/plugins/sql/sql_attribute.c287
-rw-r--r--src/charon/plugins/sql/sql_attribute.h51
-rw-r--r--src/charon/plugins/sql/sql_config.c517
-rw-r--r--src/charon/plugins/sql/sql_config.h55
-rw-r--r--src/charon/plugins/sql/sql_cred.c367
-rw-r--r--src/charon/plugins/sql/sql_cred.h55
-rw-r--r--src/charon/plugins/sql/sql_logger.c147
-rw-r--r--src/charon/plugins/sql/sql_logger.h55
-rw-r--r--src/charon/plugins/sql/sql_plugin.c118
-rw-r--r--src/charon/plugins/sql/sql_plugin.h49
-rw-r--r--src/charon/plugins/stroke/Makefile.am19
-rw-r--r--src/charon/plugins/stroke/Makefile.in513
-rw-r--r--src/charon/plugins/stroke/stroke_attribute.c340
-rw-r--r--src/charon/plugins/stroke/stroke_attribute.h67
-rw-r--r--src/charon/plugins/stroke/stroke_ca.c457
-rw-r--r--src/charon/plugins/stroke/stroke_ca.h82
-rw-r--r--src/charon/plugins/stroke/stroke_config.c844
-rw-r--r--src/charon/plugins/stroke/stroke_config.h68
-rw-r--r--src/charon/plugins/stroke/stroke_control.c345
-rw-r--r--src/charon/plugins/stroke/stroke_control.h76
-rw-r--r--src/charon/plugins/stroke/stroke_cred.c977
-rw-r--r--src/charon/plugins/stroke/stroke_cred.h83
-rw-r--r--src/charon/plugins/stroke/stroke_list.c729
-rw-r--r--src/charon/plugins/stroke/stroke_list.h64
-rw-r--r--src/charon/plugins/stroke/stroke_plugin.c67
-rw-r--r--src/charon/plugins/stroke/stroke_plugin.h (renamed from src/charon/control/interfaces/stroke_interface.h)56
-rw-r--r--src/charon/plugins/stroke/stroke_shared_key.c142
-rw-r--r--src/charon/plugins/stroke/stroke_shared_key.h62
-rw-r--r--src/charon/plugins/stroke/stroke_socket.c602
-rw-r--r--src/charon/plugins/stroke/stroke_socket.h44
-rw-r--r--src/charon/plugins/uci/Makefile.am13
-rw-r--r--src/charon/plugins/uci/Makefile.in501
-rw-r--r--src/charon/plugins/uci/uci_config.c360
-rw-r--r--src/charon/plugins/uci/uci_config.h57
-rw-r--r--src/charon/plugins/uci/uci_creds.c184
-rw-r--r--src/charon/plugins/uci/uci_creds.h57
-rw-r--r--src/charon/plugins/uci/uci_parser.c181
-rw-r--r--src/charon/plugins/uci/uci_parser.h62
-rw-r--r--src/charon/plugins/uci/uci_plugin.c87
-rw-r--r--src/charon/plugins/uci/uci_plugin.h50
-rw-r--r--src/charon/plugins/unit_tester/Makefile.am21
-rw-r--r--src/charon/plugins/unit_tester/Makefile.in598
-rw-r--r--src/charon/plugins/unit_tester/tests/test_aes.c467
-rw-r--r--src/charon/plugins/unit_tester/tests/test_auth_info.c142
-rw-r--r--src/charon/plugins/unit_tester/tests/test_chunk.c84
-rw-r--r--src/charon/plugins/unit_tester/tests/test_curl.c44
-rw-r--r--src/charon/plugins/unit_tester/tests/test_enumerator.c214
-rw-r--r--src/charon/plugins/unit_tester/tests/test_fips_prf.c64
-rw-r--r--src/charon/plugins/unit_tester/tests/test_med_db.c52
-rw-r--r--src/charon/plugins/unit_tester/tests/test_mutex.c100
-rw-r--r--src/charon/plugins/unit_tester/tests/test_mysql.c90
-rw-r--r--src/charon/plugins/unit_tester/tests/test_rsa_gen.c109
-rw-r--r--src/charon/plugins/unit_tester/tests/test_sqlite.c94
-rw-r--r--src/charon/plugins/unit_tester/unit_tester.c118
-rw-r--r--src/charon/plugins/unit_tester/unit_tester.h51
-rw-r--r--src/charon/processing/jobs/acquire_job.c9
-rw-r--r--src/charon/processing/jobs/acquire_job.h27
-rw-r--r--src/charon/processing/jobs/callback_job.c16
-rw-r--r--src/charon/processing/jobs/callback_job.h44
-rw-r--r--src/charon/processing/jobs/delete_child_sa_job.c9
-rw-r--r--src/charon/processing/jobs/delete_child_sa_job.h27
-rw-r--r--src/charon/processing/jobs/delete_ike_sa_job.c9
-rw-r--r--src/charon/processing/jobs/delete_ike_sa_job.h27
-rw-r--r--src/charon/processing/jobs/initiate_mediation_job.c31
-rw-r--r--src/charon/processing/jobs/initiate_mediation_job.h37
-rw-r--r--src/charon/processing/jobs/job.h33
-rw-r--r--src/charon/processing/jobs/mediation_job.c36
-rw-r--r--src/charon/processing/jobs/mediation_job.h36
-rw-r--r--src/charon/processing/jobs/process_message_job.c14
-rw-r--r--src/charon/processing/jobs/process_message_job.h27
-rw-r--r--src/charon/processing/jobs/rekey_child_sa_job.c9
-rw-r--r--src/charon/processing/jobs/rekey_child_sa_job.h32
-rw-r--r--src/charon/processing/jobs/rekey_ike_sa_job.c14
-rw-r--r--src/charon/processing/jobs/rekey_ike_sa_job.h27
-rw-r--r--src/charon/processing/jobs/retransmit_job.c9
-rw-r--r--src/charon/processing/jobs/retransmit_job.h27
-rw-r--r--src/charon/processing/jobs/roam_job.c20
-rw-r--r--src/charon/processing/jobs/roam_job.h27
-rw-r--r--src/charon/processing/jobs/send_dpd_job.c10
-rw-r--r--src/charon/processing/jobs/send_dpd_job.h26
-rw-r--r--src/charon/processing/jobs/send_keepalive_job.c10
-rw-r--r--src/charon/processing/jobs/send_keepalive_job.h26
-rw-r--r--src/charon/processing/processor.c49
-rw-r--r--src/charon/processing/processor.h51
-rw-r--r--src/charon/processing/scheduler.c9
-rw-r--r--src/charon/processing/scheduler.h38
-rw-r--r--src/charon/sa/authenticators/authenticator.c47
-rw-r--r--src/charon/sa/authenticators/authenticator.h75
-rw-r--r--src/charon/sa/authenticators/eap/eap_manager.c172
-rw-r--r--src/charon/sa/authenticators/eap/eap_manager.h84
-rw-r--r--src/charon/sa/authenticators/eap/eap_method.c189
-rw-r--r--src/charon/sa/authenticators/eap/eap_method.h107
-rw-r--r--src/charon/sa/authenticators/eap_authenticator.c30
-rw-r--r--src/charon/sa/authenticators/eap_authenticator.h36
-rw-r--r--src/charon/sa/authenticators/psk_authenticator.c85
-rw-r--r--src/charon/sa/authenticators/psk_authenticator.h28
-rw-r--r--src/charon/sa/authenticators/pubkey_authenticator.c225
-rw-r--r--src/charon/sa/authenticators/pubkey_authenticator.h (renamed from src/charon/sa/authenticators/rsa_authenticator.h)41
-rw-r--r--src/charon/sa/authenticators/rsa_authenticator.c160
-rw-r--r--src/charon/sa/child_sa.c169
-rw-r--r--src/charon/sa/child_sa.h103
-rw-r--r--src/charon/sa/connect_manager.c607
-rw-r--r--src/charon/sa/connect_manager.h74
-rw-r--r--src/charon/sa/ike_sa.c779
-rw-r--r--src/charon/sa/ike_sa.h378
-rw-r--r--src/charon/sa/ike_sa_id.c10
-rw-r--r--src/charon/sa/ike_sa_id.h61
-rw-r--r--src/charon/sa/ike_sa_manager.c349
-rw-r--r--src/charon/sa/ike_sa_manager.h85
-rw-r--r--src/charon/sa/mediation_manager.c10
-rw-r--r--src/charon/sa/mediation_manager.h43
-rw-r--r--src/charon/sa/task_manager.c51
-rw-r--r--src/charon/sa/task_manager.h63
-rw-r--r--src/charon/sa/tasks/child_create.c147
-rw-r--r--src/charon/sa/tasks/child_create.h34
-rw-r--r--src/charon/sa/tasks/child_delete.c44
-rw-r--r--src/charon/sa/tasks/child_delete.h28
-rw-r--r--src/charon/sa/tasks/child_rekey.c9
-rw-r--r--src/charon/sa/tasks/child_rekey.h28
-rw-r--r--src/charon/sa/tasks/ike_auth.c165
-rw-r--r--src/charon/sa/tasks/ike_auth.h25
-rw-r--r--src/charon/sa/tasks/ike_auth_lifetime.c9
-rw-r--r--src/charon/sa/tasks/ike_auth_lifetime.h26
-rw-r--r--src/charon/sa/tasks/ike_cert.c366
-rw-r--r--src/charon/sa/tasks/ike_cert_post.c260
-rw-r--r--src/charon/sa/tasks/ike_cert_post.h55
-rw-r--r--src/charon/sa/tasks/ike_cert_pre.c476
-rw-r--r--src/charon/sa/tasks/ike_cert_pre.h (renamed from src/charon/sa/tasks/ike_cert.h)40
-rw-r--r--src/charon/sa/tasks/ike_config.c49
-rw-r--r--src/charon/sa/tasks/ike_config.h25
-rw-r--r--src/charon/sa/tasks/ike_delete.c21
-rw-r--r--src/charon/sa/tasks/ike_delete.h25
-rw-r--r--src/charon/sa/tasks/ike_dpd.c9
-rw-r--r--src/charon/sa/tasks/ike_dpd.h25
-rw-r--r--src/charon/sa/tasks/ike_init.c144
-rw-r--r--src/charon/sa/tasks/ike_init.h28
-rw-r--r--src/charon/sa/tasks/ike_me.c (renamed from src/charon/sa/tasks/ike_p2p.c)300
-rw-r--r--src/charon/sa/tasks/ike_me.h (renamed from src/charon/sa/tasks/ike_p2p.h)72
-rw-r--r--src/charon/sa/tasks/ike_mobike.c64
-rw-r--r--src/charon/sa/tasks/ike_mobike.h35
-rw-r--r--src/charon/sa/tasks/ike_natd.c45
-rw-r--r--src/charon/sa/tasks/ike_natd.h25
-rw-r--r--src/charon/sa/tasks/ike_reauth.c41
-rw-r--r--src/charon/sa/tasks/ike_reauth.h26
-rw-r--r--src/charon/sa/tasks/ike_rekey.c9
-rw-r--r--src/charon/sa/tasks/ike_rekey.h28
-rw-r--r--src/charon/sa/tasks/task.c18
-rw-r--r--src/charon/sa/tasks/task.h58
312 files changed, 31180 insertions, 13538 deletions
diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am
index 1d7022336..9a04055c3 100644
--- a/src/charon/Makefile.am
+++ b/src/charon/Makefile.am
@@ -4,16 +4,15 @@ charon_SOURCES = \
bus/bus.c bus/bus.h \
bus/listeners/file_logger.c bus/listeners/file_logger.h \
bus/listeners/sys_logger.c bus/listeners/sys_logger.h \
-config/backends/backend.h config/backends/writeable_backend.h \
-config/backend_manager.c config/backend_manager.h \
+config/backend_manager.c config/backend_manager.h config/backend.h \
config/child_cfg.c config/child_cfg.h \
-config/credentials/local_credential_store.c config/credentials/local_credential_store.h \
config/ike_cfg.c config/ike_cfg.h \
config/peer_cfg.c config/peer_cfg.h \
config/proposal.c config/proposal.h \
config/traffic_selector.c config/traffic_selector.h \
-control/interfaces/interface.h \
-control/interface_manager.c control/interface_manager.h \
+config/attributes/attribute_provider.h \
+config/attributes/attribute_manager.c config/attributes/attribute_manager.h \
+control/controller.c control/controller.h \
daemon.c daemon.h \
encoding/generator.c encoding/generator.h \
encoding/message.c encoding/message.h \
@@ -63,8 +62,9 @@ processing/processor.c processing/processor.h \
sa/authenticators/authenticator.c sa/authenticators/authenticator.h \
sa/authenticators/eap_authenticator.c sa/authenticators/eap_authenticator.h \
sa/authenticators/eap/eap_method.c sa/authenticators/eap/eap_method.h \
+sa/authenticators/eap/eap_manager.c sa/authenticators/eap/eap_manager.h \
sa/authenticators/psk_authenticator.c sa/authenticators/psk_authenticator.h \
-sa/authenticators/rsa_authenticator.c sa/authenticators/rsa_authenticator.h \
+sa/authenticators/pubkey_authenticator.c sa/authenticators/pubkey_authenticator.h \
sa/child_sa.c sa/child_sa.h \
sa/ike_sa.c sa/ike_sa.h \
sa/ike_sa_id.c sa/ike_sa_id.h \
@@ -74,7 +74,8 @@ sa/tasks/child_create.c sa/tasks/child_create.h \
sa/tasks/child_delete.c sa/tasks/child_delete.h \
sa/tasks/child_rekey.c sa/tasks/child_rekey.h \
sa/tasks/ike_auth.c sa/tasks/ike_auth.h \
-sa/tasks/ike_cert.c sa/tasks/ike_cert.h \
+sa/tasks/ike_cert_pre.c sa/tasks/ike_cert_pre.h \
+sa/tasks/ike_cert_post.c sa/tasks/ike_cert_post.h \
sa/tasks/ike_config.c sa/tasks/ike_config.h \
sa/tasks/ike_delete.c sa/tasks/ike_delete.h \
sa/tasks/ike_dpd.c sa/tasks/ike_dpd.h \
@@ -84,7 +85,25 @@ sa/tasks/ike_mobike.c sa/tasks/ike_mobike.h \
sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \
sa/tasks/ike_reauth.c sa/tasks/ike_reauth.h \
sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \
-sa/tasks/task.c sa/tasks/task.h
+sa/tasks/task.c sa/tasks/task.h \
+credentials/credential_manager.c credentials/credential_manager.h \
+credentials/auth_info.c credentials/auth_info.h \
+credentials/sets/auth_info_wrapper.c credentials/sets/auth_info_wrapper.h \
+credentials/sets/ocsp_response_wrapper.c credentials/sets/ocsp_response_wrapper.h \
+credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
+credentials/credential_set.h
+
+INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic \
+ -DIPSEC_DIR=\"${ipsecdir}\" \
+ -DIPSEC_PIDDIR=\"${piddir}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\" \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
+ -DRESOLV_CONF=\"${resolv_conf}\"
+charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lm -ldl
+
+# compile options
+#################
# Use RAW socket if pluto gets built
if USE_PLUTO
@@ -93,98 +112,83 @@ else
charon_SOURCES += network/socket.c
endif
-if USE_P2P
+if USE_ME
charon_SOURCES += encoding/payloads/endpoint_notify.c encoding/payloads/endpoint_notify.h \
processing/jobs/initiate_mediation_job.c processing/jobs/initiate_mediation_job.h \
processing/jobs/mediation_job.c processing/jobs/mediation_job.h \
sa/connect_manager.c sa/connect_manager.h \
sa/mediation_manager.c sa/mediation_manager.h \
- sa/tasks/ike_p2p.c sa/tasks/ike_p2p.h
+ sa/tasks/ike_me.c sa/tasks/ike_me.h
endif
-INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke
-AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\" \
- -DIPSEC_EAPDIR=\"${eapdir}\" -DIPSEC_BACKENDDIR=\"${backenddir}\" -DIPSEC_INTERFACEDIR=\"${interfacedir}\" \
- -DSIM_READER_LIB=\"${simreader}\"
-charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lgmp -lpthread -lm -ldl
+if USE_INTEGRITY_TEST
+ AM_CFLAGS += -DINTEGRITY_TEST
+endif
-if USE_LIBCURL
- charon_LDADD += -lcurl
+if USE_SELF_TEST
+ AM_CFLAGS += -DSELF_TEST
endif
+# build optional plugins
+########################
-# build EAP plugins
-###################
-eap_LTLIBRARIES =
+SUBDIRS = .
+PLUGINS = ${libstrongswan_plugins}
-if USE_EAP_IDENTITY
- eap_LTLIBRARIES += libcharon-eapidentity.la
- libcharon_eapidentity_la_SOURCES = sa/authenticators/eap/eap_identity.h sa/authenticators/eap/eap_identity.c
- libcharon_eapidentity_la_LDFLAGS = -module
+if USE_UNIT_TESTS
+ SUBDIRS += plugins/unit_tester
+ PLUGINS += unit-tester
endif
-if USE_EAP_SIM
- eap_LTLIBRARIES += libcharon-eapsim.la
- libcharon_eapsim_la_SOURCES = sa/authenticators/eap/eap_sim.h sa/authenticators/eap/eap_sim.c
- libcharon_eapsim_la_LDFLAGS = -module
-
- plugin_LTLIBRARIES = libcharon-eapsim-file.la
- libcharon_eapsim_file_la_SOURCES = sa/authenticators/eap/sim/eap_sim_file.c
- libcharon_eapsim_file_la_LDFLAGS = -module
+if USE_STROKE
+ SUBDIRS += plugins/stroke
+ PLUGINS += stroke
endif
-if USE_EAP_MD5
- eap_LTLIBRARIES += libcharon-eapmd5.la
- libcharon_eapmd5_la_SOURCES = sa/authenticators/eap/eap_md5.h sa/authenticators/eap/eap_md5.c
- libcharon_eapmd5_la_LDFLAGS = -module
+if USE_SMP
+ SUBDIRS += plugins/smp
+ PLUGINS += smp
endif
-if USE_EAP_AKA
- eap_LTLIBRARIES += libcharon-eapaka.la
- libcharon_eapaka_la_SOURCES = sa/authenticators/eap/eap_aka.h sa/authenticators/eap/eap_aka.c
- libcharon_eapaka_la_LDFLAGS = -module
+if USE_SQL
+ SUBDIRS += plugins/sql
+ PLUGINS += sql
endif
-# build backends
-################
-backend_LTLIBRARIES =
+if USE_EAP_IDENTITY
+ SUBDIRS += plugins/eap_identity
+ PLUGINS += eapidentity
+endif
-if USE_STROKE
- backend_LTLIBRARIES += libcharon-local.la
- libcharon_local_la_SOURCES = config/backends/local_backend.h config/backends/local_backend.c
- libcharon_local_la_LDFLAGS = -module
+if USE_EAP_SIM
+ SUBDIRS += plugins/eap_sim
+ PLUGINS += eapsim
endif
-if USE_LIBSQLITE
- backend_LTLIBRARIES += libcharon-sqlite.la
- libcharon_sqlite_la_SOURCES = config/backends/sqlite_backend.h config/backends/sqlite_backend.c
- libcharon_sqlite_la_LIBADD = -lsqlite3
- libcharon_sqlite_la_LDFLAGS = -module
+if USE_EAP_MD5
+ SUBDIRS += plugins/eap_md5
+ PLUGINS += eapmd5
endif
-# build control interfaces
-##########################
-interface_LTLIBRARIES =
+if USE_EAP_AKA
+ SUBDIRS += plugins/eap_aka
+ PLUGINS += eapaka
+endif
-if USE_STROKE
- interface_LTLIBRARIES += libcharon-stroke.la
- libcharon_stroke_la_SOURCES = control/interfaces/stroke_interface.h control/interfaces/stroke_interface.c
- libcharon_stroke_la_LDFLAGS = -module
+if USE_MEDSRV
+ SUBDIRS += plugins/medsrv
+ PLUGINS += medsrv
endif
-if USE_LIBDBUS
- interface_LTLIBRARIES += libcharon-dbus.la
- libcharon_dbus_la_SOURCES = control/interfaces/dbus_interface.h control/interfaces/dbus_interface.c
- libcharon_dbus_la_LDFLAGS = -module
- libcharon_dbus_la_LIBADD = ${dbus_LIBS}
- INCLUDES += ${dbus_CFLAGS}
+if USE_MEDCLI
+ SUBDIRS += plugins/medcli
+ PLUGINS += medcli
endif
-if USE_LIBXML
- interface_LTLIBRARIES += libcharon-xml.la
- libcharon_xml_la_SOURCES = control/interfaces/xml_interface.h control/interfaces/xml_interface.c
- libcharon_xml_la_LDFLAGS = -module
- libcharon_xml_la_LIBADD = ${xml_LIBS}
- INCLUDES += ${xml_CFLAGS}
+if USE_UCI
+ SUBDIRS += plugins/uci
+ PLUGINS += uci
endif
+AM_CFLAGS += -DPLUGINS=\""${PLUGINS}\""
+
diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in
index 41f1690e2..cf03a0e35 100644
--- a/src/charon/Makefile.in
+++ b/src/charon/Makefile.in
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008 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.
@@ -14,7 +14,6 @@
@SET_MAKE@
-
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -35,28 +34,43 @@ build_triplet = @build@
host_triplet = @host@
ipsec_PROGRAMS = charon$(EXEEXT)
+# compile options
+#################
+
# Use RAW socket if pluto gets built
@USE_PLUTO_TRUE@am__append_1 = network/socket-raw.c
@USE_PLUTO_FALSE@am__append_2 = network/socket.c
-@USE_P2P_TRUE@am__append_3 = encoding/payloads/endpoint_notify.c encoding/payloads/endpoint_notify.h \
-@USE_P2P_TRUE@ processing/jobs/initiate_mediation_job.c processing/jobs/initiate_mediation_job.h \
-@USE_P2P_TRUE@ processing/jobs/mediation_job.c processing/jobs/mediation_job.h \
-@USE_P2P_TRUE@ sa/connect_manager.c sa/connect_manager.h \
-@USE_P2P_TRUE@ sa/mediation_manager.c sa/mediation_manager.h \
-@USE_P2P_TRUE@ sa/tasks/ike_p2p.c sa/tasks/ike_p2p.h
-
-@USE_LIBCURL_TRUE@am__append_4 = -lcurl
-@USE_EAP_IDENTITY_TRUE@am__append_5 = libcharon-eapidentity.la
-@USE_EAP_SIM_TRUE@am__append_6 = libcharon-eapsim.la
-@USE_EAP_MD5_TRUE@am__append_7 = libcharon-eapmd5.la
-@USE_EAP_AKA_TRUE@am__append_8 = libcharon-eapaka.la
-@USE_STROKE_TRUE@am__append_9 = libcharon-local.la
-@USE_LIBSQLITE_TRUE@am__append_10 = libcharon-sqlite.la
-@USE_STROKE_TRUE@am__append_11 = libcharon-stroke.la
-@USE_LIBDBUS_TRUE@am__append_12 = libcharon-dbus.la
-@USE_LIBDBUS_TRUE@am__append_13 = ${dbus_CFLAGS}
-@USE_LIBXML_TRUE@am__append_14 = libcharon-xml.la
-@USE_LIBXML_TRUE@am__append_15 = ${xml_CFLAGS}
+@USE_ME_TRUE@am__append_3 = encoding/payloads/endpoint_notify.c encoding/payloads/endpoint_notify.h \
+@USE_ME_TRUE@ processing/jobs/initiate_mediation_job.c processing/jobs/initiate_mediation_job.h \
+@USE_ME_TRUE@ processing/jobs/mediation_job.c processing/jobs/mediation_job.h \
+@USE_ME_TRUE@ sa/connect_manager.c sa/connect_manager.h \
+@USE_ME_TRUE@ sa/mediation_manager.c sa/mediation_manager.h \
+@USE_ME_TRUE@ sa/tasks/ike_me.c sa/tasks/ike_me.h
+
+@USE_INTEGRITY_TEST_TRUE@am__append_4 = -DINTEGRITY_TEST
+@USE_SELF_TEST_TRUE@am__append_5 = -DSELF_TEST
+@USE_UNIT_TESTS_TRUE@am__append_6 = plugins/unit_tester
+@USE_UNIT_TESTS_TRUE@am__append_7 = unit-tester
+@USE_STROKE_TRUE@am__append_8 = plugins/stroke
+@USE_STROKE_TRUE@am__append_9 = stroke
+@USE_SMP_TRUE@am__append_10 = plugins/smp
+@USE_SMP_TRUE@am__append_11 = smp
+@USE_SQL_TRUE@am__append_12 = plugins/sql
+@USE_SQL_TRUE@am__append_13 = sql
+@USE_EAP_IDENTITY_TRUE@am__append_14 = plugins/eap_identity
+@USE_EAP_IDENTITY_TRUE@am__append_15 = eapidentity
+@USE_EAP_SIM_TRUE@am__append_16 = plugins/eap_sim
+@USE_EAP_SIM_TRUE@am__append_17 = eapsim
+@USE_EAP_MD5_TRUE@am__append_18 = plugins/eap_md5
+@USE_EAP_MD5_TRUE@am__append_19 = eapmd5
+@USE_EAP_AKA_TRUE@am__append_20 = plugins/eap_aka
+@USE_EAP_AKA_TRUE@am__append_21 = eapaka
+@USE_MEDSRV_TRUE@am__append_22 = plugins/medsrv
+@USE_MEDSRV_TRUE@am__append_23 = medsrv
+@USE_MEDCLI_TRUE@am__append_24 = plugins/medcli
+@USE_MEDCLI_TRUE@am__append_25 = medcli
+@USE_UCI_TRUE@am__append_26 = plugins/uci
+@USE_UCI_TRUE@am__append_27 = uci
subdir = src/charon
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -65,147 +79,24 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(backenddir)" "$(DESTDIR)$(eapdir)" \
- "$(DESTDIR)$(interfacedir)" "$(DESTDIR)$(plugindir)" \
- "$(DESTDIR)$(ipsecdir)"
-backendLTLIBRARIES_INSTALL = $(INSTALL)
-eapLTLIBRARIES_INSTALL = $(INSTALL)
-interfaceLTLIBRARIES_INSTALL = $(INSTALL)
-pluginLTLIBRARIES_INSTALL = $(INSTALL)
-LTLIBRARIES = $(backend_LTLIBRARIES) $(eap_LTLIBRARIES) \
- $(interface_LTLIBRARIES) $(plugin_LTLIBRARIES)
-am__DEPENDENCIES_1 =
-@USE_LIBDBUS_TRUE@libcharon_dbus_la_DEPENDENCIES = \
-@USE_LIBDBUS_TRUE@ $(am__DEPENDENCIES_1)
-am__libcharon_dbus_la_SOURCES_DIST = \
- control/interfaces/dbus_interface.h \
- control/interfaces/dbus_interface.c
-@USE_LIBDBUS_TRUE@am_libcharon_dbus_la_OBJECTS = dbus_interface.lo
-libcharon_dbus_la_OBJECTS = $(am_libcharon_dbus_la_OBJECTS)
-libcharon_dbus_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libcharon_dbus_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_LIBDBUS_TRUE@am_libcharon_dbus_la_rpath = -rpath $(interfacedir)
-libcharon_eapaka_la_LIBADD =
-am__libcharon_eapaka_la_SOURCES_DIST = \
- sa/authenticators/eap/eap_aka.h \
- sa/authenticators/eap/eap_aka.c
-@USE_EAP_AKA_TRUE@am_libcharon_eapaka_la_OBJECTS = eap_aka.lo
-libcharon_eapaka_la_OBJECTS = $(am_libcharon_eapaka_la_OBJECTS)
-libcharon_eapaka_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libcharon_eapaka_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_EAP_AKA_TRUE@am_libcharon_eapaka_la_rpath = -rpath $(eapdir)
-libcharon_eapidentity_la_LIBADD =
-am__libcharon_eapidentity_la_SOURCES_DIST = \
- sa/authenticators/eap/eap_identity.h \
- sa/authenticators/eap/eap_identity.c
-@USE_EAP_IDENTITY_TRUE@am_libcharon_eapidentity_la_OBJECTS = \
-@USE_EAP_IDENTITY_TRUE@ eap_identity.lo
-libcharon_eapidentity_la_OBJECTS = \
- $(am_libcharon_eapidentity_la_OBJECTS)
-libcharon_eapidentity_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libcharon_eapidentity_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_EAP_IDENTITY_TRUE@am_libcharon_eapidentity_la_rpath = -rpath \
-@USE_EAP_IDENTITY_TRUE@ $(eapdir)
-libcharon_eapmd5_la_LIBADD =
-am__libcharon_eapmd5_la_SOURCES_DIST = \
- sa/authenticators/eap/eap_md5.h \
- sa/authenticators/eap/eap_md5.c
-@USE_EAP_MD5_TRUE@am_libcharon_eapmd5_la_OBJECTS = eap_md5.lo
-libcharon_eapmd5_la_OBJECTS = $(am_libcharon_eapmd5_la_OBJECTS)
-libcharon_eapmd5_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libcharon_eapmd5_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_EAP_MD5_TRUE@am_libcharon_eapmd5_la_rpath = -rpath $(eapdir)
-libcharon_eapsim_file_la_LIBADD =
-am__libcharon_eapsim_file_la_SOURCES_DIST = \
- sa/authenticators/eap/sim/eap_sim_file.c
-@USE_EAP_SIM_TRUE@am_libcharon_eapsim_file_la_OBJECTS = \
-@USE_EAP_SIM_TRUE@ eap_sim_file.lo
-libcharon_eapsim_file_la_OBJECTS = \
- $(am_libcharon_eapsim_file_la_OBJECTS)
-libcharon_eapsim_file_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libcharon_eapsim_file_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_EAP_SIM_TRUE@am_libcharon_eapsim_file_la_rpath = -rpath \
-@USE_EAP_SIM_TRUE@ $(plugindir)
-libcharon_eapsim_la_LIBADD =
-am__libcharon_eapsim_la_SOURCES_DIST = \
- sa/authenticators/eap/eap_sim.h \
- sa/authenticators/eap/eap_sim.c
-@USE_EAP_SIM_TRUE@am_libcharon_eapsim_la_OBJECTS = eap_sim.lo
-libcharon_eapsim_la_OBJECTS = $(am_libcharon_eapsim_la_OBJECTS)
-libcharon_eapsim_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libcharon_eapsim_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_EAP_SIM_TRUE@am_libcharon_eapsim_la_rpath = -rpath $(eapdir)
-libcharon_local_la_LIBADD =
-am__libcharon_local_la_SOURCES_DIST = config/backends/local_backend.h \
- config/backends/local_backend.c
-@USE_STROKE_TRUE@am_libcharon_local_la_OBJECTS = local_backend.lo
-libcharon_local_la_OBJECTS = $(am_libcharon_local_la_OBJECTS)
-libcharon_local_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libcharon_local_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_STROKE_TRUE@am_libcharon_local_la_rpath = -rpath $(backenddir)
-libcharon_sqlite_la_DEPENDENCIES =
-am__libcharon_sqlite_la_SOURCES_DIST = \
- config/backends/sqlite_backend.h \
- config/backends/sqlite_backend.c
-@USE_LIBSQLITE_TRUE@am_libcharon_sqlite_la_OBJECTS = \
-@USE_LIBSQLITE_TRUE@ sqlite_backend.lo
-libcharon_sqlite_la_OBJECTS = $(am_libcharon_sqlite_la_OBJECTS)
-libcharon_sqlite_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libcharon_sqlite_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_LIBSQLITE_TRUE@am_libcharon_sqlite_la_rpath = -rpath \
-@USE_LIBSQLITE_TRUE@ $(backenddir)
-libcharon_stroke_la_LIBADD =
-am__libcharon_stroke_la_SOURCES_DIST = \
- control/interfaces/stroke_interface.h \
- control/interfaces/stroke_interface.c
-@USE_STROKE_TRUE@am_libcharon_stroke_la_OBJECTS = stroke_interface.lo
-libcharon_stroke_la_OBJECTS = $(am_libcharon_stroke_la_OBJECTS)
-libcharon_stroke_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libcharon_stroke_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_STROKE_TRUE@am_libcharon_stroke_la_rpath = -rpath $(interfacedir)
-@USE_LIBXML_TRUE@libcharon_xml_la_DEPENDENCIES = \
-@USE_LIBXML_TRUE@ $(am__DEPENDENCIES_1)
-am__libcharon_xml_la_SOURCES_DIST = \
- control/interfaces/xml_interface.h \
- control/interfaces/xml_interface.c
-@USE_LIBXML_TRUE@am_libcharon_xml_la_OBJECTS = xml_interface.lo
-libcharon_xml_la_OBJECTS = $(am_libcharon_xml_la_OBJECTS)
-libcharon_xml_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libcharon_xml_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_LIBXML_TRUE@am_libcharon_xml_la_rpath = -rpath $(interfacedir)
+am__installdirs = "$(DESTDIR)$(ipsecdir)"
ipsecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(ipsec_PROGRAMS)
am__charon_SOURCES_DIST = bus/bus.c bus/bus.h \
bus/listeners/file_logger.c bus/listeners/file_logger.h \
bus/listeners/sys_logger.c bus/listeners/sys_logger.h \
- config/backends/backend.h config/backends/writeable_backend.h \
config/backend_manager.c config/backend_manager.h \
- config/child_cfg.c config/child_cfg.h \
- config/credentials/local_credential_store.c \
- config/credentials/local_credential_store.h config/ike_cfg.c \
- config/ike_cfg.h config/peer_cfg.c config/peer_cfg.h \
- config/proposal.c config/proposal.h config/traffic_selector.c \
- config/traffic_selector.h control/interfaces/interface.h \
- control/interface_manager.c control/interface_manager.h \
- daemon.c daemon.h encoding/generator.c encoding/generator.h \
- encoding/message.c encoding/message.h encoding/parser.c \
- encoding/parser.h encoding/payloads/auth_payload.c \
+ config/backend.h config/child_cfg.c config/child_cfg.h \
+ config/ike_cfg.c config/ike_cfg.h config/peer_cfg.c \
+ config/peer_cfg.h config/proposal.c config/proposal.h \
+ config/traffic_selector.c config/traffic_selector.h \
+ config/attributes/attribute_provider.h \
+ config/attributes/attribute_manager.c \
+ config/attributes/attribute_manager.h control/controller.c \
+ control/controller.h daemon.c daemon.h encoding/generator.c \
+ encoding/generator.h encoding/message.c encoding/message.h \
+ encoding/parser.c encoding/parser.h \
+ encoding/payloads/auth_payload.c \
encoding/payloads/auth_payload.h \
encoding/payloads/cert_payload.c \
encoding/payloads/cert_payload.h \
@@ -273,46 +164,55 @@ am__charon_SOURCES_DIST = bus/bus.c bus/bus.h \
sa/authenticators/eap_authenticator.h \
sa/authenticators/eap/eap_method.c \
sa/authenticators/eap/eap_method.h \
+ sa/authenticators/eap/eap_manager.c \
+ sa/authenticators/eap/eap_manager.h \
sa/authenticators/psk_authenticator.c \
sa/authenticators/psk_authenticator.h \
- sa/authenticators/rsa_authenticator.c \
- sa/authenticators/rsa_authenticator.h sa/child_sa.c \
+ sa/authenticators/pubkey_authenticator.c \
+ sa/authenticators/pubkey_authenticator.h sa/child_sa.c \
sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \
sa/ike_sa_id.h sa/ike_sa_manager.c sa/ike_sa_manager.h \
sa/task_manager.c sa/task_manager.h sa/tasks/child_create.c \
sa/tasks/child_create.h sa/tasks/child_delete.c \
sa/tasks/child_delete.h sa/tasks/child_rekey.c \
sa/tasks/child_rekey.h sa/tasks/ike_auth.c sa/tasks/ike_auth.h \
- sa/tasks/ike_cert.c sa/tasks/ike_cert.h sa/tasks/ike_config.c \
- sa/tasks/ike_config.h sa/tasks/ike_delete.c \
- sa/tasks/ike_delete.h sa/tasks/ike_dpd.c sa/tasks/ike_dpd.h \
- sa/tasks/ike_init.c sa/tasks/ike_init.h sa/tasks/ike_natd.c \
- sa/tasks/ike_natd.h sa/tasks/ike_mobike.c \
+ sa/tasks/ike_cert_pre.c sa/tasks/ike_cert_pre.h \
+ sa/tasks/ike_cert_post.c sa/tasks/ike_cert_post.h \
+ sa/tasks/ike_config.c sa/tasks/ike_config.h \
+ sa/tasks/ike_delete.c sa/tasks/ike_delete.h sa/tasks/ike_dpd.c \
+ sa/tasks/ike_dpd.h sa/tasks/ike_init.c sa/tasks/ike_init.h \
+ sa/tasks/ike_natd.c sa/tasks/ike_natd.h sa/tasks/ike_mobike.c \
sa/tasks/ike_mobike.h sa/tasks/ike_rekey.c \
sa/tasks/ike_rekey.h sa/tasks/ike_reauth.c \
sa/tasks/ike_reauth.h sa/tasks/ike_auth_lifetime.c \
sa/tasks/ike_auth_lifetime.h sa/tasks/task.c sa/tasks/task.h \
- network/socket-raw.c network/socket.c \
- encoding/payloads/endpoint_notify.c \
+ credentials/credential_manager.c \
+ credentials/credential_manager.h credentials/auth_info.c \
+ credentials/auth_info.h credentials/sets/auth_info_wrapper.c \
+ credentials/sets/auth_info_wrapper.h \
+ credentials/sets/ocsp_response_wrapper.c \
+ credentials/sets/ocsp_response_wrapper.h \
+ credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
+ credentials/credential_set.h network/socket-raw.c \
+ network/socket.c encoding/payloads/endpoint_notify.c \
encoding/payloads/endpoint_notify.h \
processing/jobs/initiate_mediation_job.c \
processing/jobs/initiate_mediation_job.h \
processing/jobs/mediation_job.c \
processing/jobs/mediation_job.h sa/connect_manager.c \
sa/connect_manager.h sa/mediation_manager.c \
- sa/mediation_manager.h sa/tasks/ike_p2p.c sa/tasks/ike_p2p.h
+ sa/mediation_manager.h sa/tasks/ike_me.c sa/tasks/ike_me.h
@USE_PLUTO_TRUE@am__objects_1 = socket-raw.$(OBJEXT)
@USE_PLUTO_FALSE@am__objects_2 = socket.$(OBJEXT)
-@USE_P2P_TRUE@am__objects_3 = endpoint_notify.$(OBJEXT) \
-@USE_P2P_TRUE@ initiate_mediation_job.$(OBJEXT) \
-@USE_P2P_TRUE@ mediation_job.$(OBJEXT) \
-@USE_P2P_TRUE@ connect_manager.$(OBJEXT) \
-@USE_P2P_TRUE@ mediation_manager.$(OBJEXT) ike_p2p.$(OBJEXT)
+@USE_ME_TRUE@am__objects_3 = endpoint_notify.$(OBJEXT) \
+@USE_ME_TRUE@ initiate_mediation_job.$(OBJEXT) \
+@USE_ME_TRUE@ mediation_job.$(OBJEXT) connect_manager.$(OBJEXT) \
+@USE_ME_TRUE@ mediation_manager.$(OBJEXT) ike_me.$(OBJEXT)
am_charon_OBJECTS = bus.$(OBJEXT) file_logger.$(OBJEXT) \
sys_logger.$(OBJEXT) backend_manager.$(OBJEXT) \
- child_cfg.$(OBJEXT) local_credential_store.$(OBJEXT) \
- ike_cfg.$(OBJEXT) peer_cfg.$(OBJEXT) proposal.$(OBJEXT) \
- traffic_selector.$(OBJEXT) interface_manager.$(OBJEXT) \
+ child_cfg.$(OBJEXT) ike_cfg.$(OBJEXT) peer_cfg.$(OBJEXT) \
+ proposal.$(OBJEXT) traffic_selector.$(OBJEXT) \
+ attribute_manager.$(OBJEXT) controller.$(OBJEXT) \
daemon.$(OBJEXT) generator.$(OBJEXT) message.$(OBJEXT) \
parser.$(OBJEXT) auth_payload.$(OBJEXT) cert_payload.$(OBJEXT) \
certreq_payload.$(OBJEXT) configuration_attribute.$(OBJEXT) \
@@ -334,21 +234,24 @@ am_charon_OBJECTS = bus.$(OBJEXT) file_logger.$(OBJEXT) \
send_dpd_job.$(OBJEXT) send_keepalive_job.$(OBJEXT) \
roam_job.$(OBJEXT) scheduler.$(OBJEXT) processor.$(OBJEXT) \
authenticator.$(OBJEXT) eap_authenticator.$(OBJEXT) \
- eap_method.$(OBJEXT) psk_authenticator.$(OBJEXT) \
- rsa_authenticator.$(OBJEXT) child_sa.$(OBJEXT) \
- ike_sa.$(OBJEXT) ike_sa_id.$(OBJEXT) ike_sa_manager.$(OBJEXT) \
- task_manager.$(OBJEXT) child_create.$(OBJEXT) \
- child_delete.$(OBJEXT) child_rekey.$(OBJEXT) \
- ike_auth.$(OBJEXT) ike_cert.$(OBJEXT) ike_config.$(OBJEXT) \
- ike_delete.$(OBJEXT) ike_dpd.$(OBJEXT) ike_init.$(OBJEXT) \
- ike_natd.$(OBJEXT) ike_mobike.$(OBJEXT) ike_rekey.$(OBJEXT) \
- ike_reauth.$(OBJEXT) ike_auth_lifetime.$(OBJEXT) \
- task.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
+ eap_method.$(OBJEXT) eap_manager.$(OBJEXT) \
+ psk_authenticator.$(OBJEXT) pubkey_authenticator.$(OBJEXT) \
+ child_sa.$(OBJEXT) ike_sa.$(OBJEXT) ike_sa_id.$(OBJEXT) \
+ ike_sa_manager.$(OBJEXT) task_manager.$(OBJEXT) \
+ child_create.$(OBJEXT) child_delete.$(OBJEXT) \
+ child_rekey.$(OBJEXT) ike_auth.$(OBJEXT) \
+ ike_cert_pre.$(OBJEXT) ike_cert_post.$(OBJEXT) \
+ ike_config.$(OBJEXT) ike_delete.$(OBJEXT) ike_dpd.$(OBJEXT) \
+ ike_init.$(OBJEXT) ike_natd.$(OBJEXT) ike_mobike.$(OBJEXT) \
+ ike_rekey.$(OBJEXT) ike_reauth.$(OBJEXT) \
+ ike_auth_lifetime.$(OBJEXT) task.$(OBJEXT) \
+ credential_manager.$(OBJEXT) auth_info.$(OBJEXT) \
+ auth_info_wrapper.$(OBJEXT) ocsp_response_wrapper.$(OBJEXT) \
+ cert_cache.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
$(am__objects_3)
charon_OBJECTS = $(am_charon_OBJECTS)
charon_DEPENDENCIES = \
- $(top_builddir)/src/libstrongswan/libstrongswan.la \
- $(am__DEPENDENCIES_1)
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -361,26 +264,23 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libcharon_dbus_la_SOURCES) $(libcharon_eapaka_la_SOURCES) \
- $(libcharon_eapidentity_la_SOURCES) \
- $(libcharon_eapmd5_la_SOURCES) \
- $(libcharon_eapsim_file_la_SOURCES) \
- $(libcharon_eapsim_la_SOURCES) $(libcharon_local_la_SOURCES) \
- $(libcharon_sqlite_la_SOURCES) $(libcharon_stroke_la_SOURCES) \
- $(libcharon_xml_la_SOURCES) $(charon_SOURCES)
-DIST_SOURCES = $(am__libcharon_dbus_la_SOURCES_DIST) \
- $(am__libcharon_eapaka_la_SOURCES_DIST) \
- $(am__libcharon_eapidentity_la_SOURCES_DIST) \
- $(am__libcharon_eapmd5_la_SOURCES_DIST) \
- $(am__libcharon_eapsim_file_la_SOURCES_DIST) \
- $(am__libcharon_eapsim_la_SOURCES_DIST) \
- $(am__libcharon_local_la_SOURCES_DIST) \
- $(am__libcharon_sqlite_la_SOURCES_DIST) \
- $(am__libcharon_stroke_la_SOURCES_DIST) \
- $(am__libcharon_xml_la_SOURCES_DIST) \
- $(am__charon_SOURCES_DIST)
+SOURCES = $(charon_SOURCES)
+DIST_SOURCES = $(am__charon_SOURCES_DIST)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
+DIST_SUBDIRS = . plugins/unit_tester plugins/stroke plugins/smp \
+ plugins/sql plugins/eap_identity plugins/eap_sim \
+ plugins/eap_md5 plugins/eap_aka plugins/medsrv plugins/medcli \
+ plugins/uci
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -401,6 +301,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -430,6 +331,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -460,7 +362,6 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
-backenddir = @backenddir@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -471,12 +372,11 @@ builddir = @builddir@
confdir = @confdir@
datadir = @datadir@
datarootdir = @datarootdir@
-dbus_CFLAGS = @dbus_CFLAGS@
-dbus_LIBS = @dbus_LIBS@
docdir = @docdir@
dvidir = @dvidir@
-eapdir = @eapdir@
exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -486,12 +386,12 @@ htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
-interfacedir = @interfacedir@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
-ipsecuid = @ipsecuid@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
libdir = @libdir@
libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
linuxdir = @linuxdir@
localedir = @localedir@
localstatedir = @localstatedir@
@@ -504,10 +404,12 @@ plugindir = @plugindir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+resolv_conf = @resolv_conf@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
simreader = @simreader@
srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
@@ -516,18 +418,19 @@ xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
charon_SOURCES = bus/bus.c bus/bus.h bus/listeners/file_logger.c \
bus/listeners/file_logger.h bus/listeners/sys_logger.c \
- bus/listeners/sys_logger.h config/backends/backend.h \
- config/backends/writeable_backend.h config/backend_manager.c \
- config/backend_manager.h config/child_cfg.c config/child_cfg.h \
- config/credentials/local_credential_store.c \
- config/credentials/local_credential_store.h config/ike_cfg.c \
- config/ike_cfg.h config/peer_cfg.c config/peer_cfg.h \
- config/proposal.c config/proposal.h config/traffic_selector.c \
- config/traffic_selector.h control/interfaces/interface.h \
- control/interface_manager.c control/interface_manager.h \
- daemon.c daemon.h encoding/generator.c encoding/generator.h \
- encoding/message.c encoding/message.h encoding/parser.c \
- encoding/parser.h encoding/payloads/auth_payload.c \
+ bus/listeners/sys_logger.h config/backend_manager.c \
+ config/backend_manager.h config/backend.h config/child_cfg.c \
+ config/child_cfg.h config/ike_cfg.c config/ike_cfg.h \
+ config/peer_cfg.c config/peer_cfg.h config/proposal.c \
+ config/proposal.h config/traffic_selector.c \
+ config/traffic_selector.h \
+ config/attributes/attribute_provider.h \
+ config/attributes/attribute_manager.c \
+ config/attributes/attribute_manager.h control/controller.c \
+ control/controller.h daemon.c daemon.h encoding/generator.c \
+ encoding/generator.h encoding/message.c encoding/message.h \
+ encoding/parser.c encoding/parser.h \
+ encoding/payloads/auth_payload.c \
encoding/payloads/auth_payload.h \
encoding/payloads/cert_payload.c \
encoding/payloads/cert_payload.h \
@@ -595,74 +498,57 @@ charon_SOURCES = bus/bus.c bus/bus.h bus/listeners/file_logger.c \
sa/authenticators/eap_authenticator.h \
sa/authenticators/eap/eap_method.c \
sa/authenticators/eap/eap_method.h \
+ sa/authenticators/eap/eap_manager.c \
+ sa/authenticators/eap/eap_manager.h \
sa/authenticators/psk_authenticator.c \
sa/authenticators/psk_authenticator.h \
- sa/authenticators/rsa_authenticator.c \
- sa/authenticators/rsa_authenticator.h sa/child_sa.c \
+ sa/authenticators/pubkey_authenticator.c \
+ sa/authenticators/pubkey_authenticator.h sa/child_sa.c \
sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \
sa/ike_sa_id.h sa/ike_sa_manager.c sa/ike_sa_manager.h \
sa/task_manager.c sa/task_manager.h sa/tasks/child_create.c \
sa/tasks/child_create.h sa/tasks/child_delete.c \
sa/tasks/child_delete.h sa/tasks/child_rekey.c \
sa/tasks/child_rekey.h sa/tasks/ike_auth.c sa/tasks/ike_auth.h \
- sa/tasks/ike_cert.c sa/tasks/ike_cert.h sa/tasks/ike_config.c \
- sa/tasks/ike_config.h sa/tasks/ike_delete.c \
- sa/tasks/ike_delete.h sa/tasks/ike_dpd.c sa/tasks/ike_dpd.h \
- sa/tasks/ike_init.c sa/tasks/ike_init.h sa/tasks/ike_natd.c \
- sa/tasks/ike_natd.h sa/tasks/ike_mobike.c \
+ sa/tasks/ike_cert_pre.c sa/tasks/ike_cert_pre.h \
+ sa/tasks/ike_cert_post.c sa/tasks/ike_cert_post.h \
+ sa/tasks/ike_config.c sa/tasks/ike_config.h \
+ sa/tasks/ike_delete.c sa/tasks/ike_delete.h sa/tasks/ike_dpd.c \
+ sa/tasks/ike_dpd.h sa/tasks/ike_init.c sa/tasks/ike_init.h \
+ sa/tasks/ike_natd.c sa/tasks/ike_natd.h sa/tasks/ike_mobike.c \
sa/tasks/ike_mobike.h sa/tasks/ike_rekey.c \
sa/tasks/ike_rekey.h sa/tasks/ike_reauth.c \
sa/tasks/ike_reauth.h sa/tasks/ike_auth_lifetime.c \
sa/tasks/ike_auth_lifetime.h sa/tasks/task.c sa/tasks/task.h \
- $(am__append_1) $(am__append_2) $(am__append_3)
-INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan \
- -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke \
- $(am__append_13) $(am__append_15)
-AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\" \
- -DIPSEC_EAPDIR=\"${eapdir}\" -DIPSEC_BACKENDDIR=\"${backenddir}\" -DIPSEC_INTERFACEDIR=\"${interfacedir}\" \
- -DSIM_READER_LIB=\"${simreader}\"
-
-charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
- -lgmp -lpthread -lm -ldl $(am__append_4)
-
-# build EAP plugins
-###################
-eap_LTLIBRARIES = $(am__append_5) $(am__append_6) $(am__append_7) \
- $(am__append_8)
-@USE_EAP_IDENTITY_TRUE@libcharon_eapidentity_la_SOURCES = sa/authenticators/eap/eap_identity.h sa/authenticators/eap/eap_identity.c
-@USE_EAP_IDENTITY_TRUE@libcharon_eapidentity_la_LDFLAGS = -module
-@USE_EAP_SIM_TRUE@libcharon_eapsim_la_SOURCES = sa/authenticators/eap/eap_sim.h sa/authenticators/eap/eap_sim.c
-@USE_EAP_SIM_TRUE@libcharon_eapsim_la_LDFLAGS = -module
-@USE_EAP_SIM_TRUE@plugin_LTLIBRARIES = libcharon-eapsim-file.la
-@USE_EAP_SIM_TRUE@libcharon_eapsim_file_la_SOURCES = sa/authenticators/eap/sim/eap_sim_file.c
-@USE_EAP_SIM_TRUE@libcharon_eapsim_file_la_LDFLAGS = -module
-@USE_EAP_MD5_TRUE@libcharon_eapmd5_la_SOURCES = sa/authenticators/eap/eap_md5.h sa/authenticators/eap/eap_md5.c
-@USE_EAP_MD5_TRUE@libcharon_eapmd5_la_LDFLAGS = -module
-@USE_EAP_AKA_TRUE@libcharon_eapaka_la_SOURCES = sa/authenticators/eap/eap_aka.h sa/authenticators/eap/eap_aka.c
-@USE_EAP_AKA_TRUE@libcharon_eapaka_la_LDFLAGS = -module
-
-# build backends
-################
-backend_LTLIBRARIES = $(am__append_9) $(am__append_10)
-@USE_STROKE_TRUE@libcharon_local_la_SOURCES = config/backends/local_backend.h config/backends/local_backend.c
-@USE_STROKE_TRUE@libcharon_local_la_LDFLAGS = -module
-@USE_LIBSQLITE_TRUE@libcharon_sqlite_la_SOURCES = config/backends/sqlite_backend.h config/backends/sqlite_backend.c
-@USE_LIBSQLITE_TRUE@libcharon_sqlite_la_LIBADD = -lsqlite3
-@USE_LIBSQLITE_TRUE@libcharon_sqlite_la_LDFLAGS = -module
-
-# build control interfaces
-##########################
-interface_LTLIBRARIES = $(am__append_11) $(am__append_12) \
- $(am__append_14)
-@USE_STROKE_TRUE@libcharon_stroke_la_SOURCES = control/interfaces/stroke_interface.h control/interfaces/stroke_interface.c
-@USE_STROKE_TRUE@libcharon_stroke_la_LDFLAGS = -module
-@USE_LIBDBUS_TRUE@libcharon_dbus_la_SOURCES = control/interfaces/dbus_interface.h control/interfaces/dbus_interface.c
-@USE_LIBDBUS_TRUE@libcharon_dbus_la_LDFLAGS = -module
-@USE_LIBDBUS_TRUE@libcharon_dbus_la_LIBADD = ${dbus_LIBS}
-@USE_LIBXML_TRUE@libcharon_xml_la_SOURCES = control/interfaces/xml_interface.h control/interfaces/xml_interface.c
-@USE_LIBXML_TRUE@libcharon_xml_la_LDFLAGS = -module
-@USE_LIBXML_TRUE@libcharon_xml_la_LIBADD = ${xml_LIBS}
-all: all-am
+ credentials/credential_manager.c \
+ credentials/credential_manager.h credentials/auth_info.c \
+ credentials/auth_info.h credentials/sets/auth_info_wrapper.c \
+ credentials/sets/auth_info_wrapper.h \
+ credentials/sets/ocsp_response_wrapper.c \
+ credentials/sets/ocsp_response_wrapper.h \
+ credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
+ credentials/credential_set.h $(am__append_1) $(am__append_2) \
+ $(am__append_3)
+INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic -DIPSEC_DIR=\"${ipsecdir}\" \
+ -DIPSEC_PIDDIR=\"${piddir}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\" \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
+ -DRESOLV_CONF=\"${resolv_conf}\" $(am__append_4) \
+ $(am__append_5) -DPLUGINS=\""${PLUGINS}\""
+charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lm -ldl
+
+# build optional plugins
+########################
+SUBDIRS = . $(am__append_6) $(am__append_8) $(am__append_10) \
+ $(am__append_12) $(am__append_14) $(am__append_16) \
+ $(am__append_18) $(am__append_20) $(am__append_22) \
+ $(am__append_24) $(am__append_26)
+PLUGINS = ${libstrongswan_plugins} $(am__append_7) $(am__append_9) \
+ $(am__append_11) $(am__append_13) $(am__append_15) \
+ $(am__append_17) $(am__append_19) $(am__append_21) \
+ $(am__append_23) $(am__append_25) $(am__append_27)
+all: all-recursive
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
@@ -695,134 +581,6 @@ $(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
-install-backendLTLIBRARIES: $(backend_LTLIBRARIES)
- @$(NORMAL_INSTALL)
- test -z "$(backenddir)" || $(MKDIR_P) "$(DESTDIR)$(backenddir)"
- @list='$(backend_LTLIBRARIES)'; for p in $$list; do \
- if test -f $$p; then \
- f=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=install $(backendLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(backenddir)/$$f'"; \
- $(LIBTOOL) --mode=install $(backendLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(backenddir)/$$f"; \
- else :; fi; \
- done
-
-uninstall-backendLTLIBRARIES:
- @$(NORMAL_UNINSTALL)
- @list='$(backend_LTLIBRARIES)'; for p in $$list; do \
- p=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(backenddir)/$$p'"; \
- $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(backenddir)/$$p"; \
- done
-
-clean-backendLTLIBRARIES:
- -test -z "$(backend_LTLIBRARIES)" || rm -f $(backend_LTLIBRARIES)
- @list='$(backend_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-eapLTLIBRARIES: $(eap_LTLIBRARIES)
- @$(NORMAL_INSTALL)
- test -z "$(eapdir)" || $(MKDIR_P) "$(DESTDIR)$(eapdir)"
- @list='$(eap_LTLIBRARIES)'; for p in $$list; do \
- if test -f $$p; then \
- f=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=install $(eapLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(eapdir)/$$f'"; \
- $(LIBTOOL) --mode=install $(eapLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(eapdir)/$$f"; \
- else :; fi; \
- done
-
-uninstall-eapLTLIBRARIES:
- @$(NORMAL_UNINSTALL)
- @list='$(eap_LTLIBRARIES)'; for p in $$list; do \
- p=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(eapdir)/$$p'"; \
- $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(eapdir)/$$p"; \
- done
-
-clean-eapLTLIBRARIES:
- -test -z "$(eap_LTLIBRARIES)" || rm -f $(eap_LTLIBRARIES)
- @list='$(eap_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-interfaceLTLIBRARIES: $(interface_LTLIBRARIES)
- @$(NORMAL_INSTALL)
- test -z "$(interfacedir)" || $(MKDIR_P) "$(DESTDIR)$(interfacedir)"
- @list='$(interface_LTLIBRARIES)'; for p in $$list; do \
- if test -f $$p; then \
- f=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=install $(interfaceLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(interfacedir)/$$f'"; \
- $(LIBTOOL) --mode=install $(interfaceLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(interfacedir)/$$f"; \
- else :; fi; \
- done
-
-uninstall-interfaceLTLIBRARIES:
- @$(NORMAL_UNINSTALL)
- @list='$(interface_LTLIBRARIES)'; for p in $$list; do \
- p=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(interfacedir)/$$p'"; \
- $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(interfacedir)/$$p"; \
- done
-
-clean-interfaceLTLIBRARIES:
- -test -z "$(interface_LTLIBRARIES)" || rm -f $(interface_LTLIBRARIES)
- @list='$(interface_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)'; for p in $$list; do \
- if test -f $$p; then \
- f=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
- $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
- else :; fi; \
- done
-
-uninstall-pluginLTLIBRARIES:
- @$(NORMAL_UNINSTALL)
- @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
- p=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
- $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
- 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
-libcharon-dbus.la: $(libcharon_dbus_la_OBJECTS) $(libcharon_dbus_la_DEPENDENCIES)
- $(libcharon_dbus_la_LINK) $(am_libcharon_dbus_la_rpath) $(libcharon_dbus_la_OBJECTS) $(libcharon_dbus_la_LIBADD) $(LIBS)
-libcharon-eapaka.la: $(libcharon_eapaka_la_OBJECTS) $(libcharon_eapaka_la_DEPENDENCIES)
- $(libcharon_eapaka_la_LINK) $(am_libcharon_eapaka_la_rpath) $(libcharon_eapaka_la_OBJECTS) $(libcharon_eapaka_la_LIBADD) $(LIBS)
-libcharon-eapidentity.la: $(libcharon_eapidentity_la_OBJECTS) $(libcharon_eapidentity_la_DEPENDENCIES)
- $(libcharon_eapidentity_la_LINK) $(am_libcharon_eapidentity_la_rpath) $(libcharon_eapidentity_la_OBJECTS) $(libcharon_eapidentity_la_LIBADD) $(LIBS)
-libcharon-eapmd5.la: $(libcharon_eapmd5_la_OBJECTS) $(libcharon_eapmd5_la_DEPENDENCIES)
- $(libcharon_eapmd5_la_LINK) $(am_libcharon_eapmd5_la_rpath) $(libcharon_eapmd5_la_OBJECTS) $(libcharon_eapmd5_la_LIBADD) $(LIBS)
-libcharon-eapsim-file.la: $(libcharon_eapsim_file_la_OBJECTS) $(libcharon_eapsim_file_la_DEPENDENCIES)
- $(libcharon_eapsim_file_la_LINK) $(am_libcharon_eapsim_file_la_rpath) $(libcharon_eapsim_file_la_OBJECTS) $(libcharon_eapsim_file_la_LIBADD) $(LIBS)
-libcharon-eapsim.la: $(libcharon_eapsim_la_OBJECTS) $(libcharon_eapsim_la_DEPENDENCIES)
- $(libcharon_eapsim_la_LINK) $(am_libcharon_eapsim_la_rpath) $(libcharon_eapsim_la_OBJECTS) $(libcharon_eapsim_la_LIBADD) $(LIBS)
-libcharon-local.la: $(libcharon_local_la_OBJECTS) $(libcharon_local_la_DEPENDENCIES)
- $(libcharon_local_la_LINK) $(am_libcharon_local_la_rpath) $(libcharon_local_la_OBJECTS) $(libcharon_local_la_LIBADD) $(LIBS)
-libcharon-sqlite.la: $(libcharon_sqlite_la_OBJECTS) $(libcharon_sqlite_la_DEPENDENCIES)
- $(libcharon_sqlite_la_LINK) $(am_libcharon_sqlite_la_rpath) $(libcharon_sqlite_la_OBJECTS) $(libcharon_sqlite_la_LIBADD) $(LIBS)
-libcharon-stroke.la: $(libcharon_stroke_la_OBJECTS) $(libcharon_stroke_la_DEPENDENCIES)
- $(libcharon_stroke_la_LINK) $(am_libcharon_stroke_la_rpath) $(libcharon_stroke_la_OBJECTS) $(libcharon_stroke_la_LIBADD) $(LIBS)
-libcharon-xml.la: $(libcharon_xml_la_OBJECTS) $(libcharon_xml_la_DEPENDENCIES)
- $(libcharon_xml_la_LINK) $(am_libcharon_xml_la_rpath) $(libcharon_xml_la_OBJECTS) $(libcharon_xml_la_LIBADD) $(LIBS)
install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(ipsecdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsecdir)"
@@ -832,8 +590,8 @@ install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
|| test -f $$p1 \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(ipsecPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(ipsecdir)/$$f'"; \
- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(ipsecPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(ipsecdir)/$$f" || exit 1; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(ipsecPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(ipsecdir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(ipsecPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(ipsecdir)/$$f" || exit 1; \
else :; fi; \
done
@@ -862,11 +620,15 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acquire_job.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attribute_manager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_info.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_info_wrapper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/authenticator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_manager.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bus.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback_job.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cert_cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cert_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certreq_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/child_cfg.Po@am__quote@
@@ -876,20 +638,17 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/child_sa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/configuration_attribute.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connect_manager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/controller.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cp_payload.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/credential_manager.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/daemon.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbus_interface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delete_child_sa_job.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delete_ike_sa_job.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delete_payload.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_aka.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_authenticator.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_identity.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_md5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_manager.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_method.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_payload.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_sim.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_sim_file.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encodings.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encryption_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/endpoint_notify.Po@am__quote@
@@ -898,32 +657,31 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_auth.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_auth_lifetime.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_cert.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_cert_post.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_cert_pre.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_cfg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_config.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_delete.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_dpd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_header.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_init.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_me.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_mobike.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_natd.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_p2p.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_reauth.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_rekey.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_sa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_sa_id.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_sa_manager.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/initiate_mediation_job.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interface_manager.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ke_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_interface.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/local_backend.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/local_credential_store.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mediation_job.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mediation_manager.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nonce_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notify_payload.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp_response_wrapper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/payload.Po@am__quote@
@@ -933,12 +691,12 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proposal.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proposal_substructure.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psk_authenticator.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey_authenticator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/receiver.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rekey_child_sa_job.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rekey_ike_sa_job.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/retransmit_job.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/roam_job.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa_authenticator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sa_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scheduler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/send_dpd_job.Po@am__quote@
@@ -946,8 +704,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sender.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket-raw.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqlite_backend.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_interface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sys_logger.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task_manager.Po@am__quote@
@@ -958,7 +714,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unknown_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vendor_id_payload.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_interface.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -981,76 +736,6 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-dbus_interface.lo: control/interfaces/dbus_interface.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dbus_interface.lo -MD -MP -MF $(DEPDIR)/dbus_interface.Tpo -c -o dbus_interface.lo `test -f 'control/interfaces/dbus_interface.c' || echo '$(srcdir)/'`control/interfaces/dbus_interface.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/dbus_interface.Tpo $(DEPDIR)/dbus_interface.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='control/interfaces/dbus_interface.c' object='dbus_interface.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dbus_interface.lo `test -f 'control/interfaces/dbus_interface.c' || echo '$(srcdir)/'`control/interfaces/dbus_interface.c
-
-eap_aka.lo: sa/authenticators/eap/eap_aka.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_aka.lo -MD -MP -MF $(DEPDIR)/eap_aka.Tpo -c -o eap_aka.lo `test -f 'sa/authenticators/eap/eap_aka.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_aka.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_aka.Tpo $(DEPDIR)/eap_aka.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/eap_aka.c' object='eap_aka.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_aka.lo `test -f 'sa/authenticators/eap/eap_aka.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_aka.c
-
-eap_identity.lo: sa/authenticators/eap/eap_identity.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_identity.lo -MD -MP -MF $(DEPDIR)/eap_identity.Tpo -c -o eap_identity.lo `test -f 'sa/authenticators/eap/eap_identity.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_identity.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_identity.Tpo $(DEPDIR)/eap_identity.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/eap_identity.c' object='eap_identity.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_identity.lo `test -f 'sa/authenticators/eap/eap_identity.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_identity.c
-
-eap_md5.lo: sa/authenticators/eap/eap_md5.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_md5.lo -MD -MP -MF $(DEPDIR)/eap_md5.Tpo -c -o eap_md5.lo `test -f 'sa/authenticators/eap/eap_md5.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_md5.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_md5.Tpo $(DEPDIR)/eap_md5.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/eap_md5.c' object='eap_md5.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_md5.lo `test -f 'sa/authenticators/eap/eap_md5.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_md5.c
-
-eap_sim_file.lo: sa/authenticators/eap/sim/eap_sim_file.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_sim_file.lo -MD -MP -MF $(DEPDIR)/eap_sim_file.Tpo -c -o eap_sim_file.lo `test -f 'sa/authenticators/eap/sim/eap_sim_file.c' || echo '$(srcdir)/'`sa/authenticators/eap/sim/eap_sim_file.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_sim_file.Tpo $(DEPDIR)/eap_sim_file.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/sim/eap_sim_file.c' object='eap_sim_file.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_sim_file.lo `test -f 'sa/authenticators/eap/sim/eap_sim_file.c' || echo '$(srcdir)/'`sa/authenticators/eap/sim/eap_sim_file.c
-
-eap_sim.lo: sa/authenticators/eap/eap_sim.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_sim.lo -MD -MP -MF $(DEPDIR)/eap_sim.Tpo -c -o eap_sim.lo `test -f 'sa/authenticators/eap/eap_sim.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_sim.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_sim.Tpo $(DEPDIR)/eap_sim.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/eap_sim.c' object='eap_sim.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_sim.lo `test -f 'sa/authenticators/eap/eap_sim.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_sim.c
-
-local_backend.lo: config/backends/local_backend.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT local_backend.lo -MD -MP -MF $(DEPDIR)/local_backend.Tpo -c -o local_backend.lo `test -f 'config/backends/local_backend.c' || echo '$(srcdir)/'`config/backends/local_backend.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/local_backend.Tpo $(DEPDIR)/local_backend.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/backends/local_backend.c' object='local_backend.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o local_backend.lo `test -f 'config/backends/local_backend.c' || echo '$(srcdir)/'`config/backends/local_backend.c
-
-sqlite_backend.lo: config/backends/sqlite_backend.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sqlite_backend.lo -MD -MP -MF $(DEPDIR)/sqlite_backend.Tpo -c -o sqlite_backend.lo `test -f 'config/backends/sqlite_backend.c' || echo '$(srcdir)/'`config/backends/sqlite_backend.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sqlite_backend.Tpo $(DEPDIR)/sqlite_backend.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/backends/sqlite_backend.c' object='sqlite_backend.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sqlite_backend.lo `test -f 'config/backends/sqlite_backend.c' || echo '$(srcdir)/'`config/backends/sqlite_backend.c
-
-stroke_interface.lo: control/interfaces/stroke_interface.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stroke_interface.lo -MD -MP -MF $(DEPDIR)/stroke_interface.Tpo -c -o stroke_interface.lo `test -f 'control/interfaces/stroke_interface.c' || echo '$(srcdir)/'`control/interfaces/stroke_interface.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/stroke_interface.Tpo $(DEPDIR)/stroke_interface.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='control/interfaces/stroke_interface.c' object='stroke_interface.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stroke_interface.lo `test -f 'control/interfaces/stroke_interface.c' || echo '$(srcdir)/'`control/interfaces/stroke_interface.c
-
-xml_interface.lo: control/interfaces/xml_interface.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xml_interface.lo -MD -MP -MF $(DEPDIR)/xml_interface.Tpo -c -o xml_interface.lo `test -f 'control/interfaces/xml_interface.c' || echo '$(srcdir)/'`control/interfaces/xml_interface.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/xml_interface.Tpo $(DEPDIR)/xml_interface.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='control/interfaces/xml_interface.c' object='xml_interface.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xml_interface.lo `test -f 'control/interfaces/xml_interface.c' || echo '$(srcdir)/'`control/interfaces/xml_interface.c
-
bus.o: bus/bus.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bus.o -MD -MP -MF $(DEPDIR)/bus.Tpo -c -o bus.o `test -f 'bus/bus.c' || echo '$(srcdir)/'`bus/bus.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/bus.Tpo $(DEPDIR)/bus.Po
@@ -1121,20 +806,6 @@ child_cfg.obj: config/child_cfg.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o child_cfg.obj `if test -f 'config/child_cfg.c'; then $(CYGPATH_W) 'config/child_cfg.c'; else $(CYGPATH_W) '$(srcdir)/config/child_cfg.c'; fi`
-local_credential_store.o: config/credentials/local_credential_store.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT local_credential_store.o -MD -MP -MF $(DEPDIR)/local_credential_store.Tpo -c -o local_credential_store.o `test -f 'config/credentials/local_credential_store.c' || echo '$(srcdir)/'`config/credentials/local_credential_store.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/local_credential_store.Tpo $(DEPDIR)/local_credential_store.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/credentials/local_credential_store.c' object='local_credential_store.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o local_credential_store.o `test -f 'config/credentials/local_credential_store.c' || echo '$(srcdir)/'`config/credentials/local_credential_store.c
-
-local_credential_store.obj: config/credentials/local_credential_store.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT local_credential_store.obj -MD -MP -MF $(DEPDIR)/local_credential_store.Tpo -c -o local_credential_store.obj `if test -f 'config/credentials/local_credential_store.c'; then $(CYGPATH_W) 'config/credentials/local_credential_store.c'; else $(CYGPATH_W) '$(srcdir)/config/credentials/local_credential_store.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/local_credential_store.Tpo $(DEPDIR)/local_credential_store.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/credentials/local_credential_store.c' object='local_credential_store.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o local_credential_store.obj `if test -f 'config/credentials/local_credential_store.c'; then $(CYGPATH_W) 'config/credentials/local_credential_store.c'; else $(CYGPATH_W) '$(srcdir)/config/credentials/local_credential_store.c'; fi`
-
ike_cfg.o: config/ike_cfg.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_cfg.o -MD -MP -MF $(DEPDIR)/ike_cfg.Tpo -c -o ike_cfg.o `test -f 'config/ike_cfg.c' || echo '$(srcdir)/'`config/ike_cfg.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_cfg.Tpo $(DEPDIR)/ike_cfg.Po
@@ -1191,19 +862,33 @@ traffic_selector.obj: config/traffic_selector.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o traffic_selector.obj `if test -f 'config/traffic_selector.c'; then $(CYGPATH_W) 'config/traffic_selector.c'; else $(CYGPATH_W) '$(srcdir)/config/traffic_selector.c'; fi`
-interface_manager.o: control/interface_manager.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT interface_manager.o -MD -MP -MF $(DEPDIR)/interface_manager.Tpo -c -o interface_manager.o `test -f 'control/interface_manager.c' || echo '$(srcdir)/'`control/interface_manager.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/interface_manager.Tpo $(DEPDIR)/interface_manager.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='control/interface_manager.c' object='interface_manager.o' libtool=no @AMDEPBACKSLASH@
+attribute_manager.o: config/attributes/attribute_manager.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT attribute_manager.o -MD -MP -MF $(DEPDIR)/attribute_manager.Tpo -c -o attribute_manager.o `test -f 'config/attributes/attribute_manager.c' || echo '$(srcdir)/'`config/attributes/attribute_manager.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/attribute_manager.Tpo $(DEPDIR)/attribute_manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/attributes/attribute_manager.c' object='attribute_manager.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o attribute_manager.o `test -f 'config/attributes/attribute_manager.c' || echo '$(srcdir)/'`config/attributes/attribute_manager.c
+
+attribute_manager.obj: config/attributes/attribute_manager.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT attribute_manager.obj -MD -MP -MF $(DEPDIR)/attribute_manager.Tpo -c -o attribute_manager.obj `if test -f 'config/attributes/attribute_manager.c'; then $(CYGPATH_W) 'config/attributes/attribute_manager.c'; else $(CYGPATH_W) '$(srcdir)/config/attributes/attribute_manager.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/attribute_manager.Tpo $(DEPDIR)/attribute_manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/attributes/attribute_manager.c' object='attribute_manager.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o interface_manager.o `test -f 'control/interface_manager.c' || echo '$(srcdir)/'`control/interface_manager.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o attribute_manager.obj `if test -f 'config/attributes/attribute_manager.c'; then $(CYGPATH_W) 'config/attributes/attribute_manager.c'; else $(CYGPATH_W) '$(srcdir)/config/attributes/attribute_manager.c'; fi`
-interface_manager.obj: control/interface_manager.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT interface_manager.obj -MD -MP -MF $(DEPDIR)/interface_manager.Tpo -c -o interface_manager.obj `if test -f 'control/interface_manager.c'; then $(CYGPATH_W) 'control/interface_manager.c'; else $(CYGPATH_W) '$(srcdir)/control/interface_manager.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/interface_manager.Tpo $(DEPDIR)/interface_manager.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='control/interface_manager.c' object='interface_manager.obj' libtool=no @AMDEPBACKSLASH@
+controller.o: control/controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT controller.o -MD -MP -MF $(DEPDIR)/controller.Tpo -c -o controller.o `test -f 'control/controller.c' || echo '$(srcdir)/'`control/controller.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/controller.Tpo $(DEPDIR)/controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='control/controller.c' object='controller.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o interface_manager.obj `if test -f 'control/interface_manager.c'; then $(CYGPATH_W) 'control/interface_manager.c'; else $(CYGPATH_W) '$(srcdir)/control/interface_manager.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o controller.o `test -f 'control/controller.c' || echo '$(srcdir)/'`control/controller.c
+
+controller.obj: control/controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT controller.obj -MD -MP -MF $(DEPDIR)/controller.Tpo -c -o controller.obj `if test -f 'control/controller.c'; then $(CYGPATH_W) 'control/controller.c'; else $(CYGPATH_W) '$(srcdir)/control/controller.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/controller.Tpo $(DEPDIR)/controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='control/controller.c' object='controller.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o controller.obj `if test -f 'control/controller.c'; then $(CYGPATH_W) 'control/controller.c'; else $(CYGPATH_W) '$(srcdir)/control/controller.c'; fi`
generator.o: encoding/generator.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT generator.o -MD -MP -MF $(DEPDIR)/generator.Tpo -c -o generator.o `test -f 'encoding/generator.c' || echo '$(srcdir)/'`encoding/generator.c
@@ -1849,6 +1534,20 @@ eap_method.obj: sa/authenticators/eap/eap_method.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_method.obj `if test -f 'sa/authenticators/eap/eap_method.c'; then $(CYGPATH_W) 'sa/authenticators/eap/eap_method.c'; else $(CYGPATH_W) '$(srcdir)/sa/authenticators/eap/eap_method.c'; fi`
+eap_manager.o: sa/authenticators/eap/eap_manager.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_manager.o -MD -MP -MF $(DEPDIR)/eap_manager.Tpo -c -o eap_manager.o `test -f 'sa/authenticators/eap/eap_manager.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_manager.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_manager.Tpo $(DEPDIR)/eap_manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/eap_manager.c' object='eap_manager.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_manager.o `test -f 'sa/authenticators/eap/eap_manager.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_manager.c
+
+eap_manager.obj: sa/authenticators/eap/eap_manager.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_manager.obj -MD -MP -MF $(DEPDIR)/eap_manager.Tpo -c -o eap_manager.obj `if test -f 'sa/authenticators/eap/eap_manager.c'; then $(CYGPATH_W) 'sa/authenticators/eap/eap_manager.c'; else $(CYGPATH_W) '$(srcdir)/sa/authenticators/eap/eap_manager.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_manager.Tpo $(DEPDIR)/eap_manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/eap_manager.c' object='eap_manager.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_manager.obj `if test -f 'sa/authenticators/eap/eap_manager.c'; then $(CYGPATH_W) 'sa/authenticators/eap/eap_manager.c'; else $(CYGPATH_W) '$(srcdir)/sa/authenticators/eap/eap_manager.c'; fi`
+
psk_authenticator.o: sa/authenticators/psk_authenticator.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psk_authenticator.o -MD -MP -MF $(DEPDIR)/psk_authenticator.Tpo -c -o psk_authenticator.o `test -f 'sa/authenticators/psk_authenticator.c' || echo '$(srcdir)/'`sa/authenticators/psk_authenticator.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/psk_authenticator.Tpo $(DEPDIR)/psk_authenticator.Po
@@ -1863,19 +1562,19 @@ psk_authenticator.obj: sa/authenticators/psk_authenticator.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o psk_authenticator.obj `if test -f 'sa/authenticators/psk_authenticator.c'; then $(CYGPATH_W) 'sa/authenticators/psk_authenticator.c'; else $(CYGPATH_W) '$(srcdir)/sa/authenticators/psk_authenticator.c'; fi`
-rsa_authenticator.o: sa/authenticators/rsa_authenticator.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsa_authenticator.o -MD -MP -MF $(DEPDIR)/rsa_authenticator.Tpo -c -o rsa_authenticator.o `test -f 'sa/authenticators/rsa_authenticator.c' || echo '$(srcdir)/'`sa/authenticators/rsa_authenticator.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rsa_authenticator.Tpo $(DEPDIR)/rsa_authenticator.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/rsa_authenticator.c' object='rsa_authenticator.o' libtool=no @AMDEPBACKSLASH@
+pubkey_authenticator.o: sa/authenticators/pubkey_authenticator.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pubkey_authenticator.o -MD -MP -MF $(DEPDIR)/pubkey_authenticator.Tpo -c -o pubkey_authenticator.o `test -f 'sa/authenticators/pubkey_authenticator.c' || echo '$(srcdir)/'`sa/authenticators/pubkey_authenticator.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pubkey_authenticator.Tpo $(DEPDIR)/pubkey_authenticator.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/pubkey_authenticator.c' object='pubkey_authenticator.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsa_authenticator.o `test -f 'sa/authenticators/rsa_authenticator.c' || echo '$(srcdir)/'`sa/authenticators/rsa_authenticator.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pubkey_authenticator.o `test -f 'sa/authenticators/pubkey_authenticator.c' || echo '$(srcdir)/'`sa/authenticators/pubkey_authenticator.c
-rsa_authenticator.obj: sa/authenticators/rsa_authenticator.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsa_authenticator.obj -MD -MP -MF $(DEPDIR)/rsa_authenticator.Tpo -c -o rsa_authenticator.obj `if test -f 'sa/authenticators/rsa_authenticator.c'; then $(CYGPATH_W) 'sa/authenticators/rsa_authenticator.c'; else $(CYGPATH_W) '$(srcdir)/sa/authenticators/rsa_authenticator.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rsa_authenticator.Tpo $(DEPDIR)/rsa_authenticator.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/rsa_authenticator.c' object='rsa_authenticator.obj' libtool=no @AMDEPBACKSLASH@
+pubkey_authenticator.obj: sa/authenticators/pubkey_authenticator.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pubkey_authenticator.obj -MD -MP -MF $(DEPDIR)/pubkey_authenticator.Tpo -c -o pubkey_authenticator.obj `if test -f 'sa/authenticators/pubkey_authenticator.c'; then $(CYGPATH_W) 'sa/authenticators/pubkey_authenticator.c'; else $(CYGPATH_W) '$(srcdir)/sa/authenticators/pubkey_authenticator.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pubkey_authenticator.Tpo $(DEPDIR)/pubkey_authenticator.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/pubkey_authenticator.c' object='pubkey_authenticator.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsa_authenticator.obj `if test -f 'sa/authenticators/rsa_authenticator.c'; then $(CYGPATH_W) 'sa/authenticators/rsa_authenticator.c'; else $(CYGPATH_W) '$(srcdir)/sa/authenticators/rsa_authenticator.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pubkey_authenticator.obj `if test -f 'sa/authenticators/pubkey_authenticator.c'; then $(CYGPATH_W) 'sa/authenticators/pubkey_authenticator.c'; else $(CYGPATH_W) '$(srcdir)/sa/authenticators/pubkey_authenticator.c'; fi`
child_sa.o: sa/child_sa.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT child_sa.o -MD -MP -MF $(DEPDIR)/child_sa.Tpo -c -o child_sa.o `test -f 'sa/child_sa.c' || echo '$(srcdir)/'`sa/child_sa.c
@@ -2003,19 +1702,33 @@ ike_auth.obj: sa/tasks/ike_auth.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_auth.obj `if test -f 'sa/tasks/ike_auth.c'; then $(CYGPATH_W) 'sa/tasks/ike_auth.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_auth.c'; fi`
-ike_cert.o: sa/tasks/ike_cert.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_cert.o -MD -MP -MF $(DEPDIR)/ike_cert.Tpo -c -o ike_cert.o `test -f 'sa/tasks/ike_cert.c' || echo '$(srcdir)/'`sa/tasks/ike_cert.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_cert.Tpo $(DEPDIR)/ike_cert.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_cert.c' object='ike_cert.o' libtool=no @AMDEPBACKSLASH@
+ike_cert_pre.o: sa/tasks/ike_cert_pre.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_cert_pre.o -MD -MP -MF $(DEPDIR)/ike_cert_pre.Tpo -c -o ike_cert_pre.o `test -f 'sa/tasks/ike_cert_pre.c' || echo '$(srcdir)/'`sa/tasks/ike_cert_pre.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_cert_pre.Tpo $(DEPDIR)/ike_cert_pre.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_cert_pre.c' object='ike_cert_pre.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_cert_pre.o `test -f 'sa/tasks/ike_cert_pre.c' || echo '$(srcdir)/'`sa/tasks/ike_cert_pre.c
+
+ike_cert_pre.obj: sa/tasks/ike_cert_pre.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_cert_pre.obj -MD -MP -MF $(DEPDIR)/ike_cert_pre.Tpo -c -o ike_cert_pre.obj `if test -f 'sa/tasks/ike_cert_pre.c'; then $(CYGPATH_W) 'sa/tasks/ike_cert_pre.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_cert_pre.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_cert_pre.Tpo $(DEPDIR)/ike_cert_pre.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_cert_pre.c' object='ike_cert_pre.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_cert_pre.obj `if test -f 'sa/tasks/ike_cert_pre.c'; then $(CYGPATH_W) 'sa/tasks/ike_cert_pre.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_cert_pre.c'; fi`
+
+ike_cert_post.o: sa/tasks/ike_cert_post.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_cert_post.o -MD -MP -MF $(DEPDIR)/ike_cert_post.Tpo -c -o ike_cert_post.o `test -f 'sa/tasks/ike_cert_post.c' || echo '$(srcdir)/'`sa/tasks/ike_cert_post.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_cert_post.Tpo $(DEPDIR)/ike_cert_post.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_cert_post.c' object='ike_cert_post.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_cert.o `test -f 'sa/tasks/ike_cert.c' || echo '$(srcdir)/'`sa/tasks/ike_cert.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_cert_post.o `test -f 'sa/tasks/ike_cert_post.c' || echo '$(srcdir)/'`sa/tasks/ike_cert_post.c
-ike_cert.obj: sa/tasks/ike_cert.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_cert.obj -MD -MP -MF $(DEPDIR)/ike_cert.Tpo -c -o ike_cert.obj `if test -f 'sa/tasks/ike_cert.c'; then $(CYGPATH_W) 'sa/tasks/ike_cert.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_cert.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_cert.Tpo $(DEPDIR)/ike_cert.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_cert.c' object='ike_cert.obj' libtool=no @AMDEPBACKSLASH@
+ike_cert_post.obj: sa/tasks/ike_cert_post.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_cert_post.obj -MD -MP -MF $(DEPDIR)/ike_cert_post.Tpo -c -o ike_cert_post.obj `if test -f 'sa/tasks/ike_cert_post.c'; then $(CYGPATH_W) 'sa/tasks/ike_cert_post.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_cert_post.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_cert_post.Tpo $(DEPDIR)/ike_cert_post.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_cert_post.c' object='ike_cert_post.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_cert.obj `if test -f 'sa/tasks/ike_cert.c'; then $(CYGPATH_W) 'sa/tasks/ike_cert.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_cert.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_cert_post.obj `if test -f 'sa/tasks/ike_cert_post.c'; then $(CYGPATH_W) 'sa/tasks/ike_cert_post.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_cert_post.c'; fi`
ike_config.o: sa/tasks/ike_config.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_config.o -MD -MP -MF $(DEPDIR)/ike_config.Tpo -c -o ike_config.o `test -f 'sa/tasks/ike_config.c' || echo '$(srcdir)/'`sa/tasks/ike_config.c
@@ -2157,6 +1870,76 @@ task.obj: sa/tasks/task.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o task.obj `if test -f 'sa/tasks/task.c'; then $(CYGPATH_W) 'sa/tasks/task.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/task.c'; fi`
+credential_manager.o: credentials/credential_manager.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT credential_manager.o -MD -MP -MF $(DEPDIR)/credential_manager.Tpo -c -o credential_manager.o `test -f 'credentials/credential_manager.c' || echo '$(srcdir)/'`credentials/credential_manager.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/credential_manager.Tpo $(DEPDIR)/credential_manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/credential_manager.c' object='credential_manager.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o credential_manager.o `test -f 'credentials/credential_manager.c' || echo '$(srcdir)/'`credentials/credential_manager.c
+
+credential_manager.obj: credentials/credential_manager.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT credential_manager.obj -MD -MP -MF $(DEPDIR)/credential_manager.Tpo -c -o credential_manager.obj `if test -f 'credentials/credential_manager.c'; then $(CYGPATH_W) 'credentials/credential_manager.c'; else $(CYGPATH_W) '$(srcdir)/credentials/credential_manager.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/credential_manager.Tpo $(DEPDIR)/credential_manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/credential_manager.c' object='credential_manager.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o credential_manager.obj `if test -f 'credentials/credential_manager.c'; then $(CYGPATH_W) 'credentials/credential_manager.c'; else $(CYGPATH_W) '$(srcdir)/credentials/credential_manager.c'; fi`
+
+auth_info.o: credentials/auth_info.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_info.o -MD -MP -MF $(DEPDIR)/auth_info.Tpo -c -o auth_info.o `test -f 'credentials/auth_info.c' || echo '$(srcdir)/'`credentials/auth_info.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_info.Tpo $(DEPDIR)/auth_info.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/auth_info.c' object='auth_info.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_info.o `test -f 'credentials/auth_info.c' || echo '$(srcdir)/'`credentials/auth_info.c
+
+auth_info.obj: credentials/auth_info.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_info.obj -MD -MP -MF $(DEPDIR)/auth_info.Tpo -c -o auth_info.obj `if test -f 'credentials/auth_info.c'; then $(CYGPATH_W) 'credentials/auth_info.c'; else $(CYGPATH_W) '$(srcdir)/credentials/auth_info.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_info.Tpo $(DEPDIR)/auth_info.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/auth_info.c' object='auth_info.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_info.obj `if test -f 'credentials/auth_info.c'; then $(CYGPATH_W) 'credentials/auth_info.c'; else $(CYGPATH_W) '$(srcdir)/credentials/auth_info.c'; fi`
+
+auth_info_wrapper.o: credentials/sets/auth_info_wrapper.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_info_wrapper.o -MD -MP -MF $(DEPDIR)/auth_info_wrapper.Tpo -c -o auth_info_wrapper.o `test -f 'credentials/sets/auth_info_wrapper.c' || echo '$(srcdir)/'`credentials/sets/auth_info_wrapper.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_info_wrapper.Tpo $(DEPDIR)/auth_info_wrapper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/sets/auth_info_wrapper.c' object='auth_info_wrapper.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_info_wrapper.o `test -f 'credentials/sets/auth_info_wrapper.c' || echo '$(srcdir)/'`credentials/sets/auth_info_wrapper.c
+
+auth_info_wrapper.obj: credentials/sets/auth_info_wrapper.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_info_wrapper.obj -MD -MP -MF $(DEPDIR)/auth_info_wrapper.Tpo -c -o auth_info_wrapper.obj `if test -f 'credentials/sets/auth_info_wrapper.c'; then $(CYGPATH_W) 'credentials/sets/auth_info_wrapper.c'; else $(CYGPATH_W) '$(srcdir)/credentials/sets/auth_info_wrapper.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_info_wrapper.Tpo $(DEPDIR)/auth_info_wrapper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/sets/auth_info_wrapper.c' object='auth_info_wrapper.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_info_wrapper.obj `if test -f 'credentials/sets/auth_info_wrapper.c'; then $(CYGPATH_W) 'credentials/sets/auth_info_wrapper.c'; else $(CYGPATH_W) '$(srcdir)/credentials/sets/auth_info_wrapper.c'; fi`
+
+ocsp_response_wrapper.o: credentials/sets/ocsp_response_wrapper.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ocsp_response_wrapper.o -MD -MP -MF $(DEPDIR)/ocsp_response_wrapper.Tpo -c -o ocsp_response_wrapper.o `test -f 'credentials/sets/ocsp_response_wrapper.c' || echo '$(srcdir)/'`credentials/sets/ocsp_response_wrapper.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ocsp_response_wrapper.Tpo $(DEPDIR)/ocsp_response_wrapper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/sets/ocsp_response_wrapper.c' object='ocsp_response_wrapper.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ocsp_response_wrapper.o `test -f 'credentials/sets/ocsp_response_wrapper.c' || echo '$(srcdir)/'`credentials/sets/ocsp_response_wrapper.c
+
+ocsp_response_wrapper.obj: credentials/sets/ocsp_response_wrapper.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ocsp_response_wrapper.obj -MD -MP -MF $(DEPDIR)/ocsp_response_wrapper.Tpo -c -o ocsp_response_wrapper.obj `if test -f 'credentials/sets/ocsp_response_wrapper.c'; then $(CYGPATH_W) 'credentials/sets/ocsp_response_wrapper.c'; else $(CYGPATH_W) '$(srcdir)/credentials/sets/ocsp_response_wrapper.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ocsp_response_wrapper.Tpo $(DEPDIR)/ocsp_response_wrapper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/sets/ocsp_response_wrapper.c' object='ocsp_response_wrapper.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ocsp_response_wrapper.obj `if test -f 'credentials/sets/ocsp_response_wrapper.c'; then $(CYGPATH_W) 'credentials/sets/ocsp_response_wrapper.c'; else $(CYGPATH_W) '$(srcdir)/credentials/sets/ocsp_response_wrapper.c'; fi`
+
+cert_cache.o: credentials/sets/cert_cache.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cert_cache.o -MD -MP -MF $(DEPDIR)/cert_cache.Tpo -c -o cert_cache.o `test -f 'credentials/sets/cert_cache.c' || echo '$(srcdir)/'`credentials/sets/cert_cache.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cert_cache.Tpo $(DEPDIR)/cert_cache.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/sets/cert_cache.c' object='cert_cache.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cert_cache.o `test -f 'credentials/sets/cert_cache.c' || echo '$(srcdir)/'`credentials/sets/cert_cache.c
+
+cert_cache.obj: credentials/sets/cert_cache.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cert_cache.obj -MD -MP -MF $(DEPDIR)/cert_cache.Tpo -c -o cert_cache.obj `if test -f 'credentials/sets/cert_cache.c'; then $(CYGPATH_W) 'credentials/sets/cert_cache.c'; else $(CYGPATH_W) '$(srcdir)/credentials/sets/cert_cache.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cert_cache.Tpo $(DEPDIR)/cert_cache.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/sets/cert_cache.c' object='cert_cache.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cert_cache.obj `if test -f 'credentials/sets/cert_cache.c'; then $(CYGPATH_W) 'credentials/sets/cert_cache.c'; else $(CYGPATH_W) '$(srcdir)/credentials/sets/cert_cache.c'; fi`
+
socket-raw.o: network/socket-raw.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT socket-raw.o -MD -MP -MF $(DEPDIR)/socket-raw.Tpo -c -o socket-raw.o `test -f 'network/socket-raw.c' || echo '$(srcdir)/'`network/socket-raw.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/socket-raw.Tpo $(DEPDIR)/socket-raw.Po
@@ -2255,19 +2038,19 @@ mediation_manager.obj: sa/mediation_manager.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mediation_manager.obj `if test -f 'sa/mediation_manager.c'; then $(CYGPATH_W) 'sa/mediation_manager.c'; else $(CYGPATH_W) '$(srcdir)/sa/mediation_manager.c'; fi`
-ike_p2p.o: sa/tasks/ike_p2p.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_p2p.o -MD -MP -MF $(DEPDIR)/ike_p2p.Tpo -c -o ike_p2p.o `test -f 'sa/tasks/ike_p2p.c' || echo '$(srcdir)/'`sa/tasks/ike_p2p.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_p2p.Tpo $(DEPDIR)/ike_p2p.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_p2p.c' object='ike_p2p.o' libtool=no @AMDEPBACKSLASH@
+ike_me.o: sa/tasks/ike_me.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_me.o -MD -MP -MF $(DEPDIR)/ike_me.Tpo -c -o ike_me.o `test -f 'sa/tasks/ike_me.c' || echo '$(srcdir)/'`sa/tasks/ike_me.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_me.Tpo $(DEPDIR)/ike_me.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_me.c' object='ike_me.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_p2p.o `test -f 'sa/tasks/ike_p2p.c' || echo '$(srcdir)/'`sa/tasks/ike_p2p.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_me.o `test -f 'sa/tasks/ike_me.c' || echo '$(srcdir)/'`sa/tasks/ike_me.c
-ike_p2p.obj: sa/tasks/ike_p2p.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_p2p.obj -MD -MP -MF $(DEPDIR)/ike_p2p.Tpo -c -o ike_p2p.obj `if test -f 'sa/tasks/ike_p2p.c'; then $(CYGPATH_W) 'sa/tasks/ike_p2p.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_p2p.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_p2p.Tpo $(DEPDIR)/ike_p2p.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_p2p.c' object='ike_p2p.obj' libtool=no @AMDEPBACKSLASH@
+ike_me.obj: sa/tasks/ike_me.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_me.obj -MD -MP -MF $(DEPDIR)/ike_me.Tpo -c -o ike_me.obj `if test -f 'sa/tasks/ike_me.c'; then $(CYGPATH_W) 'sa/tasks/ike_me.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_me.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_me.Tpo $(DEPDIR)/ike_me.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_me.c' object='ike_me.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_p2p.obj `if test -f 'sa/tasks/ike_p2p.c'; then $(CYGPATH_W) 'sa/tasks/ike_p2p.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_p2p.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_me.obj `if test -f 'sa/tasks/ike_me.c'; then $(CYGPATH_W) 'sa/tasks/ike_me.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_me.c'; fi`
mostlyclean-libtool:
-rm -f *.lo
@@ -2275,42 +2058,124 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
- 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; } \
- END { for (i in files) print i; }'`; \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
@@ -2349,22 +2214,40 @@ distdir: $(DISTFILES)
|| exit 1; \
fi; \
done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
-installdirs:
- for dir in "$(DESTDIR)$(backenddir)" "$(DESTDIR)$(eapdir)" "$(DESTDIR)$(interfacedir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(ipsecdir)"; do \
+check: check-recursive
+all-am: Makefile $(PROGRAMS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(ipsecdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-installcheck: installcheck-am
+installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
@@ -2380,91 +2263,83 @@ distclean-generic:
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
+clean: clean-recursive
-clean-am: clean-backendLTLIBRARIES clean-eapLTLIBRARIES clean-generic \
- clean-interfaceLTLIBRARIES clean-ipsecPROGRAMS clean-libtool \
- clean-pluginLTLIBRARIES mostlyclean-am
+clean-am: clean-generic clean-ipsecPROGRAMS clean-libtool \
+ mostlyclean-am
-distclean: distclean-am
+distclean: distclean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
-dvi: dvi-am
+dvi: dvi-recursive
dvi-am:
-html: html-am
+html: html-recursive
-info: info-am
+info: info-recursive
info-am:
-install-data-am: install-backendLTLIBRARIES install-eapLTLIBRARIES \
- install-interfaceLTLIBRARIES install-ipsecPROGRAMS \
- install-pluginLTLIBRARIES
+install-data-am: install-ipsecPROGRAMS
-install-dvi: install-dvi-am
+install-dvi: install-dvi-recursive
install-exec-am:
-install-html: install-html-am
+install-html: install-html-recursive
-install-info: install-info-am
+install-info: install-info-recursive
install-man:
-install-pdf: install-pdf-am
+install-pdf: install-pdf-recursive
-install-ps: install-ps-am
+install-ps: install-ps-recursive
installcheck-am:
-maintainer-clean: maintainer-clean-am
+maintainer-clean: maintainer-clean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
-mostlyclean: mostlyclean-am
+mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
-pdf: pdf-am
+pdf: pdf-recursive
pdf-am:
-ps: ps-am
+ps: ps-recursive
ps-am:
-uninstall-am: uninstall-backendLTLIBRARIES uninstall-eapLTLIBRARIES \
- uninstall-interfaceLTLIBRARIES uninstall-ipsecPROGRAMS \
- uninstall-pluginLTLIBRARIES
+uninstall-am: uninstall-ipsecPROGRAMS
-.MAKE: install-am install-strip
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
+ install-strip
-.PHONY: CTAGS GTAGS all all-am check check-am clean \
- clean-backendLTLIBRARIES clean-eapLTLIBRARIES clean-generic \
- clean-interfaceLTLIBRARIES clean-ipsecPROGRAMS clean-libtool \
- 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-backendLTLIBRARIES install-data install-data-am \
- install-dvi install-dvi-am install-eapLTLIBRARIES install-exec \
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic \
+ clean-ipsecPROGRAMS clean-libtool ctags ctags-recursive \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
- install-info-am install-interfaceLTLIBRARIES \
- install-ipsecPROGRAMS install-man install-pdf install-pdf-am \
- install-pluginLTLIBRARIES install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
+ install-info-am install-ipsecPROGRAMS install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am \
- uninstall-backendLTLIBRARIES uninstall-eapLTLIBRARIES \
- uninstall-interfaceLTLIBRARIES uninstall-ipsecPROGRAMS \
- uninstall-pluginLTLIBRARIES
+ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-ipsecPROGRAMS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c
index e53ac43ce..1b12f8735 100644
--- a/src/charon/bus/bus.c
+++ b/src/charon/bus/bus.c
@@ -1,10 +1,3 @@
-/**
- * @file bus.c
- *
- * @brief Implementation of bus_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: bus.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "bus.h"
@@ -25,6 +20,7 @@
#include <pthread.h>
#include <daemon.h>
+#include <utils/mutex.h>
ENUM(signal_names, SIG_ANY, SIG_MAX,
/** should not get printed */
@@ -72,9 +68,9 @@ struct private_bus_t {
linked_list_t *listeners;
/**
- * mutex to synchronize active listeners
+ * mutex to synchronize active listeners, recursively
*/
- pthread_mutex_t mutex;
+ mutex_t *mutex;
/**
* Thread local storage for a unique, simple thread ID
@@ -107,7 +103,7 @@ struct entry_t {
/**
* condvar where active listeners wait
*/
- pthread_cond_t cond;
+ condvar_t *condvar;
};
/**
@@ -119,12 +115,21 @@ static entry_t *entry_create(bus_listener_t *listener, bool blocker)
this->listener = listener;
this->blocker = blocker;
- pthread_cond_init(&this->cond, NULL);
+ this->condvar = condvar_create(CONDVAR_DEFAULT);
return this;
}
/**
+ * destroy an entry_t
+ */
+static void entry_destroy(entry_t *entry)
+{
+ entry->condvar->destroy(entry->condvar);
+ free(entry);
+}
+
+/**
* Get a unique thread number for a calling thread. Since
* pthread_self returns large and ugly numbers, use this function
* for logging; these numbers are incremental starting at 1
@@ -151,9 +156,9 @@ static int get_thread_number(private_bus_t *this)
*/
static void add_listener(private_bus_t *this, bus_listener_t *listener)
{
- pthread_mutex_lock(&this->mutex);
+ this->mutex->lock(this->mutex);
this->listeners->insert_last(this->listeners, entry_create(listener, FALSE));
- pthread_mutex_unlock(&this->mutex);
+ this->mutex->unlock(this->mutex);
}
/**
@@ -164,19 +169,19 @@ static void remove_listener(private_bus_t *this, bus_listener_t *listener)
iterator_t *iterator;
entry_t *entry;
- pthread_mutex_lock(&this->mutex);
+ this->mutex->lock(this->mutex);
iterator = this->listeners->create_iterator(this->listeners, TRUE);
while (iterator->iterate(iterator, (void**)&entry))
{
if (entry->listener == listener)
{
iterator->remove(iterator);
- free(entry);
+ entry_destroy(entry);
break;
}
}
iterator->destroy(iterator);
- pthread_mutex_unlock(&this->mutex);
+ this->mutex->unlock(this->mutex);
}
typedef struct cleanup_data_t cleanup_data_t;
@@ -205,7 +210,7 @@ static void listener_cleanup(cleanup_data_t *data)
if (entry == data->entry)
{
iterator->remove(iterator);
- free(entry);
+ entry_destroy(entry);
break;
}
}
@@ -223,21 +228,21 @@ static void listen_(private_bus_t *this, bus_listener_t *listener, job_t *job)
data.this = this;
data.entry = entry_create(listener, TRUE);
- pthread_mutex_lock(&this->mutex);
+ this->mutex->lock(this->mutex);
this->listeners->insert_last(this->listeners, data.entry);
charon->processor->queue_job(charon->processor, job);
- pthread_cleanup_push((void*)pthread_mutex_unlock, &this->mutex);
+ pthread_cleanup_push((void*)this->mutex->unlock, this->mutex);
pthread_cleanup_push((void*)listener_cleanup, &data);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
while (data.entry->blocker)
{
- pthread_cond_wait(&data.entry->cond, &this->mutex);
+ data.entry->condvar->wait(data.entry->condvar, this->mutex);
}
pthread_setcancelstate(old, NULL);
pthread_cleanup_pop(FALSE);
/* unlock mutex */
pthread_cleanup_pop(TRUE);
- free(data.entry);
+ entry_destroy(data.entry);
}
/**
@@ -248,6 +253,7 @@ static void set_sa(private_bus_t *this, ike_sa_t *ike_sa)
pthread_setspecific(this->thread_sa, ike_sa);
}
+
/**
* Implementation of bus_t.vsignal.
*/
@@ -259,7 +265,7 @@ static void vsignal(private_bus_t *this, signal_t signal, level_t level,
ike_sa_t *ike_sa;
long thread;
- pthread_mutex_lock(&this->mutex);
+ this->mutex->lock(this->mutex);
ike_sa = pthread_getspecific(this->thread_sa);
thread = get_thread_number(this);
@@ -275,18 +281,18 @@ static void vsignal(private_bus_t *this, signal_t signal, level_t level,
if (entry->blocker)
{
entry->blocker = FALSE;
- pthread_cond_signal(&entry->cond);
+ entry->condvar->signal(entry->condvar);
}
else
{
- free(entry);
+ entry_destroy(entry);
}
}
va_end(args_copy);
}
iterator->destroy(iterator);
- pthread_mutex_unlock(&this->mutex);
+ this->mutex->unlock(this->mutex);
}
/**
@@ -307,7 +313,8 @@ static void signal_(private_bus_t *this, signal_t signal, level_t level,
*/
static void destroy(private_bus_t *this)
{
- this->listeners->destroy_function(this->listeners, free);
+ this->mutex->destroy(this->mutex);
+ this->listeners->destroy_function(this->listeners, (void*)entry_destroy);
free(this);
}
@@ -327,7 +334,7 @@ bus_t *bus_create()
this->public.destroy = (void(*)(bus_t*)) destroy;
this->listeners = linked_list_create();
- pthread_mutex_init(&this->mutex, NULL);
+ this->mutex = mutex_create(MUTEX_DEFAULT);
pthread_key_create(&this->thread_id, NULL);
pthread_key_create(&this->thread_sa, NULL);
diff --git a/src/charon/bus/bus.h b/src/charon/bus/bus.h
index f71018444..7fa2c42bc 100644
--- a/src/charon/bus/bus.h
+++ b/src/charon/bus/bus.h
@@ -1,10 +1,3 @@
-/**
- * @file bus.h
- *
- * @brief Interface of bus_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: bus.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup bus bus
+ * @{ @ingroup charon
*/
#ifndef BUS_H_
@@ -36,7 +36,7 @@ typedef struct bus_t bus_t;
/**
- * @brief signals emitted by the daemon.
+ * signals emitted by the daemon.
*
* Signaling is for different purporses. First, it allows debugging via
* "debugging signal messages", sencondly, it allows to follow certain
@@ -52,8 +52,6 @@ typedef struct bus_t bus_t;
* Debug signal betwee a START and a SUCCESS/FAILED belongs to that operation
* if the IKE_SA is the same. The thread may change, as multiple threads
* may be involved in a complex scenario.
- *
- * @ingroup bus
*/
enum signal_t {
/** pseudo signal, representing any other signal */
@@ -157,7 +155,7 @@ enum level_t {
#if DEBUG_LEVEL >= 1
/**
- * @brief Log a debug message via the signal bus.
+ * Log a debug message via the signal bus.
*
* @param signal signal_t signal description
* @param format printf() style format string
@@ -189,7 +187,7 @@ enum level_t {
#endif /* DBG4 */
/**
- * @brief Raise a signal for an occured event.
+ * Raise a signal for an occured event.
*
* @param sig signal_t signal description
* @param format printf() style format string
@@ -198,7 +196,7 @@ enum level_t {
#define SIG(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_0, format, ##__VA_ARGS__)
/**
- * @brief Get the type of a signal.
+ * Get the type of a signal.
*
* A signal may be a debugging signal with a specific context. They have
* a level specific for their context > 0. All audit signals use the
@@ -211,17 +209,15 @@ enum level_t {
/**
- * @brief Interface for registering at the signal bus.
+ * Interface for registering at the signal bus.
*
* To receive signals from the bus, the client implementing the
* bus_listener_t interface registers itself at the signal bus.
- *
- * @ingroup bus
*/
struct bus_listener_t {
/**
- * @brief Send a signal to a bus listener.
+ * Send a signal to a bus listener.
*
* A numerical identification for the thread is included, as the
* associated IKE_SA, if any. Signal specifies the type of
@@ -231,8 +227,10 @@ struct bus_listener_t {
* a "..." parameters to functions is not (cleanly) possible.
* The implementing signal function returns TRUE to stay registered
* to the bus, or FALSE to unregister itself.
+ * You should not call bus_t.signal() inside of a registered listener,
+ * as it WILL call itself recursively. If you do so, make shure to
+ * avoid infinite recursion. Watch your stack!
*
- * @param this listener
* @param singal kind of the signal (up, down, rekeyed, ...)
* @param level verbosity level of the signal
* @param thread ID of the thread raised this signal
@@ -246,40 +244,36 @@ struct bus_listener_t {
};
/**
- * @brief Signal bus which sends signals to registered listeners.
+ * Signal bus which sends signals to registered listeners.
*
* The signal bus is not much more than a multiplexer. A listener interested
* in receiving event signals registers at the bus. Any signals sent to
* are delivered to all registered listeners.
* To deliver signals to threads, the blocking listen() call may be used
* to wait for a signal.
- *
- * @ingroup bus
*/
struct bus_t {
/**
- * @brief Register a listener to the bus.
+ * Register a listener to the bus.
*
* A registered listener receives all signals which are sent to the bus.
* The listener is passive; the thread which emitted the signal
* processes the listener routine.
*
- * @param this bus
* @param listener listener to register.
*/
void (*add_listener) (bus_t *this, bus_listener_t *listener);
/**
- * @brief Unregister a listener from the bus.
+ * Unregister a listener from the bus.
*
- * @param this bus
* @param listener listener to unregister.
*/
void (*remove_listener) (bus_t *this, bus_listener_t *listener);
/**
- * @brief Register a listener and block the calling thread.
+ * Register a listener and block the calling thread.
*
* This call registers a listener and blocks the calling thread until
* its listeners function returns FALSE. This allows to wait for certain
@@ -287,14 +281,13 @@ struct bus_t {
* registered, this allows to listen on events we initiate with the job
* without missing any signals.
*
- * @param this bus
* @param listener listener to register
* @param job job to execute asynchronously when registered, or NULL
*/
void (*listen)(bus_t *this, bus_listener_t *listener, job_t *job);
/**
- * @brief Set the IKE_SA the calling thread is using.
+ * Set the IKE_SA the calling thread is using.
*
* To associate an received signal to an IKE_SA without passing it as
* parameter each time, the thread registers it's used IKE_SA each
@@ -302,13 +295,12 @@ struct bus_t {
* the IKE_SA (by passing NULL). This IKE_SA is stored per-thread, so each
* thread has one IKE_SA registered (or not).
*
- * @param this bus
* @param ike_sa ike_sa to register, or NULL to unregister
*/
void (*set_sa) (bus_t *this, ike_sa_t *ike_sa);
/**
- * @brief Send a signal to the bus.
+ * Send a signal to the bus.
*
* The signal specifies the type of the event occured. The format string
* specifies an additional informational or error message with a
@@ -316,7 +308,6 @@ struct bus_t {
* Some useful macros are available to shorten this call.
* @see SIG(), DBG1()
*
- * @param this bus
* @param singal kind of the signal (up, down, rekeyed, ...)
* @param level verbosity level of the signal
* @param format printf() style format string
@@ -325,7 +316,7 @@ struct bus_t {
void (*signal) (bus_t *this, signal_t signal, level_t level, char* format, ...);
/**
- * @brief Send a signal to the bus using va_list arguments.
+ * Send a signal to the bus using va_list arguments.
*
* Same as bus_t.signal(), but uses va_list argument list.
*
@@ -333,7 +324,6 @@ struct bus_t {
* called extensively and therefore shouldn't allocate heap memory or
* do other expensive tasks!
*
- * @param this bus
* @param singal kind of the signal (up, down, rekeyed, ...)
* @param level verbosity level of the signal
* @param format printf() style format string
@@ -342,20 +332,16 @@ struct bus_t {
void (*vsignal) (bus_t *this, signal_t signal, level_t level, char* format, va_list args);
/**
- * @brief Destroy the signal bus.
- *
- * @param this bus to destroy
+ * Destroy the signal bus.
*/
void (*destroy) (bus_t *this);
};
/**
- * @brief Create the signal bus which multiplexes signals to its listeners.
+ * Create the signal bus which multiplexes signals to its listeners.
*
* @return signal bus instance
- *
- * @ingroup bus
*/
bus_t *bus_create();
-#endif /* BUS_H_ */
+#endif /* BUS_H_ @} */
diff --git a/src/charon/bus/listeners/file_logger.c b/src/charon/bus/listeners/file_logger.c
index 14f9f72cf..f89da8529 100644
--- a/src/charon/bus/listeners/file_logger.c
+++ b/src/charon/bus/listeners/file_logger.c
@@ -1,10 +1,3 @@
-/**
- * @file file_logger.c
- *
- * @brief Implementation of file_logger_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: file_logger.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdio.h>
diff --git a/src/charon/bus/listeners/file_logger.h b/src/charon/bus/listeners/file_logger.h
index d67daba25..86b79c002 100644
--- a/src/charon/bus/listeners/file_logger.h
+++ b/src/charon/bus/listeners/file_logger.h
@@ -1,10 +1,3 @@
-/**
- * @file file_logger.h
- *
- * @brief Interface of file_logger_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: file_logger.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup file_logger file_logger
+ * @{ @ingroup listeners
*/
#ifndef FILE_LOGGER_H_
@@ -28,12 +28,7 @@ typedef struct file_logger_t file_logger_t;
#include <bus/bus.h>
/**
- * @brief Logger to files which implements bus_listener_t.
- *
- * @b Constructors:
- * - file_logger_create()
- *
- * @ingroup listeners
+ * Logger to files which implements bus_listener_t.
*/
struct file_logger_t {
@@ -43,31 +38,25 @@ struct file_logger_t {
bus_listener_t listener;
/**
- * @brief Set the loglevel for a signal type.
+ * Set the loglevel for a signal type.
*
- * @param this stream_logger_t object
* @param singal type of signal
* @param level max level to log (0..4)
*/
void (*set_level) (file_logger_t *this, signal_t signal, level_t level);
/**
- * @brief Destroys a file_logger_t object.
- *
- * @param this file_logger_t object
+ * Destroys a file_logger_t object.
*/
void (*destroy) (file_logger_t *this);
};
/**
- * @brief Constructor to create a file_logger_t object.
+ * Constructor to create a file_logger_t object.
*
* @param out FILE to write to
* @return file_logger_t object
- *
- * @ingroup listeners
*/
file_logger_t *file_logger_create(FILE *out);
-
-#endif /* FILE_LOGGER_H_ */
+#endif /* FILE_LOGGER_H_ @} */
diff --git a/src/charon/bus/listeners/sys_logger.c b/src/charon/bus/listeners/sys_logger.c
index d26d14dc0..900fa3aa6 100644
--- a/src/charon/bus/listeners/sys_logger.c
+++ b/src/charon/bus/listeners/sys_logger.c
@@ -1,10 +1,3 @@
-/**
- * @file sys_logger.c
- *
- * @brief Implementation of sys_logger_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: sys_logger.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdio.h>
diff --git a/src/charon/bus/listeners/sys_logger.h b/src/charon/bus/listeners/sys_logger.h
index 091217313..0aade375a 100644
--- a/src/charon/bus/listeners/sys_logger.h
+++ b/src/charon/bus/listeners/sys_logger.h
@@ -1,10 +1,3 @@
-/**
- * @file sys_logger.h
- *
- * @brief Interface of sys_logger_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: sys_logger.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup sys_logger sys_logger
+ * @{ @ingroup listeners
*/
#ifndef SYS_LOGGER_H_
@@ -30,12 +30,7 @@ typedef struct sys_logger_t sys_logger_t;
#include <bus/bus.h>
/**
- * @brief Logger for syslog which implements bus_listener_t.
- *
- * @b Constructors:
- * - sys_logger_create()
- *
- * @ingroup listeners
+ * Logger for syslog which implements bus_listener_t.
*/
struct sys_logger_t {
@@ -45,31 +40,25 @@ struct sys_logger_t {
bus_listener_t listener;
/**
- * @brief Set the loglevel for a signal type.
+ * Set the loglevel for a signal type.
*
- * @param this stream_logger_t object
* @param singal type of signal
* @param level max level to log
*/
void (*set_level) (sys_logger_t *this, signal_t signal, level_t level);
/**
- * @brief Destroys a sys_logger_t object.
- *
- * @param this sys_logger_t object
+ * Destroys a sys_logger_t object.
*/
void (*destroy) (sys_logger_t *this);
};
/**
- * @brief Constructor to create a sys_logger_t object.
+ * Constructor to create a sys_logger_t object.
*
* @param facility syslog facility to use
* @return sys_logger_t object
- *
- * @ingroup listeners
*/
sys_logger_t *sys_logger_create(int facility);
-
-#endif /* SYS_LOGGER_H_ */
+#endif /* SYS_LOGGER_H_ @} */
diff --git a/src/charon/config/attributes/attribute_manager.c b/src/charon/config/attributes/attribute_manager.c
new file mode 100644
index 000000000..0ec84c7be
--- /dev/null
+++ b/src/charon/config/attributes/attribute_manager.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "attribute_manager.h"
+
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+
+typedef struct private_attribute_manager_t private_attribute_manager_t;
+
+/**
+ * private data of attribute_manager
+ */
+struct private_attribute_manager_t {
+
+ /**
+ * public functions
+ */
+ attribute_manager_t public;
+
+ /**
+ * list of registered providers
+ */
+ linked_list_t *providers;
+
+ /**
+ * mutex to lock provider list
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * Implementation of attribute_manager_t.acquire_address.
+ */
+static host_t* acquire_address(private_attribute_manager_t *this,
+ char *pool, identification_t *id,
+ auth_info_t *auth, host_t *requested)
+{
+ enumerator_t *enumerator;
+ attribute_provider_t *current;
+ host_t *host = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->providers->create_enumerator(this->providers);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ host = current->acquire_address(current, pool, id, auth, requested);
+ if (host)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+
+ return host;
+}
+
+/**
+ * Implementation of attribute_manager_t.release_address.
+ */
+static void release_address(private_attribute_manager_t *this,
+ char *pool, host_t *address)
+{
+ enumerator_t *enumerator;
+ attribute_provider_t *current;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->providers->create_enumerator(this->providers);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (current->release_address(current, pool, address))
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of attribute_manager_t.add_provider.
+ */
+static void add_provider(private_attribute_manager_t *this,
+ attribute_provider_t *provider)
+{
+ this->mutex->lock(this->mutex);
+ this->providers->insert_last(this->providers, provider);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of attribute_manager_t.remove_provider.
+ */
+static void remove_provider(private_attribute_manager_t *this,
+ attribute_provider_t *provider)
+{
+ this->mutex->lock(this->mutex);
+ this->providers->remove(this->providers, provider, NULL);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of attribute_manager_t.destroy
+ */
+static void destroy(private_attribute_manager_t *this)
+{
+ this->providers->destroy(this->providers);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+attribute_manager_t *attribute_manager_create()
+{
+ private_attribute_manager_t *this = malloc_thing(private_attribute_manager_t);
+
+ this->public.acquire_address = (host_t*(*)(attribute_manager_t*, char*, identification_t*,auth_info_t*,host_t*))acquire_address;
+ this->public.release_address = (void(*)(attribute_manager_t*, char *, host_t*))release_address;
+ this->public.add_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))add_provider;
+ this->public.remove_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))remove_provider;
+ this->public.destroy = (void(*)(attribute_manager_t*))destroy;
+
+ this->providers = linked_list_create();
+ this->mutex = mutex_create(MUTEX_DEFAULT);
+
+ return &this->public;
+}
+
diff --git a/src/charon/config/attributes/attribute_manager.h b/src/charon/config/attributes/attribute_manager.h
new file mode 100644
index 000000000..540e054fd
--- /dev/null
+++ b/src/charon/config/attributes/attribute_manager.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup attribute_manager attribute_manager
+ * @{ @ingroup attributes
+ */
+
+#ifndef ATTRIBUTE_MANAGER_H_
+#define ATTRIBUTE_MANAGER_H_
+
+#include <config/attributes/attribute_provider.h>
+
+typedef struct attribute_manager_t attribute_manager_t;
+
+/**
+ * Provide configuration attributes to include in CFG Payloads.
+ */
+struct attribute_manager_t {
+
+ /**
+ * Acquire a virtual IP address to assign to a peer.
+ *
+ * @param pool pool name to acquire address from
+ * @param id peer identity to get address for
+ * @param auth authorization infos of peer
+ * @param requested IP in configuration request
+ * @return allocated address, NULL to serve none
+ */
+ host_t* (*acquire_address)(attribute_manager_t *this,
+ char *pool, identification_t *id,
+ auth_info_t *auth, host_t *requested);
+
+ /**
+ * Release a previously acquired address.
+ *
+ * @param pool pool name from which the address was acquired
+ * @param address address to release
+ */
+ void (*release_address)(attribute_manager_t *this,
+ char *pool, host_t *address);
+
+ /**
+ * Register an attribute provider to the manager.
+ *
+ * @param provider attribute provider to register
+ */
+ void (*add_provider)(attribute_manager_t *this,
+ attribute_provider_t *provider);
+ /**
+ * Unregister an attribute provider from the manager.
+ *
+ * @param provider attribute provider to unregister
+ */
+ void (*remove_provider)(attribute_manager_t *this,
+ attribute_provider_t *provider);
+ /**
+ * Destroy a attribute_manager instance.
+ */
+ void (*destroy)(attribute_manager_t *this);
+};
+
+/**
+ * Create a attribute_manager instance.
+ */
+attribute_manager_t *attribute_manager_create();
+
+#endif /* ATTRIBUTE_MANAGER_H_ @}*/
diff --git a/src/charon/config/attributes/attribute_provider.h b/src/charon/config/attributes/attribute_provider.h
new file mode 100644
index 000000000..1712bd188
--- /dev/null
+++ b/src/charon/config/attributes/attribute_provider.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup attribute_provider attribute_provider
+ * @{ @ingroup attributes
+ */
+
+#ifndef ATTRIBUTE_PROVIDER_H_
+#define ATTRIBUTE_PROVIDER_H_
+
+#include <library.h>
+#include <utils/host.h>
+#include <credentials/auth_info.h>
+
+typedef struct attribute_provider_t attribute_provider_t;
+
+/**
+ * Interface to provide attributes to peers through attribute manager.
+ */
+struct attribute_provider_t {
+
+ /**
+ * Acquire a virtual IP address to assign to a peer.
+ *
+ * @param pool name of the pool to acquire address from
+ * @param id peer ID
+ * @param auth authorization infos
+ * @param requested IP in configuration request
+ * @return allocated address, NULL to serve none
+ */
+ host_t* (*acquire_address)(attribute_provider_t *this,
+ char *pool, identification_t *id,
+ auth_info_t *auth, host_t *requested);
+ /**
+ * Release a previously acquired address.
+ *
+ * @param pool name of the pool this address was acquired from
+ * @param address address to release
+ * @return TRUE if the address has been released by the provider
+ */
+ bool (*release_address)(attribute_provider_t *this,
+ char *pool, host_t *address);
+};
+
+#endif /* ATTRIBUTE_PROVIDER_H_ @}*/
diff --git a/src/charon/config/backend.h b/src/charon/config/backend.h
new file mode 100644
index 000000000..ec2c481bd
--- /dev/null
+++ b/src/charon/config/backend.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: backend.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup backend backend
+ * @{ @ingroup config
+ */
+
+#ifndef BACKEND_H_
+#define BACKEND_H_
+
+typedef struct backend_t backend_t;
+
+#include <library.h>
+#include <config/ike_cfg.h>
+#include <config/peer_cfg.h>
+#include <credentials/auth_info.h>
+#include <utils/linked_list.h>
+
+/**
+ * The interface for a configuration backend.
+ *
+ * A configuration backend is loaded into the backend_manager. It does the actual
+ * configuration lookup for the method it implements. See backend_manager_t for
+ * more information.
+ */
+struct backend_t {
+
+ /**
+ * Create an enumerator over all IKE configs matching two hosts.
+ *
+ * Hosts may be NULL to get all.
+ *
+ * @param me address of local host
+ * @param other address of remote host
+ * @return enumerator over ike_cfg_t's
+ */
+ enumerator_t* (*create_ike_cfg_enumerator)(backend_t *this,
+ host_t *me, host_t *other);
+ /**
+ * Create an enumerator over all Peer configs matching two IDs.
+ *
+ * IDs may be NULL to get all.
+ *
+ * @param me identity of ourself
+ * @param other identity of remote host
+ * @return enumerator over peer_cfg_t
+ */
+ enumerator_t* (*create_peer_cfg_enumerator)(backend_t *this,
+ identification_t *me,
+ identification_t *other);
+ /**
+ * Get a peer_cfg identified by it's name, or a name of its child.
+ *
+ * @param name name of peer/child cfg
+ * @return matching peer_config, or NULL if none found
+ */
+ peer_cfg_t *(*get_peer_cfg_by_name)(backend_t *this, char *name);
+};
+
+#endif /* BACKEND_H_ @} */
diff --git a/src/charon/config/backend_manager.c b/src/charon/config/backend_manager.c
index b2104acea..d77c05fd7 100644
--- a/src/charon/config/backend_manager.c
+++ b/src/charon/config/backend_manager.c
@@ -1,10 +1,3 @@
-/**
- * @file backend_manager.c
- *
- * @brief Implementation of backend_manager_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,18 +11,18 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: backend_manager.c 4044 2008-06-06 15:05:54Z martin $
*/
#include "backend_manager.h"
#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <dlfcn.h>
+#include <pthread.h>
#include <daemon.h>
#include <utils/linked_list.h>
-#include <config/backends/writeable_backend.h>
+#include <utils/mutex.h>
typedef struct private_backend_manager_t private_backend_manager_t;
@@ -50,164 +43,268 @@ struct private_backend_manager_t {
linked_list_t *backends;
/**
- * Additional list of writable backends.
+ * locking mutex
*/
- linked_list_t *writeable;
-
- /**
- * List of dlopen() handles we used to open backends
- */
- linked_list_t *handles;
+ mutex_t *mutex;
};
/**
- * implements backend_manager_t.get_ike_cfg.
+ * data to pass nested IKE enumerator
*/
-static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
- host_t *my_host, host_t *other_host)
+typedef struct {
+ private_backend_manager_t *this;
+ host_t *me;
+ host_t *other;
+} ike_data_t;
+
+/**
+ * data to pass nested peer enumerator
+ */
+typedef struct {
+ private_backend_manager_t *this;
+ identification_t *me;
+ identification_t *other;
+} peer_data_t;
+
+/**
+ * destroy IKE enumerator data and unlock list
+ */
+static void ike_enum_destroy(ike_data_t *data)
{
- backend_t *backend;
- ike_cfg_t *config = NULL;
- iterator_t *iterator = this->backends->create_iterator(this->backends, TRUE);
- while (config == NULL && iterator->iterate(iterator, (void**)&backend))
- {
- config = backend->get_ike_cfg(backend, my_host, other_host);
- }
- iterator->destroy(iterator);
- return config;
+ data->this->mutex->unlock(data->this->mutex);
+ free(data);
}
/**
- * implements backend_manager_t.get_peer_cfg.
- */
-static peer_cfg_t *get_peer_cfg(private_backend_manager_t *this,
- identification_t *my_id, identification_t *other_id,
- ca_info_t *other_ca_info)
+ * destroy PEER enumerator data and unlock list
+ */
+static void peer_enum_destroy(peer_data_t *data)
{
- backend_t *backend;
- peer_cfg_t *config = NULL;
- iterator_t *iterator = this->backends->create_iterator(this->backends, TRUE);
- while (config == NULL && iterator->iterate(iterator, (void**)&backend))
- {
- config = backend->get_peer_cfg(backend, my_id, other_id, other_ca_info);
- }
- iterator->destroy(iterator);
- return config;
+ data->this->mutex->unlock(data->this->mutex);
+ free(data);
}
/**
- * implements backend_manager_t.get_peer_cfg_by_name.
- */
-static peer_cfg_t *get_peer_cfg_by_name(private_backend_manager_t *this, char *name)
+ * inner enumerator constructor for IKE cfgs
+ */
+static enumerator_t *ike_enum_create(backend_t *backend, ike_data_t *data)
{
- backend_t *backend;
- peer_cfg_t *config = NULL;
- iterator_t *iterator = this->backends->create_iterator(this->backends, TRUE);
- while (config == NULL && iterator->iterate(iterator, (void**)&backend))
- {
- config = backend->get_peer_cfg_by_name(backend, name);
- }
- iterator->destroy(iterator);
- return config;
+ return backend->create_ike_cfg_enumerator(backend, data->me, data->other);
}
/**
- * implements backend_manager_t.add_peer_cfg.
- */
-static void add_peer_cfg(private_backend_manager_t *this, peer_cfg_t *config)
+ * inner enumerator constructor for Peer cfgs
+ */
+static enumerator_t *peer_enum_create(backend_t *backend, peer_data_t *data)
{
- writeable_backend_t *backend;
-
- if (this->writeable->get_first(this->writeable, (void**)&backend) == SUCCESS)
- {
- backend->add_cfg(backend, config);
- }
+ return backend->create_peer_cfg_enumerator(backend, data->me, data->other);
}
-
/**
- * implements backend_manager_t.create_iterator.
- */
-static iterator_t* create_iterator(private_backend_manager_t *this)
+ * inner enumerator constructor for all Peer cfgs
+ */
+static enumerator_t *peer_enum_create_all(backend_t *backend)
{
- writeable_backend_t *backend;
-
- if (this->writeable->get_first(this->writeable, (void**)&backend) == SUCCESS)
- {
- return backend->create_iterator(backend);
- }
- /* give out an empty iterator if we have no writable backend*/
- return this->writeable->create_iterator(this->writeable, TRUE);
+ return backend->create_peer_cfg_enumerator(backend, NULL, NULL);
}
/**
- * load the configuration backend modules
+ * implements backend_manager_t.get_ike_cfg.
*/
-static void load_backends(private_backend_manager_t *this)
+static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
+ host_t *me, host_t *other)
{
- struct dirent* entry;
- DIR* dir;
-
- dir = opendir(IPSEC_BACKENDDIR);
- if (dir == NULL)
- {
- DBG1(DBG_CFG, "error opening backend modules directory "IPSEC_BACKENDDIR);
- return;
- }
+ ike_cfg_t *current, *found = NULL;
+ enumerator_t *enumerator;
+ host_t *my_candidate, *other_candidate;
+ ike_data_t *data;
+ enum {
+ MATCH_NONE = 0x00,
+ MATCH_ANY = 0x01,
+ MATCH_ME = 0x04,
+ MATCH_OTHER = 0x08,
+ } prio, best = MATCH_ANY;
- DBG1(DBG_CFG, "loading backend modules from '"IPSEC_BACKENDDIR"'");
-
- while ((entry = readdir(dir)) != NULL)
+ data = malloc_thing(ike_data_t);
+ data->this = this;
+ data->me = me;
+ data->other = other;
+
+ DBG2(DBG_CFG, "looking for a config for %H...%H", me, other);
+
+ this->mutex->lock(this->mutex);
+ enumerator = enumerator_create_nested(
+ this->backends->create_enumerator(this->backends),
+ (void*)ike_enum_create, data, (void*)ike_enum_destroy);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
- char file[256];
- backend_t *backend;
- backend_constructor_t constructor;
- void *handle;
- char *ending;
-
- snprintf(file, sizeof(file), IPSEC_BACKENDDIR"/%s", entry->d_name);
+ prio = MATCH_NONE;
- ending = entry->d_name + strlen(entry->d_name) - 3;
- if (ending <= entry->d_name || !streq(ending, ".so"))
+ my_candidate = host_create_from_dns(current->get_my_addr(current),
+ me->get_family(me), 0);
+ if (!my_candidate)
{
- /* skip anything which does not look like a library */
- DBG2(DBG_CFG, " skipping %s, doesn't look like a library",
- entry->d_name);
continue;
}
- /* try to load the library */
- handle = dlopen(file, RTLD_LAZY);
- if (handle == NULL)
+ if (my_candidate->ip_equals(my_candidate, me))
{
- DBG1(DBG_CFG, " opening backend module %s failed: %s",
- entry->d_name, dlerror());
- continue;
+ prio += MATCH_ME;
}
- constructor = dlsym(handle, "backend_create");
- if (constructor == NULL)
+ else if (my_candidate->is_anyaddr(my_candidate))
{
- DBG1(DBG_CFG, " backend module %s has no backend_create() "
- "function, skipped", entry->d_name);
- dlclose(handle);
- continue;
+ prio += MATCH_ANY;
}
+ my_candidate->destroy(my_candidate);
- backend = constructor();
- if (backend == NULL)
+ other_candidate = host_create_from_dns(current->get_other_addr(current),
+ other->get_family(other), 0);
+ if (!other_candidate)
{
- DBG1(DBG_CFG, " unable to create instance of backend "
- "module %s, skipped", entry->d_name);
- dlclose(handle);
continue;
}
- DBG1(DBG_CFG, " loaded backend module successfully from %s", entry->d_name);
- this->backends->insert_last(this->backends, backend);
- if (backend->is_writeable(backend))
+ if (other_candidate->ip_equals(other_candidate, other))
+ {
+ prio += MATCH_OTHER;
+ }
+ else if (other_candidate->is_anyaddr(other_candidate))
+ {
+ prio += MATCH_ANY;
+ }
+ other_candidate->destroy(other_candidate);
+
+ DBG2(DBG_CFG, " candidate: %s...%s, prio %d",
+ current->get_my_addr(current), current->get_other_addr(current),
+ prio);
+
+ /* we require at least two MATCH_ANY */
+ if (prio > best)
{
- this->writeable->insert_last(this->writeable, backend);
+ best = prio;
+ DESTROY_IF(found);
+ found = current;
+ found->get_ref(found);
}
- this->handles->insert_last(this->handles, handle);
}
- closedir(dir);
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return found;
+}
+
+
+static enumerator_t *create_peer_cfg_enumerator(private_backend_manager_t *this)
+{
+ this->mutex->lock(this->mutex);
+ return enumerator_create_nested(
+ this->backends->create_enumerator(this->backends),
+ (void*)peer_enum_create_all, this->mutex,
+ (void*)this->mutex->unlock);
+}
+
+/**
+ * implements backend_manager_t.get_peer_cfg.
+ */
+static peer_cfg_t *get_peer_cfg(private_backend_manager_t *this,
+ identification_t *me, identification_t *other,
+ auth_info_t *auth)
+{
+ peer_cfg_t *current, *found = NULL;
+ enumerator_t *enumerator;
+ identification_t *my_candidate, *other_candidate;
+ id_match_t best = ID_MATCH_NONE;
+ peer_data_t *data;
+
+ DBG2(DBG_CFG, "looking for a config for %D...%D", me, other);
+
+ data = malloc_thing(peer_data_t);
+ data->this = this;
+ data->me = me;
+ data->other = other;
+
+ this->mutex->lock(this->mutex);
+ enumerator = enumerator_create_nested(
+ this->backends->create_enumerator(this->backends),
+ (void*)peer_enum_create, data, (void*)peer_enum_destroy);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ id_match_t m1, m2, sum;
+
+ my_candidate = current->get_my_id(current);
+ other_candidate = current->get_other_id(current);
+
+ /* own ID may have wildcards in both, config and request (missing IDr) */
+ m1 = my_candidate->matches(my_candidate, me);
+ if (!m1)
+ {
+ m1 = me->matches(me, my_candidate);
+ }
+ m2 = other->matches(other, other_candidate);
+ sum = m1 + m2;
+
+ if (m1 && m2)
+ {
+ if (auth->complies(auth, current->get_auth(current)))
+ {
+ DBG2(DBG_CFG, " candidate '%s': %D...%D, prio %d",
+ current->get_name(current), my_candidate,
+ other_candidate, sum);
+ if (sum > best)
+ {
+ DESTROY_IF(found);
+ found = current;
+ found->get_ref(found);
+ best = sum;
+ }
+ }
+ }
+ }
+ if (found)
+ {
+ DBG1(DBG_CFG, "found matching config \"%s\": %D...%D, prio %d",
+ found->get_name(found), found->get_my_id(found),
+ found->get_other_id(found), best);
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return found;
+}
+
+/**
+ * implements backend_manager_t.get_peer_cfg_by_name.
+ */
+static peer_cfg_t *get_peer_cfg_by_name(private_backend_manager_t *this, char *name)
+{
+ backend_t *backend;
+ peer_cfg_t *config = NULL;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->backends->create_enumerator(this->backends);
+ while (config == NULL && enumerator->enumerate(enumerator, (void**)&backend))
+ {
+ config = backend->get_peer_cfg_by_name(backend, name);
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return config;
+}
+
+/**
+ * Implementation of backend_manager_t.remove_backend.
+ */
+static void remove_backend(private_backend_manager_t *this, backend_t *backend)
+{
+ this->mutex->lock(this->mutex);
+ this->backends->remove(this->backends, backend, NULL);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of backend_manager_t.add_backend.
+ */
+static void add_backend(private_backend_manager_t *this, backend_t *backend)
+{
+ this->mutex->lock(this->mutex);
+ this->backends->insert_last(this->backends, backend);
+ this->mutex->unlock(this->mutex);
}
/**
@@ -215,9 +312,8 @@ static void load_backends(private_backend_manager_t *this)
*/
static void destroy(private_backend_manager_t *this)
{
- this->backends->destroy_offset(this->backends, offsetof(backend_t, destroy));
- this->writeable->destroy(this->writeable);
- this->handles->destroy_function(this->handles, (void*)dlclose);
+ this->backends->destroy(this->backends);
+ this->mutex->destroy(this->mutex);
free(this);
}
@@ -229,17 +325,15 @@ backend_manager_t *backend_manager_create()
private_backend_manager_t *this = malloc_thing(private_backend_manager_t);
this->public.get_ike_cfg = (ike_cfg_t* (*)(backend_manager_t*, host_t*, host_t*))get_ike_cfg;
- this->public.get_peer_cfg = (peer_cfg_t* (*)(backend_manager_t*,identification_t*,identification_t*,ca_info_t*))get_peer_cfg;
+ this->public.get_peer_cfg = (peer_cfg_t* (*)(backend_manager_t*,identification_t*,identification_t*,auth_info_t*))get_peer_cfg;
this->public.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_manager_t*,char*))get_peer_cfg_by_name;
- this->public.add_peer_cfg = (void (*)(backend_manager_t*,peer_cfg_t*))add_peer_cfg;
- this->public.create_iterator = (iterator_t* (*)(backend_manager_t*))create_iterator;
+ this->public.create_peer_cfg_enumerator = (enumerator_t* (*)(backend_manager_t*))create_peer_cfg_enumerator;
+ this->public.add_backend = (void(*)(backend_manager_t*, backend_t *backend))add_backend;
+ this->public.remove_backend = (void(*)(backend_manager_t*, backend_t *backend))remove_backend;
this->public.destroy = (void (*)(backend_manager_t*))destroy;
this->backends = linked_list_create();
- this->writeable = linked_list_create();
- this->handles = linked_list_create();
-
- load_backends(this);
+ this->mutex = mutex_create(MUTEX_RECURSIVE);
return &this->public;
}
diff --git a/src/charon/config/backend_manager.h b/src/charon/config/backend_manager.h
index 7ca6d660e..6400bd7fd 100644
--- a/src/charon/config/backend_manager.h
+++ b/src/charon/config/backend_manager.h
@@ -1,10 +1,3 @@
-/**
- * @file backend_manager.h
- *
- * @brief Interface backend_manager_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: backend_manager.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup backend_manager backend_manager
+ * @{ @ingroup config
*/
#ifndef BACKEND_MANAGER_H_
@@ -30,20 +30,15 @@ typedef struct backend_manager_t backend_manager_t;
#include <utils/identification.h>
#include <config/ike_cfg.h>
#include <config/peer_cfg.h>
-#include <config/backends/backend.h>
+#include <config/backend.h>
/**
- * @brief A loader and multiplexer to use multiple backends.
+ * A loader and multiplexer to use multiple backends.
*
* Charon allows the use of multiple configuration backends simultaneously. To
* access all this backends by a single call, this class wraps multiple
- * backends behind a single object. It is also responsible for loading
- * the backend modules and cleaning them up.
- * A backend may be writeable or not. All backends implement the backend_t
- * interface, those who are writeable additionally implement the
- * writeable_backend_t interface. Adding configs to the backend_manager will
- * be redirected to the first writeable backend.
+ * backends behind a single object.
* @verbatim
+---------+ +-----------+ +--------------+ |
@@ -55,18 +50,12 @@ typedef struct backend_manager_t backend_manager_t;
+---------+ +-----------+ |
@endverbatim
- *
- * @b Constructors:
- * - backend_manager_create()
- *
- * @ingroup config
*/
struct backend_manager_t {
/**
- * @brief Get an ike_config identified by two hosts.
+ * Get an ike_config identified by two hosts.
*
- * @param this calling object
* @param my_host address of own host
* @param other_host address of remote host
* @return matching ike_config, or NULL if none found
@@ -75,59 +64,57 @@ struct backend_manager_t {
host_t *my_host, host_t *other_host);
/**
- * @brief Get a peer_config identified by two IDs and the peer's certificate issuer
+ * Get a peer_config identified by two IDs and authorization info.
*
- * @param this calling object
* @param my_id own ID
* @param other_id peer ID
- * @param other_ca_info info record on issuer of peer certificate
+ * @param auth_info authorization info
* @return matching peer_config, or NULL if none found
*/
- peer_cfg_t* (*get_peer_cfg)(backend_manager_t *this,
- identification_t *my_id, identification_t *other_id,
- ca_info_t *other_ca_info);
+ peer_cfg_t* (*get_peer_cfg)(backend_manager_t *this, identification_t *my_id,
+ identification_t *other_id, auth_info_t *auth);
/**
- * @brief Get a peer_config identified by it's name.
+ * Get a peer_config identified by it's name.
*
- * @param this calling object
* @param name name of the peer_config
* @return matching peer_config, or NULL if none found
*/
peer_cfg_t* (*get_peer_cfg_by_name)(backend_manager_t *this, char *name);
/**
- * @brief Add a peer_config to the first found writable backend.
+ * Create an enumerator over all peer configs.
*
- * @param this calling object
- * @param config peer_config to add to the backend
+ * @return enumerator over peer configs
*/
- void (*add_peer_cfg)(backend_manager_t *this, peer_cfg_t *config);
+ enumerator_t* (*create_peer_cfg_enumerator)(backend_manager_t *this);
/**
- * @brief Create an iterator over all peer configs of the writable backend.
+ * Register a backend on the manager.
*
- * @param this calling object
- * @return iterator over peer configs
+ * @param backend backend to register
*/
- iterator_t* (*create_iterator)(backend_manager_t *this);
+ void (*add_backend)(backend_manager_t *this, backend_t *backend);
/**
- * @brief Destroys a backend_manager_t object.
+ * Unregister a backend.
*
- * @param this calling object
+ * @param backend backend to unregister
+ */
+ void (*remove_backend)(backend_manager_t *this, backend_t *backend);
+
+ /**
+ * Destroys a backend_manager_t object.
*/
void (*destroy) (backend_manager_t *this);
};
/**
- * @brief Creates a new instance of the manager and loads all backends.
+ * Create an instance of the backend manager
*
* @return backend_manager instance
- *
- * @ingroup config
*/
backend_manager_t* backend_manager_create(void);
-#endif /*BACKEND_MANAGER_H_*/
+#endif /*BACKEND_MANAGER_H_ @} */
diff --git a/src/charon/config/backends/backend.h b/src/charon/config/backends/backend.h
deleted file mode 100644
index 592d1dd4c..000000000
--- a/src/charon/config/backends/backend.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * @file backend.h
- *
- * @brief Interface backend_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifndef BACKEND_H_
-#define BACKEND_H_
-
-typedef struct backend_t backend_t;
-
-#include <library.h>
-#include <config/ike_cfg.h>
-#include <config/peer_cfg.h>
-#include <utils/linked_list.h>
-
-/**
- * @brief The interface for a configuration backend.
- *
- * A configuration backend is loaded by the backend_manager. It does the actual
- * configuration lookup for the method it implements. See backend_manager_t for
- * more information.
- *
- * @b Constructors:
- * - implementations constructors
- *
- * @ingroup backends
- */
-struct backend_t {
-
- /**
- * @brief Get an ike_cfg identified by two hosts.
- *
- * @param this calling object
- * @param my_host address of own host
- * @param other_host address of remote host
- * @return matching ike_config, or NULL if none found
- */
- ike_cfg_t *(*get_ike_cfg)(backend_t *this,
- host_t *my_host, host_t *other_host);
-
- /**
- * @brief Get a peer_cfg identified by two IDs.
- *
- * Select a config based on the two IDs and the other's certificate issuer
- *
- * @param this calling object
- * @param my_id own ID
- * @param other_id peer ID
- * @param other_ca_info info record on issuer of peer certificate
- * @return matching peer_config, or NULL if none found
- */
- peer_cfg_t *(*get_peer_cfg)(backend_t *this,
- identification_t *my_id, identification_t *other_id,
- ca_info_t *other_ca_info);
-
- /**
- * @brief Get a peer_cfg identified by it's name, or a name of its child.
- *
- * @param this calling object
- * @param name
- * @return matching peer_config, or NULL if none found
- */
- peer_cfg_t *(*get_peer_cfg_by_name)(backend_t *this, char *name);
-
- /**
- * @brief Check if a backend is writable and implements writable_backend_t.
- *
- * @param this calling object
- * @return TRUE if backend implements writable_backend_t.
- */
- bool (*is_writeable)(backend_t *this);
-
- /**
- * @brief Destroy a backend.
- *
- * @param this calling object
- */
- void (*destroy)(backend_t *this);
-};
-
-
-/**
- * Construction to create a backend.
- */
-typedef backend_t*(*backend_constructor_t)(void);
-
-#endif /* BACKEND_H_ */
-
diff --git a/src/charon/config/backends/local_backend.c b/src/charon/config/backends/local_backend.c
deleted file mode 100644
index e04c72ac1..000000000
--- a/src/charon/config/backends/local_backend.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/**
- * @file local_backend.c
- *
- * @brief Implementation of local_backend_t.
- *
- */
-
-/*
- * Copyright (C) 2006 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 <string.h>
-
-#include "local_backend.h"
-
-#include <daemon.h>
-#include <utils/linked_list.h>
-#include <crypto/ca.h>
-
-
-typedef struct private_local_backend_t private_local_backend_t;
-
-/**
- * Private data of an local_backend_t object
- */
-struct private_local_backend_t {
-
- /**
- * Public part
- */
- local_backend_t public;
-
- /**
- * list of configs
- */
- linked_list_t *cfgs;
-
- /**
- * Mutex to exclusivly access list
- */
- pthread_mutex_t mutex;
-};
-
-/**
- * implements backen_t.get_ike_cfg.
- */
-static ike_cfg_t *get_ike_cfg(private_local_backend_t *this,
- host_t *my_host, host_t *other_host)
-{
- peer_cfg_t *peer;
- ike_cfg_t *current, *found = NULL;
- iterator_t *iterator;
- host_t *my_candidate, *other_candidate;
- enum {
- MATCH_NONE = 0x00,
- MATCH_ANY = 0x01,
- MATCH_ME = 0x04,
- MATCH_OTHER = 0x08,
- } prio, best = MATCH_ANY;
-
- DBG2(DBG_CFG, "looking for a config for %H...%H",
- my_host, other_host);
-
- iterator = this->cfgs->create_iterator_locked(this->cfgs, &this->mutex);
- while (iterator->iterate(iterator, (void**)&peer))
- {
- prio = MATCH_NONE;
- current = peer->get_ike_cfg(peer);
- my_candidate = current->get_my_host(current);
- other_candidate = current->get_other_host(current);
-
- if (my_candidate->ip_equals(my_candidate, my_host))
- {
- prio += MATCH_ME;
- }
- else if (my_candidate->is_anyaddr(my_candidate))
- {
- prio += MATCH_ANY;
- }
-
- if (other_candidate->ip_equals(other_candidate, other_host))
- {
- prio += MATCH_OTHER;
- }
- else if (other_candidate->is_anyaddr(other_candidate))
- {
- prio += MATCH_ANY;
- }
-
- DBG2(DBG_CFG, " candidate '%s': %H...%H, prio %d",
- peer->get_name(peer), my_candidate, other_candidate, prio);
-
- /* we require at least two MATCH_ANY */
- if (prio > best)
- {
- best = prio;
- found = current;
- }
- }
- if (found)
- {
- found->get_ref(found);
- }
- iterator->destroy(iterator);
- return found;
-}
-
-#define PRIO_NO_MATCH_FOUND 256
-
-/**
- * implements backend_t.get_peer.
- */
-static peer_cfg_t *get_peer_cfg(private_local_backend_t *this,
- identification_t *my_id, identification_t *other_id,
- ca_info_t *other_ca_info)
-{
- peer_cfg_t *current, *found = NULL;
- iterator_t *iterator;
- identification_t *my_candidate, *other_candidate;
- int best = PRIO_NO_MATCH_FOUND;
-
- DBG2(DBG_CFG, "looking for a config for %D...%D", my_id, other_id);
-
- iterator = this->cfgs->create_iterator_locked(this->cfgs, &this->mutex);
- while (iterator->iterate(iterator, (void**)&current))
- {
- int wc1, wc2;
-
- my_candidate = current->get_my_id(current);
- other_candidate = current->get_other_id(current);
-
- if (my_candidate->matches(my_candidate, my_id, &wc1)
- && other_id->matches(other_id, other_candidate, &wc2))
- {
- int prio = (wc1 + wc2) * (MAX_CA_PATH_LEN + 1);
- int pathlen = 0;
- identification_t *other_candidate_ca = current->get_other_ca(current);
- linked_list_t *groups = current->get_groups(current);
-
- /* is a group membership required? */
- if (groups->get_count(groups) > 0)
- {
- DBG1(DBG_CFG, " group membership required");
- }
-
- /* are there any ca constraints? */
- if (other_candidate_ca->get_type(other_candidate_ca) != ID_ANY)
- {
- ca_info_t *ca_info = other_ca_info;
-
- for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
- {
- if (ca_info == NULL)
- {
- prio = PRIO_NO_MATCH_FOUND;
- break;
- }
- else
- {
- x509_t *cacert = ca_info->get_certificate(ca_info);
- identification_t *other_ca = cacert->get_subject(cacert);
-
- if (other_candidate_ca->equals(other_candidate_ca, other_ca))
- {
- /* found a ca match */
- break;
- }
- if (cacert->is_self_signed(cacert))
- {
- /* reached the root ca without a match */
- prio = PRIO_NO_MATCH_FOUND;
- break;
- }
- /* move a level upward in the trust path hierarchy */
- ca_info = charon->credentials->get_issuer(charon->credentials, cacert);
- }
- }
- if (pathlen == MAX_CA_PATH_LEN)
- {
- DBG1(DBG_CFG, "maximum ca path length of %d levels reached", MAX_CA_PATH_LEN);
- prio = PRIO_NO_MATCH_FOUND;
- }
- }
- if (prio == PRIO_NO_MATCH_FOUND)
- {
- DBG2(DBG_CFG, " candidate '%s': %D...%D, no ca match",
- current->get_name(current), my_candidate, other_candidate);
- }
- else
- {
- prio += pathlen;
- DBG2(DBG_CFG, " candidate '%s': %D...%D, prio %d",
- current->get_name(current), my_candidate, other_candidate, prio);
-
- if (prio < best)
- {
- found = current;
- best = prio;
- }
- }
- }
- }
- if (found)
- {
- DBG1(DBG_CFG, "found matching config \"%s\": %D...%D, prio %d",
- found->get_name(found),
- found->get_my_id(found),
- found->get_other_id(found),
- best);
- found->get_ref(found);
- }
- iterator->destroy(iterator);
- return found;
-}
-
-/**
- * implements backend_t.get_peer_cfg_by_name.
- */
-static peer_cfg_t *get_peer_cfg_by_name(private_local_backend_t *this, char *name)
-{
- iterator_t *i1, *i2;
- peer_cfg_t *current, *found = NULL;
- child_cfg_t *child;
-
- i1 = this->cfgs->create_iterator(this->cfgs, TRUE);
- while (i1->iterate(i1, (void**)&current))
- {
- /* compare peer_cfgs name first */
- if (streq(current->get_name(current), name))
- {
- found = current;
- found->get_ref(found);
- break;
- }
- /* compare all child_cfg names otherwise */
- i2 = current->create_child_cfg_iterator(current);
- while (i2->iterate(i2, (void**)&child))
- {
- if (streq(child->get_name(child), name))
- {
- found = current;
- found->get_ref(found);
- break;
- }
- }
- i2->destroy(i2);
- if (found)
- {
- break;
- }
- }
- i1->destroy(i1);
- return found;
-}
-
-/**
- * Implementation of backend_t.is_writable.
- */
-static bool is_writeable(private_local_backend_t *this)
-{
- return TRUE;
-}
-
-/**
- * Implementation of writable_backend_t.create_iterator.
- */
-static iterator_t* create_iterator(private_local_backend_t *this)
-{
- return this->cfgs->create_iterator_locked(this->cfgs, &this->mutex);
-}
-
-/**
- * Implementation of writable_backend_t.add_peer_cfg.
- */
-static void add_cfg(private_local_backend_t *this, peer_cfg_t *config)
-{
- pthread_mutex_lock(&this->mutex);
- this->cfgs->insert_last(this->cfgs, config);
- pthread_mutex_unlock(&this->mutex);
-}
-
-/**
- * Implementation of backend_t.destroy.
- */
-static void destroy(private_local_backend_t *this)
-{
- this->cfgs->destroy_offset(this->cfgs, offsetof(peer_cfg_t, destroy));
- free(this);
-}
-
-/**
- * Described in header.
- */
-backend_t *backend_create(void)
-{
- private_local_backend_t *this = malloc_thing(private_local_backend_t);
-
- this->public.backend.backend.get_ike_cfg = (ike_cfg_t* (*)(backend_t*, host_t*, host_t*))get_ike_cfg;
- this->public.backend.backend.get_peer_cfg = (peer_cfg_t* (*)(backend_t*,identification_t*,identification_t*,ca_info_t*))get_peer_cfg;
- this->public.backend.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
- this->public.backend.backend.is_writeable = (bool(*) (backend_t*))is_writeable;
- this->public.backend.backend.destroy = (void (*)(backend_t*))destroy;
- this->public.backend.create_iterator = (iterator_t* (*)(writeable_backend_t*))create_iterator;
- this->public.backend.add_cfg = (void (*)(writeable_backend_t*,peer_cfg_t*))add_cfg;
-
- /* private variables */
- this->cfgs = linked_list_create();
- pthread_mutex_init(&this->mutex, NULL);
-
- return &this->public.backend.backend;
-}
diff --git a/src/charon/config/backends/local_backend.h b/src/charon/config/backends/local_backend.h
deleted file mode 100644
index b33c6443b..000000000
--- a/src/charon/config/backends/local_backend.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * @file local_backend.h
- *
- * @brief Interface of local_backend_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifndef LOCAL_BACKEND_H_
-#define LOCAL_BACKEND_H_
-
-typedef struct local_backend_t local_backend_t;
-
-#include <library.h>
-#include <config/backends/writeable_backend.h>
-
-/**
- * @brief An in-memory backend to store configurations.
- *
- * The local_backend_t stores the configuration in a simple list. It
- * implements both, backend_t and writeable_backend_t.
- *
- * @b Constructors:
- * - local_backend_create()
- *
- * @ingroup backends
- */
-struct local_backend_t {
-
- /**
- * Implements writable_backend_t interface
- */
- writeable_backend_t backend;
-};
-
-/**
- * @brief Create a backend_t instance implemented as local backend.
- *
- * @return backend instance
- *
- * @ingroup backends
- */
-backend_t *backend_create(void);
-
-#endif /* LOCAL_BACKEND_H_ */
-
diff --git a/src/charon/config/backends/sqlite_backend.c b/src/charon/config/backends/sqlite_backend.c
deleted file mode 100644
index e1c96c870..000000000
--- a/src/charon/config/backends/sqlite_backend.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/**
- * @file sqlite_backend.c
- *
- * @brief Implementation of sqlite_backend_t.
- *
- */
-
-/*
- * Copyright (C) 2006 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 <string.h>
-#include <sqlite3.h>
-
-#include "sqlite_backend.h"
-
-#include <daemon.h>
-
-
-typedef struct private_sqlite_backend_t private_sqlite_backend_t;
-
-/**
- * Private data of an sqlite_backend_t object
- */
-struct private_sqlite_backend_t {
-
- /**
- * Public part
- */
- sqlite_backend_t public;
-
- /**
- * SQLite database handle
- */
- sqlite3 *db;
-};
-
-/**
- * implements backen_t.get_ike_cfg.
- */
-static ike_cfg_t *get_ike_cfg(private_sqlite_backend_t *this,
- host_t *my_host, host_t *other_host)
-{
- return NULL;
-}
-
-/**
- * add TS with child "id" to "child_cfg"
- */
-static void add_ts(private_sqlite_backend_t *this, child_cfg_t *child_cfg, int id)
-{
- sqlite3_stmt *stmt;
-
- if (sqlite3_prepare_v2(this->db,
- "SELECT type, protocol, start_addr, end_addr, start_port, end_port, kind "
- "FROM traffic_selectors, child_config_traffic_selector "
- "ON traffic_selectors.oid = child_config_traffic_selector.traffic_selector "
- "WHERE child_config_traffic_selector.child_cfg = ?;",
- -1, &stmt, NULL) == SQLITE_OK &&
- sqlite3_bind_int(stmt, 1, id) == SQLITE_OK)
- {
- while (sqlite3_step(stmt) == SQLITE_ROW)
- {
- traffic_selector_t *ts;
- bool local = FALSE;
- enum {
- TS_LOCAL = 0,
- TS_REMOTE = 1,
- TS_LOCAL_DYNAMIC = 2,
- TS_REMOTE_DYNAMIC = 3,
- } kind;
-
- kind = sqlite3_column_int(stmt, 6);
- switch (kind)
- {
- case TS_LOCAL:
- local = TRUE;
- /* FALL */
- case TS_REMOTE:
- ts = traffic_selector_create_from_string(
- sqlite3_column_int(stmt, 1), /* protocol */
- sqlite3_column_int(stmt, 0), /* type */
- (char*)sqlite3_column_text(stmt, 2), /* from addr */
- sqlite3_column_int(stmt, 4), /* from port */
- (char*)sqlite3_column_text(stmt, 3), /* to addr */
- sqlite3_column_int(stmt, 5)); /* to port */
- break;
- case TS_LOCAL_DYNAMIC:
- local = TRUE;
- /* FALL */
- case TS_REMOTE_DYNAMIC:
- ts = traffic_selector_create_dynamic(
- sqlite3_column_int(stmt, 1), /* protocol */
- sqlite3_column_int(stmt, 0), /* type */
- sqlite3_column_int(stmt, 4), /* from port */
- sqlite3_column_int(stmt, 5)); /* to port */
- break;
- default:
- continue;
- }
- if (ts)
- {
- child_cfg->add_traffic_selector(child_cfg, local, ts);
- }
- }
- }
- sqlite3_finalize(stmt);
-}
-
-/**
- * add childrens belonging to config with "id" to "peer_cfg"
- */
-static void add_children(private_sqlite_backend_t *this, peer_cfg_t *peer_cfg, int id)
-{
- sqlite3_stmt *stmt;
- child_cfg_t *child_cfg;
-
- if (sqlite3_prepare_v2(this->db,
- "SELECT child_configs.oid, name, updown, hostaccess, mode, "
- "lifetime, rekeytime, jitter "
- "FROM child_configs, peer_config_child_config "
- "ON child_configs.oid = peer_config_child_config.child_cfg "
- "WHERE peer_config_child_config.peer_cfg = ?;",
- -1, &stmt, NULL) == SQLITE_OK &&
- sqlite3_bind_int(stmt, 1, id) == SQLITE_OK)
- {
- while (sqlite3_step(stmt) == SQLITE_ROW)
- {
- child_cfg = child_cfg_create(
- (char*)sqlite3_column_text(stmt, 1), /* name */
- sqlite3_column_int(stmt, 5), /* lifetime */
- sqlite3_column_int(stmt, 6), /* rekeytime */
- sqlite3_column_int(stmt, 7), /* jitter */
- (char*)sqlite3_column_text(stmt, 2), /* updown */
- sqlite3_column_int(stmt, 3), /* hostaccess */
- sqlite3_column_int(stmt, 4)); /* mode */
- add_ts(this, child_cfg, sqlite3_column_int(stmt, 0));
- child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
- peer_cfg->add_child_cfg(peer_cfg, child_cfg);
- }
- }
- sqlite3_finalize(stmt);
-}
-
-/**
- * processing function for get_peer_cfg and get_peer_cfg_by_name
- */
-static peer_cfg_t *process_peer_cfg_row(private_sqlite_backend_t *this,
- sqlite3_stmt *stmt)
-{
- host_t *local_host, *remote_host, *local_vip = NULL, *remote_vip = NULL;
- identification_t *local_id, *remote_id;
- peer_cfg_t *peer_cfg;
- ike_cfg_t *ike_cfg;
-
- local_host = host_create_from_string((char*)sqlite3_column_text(stmt, 17), IKEV2_UDP_PORT);
- remote_host = host_create_from_string((char*)sqlite3_column_text(stmt, 18), IKEV2_UDP_PORT);
- if (sqlite3_column_text(stmt, 15))
- {
- local_vip = host_create_from_string((char*)sqlite3_column_text(stmt, 15), 0);
- }
- if (sqlite3_column_text(stmt, 16))
- {
- remote_vip = host_create_from_string((char*)sqlite3_column_text(stmt, 16), 0);
- }
- local_id = identification_create_from_string((char*)sqlite3_column_text(stmt, 2));
- remote_id = identification_create_from_string((char*)sqlite3_column_text(stmt, 3));
- if (local_host && remote_host && local_id && remote_id)
- {
- ike_cfg = ike_cfg_create(sqlite3_column_int(stmt, 19), FALSE,
- local_host, remote_host);
- ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
- peer_cfg = peer_cfg_create(
- (char*)sqlite3_column_text(stmt, 1), /* name */
- 2, ike_cfg, local_id, remote_id, NULL, NULL, linked_list_create(),
- sqlite3_column_int(stmt, 4), /* cert_policy */
- sqlite3_column_int(stmt, 5), /* auth_method */
- sqlite3_column_int(stmt, 6), 0 /* eap_type, vendor */
- sqlite3_column_int(stmt, 7), /* keyingtries */
- sqlite3_column_int(stmt, 8), /* rekey_time */
- sqlite3_column_int(stmt, 9), /* reauth_time */
- sqlite3_column_int(stmt, 10), /* jitter_time */
- sqlite3_column_int(stmt, 11), /* over_time */
- sqlite3_column_int(stmt, 14), /* mobike */
- sqlite3_column_int(stmt, 12), /* dpd_delay */
- sqlite3_column_int(stmt, 13), /* dpd_action */
- local_vip, remote_vip, FALSE, NULL, NULL);
- add_children(this, peer_cfg, sqlite3_column_int(stmt, 0));
- return peer_cfg;
- }
-
- DESTROY_IF(local_host);
- DESTROY_IF(remote_host);
- DESTROY_IF(local_id);
- DESTROY_IF(remote_id);
- DESTROY_IF(local_vip);
- DESTROY_IF(remote_vip);
- return NULL;
-}
-
-/**
- * implements backend_t.get_peer_cfg.
- */
-static peer_cfg_t *get_peer_cfg(private_sqlite_backend_t *this,
- identification_t *my_id, identification_t *other_id,
- ca_info_t *other_ca_info)
-{
- sqlite3_stmt *stmt;
- char local[256], remote[256];
- peer_cfg_t *peer_cfg = NULL;
-
- snprintf(local, sizeof(local), "%D", my_id);
- snprintf(remote, sizeof(remote), "%D", other_id);
-
- if (sqlite3_prepare_v2(this->db,
- "SELECT peer_configs.oid, name, local_id, remote_id, cert_policy, "
- "auth_method, eap_type, keyingtries, "
- "rekey_time, reauth_time, jitter_time, over_time, "
- "dpd_delay, dpd_action, mobike, local_vip, remote_vip, "
- "local, remote, certreq "
- "FROM peer_configs, ike_configs "
- "ON peer_configs.ike_cfg = ike_configs.oid "
- "WHERE local_id = ? and remote_id = ?;", -1, &stmt, NULL) == SQLITE_OK &&
- sqlite3_bind_text(stmt, 1, local, -1, SQLITE_STATIC) == SQLITE_OK &&
- sqlite3_bind_text(stmt, 2, remote, -1, SQLITE_STATIC) == SQLITE_OK &&
- sqlite3_step(stmt) == SQLITE_ROW)
- {
- peer_cfg = process_peer_cfg_row(this, stmt);
- }
- sqlite3_finalize(stmt);
- return peer_cfg;
-}
-
-/**
- * implements backend_t.get_peer_cfg_by_name.
- */
-static peer_cfg_t *get_peer_cfg_by_name(private_sqlite_backend_t *this, char *name)
-{
- sqlite3_stmt *stmt;
- peer_cfg_t *peer_cfg = NULL;
-
- if (sqlite3_prepare_v2(this->db,
- "SELECT peer_configs.oid, name, local_id, remote_id, cert_policy, "
- "auth_method, eap_type, keyingtries, lifetime, rekeytime, jitter, "
- "dpd_delay, dpd_action, reauth, mobike, local_vip, remote_vip, "
- "local, remote, certreq "
- "FROM peer_configs, ike_configs "
- "ON peer_configs.ike_cfg = ike_configs.oid "
- "WHERE name = ? ;", -1, &stmt, NULL) == SQLITE_OK &&
- sqlite3_bind_text(stmt, 1, name, -1, SQLITE_STATIC) == SQLITE_OK &&
- sqlite3_step(stmt) == SQLITE_ROW)
- {
- peer_cfg = process_peer_cfg_row(this, stmt);
- }
- sqlite3_finalize(stmt);
- return peer_cfg;
-}
-
-/**
- * Implementation of backend_t.is_writable.
- */
-static bool is_writeable(private_sqlite_backend_t *this)
-{
- return FALSE;
-}
-
-/**
- * Implementation of backend_t.destroy.
- */
-static void destroy(private_sqlite_backend_t *this)
-{
- sqlite3_close(this->db);
- free(this);
-}
-
-/**
- * Described in header.
- */
-backend_t *backend_create(void)
-{
- private_sqlite_backend_t *this = malloc_thing(private_sqlite_backend_t);
-
- this->public.backend.get_ike_cfg = (ike_cfg_t* (*)(backend_t*, host_t*, host_t*))get_ike_cfg;
- this->public.backend.get_peer_cfg = (peer_cfg_t* (*)(backend_t*,identification_t*,identification_t*,ca_info_t*))get_peer_cfg;
- this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
- this->public.backend.is_writeable = (bool(*) (backend_t*))is_writeable;
- this->public.backend.destroy = (void (*)(backend_t*))destroy;
-
- if (sqlite3_open(IPSEC_DIR "/manager.db", &this->db) != SQLITE_OK)
- {
- DBG1(DBG_CFG, "opening SQLite database '" IPSEC_DIR "/manager.db' failed.");
- destroy(this);
- return NULL;
- }
-
- return &this->public.backend;
-}
-
diff --git a/src/charon/config/backends/writeable_backend.h b/src/charon/config/backends/writeable_backend.h
deleted file mode 100644
index ea62f62c9..000000000
--- a/src/charon/config/backends/writeable_backend.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * @file writeable_backend.h
- *
- * @brief Interface of writeable_backend_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifndef WRITEABLE_BACKEND_H_
-#define WRITEABLE_BACKEND_H_
-
-typedef struct writeable_backend_t writeable_backend_t;
-
-#include <library.h>
-#include <config/backends/backend.h>
-
-/**
- * @brief A writeable backend extends backend_t by modification functions.
- *
- * @b Constructors:
- * - writeable_backend_create()
- *
- * @ingroup backends
- */
-struct writeable_backend_t {
-
- /**
- * Implements backend_t interface
- */
- backend_t backend;
-
- /**
- * @brief Add a peer_config to the backend.
- *
- * @param this calling object
- * @param config peer_config to add to the backend
- */
- void (*add_cfg)(writeable_backend_t *this, peer_cfg_t *config);
-
- /**
- * @brief Create an iterator over all peer configs.
- *
- * @param this calling object
- * @return iterator over peer configs
- */
- iterator_t* (*create_iterator)(writeable_backend_t *this);
-};
-
-#endif /* WRITEABLE_BACKEND_H_ */
-
diff --git a/src/charon/config/child_cfg.c b/src/charon/config/child_cfg.c
index 5827b4f61..f929927ef 100644
--- a/src/charon/config/child_cfg.c
+++ b/src/charon/config/child_cfg.c
@@ -1,11 +1,5 @@
-/**
- * @file child_cfg.c
- *
- * @brief Implementation of child_cfg_t.
- *
- */
-
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -19,9 +13,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: child_cfg.c 4062 2008-06-12 11:42:19Z martin $
*/
-
#include "child_cfg.h"
#include <daemon.h>
@@ -34,6 +29,21 @@ ENUM(mode_names, MODE_TRANSPORT, MODE_BEET,
"BEET",
);
+ENUM(action_names, ACTION_NONE, ACTION_RESTART,
+ "ACTION_NONE",
+ "ACTION_ROUTE",
+ "ACTION_RESTART",
+);
+
+ENUM_BEGIN(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_NONE,
+ "IPCOMP_NONE");
+ENUM_NEXT(ipcomp_transform_names, IPCOMP_OUI, IPCOMP_LZJH, IPCOMP_NONE,
+ "IPCOMP_OUI",
+ "IPCOMP_DEFLATE",
+ "IPCOMP_LZS",
+ "IPCOMP_LZJH");
+ENUM_END(ipcomp_transform_names, IPCOMP_LZJH);
+
typedef struct private_child_cfg_t private_child_cfg_t;
/**
@@ -87,6 +97,16 @@ struct private_child_cfg_t {
mode_t mode;
/**
+ * action to take on DPD
+ */
+ action_t dpd_action;
+
+ /**
+ * action to take on CHILD_SA close
+ */
+ action_t close_action;
+
+ /**
* Time before an SA gets invalid
*/
u_int32_t lifetime;
@@ -101,6 +121,11 @@ struct private_child_cfg_t {
* substracted from rekeytime.
*/
u_int32_t jitter;
+
+ /**
+ * enable IPComp
+ */
+ bool use_ipcomp;
};
/**
@@ -120,42 +145,25 @@ static void add_proposal(private_child_cfg_t *this, proposal_t *proposal)
}
/**
- * strip out DH groups from a proposal
- */
-static void strip_dh_from_proposal(proposal_t *proposal)
-{
- iterator_t *iterator;
- algorithm_t *algo;
-
- iterator = proposal->create_algorithm_iterator(proposal, DIFFIE_HELLMAN_GROUP);
- while (iterator->iterate(iterator, (void**)&algo))
- {
- iterator->remove(iterator);
- free(algo);
- }
- iterator->destroy(iterator);
-}
-
-/**
* Implementation of child_cfg_t.get_proposals
*/
static linked_list_t* get_proposals(private_child_cfg_t *this, bool strip_dh)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
proposal_t *current;
linked_list_t *proposals = linked_list_create();
- iterator = this->proposals->create_iterator(this->proposals, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = this->proposals->create_enumerator(this->proposals);
+ while (enumerator->enumerate(enumerator, &current))
{
current = current->clone(current);
if (strip_dh)
{
- strip_dh_from_proposal(current);
+ current->strip_dh(current);
}
proposals->insert_last(proposals, current);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return proposals;
}
@@ -166,26 +174,28 @@ static linked_list_t* get_proposals(private_child_cfg_t *this, bool strip_dh)
static proposal_t* select_proposal(private_child_cfg_t*this,
linked_list_t *proposals, bool strip_dh)
{
- iterator_t *stored_iter, *supplied_iter;
+ enumerator_t *stored_enum, *supplied_enum;
proposal_t *stored, *supplied, *selected = NULL;
- stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
- supplied_iter = proposals->create_iterator(proposals, TRUE);
+ stored_enum = this->proposals->create_enumerator(this->proposals);
+ supplied_enum = proposals->create_enumerator(proposals);
/* compare all stored proposals with all supplied. Stored ones are preferred. */
- while (stored_iter->iterate(stored_iter, (void**)&stored))
+ while (stored_enum->enumerate(stored_enum, &stored))
{
stored = stored->clone(stored);
- supplied_iter->reset(supplied_iter);
- while (supplied_iter->iterate(supplied_iter, (void**)&supplied))
+ while (supplied_enum->enumerate(supplied_enum, &supplied))
{
if (strip_dh)
{
- strip_dh_from_proposal(stored);
+ stored->strip_dh(stored);
}
selected = stored->select(stored, supplied);
if (selected)
{
+ DBG2(DBG_CFG, "received proposals: %#P", proposals);
+ DBG2(DBG_CFG, "configured proposals: %#P", this->proposals);
+ DBG2(DBG_CFG, "selected proposal: %P", selected);
break;
}
}
@@ -194,9 +204,16 @@ static proposal_t* select_proposal(private_child_cfg_t*this,
{
break;
}
+ supplied_enum->destroy(supplied_enum);
+ supplied_enum = proposals->create_enumerator(proposals);
+ }
+ stored_enum->destroy(stored_enum);
+ supplied_enum->destroy(supplied_enum);
+ if (selected == NULL)
+ {
+ DBG1(DBG_CFG, "received proposals: %#P", proposals);
+ DBG1(DBG_CFG, "configured proposals: %#P", this->proposals);
}
- stored_iter->destroy(stored_iter);
- supplied_iter->destroy(supplied_iter);
return selected;
}
@@ -223,17 +240,17 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
linked_list_t *supplied,
host_t *host)
{
- iterator_t *i1, *i2;
+ enumerator_t *e1, *e2;
traffic_selector_t *ts1, *ts2, *selected;
linked_list_t *result = linked_list_create();
if (local)
{
- i1 = this->my_ts->create_iterator(this->my_ts, TRUE);
+ e1 = this->my_ts->create_enumerator(this->my_ts);
}
else
{
- i1 = this->other_ts->create_iterator(this->other_ts, FALSE);
+ e1 = this->other_ts->create_enumerator(this->other_ts);
}
/* no list supplied, just fetch the stored traffic selectors */
@@ -241,7 +258,7 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
{
DBG2(DBG_CFG, "proposing traffic selectors for %s:",
local ? "us" : "other");
- while (i1->iterate(i1, (void**)&ts1))
+ while (e1->enumerate(e1, &ts1))
{
/* we make a copy of the TS, this allows us to update dynamic TS' */
selected = ts1->clone(ts1);
@@ -252,15 +269,15 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
DBG2(DBG_CFG, " %R (derived from %R)", selected, ts1);
result->insert_last(result, selected);
}
- i1->destroy(i1);
+ e1->destroy(e1);
}
else
{
DBG2(DBG_CFG, "selecting traffic selectors for %s:",
local ? "us" : "other");
- i2 = supplied->create_iterator(supplied, TRUE);
+ e2 = supplied->create_enumerator(supplied);
/* iterate over all stored selectors */
- while (i1->iterate(i1, (void**)&ts1))
+ while (e1->enumerate(e1, &ts1))
{
/* we make a copy of the TS, as we have to update dynamic TS' */
ts1 = ts1->clone(ts1);
@@ -269,9 +286,8 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
ts1->set_address(ts1, host);
}
- i2->reset(i2);
/* iterate over all supplied traffic selectors */
- while (i2->iterate(i2, (void**)&ts2))
+ while (e2->enumerate(e2, &ts2))
{
selected = ts1->get_subset(ts1, ts2);
if (selected)
@@ -286,40 +302,44 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
ts1, ts2, selected);
}
}
+ e2->destroy(e2);
+ e2 = supplied->create_enumerator(supplied);
ts1->destroy(ts1);
}
- i1->destroy(i1);
- i2->destroy(i2);
+ e1->destroy(e1);
+ e2->destroy(e2);
}
/* remove any redundant traffic selectors in the list */
- i1 = result->create_iterator(result, TRUE);
- i2 = result->create_iterator(result, TRUE);
- while (i1->iterate(i1, (void**)&ts1))
+ e1 = result->create_enumerator(result);
+ e2 = result->create_enumerator(result);
+ while (e1->enumerate(e1, &ts1))
{
- while (i2->iterate(i2, (void**)&ts2))
+ while (e2->enumerate(e2, &ts2))
{
if (ts1 != ts2)
{
if (ts2->is_contained_in(ts2, ts1))
{
- i2->remove(i2);
+ result->remove_at(result, e2);
ts2->destroy(ts2);
- i1->reset(i1);
+ e1->destroy(e1);
+ e1 = result->create_enumerator(result);
break;
}
if (ts1->is_contained_in(ts1, ts2))
{
- i1->remove(i1);
+ result->remove_at(result, e1);
ts1->destroy(ts1);
- i2->reset(i2);
+ e2->destroy(e2);
+ e2 = result->create_enumerator(result);
break;
}
}
}
}
- i1->destroy(i1);
- i2->destroy(i2);
+ e1->destroy(e1);
+ e2->destroy(e2);
return result;
}
@@ -357,7 +377,7 @@ static u_int32_t get_lifetime(private_child_cfg_t *this, bool rekey)
}
/**
- * Implementation of child_cfg_t.get_name
+ * Implementation of child_cfg_t.get_mode
*/
static mode_t get_mode(private_child_cfg_t *this)
{
@@ -365,34 +385,57 @@ static mode_t get_mode(private_child_cfg_t *this)
}
/**
+ * Implementation of child_cfg_t.get_dpd_action
+ */
+static action_t get_dpd_action(private_child_cfg_t *this)
+{
+ return this->dpd_action;
+}
+
+/**
+ * Implementation of child_cfg_t.get_close_action
+ */
+static action_t get_close_action(private_child_cfg_t *this)
+{
+ return this->close_action;
+}
+
+/**
* Implementation of child_cfg_t.get_dh_group.
*/
static diffie_hellman_group_t get_dh_group(private_child_cfg_t *this)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
proposal_t *proposal;
- algorithm_t *algo;
- diffie_hellman_group_t dh_group = MODP_NONE;
+ u_int16_t dh_group = MODP_NONE;
- iterator = this->proposals->create_iterator(this->proposals, TRUE);
- while (iterator->iterate(iterator, (void**)&proposal))
+ enumerator = this->proposals->create_enumerator(this->proposals);
+ while (enumerator->enumerate(enumerator, &proposal))
{
- if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &algo))
+ if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &dh_group, NULL))
{
- dh_group = algo->algorithm;
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return dh_group;
}
/**
+ * Implementation of child_cfg_t.use_ipcomp.
+ */
+static bool use_ipcomp(private_child_cfg_t *this)
+{
+ return this->use_ipcomp;
+}
+
+/**
* Implementation of child_cfg_t.get_name
*/
-static void get_ref(private_child_cfg_t *this)
+static child_cfg_t* get_ref(private_child_cfg_t *this)
{
ref_get(&this->refcount);
+ return &this->public;
}
/**
@@ -419,11 +462,11 @@ static void destroy(private_child_cfg_t *this)
*/
child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
u_int32_t rekeytime, u_int32_t jitter,
- char *updown, bool hostaccess, mode_t mode)
+ char *updown, bool hostaccess, mode_t mode,
+ action_t dpd_action, action_t close_action, bool ipcomp)
{
private_child_cfg_t *this = malloc_thing(private_child_cfg_t);
- /* public functions */
this->public.get_name = (char* (*) (child_cfg_t*))get_name;
this->public.add_traffic_selector = (void (*)(child_cfg_t*,bool,traffic_selector_t*))add_traffic_selector;
this->public.get_traffic_selectors = (linked_list_t*(*)(child_cfg_t*,bool,linked_list_t*,host_t*))get_traffic_selectors;
@@ -433,12 +476,14 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
this->public.get_updown = (char* (*) (child_cfg_t*))get_updown;
this->public.get_hostaccess = (bool (*) (child_cfg_t*))get_hostaccess;
this->public.get_mode = (mode_t (*) (child_cfg_t *))get_mode;
+ this->public.get_dpd_action = (action_t (*) (child_cfg_t *))get_dpd_action;
+ this->public.get_close_action = (action_t (*) (child_cfg_t *))get_close_action;
this->public.get_lifetime = (u_int32_t (*) (child_cfg_t *,bool))get_lifetime;
this->public.get_dh_group = (diffie_hellman_group_t(*)(child_cfg_t*)) get_dh_group;
- this->public.get_ref = (void (*) (child_cfg_t*))get_ref;
+ this->public.use_ipcomp = (bool (*) (child_cfg_t *))use_ipcomp;
+ this->public.get_ref = (child_cfg_t* (*) (child_cfg_t*))get_ref;
this->public.destroy = (void (*) (child_cfg_t*))destroy;
- /* apply init values */
this->name = strdup(name);
this->lifetime = lifetime;
this->rekeytime = rekeytime;
@@ -446,8 +491,9 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
this->updown = updown ? strdup(updown) : NULL;
this->hostaccess = hostaccess;
this->mode = mode;
-
- /* initialize private members*/
+ this->dpd_action = dpd_action;
+ this->close_action = close_action;
+ this->use_ipcomp = ipcomp;
this->refcount = 1;
this->proposals = linked_list_create();
this->my_ts = linked_list_create();
@@ -455,3 +501,4 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
return &this->public;
}
+
diff --git a/src/charon/config/child_cfg.h b/src/charon/config/child_cfg.h
index e1a6553b4..6d262c217 100644
--- a/src/charon/config/child_cfg.h
+++ b/src/charon/config/child_cfg.h
@@ -1,11 +1,5 @@
-/**
- * @file child_cfg.h
- *
- * @brief Interface of child_cfg_t.
- *
- */
-
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -19,12 +13,21 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: child_cfg.h 3920 2008-05-08 16:19:11Z tobias $
+ */
+
+/**
+ * @defgroup child_cfg child_cfg
+ * @{ @ingroup config
*/
#ifndef CHILD_CFG_H_
#define CHILD_CFG_H_
typedef enum mode_t mode_t;
+typedef enum action_t action_t;
+typedef enum ipcomp_transform_t ipcomp_transform_t;
typedef struct child_cfg_t child_cfg_t;
#include <library.h>
@@ -32,11 +35,9 @@ typedef struct child_cfg_t child_cfg_t;
#include <config/traffic_selector.h>
/**
- * @brief Mode of an CHILD_SA.
+ * Mode of an CHILD_SA.
*
* These are equal to those defined in XFRM, so don't change.
- *
- * @ingroup config
*/
enum mode_t {
/** transport mode, no inner address */
@@ -53,7 +54,40 @@ enum mode_t {
extern enum_name_t *mode_names;
/**
- * @brief A child_cfg_t defines the config template for a CHILD_SA.
+ * Action to take when DPD detected/connection gets closed by peer.
+ */
+enum action_t {
+ /** No action */
+ ACTION_NONE,
+ /** Route config to reestablish on demand */
+ ACTION_ROUTE,
+ /** Restart config immediately */
+ ACTION_RESTART,
+};
+
+/**
+ * enum names for action_t.
+ */
+extern enum_name_t *action_names;
+
+/**
+ * IPComp transform IDs, as in RFC 4306
+ */
+enum ipcomp_transform_t {
+ IPCOMP_NONE = 241,
+ IPCOMP_OUI = 1,
+ IPCOMP_DEFLATE = 2,
+ IPCOMP_LZS = 3,
+ IPCOMP_LZJH = 4,
+};
+
+/**
+ * enum strings for ipcomp_transform_t.
+ */
+extern enum_name_t *ipcomp_transform_names;
+
+/**
+ * A child_cfg_t defines the config template for a CHILD_SA.
*
* After creation, proposals and traffic selectors may be added to the config.
* A child_cfg object is referenced multiple times, and is not thread save.
@@ -62,51 +96,42 @@ extern enum_name_t *mode_names;
* A reference counter handles the number of references hold to this config.
*
* @see peer_cfg_t to get an overview over the configurations.
- *
- * @b Constructors:
- * - child_cfg_create()
- *
- * @ingroup config
*/
struct child_cfg_t {
/**
- * @brief Get the name of the child_cfg.
+ * Get the name of the child_cfg.
*
- * @param this calling object
* @return child_cfg's name
*/
char *(*get_name) (child_cfg_t *this);
/**
- * @brief Add a proposal to the list.
+ * Add a proposal to the list.
*
* The proposals are stored by priority, first added
* is the most prefered.
* After add, proposal is owned by child_cfg.
*
- * @param this calling object
* @param proposal proposal to add
*/
void (*add_proposal) (child_cfg_t *this, proposal_t *proposal);
/**
- * @brief Get the list of proposals for the CHILD_SA.
+ * Get the list of proposals for the CHILD_SA.
*
* Resulting list and all of its proposals must be freed after use.
*
- * @param this calling object
* @param strip_dh TRUE strip out diffie hellman groups
* @return list of proposals
*/
linked_list_t* (*get_proposals)(child_cfg_t *this, bool strip_dh);
/**
- * @brief Select a proposal from a supplied list.
+ * Select a proposal from a supplied list.
*
* Returned propsal is newly created and must be destroyed after usage.
*
- * @param this calling object
* @param proposals list from from wich proposals are selected
* @param strip_dh TRUE strip out diffie hellman groups
* @return selected proposal, or NULL if nothing matches
@@ -115,12 +140,11 @@ struct child_cfg_t {
bool strip_dh);
/**
- * @brief Add a traffic selector to the config.
+ * Add a traffic selector to the config.
*
* Use the "local" parameter to add it for the local or the remote side.
* After add, traffic selector is owned by child_cfg.
*
- * @param this calling object
* @param local TRUE for local side, FALSE for remote
* @param ts traffic_selector to add
*/
@@ -128,7 +152,7 @@ struct child_cfg_t {
traffic_selector_t *ts);
/**
- * @brief Get a list of traffic selectors to use for the CHILD_SA.
+ * Get a list of traffic selectors to use for the CHILD_SA.
*
* The config contains two set of traffic selectors, one for the local
* side, one for the remote side.
@@ -139,7 +163,6 @@ struct child_cfg_t {
* the "host" parameter to narrow such traffic selectors to that address.
* Resulted list and its traffic selectors must be destroyed after use.
*
- * @param this calling object
* @param local TRUE for TS on local side, FALSE for remote
* @param supplied list with TS to select from, or NULL
* @param host address to use for narrowing "dynamic" TS', or NULL
@@ -150,23 +173,21 @@ struct child_cfg_t {
host_t *host);
/**
- * @brief Get the updown script to run for the CHILD_SA.
+ * Get the updown script to run for the CHILD_SA.
*
- * @param this calling object
* @return path to updown script
*/
char* (*get_updown)(child_cfg_t *this);
/**
- * @brief Should we allow access to the local host (gateway)?
+ * Should we allow access to the local host (gateway)?
*
- * @param this calling object
* @return value of hostaccess flag
*/
bool (*get_hostaccess) (child_cfg_t *this);
/**
- * @brief Get the lifetime of a CHILD_SA.
+ * Get the lifetime of a CHILD_SA.
*
* If "rekey" is set to TRUE, a lifetime is returned before the first
* rekeying should be started. If it is FALSE, the actual lifetime is
@@ -174,57 +195,68 @@ struct child_cfg_t {
* The rekey time automatically contains a jitter to avoid simlutaneous
* rekeying.
*
- * @param this child_cfg
* @param rekey TRUE to get rekey time
* @return lifetime in seconds
*/
u_int32_t (*get_lifetime) (child_cfg_t *this, bool rekey);
/**
- * @brief Get the mode to use for the CHILD_SA.
+ * Get the mode to use for the CHILD_SA.
*
* The mode is either tunnel, transport or BEET. The peer must agree
* on the method, fallback is tunnel mode.
*
- * @param this child_cfg
- * @return lifetime in seconds
+ * @return ipsec mode
*/
mode_t (*get_mode) (child_cfg_t *this);
/**
- * @brief Get the DH group to use for CHILD_SA setup.
+ * Action to take on DPD.
+ *
+ * @return DPD action
+ */
+ action_t (*get_dpd_action) (child_cfg_t *this);
+
+ /**
+ * Action to take if CHILD_SA gets closed.
+ *
+ * @return close action
+ */
+ action_t (*get_close_action) (child_cfg_t *this);
+
+ /**
+ * Get the DH group to use for CHILD_SA setup.
*
- * @param this calling object
- * @return dh group to use
+ * @return dh group to use
*/
diffie_hellman_group_t (*get_dh_group)(child_cfg_t *this);
/**
- * @brief Get a new reference.
- *
- * Get a new reference to this child_cfg by increasing
- * it's internal reference counter.
- * Do not call get_ref or any other function until you
- * already have a reference. Otherwise the object may get
- * destroyed while calling get_ref(),
+ * Check whether IPComp should be used, if the other peer supports it.
*
- * @param this calling object
+ * @return TRUE, if IPComp should be used
+ * FALSE, otherwise
*/
- void (*get_ref) (child_cfg_t *this);
+ bool (*use_ipcomp)(child_cfg_t *this);
/**
- * @brief Destroys the child_cfg object.
+ * Increase the reference count.
+ *
+ * @return reference to this
+ */
+ child_cfg_t* (*get_ref) (child_cfg_t *this);
+
+ /**
+ * Destroys the child_cfg object.
*
* Decrements the internal reference counter and
* destroys the child_cfg when it reaches zero.
- *
- * @param this calling object
*/
void (*destroy) (child_cfg_t *this);
};
/**
- * @brief Create a configuration template for CHILD_SA setup.
+ * Create a configuration template for CHILD_SA setup.
*
* The "name" string gets cloned.
* Lifetimes are in seconds. To prevent to peers to start rekeying at the
@@ -240,12 +272,15 @@ struct child_cfg_t {
* @param updown updown script to execute on up/down event
* @param hostaccess TRUE to allow access to the local host
* @param mode mode to propose for CHILD_SA, transport, tunnel or BEET
+ * @param dpd_action DPD action
+ * @param close_action close action
+ * @param ipcomp use IPComp, if peer supports it
* @return child_cfg_t object
- *
- * @ingroup config
*/
child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
u_int32_t rekeytime, u_int32_t jitter,
- char *updown, bool hostaccess, mode_t mode);
+ char *updown, bool hostaccess, mode_t mode,
+ action_t dpd_action, action_t close_action,
+ bool ipcomp);
-#endif /* CHILD_CFG_H_ */
+#endif /* CHILD_CFG_H_ @} */
diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c
deleted file mode 100644
index b838f032d..000000000
--- a/src/charon/config/credentials/local_credential_store.c
+++ /dev/null
@@ -1,1620 +0,0 @@
-/**
- * @file local_credential_store.c
- *
- * @brief Implementation of local_credential_store_t.
- *
- */
-
-/*
- * Copyright (C) 2006 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.
- *
- * RCSID $Id: local_credential_store.c 3346 2007-11-16 20:23:29Z andreas $
- */
-
-#include <sys/stat.h>
-#include <dirent.h>
-#include <string.h>
-#include <pthread.h>
-#include <errno.h>
-
-#include <library.h>
-#include <utils/lexparser.h>
-#include <utils/linked_list.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <crypto/certinfo.h>
-#include <crypto/x509.h>
-#include <crypto/ca.h>
-#include <crypto/ac.h>
-#include <crypto/crl.h>
-#include <asn1/ttodata.h>
-
-#include "local_credential_store.h"
-
-#define PATH_BUF 256
-
-typedef struct shared_key_t shared_key_t;
-
-/**
- * Private date of a shared_key_t object
- */
-struct shared_key_t {
-
- /**
- * shared secret
- */
- chunk_t secret;
-
- /**
- * list of peer IDs
- */
- linked_list_t *peers;
-};
-
-
-/**
- * Implementation of shared_key_t.destroy.
- */
-static void shared_key_destroy(shared_key_t *this)
-{
- this->peers->destroy_offset(this->peers, offsetof(identification_t, destroy));
- chunk_free_randomized(&this->secret);
- free(this);
-}
-
-/**
- * @brief Creates a shared_key_t object.
- *
- * @param shared_key shared key value
- * @return shared_key_t object
- *
- * @ingroup config
- */
-static shared_key_t *shared_key_create(chunk_t secret)
-{
- shared_key_t *this = malloc_thing(shared_key_t);
-
- /* private data */
- this->secret = secret;
- this->peers = linked_list_create();
-
- return (this);
-}
-
-/* ------------------------------------------------------------------------ *
- * the ca_info_t object as a central control element
-
-+--------------------------------------------------------+
-| local_credential_store_t |
-+--------------------------------------------------------+
- | |
-+---------------------------+ +-------------------------+
-| linked_list_t *auth_certs | | linked_list_t *ca_infos |
-+---------------------------+ +-------------------------+
- | |
- | +------------------------- +
- | | ca_info_t |
- | +--------------------------+
-+---------------+ | char *name |
-| x509_t |<--| x509_t *cacert |
-+---------------+ | linked_list_t *attrcerts | +----------------------+
-| chunk_t keyid | | linked_list_t *certinfos |-->| certinfo_t |
-+---------------+ | linked_list_t *ocspuris | +----------------------+
- | | crl_t *crl | | chunk_t serialNumber |
- | | linked_list_t *crluris | | cert_status_t status |
-+---------------+ | pthread_mutex_t mutex | | time_t thisUpdate |
-| x509_t | +--------------------------+ | time_t nextUpdate |
-+---------------+ | | bool once |
-| chunk_t keyid | | +----------------------+
-+---------------+ +------------------------- + |
- | | ca_info_t | +----------------------+
- | +--------------------------+ | certinfo_t |
-+---------------+ | char *name | +----------------------+
-| x509_t |<--| x509_t *cacert | | chunk_t serialNumber |
-+---------------+ | linked_list_t *attrcerts | | cert_status_t status |
-| chunk_t keyid | | linked_list_t *certinfos | | time_t thisUpdate |
-+---------------+ | linked_list_t *ocspuris | | time_t nextUpdate |
- | | crl_t *crl | | bool once |
- | | linked_list_t *crluris | +----------------------+
- | | pthread_mutex_t mutex; | |
- | +--------------------------+
- | |
-
- * ------------------------------------------------------------------------ */
-
-typedef struct private_local_credential_store_t private_local_credential_store_t;
-
-/**
- * Private data of an local_credential_store_t object
- */
-struct private_local_credential_store_t {
-
- /**
- * Public part
- */
- local_credential_store_t public;
-
- /**
- * list of shared keys
- */
- linked_list_t *shared_keys;
-
- /**
- * list of EAP keys
- */
- linked_list_t *eap_keys;
-
- /**
- * list of key_entry_t's with private keys
- */
- linked_list_t *private_keys;
-
- /**
- * mutex controls access to the linked lists of secret keys
- */
- pthread_mutex_t keys_mutex;
-
- /**
- * list of X.509 certificates with public keys
- */
- linked_list_t *certs;
-
- /**
- * list of X.509 authority certificates with public keys
- */
- linked_list_t *auth_certs;
-
- /**
- * list of X.509 CA information records
- */
- linked_list_t *ca_infos;
-
- /**
- * list of X.509 attribute certificates
- */
- linked_list_t *acerts;
-
- /**
- * mutex controls access to the linked list of attribute certificates
- */
- pthread_mutex_t acerts_mutex;
-};
-
-
-/**
- * Get a key from a list with shared_key_t's
- */
-static status_t get_key(linked_list_t *keys,
- identification_t *my_id,
- identification_t *other_id, chunk_t *secret)
-{
- typedef enum {
- PRIO_UNDEFINED= 0x00,
- PRIO_ANY_MATCH= 0x01,
- PRIO_MY_MATCH= 0x02,
- PRIO_OTHER_MATCH= 0x04,
- } prio_t;
-
- prio_t best_prio = PRIO_UNDEFINED;
- chunk_t found = chunk_empty;
- shared_key_t *shared_key;
- iterator_t *iterator;
-
- iterator = keys->create_iterator(keys, TRUE);
-
- while (iterator->iterate(iterator, (void**)&shared_key))
- {
- iterator_t *peer_iterator;
- identification_t *peer_id;
- prio_t prio = PRIO_UNDEFINED;
-
- peer_iterator = shared_key->peers->create_iterator(shared_key->peers, TRUE);
-
- if (peer_iterator->get_count(peer_iterator) == 0)
- {
- /* this is a wildcard shared key */
- prio = PRIO_ANY_MATCH;
- }
- else
- {
- while (peer_iterator->iterate(peer_iterator, (void**)&peer_id))
- {
- if (my_id->equals(my_id, peer_id))
- {
- prio |= PRIO_MY_MATCH;
- }
- if (other_id->equals(other_id, peer_id))
- {
- prio |= PRIO_OTHER_MATCH;
- }
- }
- }
- peer_iterator->destroy(peer_iterator);
-
- if (prio > best_prio)
- {
- best_prio = prio;
- found = shared_key->secret;
- }
- }
- iterator->destroy(iterator);
-
- if (best_prio == PRIO_UNDEFINED)
- {
- return NOT_FOUND;
- }
- else
- {
- *secret = chunk_clone(found);
- return SUCCESS;
- }
-}
-
-/**
- * Implementation of local_credential_store_t.get_shared_key.
- */
-static status_t get_shared_key(private_local_credential_store_t *this,
- identification_t *my_id,
- identification_t *other_id, chunk_t *secret)
-{
- status_t status;
-
- pthread_mutex_lock(&(this->keys_mutex));
- status = get_key(this->shared_keys, my_id, other_id, secret);
- pthread_mutex_unlock(&(this->keys_mutex));
- return status;
-}
-
-/**
- * Implementation of local_credential_store_t.get_eap_key.
- */
-static status_t get_eap_key(private_local_credential_store_t *this,
- identification_t *my_id,
- identification_t *other_id, chunk_t *secret)
-{
- status_t status;
-
- pthread_mutex_lock(&(this->keys_mutex));
- status = get_key(this->eap_keys, my_id, other_id, secret);
- pthread_mutex_unlock(&(this->keys_mutex));
- return status;
-}
-
-/**
- * Implementation of credential_store_t.get_certificate.
- */
-static x509_t* get_certificate(private_local_credential_store_t *this,
- identification_t *id)
-{
- x509_t *found = NULL;
- x509_t *current_cert;
-
- iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
-
- while (iterator->iterate(iterator, (void**)&current_cert))
- {
- if (id->equals(id, current_cert->get_subject(current_cert)) ||
- current_cert->equals_subjectAltName(current_cert, id))
- {
- found = current_cert;
- break;
- }
- }
- iterator->destroy(iterator);
- return found;
-}
-
-/**
- * Implementation of local_credential_store_t.get_rsa_public_key.
- */
-static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *this,
- identification_t *id)
-{
- x509_t *cert = get_certificate(this, id);
-
- return (cert == NULL)? NULL:cert->get_public_key(cert);
-}
-
-/**
- * Implementation of credential_store_t.get_issuer.
- */
-static ca_info_t* get_issuer(private_local_credential_store_t *this, x509_t *cert)
-{
- ca_info_t *found = cert->get_ca_info(cert);
-
- if (found == NULL)
- {
- iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
- ca_info_t *ca_info;
-
- while (iterator->iterate(iterator, (void**)&ca_info))
- {
- if (ca_info->is_cert_issuer(ca_info, cert))
- {
- found = ca_info;
- cert->set_ca_info(cert, found);
- break;
- }
- }
- iterator->destroy(iterator);
- }
- return found;
-}
-
-/**
- * Implementation of local_credential_store_t.has_rsa_private_key.
- */
-static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_public_key_t *pubkey)
-{
- bool found = FALSE;
- rsa_private_key_t *current;
- iterator_t *iterator;
-
- pthread_mutex_lock(&(this->keys_mutex));
- iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
-
- while (iterator->iterate(iterator, (void**)&current))
- {
- if (current->belongs_to(current, pubkey))
- {
- found = TRUE;
- break;
- }
- }
- iterator->destroy(iterator);
- pthread_mutex_unlock(&(this->keys_mutex));
- return found;
-}
-
-/**
- * Implementation of credential_store_t.get_auth_certificate.
- */
-static x509_t* get_auth_certificate(private_local_credential_store_t *this,
- u_int auth_flags,
- identification_t *id)
-{
- x509_t *found = NULL;
- x509_t *current_cert;
-
- iterator_t *iterator = this->auth_certs->create_iterator(this->auth_certs, TRUE);
-
- while (iterator->iterate(iterator, (void**)&current_cert))
- {
- if (current_cert->has_authority_flag(current_cert, auth_flags)
- && id->equals(id, current_cert->get_subject(current_cert)))
- {
- found = current_cert;
- break;
- }
- }
- iterator->destroy(iterator);
-
- return found;
-}
-
-/**
- * Implementation of credential_store_t.get_ca_certificate_by_keyid.
- */
-static x509_t* get_ca_certificate_by_keyid(private_local_credential_store_t *this,
- chunk_t keyid)
-{
- x509_t *found = NULL;
- x509_t *current_cert;
-
- iterator_t *iterator = this->auth_certs->create_iterator(this->auth_certs, TRUE);
-
- while (iterator->iterate(iterator, (void**)&current_cert))
- {
- rsa_public_key_t *pubkey = current_cert->get_public_key(current_cert);
-
- if (current_cert->has_authority_flag(current_cert, AUTH_CA)
- && chunk_equals(keyid, pubkey->get_keyid(pubkey)))
- {
- found = current_cert;
- break;
- }
- }
- iterator->destroy(iterator);
-
- return found;
-}
-
-/**
- * Find an exact copy of a certificate in a linked list
- */
-static x509_t* find_certificate(linked_list_t *certs, x509_t *cert)
-{
- x509_t *found_cert = NULL, *current_cert;
-
- iterator_t *iterator = certs->create_iterator(certs, TRUE);
-
- while (iterator->iterate(iterator, (void**)&current_cert))
- {
- if (cert->equals(cert, current_cert))
- {
- found_cert = current_cert;
- break;
- }
- }
- iterator->destroy(iterator);
-
- return found_cert;
-}
-
-/**
- * Adds crl and ocsp uris to the corresponding issuer info record
- */
-static void add_uris(ca_info_t *issuer, x509_t *cert)
-{
- iterator_t *iterator;
- identification_t *uri;
-
- /* add any crl distribution points to the issuer ca info record */
- iterator = cert->create_crluri_iterator(cert);
-
- while (iterator->iterate(iterator, (void**)&uri))
- {
- if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
- {
- issuer->add_crluri(issuer, uri->get_encoding(uri));
- }
- }
- iterator->destroy(iterator);
-
- /* add any ocsp access points to the issuer ca info record */
- iterator = cert->create_ocspuri_iterator(cert);
-
- while (iterator->iterate(iterator, (void**)&uri))
- {
- if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
- {
- issuer->add_ocspuri(issuer, uri->get_encoding(uri));
- }
- }
- iterator->destroy(iterator);
-}
-
-/**
- * Implementation of credential_store_t.is_trusted
- */
-static bool is_trusted(private_local_credential_store_t *this, const char *label, x509_t *cert)
-{
- int pathlen;
- time_t until = UNDEFINED_TIME;
- x509_t *cert_to_be_trusted = cert;
-
- DBG1(DBG_CFG, "establishing trust in %s certificate:", label);
-
- for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
- {
- err_t ugh = NULL;
- ca_info_t *issuer;
- x509_t *issuer_cert;
- rsa_public_key_t *issuer_public_key;
- bool valid_signature;
-
- DBG1(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
- DBG1(DBG_CFG, "issuer: '%D'", cert->get_issuer(cert));
-
- ugh = cert->is_valid(cert, &until);
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "certificate %s", ugh);
- return FALSE;
- }
- DBG2(DBG_CFG, "certificate is valid");
-
- issuer = get_issuer(this, cert);
- if (issuer == NULL)
- {
- DBG1(DBG_CFG, "issuer not found");
- return FALSE;
- }
- DBG2(DBG_CFG, "issuer found");
-
- issuer_cert = issuer->get_certificate(issuer);
- issuer_public_key = issuer_cert->get_public_key(issuer_cert);
- valid_signature = cert->verify(cert, issuer_public_key);
-
- if (!valid_signature)
- {
- DBG1(DBG_CFG, "certificate signature is invalid");
- return FALSE;
- }
- DBG2(DBG_CFG, "certificate signature is valid");
-
- /* check if cert is a self-signed root ca */
- if (pathlen > 0 && cert->is_self_signed(cert))
- {
- DBG1(DBG_CFG, "reached self-signed root ca");
- cert_to_be_trusted->set_until(cert_to_be_trusted, until);
- cert_to_be_trusted->set_status(cert_to_be_trusted, CERT_GOOD);
- return TRUE;
- }
- else
- {
- DBG1(DBG_CFG, "going up one step in the certificate trust chain (%d)",
- pathlen + 1);
- cert = issuer_cert;
- }
- }
- DBG1(DBG_CFG, "maximum ca path length of %d levels reached", MAX_CA_PATH_LEN);
- return FALSE;
-}
-
-/**
- * Implementation of credential_store_t.verify.
- */
-static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *found)
-{
- int pathlen;
- time_t until = UNDEFINED_TIME;
-
- x509_t *end_cert = cert;
- x509_t *cert_copy = find_certificate(this->certs, end_cert);
-
- DBG1(DBG_CFG, "verifying end entity certificate up to trust anchor:");
-
- *found = (cert_copy != NULL);
- if (*found)
- {
- DBG2(DBG_CFG,
- "end entitity certificate is already in credential store");
- }
-
- for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
- {
- bool valid_signature;
- err_t ugh = NULL;
- ca_info_t *issuer;
- x509_t *issuer_cert;
- rsa_public_key_t *issuer_public_key;
- chunk_t keyid = cert->get_keyid(cert);
-
- DBG1(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
- DBG1(DBG_CFG, "issuer: '%D'", cert->get_issuer(cert));
- DBG1(DBG_CFG, "keyid: %#B", &keyid);
-
- ugh = cert->is_valid(cert, &until);
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "certificate %s", ugh);
- return FALSE;
- }
- DBG2(DBG_CFG, "certificate is valid");
-
- issuer = get_issuer(this, cert);
- if (issuer == NULL)
- {
- DBG1(DBG_CFG, "issuer not found");
- return FALSE;
- }
- DBG2(DBG_CFG, "issuer found");
-
- issuer_cert = issuer->get_certificate(issuer);
- issuer_public_key = issuer_cert->get_public_key(issuer_cert);
- valid_signature = cert->verify(cert, issuer_public_key);
-
- if (!valid_signature)
- {
- DBG1(DBG_CFG, "certificate signature is invalid");
- return FALSE;
- }
- DBG2(DBG_CFG, "certificate signature is valid");
-
- /* check if cert is a self-signed root ca */
- if (pathlen > 0 && cert->is_self_signed(cert))
- {
- DBG1(DBG_CFG, "reached self-signed root ca");
-
- /* set the definite status and trust interval of the end entity certificate */
- end_cert->set_until(end_cert, until);
- if (cert_copy)
- {
- cert_copy->set_status(cert_copy, end_cert->get_status(end_cert));
- cert_copy->set_until(cert_copy, until);
- }
- return TRUE;
- }
- else
- {
- bool strict;
- time_t nextUpdate;
- cert_status_t status;
- certinfo_t *certinfo = certinfo_create(cert->get_serialNumber(cert));
-
- if (pathlen == 0)
- {
- /* add any crl and ocsp uris contained in the certificate under test */
- add_uris(issuer, cert);
- }
-
- strict = issuer->is_strict(issuer);
- DBG1(DBG_CFG, "issuer %s a strict crl policy",
- strict ? "enforces":"does not enforce");
-
- /* first check certificate revocation using ocsp */
- status = issuer->verify_by_ocsp(issuer, certinfo, &this->public.credential_store);
-
- /* if ocsp service is not available then fall back to crl */
- if ((status == CERT_UNDEFINED) || (status == CERT_UNKNOWN && strict))
- {
-
- certinfo->set_status(certinfo, CERT_UNKNOWN);
- status = issuer->verify_by_crl(issuer, certinfo, CRL_DIR);
- }
-
- nextUpdate = certinfo->get_nextUpdate(certinfo);
- cert->set_status(cert, status);
-
- switch (status)
- {
- case CERT_GOOD:
- /* with strict crl policy the public key must have the same
- * lifetime as the validity of the ocsp status or crl lifetime
- */
- if (strict)
- {
- cert->set_until(cert, nextUpdate);
- until = (nextUpdate < until)? nextUpdate : until;
- }
-
- /* if status information is stale */
- if (strict && nextUpdate < time(NULL))
- {
- DBG2(DBG_CFG, "certificate is good but status is stale");
- certinfo->destroy(certinfo);
- return FALSE;
- }
- DBG1(DBG_CFG, "certificate is good");
- break;
- case CERT_REVOKED:
- {
- time_t revocationTime = certinfo->get_revocationTime(certinfo);
- DBG1(DBG_CFG,
- "certificate was revoked on %T, reason: %N",
- &revocationTime, crl_reason_names,
- certinfo->get_revocationReason(certinfo));
-
- /* set revocationTime */
- cert->set_until(cert, revocationTime);
-
- /* update status of end certificate in the credential store */
- if (cert_copy)
- {
- if (pathlen > 0)
- {
- cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
- }
- else
- {
- cert_copy->set_status(cert_copy, CERT_REVOKED);
- cert_copy->set_until(cert_copy,
- certinfo->get_revocationTime(certinfo));
- }
- }
- certinfo->destroy(certinfo);
- return FALSE;
- }
- case CERT_UNKNOWN:
- case CERT_UNDEFINED:
- default:
- DBG1(DBG_CFG, "certificate status unknown");
- if (strict)
- {
- /* update status of end certificate in the credential store */
- if (cert_copy)
- {
- cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
- }
- certinfo->destroy(certinfo);
- return FALSE;
- }
- break;
- }
- certinfo->destroy(certinfo);
- }
- DBG1(DBG_CFG, "going up one step in the certificate trust chain (%d)",
- pathlen + 1);
- cert = issuer_cert;
- }
- DBG1(DBG_CFG, "maximum ca path length of %d levels reached", MAX_CA_PATH_LEN);
- return FALSE;
-}
-
-/**
- * Implementation of local_credential_store_t.rsa_signature.
- */
-static status_t rsa_signature(private_local_credential_store_t *this,
- rsa_public_key_t *pubkey,
- hash_algorithm_t hash_algorithm,
- chunk_t data, chunk_t *signature)
-{
- rsa_private_key_t *current, *key = NULL;
- iterator_t *iterator;
- status_t status;
- chunk_t keyid = pubkey->get_keyid(pubkey);
-
- DBG2(DBG_IKE, "looking for RSA private key with keyid %#B...", &keyid);
- pthread_mutex_lock(&(this->keys_mutex));
-
- iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
- {
- if (current->belongs_to(current, pubkey))
- {
- key = current;
- break;
- }
- }
- iterator->destroy(iterator);
-
- if (key)
- {
- DBG2(DBG_IKE, " matching RSA private key found");
- status = key->build_emsa_pkcs1_signature(key, hash_algorithm, data, signature);
- }
- else
- {
- DBG1(DBG_IKE, "no RSA private key found with keyid %#B", &keyid);
- status = NOT_FOUND;
- }
- pthread_mutex_unlock(&(this->keys_mutex));
- return status;
-}
-
-/**
- * Implementation of local_credential_store_t.verify_signature.
- */
-static status_t verify_signature(private_local_credential_store_t *this,
- chunk_t hash, chunk_t signature,
- identification_t *id, ca_info_t **issuer_p)
-{
- iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
- status_t sig_status;
- x509_t *cert;
-
- /* default return values in case of failure */
- sig_status = NOT_FOUND;
- *issuer_p = NULL;
-
- while (iterator->iterate(iterator, (void**)&cert))
- {
- if (id->equals(id, cert->get_subject(cert))
- || cert->equals_subjectAltName(cert, id))
- {
- rsa_public_key_t *public_key = cert->get_public_key(cert);
- cert_status_t cert_status = cert->get_status(cert);
-
- DBG2(DBG_CFG, "found candidate peer certificate");
-
- if (cert_status == CERT_UNDEFINED || cert->get_until(cert) < time(NULL))
- {
- bool found;
-
- if (!verify(this, cert, &found))
- {
- sig_status = VERIFY_ERROR;
- DBG1(DBG_CFG, "candidate peer certificate was not successfully verified");
- continue;
- }
- *issuer_p = get_issuer(this, cert);
- }
- else
- {
- ca_info_t *issuer = get_issuer(this, cert);
- chunk_t keyid = public_key->get_keyid(public_key);
-
- DBG2(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
- DBG2(DBG_CFG, "issuer: '%D'", cert->get_issuer(cert));
- DBG2(DBG_CFG, "keyid: %#B", &keyid);
-
- if (issuer == NULL)
- {
- DBG1(DBG_CFG, "candidate peer certificate has no retrievable issuer");
- sig_status = NOT_FOUND;
- continue;
- }
- if (cert_status == CERT_REVOKED || cert_status == CERT_UNTRUSTED
- || ((issuer)->is_strict(issuer) && cert_status != CERT_GOOD))
- {
- DBG1(DBG_CFG, "candidate peer certificate has an inacceptable status: %N", cert_status_names, cert_status);
- sig_status = VERIFY_ERROR;
- continue;
- }
- *issuer_p = issuer;
- }
- sig_status = public_key->verify_emsa_pkcs1_signature(public_key, HASH_UNKNOWN, hash, signature);
- if (sig_status == SUCCESS)
- {
- DBG2(DBG_CFG, "candidate peer certificate has a matching RSA public key");
- break;
- }
- else
- {
- DBG1(DBG_CFG, "candidate peer certificate has a non-matching RSA public key");
- *issuer_p = NULL;
- }
- }
- }
- iterator->destroy(iterator);
- if (sig_status == NOT_FOUND)
- {
- DBG1(DBG_CFG, "no candidate peer certificate found");
- }
- return sig_status;
-}
-
-/**
- * Add a unique certificate to a linked list
- */
-static x509_t* add_certificate(linked_list_t *certs, x509_t *cert)
-{
- x509_t *found_cert = find_certificate(certs, cert);
-
- if (found_cert)
- {
- /* add the authority flags */
- found_cert->add_authority_flags(found_cert, cert->get_authority_flags(cert));
-
- cert->destroy(cert);
- return found_cert;
- }
- else
- {
- certs->insert_last(certs, (void*)cert);
- return cert;
- }
-}
-
-/**
- * Add a unique ca info record to a linked list
- */
-static ca_info_t* add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_info)
-{
- ca_info_t *current_ca_info;
- ca_info_t *found_ca_info = NULL;
-
- iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
-
- while (iterator->iterate(iterator, (void**)&current_ca_info))
- {
- if (current_ca_info->equals(current_ca_info, ca_info))
- {
- found_ca_info = current_ca_info;
- break;
- }
- }
- iterator->destroy(iterator);
-
- if (found_ca_info)
- {
- current_ca_info->add_info(current_ca_info, ca_info);
- ca_info->destroy(ca_info);
- ca_info = found_ca_info;
- }
- else
- {
- this->ca_infos->insert_last(this->ca_infos, (void*)ca_info);
- }
- return ca_info;
-}
-
-/**
- * Release ca info record of a given name
- */
-static status_t release_ca_info(private_local_credential_store_t *this, const char *name)
-{
- status_t status = NOT_FOUND;
- ca_info_t *ca_info;
-
- iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
-
- while (iterator->iterate(iterator, (void**)&ca_info))
- {
- if (ca_info->equals_name_release_info(ca_info, name))
- {
- status = SUCCESS;
- break;
- }
- }
- iterator->destroy(iterator);
-
- return status;
-}
-
-/**
- * Implements local_credential_store_t.add_end_certificate
- */
-static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_t *cert)
-{
- x509_t *ret_cert = add_certificate(this->certs, cert);
-
- /* add crl and ocsp uris the first time the certificate is added */
- if (ret_cert == cert)
- {
- ca_info_t *issuer = get_issuer(this, cert);
-
- if (issuer)
- {
- add_uris(issuer, cert);
- }
- }
- return ret_cert;
-}
-
-/**
- * Implements local_credential_store_t.add_auth_certificate
- */
-static x509_t* add_auth_certificate(private_local_credential_store_t *this, x509_t *cert, u_int auth_flags)
-{
- cert->add_authority_flags(cert, auth_flags);
- return add_certificate(this->auth_certs, cert);
-}
-
-/**
- * Implements local_credential_store_t.create_cert_iterator
- */
-static iterator_t* create_cert_iterator(private_local_credential_store_t *this)
-{
- return this->certs->create_iterator(this->certs, TRUE);
-}
-
-/**
- * Implements local_credential_store_t.create_cacert_iterator
- */
-static iterator_t* create_auth_cert_iterator(private_local_credential_store_t *this)
-{
- return this->auth_certs->create_iterator(this->auth_certs, TRUE);
-}
-
-/**
- * Implements local_credential_store_t.create_cainfo_iterator
- */
-static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this)
-{
- return this->ca_infos->create_iterator(this->ca_infos, TRUE);
-}
-
-/**
- * Implements local_credential_store_t.create_acert_iterator
- */
-static iterator_t* create_acert_iterator(private_local_credential_store_t *this)
-{
- return this->acerts->create_iterator_locked(this->acerts, &this->acerts_mutex);
-}
-
-/**
- * Implements local_credential_store_t.load_auth_certificates
- */
-static void load_auth_certificates(private_local_credential_store_t *this,
- u_int auth_flag,
- const char* label,
- const char* path)
-{
- struct dirent* entry;
- struct stat stb;
- DIR* dir;
-
- DBG1(DBG_CFG, "loading %s certificates from '%s'", label, path);
-
- dir = opendir(path);
- if (dir == NULL)
- {
- DBG1(DBG_CFG, "error opening %s certs directory '%s'", label, path);
- return;
- }
-
- while ((entry = readdir(dir)) != NULL)
- {
- char file[PATH_BUF];
-
- snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
-
- if (stat(file, &stb) == -1)
- {
- continue;
- }
- /* try to parse all regular files */
- if (stb.st_mode & S_IFREG)
- {
- x509_t *cert = x509_create_from_file(file, label);
-
- if (cert)
- {
- err_t ugh = cert->is_valid(cert, NULL);
-
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "warning: %s certificate %s", label, ugh);
- }
-
- if (auth_flag == AUTH_CA && !cert->is_ca(cert))
- {
- DBG1(DBG_CFG, " CA basic constraints flag not set, cert discarded");
- cert->destroy(cert);
- }
- else
- {
- x509_t *ret_cert;
-
- cert->add_authority_flags(cert, auth_flag);
-
- ret_cert = add_certificate(this->auth_certs, cert);
-
- if (auth_flag == AUTH_CA && ret_cert == cert)
- {
- ca_info_t *ca_info = ca_info_create(NULL, cert);
-
- add_ca_info(this, ca_info);
- }
- }
- }
- }
- }
- closedir(dir);
-}
-
-/**
- * Implements local_credential_store_t.load_ca_certificates
- */
-static void load_ca_certificates(private_local_credential_store_t *this)
-{
- load_auth_certificates(this, AUTH_CA, "ca", CA_CERTIFICATE_DIR);
-
- /* add any crl and ocsp uris found in the ca certificates to the
- * corresponding issuer info record. We can do this only after all
- * ca certificates have been loaded and the ca hierarchy is known.
- */
- {
- iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
- ca_info_t *ca_info;
-
- while (iterator->iterate(iterator, (void **)&ca_info))
- {
- if (ca_info->is_ca(ca_info))
- {
- x509_t *cacert = ca_info->get_certificate(ca_info);
- ca_info_t *issuer = get_issuer(this, cacert);
-
- if (issuer)
- {
- add_uris(issuer, cacert);
- }
- }
- }
- iterator->destroy(iterator);
- }
-}
-
-/**
- * Implements local_credential_store_t.load_aa_certificates
- */
-static void load_aa_certificates(private_local_credential_store_t *this)
-{
- load_auth_certificates(this, AUTH_AA, "aa", AA_CERTIFICATE_DIR);
-}
-
-/**
- * Add a unique attribute certificate to a linked list
- */
-static void add_attr_certificate(private_local_credential_store_t *this, x509ac_t *cert)
-{
- iterator_t *iterator;
- x509ac_t *current_cert;
- bool found = FALSE;
-
- pthread_mutex_lock(&(this->acerts_mutex));
- iterator = this->acerts->create_iterator(this->acerts, TRUE);
-
- while (iterator->iterate(iterator, (void **)&current_cert))
- {
- if (cert->equals_holder(cert, current_cert))
- {
- if (cert->is_newer(cert, current_cert))
- {
- iterator->replace(iterator, NULL, (void *)cert);
- current_cert->destroy(current_cert);
- DBG1(DBG_CFG, " this attr cert is newer - existing attr cert replaced");
- }
- else
- {
- cert->destroy(cert);
- DBG1(DBG_CFG, " this attr cert is not newer - existing attr cert retained");
- }
- found = TRUE;
- break;
- }
- }
- iterator->destroy(iterator);
-
- if (!found)
- {
- this->acerts->insert_last(this->acerts, (void *)cert);
- }
- pthread_mutex_unlock(&(this->acerts_mutex));
-}
-
-/**
- * Implements local_credential_store_t.load_attr_certificates
- */
-static void load_attr_certificates(private_local_credential_store_t *this)
-{
- struct dirent* entry;
- struct stat stb;
- DIR* dir;
-
- const char *path = ATTR_CERTIFICATE_DIR;
-
- DBG1(DBG_CFG, "loading attribute certificates from '%s'", path);
-
- dir = opendir(ATTR_CERTIFICATE_DIR);
- if (dir == NULL)
- {
- DBG1(DBG_CFG, "error opening attribute certs directory '%s'", path);
- return;
- }
-
- while ((entry = readdir(dir)) != NULL)
- {
- char file[PATH_BUF];
-
- snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
-
- if (stat(file, &stb) == -1)
- {
- continue;
- }
- /* try to parse all regular files */
- if (stb.st_mode & S_IFREG)
- {
- x509ac_t *cert = x509ac_create_from_file(file);
-
- if (cert)
- {
- err_t ugh = cert->is_valid(cert, NULL);
-
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "warning: attribute certificate %s", ugh);
- }
- add_attr_certificate(this, cert);
- }
- }
- }
- closedir(dir);
-
-
-}
-
-/**
- * Implements local_credential_store_t.load_ocsp_certificates
- */
-static void load_ocsp_certificates(private_local_credential_store_t *this)
-{
- load_auth_certificates(this, AUTH_OCSP, "ocsp", OCSP_CERTIFICATE_DIR);
-}
-
-/**
- * Add the latest crl to the issuing ca
- */
-static void add_crl(private_local_credential_store_t *this, crl_t *crl, const char *path)
-{
- iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
- ca_info_t *ca_info;
- bool found = FALSE;
-
- while (iterator->iterate(iterator, (void**)&ca_info))
- {
- if (ca_info->is_ca(ca_info) && ca_info->is_crl_issuer(ca_info, crl))
- {
- char buffer[BUF_LEN];
- chunk_t uri = { buffer, 7 + strlen(path) };
-
- ca_info->add_crl(ca_info, crl);
- if (uri.len < BUF_LEN)
- {
- snprintf(buffer, BUF_LEN, "file://%s", path);
- ca_info->add_crluri(ca_info, uri);
- }
- found = TRUE;
- break;
- }
- }
- iterator->destroy(iterator);
-
- if (!found)
- {
- crl->destroy(crl);
- DBG2(DBG_CFG, " no issuing ca found for this crl - discarded");
- }
-}
-
-/**
- * Implements local_credential_store_t.load_crls
- */
-static void load_crls(private_local_credential_store_t *this)
-{
- struct dirent* entry;
- struct stat stb;
- DIR* dir;
- crl_t *crl;
-
- DBG1(DBG_CFG, "loading crls from '%s'", CRL_DIR);
-
- dir = opendir(CRL_DIR);
- if (dir == NULL)
- {
- DBG1(DBG_CFG, "error opening crl directory '%s'", CRL_DIR);
- return;
- }
-
- while ((entry = readdir(dir)) != NULL)
- {
- char file[PATH_BUF];
-
- snprintf(file, sizeof(file), "%s/%s", CRL_DIR, entry->d_name);
-
- if (stat(file, &stb) == -1)
- {
- continue;
- }
- /* try to parse all regular files */
- if (stb.st_mode & S_IFREG)
- {
- crl = crl_create_from_file(file);
- if (crl)
- {
- DBG1(DBG_CFG, " crl is %s", crl->is_valid(crl)? "valid":"stale");
- add_crl(this, crl, file);
- }
- }
- }
- closedir(dir);
-}
-
-/**
- * Convert a string of characters into a binary secret
- * A string between single or double quotes is treated as ASCII characters
- * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
- */
-static err_t extract_secret(chunk_t *secret, chunk_t *line)
-{
- chunk_t raw_secret;
- char delimiter = ' ';
- bool quotes = FALSE;
-
- if (!eat_whitespace(line))
- {
- return "missing secret";
- }
-
- if (*line->ptr == '\'' || *line->ptr == '"')
- {
- quotes = TRUE;
- delimiter = *line->ptr;
- line->ptr++; line->len--;
- }
-
- if (!extract_token(&raw_secret, delimiter, line))
- {
- if (delimiter == ' ')
- {
- raw_secret = *line;
- }
- else
- {
- return "missing second delimiter";
- }
- }
-
- if (quotes)
- {
- /* treat as an ASCII string */
- *secret = chunk_clone(raw_secret);
- }
- else
- {
- size_t len;
- err_t ugh;
-
- /* secret converted to binary form doesn't use more space than the raw_secret */
- *secret = chunk_alloc(raw_secret.len);
-
- /* convert from HEX or Base64 to binary */
- ugh = ttodata(raw_secret.ptr, raw_secret.len, 0, secret->ptr, secret->len, &len);
-
- if (ugh != NULL)
- {
- chunk_free_randomized(secret);
- return ugh;
- }
- secret->len = len;
- }
- return NULL;
-}
-
-/**
- * Implements local_credential_store_t.load_secrets
- */
-static void load_secrets(private_local_credential_store_t *this, bool reload)
-{
- FILE *fd = fopen(SECRETS_FILE, "r");
-
- if (fd)
- {
- size_t bytes;
- int line_nr = 0;
- chunk_t chunk, src, line;
-
- DBG1(DBG_CFG, "%sloading secrets from \"%s\"",
- reload? "re":"", SECRETS_FILE);
-
- fseek(fd, 0, SEEK_END);
- chunk.len = ftell(fd);
- rewind(fd);
- chunk.ptr = malloc(chunk.len);
- bytes = fread(chunk.ptr, 1, chunk.len, fd);
- fclose(fd);
- src = chunk;
-
- pthread_mutex_lock(&(this->keys_mutex));
- if (reload)
- {
- DBG1(DBG_CFG, " forgetting old secrets");
- this->private_keys->destroy_offset(this->private_keys,
- offsetof(rsa_private_key_t, destroy));
- this->private_keys = linked_list_create();
-
- this->shared_keys->destroy_function(this->shared_keys,
- (void*)shared_key_destroy);
- this->shared_keys = linked_list_create();
-
- this->eap_keys->destroy_function(this->eap_keys,
- (void*)shared_key_destroy);
- this->eap_keys = linked_list_create();
- }
-
- while (fetchline(&src, &line))
- {
- chunk_t ids, token;
- bool is_eap = FALSE;
-
- line_nr++;
-
- if (!eat_whitespace(&line))
- {
- continue;
- }
- if (!extract_last_token(&ids, ':', &line))
- {
- DBG1(DBG_CFG, "line %d: missing ':' separator", line_nr);
- goto error;
- }
- /* NULL terminate the ids string by replacing the : separator */
- *(ids.ptr + ids.len) = '\0';
-
- if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
- {
- DBG1(DBG_CFG, "line %d: missing token", line_nr);
- goto error;
- }
- if (match("RSA", &token))
- {
- char path[PATH_BUF];
- chunk_t filename;
- chunk_t secret = chunk_empty;
- chunk_t *passphrase = NULL;
-
- rsa_private_key_t *key;
-
- err_t ugh = extract_value(&filename, &line);
-
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
- goto error;
- }
- if (filename.len == 0)
- {
- DBG1(DBG_CFG, "line %d: empty filename", line_nr);
- goto error;
- }
- if (*filename.ptr == '/')
- {
- /* absolute path name */
- snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
- }
- else
- {
- /* relative path name */
- snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR,
- filename.len, filename.ptr);
- }
-
- /* check for optional passphrase */
- if (eat_whitespace(&line))
- {
- ugh = extract_secret(&secret, &line);
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
- goto error;
- }
- if (secret.len > 0)
- passphrase = &secret;
- }
- key = rsa_private_key_create_from_file(path, passphrase);
- if (key)
- {
- this->private_keys->insert_last(this->private_keys, (void*)key);
- }
- chunk_free_randomized(&secret);
- }
- else if ( match("PSK", &token) ||
- ((match("EAP", &token) || match("XAUTH", &token)) && (is_eap = TRUE)))
- {
- shared_key_t *shared_key;
- chunk_t secret = chunk_empty;
-
- err_t ugh = extract_secret(&secret, &line);
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
- goto error;
- }
-
- DBG1(DBG_CFG, " loading %s key for %s",
- is_eap ? "EAP" : "shared",
- ids.len > 0 ? (char*)ids.ptr : "%any");
-
- DBG4(DBG_CFG, " secret:", secret);
-
- shared_key = shared_key_create(secret);
- if (is_eap)
- {
- this->eap_keys->insert_last(this->eap_keys, (void*)shared_key);
- }
- else
- {
- this->shared_keys->insert_last(this->shared_keys, (void*)shared_key);
- }
- while (ids.len > 0)
- {
- chunk_t id;
- identification_t *peer_id;
-
- ugh = extract_value(&id, &ids);
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
- goto error;
- }
- if (id.len == 0)
- {
- continue;
- }
-
- /* NULL terminate the ID string */
- *(id.ptr + id.len) = '\0';
-
- peer_id = identification_create_from_string(id.ptr);
- if (peer_id == NULL)
- {
- DBG1(DBG_CFG, "line %d: malformed ID: %s", line_nr, id.ptr);
- goto error;
- }
-
- if (peer_id->get_type(peer_id) == ID_ANY)
- {
- peer_id->destroy(peer_id);
- continue;
- }
- shared_key->peers->insert_last(shared_key->peers, (void*)peer_id);
- }
- }
- else if (match("PIN", &token))
- {
-
- }
- else
- {
- DBG1(DBG_CFG, "line %d: token must be either "
- "RSA, PSK, EAP, or PIN", line_nr, token.len);
- goto error;
- }
- }
-error:
- chunk_free_randomized(&chunk);
- pthread_mutex_unlock(&(this->keys_mutex));
- }
- else
- {
- DBG1(DBG_CFG, "could not open file '%s': %s", SECRETS_FILE,
- strerror(errno));
- }
-}
-
-/**
- * Implementation of local_credential_store_t.destroy.
- */
-static void destroy(private_local_credential_store_t *this)
-{
- this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy));
- this->auth_certs->destroy_offset(this->auth_certs, offsetof(x509_t, destroy));
- this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy));
-
- pthread_mutex_lock(&(this->acerts_mutex));
- this->acerts->destroy_offset(this->acerts, offsetof(x509ac_t, destroy));
- pthread_mutex_unlock(&(this->acerts_mutex));
-
- pthread_mutex_lock(&(this->keys_mutex));
- this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy));
- this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy);
- this->eap_keys->destroy_function(this->eap_keys, (void*)shared_key_destroy);
- pthread_mutex_unlock(&(this->keys_mutex));
-
- free(this);
-}
-
-/**
- * Described in header.
- */
-local_credential_store_t * local_credential_store_create(void)
-{
- private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
-
- /* public functions */
- this->public.credential_store.get_shared_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_shared_key;
- this->public.credential_store.get_eap_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_eap_key;
- this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
- this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
- this->public.credential_store.get_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_certificate;
- this->public.credential_store.get_auth_certificate = (x509_t* (*) (credential_store_t*,u_int,identification_t*))get_auth_certificate;
- this->public.credential_store.get_ca_certificate_by_keyid = (x509_t* (*) (credential_store_t*,chunk_t))get_ca_certificate_by_keyid;
- this->public.credential_store.get_issuer = (ca_info_t* (*) (credential_store_t*,x509_t*))get_issuer;
- this->public.credential_store.is_trusted = (bool (*) (credential_store_t*,const char*,x509_t*))is_trusted;
- this->public.credential_store.rsa_signature = (status_t (*) (credential_store_t*,rsa_public_key_t*,hash_algorithm_t,chunk_t,chunk_t*))rsa_signature;
- this->public.credential_store.verify_signature = (status_t (*) (credential_store_t*,chunk_t,chunk_t,identification_t*,ca_info_t**))verify_signature;
- this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
- this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
- this->public.credential_store.add_auth_certificate = (x509_t* (*) (credential_store_t*,x509_t*,u_int))add_auth_certificate;
- this->public.credential_store.add_ca_info = (ca_info_t* (*) (credential_store_t*,ca_info_t*))add_ca_info;
- this->public.credential_store.release_ca_info = (status_t (*) (credential_store_t*,const char*))release_ca_info;
- this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator;
- this->public.credential_store.create_auth_cert_iterator = (iterator_t* (*) (credential_store_t*))create_auth_cert_iterator;
- this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator;
- this->public.credential_store.create_acert_iterator = (iterator_t* (*) (credential_store_t*))create_acert_iterator;
- this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates;
- this->public.credential_store.load_aa_certificates = (void (*) (credential_store_t*))load_aa_certificates;
- this->public.credential_store.load_attr_certificates = (void (*) (credential_store_t*))load_attr_certificates;
- this->public.credential_store.load_ocsp_certificates = (void (*) (credential_store_t*))load_ocsp_certificates;
- this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls;
- this->public.credential_store.load_secrets = (void (*) (credential_store_t*,bool))load_secrets;
- this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy;
-
- /* initialize the mutexes */
- pthread_mutex_init(&(this->keys_mutex), NULL);
- pthread_mutex_init(&(this->acerts_mutex), NULL);
-
- /* private variables */
- this->shared_keys = linked_list_create();
- this->eap_keys = linked_list_create();
- this->private_keys = linked_list_create();
- this->certs = linked_list_create();
- this->auth_certs = linked_list_create();
- this->ca_infos = linked_list_create();
- this->acerts = linked_list_create();
-
- return (&this->public);
-}
diff --git a/src/charon/config/credentials/local_credential_store.h b/src/charon/config/credentials/local_credential_store.h
deleted file mode 100644
index 87a12663a..000000000
--- a/src/charon/config/credentials/local_credential_store.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file local_credential_store.h
- *
- * @brief Interface of local_credential_store_t.
- *
- */
-
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef LOCAL_CREDENTIAL_H_
-#define LOCAL_CREDENTIAL_H_
-
-typedef struct local_credential_store_t local_credential_store_t;
-
-#include <library.h>
-#include <credential_store.h>
-#include <daemon.h>
-
-
-/**
- * @brief A credential_store_t implementation using simple credentail lists.
- *
- * The local_credential_store_t class implements the credential_store_t interface
- * as simple as possible. The credentials are stored in lists, and are loaded from
- * files on the disk.
- * Shared secret are not handled yet, so get_shared_secret always returns NOT_FOUND.
- *
- * @b Constructors:
- * - local_credential_store_create(bool strict)
- *
- * @ingroup config
- */
-struct local_credential_store_t {
-
- /**
- * Implements credential_store_t interface
- */
- credential_store_t credential_store;
-};
-
-/**
- * @brief Creates a local_credential_store_t instance.
- *
- * @return credential store instance.
- *
- * @ingroup config
- */
-local_credential_store_t *local_credential_store_create(void);
-
-#endif /* LOCAL_CREDENTIAL_H_ */
diff --git a/src/charon/config/ike_cfg.c b/src/charon/config/ike_cfg.c
index abb300aab..8beccdc29 100644
--- a/src/charon/config/ike_cfg.c
+++ b/src/charon/config/ike_cfg.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_cfg.c
- *
- * @brief Implementation of ike_cfg_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,12 +12,16 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_cfg.c 4062 2008-06-12 11:42:19Z martin $
*/
#include "ike_cfg.h"
#include <string.h>
+#include <daemon.h>
+
typedef struct private_ike_cfg_t private_ike_cfg_t;
@@ -46,12 +43,12 @@ struct private_ike_cfg_t {
/**
* Address of local host
*/
- host_t *my_host;
+ char *me;
/**
* Address of remote host
*/
- host_t *other_host;
+ char *other;
/**
* should we send a certificate request?
@@ -86,19 +83,19 @@ static bool force_encap_meth(private_ike_cfg_t *this)
}
/**
- * Implementation of ike_cfg_t.get_my_host.
+ * Implementation of ike_cfg_t.get_my_addr.
*/
-static host_t *get_my_host (private_ike_cfg_t *this)
+static char *get_my_addr(private_ike_cfg_t *this)
{
- return this->my_host;
+ return this->me;
}
/**
- * Implementation of ike_cfg_t.get_other_host.
+ * Implementation of ike_cfg_t.get_other_addr.
*/
-static host_t *get_other_host (private_ike_cfg_t *this)
+static char *get_other_addr(private_ike_cfg_t *this)
{
- return this->other_host;
+ return this->other;
}
/**
@@ -141,6 +138,7 @@ static proposal_t *select_proposal(private_ike_cfg_t *this,
stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
supplied_iter = proposals->create_iterator(proposals, TRUE);
+
/* compare all stored proposals with all supplied. Stored ones are preferred.*/
while (stored_iter->iterate(stored_iter, (void**)&stored))
{
@@ -154,6 +152,9 @@ static proposal_t *select_proposal(private_ike_cfg_t *this,
/* they match, return */
stored_iter->destroy(stored_iter);
supplied_iter->destroy(supplied_iter);
+ DBG2(DBG_CFG, "received proposals: %#P", proposals);
+ DBG2(DBG_CFG, "configured proposals: %#P", this->proposals);
+ DBG2(DBG_CFG, "selected proposal: %P", selected);
return selected;
}
}
@@ -161,6 +162,8 @@ static proposal_t *select_proposal(private_ike_cfg_t *this,
/* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
stored_iter->destroy(stored_iter);
supplied_iter->destroy(supplied_iter);
+ DBG1(DBG_CFG, "received proposals: %#P", proposals);
+ DBG1(DBG_CFG, "configured proposals: %#P", this->proposals);
return NULL;
}
@@ -170,30 +173,71 @@ static proposal_t *select_proposal(private_ike_cfg_t *this,
*/
static diffie_hellman_group_t get_dh_group(private_ike_cfg_t *this)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
proposal_t *proposal;
- algorithm_t *algo;
- diffie_hellman_group_t dh_group = MODP_NONE;
+ u_int16_t dh_group = MODP_NONE;
- iterator = this->proposals->create_iterator(this->proposals, TRUE);
- while (iterator->iterate(iterator, (void**)&proposal))
+ enumerator = this->proposals->create_enumerator(this->proposals);
+ while (enumerator->enumerate(enumerator, &proposal))
{
- if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &algo))
+ if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &dh_group, NULL))
{
- dh_group = algo->algorithm;
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return dh_group;
}
/**
+ * Implementation of ike_cfg_t.equals.
+ */
+static bool equals(private_ike_cfg_t *this, private_ike_cfg_t *other)
+{
+ enumerator_t *e1, *e2;
+ proposal_t *p1, *p2;
+ bool eq = TRUE;
+
+ if (this == other)
+ {
+ return TRUE;
+ }
+ if (this->public.equals != other->public.equals)
+ {
+ return FALSE;
+ }
+ if (this->proposals->get_count(this->proposals) !=
+ other->proposals->get_count(other->proposals))
+ {
+ return FALSE;
+ }
+ e1 = this->proposals->create_enumerator(this->proposals);
+ e2 = this->proposals->create_enumerator(this->proposals);
+ while (e1->enumerate(e1, &p1) && e2->enumerate(e2, &p2))
+ {
+ if (!p1->equals(p1, p2))
+ {
+ eq = FALSE;
+ break;
+ }
+ }
+ e1->destroy(e1);
+ e2->destroy(e2);
+
+ return (eq &&
+ this->certreq == other->certreq &&
+ this->force_encap == other->force_encap &&
+ streq(this->me, other->me) &&
+ streq(this->other, other->other));
+}
+
+/**
* Implementation of ike_cfg_t.get_ref.
*/
-static void get_ref(private_ike_cfg_t *this)
+static ike_cfg_t* get_ref(private_ike_cfg_t *this)
{
ref_get(&this->refcount);
+ return &this->public;
}
/**
@@ -205,8 +249,8 @@ static void destroy(private_ike_cfg_t *this)
{
this->proposals->destroy_offset(this->proposals,
offsetof(proposal_t, destroy));
- this->my_host->destroy(this->my_host);
- this->other_host->destroy(this->other_host);
+ free(this->me);
+ free(this->other);
free(this);
}
}
@@ -215,29 +259,29 @@ static void destroy(private_ike_cfg_t *this)
* Described in header.
*/
ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
- host_t *my_host, host_t *other_host)
+ char *me, char *other)
{
private_ike_cfg_t *this = malloc_thing(private_ike_cfg_t);
/* public functions */
this->public.send_certreq = (bool(*)(ike_cfg_t*))send_certreq;
this->public.force_encap = (bool (*) (ike_cfg_t *))force_encap_meth;
- this->public.get_my_host = (host_t*(*)(ike_cfg_t*))get_my_host;
- this->public.get_other_host = (host_t*(*)(ike_cfg_t*))get_other_host;
+ this->public.get_my_addr = (char*(*)(ike_cfg_t*))get_my_addr;
+ this->public.get_other_addr = (char*(*)(ike_cfg_t*))get_other_addr;
this->public.add_proposal = (void(*)(ike_cfg_t*, proposal_t*)) add_proposal;
this->public.get_proposals = (linked_list_t*(*)(ike_cfg_t*))get_proposals;
this->public.select_proposal = (proposal_t*(*)(ike_cfg_t*,linked_list_t*))select_proposal;
this->public.get_dh_group = (diffie_hellman_group_t(*)(ike_cfg_t*)) get_dh_group;
- this->public.get_ref = (void(*)(ike_cfg_t*))get_ref;
+ this->public.equals = (bool(*)(ike_cfg_t*,ike_cfg_t*)) equals;
+ this->public.get_ref = (ike_cfg_t*(*)(ike_cfg_t*))get_ref;
this->public.destroy = (void(*)(ike_cfg_t*))destroy;
/* private variables */
this->refcount = 1;
this->certreq = certreq;
this->force_encap = force_encap;
- this->my_host = my_host;
- this->other_host = other_host;
-
+ this->me = strdup(me);
+ this->other = strdup(other);
this->proposals = linked_list_create();
return &this->public;
diff --git a/src/charon/config/ike_cfg.h b/src/charon/config/ike_cfg.h
index 5165d12a6..6169af96b 100644
--- a/src/charon/config/ike_cfg.h
+++ b/src/charon/config/ike_cfg.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_cfg.h
- *
- * @brief Interface of ike_cfg_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_cfg.h 4044 2008-06-06 15:05:54Z martin $
+ */
+
+/**
+ * @defgroup ike_cfg ike_cfg
+ * @{ @ingroup config
*/
#ifndef IKE_CFG_H_
@@ -34,128 +34,113 @@ typedef struct ike_cfg_t ike_cfg_t;
#include <crypto/diffie_hellman.h>
/**
- * @brief An ike_cfg_t defines the rules to set up an IKE_SA.
+ * An ike_cfg_t defines the rules to set up an IKE_SA.
*
* @see peer_cfg_t to get an overview over the configurations.
- *
- * @b Constructors:
- * - ike_cfg_create()
- *
- * @ingroup config
*/
struct ike_cfg_t {
/**
- * @brief Get own address.
+ * Get own address.
*
- * @param this calling object
- * @return host information as host_t object
+ * @return string of address/DNS name
*/
- host_t* (*get_my_host) (ike_cfg_t *this);
+ char* (*get_my_addr) (ike_cfg_t *this);
/**
- * @brief Get peers address.
+ * Get peers address.
*
- * @param this calling object
- * @return host information as host_t object
+ * @return string of address/DNS name
*/
- host_t* (*get_other_host) (ike_cfg_t *this);
+ char* (*get_other_addr) (ike_cfg_t *this);
/**
- * @brief Adds a proposal to the list.
+ * Adds a proposal to the list.
*
* The first added proposal has the highest priority, the last
* added the lowest.
*
- * @param this calling object
* @param proposal proposal to add
*/
void (*add_proposal) (ike_cfg_t *this, proposal_t *proposal);
/**
- * @brief Returns a list of all supported proposals.
+ * Returns a list of all supported proposals.
*
* Returned list and its proposals must be destroyed after use.
*
- * @param this calling object
* @return list containing all the proposals
*/
linked_list_t* (*get_proposals) (ike_cfg_t *this);
/**
- * @brief Select a proposed from suggested proposals.
+ * Select a proposed from suggested proposals.
*
* Returned proposal must be destroyed after use.
*
- * @param this calling object
* @param proposals list of proposals to select from
* @return selected proposal, or NULL if none matches.
*/
proposal_t *(*select_proposal) (ike_cfg_t *this, linked_list_t *proposals);
/**
- * @brief Should we send a certificate request in IKE_SA_INIT?
+ * Should we send a certificate request in IKE_SA_INIT?
*
- * @param this calling object
* @return certificate request sending policy
*/
bool (*send_certreq) (ike_cfg_t *this);
/**
- * @brief Enforce UDP encapsulation by faking NATD notifies?
+ * Enforce UDP encapsulation by faking NATD notifies?
*
- * @param this calling object
* @return TRUE to enfoce UDP encapsulation
*/
bool (*force_encap) (ike_cfg_t *this);
/**
- * @brief Get the DH group to use for IKE_SA setup.
+ * Get the DH group to use for IKE_SA setup.
*
- * @param this calling object
* @return dh group to use for initialization
*/
diffie_hellman_group_t (*get_dh_group)(ike_cfg_t *this);
/**
- * @brief Get a new reference to this ike_cfg.
+ * Check if two IKE configs are equal.
*
- * Get a new reference to this ike_cfg by increasing
- * it's internal reference counter.
- * Do not call get_ref or any other function until you
- * already have a reference. Otherwise the object may get
- * destroyed while calling get_ref(),
+ * @param other other to check for equality
+ * @return TRUE if other equal to this
+ */
+ bool (*equals)(ike_cfg_t *this, ike_cfg_t *other);
+
+ /**
+ * Increase reference count.
*
- * @param this calling object
+ * @return reference to this
*/
- void (*get_ref) (ike_cfg_t *this);
+ ike_cfg_t* (*get_ref) (ike_cfg_t *this);
/**
- * @brief Destroys a ike_cfg_t object.
+ * Destroys a ike_cfg_t object.
*
* Decrements the internal reference counter and
* destroys the ike_cfg when it reaches zero.
- *
- * @param this calling object
*/
void (*destroy) (ike_cfg_t *this);
};
/**
- * @brief Creates a ike_cfg_t object.
+ * Creates a ike_cfg_t object.
*
* Supplied hosts become owned by ike_cfg, the name gets cloned.
*
* @param name ike_cfg identifier
* @param certreq TRUE to send a certificate request
* @param force_encap enforce UDP encapsulation by faking NATD notify
- * @param my_host host_t representing local address
- * @param other_host host_t representing remote address
+ * @param me address/DNS name of local peer
+ * @param other address/DNS name of remote peer
* @return ike_cfg_t object.
- *
- * @ingroup config
*/
ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
- host_t *my_host, host_t *other_host);
+ char *me, char *other);
-#endif /* IKE_CFG_H_ */
+#endif /* IKE_CFG_H_ @} */
diff --git a/src/charon/config/peer_cfg.c b/src/charon/config/peer_cfg.c
index 0b5d391c4..0e56759c2 100644
--- a/src/charon/config/peer_cfg.c
+++ b/src/charon/config/peer_cfg.c
@@ -1,12 +1,5 @@
-/**
- * @file peer_cfg.c
- *
- * @brief Implementation of peer_cfg_t.
- *
- */
-
/*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -20,6 +13,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: peer_cfg.c 4051 2008-06-10 09:08:27Z tobias $
*/
#include <string.h>
@@ -29,19 +24,23 @@
#include <utils/linked_list.h>
#include <utils/identification.h>
-#include <crypto/ietf_attr_list.h>
ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
"CERT_ALWAYS_SEND",
"CERT_SEND_IF_ASKED",
- "CERT_NEVER_SEND"
+ "CERT_NEVER_SEND",
);
-ENUM(dpd_action_names, DPD_NONE, DPD_RESTART,
- "DPD_NONE",
- "DPD_CLEAR",
- "DPD_ROUTE",
- "DPD_RESTART"
+ENUM(unique_policy_names, UNIQUE_NO, UNIQUE_KEEP,
+ "UNIQUE_NO",
+ "UNIQUE_REPLACE",
+ "UNIQUE_KEEP",
+);
+
+ENUM(config_auth_method_names, CONF_AUTH_PUBKEY, CONF_AUTH_EAP,
+ "CONF_AUTH_PUBKEY",
+ "CONF_AUTH_PSK",
+ "CONF_AUTH_EAP",
);
typedef struct private_peer_cfg_t private_peer_cfg_t;
@@ -97,29 +96,19 @@ struct private_peer_cfg_t {
identification_t *other_id;
/**
- * we have a cert issued by this CA
- */
- identification_t *my_ca;
-
- /**
- * we require the other end to have a cert issued by this CA
- */
- identification_t *other_ca;
-
- /**
- * we require the other end to belong to at least one group
+ * should we send a certificate
*/
- linked_list_t *groups;
+ cert_policy_t cert_policy;
/**
- * should we send a certificate
+ * uniqueness of an IKE_SA
*/
- cert_policy_t cert_policy;
+ unique_policy_t unique;
/**
* Method to use for own authentication data
*/
- auth_method_t auth_method;
+ config_auth_method_t auth_method;
/**
* EAP type to use for peer authentication
@@ -162,42 +151,42 @@ struct private_peer_cfg_t {
u_int32_t over_time;
/**
- * What to do with an SA when other peer seams to be dead?
+ * DPD check intervall
*/
- bool dpd_delay;
+ u_int32_t dpd;
/**
- * What to do with CHILDren when other peer seams to be dead?
+ * virtual IP to use locally
*/
- bool dpd_action;
+ host_t *virtual_ip;
/**
- * virtual IP to use locally
+ * pool to acquire configuration attributes from
*/
- host_t *my_virtual_ip;
+ char *pool;
/**
- * virtual IP to use remotly
+ * required authorization constraints
*/
- host_t *other_virtual_ip;
+ auth_info_t *auth;
-#ifdef P2P
+#ifdef ME
/**
* Is this a mediation connection?
*/
- bool p2p_mediation;
+ bool mediation;
/**
* Name of the mediation connection to mediate through
*/
- peer_cfg_t *p2p_mediated_by;
+ peer_cfg_t *mediated_by;
/**
* ID of our peer at the mediation server (= leftid of the peer's conn with
* the mediation server)
*/
identification_t *peer_id;
-#endif /* P2P */
+#endif /* ME */
};
/**
@@ -235,12 +224,26 @@ static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg)
}
/**
- * Implementation of peer_cfg_t.create_child_cfg_iterator.
+ * Implementation of peer_cfg_t.remove_child_cfg.
+ */
+static void remove_child_cfg(private_peer_cfg_t *this, enumerator_t *enumerator)
+{
+ pthread_mutex_lock(&this->mutex);
+ this->child_cfgs->remove_at(this->child_cfgs, enumerator);
+ pthread_mutex_unlock(&this->mutex);
+}
+
+/**
+ * Implementation of peer_cfg_t.create_child_cfg_enumerator.
*/
-static iterator_t* create_child_cfg_iterator(private_peer_cfg_t *this)
+static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this)
{
- return this->child_cfgs->create_iterator_locked(this->child_cfgs,
- &this->mutex);
+ enumerator_t *enumerator;
+
+ pthread_mutex_lock(&this->mutex);
+ enumerator = this->child_cfgs->create_enumerator(this->child_cfgs);
+ return enumerator_create_cleaner(enumerator,
+ (void*)pthread_mutex_unlock, &this->mutex);
}
/**
@@ -267,20 +270,19 @@ static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
host_t *my_host, host_t *other_host)
{
child_cfg_t *current, *found = NULL;
- iterator_t *iterator;
+ enumerator_t *enumerator;
- iterator = create_child_cfg_iterator(this);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = create_child_cfg_enumerator(this);
+ while (enumerator->enumerate(enumerator, &current))
{
if (contains_ts(current, TRUE, my_ts, my_host) &&
contains_ts(current, FALSE, other_ts, other_host))
{
- found = current;
- found->get_ref(found);
+ found = current->get_ref(current);
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return found;
}
@@ -301,47 +303,31 @@ static identification_t *get_other_id(private_peer_cfg_t *this)
}
/**
- * Implementation of peer_cfg_t.get_my_ca
- */
-static identification_t *get_my_ca(private_peer_cfg_t *this)
-{
- return this->my_ca;
-}
-
-/**
- * Implementation of peer_cfg_t.get_other_ca
- */
-static identification_t *get_other_ca(private_peer_cfg_t *this)
-{
- return this->other_ca;
-}
-
-/**
- * Implementation of peer_cfg_t.get_groups
+ * Implementation of peer_cfg_t.get_cert_policy.
*/
-static linked_list_t *get_groups(private_peer_cfg_t *this)
+static cert_policy_t get_cert_policy(private_peer_cfg_t *this)
{
- return this->groups;
+ return this->cert_policy;
}
/**
- * Implementation of peer_cfg_t.get_cert_policy.
+ * Implementation of peer_cfg_t.get_unique_policy.
*/
-static cert_policy_t get_cert_policy(private_peer_cfg_t *this)
+static unique_policy_t get_unique_policy(private_peer_cfg_t *this)
{
- return this->cert_policy;
+ return this->unique;
}
/**
- * Implementation of connection_t.auth_method_t.
+ * Implementation of peer_cfg_t.get_auth_method.
*/
-static auth_method_t get_auth_method(private_peer_cfg_t *this)
+static config_auth_method_t get_auth_method(private_peer_cfg_t *this)
{
return this->auth_method;
}
/**
- * Implementation of connection_t.get_eap_type.
+ * Implementation of peer_cfg_t.get_eap_type.
*/
static eap_type_t get_eap_type(private_peer_cfg_t *this, u_int32_t *vendor)
{
@@ -350,7 +336,7 @@ static eap_type_t get_eap_type(private_peer_cfg_t *this, u_int32_t *vendor)
}
/**
- * Implementation of connection_t.get_keyingtries.
+ * Implementation of peer_cfg_t.get_keyingtries.
*/
static u_int32_t get_keyingtries(private_peer_cfg_t *this)
{
@@ -406,60 +392,44 @@ static bool use_mobike(private_peer_cfg_t *this)
}
/**
- * Implements peer_cfg_t.get_dpd_delay
+ * Implements peer_cfg_t.get_dpd
*/
-static u_int32_t get_dpd_delay(private_peer_cfg_t *this)
+static u_int32_t get_dpd(private_peer_cfg_t *this)
{
- return this->dpd_delay;
+ return this->dpd;
}
/**
- * Implements peer_cfg_t.get_dpd_action
+ * Implementation of peer_cfg_t.get_virtual_ip.
*/
-static dpd_action_t get_dpd_action(private_peer_cfg_t *this)
+static host_t* get_virtual_ip(private_peer_cfg_t *this)
{
- return this->dpd_action;
+ return this->virtual_ip;
}
-
+
/**
- * Implementation of peer_cfg_t.get_my_virtual_ip.
+ * Implementation of peer_cfg_t.get_pool.
*/
-static host_t* get_my_virtual_ip(private_peer_cfg_t *this)
+static char* get_pool(private_peer_cfg_t *this)
{
- if (this->my_virtual_ip == NULL)
- {
- return NULL;
- }
- return this->my_virtual_ip->clone(this->my_virtual_ip);
+ return this->pool;
}
-
+
/**
- * Implementation of peer_cfg_t.get_other_virtual_ip.
+ * Implementation of peer_cfg_t.get_auth.
*/
-static host_t* get_other_virtual_ip(private_peer_cfg_t *this, host_t *suggestion)
+static auth_info_t* get_auth(private_peer_cfg_t *this)
{
- if (this->other_virtual_ip == NULL)
- { /* disallow */
- return NULL;
- }
- if (!this->other_virtual_ip->is_anyaddr(this->other_virtual_ip))
- { /* force own configuration */
- return this->other_virtual_ip->clone(this->other_virtual_ip);
- }
- if (suggestion == NULL || suggestion->is_anyaddr(suggestion))
- {
- return NULL;
- }
- return suggestion->clone(suggestion);
+ return this->auth;
}
-#ifdef P2P
+#ifdef ME
/**
* Implementation of peer_cfg_t.is_mediation.
*/
static bool is_mediation(private_peer_cfg_t *this)
{
- return this->p2p_mediation;
+ return this->mediation;
}
/**
@@ -467,11 +437,7 @@ static bool is_mediation(private_peer_cfg_t *this)
*/
static peer_cfg_t* get_mediated_by(private_peer_cfg_t *this)
{
- if (this->p2p_mediated_by) {
- this->p2p_mediated_by->get_ref(this->p2p_mediated_by);
- return this->p2p_mediated_by;
- }
- return NULL;
+ return this->mediated_by;
}
/**
@@ -481,14 +447,61 @@ static identification_t* get_peer_id(private_peer_cfg_t *this)
{
return this->peer_id;
}
-#endif /* P2P */
+#endif /* ME */
+
+/**
+ * Implementation of peer_cfg_t.equals.
+ */
+static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
+{
+ if (this == other)
+ {
+ return TRUE;
+ }
+ if (this->public.equals != other->public.equals)
+ {
+ return FALSE;
+ }
+
+ return (
+ this->ike_version == other->ike_version &&
+ this->my_id->equals(this->my_id, other->my_id) &&
+ this->other_id->equals(this->other_id, other->other_id) &&
+ this->cert_policy == other->cert_policy &&
+ this->unique == other->unique &&
+ this->auth_method == other->auth_method &&
+ this->eap_type == other->eap_type &&
+ this->eap_vendor == other->eap_vendor &&
+ this->keyingtries == other->keyingtries &&
+ this->use_mobike == other->use_mobike &&
+ this->rekey_time == other->rekey_time &&
+ this->reauth_time == other->reauth_time &&
+ this->jitter_time == other->jitter_time &&
+ this->over_time == other->over_time &&
+ this->dpd == other->dpd &&
+ (this->virtual_ip == other->virtual_ip ||
+ (this->virtual_ip && other->virtual_ip &&
+ this->virtual_ip->equals(this->virtual_ip, other->virtual_ip))) &&
+ (this->pool == other->pool ||
+ (this->pool && other->pool && streq(this->pool, other->pool))) &&
+ this->auth->equals(this->auth, other->auth)
+#ifdef ME
+ && this->mediation == other->mediation &&
+ this->mediated_by == other->mediated_by &&
+ (this->peer_id == other->peer_id ||
+ (this->peer_id && other->peer_id &&
+ this->peer_id->equals(this->peer_id, other->peer_id)))
+#endif /* ME */
+ );
+}
/**
* Implements peer_cfg_t.get_ref.
*/
-static void get_ref(private_peer_cfg_t *this)
+static peer_cfg_t* get_ref(private_peer_cfg_t *this)
{
ref_get(&this->refcount);
+ return &this->public;
}
/**
@@ -502,16 +515,14 @@ static void destroy(private_peer_cfg_t *this)
this->child_cfgs->destroy_offset(this->child_cfgs, offsetof(child_cfg_t, destroy));
this->my_id->destroy(this->my_id);
this->other_id->destroy(this->other_id);
- DESTROY_IF(this->my_ca);
- DESTROY_IF(this->other_ca);
- DESTROY_IF(this->my_virtual_ip);
- DESTROY_IF(this->other_virtual_ip);
-#ifdef P2P
- DESTROY_IF(this->p2p_mediated_by);
+ DESTROY_IF(this->virtual_ip);
+ this->auth->destroy(this->auth);
+#ifdef ME
+ DESTROY_IF(this->mediated_by);
DESTROY_IF(this->peer_id);
-#endif /* P2P */
- ietfAttr_list_destroy(this->groups);
+#endif /* ME */
free(this->name);
+ free(this->pool);
free(this);
}
}
@@ -521,16 +532,14 @@ static void destroy(private_peer_cfg_t *this)
*/
peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
identification_t *my_id, identification_t *other_id,
- identification_t *my_ca, identification_t *other_ca,
- linked_list_t *groups, cert_policy_t cert_policy,
- auth_method_t auth_method, eap_type_t eap_type,
+ cert_policy_t cert_policy, unique_policy_t unique,
+ config_auth_method_t auth_method, eap_type_t eap_type,
u_int32_t eap_vendor,
u_int32_t keyingtries, u_int32_t rekey_time,
u_int32_t reauth_time, u_int32_t jitter_time,
- u_int32_t over_time, bool mobike,
- u_int32_t dpd_delay, dpd_action_t dpd_action,
- host_t *my_virtual_ip, host_t *other_virtual_ip,
- bool p2p_mediation, peer_cfg_t *p2p_mediated_by,
+ u_int32_t over_time, bool mobike, u_int32_t dpd,
+ host_t *virtual_ip, char *pool,
+ bool mediation, peer_cfg_t *mediated_by,
identification_t *peer_id)
{
private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t);
@@ -540,32 +549,32 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version;
this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg;
this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg;
- this->public.create_child_cfg_iterator = (iterator_t* (*) (peer_cfg_t *))create_child_cfg_iterator;
+ this->public.remove_child_cfg = (void(*)(peer_cfg_t*, enumerator_t*))remove_child_cfg;
+ this->public.create_child_cfg_enumerator = (enumerator_t* (*) (peer_cfg_t *))create_child_cfg_enumerator;
this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg;
this->public.get_my_id = (identification_t* (*)(peer_cfg_t*))get_my_id;
this->public.get_other_id = (identification_t* (*)(peer_cfg_t *))get_other_id;
- this->public.get_my_ca = (identification_t* (*)(peer_cfg_t *))get_my_ca;
- this->public.get_other_ca = (identification_t* (*)(peer_cfg_t *))get_other_ca;
- this->public.get_groups = (linked_list_t* (*)(peer_cfg_t *))get_groups;
this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
- this->public.get_auth_method = (auth_method_t (*) (peer_cfg_t *))get_auth_method;
+ this->public.get_unique_policy = (unique_policy_t (*) (peer_cfg_t *))get_unique_policy;
+ this->public.get_auth_method = (config_auth_method_t (*) (peer_cfg_t *))get_auth_method;
this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *,u_int32_t*))get_eap_type;
this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time;
this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time;
this->public.get_over_time = (u_int32_t(*)(peer_cfg_t*))get_over_time;
this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
- this->public.get_dpd_delay = (u_int32_t (*) (peer_cfg_t *))get_dpd_delay;
- this->public.get_dpd_action = (dpd_action_t (*) (peer_cfg_t *))get_dpd_action;
- this->public.get_my_virtual_ip = (host_t* (*) (peer_cfg_t *))get_my_virtual_ip;
- this->public.get_other_virtual_ip = (host_t* (*) (peer_cfg_t *, host_t *))get_other_virtual_ip;
- this->public.get_ref = (void(*)(peer_cfg_t *))get_ref;
+ this->public.get_dpd = (u_int32_t (*) (peer_cfg_t *))get_dpd;
+ this->public.get_virtual_ip = (host_t* (*) (peer_cfg_t *))get_virtual_ip;
+ this->public.get_pool = (char*(*)(peer_cfg_t*))get_pool;
+ this->public.get_auth = (auth_info_t*(*)(peer_cfg_t*))get_auth;
+ this->public.equals = (bool(*)(peer_cfg_t*, peer_cfg_t *other))equals;
+ this->public.get_ref = (peer_cfg_t*(*)(peer_cfg_t *))get_ref;
this->public.destroy = (void(*)(peer_cfg_t *))destroy;
-#ifdef P2P
+#ifdef ME
this->public.is_mediation = (bool (*) (peer_cfg_t *))is_mediation;
this->public.get_mediated_by = (peer_cfg_t* (*) (peer_cfg_t *))get_mediated_by;
this->public.get_peer_id = (identification_t* (*) (peer_cfg_t *))get_peer_id;
-#endif /* P2P */
+#endif /* ME */
/* apply init values */
this->name = strdup(name);
@@ -575,10 +584,8 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
pthread_mutex_init(&this->mutex, NULL);
this->my_id = my_id;
this->other_id = other_id;
- this->my_ca = my_ca;
- this->other_ca = other_ca;
- this->groups = groups;
this->cert_policy = cert_policy;
+ this->unique = unique;
this->auth_method = auth_method;
this->eap_type = eap_type;
this->eap_vendor = eap_vendor;
@@ -596,16 +603,19 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->jitter_time = jitter_time;
this->over_time = over_time;
this->use_mobike = mobike;
- this->dpd_delay = dpd_delay;
- this->dpd_action = dpd_action;
- this->my_virtual_ip = my_virtual_ip;
- this->other_virtual_ip = other_virtual_ip;
+ this->dpd = dpd;
+ this->virtual_ip = virtual_ip;
+ this->pool = pool ? strdup(pool) : NULL;
+ this->auth = auth_info_create();
this->refcount = 1;
-#ifdef P2P
- this->p2p_mediation = p2p_mediation;
- this->p2p_mediated_by = p2p_mediated_by;
+#ifdef ME
+ this->mediation = mediation;
+ this->mediated_by = mediated_by;
this->peer_id = peer_id;
-#endif /* P2P */
+#else /* ME */
+ DESTROY_IF(mediated_by);
+ DESTROY_IF(peer_id);
+#endif /* ME */
return &this->public;
}
diff --git a/src/charon/config/peer_cfg.h b/src/charon/config/peer_cfg.h
index 7f1dbcab6..5662b48df 100644
--- a/src/charon/config/peer_cfg.h
+++ b/src/charon/config/peer_cfg.h
@@ -1,12 +1,5 @@
-/**
- * @file peer_cfg.h
- *
- * @brief Interface of peer_cfg_t.
- *
- */
-
/*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -20,32 +13,39 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: peer_cfg.h 4054 2008-06-10 20:31:53Z andreas $
+ */
+
+/**
+ * @defgroup peer_cfg peer_cfg
+ * @{ @ingroup config
*/
#ifndef PEER_CFG_H_
#define PEER_CFG_H_
-typedef enum dpd_action_t dpd_action_t;
typedef enum cert_policy_t cert_policy_t;
+typedef enum unique_policy_t unique_policy_t;
+typedef enum config_auth_method_t config_auth_method_t;
typedef struct peer_cfg_t peer_cfg_t;
#include <library.h>
#include <utils/identification.h>
-#include <utils/linked_list.h>
+#include <utils/enumerator.h>
#include <config/traffic_selector.h>
#include <config/proposal.h>
#include <config/ike_cfg.h>
#include <config/child_cfg.h>
#include <sa/authenticators/authenticator.h>
#include <sa/authenticators/eap/eap_method.h>
+#include <credentials/auth_info.h>
/**
* Certificate sending policy. This is also used for certificate
* requests when using this definition for the other peer. If
* it is CERT_NEVER_SEND, a certreq is omitted, otherwise its
* included.
- *
- * @ingroup config
*
* @warning These definitions must be the same as in pluto/starter,
* as they are sent over the stroke socket.
@@ -61,36 +61,45 @@ enum cert_policy_t {
/**
* enum strings for cert_policy_t
- *
- * @ingroup config
*/
extern enum_name_t *cert_policy_names;
/**
- * @brief Actions to take when a peer does not respond (dead peer detected).
- *
- * These values are the same as in pluto/starter, so do not modify them!
- *
- * @ingroup config
+ * Uniqueness of an IKE_SA, used to drop multiple connections with one peer.
*/
-enum dpd_action_t {
- /** DPD disabled */
- DPD_NONE,
- /** remove CHILD_SAs without replacement */
- DPD_CLEAR,
- /** route the CHILD_SAs to resetup when needed */
- DPD_ROUTE,
- /** restart CHILD_SAs in a new IKE_SA, immediately */
- DPD_RESTART,
+enum unique_policy_t {
+ /** do not check for client uniqueness */
+ UNIQUE_NO,
+ /** replace unique IKE_SAs if new ones get established */
+ UNIQUE_REPLACE,
+ /** keep existing IKE_SAs, close the new ones on connection attept */
+ UNIQUE_KEEP,
};
/**
- * enum names for dpd_action_t.
+ * enum strings for unique_policy_t
*/
-extern enum_name_t *dpd_action_names;
+extern enum_name_t *unique_policy_names;
/**
- * @brief Configuration of a peer, specified by IDs.
+ * Authentication method for this IKE_SA.
+ */
+enum config_auth_method_t {
+ /** authentication using public keys (RSA, ECDSA) */
+ CONF_AUTH_PUBKEY = 1,
+ /** authentication using a pre-shared secret */
+ CONF_AUTH_PSK = 2,
+ /** authentication using EAP */
+ CONF_AUTH_EAP = 3,
+};
+
+/**
+ * enum strings for config_auth_method_t
+ */
+extern enum_name_t *config_auth_method_names;
+
+/**
+ * Configuration of a peer, specified by IDs.
*
* The peer config defines a connection between two given IDs. It contains
* exactly one ike_cfg_t, which is use for initiation. Additionally, it contains
@@ -106,61 +115,67 @@ extern enum_name_t *dpd_action_names;
| - ... | | - dpd config | | - ... |-+
+---------------+ | - ... | +---------------+
+-------------------+
+ ^
+ |
+ +-------------------+
+ | auth_info |
+ +-------------------+
+ | auth_items |
+ +-------------------+
@endverbatim
- *
- * @b Constructors:
- * - peer_cfg_create()
- *
- * @ingroup config
+ * The auth_info_t object associated to the peer_cfg holds additional
+ * authorization constraints. A peer who wants to use a config needs to fullfil
+ * the requirements defined in auth_info.
*/
struct peer_cfg_t {
/**
- * @brief Get the name of the peer_cfg.
+ * Get the name of the peer_cfg.
*
* Returned object is not getting cloned.
*
- * @param this calling object
* @return peer_cfg's name
*/
char* (*get_name) (peer_cfg_t *this);
/**
- * @brief Get the IKE version to use for initiating.
+ * Get the IKE version to use for initiating.
*
- * @param this calling object
* @return IKE major version
*/
u_int (*get_ike_version)(peer_cfg_t *this);
/**
- * @brief Get the IKE config to use for initiaton.
+ * Get the IKE config to use for initiaton.
*
- * @param this calling object
* @return the IKE config to use
*/
ike_cfg_t* (*get_ike_cfg) (peer_cfg_t *this);
/**
- * @brief Attach a CHILD config.
+ * Attach a CHILD config.
*
- * @param this calling object
* @param child_cfg CHILD config to add
*/
void (*add_child_cfg) (peer_cfg_t *this, child_cfg_t *child_cfg);
/**
- * @brief Create an iterator for all attached CHILD configs.
+ * Detach a CHILD config, pointed to by an enumerator.
+ *
+ * @param enumerator enumerator indicating element position
+ */
+ void (*remove_child_cfg)(peer_cfg_t *this, enumerator_t *enumerator);
+
+ /**
+ * Create an enumerator for all attached CHILD configs.
*
- * @param this calling object
- * @return an iterator over all CHILD configs.
+ * @return an enumerator over all CHILD configs.
*/
- iterator_t* (*create_child_cfg_iterator) (peer_cfg_t *this);
+ enumerator_t* (*create_child_cfg_enumerator) (peer_cfg_t *this);
/**
- * @brief Select a CHILD config from traffic selectors.
+ * Select a CHILD config from traffic selectors.
*
- * @param this calling object
* @param my_ts TS for local side
* @param other_ts TS for remote side
* @param my_host host to narrow down dynamic TS for local side
@@ -172,213 +187,176 @@ struct peer_cfg_t {
host_t *other_host);
/**
- * @brief Get own ID.
+ * Get the authentication constraint items.
+ *
+ * @return auth_info object to manipulate requirements
+ */
+ auth_info_t* (*get_auth)(peer_cfg_t *this);
+
+ /**
+ * Get own ID.
*
- * @param this calling object
* @return own id
*/
identification_t* (*get_my_id)(peer_cfg_t *this);
/**
- * @brief Get peers ID.
+ * Get peers ID.
*
- * @param this calling object
* @return other id
*/
identification_t* (*get_other_id)(peer_cfg_t *this);
-
- /**
- * @brief Get own CA.
- *
- * @param this calling object
- * @return own ca
- */
- identification_t* (*get_my_ca)(peer_cfg_t *this);
/**
- * @brief Get peer CA.
- *
- * @param this calling object
- * @return other ca
- */
- identification_t* (*get_other_ca)(peer_cfg_t *this);
-
- /**
- * @brief Get list of group attributes.
- *
- * @param this calling object
- * @return linked list of group attributes
+ * Should be sent a certificate for this connection?
+ *
+ * @return certificate sending policy
*/
- linked_list_t* (*get_groups)(peer_cfg_t *this);
+ cert_policy_t (*get_cert_policy) (peer_cfg_t *this);
/**
- * @brief Should be sent a certificate for this connection?
+ * How to handle uniqueness of IKE_SAs?
*
- * @param this calling object
- * @return certificate sending policy
+ * @return unique policy
*/
- cert_policy_t (*get_cert_policy) (peer_cfg_t *this);
+ unique_policy_t (*get_unique_policy) (peer_cfg_t *this);
/**
- * @brief Get the authentication method to use to authenticate us.
+ * Get the authentication method to use to authenticate us.
*
- * @param this calling object
* @return authentication method
*/
- auth_method_t (*get_auth_method) (peer_cfg_t *this);
+ config_auth_method_t (*get_auth_method) (peer_cfg_t *this);
/**
- * @brief Get the EAP type to use for peer authentication.
+ * Get the EAP type to use for peer authentication.
*
* If vendor specific types are used, a vendor ID != 0 is returned to
* to vendor argument. Then the returned type is specific for that
* vendor ID.
*
- * @param this calling object
* @param vendor receives vendor specifier, 0 for predefined EAP types
* @return authentication method
*/
eap_type_t (*get_eap_type) (peer_cfg_t *this, u_int32_t *vendor);
/**
- * @brief Get the max number of retries after timeout.
+ * Get the max number of retries after timeout.
*
- * @param this calling object
* @return max number retries
*/
u_int32_t (*get_keyingtries) (peer_cfg_t *this);
/**
- * @brief Get a time to start rekeying (is randomized with jitter).
+ * Get a time to start rekeying (is randomized with jitter).
*
- * @param this calling object
* @return time in s when to start rekeying, 0 disables rekeying
*/
u_int32_t (*get_rekey_time)(peer_cfg_t *this);
/**
- * @brief Get a time to start reauthentication (is randomized with jitter).
+ * Get a time to start reauthentication (is randomized with jitter).
*
- * @param this calling object
* @return time in s when to start reauthentication, 0 disables it
*/
u_int32_t (*get_reauth_time)(peer_cfg_t *this);
/**
- * @brief Get the timeout of a rekeying/reauthenticating SA.
+ * Get the timeout of a rekeying/reauthenticating SA.
*
- * @param thsi calling object
* @return timeout in s
*/
u_int32_t (*get_over_time)(peer_cfg_t *this);
/**
- * @brief Use MOBIKE (RFC4555) if peer supports it?
+ * Use MOBIKE (RFC4555) if peer supports it?
*
- * @param this calling object
* @return TRUE to enable MOBIKE support
*/
bool (*use_mobike) (peer_cfg_t *this);
/**
- * @brief Get the DPD check interval.
+ * Get the DPD check interval.
*
- * @param this calling object
* @return dpd_delay in seconds
*/
- u_int32_t (*get_dpd_delay) (peer_cfg_t *this);
+ u_int32_t (*get_dpd) (peer_cfg_t *this);
/**
- * @brief What should be done with a CHILD_SA, when other peer does not respond.
- *
- * @param this calling object
- * @return dpd action
- */
- dpd_action_t (*get_dpd_action) (peer_cfg_t *this);
-
- /**
- * @brief Get a virtual IP for the local peer.
+ * Get a virtual IP for the local peer.
*
* If no virtual IP should be used, NULL is returned. %any means to request
* a virtual IP using configuration payloads. A specific address is also
* used for a request and may be changed by the server.
*
- * @param this peer_cfg
* @param suggestion NULL, %any or specific
- * @return clone of an IP, %any or NULL
+ * @return virtual IP, %any or NULL
*/
- host_t* (*get_my_virtual_ip) (peer_cfg_t *this);
+ host_t* (*get_virtual_ip) (peer_cfg_t *this);
/**
- * @brief Get a virtual IP for the remote peer.
- *
- * An IP may be supplied, if one was requested by the initiator. However,
- * the suggestion is not more as it says, any address may be returned, even
- * NULL to not use virtual IPs.
+ * Get the name of the pool to acquire configuration attributes from.
*
- * @param this peer_cfg
- * @param suggestion NULL, %any or specific
- * @return clone of an IP to use
+ * @return pool name, NULL if none defined
*/
- host_t* (*get_other_virtual_ip) (peer_cfg_t *this, host_t *suggestion);
-
-#ifdef P2P
+ char* (*get_pool)(peer_cfg_t *this);
+
+#ifdef ME
/**
- * @brief Is this a mediation connection?
+ * Is this a mediation connection?
*
- * @param this peer_cfg
* @return TRUE, if this is a mediation connection
*/
bool (*is_mediation) (peer_cfg_t *this);
/**
- * @brief Get peer_cfg of the connection this one is mediated through.
+ * Get peer_cfg of the connection this one is mediated through.
*
- * @param this peer_cfg
- * @return reference to peer_cfg of the mediation connection
+ * @return the peer_cfg of the mediation connection
*/
peer_cfg_t* (*get_mediated_by) (peer_cfg_t *this);
/**
- * @brief Get the id of the other peer at the mediation server.
+ * Get the id of the other peer at the mediation server.
*
* This is the leftid of the peer's connection with the mediation server.
*
* If it is not configured, it is assumed to be the same as the right id
* of this connection.
*
- * @param this peer_cfg
* @return the id of the other peer
*/
identification_t* (*get_peer_id) (peer_cfg_t *this);
-#endif /* P2P */
+#endif /* ME */
+
+ /**
+ * Check if two peer configurations are equal.
+ *
+ * This method does not compare associated ike/child_cfg.
+ *
+ * @param other candidate to check for equality against this
+ * @return TRUE if peer_cfg and ike_cfg are equal
+ */
+ bool (*equals)(peer_cfg_t *this, peer_cfg_t *other);
/**
- * @brief Get a new reference.
+ * Increase reference count.
*
- * Get a new reference to this peer_cfg by increasing
- * it's internal reference counter.
- * Do not call get_ref or any other function until you
- * already have a reference. Otherwise the object may get
- * destroyed while calling get_ref(),
- *
- * @param this calling object
+ * @return reference to this
*/
- void (*get_ref) (peer_cfg_t *this);
+ peer_cfg_t* (*get_ref) (peer_cfg_t *this);
/**
- * @brief Destroys the peer_cfg object.
+ * Destroys the peer_cfg object.
*
* Decrements the internal reference counter and
* destroys the peer_cfg when it reaches zero.
- *
- * @param this calling object
*/
void (*destroy) (peer_cfg_t *this);
};
/**
- * @brief Create a configuration object for IKE_AUTH and later.
+ * Create a configuration object for IKE_AUTH and later.
*
* name-string gets cloned, ID's not.
* Virtual IPs are used if they are != NULL. A %any host means the virtual
@@ -392,10 +370,8 @@ struct peer_cfg_t {
* @param ike_cfg IKE config to use when acting as initiator
* @param my_id identification_t for ourselves
* @param other_id identification_t for the remote guy
- * @param my_ca CA to use for us
- * @param other_ca CA to use for other
- * @param groups list of group memberships
* @param cert_policy should we send a certificate payload?
+ * @param unique uniqueness of an IKE_SA
* @param auth_method auth method to use to authenticate us
* @param eap_type EAP type to use for peer authentication
* @param eap_vendor EAP vendor identifier, if vendor specific type is used
@@ -406,29 +382,24 @@ struct peer_cfg_t {
* @param over_time maximum overtime before closing a rekeying/reauth SA
* @param reauth sould be done reauthentication instead of rekeying?
* @param mobike use MOBIKE (RFC4555) if peer supports it
- * @param dpd_delay after how many seconds of inactivity to check DPD
- * @param dpd_action what to do with CHILD_SAs when detected a dead peer
- * @param my_virtual_ip virtual IP for local host, or NULL
- * @param other_virtual_ip virtual IP for remote host, or NULL
- * @param p2p_mediation TRUE if this is a mediation connection
- * @param p2p_mediated_by name of the mediation connection to mediate through
+ * @param dpd DPD check interval, 0 to disable
+ * @param virtual_ip virtual IP for local host, or NULL
+ * @param pool pool name to get configuration attributes from, or NULL
+ * @param mediation TRUE if this is a mediation connection
+ * @param mediated_by peer_cfg_t of the mediation connection to mediate through
* @param peer_id ID that identifies our peer at the mediation server
* @return peer_cfg_t object
- *
- * @ingroup config
*/
peer_cfg_t *peer_cfg_create(char *name, u_int ikev_version, ike_cfg_t *ike_cfg,
identification_t *my_id, identification_t *other_id,
- identification_t *my_ca, identification_t *other_ca,
- linked_list_t *groups, cert_policy_t cert_policy,
- auth_method_t auth_method, eap_type_t eap_type,
+ cert_policy_t cert_policy, unique_policy_t unique,
+ config_auth_method_t auth_method, eap_type_t eap_type,
u_int32_t eap_vendor,
u_int32_t keyingtries, u_int32_t rekey_time,
u_int32_t reauth_time, u_int32_t jitter_time,
- u_int32_t over_time, bool mobike,
- u_int32_t dpd_delay, dpd_action_t dpd_action,
- host_t *my_virtual_ip, host_t *other_virtual_ip,
- bool p2p_mediation, peer_cfg_t *p2p_mediated_by,
+ u_int32_t over_time, bool mobike, u_int32_t dpd,
+ host_t *virtual_ip, char *pool,
+ bool mediation, peer_cfg_t *mediated_by,
identification_t *peer_id);
-#endif /* PEER_CFG_H_ */
+#endif /* PEER_CFG_H_ @} */
diff --git a/src/charon/config/proposal.c b/src/charon/config/proposal.c
index cff9859c1..803cf8ae4 100644
--- a/src/charon/config/proposal.c
+++ b/src/charon/config/proposal.c
@@ -1,11 +1,5 @@
-/**
- * @file proposal.c
- *
- * @brief Implementation of proposal_t.
- *
- */
-
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -18,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: proposal.c 4062 2008-06-12 11:42:19Z martin $
*/
#include <string.h>
@@ -51,11 +47,12 @@ ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS,
ENUM_END(transform_type_names, EXTENDED_SEQUENCE_NUMBERS);
ENUM(extended_sequence_numbers_names, NO_EXT_SEQ_NUMBERS, EXT_SEQ_NUMBERS,
- "NO_EXT_SEQ_NUMBERS",
- "EXT_SEQ_NUMBERS",
+ "NO_EXT_SEQ",
+ "EXT_SEQ",
);
typedef struct private_proposal_t private_proposal_t;
+typedef struct algorithm_t algorithm_t;
/**
* Private data of an proposal_t object
@@ -104,9 +101,24 @@ struct private_proposal_t {
};
/**
+ * Struct used to store different kinds of algorithms.
+ */
+struct algorithm_t {
+ /**
+ * Value from an encryption_algorithm_t/integrity_algorithm_t/...
+ */
+ u_int16_t algorithm;
+
+ /**
+ * the associated key size in bits, or zero if not needed
+ */
+ u_int16_t key_size;
+};
+
+/**
* Add algorithm/keysize to a algorithm list
*/
-static void add_algo(linked_list_t *list, u_int16_t algo, size_t key_size)
+static void add_algo(linked_list_t *list, u_int16_t algo, u_int16_t key_size)
{
algorithm_t *algo_key;
@@ -119,7 +131,8 @@ static void add_algo(linked_list_t *list, u_int16_t algo, size_t key_size)
/**
* Implements proposal_t.add_algorithm
*/
-static void add_algorithm(private_proposal_t *this, transform_type_t type, u_int16_t algo, size_t key_size)
+static void add_algorithm(private_proposal_t *this, transform_type_t type,
+ u_int16_t algo, u_int16_t key_size)
{
switch (type)
{
@@ -144,41 +157,68 @@ static void add_algorithm(private_proposal_t *this, transform_type_t type, u_int
}
/**
- * Implements proposal_t.create_algorithm_iterator.
+ * filter function for peer configs
+ */
+static bool alg_filter(void *null, algorithm_t **in, u_int16_t *alg,
+ void **unused, u_int16_t *key_size)
+{
+ algorithm_t *algo = *in;
+ *alg = algo->algorithm;
+ if (key_size)
+ {
+ *key_size = algo->key_size;
+ }
+ return TRUE;
+}
+
+/**
+ * Implements proposal_t.create_enumerator.
*/
-static iterator_t *create_algorithm_iterator(private_proposal_t *this, transform_type_t type)
+static enumerator_t *create_enumerator(private_proposal_t *this,
+ transform_type_t type)
{
+ linked_list_t *list;
+
switch (type)
{
case ENCRYPTION_ALGORITHM:
- return this->encryption_algos->create_iterator(this->encryption_algos, TRUE);
+ list = this->encryption_algos;
+ break;
case INTEGRITY_ALGORITHM:
- return this->integrity_algos->create_iterator(this->integrity_algos, TRUE);
+ list = this->integrity_algos;
+ break;
case PSEUDO_RANDOM_FUNCTION:
- return this->prf_algos->create_iterator(this->prf_algos, TRUE);
+ list = this->prf_algos;
+ break;
case DIFFIE_HELLMAN_GROUP:
- return this->dh_groups->create_iterator(this->dh_groups, TRUE);
+ list = this->dh_groups;
+ break;
case EXTENDED_SEQUENCE_NUMBERS:
- return this->esns->create_iterator(this->esns, TRUE);
- default:
+ list = this->esns;
break;
+ default:
+ return NULL;
}
- return NULL;
+ return enumerator_create_filter(list->create_enumerator(list),
+ (void*)alg_filter, NULL, NULL);
}
/**
* Implements proposal_t.get_algorithm.
*/
-static bool get_algorithm(private_proposal_t *this, transform_type_t type, algorithm_t** algo)
+static bool get_algorithm(private_proposal_t *this, transform_type_t type,
+ u_int16_t *alg, u_int16_t *key_size)
{
- iterator_t *iterator = create_algorithm_iterator(this, type);
- if (iterator->iterate(iterator, (void**)algo))
+ enumerator_t *enumerator;
+ bool found = FALSE;
+
+ enumerator = create_enumerator(this, type);
+ if (enumerator->enumerate(enumerator, alg, key_size))
{
- iterator->destroy(iterator);
- return TRUE;
+ found = TRUE;
}
- iterator->destroy(iterator);
- return FALSE;
+ enumerator->destroy(enumerator);
+ return found;
}
/**
@@ -186,14 +226,15 @@ static bool get_algorithm(private_proposal_t *this, transform_type_t type, algor
*/
static bool has_dh_group(private_proposal_t *this, diffie_hellman_group_t group)
{
- algorithm_t *current;
- iterator_t *iterator;
bool result = FALSE;
- iterator = this->dh_groups->create_iterator(this->dh_groups, TRUE);
- if (iterator->get_count(iterator))
+ if (this->dh_groups->get_count(this->dh_groups))
{
- while (iterator->iterate(iterator, (void**)&current))
+ algorithm_t *current;
+ enumerator_t *enumerator;
+
+ enumerator = this->dh_groups->create_enumerator(this->dh_groups);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
if (current->algorithm == group)
{
@@ -201,22 +242,54 @@ static bool has_dh_group(private_proposal_t *this, diffie_hellman_group_t group)
break;
}
}
+ enumerator->destroy(enumerator);
}
else if (group == MODP_NONE)
{
result = TRUE;
}
- iterator->destroy(iterator);
return result;
}
/**
+ * Implementation of proposal_t.strip_dh.
+ */
+static void strip_dh(private_proposal_t *this)
+{
+ algorithm_t *alg;
+
+ while (this->dh_groups->remove_last(this->dh_groups, (void**)&alg) == SUCCESS)
+ {
+ free(alg);
+ }
+}
+
+/**
+ * Returns true if the given alg is an authenticated encryption algorithm
+ */
+static bool is_authenticated_encryption(u_int16_t alg)
+{
+ switch(alg)
+ {
+ case ENCR_AES_CCM_ICV8:
+ case ENCR_AES_CCM_ICV12:
+ case ENCR_AES_CCM_ICV16:
+ case ENCR_AES_GCM_ICV8:
+ case ENCR_AES_GCM_ICV12:
+ case ENCR_AES_GCM_ICV16:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
* Find a matching alg/keysize in two linked lists
*/
-static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add, u_int16_t *alg, size_t *key_size)
+static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add,
+ u_int16_t *alg, size_t *key_size)
{
- iterator_t *first_iter, *second_iter;
- algorithm_t *first_alg, *second_alg;
+ enumerator_t *e1, *e2;
+ algorithm_t *alg1, *alg2;
/* if in both are zero algorithms specified, we HAVE a match */
if (first->get_count(first) == 0 && second->get_count(second) == 0)
@@ -225,30 +298,31 @@ static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add,
return TRUE;
}
- first_iter = first->create_iterator(first, TRUE);
- second_iter = second->create_iterator(second, TRUE);
+ e1 = first->create_enumerator(first);
+ e2 = second->create_enumerator(second);
/* compare algs, order of algs in "first" is preferred */
- while (first_iter->iterate(first_iter, (void**)&first_alg))
+ while (e1->enumerate(e1, &alg1))
{
- second_iter->reset(second_iter);
- while (second_iter->iterate(second_iter, (void**)&second_alg))
+ e2->destroy(e2);
+ e2 = second->create_enumerator(second);
+ while (e2->enumerate(e2, &alg2))
{
- if (first_alg->algorithm == second_alg->algorithm &&
- first_alg->key_size == second_alg->key_size)
+ if (alg1->algorithm == alg2->algorithm &&
+ alg1->key_size == alg2->key_size)
{
/* ok, we have an algorithm */
- *alg = first_alg->algorithm;
- *key_size = first_alg->key_size;
+ *alg = alg1->algorithm;
+ *key_size = alg1->key_size;
*add = TRUE;
- first_iter->destroy(first_iter);
- second_iter->destroy(second_iter);
+ e1->destroy(e1);
+ e2->destroy(e2);
return TRUE;
}
}
}
/* no match in all comparisons */
- first_iter->destroy(first_iter);
- second_iter->destroy(second_iter);
+ e1->destroy(e1);
+ e2->destroy(e2);
return FALSE;
}
@@ -274,45 +348,57 @@ static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t
selected = proposal_create(this->protocol);
/* select encryption algorithm */
- if (select_algo(this->encryption_algos, other->encryption_algos, &add, &algo, &key_size))
+ if (select_algo(this->encryption_algos, other->encryption_algos,
+ &add, &algo, &key_size))
{
if (add)
{
- selected->add_algorithm(selected, ENCRYPTION_ALGORITHM, algo, key_size);
+ selected->add_algorithm(selected, ENCRYPTION_ALGORITHM,
+ algo, key_size);
}
}
else
{
selected->destroy(selected);
- DBG2(DBG_CFG, " no acceptable ENCRYPTION_ALGORITHM found, skipping");
+ DBG2(DBG_CFG, " no acceptable %N found",
+ transform_type_names, ENCRYPTION_ALGORITHM);
return NULL;
}
/* select integrity algorithm */
- if (select_algo(this->integrity_algos, other->integrity_algos, &add, &algo, &key_size))
+ if (!is_authenticated_encryption(algo))
{
- if (add)
+ if (select_algo(this->integrity_algos, other->integrity_algos,
+ &add, &algo, &key_size))
{
- selected->add_algorithm(selected, INTEGRITY_ALGORITHM, algo, key_size);
+ if (add)
+ {
+ selected->add_algorithm(selected, INTEGRITY_ALGORITHM,
+ algo, key_size);
+ }
+ }
+ else
+ {
+ selected->destroy(selected);
+ DBG2(DBG_CFG, " no acceptable %N found",
+ transform_type_names, INTEGRITY_ALGORITHM);
+ return NULL;
}
- }
- else
- {
- selected->destroy(selected);
- DBG2(DBG_CFG, " no acceptable INTEGRITY_ALGORITHM found, skipping");
- return NULL;
}
/* select prf algorithm */
- if (select_algo(this->prf_algos, other->prf_algos, &add, &algo, &key_size))
+ if (select_algo(this->prf_algos, other->prf_algos,
+ &add, &algo, &key_size))
{
if (add)
{
- selected->add_algorithm(selected, PSEUDO_RANDOM_FUNCTION, algo, key_size);
+ selected->add_algorithm(selected, PSEUDO_RANDOM_FUNCTION,
+ algo, key_size);
}
}
else
{
selected->destroy(selected);
- DBG2(DBG_CFG, " no acceptable PSEUDO_RANDOM_FUNCTION found, skipping");
+ DBG2(DBG_CFG, " no acceptable %N found",
+ transform_type_names, PSEUDO_RANDOM_FUNCTION);
return NULL;
}
/* select a DH-group */
@@ -326,7 +412,8 @@ static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t
else
{
selected->destroy(selected);
- DBG2(DBG_CFG, " no acceptable DIFFIE_HELLMAN_GROUP found, skipping");
+ DBG2(DBG_CFG, " no acceptable %N found",
+ transform_type_names, DIFFIE_HELLMAN_GROUP);
return NULL;
}
/* select if we use ESNs */
@@ -340,7 +427,8 @@ static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t
else
{
selected->destroy(selected);
- DBG2(DBG_CFG, " no acceptable EXTENDED_SEQUENCE_NUMBERS found, skipping");
+ DBG2(DBG_CFG, " no acceptable %N found",
+ transform_type_names, EXTENDED_SEQUENCE_NUMBERS);
return NULL;
}
DBG2(DBG_CFG, " proposal matches");
@@ -382,14 +470,67 @@ static u_int64_t get_spi(private_proposal_t *this)
static void clone_algo_list(linked_list_t *list, linked_list_t *clone_list)
{
algorithm_t *algo, *clone_algo;
- iterator_t *iterator = list->create_iterator(list, TRUE);
- while (iterator->iterate(iterator, (void**)&algo))
+ enumerator_t *enumerator;
+
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &algo))
{
clone_algo = malloc_thing(algorithm_t);
memcpy(clone_algo, algo, sizeof(algorithm_t));
clone_list->insert_last(clone_list, (void*)clone_algo);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * check if an algorithm list equals
+ */
+static bool algo_list_equals(linked_list_t *l1, linked_list_t *l2)
+{
+ enumerator_t *e1, *e2;
+ algorithm_t *alg1, *alg2;
+ bool equals = TRUE;
+
+ if (l1->get_count(l1) != l2->get_count(l2))
+ {
+ return FALSE;
+ }
+
+ e1 = l1->create_enumerator(l1);
+ e2 = l2->create_enumerator(l2);
+ while (e1->enumerate(e1, &alg1) && e2->enumerate(e2, &alg2))
+ {
+ if (alg1->algorithm != alg2->algorithm ||
+ alg1->key_size != alg2->key_size)
+ {
+ equals = FALSE;
+ break;
+ }
+ }
+ e1->destroy(e1);
+ e2->destroy(e2);
+ return equals;
+}
+
+/**
+ * Implementation of proposal_t.equals.
+ */
+static bool equals(private_proposal_t *this, private_proposal_t *other)
+{
+ if (this == other)
+ {
+ return TRUE;
+ }
+ if (this->public.equals != other->public.equals)
+ {
+ return FALSE;
+ }
+ return (
+ algo_list_equals(this->encryption_algos, other->encryption_algos) &&
+ algo_list_equals(this->integrity_algos, other->integrity_algos) &&
+ algo_list_equals(this->prf_algos, other->prf_algos) &&
+ algo_list_equals(this->dh_groups, other->dh_groups) &&
+ algo_list_equals(this->esns, other->esns));
}
/**
@@ -411,6 +552,38 @@ static proposal_t *clone_(private_proposal_t *this)
}
/**
+ * Checks the proposal read from a string.
+ */
+static void check_proposal(private_proposal_t *this)
+{
+ enumerator_t *e;
+ algorithm_t *alg;
+ bool all_aead = TRUE;
+
+ e = this->encryption_algos->create_enumerator(this->encryption_algos);
+ while (e->enumerate(e, &alg))
+ {
+ if (!is_authenticated_encryption(alg->algorithm))
+ {
+ all_aead = FALSE;
+ break;
+ }
+ }
+ e->destroy(e);
+
+ if (all_aead)
+ {
+ /* if all encryption algorithms in the proposal are authenticated encryption
+ * algorithms we MUST NOT propose any integrity algorithms */
+ while (this->integrity_algos->remove_last(this->integrity_algos,
+ (void**)&alg) == SUCCESS)
+ {
+ free(alg);
+ }
+ }
+}
+
+/**
* add a algorithm identified by a string to the proposal.
* TODO: we could use gperf here.
*/
@@ -432,6 +605,70 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
{
add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256);
}
+ else if (strstr(alg.ptr, "ccm"))
+ {
+ u_int16_t key_size, icv_size;
+
+ if (sscanf(alg.ptr, "aes%huccm%hu", &key_size, &icv_size) == 2)
+ {
+ if (key_size == 128 || key_size == 192 || key_size == 256)
+ {
+ switch (icv_size)
+ {
+ case 8: /* octets */
+ case 64: /* bits */
+ add_algorithm(this, ENCRYPTION_ALGORITHM,
+ ENCR_AES_CCM_ICV8, key_size);
+ break;
+ case 12: /* octets */
+ case 96: /* bits */
+ add_algorithm(this, ENCRYPTION_ALGORITHM,
+ ENCR_AES_CCM_ICV12, key_size);
+ break;
+ case 16: /* octets */
+ case 128: /* bits */
+ add_algorithm(this, ENCRYPTION_ALGORITHM,
+ ENCR_AES_CCM_ICV16, key_size);
+ break;
+ default:
+ /* invalid ICV size */
+ break;
+ }
+ }
+ }
+ }
+ else if (strstr(alg.ptr, "gcm"))
+ {
+ u_int16_t key_size, icv_size;
+
+ if (sscanf(alg.ptr, "aes%hugcm%hu", &key_size, &icv_size) == 2)
+ {
+ if (key_size == 128 || key_size == 192 || key_size == 256)
+ {
+ switch (icv_size)
+ {
+ case 8: /* octets */
+ case 64: /* bits */
+ add_algorithm(this, ENCRYPTION_ALGORITHM,
+ ENCR_AES_GCM_ICV8, key_size);
+ break;
+ case 12: /* octets */
+ case 96: /* bits */
+ add_algorithm(this, ENCRYPTION_ALGORITHM,
+ ENCR_AES_GCM_ICV12, key_size);
+ break;
+ case 16: /* octets */
+ case 128: /* bits */
+ add_algorithm(this, ENCRYPTION_ALGORITHM,
+ ENCR_AES_GCM_ICV16, key_size);
+ break;
+ default:
+ /* invalid ICV size */
+ break;
+ }
+ }
+ }
+ }
else if (strncmp(alg.ptr, "3des", alg.len) == 0)
{
add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_3DES, 0);
@@ -499,7 +736,7 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0);
if (this->protocol == PROTO_IKE)
{
- add_algorithm(this, PSEUDO_RANDOM_FUNCTION, AUTH_AES_XCBC_96, 0);
+ add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_AES128_XCBC, 0);
}
}
else if (strncmp(alg.ptr, "modp768", alg.len) == 0)
@@ -526,6 +763,26 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
{
add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0);
}
+ else if (strncmp(alg.ptr, "ecp192", alg.len) == 0)
+ {
+ add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_192_BIT, 0);
+ }
+ else if (strncmp(alg.ptr, "ecp224", alg.len) == 0)
+ {
+ add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_224_BIT, 0);
+ }
+ else if (strncmp(alg.ptr, "ecp256", alg.len) == 0)
+ {
+ add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_256_BIT, 0);
+ }
+ else if (strncmp(alg.ptr, "ecp384", alg.len) == 0)
+ {
+ add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_384_BIT, 0);
+ }
+ else if (strncmp(alg.ptr, "ecp521", alg.len) == 0)
+ {
+ add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0);
+ }
else
{
return FAILED;
@@ -534,6 +791,109 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
}
/**
+ * print all algorithms of a kind to stream
+ */
+static int print_alg(private_proposal_t *this, FILE *stream, u_int kind,
+ void *names, bool *first)
+{
+ enumerator_t *enumerator;
+ size_t written = 0;
+ u_int16_t alg, size;
+
+ enumerator = create_enumerator(this, kind);
+ while (enumerator->enumerate(enumerator, &alg, &size))
+ {
+ if (*first)
+ {
+ written += fprintf(stream, "%N", names, alg);
+ *first = FALSE;
+ }
+ else
+ {
+ written += fprintf(stream, "/%N", names, alg);
+ }
+ if (size)
+ {
+ written += fprintf(stream, "-%d", size);
+ }
+ }
+ enumerator->destroy(enumerator);
+ return written;
+}
+
+/**
+ * output handler in printf()
+ */
+static int print(FILE *stream, const struct printf_info *info,
+ const void *const *args)
+{
+ private_proposal_t *this = *((private_proposal_t**)(args[0]));
+ linked_list_t *list = *((linked_list_t**)(args[0]));
+ enumerator_t *enumerator;
+ size_t written = 0;
+ bool first = TRUE;
+
+ if (this == NULL)
+ {
+ return fprintf(stream, "(null)");
+ }
+
+ if (info->alt)
+ {
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &this))
+ { /* call recursivly */
+ if (first)
+ {
+ written += fprintf(stream, "%P", this);
+ first = FALSE;
+ }
+ else
+ {
+ written += fprintf(stream, ", %P", this);
+ }
+ }
+ enumerator->destroy(enumerator);
+ return written;
+ }
+
+ written = fprintf(stream, "%N:", protocol_id_names, this->protocol);
+ written += print_alg(this, stream, ENCRYPTION_ALGORITHM,
+ encryption_algorithm_names, &first);
+ written += print_alg(this, stream, INTEGRITY_ALGORITHM,
+ integrity_algorithm_names, &first);
+ written += print_alg(this, stream, PSEUDO_RANDOM_FUNCTION,
+ pseudo_random_function_names, &first);
+ written += print_alg(this, stream, DIFFIE_HELLMAN_GROUP,
+ diffie_hellman_group_names, &first);
+ written += print_alg(this, stream, EXTENDED_SEQUENCE_NUMBERS,
+ extended_sequence_numbers_names, &first);
+ return written;
+}
+
+/**
+ * arginfo handler for printf() proposal
+ */
+static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (n > 0)
+ {
+ argtypes[0] = PA_POINTER;
+ }
+ return 1;
+}
+
+/**
+ * return printf hook functions for a proposal
+ */
+printf_hook_functions_t proposal_get_printf_hooks()
+{
+ printf_hook_functions_t hooks = {print, arginfo};
+
+ return hooks;
+}
+
+/**
* Implements proposal_t.destroy.
*/
static void destroy(private_proposal_t *this)
@@ -553,14 +913,16 @@ proposal_t *proposal_create(protocol_id_t protocol)
{
private_proposal_t *this = malloc_thing(private_proposal_t);
- this->public.add_algorithm = (void (*)(proposal_t*,transform_type_t,u_int16_t,size_t))add_algorithm;
- this->public.create_algorithm_iterator = (iterator_t* (*)(proposal_t*,transform_type_t))create_algorithm_iterator;
- this->public.get_algorithm = (bool (*)(proposal_t*,transform_type_t,algorithm_t**))get_algorithm;
+ this->public.add_algorithm = (void (*)(proposal_t*,transform_type_t,u_int16_t,u_int16_t))add_algorithm;
+ this->public.create_enumerator = (enumerator_t* (*)(proposal_t*,transform_type_t))create_enumerator;
+ this->public.get_algorithm = (bool (*)(proposal_t*,transform_type_t,u_int16_t*,u_int16_t*))get_algorithm;
this->public.has_dh_group = (bool (*)(proposal_t*,diffie_hellman_group_t))has_dh_group;
+ this->public.strip_dh = (void(*)(proposal_t*))strip_dh;
this->public.select = (proposal_t* (*)(proposal_t*,proposal_t*))select_proposal;
this->public.get_protocol = (protocol_id_t(*)(proposal_t*))get_protocol;
this->public.set_spi = (void(*)(proposal_t*,u_int64_t))set_spi;
this->public.get_spi = (u_int64_t(*)(proposal_t*))get_spi;
+ this->public.equals = (bool(*)(proposal_t*, proposal_t *other))equals;
this->public.clone = (proposal_t*(*)(proposal_t*))clone_;
this->public.destroy = (void(*)(proposal_t*))destroy;
@@ -590,17 +952,19 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192);
add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256);
add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_3DES, 0);
- add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0);
+ add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0);
+ add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0);
add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0);
add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0);
- add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0);
- add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0);
+ add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0);
+ add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0);
+ add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_AES128_XCBC, 0);
add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_256, 0);
add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA1, 0);
add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 0);
add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_384, 0);
add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_512, 0);
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+ add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0);
add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0);
@@ -662,6 +1026,8 @@ proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs
return NULL;
}
+ check_proposal(this);
+
if (protocol == PROTO_AH || protocol == PROTO_ESP)
{
add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
diff --git a/src/charon/config/proposal.h b/src/charon/config/proposal.h
index 379550f44..fb7dc9dfa 100644
--- a/src/charon/config/proposal.h
+++ b/src/charon/config/proposal.h
@@ -1,10 +1,3 @@
-/**
- * @file proposal.h
- *
- * @brief Interface of proposal_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: proposal.h 4062 2008-06-12 11:42:19Z martin $
+ */
+
+/**
+ * @defgroup proposal proposal
+ * @{ @ingroup config
*/
#ifndef PROPOSAL_H_
@@ -26,7 +26,6 @@
typedef enum protocol_id_t protocol_id_t;
typedef enum transform_type_t transform_type_t;
typedef enum extended_sequence_numbers_t extended_sequence_numbers_t;
-typedef struct algorithm_t algorithm_t;
typedef struct proposal_t proposal_t;
#include <library.h>
@@ -40,8 +39,6 @@ typedef struct proposal_t proposal_t;
/**
* Protocol ID of a proposal.
- *
- * @ingroup config
*/
enum protocol_id_t {
PROTO_NONE = 0,
@@ -52,16 +49,12 @@ enum protocol_id_t {
/**
* enum names for protocol_id_t
- *
- * @ingroup config
*/
extern enum_name_t *protocol_id_names;
/**
* Type of a transform, as in IKEv2 RFC 3.3.2.
- *
- * @ingroup config
*/
enum transform_type_t {
UNDEFINED_TRANSFORM_TYPE = 241,
@@ -74,16 +67,12 @@ enum transform_type_t {
/**
* enum names for transform_type_t.
- *
- * @ingroup config
*/
extern enum_name_t *transform_type_names;
/**
* Extended sequence numbers, as in IKEv2 RFC 3.3.2.
- *
- * @ingroup config
*/
enum extended_sequence_numbers_t {
NO_EXT_SEQ_NUMBERS = 0,
@@ -92,48 +81,21 @@ enum extended_sequence_numbers_t {
/**
* enum strings for extended_sequence_numbers_t.
- *
- * @ingroup config
*/
extern enum_name_t *extended_sequence_numbers_names;
-
-
-/**
- * Struct used to store different kinds of algorithms. The internal
- * lists of algorithms contain such structures.
- *
- * @ingroup config
- */
-struct algorithm_t {
- /**
- * Value from an encryption_algorithm_t/integrity_algorithm_t/...
- */
- u_int16_t algorithm;
-
- /**
- * the associated key size in bits, or zero if not needed
- */
- u_int16_t key_size;
-};
-
/**
- * @brief Stores a set of algorithms used for an SA.
+ * Stores a set of algorithms used for an SA.
*
* A proposal stores algorithms for a specific
* protocol. It can store algorithms for one protocol.
* Proposals with multiple protocols are not supported,
* as it's not specified in RFC4301 anymore.
- *
- * @b Constructors:
- * - proposal_create()
- *
- * @ingroup config
*/
struct proposal_t {
/**
- * @brief Add an algorithm to the proposal.
+ * Add an algorithm to the proposal.
*
* The algorithms are stored by priority, first added
* is the most preferred.
@@ -144,120 +106,119 @@ struct proposal_t {
* integrity_algorithm_t, dh_group_number_t and
* extended_sequence_numbers_t.
*
- * @param this calling object
- * @param type kind of algorithm
- * @param alg identifier for algorithm
- * @param key_size key size to use
+ * @param type kind of algorithm
+ * @param alg identifier for algorithm
+ * @param key_size key size to use
*/
- void (*add_algorithm) (proposal_t *this, transform_type_t type, u_int16_t alg, size_t key_size);
+ void (*add_algorithm) (proposal_t *this, transform_type_t type,
+ u_int16_t alg, u_int16_t key_size);
/**
- * @brief Get an iterator over algorithms for a specifc algo type.
+ * Get an enumerator over algorithms for a specifc algo type.
*
- * @param this calling object
- * @param type kind of algorithm
- * @return iterator over algorithm_t's
+ * @param type kind of algorithm
+ * @return enumerator over u_int16_t alg, u_int16_t key_size
*/
- iterator_t *(*create_algorithm_iterator) (proposal_t *this, transform_type_t type);
+ enumerator_t *(*create_enumerator) (proposal_t *this, transform_type_t type);
/**
- * @brief Get the algorithm for a type to use.
+ * Get the algorithm for a type to use.
*
* If there are multiple algorithms, only the first is returned.
*
- * @param this calling object
- * @param type kind of algorithm
- * @param[out] algo pointer which receives algorithm and key size
- * @return TRUE if algorithm of this kind available
+ * @param type kind of algorithm
+ * @param alg pointer which receives algorithm
+ * @param key_size pointer which receives the key size
+ * @return TRUE if algorithm of this kind available
*/
- bool (*get_algorithm) (proposal_t *this, transform_type_t type, algorithm_t** algo);
+ bool (*get_algorithm) (proposal_t *this, transform_type_t type,
+ u_int16_t *alg, u_int16_t *key_size);
/**
- * @brief Check if the proposal has a specific DH group.
+ * Check if the proposal has a specific DH group.
*
- * @param this calling object
- * @param group group to check for
- * @return TRUE if algorithm included
+ * @param group group to check for
+ * @return TRUE if algorithm included
*/
bool (*has_dh_group) (proposal_t *this, diffie_hellman_group_t group);
+
+ /**
+ * Strip DH groups from proposal to use it without PFS.
+ */
+ void (*strip_dh)(proposal_t *this);
/**
- * @brief Compare two proposal, and select a matching subset.
+ * Compare two proposal, and select a matching subset.
*
* If the proposals are for the same protocols (AH/ESP), they are
* compared. If they have at least one algorithm of each type
* in common, a resulting proposal of this kind is created.
*
- * @param this calling object
- * @param other proposal to compair agains
- * @return
- * - selected proposal, if possible
- * - NULL, if proposals don't match
+ * @param other proposal to compair agains
+ * @return selected proposal, NULL if proposals don't match
*/
proposal_t *(*select) (proposal_t *this, proposal_t *other);
/**
- * @brief Get the protocol ID of the proposal.
+ * Get the protocol ID of the proposal.
*
- * @param this calling object
- * @return protocol of the proposal
+ * @return protocol of the proposal
*/
protocol_id_t (*get_protocol) (proposal_t *this);
/**
- * @brief Get the SPI of the proposal.
+ * Get the SPI of the proposal.
*
- * @param this calling object
- * @return spi for proto
+ * @return spi for proto
*/
u_int64_t (*get_spi) (proposal_t *this);
/**
- * @brief Set the SPI of the proposal.
+ * Set the SPI of the proposal.
*
- * @param this calling object
- * @param spi spi to set for proto
+ * @param spi spi to set for proto
*/
void (*set_spi) (proposal_t *this, u_int64_t spi);
/**
- * @brief Clone a proposal.
+ * Check for the eqality of two proposals.
+ *
+ * @param other other proposal to check for equality
+ * @return TRUE if other equal to this
+ */
+ bool (*equals)(proposal_t *this, proposal_t *other);
+
+ /**
+ * Clone a proposal.
*
- * @param this proposal to clone
- * @return clone of it
+ * @return clone of proposal
*/
proposal_t *(*clone) (proposal_t *this);
/**
- * @brief Destroys the proposal object.
- *
- * @param this calling object
+ * Destroys the proposal object.
*/
void (*destroy) (proposal_t *this);
};
/**
- * @brief Create a child proposal for AH, ESP or IKE.
+ * Create a child proposal for AH, ESP or IKE.
*
* @param protocol protocol, such as PROTO_ESP
* @return proposal_t object
- *
- * @ingroup config
*/
proposal_t *proposal_create(protocol_id_t protocol);
/**
- * @brief Create a default proposal if nothing further specified.
+ * Create a default proposal if nothing further specified.
*
* @param protocol protocol, such as PROTO_ESP
* @return proposal_t object
- *
- * @ingroup config
*/
proposal_t *proposal_create_default(protocol_id_t protocol);
/**
- * @brief Create a proposal from a string identifying the algorithms.
+ * Create a proposal from a string identifying the algorithms.
*
* The string is in the same form as a in the ipsec.conf file.
* E.g.: aes128-sha2_256-modp2048
@@ -268,9 +229,17 @@ proposal_t *proposal_create_default(protocol_id_t protocol);
* @param protocol protocol, such as PROTO_ESP
* @param algs algorithms as string
* @return proposal_t object
- *
- * @ingroup config
*/
proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs);
-#endif /* PROPOSAL_H_ */
+/**
+ * Get printf hooks for a proposal.
+ *
+ * Arguments are:
+ * proposal_t *proposal
+ * With the #-specifier, arguments are:
+ * linked_list_t *list containing proposal_t*
+ */
+printf_hook_functions_t proposal_get_printf_hooks();
+
+#endif /* PROPOSAL_H_ @} */
diff --git a/src/charon/config/traffic_selector.c b/src/charon/config/traffic_selector.c
index da39c434d..f41c39d30 100644
--- a/src/charon/config/traffic_selector.c
+++ b/src/charon/config/traffic_selector.c
@@ -1,10 +1,3 @@
-/**
- * @file traffic_selector.c
- *
- * @brief Implementation of traffic_selector_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
@@ -20,6 +13,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: traffic_selector.c 3658 2008-03-26 10:06:45Z martin $
*/
#include <arpa/inet.h>
@@ -276,11 +271,25 @@ static int print(FILE *stream, const struct printf_info *info,
}
/**
- * register printf() handlers
+ * arginfo handler for printf() traffic selector
+ */
+static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (n > 0)
+ {
+ argtypes[0] = PA_POINTER;
+ }
+ return 1;
+}
+
+/**
+ * return printf hook functions for a chunk
*/
-static void __attribute__ ((constructor))print_register()
+printf_hook_functions_t traffic_selector_get_printf_hooks()
{
- register_printf_function(PRINTF_TRAFFIC_SELECTOR, print, arginfo_ptr);
+ printf_hook_functions_t hooks = {print, arginfo};
+
+ return hooks;
}
/**
@@ -709,6 +718,7 @@ traffic_selector_t *traffic_selector_create_from_subnet(host_t *net,
}
default:
{
+ net->destroy(net);
free(this);
return NULL;
}
@@ -718,6 +728,7 @@ traffic_selector_t *traffic_selector_create_from_subnet(host_t *net,
this->from_port = port;
this->to_port = port;
}
+ net->destroy(net);
return (&this->public);
}
@@ -770,12 +781,11 @@ traffic_selector_t *traffic_selector_create_from_string(
/*
* see header
*/
-traffic_selector_t *traffic_selector_create_dynamic(
- u_int8_t protocol, ts_type_t type,
+traffic_selector_t *traffic_selector_create_dynamic(u_int8_t protocol,
u_int16_t from_port, u_int16_t to_port)
{
- private_traffic_selector_t *this = traffic_selector_create(protocol, type,
- from_port, to_port);
+ private_traffic_selector_t *this = traffic_selector_create(
+ protocol, TS_IPV4_ADDR_RANGE, from_port, to_port);
memset(this->from6, 0, sizeof(this->from6));
memset(this->to6, 0xFF, sizeof(this->to6));
@@ -818,4 +828,3 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol,
return this;
}
-/* vim: set ts=4 sw=4 noet: */
diff --git a/src/charon/config/traffic_selector.h b/src/charon/config/traffic_selector.h
index 0e798fc6a..4b079a8e0 100644
--- a/src/charon/config/traffic_selector.h
+++ b/src/charon/config/traffic_selector.h
@@ -1,10 +1,3 @@
-/**
- * @file traffic_selector.h
- *
- * @brief Interface of traffic_selector_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
@@ -20,6 +13,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: traffic_selector.h 3658 2008-03-26 10:06:45Z martin $
+ */
+
+/**
+ * @defgroup traffic_selector traffic_selector
+ * @{ @ingroup config
*/
#ifndef TRAFFIC_SELECTOR_H_
@@ -33,8 +33,6 @@ typedef struct traffic_selector_t traffic_selector_t;
/**
* Traffic selector types.
- *
- * @ingroup config
*/
enum ts_type_t {
@@ -63,29 +61,20 @@ enum ts_type_t {
extern enum_name_t *ts_type_name;
/**
- * @brief Object representing a traffic selector entry.
+ * Object representing a traffic selector entry.
*
* A traffic selector defines an range of addresses
* and a range of ports. IPv6 is not fully supported yet.
- *
- * @b Constructors:
- * - traffic_selector_create_from_bytes()
- * - traffic_selector_create_from_string()
- *
- * @todo Add IPv6 support
- *
- * @ingroup config
*/
struct traffic_selector_t {
/**
- * @brief Compare two traffic selectors, and create a new one
+ * Compare two traffic selectors, and create a new one
* which is the largest subset of both (subnet & port).
*
* Resulting traffic_selector is newly created and must be destroyed.
*
- * @param this first to compare
- * @param other second to compare
+ * @param other traffic selector to compare
* @return
* - created subset of them
* - or NULL if no match between this and other
@@ -94,73 +83,66 @@ struct traffic_selector_t {
traffic_selector_t *other);
/**
- * @brief Clone a traffic selector.
+ * Clone a traffic selector.
*
- * @param this traffic selector to clone
* @return clone of it
*/
traffic_selector_t *(*clone) (traffic_selector_t *this);
/**
- * @brief Get starting address of this ts as a chunk.
+ * Get starting address of this ts as a chunk.
*
* Chunk is in network order gets allocated.
*
- * @param this called object
* @return chunk containing the address
*/
chunk_t (*get_from_address) (traffic_selector_t *this);
/**
- * @brief Get ending address of this ts as a chunk.
+ * Get ending address of this ts as a chunk.
*
* Chunk is in network order gets allocated.
*
- * @param this called object
* @return chunk containing the address
*/
chunk_t (*get_to_address) (traffic_selector_t *this);
/**
- * @brief Get starting port of this ts.
+ * Get starting port of this ts.
*
* Port is in host order, since the parser converts it.
* Size depends on protocol.
*
- * @param this called object
* @return port
*/
u_int16_t (*get_from_port) (traffic_selector_t *this);
/**
- * @brief Get ending port of this ts.
+ * Get ending port of this ts.
*
* Port is in host order, since the parser converts it.
* Size depends on protocol.
*
- * @param this called object
* @return port
*/
u_int16_t (*get_to_port) (traffic_selector_t *this);
/**
- * @brief Get the type of the traffic selector.
+ * Get the type of the traffic selector.
*
- * @param this called object
* @return ts_type_t specifying the type
*/
ts_type_t (*get_type) (traffic_selector_t *this);
/**
- * @brief Get the protocol id of this ts.
+ * Get the protocol id of this ts.
*
- * @param this called object
* @return protocol id
*/
u_int8_t (*get_protocol) (traffic_selector_t *this);
/**
- * @brief Check if the traffic selector is for a single host.
+ * Check if the traffic selector is for a single host.
*
* Traffic selector may describe the end of *-to-host tunnel. In this
* case, the address range is a single address equal to the hosts
@@ -168,61 +150,54 @@ struct traffic_selector_t {
* If host is NULL, the traffic selector is checked if it is a single host,
* but not a specific one.
*
- * @param this called object
* @param host host_t specifying the address range
*/
bool (*is_host) (traffic_selector_t *this, host_t* host);
/**
- * @brief Update the address of a traffic selector.
+ * Update the address of a traffic selector.
*
* Update the address range of a traffic selector, if it is
* constructed with the traffic_selector_create_dynamic().
*
- * @param this called object
* @param host host_t specifying the address
*/
void (*set_address) (traffic_selector_t *this, host_t* host);
/**
- * @brief Compare two traffic selectors for equality.
+ * Compare two traffic selectors for equality.
*
- * @param this first to compare
- * @param other second to compare with first
+ * @param other ts to compare with this
* @return pointer to a string.
*/
bool (*equals) (traffic_selector_t *this, traffic_selector_t *other);
/**
- * @brief Check if a traffic selector is contained completly in another.
+ * Check if a traffic selector is contained completly in another.
*
* contains() allows to check if multiple traffic selectors are redundant.
*
- * @param this ts that is contained in another
* @param other ts that contains this
* @return TRUE if other contains this completly, FALSE otherwise
*/
bool (*is_contained_in) (traffic_selector_t *this, traffic_selector_t *other);
/**
- * @brief Check if a specific host is included in the address range of
+ * Check if a specific host is included in the address range of
* this traffic selector.
*
- * @param this called object
* @param host the host to check
*/
bool (*includes) (traffic_selector_t *this, host_t *host);
/**
- * @brief Destroys the ts object
- *
- * @param this called object
+ * Destroys the ts object
*/
void (*destroy) (traffic_selector_t *this);
};
/**
- * @brief Create a new traffic selector using human readable params.
+ * Create a new traffic selector using human readable params.
*
* @param protocol protocol for this ts, such as TCP or UDP
* @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
@@ -233,8 +208,6 @@ struct traffic_selector_t {
* @return
* - traffic_selector_t object
* - NULL if invalid address strings/protocol
- *
- * @ingroup config
*/
traffic_selector_t *traffic_selector_create_from_string(
u_int8_t protocol, ts_type_t type,
@@ -242,7 +215,7 @@ traffic_selector_t *traffic_selector_create_from_string(
char *to_addr, u_int16_t to_port);
/**
- * @brief Create a new traffic selector using data read from the net.
+ * Create a new traffic selector using data read from the net.
*
* There exists a mix of network and host order in the params.
* But the parser gives us this data in this format, so we
@@ -255,8 +228,6 @@ traffic_selector_t *traffic_selector_create_from_string(
* @param to_address end of address range as string, network
* @param to_port port number, host order
* @return traffic_selector_t object
- *
- * @ingroup config
*/
traffic_selector_t *traffic_selector_create_from_bytes(
u_int8_t protocol, ts_type_t type,
@@ -264,7 +235,7 @@ traffic_selector_t *traffic_selector_create_from_bytes(
chunk_t to_address, u_int16_t to_port);
/**
- * @brief Create a new traffic selector defining a whole subnet.
+ * Create a new traffic selector defining a whole subnet.
*
* In most cases, definition of a traffic selector for full subnets
* is sufficient. This constructor creates a traffic selector for
@@ -278,15 +249,13 @@ traffic_selector_t *traffic_selector_create_from_bytes(
* @return
* - traffic_selector_t object
* - NULL if address family of net not supported
- *
- * @ingroup config
*/
traffic_selector_t *traffic_selector_create_from_subnet(
host_t *net, u_int8_t netbits,
u_int8_t protocol, u_int16_t port);
/**
- * @brief Create a traffic selector for host-to-host cases.
+ * Create a traffic selector for host-to-host cases.
*
* For host2host or virtual IP setups, the traffic selectors gets
* created at runtime using the external/virtual IP. Using this constructor,
@@ -294,19 +263,23 @@ traffic_selector_t *traffic_selector_create_from_subnet(
*
*
* @param protocol upper layer protocl to allow
- * @param type family type
* @param from_port start of allowed port range
* @param to_port end of range
* @return
* - traffic_selector_t object
* - NULL if type not supported
- *
- * @ingroup config
*/
-traffic_selector_t *traffic_selector_create_dynamic(
- u_int8_t protocol, ts_type_t type,
+traffic_selector_t *traffic_selector_create_dynamic(u_int8_t protocol,
u_int16_t from_port, u_int16_t to_port);
-#endif /* TRAFFIC_SELECTOR_H_ */
+/**
+ * Get printf hooks for a traffic selector.
+ *
+ * Arguments are:
+ * traffic_selector_t *ts
+ * With the #-specifier, arguments are:
+ * linked_list_t *list containing traffic_selector_t*
+ */
+printf_hook_functions_t traffic_selector_get_printf_hooks();
-/* vim: set ts=4 sw=4 noet: */
+#endif /* TRAFFIC_SELECTOR_H_ @} */
diff --git a/src/charon/control/interface_manager.c b/src/charon/control/controller.c
index 4d5aa2ea6..2d1decd88 100644
--- a/src/charon/control/interface_manager.c
+++ b/src/charon/control/controller.c
@@ -1,10 +1,3 @@
-/**
- * @file interface_manager.c
- *
- * @brief Implementation of interface_manager_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,9 +11,11 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: controller.c 3820 2008-04-17 11:22:37Z martin $
*/
-#include "interface_manager.h"
+#include "controller.h"
#include <sys/types.h>
#include <dirent.h>
@@ -29,31 +24,20 @@
#include <daemon.h>
#include <library.h>
-#include <control/interfaces/interface.h>
-typedef struct private_interface_manager_t private_interface_manager_t;
+typedef struct private_controller_t private_controller_t;
typedef struct interface_bus_listener_t interface_bus_listener_t;
/**
* Private data of an stroke_t object.
*/
-struct private_interface_manager_t {
+struct private_controller_t {
/**
* Public part of stroke_t object.
*/
- interface_manager_t public;
-
- /**
- * a list of all loaded interfaces
- */
- linked_list_t *interfaces;
-
- /**
- * dlopen() handles of interfaces
- */
- linked_list_t *handles;
+ controller_t public;
};
@@ -80,7 +64,7 @@ struct interface_bus_listener_t {
/**
* interface callback (listener gets redirected to here)
*/
- interface_manager_cb_t callback;
+ controller_cb_t callback;
/**
* user parameter to pass to callback
@@ -122,19 +106,11 @@ struct interface_job_t {
};
/**
- * Implements the famous nop operation
+ * Implementation of controller_t.create_ike_sa_iterator.
*/
-static void nop(job_t *job)
+static enumerator_t* create_ike_sa_enumerator(controller_t *this)
{
- /* NOP */
-}
-
-/**
- * Implementation of interface_manager_t.create_ike_sa_iterator.
- */
-static iterator_t* create_ike_sa_iterator(interface_manager_t *this)
-{
- return charon->ike_sa_manager->create_iterator(charon->ike_sa_manager);
+ return charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager);
}
/**
@@ -173,11 +149,11 @@ static status_t initiate_execute(interface_job_t *job)
ike_sa_t *ike_sa;
interface_bus_listener_t *listener = &job->listener;
peer_cfg_t *peer_cfg = listener->peer_cfg;
-
+
ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
peer_cfg);
listener->ike_sa = ike_sa;
-
+
if (ike_sa->get_peer_cfg(ike_sa) == NULL)
{
ike_sa->set_peer_cfg(ike_sa, peer_cfg);
@@ -193,11 +169,11 @@ static status_t initiate_execute(interface_job_t *job)
}
/**
- * Implementation of interface_manager_t.initiate.
+ * Implementation of controller_t.initiate.
*/
-static status_t initiate(private_interface_manager_t *this,
+static status_t initiate(private_controller_t *this,
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- interface_manager_cb_t callback, void *param)
+ controller_cb_t callback, void *param)
{
interface_job_t job;
@@ -273,10 +249,10 @@ static status_t terminate_ike_execute(interface_job_t *job)
}
/**
- * Implementation of interface_manager_t.terminate_ike.
+ * Implementation of controller_t.terminate_ike.
*/
-static status_t terminate_ike(interface_manager_t *this, u_int32_t unique_id,
- interface_manager_cb_t callback, void *param)
+static status_t terminate_ike(controller_t *this, u_int32_t unique_id,
+ controller_cb_t callback, void *param)
{
interface_job_t job;
@@ -375,10 +351,10 @@ static status_t terminate_child_execute(interface_job_t *job)
}
/**
- * Implementation of interface_manager_t.terminate_child.
+ * Implementation of controller_t.terminate_child.
*/
-static status_t terminate_child(interface_manager_t *this, u_int32_t reqid,
- interface_manager_cb_t callback, void *param)
+static status_t terminate_child(controller_t *this, u_int32_t reqid,
+ controller_cb_t callback, void *param)
{
interface_job_t job;
@@ -434,7 +410,6 @@ static status_t route_execute(interface_job_t *job)
ike_sa_t *ike_sa;
interface_bus_listener_t *listener = &job->listener;
peer_cfg_t *peer_cfg = listener->peer_cfg;
-
ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
peer_cfg);
listener->ike_sa = ike_sa;
@@ -452,11 +427,11 @@ static status_t route_execute(interface_job_t *job)
}
/**
- * Implementation of interface_manager_t.route.
+ * Implementation of controller_t.route.
*/
-static status_t route(interface_manager_t *this,
+static status_t route(controller_t *this,
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- interface_manager_cb_t callback, void *param)
+ controller_cb_t callback, void *param)
{
interface_job_t job;
@@ -530,10 +505,10 @@ static status_t unroute_execute(interface_job_t *job)
}
/**
- * Implementation of interface_manager_t.unroute.
+ * Implementation of controller_t.unroute.
*/
-static status_t unroute(interface_manager_t *this, u_int32_t reqid,
- interface_manager_cb_t callback, void *param)
+static status_t unroute(controller_t *this, u_int32_t reqid,
+ controller_cb_t callback, void *param)
{
interface_job_t job;
@@ -555,76 +530,9 @@ static status_t unroute(interface_manager_t *this, u_int32_t reqid,
}
/**
- * load the control interface modules
- */
-static void load_interfaces(private_interface_manager_t *this)
-{
- struct dirent* entry;
- DIR* dir;
-
- dir = opendir(IPSEC_INTERFACEDIR);
- if (dir == NULL)
- {
- DBG1(DBG_CFG, "error opening interface modules directory "IPSEC_INTERFACEDIR);
- return;
- }
-
- DBG1(DBG_CFG, "loading control interface modules from '"IPSEC_INTERFACEDIR"'");
-
- while ((entry = readdir(dir)) != NULL)
- {
- char file[256];
- interface_t *interface;
- interface_constructor_t constructor;
- void *handle;
- char *ending;
-
- snprintf(file, sizeof(file), IPSEC_INTERFACEDIR"/%s", entry->d_name);
-
- ending = entry->d_name + strlen(entry->d_name) - 3;
- if (ending <= entry->d_name || !streq(ending, ".so"))
- {
- /* skip anything which does not look like a library */
- DBG2(DBG_CFG, " skipping %s, doesn't look like a library",
- entry->d_name);
- continue;
- }
- /* try to load the library */
- handle = dlopen(file, RTLD_LAZY);
- if (handle == NULL)
- {
- DBG1(DBG_CFG, " opening control interface module %s failed: %s",
- entry->d_name, dlerror());
- continue;
- }
- constructor = dlsym(handle, "interface_create");
- if (constructor == NULL)
- {
- DBG1(DBG_CFG, " interface module %s has no interface_create() "
- "function, skipped", entry->d_name);
- dlclose(handle);
- continue;
- }
-
- interface = constructor();
- if (interface == NULL)
- {
- DBG1(DBG_CFG, " unable to create instance of interface "
- "module %s, skipped", entry->d_name);
- dlclose(handle);
- continue;
- }
- DBG1(DBG_CFG, " loaded control interface module successfully from %s", entry->d_name);
- this->interfaces->insert_last(this->interfaces, interface);
- this->handles->insert_last(this->handles, handle);
- }
- closedir(dir);
-}
-
-/**
* See header
*/
-bool interface_manager_cb_empty(void *param, signal_t signal, level_t level,
+bool controller_cb_empty(void *param, signal_t signal, level_t level,
ike_sa_t *ike_sa, char *format, va_list args)
{
return TRUE;
@@ -633,32 +541,25 @@ bool interface_manager_cb_empty(void *param, signal_t signal, level_t level,
/**
* Implementation of stroke_t.destroy.
*/
-static void destroy(private_interface_manager_t *this)
+static void destroy(private_controller_t *this)
{
- this->interfaces->destroy_offset(this->interfaces, offsetof(interface_t, destroy));
- this->handles->destroy_function(this->handles, (void*)dlclose);
free(this);
}
/*
* Described in header-file
*/
-interface_manager_t *interface_manager_create(void)
+controller_t *controller_create(void)
{
- private_interface_manager_t *this = malloc_thing(private_interface_manager_t);
-
- this->public.create_ike_sa_iterator = (iterator_t*(*)(interface_manager_t*))create_ike_sa_iterator;
- this->public.initiate = (status_t(*)(interface_manager_t*,peer_cfg_t*,child_cfg_t*,bool(*)(void*,signal_t,level_t,ike_sa_t*,char*,va_list),void*))initiate;
- this->public.terminate_ike = (status_t(*)(interface_manager_t*,u_int32_t,interface_manager_cb_t, void*))terminate_ike;
- this->public.terminate_child = (status_t(*)(interface_manager_t*,u_int32_t,interface_manager_cb_t, void *param))terminate_child;
- this->public.route = (status_t(*)(interface_manager_t*,peer_cfg_t*, child_cfg_t*,interface_manager_cb_t,void*))route;
- this->public.unroute = (status_t(*)(interface_manager_t*,u_int32_t,interface_manager_cb_t,void*))unroute;
- this->public.destroy = (void (*)(interface_manager_t*))destroy;
-
- this->interfaces = linked_list_create();
- this->handles = linked_list_create();
+ private_controller_t *this = malloc_thing(private_controller_t);
- load_interfaces(this);
+ this->public.create_ike_sa_enumerator = (enumerator_t*(*)(controller_t*))create_ike_sa_enumerator;
+ this->public.initiate = (status_t(*)(controller_t*,peer_cfg_t*,child_cfg_t*,bool(*)(void*,signal_t,level_t,ike_sa_t*,char*,va_list),void*))initiate;
+ this->public.terminate_ike = (status_t(*)(controller_t*,u_int32_t,controller_cb_t, void*))terminate_ike;
+ this->public.terminate_child = (status_t(*)(controller_t*,u_int32_t,controller_cb_t, void *param))terminate_child;
+ this->public.route = (status_t(*)(controller_t*,peer_cfg_t*, child_cfg_t*,controller_cb_t,void*))route;
+ this->public.unroute = (status_t(*)(controller_t*,u_int32_t,controller_cb_t,void*))unroute;
+ this->public.destroy = (void (*)(controller_t*))destroy;
return &this->public;
}
diff --git a/src/charon/control/interface_manager.h b/src/charon/control/controller.h
index 3ee1f0e39..643611965 100644
--- a/src/charon/control/interface_manager.h
+++ b/src/charon/control/controller.h
@@ -1,10 +1,3 @@
-/**
- * @file interface_manager.h
- *
- * @brief Interface of interface_manager_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,15 +11,22 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: controller.h 3804 2008-04-14 11:37:46Z martin $
*/
-#ifndef INTERFACE_MANAGER_H_
-#define INTERFACE_MANAGER_H_
+/**
+ * @defgroup controller_i controller
+ * @{ @ingroup control
+ */
+
+#ifndef CONTROLLER_H_
+#define CONTROLLER_H_
#include <bus/bus.h>
/**
- * callback to log things triggered by interface_manager.
+ * callback to log things triggered by controller.
*
* @param param echoed parameter supplied when function invoked
* @param signal type of signal
@@ -35,74 +35,51 @@
* @param format printf like format string
* @param args list of arguments to use for format
* @return FALSE to return from invoked function
- * @ingroup control
*/
-typedef bool(*interface_manager_cb_t)(void* param, signal_t signal, level_t level,
+typedef bool(*controller_cb_t)(void* param, signal_t signal, level_t level,
ike_sa_t* ike_sa, char* format, va_list args);
/**
- * @brief Empty callback function for interface_manager_t functions.
+ * Empty callback function for controller_t functions.
*
* If you wan't to do a syncrhonous call, but don't need a callback, pass
- * this function to the interface_managers methods.
+ * this function to the controllers methods.
*/
-bool interface_manager_cb_empty(void *param, signal_t signal, level_t level,
+bool controller_cb_empty(void *param, signal_t signal, level_t level,
ike_sa_t *ike_sa, char *format, va_list args);
-typedef struct interface_manager_t interface_manager_t;
+typedef struct controller_t controller_t;
/**
- * @brief The interface_manager loads control interfaces and has helper methods.
+ * The controller provides a simple interface to run actions.
*
- * One job of the interface manager is to load pluggable control interface
- * modules, implemented as interface_t.
- * @verbatim
-
- +---------+ +------------+ +--------------+ |
- | | | |<----- +--------------+ | |
- | daemon |<-----| interface- | +--------------+ |-+ <==|==> IPC
- | core | | manager |<----| interfaces |-+ |
- | |<-----| | +--------------+ |
- | | | | |
- +---------+ +------------+ |
-
- @endverbatim
- * The manager does not really use the interfaces, instead, the interface
- * use the manager to fullfill their tasks (initiating, terminating, ...).
- * The interface_manager starts actions by creating jobs. It then tries to
+ * The controller starts actions by creating jobs. It then tries to
* evaluate the result of the operation by listening on the bus.
*
* Passing NULL as callback to the managers function calls them asynchronously.
* If a callback is specified, they are called synchronoulsy. There is a default
- * callback "interface_manager_cb_empty" if you wan't to call a function
+ * callback "controller_cb_empty" if you wan't to call a function
* synchronously, but don't need a callback.
- *
- * @b Constructors:
- * - interface_manager_create()
- *
- * @ingroup control
*/
-struct interface_manager_t {
+struct controller_t {
/**
- * @brief Create an iterator for all IKE_SAs.
+ * Create an enumerator for all IKE_SAs.
*
- * The iterator blocks the IKE_SA manager until it gets destroyed. Do
+ * The enumerator blocks the IKE_SA manager until it gets destroyed. Do
* not call another interface/manager method while the iterator is alive.
*
- * @param this calling object
- * @return iterator, locks IKE_SA manager until destroyed
+ * @return enumerator, locks IKE_SA manager until destroyed
*/
- iterator_t* (*create_ike_sa_iterator)(interface_manager_t *this);
+ enumerator_t* (*create_ike_sa_enumerator)(controller_t *this);
/**
- * @brief Initiate a CHILD_SA, and if required, an IKE_SA.
+ * Initiate a CHILD_SA, and if required, an IKE_SA.
*
* The inititate() function is synchronous and thus blocks until the
* IKE_SA is established or failed. Because of this, the initiate() function
* contains a thread cancellation point.
*
- * @param this calling object
* @param peer_cfg peer_cfg to use for IKE_SA setup
* @param child_cfg child_cfg to set up CHILD_SA from
* @param cb logging callback
@@ -112,18 +89,17 @@ struct interface_manager_t {
* - FAILED, if setup failed
* - NEED_MORE, if callback returned FALSE
*/
- status_t (*initiate)(interface_manager_t *this,
+ status_t (*initiate)(controller_t *this,
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- interface_manager_cb_t callback, void *param);
+ controller_cb_t callback, void *param);
/**
- * @brief Terminate an IKE_SA and all of its CHILD_SAs.
+ * Terminate an IKE_SA and all of its CHILD_SAs.
*
* The terminate() function is synchronous and thus blocks until the
* IKE_SA is properly deleted, or the delete timed out.
* The terminate() function contains a thread cancellation point.
*
- * @param this calling object
* @param unique_id unique id of the IKE_SA to terminate.
* @param cb logging callback
* @param param parameter to include in each call of cb
@@ -132,13 +108,12 @@ struct interface_manager_t {
* - NOT_FOUND, if no such CHILD_SA found
* - NEED_MORE, if callback returned FALSE
*/
- status_t (*terminate_ike)(interface_manager_t *this, u_int32_t unique_id,
- interface_manager_cb_t callback, void *param);
+ status_t (*terminate_ike)(controller_t *this, u_int32_t unique_id,
+ controller_cb_t callback, void *param);
/**
- * @brief Terminate a CHILD_SA.
+ * Terminate a CHILD_SA.
*
- * @param this calling object
* @param reqid reqid of the CHILD_SA to terminate
* @param cb logging callback
* @param param parameter to include in each call of cb
@@ -147,13 +122,12 @@ struct interface_manager_t {
* - NOT_FOUND, if no such CHILD_SA found
* - NEED_MORE, if callback returned FALSE
*/
- status_t (*terminate_child)(interface_manager_t *this, u_int32_t reqid,
- interface_manager_cb_t callback, void *param);
+ status_t (*terminate_child)(controller_t *this, u_int32_t reqid,
+ controller_cb_t callback, void *param);
/**
- * @brief Route a CHILD_SA (install triggering policies).
+ * Route a CHILD_SA (install triggering policies).
*
- * @param this calling object
* @param peer_cfg peer_cfg to use for IKE_SA setup, if triggered
* @param child_cfg child_cfg to route
* @param cb logging callback
@@ -163,16 +137,15 @@ struct interface_manager_t {
* - FAILED, if routing failed
* - NEED_MORE, if callback returned FALSE
*/
- status_t (*route)(interface_manager_t *this,
+ status_t (*route)(controller_t *this,
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- interface_manager_cb_t callback, void *param);
+ controller_cb_t callback, void *param);
/**
- * @brief Unroute a routed CHILD_SA (uninstall triggering policies).
+ * Unroute a routed CHILD_SA (uninstall triggering policies).
*
* Only the route is removed, not the CHILD_SAs the route triggered.
*
- * @param this calling object
* @param reqid reqid of the CHILD_SA to unroute
* @param cb logging callback
* @param param parameter to include in each call of cb
@@ -181,26 +154,21 @@ struct interface_manager_t {
* - NOT_FOUND, if no such CHILD_SA routed
* - NEED_MORE, if callback returned FALSE
*/
- status_t (*unroute)(interface_manager_t *this, u_int32_t reqid,
- interface_manager_cb_t callback, void *param);
+ status_t (*unroute)(controller_t *this, u_int32_t reqid,
+ controller_cb_t callback, void *param);
/**
- * @brief Destroy a interface_manager_t instance.
- *
- * @param this interface_manager_t objec to destroy
+ * Destroy a controller_t instance.
*/
- void (*destroy) (interface_manager_t *this);
+ void (*destroy) (controller_t *this);
};
/**
- * @brief Creates a interface_manager instance and loads all interface modules.
- *
- * @return interface_manager_t object
+ * Creates a controller instance.
*
- * @ingroup control
+ * @return controller_t object
*/
-interface_manager_t *interface_manager_create(void);
-
-#endif /* INTERFACE_MANAGER_H_ */
+controller_t *controller_create(void);
+#endif /* CONTROLLER_H_ @} */
diff --git a/src/charon/control/interfaces/dbus_interface.c b/src/charon/control/interfaces/dbus_interface.c
deleted file mode 100644
index 39226aaef..000000000
--- a/src/charon/control/interfaces/dbus_interface.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/**
- * @file dbus_interface.c
- *
- * @brief Implementation of dbus_interface_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#define DBUS_API_SUBJECT_TO_CHANGE
-#include <dbus/dbus.h>
-#include <NetworkManager/NetworkManager.h>
-#include <NetworkManager/NetworkManagerVPN.h>
-#include <stdlib.h>
-
-#include "dbus_interface.h"
-
-#include <library.h>
-#include <daemon.h>
-#include <processing/jobs/callback_job.h>
-
-
-#define NM_DBUS_SERVICE_STRONG "org.freedesktop.NetworkManager.strongswan"
-#define NM_DBUS_INTERFACE_STRONG "org.freedesktop.NetworkManager.strongswan"
-#define NM_DBUS_PATH_STRONG "/org/freedesktop/NetworkManager/strongswan"
-
-typedef struct private_dbus_interface_t private_dbus_interface_t;
-
-/**
- * Private data of an dbus_interface_t object.
- */
-struct private_dbus_interface_t {
-
- /**
- * Public part of dbus_t object.
- */
- dbus_interface_t public;
-
- /**
- * DBUS connection
- */
- DBusConnection* conn;
-
- /**
- * error value used here and there
- */
- DBusError err;
-
- /**
- * state of the daemon
- */
- NMVPNState state;
-
- /**
- * job accepting stroke messages
- */
- callback_job_t *job;
-
- /**
- * name of the currently active connection
- */
- char *name;
-};
-
-/**
- * set daemon state and send StateChange signal to the bus
- */
-static void set_state(private_dbus_interface_t *this, NMVPNState state)
-{
- DBusMessage* msg;
-
- msg = dbus_message_new_signal(NM_DBUS_PATH_STRONG, NM_DBUS_INTERFACE_STRONG, NM_DBUS_VPN_SIGNAL_STATE_CHANGE);
-
- if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &this->state,
- DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID) ||
- !dbus_connection_send(this->conn, msg, NULL))
- {
- DBG1(DBG_CFG, "unable to send DBUS StateChange signal");
- }
- dbus_connection_flush(this->conn);
- dbus_message_unref(msg);
- this->state = state;
-}
-
-
-/**
- * get the child_cfg with the same name as the peer cfg
- */
-static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
-{
- child_cfg_t *current, *found = NULL;
- iterator_t *iterator;
-
- iterator = peer_cfg->create_child_cfg_iterator(peer_cfg);
- while (iterator->iterate(iterator, (void**)&current))
- {
- if (streq(current->get_name(current), name))
- {
- found = current;
- found->get_ref(found);
- break;
- }
- }
- iterator->destroy(iterator);
- return found;
-}
-
-
-/**
- * process NetworkManagers startConnection method call
- */
-static bool start_connection(private_dbus_interface_t *this, DBusMessage* msg)
-{
- DBusMessage *reply, *signal;
- char *name, *user, **data, **passwords, **routes;
- int data_count, passwords_count, routes_count;
- u_int32_t me, other, p2p, netmask, mss;
- char *dev, *domain, *banner;
- const dbus_int32_t array[] = {};
- const dbus_int32_t *varray = array;
- peer_cfg_t *peer_cfg;
- child_cfg_t *child_cfg;
- status_t status = FAILED;
-
- dbus_error_free(&this->err);
-
- if (!dbus_message_get_args(msg, &this->err,
- DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &user,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &passwords, &passwords_count,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &data, &data_count,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &routes, &routes_count,
- DBUS_TYPE_INVALID))
- {
- return FALSE;
- }
- set_state(this, NM_VPN_STATE_STARTING);
-
- peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends, name);
- if (peer_cfg)
- {
- free(this->name);
- this->name = strdup(peer_cfg->get_name(peer_cfg));
- child_cfg = get_child_from_peer(peer_cfg, name);
- if (child_cfg)
- {
- status = charon->interfaces->initiate(charon->interfaces,
- peer_cfg, child_cfg, interface_manager_cb_empty, NULL);
- }
- else
- {
- peer_cfg->destroy(peer_cfg);
- }
- }
- reply = dbus_message_new_method_return(msg);
- dbus_connection_send(this->conn, reply, NULL);
- dbus_message_unref(reply);
-
- if (status == SUCCESS)
- {
-
- set_state(this, NM_VPN_STATE_STARTED);
- signal = dbus_message_new_signal(NM_DBUS_PATH_STRONG,
- NM_DBUS_INTERFACE_STRONG,
- NM_DBUS_VPN_SIGNAL_IP4_CONFIG);
- me = other = p2p = mss = netmask = 0;
- dev = domain = banner = "";
- if (dbus_message_append_args(signal,
- DBUS_TYPE_UINT32, &other,
- DBUS_TYPE_STRING, &dev,
- DBUS_TYPE_UINT32, &me,
- DBUS_TYPE_UINT32, &p2p,
- DBUS_TYPE_UINT32, &netmask,
- DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &varray, 0,
- DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &varray, 0,
- DBUS_TYPE_UINT32, &mss,
- DBUS_TYPE_STRING, &domain,
- DBUS_TYPE_STRING, &banner, DBUS_TYPE_INVALID))
- {
- dbus_connection_send(this->conn, signal, NULL);
- }
- dbus_message_unref(signal);
- }
- else
- {
- set_state(this, NM_VPN_STATE_STOPPED);
- }
-
- dbus_connection_flush(this->conn);
- return TRUE;
-}
-
-/**
- * process NetworkManagers stopConnection method call
- */
-static bool stop_connection(private_dbus_interface_t *this, DBusMessage* msg)
-{
- u_int32_t id;
- iterator_t *iterator;
- ike_sa_t *ike_sa;
-
- if (this->name == NULL)
- {
- return FALSE;
- }
-
- dbus_error_free(&this->err);
-
- set_state(this, NM_VPN_STATE_STOPPING);
-
- iterator = charon->interfaces->create_ike_sa_iterator(charon->interfaces);
- while (iterator->iterate(iterator, (void**)&ike_sa))
- {
- child_sa_t *child_sa;
- iterator_t *children;
-
- if (this->name && streq(this->name, ike_sa->get_name(ike_sa)))
- {
- id = ike_sa->get_unique_id(ike_sa);
- iterator->destroy(iterator);
- charon->interfaces->terminate_ike(charon->interfaces, id, NULL, NULL);
- set_state(this, NM_VPN_STATE_STOPPED);
- return TRUE;;
- }
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
- {
- if (this->name && streq(this->name, child_sa->get_name(child_sa)))
- {
- id = child_sa->get_reqid(child_sa);
- children->destroy(children);
- iterator->destroy(iterator);
- charon->interfaces->terminate_child(charon->interfaces, id, NULL, NULL);
- set_state(this, NM_VPN_STATE_STOPPED);
- return TRUE;
- }
- }
- children->destroy(children);
- }
- iterator->destroy(iterator);
- set_state(this, NM_VPN_STATE_STOPPED);
- return TRUE;
-}
-
-/**
- * process NetworkManagers getState method call
- */
-static bool get_state(private_dbus_interface_t *this, DBusMessage* msg)
-{
- DBusMessage* reply;
- reply = dbus_message_new_method_return(msg);
- if (!reply || !dbus_message_append_args(reply,
- DBUS_TYPE_UINT32, &this->state,
- DBUS_TYPE_INVALID))
- {
- return FALSE;
- }
- dbus_connection_send(this->conn, reply, NULL);
- return TRUE;
-}
-
-/**
- * Handle incoming messages
- */
-static DBusHandlerResult message_handler(DBusConnection *con, DBusMessage *msg,
- private_dbus_interface_t *this)
-{
- bool handled;
-
- if (dbus_message_is_method_call(msg, NM_DBUS_INTERFACE_STRONG,
- "startConnection"))
- {
- handled = start_connection(this, msg);
- }
- else if (dbus_message_is_method_call(msg, NM_DBUS_INTERFACE_STRONG,
- "stopConnection"))
- {
- handled = stop_connection(this, msg);
- }
- else if (dbus_message_is_method_call(msg, NM_DBUS_INTERFACE_STRONG,
- "getState"))
- {
- handled = get_state(this, msg);
- }
- else
- {
- DBG1(DBG_CFG, "ignoring DBUS message %s.%s",
- dbus_message_get_interface(msg), dbus_message_get_member(msg));
- handled = FALSE;
- }
-
- if (handled)
- {
- return DBUS_HANDLER_RESULT_HANDLED;
- }
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-/**
- * Handle received signals
-
-static DBusHandlerResult signal_handler(DBusConnection *con, DBusMessage *msg,
- private_dbus_interface_t *this)
-{
- bool handled;
-
- if (dbus_message_is_signal(msg, NM_DBUS_INTERFACE, "VPNConnectionStateChange"))
- {
- NMVPNState state;
- char *name;
-
- if (dbus_message_get_args(msg, &this->err, DBUS_TYPE_STRING, &name,
- DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID))
- {
- DBG1(DBG_CFG, "got state %d for %s", state, name);
- }
- handled = TRUE;
- }
- else
- {
- DBG1(DBG_CFG, "ignoring DBUS signal %s.%s",
- dbus_message_get_interface(msg), dbus_message_get_member(msg));
- handled = FALSE;
- }
- if (handled)
- {
- return DBUS_HANDLER_RESULT_HANDLED;
- }
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-} */
-
-/**
- * dispatcher function processed by a seperate thread
- */
-static job_requeue_t dispatch(private_dbus_interface_t *this)
-{
- if (dbus_connection_read_write_dispatch(this->conn, -1))
- {
- return JOB_REQUEUE_DIRECT;
- }
- return JOB_REQUEUE_NONE;
-}
-
-/**
- * Implementation of interface_t.destroy.
- */
-static void destroy(private_dbus_interface_t *this)
-{
- this->job->cancel(this->job);
- dbus_connection_close(this->conn);
- dbus_error_free(&this->err);
- dbus_shutdown();
- free(this->name);
- free(this);
-}
-
-/*
- * Described in header file
- */
-interface_t *interface_create()
-{
- int ret;
- DBusObjectPathVTable v = {NULL, (void*)&message_handler, NULL, NULL, NULL, NULL};
- private_dbus_interface_t *this = malloc_thing(private_dbus_interface_t);
-
- this->public.interface.destroy = (void (*)(interface_t*))destroy;
-
- dbus_error_init(&this->err);
- this->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &this->err);
- if (dbus_error_is_set(&this->err))
- {
- DBG1(DBG_CFG, "unable to open DBUS connection: %s", this->err.message);
- charon->kill(charon, "DBUS initialization failed");
- }
- dbus_connection_set_exit_on_disconnect(this->conn, FALSE);
-
- ret = dbus_bus_request_name(this->conn, NM_DBUS_SERVICE_STRONG,
- DBUS_NAME_FLAG_REPLACE_EXISTING , &this->err);
- if (dbus_error_is_set(&this->err))
- {
- DBG1(DBG_CFG, "unable to set DBUS name: %s", this->err.message);
- charon->kill(charon, "unable to set DBUS name");
- }
- if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
- {
- charon->kill(charon, "DBUS name already owned");
- }
- if (!dbus_connection_register_object_path(this->conn, NM_DBUS_PATH_STRONG, &v, this))
- {
- charon->kill(charon, "unable to register DBUS message handler");
- }
- /*
- if (!dbus_connection_add_filter(this->conn, (void*)signal_handler, this, NULL))
- {
- charon->kill(charon, "unable to register DBUS signal handler");
- }
-
- dbus_bus_add_match(this->conn, "type='signal', "
- "interface='" NM_DBUS_INTERFACE_VPN "',"
- "path='" NM_DBUS_PATH_VPN "'", &this->err);
- if (dbus_error_is_set (&this->err))
- {
- charon->kill(charon, "unable to add DBUS signal match");
- }*/
-
- this->name = NULL;
- this->state = NM_VPN_STATE_INIT;
- set_state(this, NM_VPN_STATE_STOPPED);
-
- this->job = callback_job_create((callback_job_cb_t)dispatch, this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
-
- return &this->public.interface;
-}
-
diff --git a/src/charon/control/interfaces/interface.h b/src/charon/control/interfaces/interface.h
deleted file mode 100644
index 955f4a4eb..000000000
--- a/src/charon/control/interfaces/interface.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file interface.h
- *
- * @brief Interface of interface_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifndef INTERFACE_H_
-#define INTERFACE_H_
-
-typedef struct interface_t interface_t;
-
-/**
- * @brief Interface for a controller.
- *
- * An interface controls the daemon by calling functions on the
- * interface_manager. All interfaces are manager by the interface_manager
- * in a generic way, so they need their own class.
- *
- * @b Constructors:
- * - interface_create() of one of the modules
- *
- * @ingroup interfaces
- */
-struct interface_t {
-
- /**
- * @brief Destroy all interfaces
- *
- * @param this stroke_t objec to destroy
- */
- void (*destroy) (interface_t *this);
-};
-
-
-/**
- * Constructor in a control interface module to create the interface.
- *
- * @ingroup interfaces
- */
-typedef interface_t*(*interface_constructor_t)(void);
-
-#endif /* INTERFACE_H_ */
-
diff --git a/src/charon/control/interfaces/stroke_interface.c b/src/charon/control/interfaces/stroke_interface.c
deleted file mode 100755
index 3b4b246bd..000000000
--- a/src/charon/control/interfaces/stroke_interface.c
+++ /dev/null
@@ -1,1818 +0,0 @@
-/**
- * @file stroke_interface.c
- *
- * @brief Implementation of stroke_interface_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Tobias Brunner
- * Copyright (C) 2006-2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/fcntl.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <errno.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include "stroke_interface.h"
-
-#include <library.h>
-#include <stroke.h>
-#include <daemon.h>
-#include <crypto/x509.h>
-#include <crypto/ietf_attr_list.h>
-#include <crypto/ac.h>
-#include <crypto/ca.h>
-#include <crypto/crl.h>
-#include <control/interface_manager.h>
-#include <control/interfaces/interface.h>
-#include <utils/leak_detective.h>
-#include <processing/jobs/callback_job.h>
-
-#define IKE_PORT 500
-#define PATH_BUF 256
-#define STROKE_THREADS 3
-
-typedef struct private_stroke_interface_t private_stroke_interface_t;
-
-/**
- * Private data of an stroke_interfacet object.
- */
-struct private_stroke_interface_t {
-
- /**
- * Public part of stroke_interfacet object.
- */
- stroke_interface_t public;
-
- /**
- * Unix socket to listen for strokes
- */
- int socket;
-
- /**
- * job accepting stroke messages
- */
- callback_job_t *job;
-};
-
-typedef struct stroke_log_info_t stroke_log_info_t;
-
-/**
- * helper struct to say what and where to log when using controller callback
- */
-struct stroke_log_info_t {
-
- /**
- * level to log up to
- */
- level_t level;
-
- /**
- * where to write log
- */
- FILE* out;
-};
-
-/**
- * Helper function which corrects the string pointers
- * in a stroke_msg_t. Strings in a stroke_msg sent over "wire"
- * contains RELATIVE addresses (relative to the beginning of the
- * stroke_msg). They must be corrected if they reach our address
- * space...
- */
-static void pop_string(stroke_msg_t *msg, char **string)
-{
- if (*string == NULL)
- return;
-
- /* check for sanity of string pointer and string */
- if (string < (char**)msg
- || string > (char**)msg + sizeof(stroke_msg_t)
- || (unsigned long)*string < (unsigned long)((char*)msg->buffer - (char*)msg)
- || (unsigned long)*string > msg->length)
- {
- *string = "(invalid pointer in stroke msg)";
- }
- else
- {
- *string = (char*)msg + (unsigned long)*string;
- }
-}
-
-/**
- * Load end entitity certificate
- */
-static x509_t* load_end_certificate(const char *filename, identification_t **idp)
-{
- char path[PATH_BUF];
- x509_t *cert;
-
- if (*filename == '/')
- {
- /* absolute path name */
- snprintf(path, sizeof(path), "%s", filename);
- }
- else
- {
- /* relative path name */
- snprintf(path, sizeof(path), "%s/%s", CERTIFICATE_DIR, filename);
- }
-
- cert = x509_create_from_file(path, "end entity");
-
- if (cert)
- {
- identification_t *id = *idp;
- identification_t *subject = cert->get_subject(cert);
-
- err_t ugh = cert->is_valid(cert, NULL);
-
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "warning: certificate %s", ugh);
- }
- if (!id->equals(id, subject) && !cert->equals_subjectAltName(cert, id))
- {
- id->destroy(id);
- id = subject;
- *idp = id->clone(id);
- }
- return charon->credentials->add_end_certificate(charon->credentials, cert);
- }
- return NULL;
-}
-
-/**
- * Load ca certificate
- */
-static x509_t* load_ca_certificate(const char *filename)
-{
- char path[PATH_BUF];
- x509_t *cert;
-
- if (*filename == '/')
- {
- /* absolute path name */
- snprintf(path, sizeof(path), "%s", filename);
- }
- else
- {
- /* relative path name */
- snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
- }
-
- cert = x509_create_from_file(path, "ca");
-
- if (cert)
- {
- if (cert->is_ca(cert))
- {
- return charon->credentials->add_auth_certificate(charon->credentials, cert, AUTH_CA);
- }
- else
- {
- DBG1(DBG_CFG, " CA basic constraints flag not set, cert discarded");
- cert->destroy(cert);
- }
- }
- return NULL;
-}
-
-/**
- * Pop the strings of a stroke_end_t struct and log them for debugging purposes
- */
-static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
-{
- pop_string(msg, &end->address);
- pop_string(msg, &end->subnet);
- pop_string(msg, &end->sourceip);
- pop_string(msg, &end->id);
- pop_string(msg, &end->cert);
- pop_string(msg, &end->ca);
- pop_string(msg, &end->groups);
- pop_string(msg, &end->updown);
-
- DBG2(DBG_CFG, " %s=%s", label, end->address);
- DBG2(DBG_CFG, " %ssubnet=%s", label, end->subnet);
- DBG2(DBG_CFG, " %ssourceip=%s", label, end->sourceip);
- DBG2(DBG_CFG, " %sid=%s", label, end->id);
- DBG2(DBG_CFG, " %scert=%s", label, end->cert);
- DBG2(DBG_CFG, " %sca=%s", label, end->ca);
- DBG2(DBG_CFG, " %sgroups=%s", label, end->groups);
- DBG2(DBG_CFG, " %supdown=%s", label, end->updown);
-}
-
-/**
- * Add a connection to the configuration list
- */
-static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
-{
- ike_cfg_t *ike_cfg;
- peer_cfg_t *peer_cfg;
- peer_cfg_t *mediated_by_cfg = NULL;
- child_cfg_t *child_cfg;
- identification_t *my_id, *other_id;
- identification_t *my_ca = NULL;
- identification_t *other_ca = NULL;
- identification_t *peer_id = NULL;
- bool my_ca_same = FALSE;
- bool other_ca_same =FALSE;
- host_t *my_host, *other_host, *my_subnet, *other_subnet;
- host_t *my_vip = NULL, *other_vip = NULL;
- linked_list_t *other_groups = linked_list_create();
- proposal_t *proposal;
- traffic_selector_t *my_ts, *other_ts;
- char *interface;
- bool use_existing = FALSE;
- iterator_t *iterator;
- u_int32_t vendor;
-
- pop_string(msg, &msg->add_conn.name);
- DBG1(DBG_CFG, "received stroke: add connection '%s'", msg->add_conn.name);
- DBG2(DBG_CFG, "conn %s", msg->add_conn.name);
- pop_end(msg, "left", &msg->add_conn.me);
- pop_end(msg, "right", &msg->add_conn.other);
- pop_string(msg, &msg->add_conn.algorithms.ike);
- pop_string(msg, &msg->add_conn.algorithms.esp);
- DBG2(DBG_CFG, " ike=%s", msg->add_conn.algorithms.ike);
- DBG2(DBG_CFG, " esp=%s", msg->add_conn.algorithms.esp);
- pop_string(msg, &msg->add_conn.p2p.mediated_by);
- pop_string(msg, &msg->add_conn.p2p.peerid);
- DBG2(DBG_CFG, " p2p_mediation=%s", msg->add_conn.p2p.mediation ? "yes" : "no");
- DBG2(DBG_CFG, " p2p_mediated_by=%s", msg->add_conn.p2p.mediated_by);
- DBG2(DBG_CFG, " p2p_peerid=%s", msg->add_conn.p2p.peerid);
-
- my_host = msg->add_conn.me.address ?
- host_create_from_string(msg->add_conn.me.address, IKE_PORT) : NULL;
- if (my_host == NULL)
- {
- DBG1(DBG_CFG, "invalid host: %s\n", msg->add_conn.me.address);
- return;
- }
-
- other_host = msg->add_conn.other.address ?
- host_create_from_string(msg->add_conn.other.address, IKE_PORT) : NULL;
- if (other_host == NULL)
- {
- DBG1(DBG_CFG, "invalid host: %s\n", msg->add_conn.other.address);
- my_host->destroy(my_host);
- return;
- }
-
- interface = charon->kernel_interface->get_interface(charon->kernel_interface,
- other_host);
- if (interface)
- {
- stroke_end_t tmp_end;
- host_t *tmp_host;
-
- DBG2(DBG_CFG, "left is other host, swapping ends\n");
-
- tmp_host = my_host;
- my_host = other_host;
- other_host = tmp_host;
-
- tmp_end = msg->add_conn.me;
- msg->add_conn.me = msg->add_conn.other;
- msg->add_conn.other = tmp_end;
- free(interface);
- }
- else
- {
- interface = charon->kernel_interface->get_interface(
- charon->kernel_interface, my_host);
- if (!interface)
- {
- DBG1(DBG_CFG, "left nor right host is our side, assuming left=local");
- }
- else
- {
- free(interface);
- }
- }
-
- my_id = identification_create_from_string(msg->add_conn.me.id ?
- msg->add_conn.me.id : msg->add_conn.me.address);
- if (my_id == NULL)
- {
- DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.me.id);
- goto destroy_hosts;
- }
-
- other_id = identification_create_from_string(msg->add_conn.other.id ?
- msg->add_conn.other.id : msg->add_conn.other.address);
- if (other_id == NULL)
- {
- DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.other.id);
- my_id->destroy(my_id);
- goto destroy_hosts;
- }
-
-#ifdef P2P
- if (msg->add_conn.p2p.mediation && msg->add_conn.p2p.mediated_by)
- {
- DBG1(DBG_CFG, "a mediation connection cannot be a"
- " mediated connection at the same time, aborting");
- goto destroy_ids;
- }
-
- if (msg->add_conn.p2p.mediated_by)
- {
- mediated_by_cfg = charon->backends->get_peer_cfg_by_name(charon->backends, msg->add_conn.p2p.mediated_by);
- if (!mediated_by_cfg)
- {
- DBG1(DBG_CFG, "mediation connection '%s' not found, aborting",
- msg->add_conn.p2p.mediated_by);
- goto destroy_ids;
- }
-
- if (!mediated_by_cfg->is_mediation(mediated_by_cfg))
- {
- DBG1(DBG_CFG, "connection '%s' as referred to by '%s' is"
- "no mediation connection, aborting",
- msg->add_conn.p2p.mediated_by, msg->add_conn.name);
- goto destroy_ids;
- }
- }
-
- if (msg->add_conn.p2p.peerid)
- {
- peer_id = identification_create_from_string(msg->add_conn.p2p.peerid);
- if (!peer_id)
- {
- DBG1(DBG_CFG, "invalid peer ID: %s\n", msg->add_conn.p2p.peerid);
- goto destroy_ids;
- }
- }
- else
- {
- /* no peer ID supplied, assume right ID */
- peer_id = other_id->clone(other_id);
- }
-#endif /* P2P */
-
- my_subnet = host_create_from_string(msg->add_conn.me.subnet ?
- msg->add_conn.me.subnet : msg->add_conn.me.address, IKE_PORT);
- if (my_subnet == NULL)
- {
- DBG1(DBG_CFG, "invalid subnet: %s\n", msg->add_conn.me.subnet);
- goto destroy_ids;
- }
-
- other_subnet = host_create_from_string(msg->add_conn.other.subnet ?
- msg->add_conn.other.subnet : msg->add_conn.other.address, IKE_PORT);
- if (other_subnet == NULL)
- {
- DBG1(DBG_CFG, "invalid subnet: %s\n", msg->add_conn.me.subnet);
- my_subnet->destroy(my_subnet);
- goto destroy_ids;
- }
-
- if (msg->add_conn.me.virtual_ip && msg->add_conn.me.sourceip)
- {
- my_vip = host_create_from_string(msg->add_conn.me.sourceip, 0);
- }
- if (msg->add_conn.other.virtual_ip && msg->add_conn.other.sourceip)
- {
- other_vip = host_create_from_string(msg->add_conn.other.sourceip, 0);
- }
-
- if (msg->add_conn.me.tohost)
- {
- my_ts = traffic_selector_create_dynamic(msg->add_conn.me.protocol,
- my_host->get_family(my_host) == AF_INET ?
- TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE,
- msg->add_conn.me.port ? msg->add_conn.me.port : 0,
- msg->add_conn.me.port ? msg->add_conn.me.port : 65535);
- }
- else
- {
- my_ts = traffic_selector_create_from_subnet(my_subnet,
- msg->add_conn.me.subnet ? msg->add_conn.me.subnet_mask : 0,
- msg->add_conn.me.protocol, msg->add_conn.me.port);
- }
- my_subnet->destroy(my_subnet);
-
- if (msg->add_conn.other.tohost)
- {
- other_ts = traffic_selector_create_dynamic(msg->add_conn.other.protocol,
- other_host->get_family(other_host) == AF_INET ?
- TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE,
- msg->add_conn.other.port ? msg->add_conn.other.port : 0,
- msg->add_conn.other.port ? msg->add_conn.other.port : 65535);
- }
- else
- {
- other_ts = traffic_selector_create_from_subnet(other_subnet,
- msg->add_conn.other.subnet ? msg->add_conn.other.subnet_mask : 0,
- msg->add_conn.other.protocol, msg->add_conn.other.port);
- }
- other_subnet->destroy(other_subnet);
-
- if (msg->add_conn.me.ca)
- {
- if (streq(msg->add_conn.me.ca, "%same"))
- {
- my_ca_same = TRUE;
- }
- else
- {
- my_ca = identification_create_from_string(msg->add_conn.me.ca);
- }
- }
- if (msg->add_conn.other.ca)
- {
- if (streq(msg->add_conn.other.ca, "%same"))
- {
- other_ca_same = TRUE;
- }
- else
- {
- other_ca = identification_create_from_string(msg->add_conn.other.ca);
- }
- }
- if (msg->add_conn.me.cert)
- {
- x509_t *cert = load_end_certificate(msg->add_conn.me.cert, &my_id);
-
- if (cert)
- {
- ca_info_t *ca_info;
-
- if (cert->is_self_signed(cert))
- {
- /* a self-signed certificate is its own ca */
- ca_info = ca_info_create(NULL, cert);
- ca_info = charon->credentials->add_ca_info(charon->credentials, ca_info);
- cert->set_ca_info(cert, ca_info);
- }
- else
- {
- /* get_issuer() automatically sets cert->ca_info */
- ca_info = charon->credentials->get_issuer(charon->credentials, cert);
- }
- if (my_ca == NULL && !my_ca_same)
- {
- identification_t *issuer = cert->get_issuer(cert);
-
- my_ca = issuer->clone(issuer);
- }
- }
- }
- if (msg->add_conn.other.cert)
- {
- x509_t *cert = load_end_certificate(msg->add_conn.other.cert, &other_id);
-
- if (cert)
- {
- ca_info_t *ca_info;
-
- if (cert->is_self_signed(cert))
- {
- /* a self-signed certificate is its own ca */
- ca_info = ca_info_create(NULL, cert);
- ca_info = charon->credentials->add_ca_info(charon->credentials, ca_info);
- cert->set_ca_info(cert, ca_info);
- }
- else
- {
- /* get_issuer() automatically sets cert->ca_info */
- ca_info = charon->credentials->get_issuer(charon->credentials, cert);
- }
- if (other_ca == NULL && !other_ca_same)
- {
- identification_t *issuer = cert->get_issuer(cert);
-
- other_ca = issuer->clone(issuer);
- }
- }
- }
- if (other_ca_same && my_ca)
- {
- other_ca = my_ca->clone(my_ca);
- }
- else if (my_ca_same && other_ca)
- {
- my_ca = other_ca->clone(other_ca);
- }
- if (my_ca == NULL)
- {
- my_ca = identification_create_from_string("%any");
- }
- if (other_ca == NULL)
- {
- other_ca = identification_create_from_string("%any");
- }
- DBG2(DBG_CFG, " my ca: '%D'", my_ca);
- DBG2(DBG_CFG, " other ca:'%D'", other_ca);
-
- if (msg->add_conn.other.groups)
- {
- ietfAttr_list_create_from_string(msg->add_conn.other.groups, other_groups);
- }
-
- /* have a look for an (almost) identical peer config to reuse */
- iterator = charon->backends->create_iterator(charon->backends);
- while (iterator->iterate(iterator, (void**)&peer_cfg))
- {
- host_t *my_vip_conf, *other_vip_conf;
- bool my_vip_equals = FALSE, other_vip_equals = FALSE;
-
- my_vip_conf = peer_cfg->get_my_virtual_ip(peer_cfg);
- if ((my_vip && my_vip_conf && my_vip->equals(my_vip, my_vip_conf)) ||
- (!my_vip_conf && !my_vip))
- {
- my_vip_equals = TRUE;
- }
- DESTROY_IF(my_vip_conf);
- other_vip_conf = peer_cfg->get_other_virtual_ip(peer_cfg, NULL);
- if ((other_vip && other_vip_conf && other_vip->equals(other_vip, other_vip_conf)) ||
- (!other_vip_conf && !other_vip))
- {
- other_vip_equals = TRUE;
- }
- DESTROY_IF(other_vip_conf);
-
- ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
- if (my_id->equals(my_id, peer_cfg->get_my_id(peer_cfg))
- && other_id->equals(other_id, peer_cfg->get_other_id(peer_cfg))
- && my_host->equals(my_host, ike_cfg->get_my_host(ike_cfg))
- && other_host->equals(other_host, ike_cfg->get_other_host(ike_cfg))
- && other_ca->equals(other_ca, peer_cfg->get_other_ca(peer_cfg))
- && ietfAttr_list_equals(other_groups, peer_cfg->get_groups(peer_cfg))
- && peer_cfg->get_ike_version(peer_cfg) == (msg->add_conn.ikev2 ? 2 : 1)
- && peer_cfg->get_auth_method(peer_cfg) == msg->add_conn.auth_method
- && peer_cfg->get_eap_type(peer_cfg, &vendor) == msg->add_conn.eap_type
- && vendor == msg->add_conn.eap_vendor
- && my_vip_equals && other_vip_equals)
- {
- DBG1(DBG_CFG, "reusing existing configuration '%s'",
- peer_cfg->get_name(peer_cfg));
- use_existing = TRUE;
- break;
- }
- }
- iterator->destroy(iterator);
-
- if (use_existing)
- {
- DESTROY_IF(my_vip);
- DESTROY_IF(other_vip);
- my_host->destroy(my_host);
- my_id->destroy(my_id);
- my_ca->destroy(my_ca);
- other_host->destroy(other_host);
- other_id->destroy(other_id);
- other_ca->destroy(other_ca);
- DESTROY_IF(peer_id);
- DESTROY_IF(mediated_by_cfg);
- ietfAttr_list_destroy(other_groups);
- }
- else
- {
- ike_cfg = ike_cfg_create(msg->add_conn.other.sendcert != CERT_NEVER_SEND,
- msg->add_conn.force_encap, my_host, other_host);
-
- if (msg->add_conn.algorithms.ike)
- {
- char *proposal_string;
- char *strict = msg->add_conn.algorithms.ike + strlen(msg->add_conn.algorithms.ike) - 1;
-
- if (*strict == '!')
- *strict = '\0';
- else
- strict = NULL;
-
- while ((proposal_string = strsep(&msg->add_conn.algorithms.ike, ",")))
- {
- proposal = proposal_create_from_string(PROTO_IKE, proposal_string);
- if (proposal == NULL)
- {
- DBG1(DBG_CFG, "invalid IKE proposal string: %s", proposal_string);
- my_id->destroy(my_id);
- other_id->destroy(other_id);
- my_ts->destroy(my_ts);
- other_ts->destroy(other_ts);
- my_ca->destroy(my_ca);
- other_ca->destroy(other_ca);
- ike_cfg->destroy(ike_cfg);
- return;
- }
- ike_cfg->add_proposal(ike_cfg, proposal);
- }
- if (!strict)
- {
- proposal = proposal_create_default(PROTO_IKE);
- ike_cfg->add_proposal(ike_cfg, proposal);
- }
- }
- else
- {
- proposal = proposal_create_default(PROTO_IKE);
- ike_cfg->add_proposal(ike_cfg, proposal);
- }
-
- u_int32_t rekey = 0, reauth = 0, over, jitter;
-
- jitter = msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100;
- over = msg->add_conn.rekey.margin;
- if (msg->add_conn.rekey.reauth)
- {
- reauth = msg->add_conn.rekey.ike_lifetime - over;
- }
- else
- {
- rekey = msg->add_conn.rekey.ike_lifetime - over;
- }
-
- peer_cfg = peer_cfg_create(msg->add_conn.name, msg->add_conn.ikev2 ? 2 : 1,
- ike_cfg, my_id, other_id, my_ca, other_ca, other_groups,
- msg->add_conn.me.sendcert, msg->add_conn.auth_method,
- msg->add_conn.eap_type, msg->add_conn.eap_vendor,
- msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
- msg->add_conn.mobike,
- msg->add_conn.dpd.delay, msg->add_conn.dpd.action, my_vip, other_vip,
- msg->add_conn.p2p.mediation, mediated_by_cfg, peer_id);
- }
-
- child_cfg = child_cfg_create(
- msg->add_conn.name, msg->add_conn.rekey.ipsec_lifetime,
- msg->add_conn.rekey.ipsec_lifetime - msg->add_conn.rekey.margin,
- msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100,
- msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
- msg->add_conn.mode);
-
- peer_cfg->add_child_cfg(peer_cfg, child_cfg);
-
- child_cfg->add_traffic_selector(child_cfg, TRUE, my_ts);
- child_cfg->add_traffic_selector(child_cfg, FALSE, other_ts);
-
- if (msg->add_conn.algorithms.esp)
- {
- char *proposal_string;
- char *strict = msg->add_conn.algorithms.esp + strlen(msg->add_conn.algorithms.esp) - 1;
-
- if (*strict == '!')
- *strict = '\0';
- else
- strict = NULL;
-
- while ((proposal_string = strsep(&msg->add_conn.algorithms.esp, ",")))
- {
- proposal = proposal_create_from_string(PROTO_ESP, proposal_string);
- if (proposal == NULL)
- {
- DBG1(DBG_CFG, "invalid ESP proposal string: %s", proposal_string);
- peer_cfg->destroy(peer_cfg);
- return;
- }
- child_cfg->add_proposal(child_cfg, proposal);
- }
- if (!strict)
- {
- proposal = proposal_create_default(PROTO_ESP);
- child_cfg->add_proposal(child_cfg, proposal);
- }
- }
- else
- {
- proposal = proposal_create_default(PROTO_ESP);
- child_cfg->add_proposal(child_cfg, proposal);
- }
-
- if (!use_existing)
- {
- /* add config to backend */
- charon->backends->add_peer_cfg(charon->backends, peer_cfg);
- DBG1(DBG_CFG, "added configuration '%s': %H[%D]...%H[%D]",
- msg->add_conn.name, my_host, my_id, other_host, other_id);
- }
- return;
-
- /* mopping up after parsing errors */
-
-destroy_ids:
- my_id->destroy(my_id);
- other_id->destroy(other_id);
- DESTROY_IF(mediated_by_cfg);
- DESTROY_IF(peer_id);
-
-destroy_hosts:
- my_host->destroy(my_host);
- other_host->destroy(other_host);
-}
-
-/**
- * Delete a connection from the list
- */
-static void stroke_del_conn(stroke_msg_t *msg, FILE *out)
-{
- iterator_t *peer_iter, *child_iter;
- peer_cfg_t *peer;
- child_cfg_t *child;
-
- pop_string(msg, &(msg->del_conn.name));
- DBG1(DBG_CFG, "received stroke: delete connection '%s'", msg->del_conn.name);
-
- peer_iter = charon->backends->create_iterator(charon->backends);
- while (peer_iter->iterate(peer_iter, (void**)&peer))
- {
- /* remove peer config with such a name */
- if (streq(peer->get_name(peer), msg->del_conn.name))
- {
- peer_iter->remove(peer_iter);
- peer->destroy(peer);
- continue;
- }
- /* remove any child with such a name */
- child_iter = peer->create_child_cfg_iterator(peer);
- while (child_iter->iterate(child_iter, (void**)&child))
- {
- if (streq(child->get_name(child), msg->del_conn.name))
- {
- child_iter->remove(child_iter);
- child->destroy(child);
- }
- }
- child_iter->destroy(child_iter);
- }
- peer_iter->destroy(peer_iter);
-
- fprintf(out, "deleted connection '%s'\n", msg->del_conn.name);
-}
-
-/**
- * get the child_cfg with the same name as the peer cfg
- */
-static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
-{
- child_cfg_t *current, *found = NULL;
- iterator_t *iterator;
-
- iterator = peer_cfg->create_child_cfg_iterator(peer_cfg);
- while (iterator->iterate(iterator, (void**)&current))
- {
- if (streq(current->get_name(current), name))
- {
- found = current;
- found->get_ref(found);
- break;
- }
- }
- iterator->destroy(iterator);
- return found;
-}
-
-/**
- * logging to the stroke interface
- */
-static bool stroke_log(stroke_log_info_t *info, signal_t signal, level_t level,
- ike_sa_t *ike_sa, char *format, va_list args)
-{
- if (level <= info->level)
- {
- if (vfprintf(info->out, format, args) < 0 ||
- fprintf(info->out, "\n") < 0 ||
- fflush(info->out) != 0)
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-/**
- * initiate a connection by name
- */
-static void stroke_initiate(stroke_msg_t *msg, FILE *out)
-{
- peer_cfg_t *peer_cfg;
- child_cfg_t *child_cfg;
- stroke_log_info_t info;
-
- pop_string(msg, &(msg->initiate.name));
- DBG1(DBG_CFG, "received stroke: initiate '%s'", msg->initiate.name);
-
- peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
- msg->initiate.name);
- if (peer_cfg == NULL)
- {
- fprintf(out, "no config named '%s'\n", msg->initiate.name);
- return;
- }
- if (peer_cfg->get_ike_version(peer_cfg) != 2)
- {
- DBG1(DBG_CFG, "ignoring initiation request for IKEv%d config",
- peer_cfg->get_ike_version(peer_cfg));
- peer_cfg->destroy(peer_cfg);
- return;
- }
-
- child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
- if (child_cfg == NULL)
- {
- fprintf(out, "no child config named '%s'\n", msg->initiate.name);
- peer_cfg->destroy(peer_cfg);
- return;
- }
-
- if (msg->output_verbosity < 0)
- {
- charon->interfaces->initiate(charon->interfaces, peer_cfg, child_cfg,
- NULL, NULL);
- }
- else
- {
- info.out = out;
- info.level = msg->output_verbosity;
- charon->interfaces->initiate(charon->interfaces, peer_cfg, child_cfg,
- (interface_manager_cb_t)stroke_log, &info);
- }
-}
-
-/**
- * route a policy (install SPD entries)
- */
-static void stroke_route(stroke_msg_t *msg, FILE *out)
-{
- peer_cfg_t *peer_cfg;
- child_cfg_t *child_cfg;
- stroke_log_info_t info;
-
- pop_string(msg, &(msg->route.name));
- DBG1(DBG_CFG, "received stroke: route '%s'", msg->route.name);
-
- peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
- msg->route.name);
- if (peer_cfg == NULL)
- {
- fprintf(out, "no config named '%s'\n", msg->route.name);
- return;
- }
- if (peer_cfg->get_ike_version(peer_cfg) != 2)
- {
- peer_cfg->destroy(peer_cfg);
- return;
- }
-
- child_cfg = get_child_from_peer(peer_cfg, msg->route.name);
- if (child_cfg == NULL)
- {
- fprintf(out, "no child config named '%s'\n", msg->route.name);
- peer_cfg->destroy(peer_cfg);
- return;
- }
-
- info.out = out;
- info.level = msg->output_verbosity;
- charon->interfaces->route(charon->interfaces, peer_cfg, child_cfg,
- (interface_manager_cb_t)stroke_log, &info);
- peer_cfg->destroy(peer_cfg);
- child_cfg->destroy(child_cfg);
-}
-
-/**
- * unroute a policy
- */
-static void stroke_unroute(stroke_msg_t *msg, FILE *out)
-{
- char *name;
- ike_sa_t *ike_sa;
- iterator_t *iterator;
- stroke_log_info_t info;
-
- pop_string(msg, &(msg->terminate.name));
- name = msg->terminate.name;
-
- info.out = out;
- info.level = msg->output_verbosity;
-
- iterator = charon->interfaces->create_ike_sa_iterator(charon->interfaces);
- while (iterator->iterate(iterator, (void**)&ike_sa))
- {
- child_sa_t *child_sa;
- iterator_t *children;
- u_int32_t id;
-
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
- {
- if (child_sa->get_state(child_sa) == CHILD_ROUTED &&
- streq(name, child_sa->get_name(child_sa)))
- {
- id = child_sa->get_reqid(child_sa);
- children->destroy(children);
- iterator->destroy(iterator);
- charon->interfaces->unroute(charon->interfaces, id,
- (interface_manager_cb_t)stroke_log, &info);
- return;
- }
- }
- children->destroy(children);
- }
- iterator->destroy(iterator);
- DBG1(DBG_CFG, "no such SA found");
-}
-
-/**
- * terminate a connection by name
- */
-static void stroke_terminate(stroke_msg_t *msg, FILE *out)
-{
- char *string, *pos = NULL, *name = NULL;
- u_int32_t id = 0;
- bool child;
- int len;
- ike_sa_t *ike_sa;
- iterator_t *iterator;
- stroke_log_info_t info;
-
- pop_string(msg, &(msg->terminate.name));
- string = msg->terminate.name;
- DBG1(DBG_CFG, "received stroke: terminate '%s'", string);
-
- len = strlen(string);
- if (len < 1)
- {
- DBG1(DBG_CFG, "error parsing string");
- return;
- }
- switch (string[len-1])
- {
- case '}':
- child = TRUE;
- pos = strchr(string, '{');
- break;
- case ']':
- child = FALSE;
- pos = strchr(string, '[');
- break;
- default:
- name = string;
- child = FALSE;
- break;
- }
-
- if (name)
- {
- /* is a single name */
- }
- else if (pos == string + len - 2)
- { /* is name[] or name{} */
- string[len-2] = '\0';
- name = string;
- }
- else
- { /* is name[123] or name{23} */
- string[len-1] = '\0';
- id = atoi(pos + 1);
- if (id == 0)
- {
- DBG1(DBG_CFG, "error parsing string");
- return;
- }
- }
-
- info.out = out;
- info.level = msg->output_verbosity;
-
- iterator = charon->interfaces->create_ike_sa_iterator(charon->interfaces);
- while (iterator->iterate(iterator, (void**)&ike_sa))
- {
- child_sa_t *child_sa;
- iterator_t *children;
-
- if (child)
- {
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
- {
- if ((name && streq(name, child_sa->get_name(child_sa))) ||
- (id && id == child_sa->get_reqid(child_sa)))
- {
- id = child_sa->get_reqid(child_sa);
- children->destroy(children);
- iterator->destroy(iterator);
-
- charon->interfaces->terminate_child(charon->interfaces, id,
- (interface_manager_cb_t)stroke_log, &info);
- return;
- }
- }
- children->destroy(children);
- }
- else if ((name && streq(name, ike_sa->get_name(ike_sa))) ||
- (id && id == ike_sa->get_unique_id(ike_sa)))
- {
- id = ike_sa->get_unique_id(ike_sa);
- /* unlock manager first */
- iterator->destroy(iterator);
-
- charon->interfaces->terminate_ike(charon->interfaces, id,
- (interface_manager_cb_t)stroke_log, &info);
- return;
- }
-
- }
- iterator->destroy(iterator);
- DBG1(DBG_CFG, "no such SA found");
-}
-
-/**
- * Add a ca information record to the cainfo list
- */
-static void stroke_add_ca(stroke_msg_t *msg, FILE *out)
-{
- x509_t *cacert;
- ca_info_t *ca_info;
-
- pop_string(msg, &msg->add_ca.name);
- pop_string(msg, &msg->add_ca.cacert);
- pop_string(msg, &msg->add_ca.crluri);
- pop_string(msg, &msg->add_ca.crluri2);
- pop_string(msg, &msg->add_ca.ocspuri);
- pop_string(msg, &msg->add_ca.ocspuri2);
-
- DBG1(DBG_CFG, "received stroke: add ca '%s'", msg->add_ca.name);
-
- DBG2(DBG_CFG, "ca %s", msg->add_ca.name);
- DBG2(DBG_CFG, " cacert=%s", msg->add_ca.cacert);
- DBG2(DBG_CFG, " crluri=%s", msg->add_ca.crluri);
- DBG2(DBG_CFG, " crluri2=%s", msg->add_ca.crluri2);
- DBG2(DBG_CFG, " ocspuri=%s", msg->add_ca.ocspuri);
- DBG2(DBG_CFG, " ocspuri2=%s", msg->add_ca.ocspuri2);
-
- if (msg->add_ca.cacert == NULL)
- {
- DBG1(DBG_CFG, "missing cacert parameter\n");
- return;
- }
-
- cacert = load_ca_certificate(msg->add_ca.cacert);
-
- if (cacert == NULL)
- {
- return;
- }
- ca_info = ca_info_create(msg->add_ca.name, cacert);
-
- if (msg->add_ca.crluri)
- {
- chunk_t uri = { msg->add_ca.crluri, strlen(msg->add_ca.crluri) };
-
- ca_info->add_crluri(ca_info, uri);
- }
- if (msg->add_ca.crluri2)
- {
- chunk_t uri = { msg->add_ca.crluri2, strlen(msg->add_ca.crluri2) };
-
- ca_info->add_crluri(ca_info, uri);
- }
- if (msg->add_ca.ocspuri)
- {
- chunk_t uri = { msg->add_ca.ocspuri, strlen(msg->add_ca.ocspuri) };
-
- ca_info->add_ocspuri(ca_info, uri);
- }
- if (msg->add_ca.ocspuri2)
- {
- chunk_t uri = { msg->add_ca.ocspuri2, strlen(msg->add_ca.ocspuri2) };
-
- ca_info->add_ocspuri(ca_info, uri);
- }
- charon->credentials->add_ca_info(charon->credentials, ca_info);
- DBG1(DBG_CFG, "added ca '%s'", msg->add_ca.name);
-
-}
-
-/**
- * Delete a ca information record from the cainfo list
- */
-static void stroke_del_ca(stroke_msg_t *msg, FILE *out)
-{
- status_t status;
-
- pop_string(msg, &(msg->del_ca.name));
- DBG1(DBG_CFG, "received stroke: delete ca '%s'", msg->del_ca.name);
-
- status = charon->credentials->release_ca_info(charon->credentials,
- msg->del_ca.name);
-
- if (status == SUCCESS)
- {
- fprintf(out, "deleted ca '%s'\n", msg->del_ca.name);
- }
- else
- {
- fprintf(out, "no ca named '%s'\n", msg->del_ca.name);
- }
-}
-
-/**
- * log an IKE_SA to out
- */
-static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
-{
- ike_sa_id_t *id = ike_sa->get_id(ike_sa);
- u_int32_t rekey, reauth;
-
- fprintf(out, "%12s[%d]: %N, %H[%D]...%H[%D]\n",
- ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
- ike_sa_state_names, ike_sa->get_state(ike_sa),
- ike_sa->get_my_host(ike_sa), ike_sa->get_my_id(ike_sa),
- ike_sa->get_other_host(ike_sa), ike_sa->get_other_id(ike_sa));
-
- if (all)
- {
- fprintf(out, "%12s[%d]: IKE SPIs: %.16llx_i%s %.16llx_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) ? "" : "*");
-
- rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY_TIME);
- reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH_TIME);
- if (rekey)
- {
- fprintf(out, ", rekeying in %V", &rekey);
- }
- if (reauth)
- {
- fprintf(out, ", reauthentication in %V", &reauth);
- }
- if (!rekey && !reauth)
- {
- fprintf(out, ", rekeying disabled");
- }
- fprintf(out, "\n");
- }
-}
-
-/**
- * log an CHILD_SA to out
- */
-static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
-{
- u_int32_t rekey, now = time(NULL);
- u_int32_t use_in, use_out, use_fwd;
- encryption_algorithm_t encr_alg;
- integrity_algorithm_t int_alg;
- size_t encr_len, int_len;
- mode_t mode;
-
- child_sa->get_stats(child_sa, &mode, &encr_alg, &encr_len,
- &int_alg, &int_len, &rekey, &use_in, &use_out,
- &use_fwd);
-
- fprintf(out, "%12s{%d}: %N, %N",
- child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
- child_sa_state_names, child_sa->get_state(child_sa),
- mode_names, mode);
-
- if (child_sa->get_state(child_sa) == CHILD_INSTALLED)
- {
- fprintf(out, ", %N SPIs: %.8x_i %.8x_o",
- protocol_id_names, child_sa->get_protocol(child_sa),
- htonl(child_sa->get_spi(child_sa, TRUE)),
- htonl(child_sa->get_spi(child_sa, FALSE)));
-
- if (all)
- {
- fprintf(out, "\n%12s{%d}: ", child_sa->get_name(child_sa),
- child_sa->get_reqid(child_sa));
-
-
- if (child_sa->get_protocol(child_sa) == PROTO_ESP)
- {
- fprintf(out, "%N", encryption_algorithm_names, encr_alg);
-
- if (encr_len)
- {
- fprintf(out, "-%d", encr_len);
- }
- fprintf(out, "/");
- }
-
- fprintf(out, "%N", integrity_algorithm_names, int_alg);
- if (int_len)
- {
- fprintf(out, "-%d", int_len);
- }
- fprintf(out, ", rekeying ");
-
- if (rekey)
- {
- fprintf(out, "in %#V", &now, &rekey);
- }
- else
- {
- fprintf(out, "disabled");
- }
-
- fprintf(out, ", last use: ");
- use_in = max(use_in, use_fwd);
- if (use_in)
- {
- fprintf(out, "%ds_i ", now - use_in);
- }
- else
- {
- fprintf(out, "no_i ");
- }
- if (use_out)
- {
- fprintf(out, "%ds_o ", now - use_out);
- }
- else
- {
- fprintf(out, "no_o ");
- }
- }
- }
-
- fprintf(out, "\n%12s{%d}: %#R=== %#R\n",
- child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
- child_sa->get_traffic_selectors(child_sa, TRUE),
- child_sa->get_traffic_selectors(child_sa, FALSE));
-}
-
-/**
- * show status of daemon
- */
-static void stroke_status(stroke_msg_t *msg, FILE *out, bool all)
-{
- iterator_t *iterator, *children;
- host_t *host;
- peer_cfg_t *peer_cfg;
- ike_cfg_t *ike_cfg;
- child_cfg_t *child_cfg;
- ike_sa_t *ike_sa;
- char *name = NULL;
-
- if (msg->status.name)
- {
- pop_string(msg, &(msg->status.name));
- name = msg->status.name;
- }
-
- if (all)
- {
- leak_detective_status(out);
-
- fprintf(out, "Performance:\n");
- fprintf(out, " worker threads: %d idle of %d,",
- charon->processor->get_idle_threads(charon->processor),
- charon->processor->get_total_threads(charon->processor));
- fprintf(out, " job queue load: %d,",
- charon->processor->get_job_load(charon->processor));
- fprintf(out, " scheduled events: %d\n",
- charon->scheduler->get_job_load(charon->scheduler));
- iterator = charon->kernel_interface->create_address_iterator(
- charon->kernel_interface);
- fprintf(out, "Listening IP addresses:\n");
- while (iterator->iterate(iterator, (void**)&host))
- {
- fprintf(out, " %H\n", host);
- }
- iterator->destroy(iterator);
-
- fprintf(out, "Connections:\n");
- iterator = charon->backends->create_iterator(charon->backends);
- while (iterator->iterate(iterator, (void**)&peer_cfg))
- {
- if (peer_cfg->get_ike_version(peer_cfg) != 2 ||
- (name && !streq(name, peer_cfg->get_name(peer_cfg))))
- {
- continue;
- }
-
- ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
- fprintf(out, "%12s: %H[%D]...%H[%D]\n", peer_cfg->get_name(peer_cfg),
- ike_cfg->get_my_host(ike_cfg), peer_cfg->get_my_id(peer_cfg),
- ike_cfg->get_other_host(ike_cfg), peer_cfg->get_other_id(peer_cfg));
- {
- identification_t *my_ca = peer_cfg->get_my_ca(peer_cfg);
- identification_t *other_ca = peer_cfg->get_other_ca(peer_cfg);
- linked_list_t *groups = peer_cfg->get_groups(peer_cfg);
-
- if (my_ca->get_type(my_ca) != ID_ANY
- || other_ca->get_type(other_ca) != ID_ANY)
- {
- fprintf(out, "%12s: CAs: '%D'...'%D'\n", peer_cfg->get_name(peer_cfg),
- my_ca, other_ca);
- }
- if (groups->get_count(groups) > 0)
- {
- fprintf(out, "%12s: groups: ", peer_cfg->get_name(peer_cfg));
- ietfAttr_list_list(groups, out);
- fprintf(out, "\n");
- }
-
- }
- children = peer_cfg->create_child_cfg_iterator(peer_cfg);
- while (children->iterate(children, (void**)&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: %#R=== %#R\n", child_cfg->get_name(child_cfg),
- my_ts, other_ts);
- my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
- other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
- }
- children->destroy(children);
- }
- iterator->destroy(iterator);
- }
-
- iterator = charon->ike_sa_manager->create_iterator(charon->ike_sa_manager);
- if (all && iterator->get_count(iterator) > 0)
- {
- fprintf(out, "Security Associations:\n");
- }
- while (iterator->iterate(iterator, (void**)&ike_sa))
- {
- bool ike_printed = FALSE;
- child_sa_t *child_sa;
- iterator_t *children = ike_sa->create_child_sa_iterator(ike_sa);
-
- if (name == NULL || streq(name, ike_sa->get_name(ike_sa)))
- {
- log_ike_sa(out, ike_sa, all);
- ike_printed = TRUE;
- }
-
- while (children->iterate(children, (void**)&child_sa))
- {
- if (name == NULL || streq(name, child_sa->get_name(child_sa)))
- {
- if (!ike_printed)
- {
- log_ike_sa(out, ike_sa, all);
- ike_printed = TRUE;
- }
- log_child_sa(out, child_sa, all);
- }
- }
- children->destroy(children);
- }
- iterator->destroy(iterator);
-}
-
-/**
- * list all authority certificates matching a specified flag
- */
-static void list_auth_certificates(u_int flag, const char *label,
- bool utc, FILE *out)
-{
- bool first = TRUE;
- x509_t *cert;
-
- iterator_t *iterator = charon->credentials->create_auth_cert_iterator(charon->credentials);
-
- while (iterator->iterate(iterator, (void**)&cert))
- {
- if (cert->has_authority_flag(cert, flag))
- {
- if (first)
- {
- fprintf(out, "\n");
- fprintf(out, "List of X.509 %s Certificates:\n", label);
- fprintf(out, "\n");
- first = FALSE;
- }
- cert->list(cert, out, utc);
- fprintf(out, "\n");
- }
- }
- iterator->destroy(iterator);
-}
-
-/**
- * list various information
- */
-static void stroke_list(stroke_msg_t *msg, FILE *out)
-{
- iterator_t *iterator;
-
- if (msg->list.flags & LIST_CERTS)
- {
- x509_t *cert;
-
- iterator = charon->credentials->create_cert_iterator(charon->credentials);
- if (iterator->get_count(iterator))
- {
- fprintf(out, "\n");
- fprintf(out, "List of X.509 End Entity Certificates:\n");
- fprintf(out, "\n");
- }
- while (iterator->iterate(iterator, (void**)&cert))
- {
- cert->list(cert, out, msg->list.utc);
- if (charon->credentials->has_rsa_private_key(
- charon->credentials, cert->get_public_key(cert)))
- {
- fprintf(out, ", has private key");
- }
- fprintf(out, "\n");
-
- }
- iterator->destroy(iterator);
- }
- if (msg->list.flags & LIST_CACERTS)
- {
- list_auth_certificates(AUTH_CA, "CA", msg->list.utc, out);
- }
- if (msg->list.flags & LIST_OCSPCERTS)
- {
- list_auth_certificates(AUTH_OCSP, "OCSP", msg->list.utc, out);
- }
- if (msg->list.flags & LIST_AACERTS)
- {
- list_auth_certificates(AUTH_AA, "AA", msg->list.utc, out);
- }
- if (msg->list.flags & LIST_ACERTS)
- {
- x509ac_t *cert;
-
- iterator = charon->credentials->create_acert_iterator(charon->credentials);
- if (iterator->get_count(iterator))
- {
- fprintf(out, "\n");
- fprintf(out, "List of X.509 Attribute Certificates:\n");
- fprintf(out, "\n");
- }
- while (iterator->iterate(iterator, (void**)&cert))
- {
- cert->list(cert, out, msg->list.utc);
- }
- iterator->destroy(iterator);
- }
- if (msg->list.flags & LIST_CAINFOS)
- {
- ca_info_t *ca_info;
- bool first = TRUE;
-
- iterator = charon->credentials->create_cainfo_iterator(charon->credentials);
- while (iterator->iterate(iterator, (void**)&ca_info))
- {
- if (ca_info->is_ca(ca_info))
- {
- if (first)
- {
- fprintf(out, "\n");
- fprintf(out, "List of X.509 CA Information Records:\n");
- fprintf(out, "\n");
- first = FALSE;
- }
- ca_info->list(ca_info, out, msg->list.utc);
- }
- }
- iterator->destroy(iterator);
- }
- if (msg->list.flags & LIST_CRLS)
- {
- ca_info_t *ca_info;
- bool first = TRUE;
-
- iterator = charon->credentials->create_cainfo_iterator(charon->credentials);
- while (iterator->iterate(iterator, (void **)&ca_info))
- {
- if (ca_info->is_ca(ca_info) && ca_info->has_crl(ca_info))
- {
- if (first)
- {
- fprintf(out, "\n");
- fprintf(out, "List of X.509 CRLs:\n");
- fprintf(out, "\n");
- first = FALSE;
- }
- ca_info->list_crl(ca_info, out, msg->list.utc);
- }
- }
- iterator->destroy(iterator);
- }
- if (msg->list.flags & LIST_OCSP)
- {
- ca_info_t *ca_info;
- bool first = TRUE;
-
- iterator = charon->credentials->create_cainfo_iterator(charon->credentials);
- while (iterator->iterate(iterator, (void **)&ca_info))
- {
- if (ca_info->is_ca(ca_info) && ca_info->has_certinfos(ca_info))
- {
- if (first)
- {
- fprintf(out, "\n");
- fprintf(out, "List of OCSP responses:\n");
- first = FALSE;
- }
- fprintf(out, "\n");
- ca_info->list_certinfos(ca_info, out, msg->list.utc);
- }
- }
- iterator->destroy(iterator);
- }
-}
-
-/**
- * reread various information
- */
-static void stroke_reread(stroke_msg_t *msg, FILE *out)
-{
- if (msg->reread.flags & REREAD_SECRETS)
- {
- charon->credentials->load_secrets(charon->credentials, TRUE);
- }
- if (msg->reread.flags & REREAD_CACERTS)
- {
- charon->credentials->load_ca_certificates(charon->credentials);
- }
- if (msg->reread.flags & REREAD_OCSPCERTS)
- {
- charon->credentials->load_ocsp_certificates(charon->credentials);
- }
- if (msg->reread.flags & REREAD_AACERTS)
- {
- charon->credentials->load_aa_certificates(charon->credentials);
- }
- if (msg->reread.flags & REREAD_ACERTS)
- {
- charon->credentials->load_attr_certificates(charon->credentials);
- }
- if (msg->reread.flags & REREAD_CRLS)
- {
- charon->credentials->load_crls(charon->credentials);
- }
-}
-
-/**
- * purge various information
- */
-static void stroke_purge(stroke_msg_t *msg, FILE *out)
-{
- if (msg->purge.flags & PURGE_OCSP)
- {
- iterator_t *iterator = charon->credentials->create_cainfo_iterator(charon->credentials);
- ca_info_t *ca_info;
-
- while (iterator->iterate(iterator, (void**)&ca_info))
- {
- if (ca_info->is_ca(ca_info))
- {
- ca_info->purge_ocsp(ca_info);
- }
- }
- iterator->destroy(iterator);
- }
-}
-
-signal_t get_signal_from_logtype(char *type)
-{
- if (strcasecmp(type, "any") == 0) return SIG_ANY;
- else if (strcasecmp(type, "mgr") == 0) return DBG_MGR;
- else if (strcasecmp(type, "ike") == 0) return DBG_IKE;
- else if (strcasecmp(type, "chd") == 0) return DBG_CHD;
- else if (strcasecmp(type, "job") == 0) return DBG_JOB;
- else if (strcasecmp(type, "cfg") == 0) return DBG_CFG;
- else if (strcasecmp(type, "knl") == 0) return DBG_KNL;
- else if (strcasecmp(type, "net") == 0) return DBG_NET;
- else if (strcasecmp(type, "enc") == 0) return DBG_ENC;
- else if (strcasecmp(type, "lib") == 0) return DBG_LIB;
- else return -1;
-}
-
-/**
- * set the verbosity debug output
- */
-static void stroke_loglevel(stroke_msg_t *msg, FILE *out)
-{
- signal_t signal;
-
- pop_string(msg, &(msg->loglevel.type));
- DBG1(DBG_CFG, "received stroke: loglevel %d for %s",
- msg->loglevel.level, msg->loglevel.type);
-
- signal = get_signal_from_logtype(msg->loglevel.type);
- if (signal < 0)
- {
- fprintf(out, "invalid type (%s)!\n", msg->loglevel.type);
- return;
- }
-
- charon->outlog->set_level(charon->outlog, signal, msg->loglevel.level);
- charon->syslog->set_level(charon->syslog, signal, msg->loglevel.level);
-}
-
-/**
- * process a stroke request from the socket pointed by "fd"
- */
-static job_requeue_t stroke_process(int *fdp)
-{
- stroke_msg_t *msg;
- u_int16_t msg_length;
- ssize_t bytes_read;
- FILE *out;
- int strokefd = *fdp;
-
- /* peek the length */
- bytes_read = recv(strokefd, &msg_length, sizeof(msg_length), MSG_PEEK);
- if (bytes_read != sizeof(msg_length))
- {
- DBG1(DBG_CFG, "reading length of stroke message failed: %s",
- strerror(errno));
- close(strokefd);
- return JOB_REQUEUE_NONE;
- }
-
- /* read message */
- msg = malloc(msg_length);
- bytes_read = recv(strokefd, msg, msg_length, 0);
- if (bytes_read != msg_length)
- {
- DBG1(DBG_CFG, "reading stroke message failed: %s", strerror(errno));
- close(strokefd);
- return JOB_REQUEUE_NONE;
- }
-
- out = fdopen(strokefd, "w");
- if (out == NULL)
- {
- DBG1(DBG_CFG, "opening stroke output channel failed: %s", strerror(errno));
- close(strokefd);
- free(msg);
- return JOB_REQUEUE_NONE;
- }
-
- DBG3(DBG_CFG, "stroke message %b", (void*)msg, msg_length);
-
- /* the stroke_* functions are blocking, as they listen on the bus. Add
- * cancellation handlers. */
- pthread_cleanup_push((void*)fclose, out);
- pthread_cleanup_push(free, msg);
-
- switch (msg->type)
- {
- case STR_INITIATE:
- stroke_initiate(msg, out);
- break;
- case STR_ROUTE:
- stroke_route(msg, out);
- break;
- case STR_UNROUTE:
- stroke_unroute(msg, out);
- break;
- case STR_TERMINATE:
- stroke_terminate(msg, out);
- break;
- case STR_STATUS:
- stroke_status(msg, out, FALSE);
- break;
- case STR_STATUS_ALL:
- stroke_status(msg, out, TRUE);
- break;
- case STR_ADD_CONN:
- stroke_add_conn(msg, out);
- break;
- case STR_DEL_CONN:
- stroke_del_conn(msg, out);
- break;
- case STR_ADD_CA:
- stroke_add_ca(msg, out);
- break;
- case STR_DEL_CA:
- stroke_del_ca(msg, out);
- break;
- case STR_LOGLEVEL:
- stroke_loglevel(msg, out);
- break;
- case STR_LIST:
- stroke_list(msg, out);
- break;
- case STR_REREAD:
- stroke_reread(msg, out);
- break;
- case STR_PURGE:
- stroke_purge(msg, out);
- break;
- default:
- DBG1(DBG_CFG, "received unknown stroke");
- }
- /* remove and execute cancellation handlers */
- pthread_cleanup_pop(1);
- pthread_cleanup_pop(1);
-
- return JOB_REQUEUE_NONE;
-}
-
-/**
- * Implementation of private_stroke_interface_t.stroke_receive.
- */
-static job_requeue_t stroke_receive(private_stroke_interface_t *this)
-{
- struct sockaddr_un strokeaddr;
- int strokeaddrlen = sizeof(strokeaddr);
- int strokefd, *fdp;
- int oldstate;
- callback_job_t *job;
-
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
- strokefd = accept(this->socket, (struct sockaddr *)&strokeaddr, &strokeaddrlen);
- pthread_setcancelstate(oldstate, NULL);
-
- if (strokefd < 0)
- {
- DBG1(DBG_CFG, "accepting stroke connection failed: %s", strerror(errno));
- return JOB_REQUEUE_FAIR;
- }
-
- fdp = malloc_thing(int);
- *fdp = strokefd;
- job = callback_job_create((callback_job_cb_t)stroke_process, fdp, free, this->job);
- charon->processor->queue_job(charon->processor, (job_t*)job);
-
- return JOB_REQUEUE_FAIR;
-}
-
-/**
- * Implementation of interface_t.destroy.
- */
-static void destroy(private_stroke_interface_t *this)
-{
- this->job->cancel(this->job);
- free(this);
-}
-
-/*
- * Described in header-file
- */
-interface_t *interface_create()
-{
- struct sockaddr_un socket_addr = { AF_UNIX, STROKE_SOCKET};
- private_stroke_interface_t *this = malloc_thing(private_stroke_interface_t);
- mode_t old;
-
- /* public functions */
- this->public.interface.destroy = (void (*)(interface_t*))destroy;
-
- /* set up unix socket */
- this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
- if (this->socket == -1)
- {
- DBG1(DBG_CFG, "could not create stroke socket");
- free(this);
- return NULL;
- }
-
- unlink(socket_addr.sun_path);
- old = umask(~(S_IRWXU | S_IRWXG));
- if (bind(this->socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr)) < 0)
- {
- DBG1(DBG_CFG, "could not bind stroke socket: %s", strerror(errno));
- close(this->socket);
- free(this);
- return NULL;
- }
- umask(old);
- if (chown(socket_addr.sun_path, IPSEC_UID, IPSEC_GID) != 0)
- {
- DBG1(DBG_CFG, "changing stroke socket permissions failed: %s",
- strerror(errno));
- }
-
- if (listen(this->socket, 0) < 0)
- {
- DBG1(DBG_CFG, "could not listen on stroke socket: %s", strerror(errno));
- close(this->socket);
- unlink(socket_addr.sun_path);
- free(this);
- return NULL;
- }
-
- this->job = callback_job_create((callback_job_cb_t)stroke_receive,
- this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
-
- return &this->public.interface;
-}
-
diff --git a/src/charon/credentials/auth_info.c b/src/charon/credentials/auth_info.c
new file mode 100644
index 000000000..cd748bc97
--- /dev/null
+++ b/src/charon/credentials/auth_info.c
@@ -0,0 +1,571 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: auth_info.c 3838 2008-04-18 11:24:45Z tobias $
+ */
+
+
+#include "auth_info.h"
+
+#include <daemon.h>
+#include <utils/linked_list.h>
+#include <utils/identification.h>
+#include <credentials/certificates/certificate.h>
+
+ENUM(auth_item_names, AUTHN_CA_CERT, AUTHZ_AC_GROUP,
+ "AUTHN_CA_CERT",
+ "AUTHN_CA_CERT_KEYID",
+ "AUTHN_CA_CERT_NAME",
+ "AUTHN_IM_CERT",
+ "AUTHN_SUBJECT_CERT",
+ "AUTHN_IM_HASH_URL",
+ "AUTHN_SUBJECT_HASH_URL",
+ "AUTHZ_PUBKEY",
+ "AUTHZ_PSK",
+ "AUTHZ_EAP",
+ "AUTHZ_CA_CERT",
+ "AUTHZ_CA_CERT_NAME",
+ "AUTHZ_IM_CERT",
+ "AUTHZ_SUBJECT_CERT",
+ "AUTHZ_CRL_VALIDATION",
+ "AUTHZ_OCSP_VALIDATION",
+ "AUTHZ_AC_GROUP",
+);
+
+typedef struct private_auth_info_t private_auth_info_t;
+
+/**
+ * private data of item_set
+ */
+struct private_auth_info_t {
+
+ /**
+ * public functions
+ */
+ auth_info_t public;
+
+ /**
+ * list of item_t's
+ */
+ linked_list_t *items;
+};
+
+typedef struct item_t item_t;
+
+struct item_t {
+ /** type of this item */
+ auth_item_t type;
+ /** associated privlege value, if any */
+ void *value;
+};
+
+/**
+ * enumerator for auth_info_wrapper_t.create_cert_enumerator()
+ */
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** inner enumerator from linked_list_t */
+ enumerator_t *inner;
+ /** the current item */
+ item_t *item;
+} item_enumerator_t;
+
+/**
+ * enumerate function for item_enumerator_t
+ */
+static bool enumerate(item_enumerator_t *this, auth_item_t *type, void **value)
+{
+ if (this->inner->enumerate(this->inner, &this->item))
+ {
+ *type = this->item->type;
+ *value = this->item->value;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * destroy function for item_enumerator_t
+ */
+static void item_enumerator_destroy(item_enumerator_t *this)
+{
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+/**
+ * Implementation of auth_info_t.create_item_enumerator.
+ */
+static enumerator_t* create_item_enumerator(private_auth_info_t *this)
+{
+ item_enumerator_t *enumerator;
+
+ enumerator = malloc_thing(item_enumerator_t);
+ enumerator->item = NULL;
+ enumerator->inner = this->items->create_enumerator(this->items);
+ enumerator->public.enumerate = (void*)enumerate;
+ enumerator->public.destroy = (void*)item_enumerator_destroy;
+ return &enumerator->public;
+}
+
+static void destroy_item_value(item_t *item);
+
+/**
+ * Implementation of auth_info_t.replace_item.
+ */
+static void replace_item(item_enumerator_t *enumerator, auth_item_t type, void *value)
+{
+ destroy_item_value(enumerator->item);
+ enumerator->item->type = type;
+ enumerator->item->value = value;
+}
+
+/**
+ * Implementation of auth_info_t.get_item.
+ */
+static bool get_item(private_auth_info_t *this, auth_item_t type, void** value)
+{
+ enumerator_t *enumerator;
+ void *current_value;
+ auth_item_t current_type;
+ bool found = FALSE;
+
+ enumerator = create_item_enumerator(this);
+ while (enumerator->enumerate(enumerator, &current_type, &current_value))
+ {
+ if (type == current_type)
+ {
+ *value = current_value;
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found;
+}
+
+/**
+ * Implementation of auth_info_t.add_item.
+ */
+static void add_item(private_auth_info_t *this, auth_item_t type, void *value)
+{
+ item_t *item = malloc_thing(item_t);
+
+ item->type = type;
+ switch (type)
+ {
+ case AUTHZ_PUBKEY:
+ {
+ public_key_t *key = (public_key_t*)value;
+
+ item->value = key->get_ref(key);
+ break;
+ }
+ case AUTHZ_PSK:
+ {
+ shared_key_t *key = (shared_key_t*)value;
+
+ item->value = key->get_ref(key);
+ break;
+ }
+ case AUTHN_IM_HASH_URL:
+ case AUTHN_SUBJECT_HASH_URL:
+ {
+ item->value = strdup(value);
+ break;
+ }
+ case AUTHN_CA_CERT:
+ case AUTHN_IM_CERT:
+ case AUTHN_SUBJECT_CERT:
+ case AUTHZ_CA_CERT:
+ case AUTHZ_IM_CERT:
+ case AUTHZ_SUBJECT_CERT:
+ {
+ certificate_t *cert = (certificate_t*)value;
+
+ item->value = cert->get_ref(cert);
+ break;
+ }
+ case AUTHZ_CRL_VALIDATION:
+ case AUTHZ_OCSP_VALIDATION:
+ {
+ cert_validation_t *validation = malloc_thing(cert_validation_t);
+
+ *validation = *(cert_validation_t*)value;
+ item->value = validation;
+ break;
+ }
+ case AUTHZ_EAP:
+ {
+ eap_method_t *method = malloc_thing(eap_method_t);
+
+ *method = *(eap_method_t*)value;
+ item->value = method;
+ break;
+ }
+ case AUTHN_CA_CERT_KEYID:
+ case AUTHN_CA_CERT_NAME:
+ case AUTHZ_CA_CERT_NAME:
+ case AUTHZ_AC_GROUP:
+ {
+ identification_t *id = (identification_t*)value;
+
+ item->value = id->clone(id);
+ break;
+ }
+ }
+ this->items->insert_last(this->items, item);
+}
+
+
+/**
+ * Implementation of auth_info_t.complies.
+ */
+static bool complies(private_auth_info_t *this, auth_info_t *constraints)
+{
+ enumerator_t *enumerator;
+ bool success = TRUE;
+ auth_item_t t1, t2;
+ void *value;
+
+ enumerator = constraints->create_item_enumerator(constraints);
+ while (enumerator->enumerate(enumerator, &t1, &value))
+ {
+ switch (t1)
+ {
+ case AUTHN_CA_CERT_KEYID:
+ case AUTHN_CA_CERT:
+ case AUTHN_CA_CERT_NAME:
+ case AUTHN_IM_CERT:
+ case AUTHN_SUBJECT_CERT:
+ case AUTHN_IM_HASH_URL:
+ case AUTHN_SUBJECT_HASH_URL:
+ { /* skip non-authorization tokens */
+ continue;
+ }
+ case AUTHZ_CRL_VALIDATION:
+ case AUTHZ_OCSP_VALIDATION:
+ {
+ cert_validation_t *valid;
+
+ /* OCSP validation is also sufficient for CRL constraint, but
+ * not vice-versa */
+ if (!get_item(this, t1, (void**)&valid) &&
+ t1 == AUTHZ_CRL_VALIDATION &&
+ !get_item(this, AUTHZ_OCSP_VALIDATION, (void**)&valid))
+ {
+ DBG1(DBG_CFG, "constraint check failed: %N requires at "
+ "least %N, but no check done", auth_item_names, t1,
+ cert_validation_names, *(cert_validation_t*)value);
+ success = FALSE;
+ break;
+ }
+ switch (*(cert_validation_t*)value)
+ {
+ case VALIDATION_SKIPPED:
+ if (*valid == VALIDATION_SKIPPED)
+ {
+ break;
+ } /* FALL */
+ case VALIDATION_GOOD:
+ if (*valid == VALIDATION_GOOD)
+ {
+ break;
+ } /* FALL */
+ default:
+ DBG1(DBG_CFG, "constraint check failed: %N is %N, but "
+ "requires at least %N", auth_item_names, t1,
+ cert_validation_names, *valid,
+ cert_validation_names, *(cert_validation_t*)value);
+ success = FALSE;
+ break;
+ }
+ break;
+ }
+ case AUTHZ_CA_CERT:
+ {
+ enumerator_t *enumerator;
+ certificate_t *c1, *c2;
+
+ c1 = (certificate_t*)value;
+
+ success = FALSE;
+ enumerator = create_item_enumerator(this);
+ while (enumerator->enumerate(enumerator, &t2, &c2))
+ {
+ if ((t2 == AUTHZ_CA_CERT || t2 == AUTHZ_IM_CERT) &&
+ c1->equals(c1, c2))
+ {
+ success = TRUE;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!success)
+ {
+ DBG1(DBG_CFG, "constraint check failed: peer not "
+ "authenticated by CA '%D'.", c1->get_subject(c1));
+ }
+ break;
+ }
+ case AUTHZ_CA_CERT_NAME:
+ {
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ identification_t *id;
+
+ id = (identification_t*)value;
+ success = FALSE;
+ enumerator = create_item_enumerator(this);
+ while (enumerator->enumerate(enumerator, &t2, &cert))
+ {
+ if ((t2 == AUTHZ_CA_CERT || t2 == AUTHZ_IM_CERT) &&
+ cert->has_subject(cert, id))
+ {
+ success = TRUE;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!success)
+ {
+ DBG1(DBG_CFG, "constraint check failed: peer not "
+ "authenticated by CA '%D'.", id);
+ }
+ break;
+ }
+ case AUTHZ_PUBKEY:
+ case AUTHZ_PSK:
+ case AUTHZ_IM_CERT:
+ case AUTHZ_SUBJECT_CERT:
+ case AUTHZ_EAP:
+ case AUTHZ_AC_GROUP:
+ {
+ DBG1(DBG_CFG, "constraint check %N not implemented!",
+ auth_item_names, t1);
+ success = FALSE;
+ break;
+ }
+ }
+ if (!success)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return success;
+}
+
+/**
+ * Implementation of auth_info_t.merge.
+ */
+static void merge(private_auth_info_t *this, private_auth_info_t *other)
+{
+ item_t *item;
+
+ while (other->items->remove_first(other->items, (void**)&item) == SUCCESS)
+ {
+ this->items->insert_last(this->items, item);
+ }
+}
+
+/**
+ * Implementation of auth_info_t.equals.
+ */
+static bool equals(private_auth_info_t *this, private_auth_info_t *other)
+{
+ enumerator_t *e1, *e2;
+ item_t *i1, *i2;
+ bool equal = TRUE, found;
+
+ e1 = this->items->create_enumerator(this->items);
+ while (e1->enumerate(e1, &i1))
+ {
+ found = FALSE;
+ e2 = other->items->create_enumerator(other->items);
+ while (e2->enumerate(e2, &i2))
+ {
+ if (i1->type == i2->type)
+ {
+ switch (i1->type)
+ {
+ case AUTHZ_CRL_VALIDATION:
+ case AUTHZ_OCSP_VALIDATION:
+ {
+ cert_validation_t c1, c2;
+
+ c1 = *(cert_validation_t*)i1->value;
+ c2 = *(cert_validation_t*)i2->value;
+
+ if (c1 == c2)
+ {
+ found = TRUE;
+ break;
+ }
+ continue;
+ }
+ case AUTHN_IM_HASH_URL:
+ case AUTHN_SUBJECT_HASH_URL:
+ {
+ if (streq(i1->value, i2->value))
+ {
+ found = TRUE;
+ break;
+ }
+ continue;
+ }
+ case AUTHN_CA_CERT:
+ case AUTHN_IM_CERT:
+ case AUTHN_SUBJECT_CERT:
+ case AUTHZ_CA_CERT:
+ case AUTHZ_IM_CERT:
+ case AUTHZ_SUBJECT_CERT:
+ {
+ certificate_t *c1, *c2;
+
+ c1 = (certificate_t*)i1->value;
+ c2 = (certificate_t*)i2->value;
+
+ if (c1->equals(c1, c2))
+ {
+ found = TRUE;
+ break;
+ }
+ continue;
+ }
+ case AUTHN_CA_CERT_KEYID:
+ case AUTHN_CA_CERT_NAME:
+ case AUTHZ_CA_CERT_NAME:
+ {
+ identification_t *c1, *c2;
+
+ c1 = (identification_t*)i1->value;
+ c2 = (identification_t*)i2->value;
+
+ if (c1->equals(c1, c2))
+ {
+ found = TRUE;
+ break;
+ }
+ continue;
+ }
+ case AUTHZ_PUBKEY:
+ case AUTHZ_PSK:
+ case AUTHZ_EAP:
+ case AUTHZ_AC_GROUP:
+ /* TODO: implement value comparison */
+ break;
+ }
+ break;
+ }
+ }
+ e2->destroy(e2);
+ if (!found)
+ {
+ equal = FALSE;
+ break;
+ }
+ }
+ e1->destroy(e1);
+ return equal;
+}
+
+/**
+ * Destroy the value associated with an item
+ */
+static void destroy_item_value(item_t *item)
+{
+ switch (item->type)
+ {
+ case AUTHZ_PUBKEY:
+ {
+ public_key_t *key = (public_key_t*)item->value;
+ key->destroy(key);
+ break;
+ }
+ case AUTHZ_PSK:
+ {
+ shared_key_t *key = (shared_key_t*)item->value;
+ key->destroy(key);
+ break;
+ }
+ case AUTHN_CA_CERT:
+ case AUTHN_IM_CERT:
+ case AUTHN_SUBJECT_CERT:
+ case AUTHZ_CA_CERT:
+ case AUTHZ_IM_CERT:
+ case AUTHZ_SUBJECT_CERT:
+ {
+ certificate_t *cert = (certificate_t*)item->value;
+ cert->destroy(cert);
+ break;
+ }
+ case AUTHN_IM_HASH_URL:
+ case AUTHN_SUBJECT_HASH_URL:
+ case AUTHZ_CRL_VALIDATION:
+ case AUTHZ_OCSP_VALIDATION:
+ case AUTHZ_EAP:
+ {
+ free(item->value);
+ break;
+ }
+ case AUTHN_CA_CERT_KEYID:
+ case AUTHN_CA_CERT_NAME:
+ case AUTHZ_CA_CERT_NAME:
+ case AUTHZ_AC_GROUP:
+ {
+ identification_t *id = (identification_t*)item->value;
+ id->destroy(id);
+ break;
+ }
+ }
+}
+
+/**
+ * Implementation of auth_info_t.destroy
+ */
+static void destroy(private_auth_info_t *this)
+{
+ item_t *item;
+
+ while (this->items->remove_last(this->items, (void**)&item) == SUCCESS)
+ {
+ destroy_item_value(item);
+ free(item);
+ }
+ this->items->destroy(this->items);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+auth_info_t *auth_info_create()
+{
+ private_auth_info_t *this = malloc_thing(private_auth_info_t);
+
+ this->public.add_item = (void(*)(auth_info_t*, auth_item_t type, void *value))add_item;
+ this->public.get_item = (bool(*)(auth_info_t*, auth_item_t type, void **value))get_item;
+ this->public.replace_item = (void(*)(enumerator_t*,auth_item_t,void*))replace_item;
+ this->public.create_item_enumerator = (enumerator_t*(*)(auth_info_t*))create_item_enumerator;
+ this->public.complies = (bool(*)(auth_info_t*, auth_info_t *))complies;
+ this->public.merge = (void(*)(auth_info_t*, auth_info_t *other))merge;
+ this->public.equals = (bool(*)(auth_info_t*, auth_info_t *other))equals;
+ this->public.destroy = (void(*)(auth_info_t*))destroy;
+
+ this->items = linked_list_create();
+
+ return &this->public;
+}
+
diff --git a/src/charon/credentials/auth_info.h b/src/charon/credentials/auth_info.h
new file mode 100644
index 000000000..5fe2919f8
--- /dev/null
+++ b/src/charon/credentials/auth_info.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup auth_info auth_info
+ * @{ @ingroup ccredentials
+ */
+
+#ifndef AUTH_INFO_H_
+#define AUTH_INFO_H_
+
+#include <utils/enumerator.h>
+
+typedef struct auth_info_t auth_info_t;
+typedef enum auth_item_t auth_item_t;
+
+/**
+ * Authentication/Authorization process helper item.
+ *
+ * For the authentication process, further information may be needed. These
+ * items are defined as auth_item_t and have a AUTHN prefix.
+ * The authentication process returns important data for the authorization
+ * process, these items are defined with a AUTHZ prefix.
+ * Authentication uses AUTHN items and creates AUTHZ items during authentication,
+ * authorization reads AUTHZ values to give out privileges.
+ *
+ * +---+ +---------------------+
+ * | A | | A |
+ * | u | | u +-----------+ |
+ * | t | | t | Required | |
+ * | h | | h | auth_info | |
+ * | e | | o +-----------+ |
+ * | n | | r | |
+ * +-----------+ | t | | i | |
+ * | Provided | | i | | z V |
+ * | auth_info |--| c |-------------| a ----> match? ----|------->
+ * +-----------+ | a | | t |
+ * | t | | i |
+ * | i | | o |
+ * | o | | n |
+ * | n | | |
+ * +---+ +---------------------+
+ */
+enum auth_item_t {
+
+ /*
+ * items provided to authentication process
+ */
+
+ /** CA certificate to use for authentication, value is certificate_t* */
+ AUTHN_CA_CERT,
+ /** Keyid of a CA certificate to use, value is identification_t* */
+ AUTHN_CA_CERT_KEYID,
+ /** subject DN of a CA certificate to use, value is identification_t* */
+ AUTHN_CA_CERT_NAME,
+ /** intermediate certificate, value is certificate_t* */
+ AUTHN_IM_CERT,
+ /** certificate for trustchain verification, value is certificate_t* */
+ AUTHN_SUBJECT_CERT,
+ /** intermediate certificate supplied as hash and url */
+ AUTHN_IM_HASH_URL,
+ /** end-entity certificate supplied as hash and url */
+ AUTHN_SUBJECT_HASH_URL,
+
+ /*
+ * item provided to authorization process
+ */
+
+ /** subject has been authenticated by public key, value is public_key_t* */
+ AUTHZ_PUBKEY,
+ /** subject has ben authenticated using preshared secrets, value is shared_key_t* */
+ AUTHZ_PSK,
+ /** subject has been authenticated using EAP, value is eap_method_t */
+ AUTHZ_EAP,
+ /** certificate authority, value is certificate_t* */
+ AUTHZ_CA_CERT,
+ /** subject DN of a certificate authority, value is identification_t* */
+ AUTHZ_CA_CERT_NAME,
+ /** intermediate certificate in trustchain, value is certificate_t* */
+ AUTHZ_IM_CERT,
+ /** subject certificate, value is certificate_t* */
+ AUTHZ_SUBJECT_CERT,
+ /** result of a CRL validation, value is cert_validation_t */
+ AUTHZ_CRL_VALIDATION,
+ /** result of a OCSP validation, value is cert_validation_t */
+ AUTHZ_OCSP_VALIDATION,
+ /** subject is in attribute certificate group, value is identification_t* */
+ AUTHZ_AC_GROUP,
+};
+
+
+/**
+ * enum name for auth_item_t.
+ */
+extern enum_name_t *auth_item_names;
+
+/**
+ * The auth_info class contains auth_item_t's used for AA.
+ *
+ * A auth_info allows the separation of authentication and authorization.
+ */
+struct auth_info_t {
+
+ /**
+ * Add an item to the set.
+ *
+ * @param type auth_info type
+ * @param value associated value to auth_info type, if any
+ */
+ void (*add_item)(auth_info_t *this, auth_item_t type, void *value);
+
+ /**
+ * Get an item.
+ *
+ * @param type auth_info type to get
+ * @param value pointer to a pointer receiving item
+ * @return bool if item has been found
+ */
+ bool (*get_item)(auth_info_t *this, auth_item_t type, void **value);
+
+ /**
+ * Replace an item.
+ *
+ * @param type new auth_info type
+ * @param value pointer to the new value
+ */
+ void (*replace_item)(enumerator_t *this, auth_item_t type, void *value);
+
+ /**
+ * Create an enumerator over all items.
+ *
+ * @return enumerator over (auth_item_t type, void *value)
+ */
+ enumerator_t* (*create_item_enumerator)(auth_info_t *this);
+
+ /**
+ * Check if this fulfills a set of required constraints.
+ *
+ * @param constraints required authorization infos
+ * @return TRUE if this complies with constraints
+ */
+ bool (*complies)(auth_info_t *this, auth_info_t *constraints);
+
+ /**
+ * Merge items from other into this.
+ *
+ * Items do not get cloned, but moved from other to this.
+ *
+ * @param other items to read for merge
+ */
+ void (*merge)(auth_info_t *this, auth_info_t *other);
+
+ /**
+ * Check two auth_infos for equality.
+ *
+ * @param other other item to compaire against this
+ * @return TRUE if auth infos identical
+ */
+ bool (*equals)(auth_info_t *this, auth_info_t *other);
+
+ /**
+ * Destroy a auth_info instance with all associated values.
+ */
+ void (*destroy)(auth_info_t *this);
+};
+
+/**
+ * Create a auth_info instance.
+ */
+auth_info_t *auth_info_create();
+
+#endif /* AUTH_INFO_H_ @}*/
diff --git a/src/charon/credentials/credential_manager.c b/src/charon/credentials/credential_manager.c
new file mode 100644
index 000000000..251559141
--- /dev/null
+++ b/src/charon/credentials/credential_manager.c
@@ -0,0 +1,1540 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: credential_manager.c 3953 2008-05-14 06:49:31Z martin $
+ */
+
+/* some clibs need it for rwlocks */
+#define _GNU_SOURCE
+#include <pthread.h>
+
+#include "credential_manager.h"
+
+#include <daemon.h>
+#include <utils/linked_list.h>
+#include <credentials/sets/cert_cache.h>
+#include <credentials/sets/auth_info_wrapper.h>
+#include <credentials/sets/ocsp_response_wrapper.h>
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+#include <credentials/certificates/ocsp_request.h>
+#include <credentials/certificates/ocsp_response.h>
+
+#define MAX_CA_LEVELS 6
+
+typedef struct private_credential_manager_t private_credential_manager_t;
+
+/**
+ * private data of credential_manager
+ */
+struct private_credential_manager_t {
+
+ /**
+ * public functions
+ */
+ credential_manager_t public;
+
+ /**
+ * list of credential sets
+ */
+ linked_list_t *sets;
+
+ /**
+ * thread local set of credentials, linked_list_t with credential_set_t's
+ */
+ pthread_key_t local_sets;
+
+ /**
+ * trust relationship and certificate cache
+ */
+ cert_cache_t *cache;
+
+ /**
+ * read-write lock to sets list
+ */
+ pthread_rwlock_t lock;
+};
+
+/** data to pass to create_private_enumerator */
+typedef struct {
+ private_credential_manager_t *this;
+ key_type_t type;
+ identification_t* keyid;
+} private_data_t;
+
+/** data to pass to create_cert_enumerator */
+typedef struct {
+ private_credential_manager_t *this;
+ certificate_type_t cert;
+ key_type_t key;
+ identification_t *id;
+ bool trusted;
+} cert_data_t;
+
+/** data to pass to create_cdp_enumerator */
+typedef struct {
+ private_credential_manager_t *this;
+ certificate_type_t type;
+ identification_t *id;
+} cdp_data_t;
+
+/** data to pass to create_shared_enumerator */
+typedef struct {
+ private_credential_manager_t *this;
+ shared_key_type_t type;
+ identification_t *me;
+ identification_t *other;
+} shared_data_t;
+
+/** enumerator over local and global sets */
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** enumerator over global sets */
+ enumerator_t *global;
+ /** enumerator over local sets */
+ enumerator_t *local;
+} sets_enumerator_t;
+
+/**
+ * destroy a sets_enumerator_t
+ */
+static void sets_enumerator_destroy(sets_enumerator_t *this)
+{
+ DESTROY_IF(this->global);
+ DESTROY_IF(this->local);
+ free(this);
+}
+
+/**
+ * sets_enumerator_t.enumerate
+ */
+static bool sets_enumerator_enumerate(sets_enumerator_t *this,
+ credential_set_t **set)
+{
+ if (this->global)
+ {
+ if (this->global->enumerate(this->global, set))
+ {
+ return TRUE;
+ }
+ /* end of global sets, look for local */
+ this->global->destroy(this->global);
+ this->global = NULL;
+ }
+ if (this->local)
+ {
+ return this->local->enumerate(this->local, set);
+ }
+ return FALSE;
+}
+
+/**
+ * create an enumerator over both, global and local sets
+ */
+static enumerator_t *create_sets_enumerator(private_credential_manager_t *this)
+{
+ linked_list_t *local;
+ sets_enumerator_t *enumerator = malloc_thing(sets_enumerator_t);
+
+ enumerator->public.enumerate = (void*)sets_enumerator_enumerate;
+ enumerator->public.destroy = (void*)sets_enumerator_destroy;
+ enumerator->global = this->sets->create_enumerator(this->sets);
+ enumerator->local = NULL;
+ local = pthread_getspecific(this->local_sets);
+ if (local)
+ {
+ enumerator->local = local->create_enumerator(local);
+ }
+ return &enumerator->public;
+}
+
+/**
+ * cleanup function for cert data
+ */
+static void destroy_cert_data(cert_data_t *data)
+{
+ pthread_rwlock_unlock(&data->this->lock);
+ free(data);
+}
+
+/**
+ * enumerator constructor for certificates
+ */
+static enumerator_t *create_cert(credential_set_t *set, cert_data_t *data)
+{
+ return set->create_cert_enumerator(set, data->cert, data->key,
+ data->id, data->trusted);
+}
+
+/**
+ * Implementation of credential_manager_t.create_cert_enumerator.
+ */
+static enumerator_t *create_cert_enumerator(private_credential_manager_t *this,
+ certificate_type_t certificate, key_type_t key,
+ identification_t *id, bool trusted)
+{
+ cert_data_t *data = malloc_thing(cert_data_t);
+ data->this = this;
+ data->cert = certificate;
+ data->key = key;
+ data->id = id;
+ data->trusted = trusted;
+
+ pthread_rwlock_rdlock(&this->lock);
+ return enumerator_create_nested(create_sets_enumerator(this),
+ (void*)create_cert, data,
+ (void*)destroy_cert_data);
+}
+
+/**
+ * Implementation of credential_manager_t.get_cert.
+ */
+static certificate_t *get_cert(private_credential_manager_t *this,
+ certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
+{
+ certificate_t *current, *found = NULL;
+ enumerator_t *enumerator;
+
+ enumerator = create_cert_enumerator(this, cert, key, id, trusted);
+ if (enumerator->enumerate(enumerator, &current))
+ {
+ /* TODO: best match? order by keyid, subject, sualtname */
+ found = current->get_ref(current);
+ }
+ enumerator->destroy(enumerator);
+ return found;
+}
+
+
+/**
+ * cleanup function for cdp data
+ */
+static void destroy_cdp_data(cdp_data_t *data)
+{
+ pthread_rwlock_unlock(&data->this->lock);
+ free(data);
+}
+
+/**
+ * enumerator constructor for CDPs
+ */
+static enumerator_t *create_cdp(credential_set_t *set, cdp_data_t *data)
+{
+ return set->create_cdp_enumerator(set, data->type, data->id);
+}
+/**
+ * Implementation of credential_manager_t.create_cdp_enumerator.
+ */
+static enumerator_t * create_cdp_enumerator(private_credential_manager_t *this,
+ certificate_type_t type, identification_t *id)
+{
+ cdp_data_t *data = malloc_thing(cdp_data_t);
+ data->this = this;
+ data->type = type;
+ data->id = id;
+
+ pthread_rwlock_rdlock(&this->lock);
+ return enumerator_create_nested(create_sets_enumerator(this),
+ (void*)create_cdp, data,
+ (void*)destroy_cdp_data);
+}
+
+/**
+ * cleanup function for private data
+ */
+static void destroy_private_data(private_data_t *data)
+{
+ pthread_rwlock_unlock(&data->this->lock);
+ free(data);
+}
+
+/**
+ * enumerator constructor for private keys
+ */
+static enumerator_t *create_private(credential_set_t *set, private_data_t *data)
+{
+ return set->create_private_enumerator(set, data->type, data->keyid);
+}
+
+/**
+ * Implementation of credential_manager_t.get_private_by_keyid.
+ */
+static enumerator_t* create_private_enumerator(
+ private_credential_manager_t *this,
+ key_type_t key, identification_t *keyid)
+{
+ private_data_t *data;
+
+ data = malloc_thing(private_data_t);
+ data->this = this;
+ data->type = key;
+ data->keyid = keyid;
+ pthread_rwlock_rdlock(&this->lock);
+ return enumerator_create_nested(create_sets_enumerator(this),
+ (void*)create_private, data,
+ (void*)destroy_private_data);
+}
+
+/**
+ * Implementation of credential_manager_t.get_private_by_keyid.
+ */
+static private_key_t *get_private_by_keyid(private_credential_manager_t *this,
+ key_type_t key, identification_t *keyid)
+{
+ private_key_t *found = NULL;
+ enumerator_t *enumerator;
+
+ enumerator = create_private_enumerator(this, key, keyid);
+ if (enumerator->enumerate(enumerator, &found))
+ {
+ found->get_ref(found);
+ }
+ enumerator->destroy(enumerator);
+ return found;
+}
+
+/**
+ * cleanup function for shared data
+ */
+static void destroy_shared_data(shared_data_t *data)
+{
+ pthread_rwlock_unlock(&data->this->lock);
+ free(data);
+}
+
+/**
+ * enumerator constructor for shared keys
+ */
+static enumerator_t *create_shared(credential_set_t *set, shared_data_t *data)
+{
+ return set->create_shared_enumerator(set, data->type, data->me, data->other);
+}
+
+/**
+ * Implementation of credential_manager_t.create_shared_enumerator.
+ */
+static enumerator_t *create_shared_enumerator(private_credential_manager_t *this,
+ shared_key_type_t type,
+ identification_t *me, identification_t *other)
+{
+ shared_data_t *data = malloc_thing(shared_data_t);
+ data->this = this;
+ data->type = type;
+ data->me = me;
+ data->other = other;
+
+ pthread_rwlock_rdlock(&this->lock);
+ return enumerator_create_nested(create_sets_enumerator(this),
+ (void*)create_shared, data,
+ (void*)destroy_shared_data);
+}
+
+/**
+ * Implementation of credential_manager_t.get_shared.
+ */
+static shared_key_t *get_shared(private_credential_manager_t *this,
+ shared_key_type_t type, identification_t *me,
+ identification_t *other)
+{
+ shared_key_t *current, *found = NULL;
+ id_match_t *best_me = ID_MATCH_NONE, *best_other = ID_MATCH_NONE;
+ id_match_t *match_me, *match_other;
+ enumerator_t *enumerator;
+
+ enumerator = create_shared_enumerator(this, type, me, other);
+ while (enumerator->enumerate(enumerator, &current, &match_me, &match_other))
+ {
+ if (match_other > best_other ||
+ (match_other == best_other && match_me > best_me))
+ {
+ DESTROY_IF(found);
+ found = current->get_ref(current);
+ best_me = match_me;
+ best_other = match_other;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found;
+}
+
+/**
+ * add a credential set to the thread local list
+ */
+static void add_local_set(private_credential_manager_t *this,
+ credential_set_t *set)
+{
+ linked_list_t *sets;
+
+ sets = pthread_getspecific(this->local_sets);
+ if (!sets)
+ { /* first invocation */
+ sets = linked_list_create();
+ pthread_setspecific(this->local_sets, sets);
+ }
+ sets->insert_last(sets, set);
+}
+
+/**
+ * remove a credential set from the thread local list
+ */
+static void remove_local_set(private_credential_manager_t *this,
+ credential_set_t *set)
+{
+ linked_list_t *sets;
+
+ sets = pthread_getspecific(this->local_sets);
+ sets->remove(sets, set, NULL);
+}
+
+/**
+ * Implementation of credential_manager_t.cache_cert.
+ */
+static void cache_cert(private_credential_manager_t *this, certificate_t *cert)
+{
+ credential_set_t *set;
+ enumerator_t *enumerator;
+
+ pthread_rwlock_rdlock(&this->lock);
+ enumerator = this->sets->create_enumerator(this->sets);
+ while (enumerator->enumerate(enumerator, &set))
+ {
+ set->cache_cert(set, cert);
+ }
+ enumerator->destroy(enumerator);
+ pthread_rwlock_unlock(&this->lock);
+}
+
+/**
+ * forward declaration
+ */
+static enumerator_t *create_trusted_enumerator(private_credential_manager_t *this,
+ key_type_t type, identification_t *id, bool crl, bool ocsp);
+
+/**
+ * Do an OCSP request
+ */
+static certificate_t *fetch_ocsp(private_credential_manager_t *this, char *url,
+ certificate_t *subject, certificate_t *issuer)
+{
+ certificate_t *request, *response;
+ chunk_t send, receive;
+
+ /* TODO: requestor name, signature */
+ request = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
+ BUILD_CA_CERT, issuer->get_ref(issuer),
+ BUILD_CERT, subject->get_ref(subject), BUILD_END);
+ if (!request)
+ {
+ DBG1(DBG_CFG, "generating ocsp request failed");
+ return NULL;
+ }
+
+ send = request->get_encoding(request);
+ request->destroy(request);
+
+ DBG1(DBG_CFG, " requesting ocsp status from '%s' ...", url);
+ if (lib->fetcher->fetch(lib->fetcher, url, &receive,
+ FETCH_REQUEST_DATA, send,
+ FETCH_REQUEST_TYPE, "application/ocsp-request",
+ FETCH_END) != SUCCESS)
+ {
+ DBG1(DBG_CFG, "ocsp request to %s failed", url);
+ chunk_free(&send);
+ return NULL;
+ }
+ chunk_free(&send);
+
+ response = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
+ BUILD_BLOB_ASN1_DER, receive, BUILD_END);
+ if (!response)
+ {
+ DBG1(DBG_CFG, "parsing ocsp response failed");
+ return NULL;
+ }
+ return response;
+}
+
+/**
+ * check the signature of an OCSP response
+ */
+static bool verify_ocsp(private_credential_manager_t *this,
+ ocsp_response_t *response)
+{
+ certificate_t *issuer, *subject;
+ identification_t *responder;
+ ocsp_response_wrapper_t *wrapper;
+ enumerator_t *enumerator;
+ bool verified = FALSE;
+
+ wrapper = ocsp_response_wrapper_create((ocsp_response_t*)response);
+ add_local_set(this, &wrapper->set);
+
+ subject = &response->certificate;
+ responder = subject->get_issuer(subject);
+ enumerator = create_trusted_enumerator(this, KEY_ANY, responder, FALSE, FALSE);
+ while (enumerator->enumerate(enumerator, &issuer, NULL))
+ {
+ if (this->cache->issued_by(this->cache, subject, issuer))
+ {
+ DBG1(DBG_CFG, " ocsp response correctly signed by \"%D\"",
+ issuer->get_subject(issuer));
+ verified = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ remove_local_set(this, &wrapper->set);
+ wrapper->destroy(wrapper);
+ return verified;
+}
+
+/**
+ * Get the better of two OCSP responses, and check for usable OCSP info
+ */
+static certificate_t *get_better_ocsp(private_credential_manager_t *this,
+ certificate_t *cand, certificate_t *best,
+ x509_t *subject, x509_t *issuer,
+ cert_validation_t *valid, bool cache)
+{
+ ocsp_response_t *response;
+ time_t revocation, this_update, next_update, valid_until;
+ crl_reason_t reason;
+ bool revoked = FALSE;
+
+ response = (ocsp_response_t*)cand;
+
+ /* check ocsp signature */
+ if (!verify_ocsp(this, response))
+ {
+ DBG1(DBG_CFG, "ocsp response verification failed");
+ cand->destroy(cand);
+ return best;
+ }
+ /* check if response contains our certificate */
+ switch (response->get_status(response, subject, issuer, &revocation, &reason,
+ &this_update, &next_update))
+ {
+ case VALIDATION_REVOKED:
+ /* subject has been revoked by a valid OCSP response */
+ DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
+ &revocation, crl_reason_names, reason);
+ revoked = TRUE;
+ break;
+ case VALIDATION_GOOD:
+ /* results in either good or stale */
+ break;
+ default:
+ case VALIDATION_FAILED:
+ /* candidate unusable, does not contain our cert */
+ DBG1(DBG_CFG, " ocsp response contains no status on our certificate");
+ cand->destroy(cand);
+ return best;
+ }
+
+ /* select the better of the two responses */
+ if (best == NULL || cand->is_newer(cand, best))
+ {
+ DESTROY_IF(best);
+ best = cand;
+ if (best->get_validity(best, NULL, NULL, &valid_until))
+ {
+ DBG1(DBG_CFG, " ocsp response is valid: until %#T",
+ &valid_until, FALSE);
+ *valid = VALIDATION_GOOD;
+ if (cache)
+ { /* cache non-stale only, stale certs get refetched */
+ cache_cert(this, best);
+ }
+ }
+ else
+ {
+ DBG1(DBG_CFG, " ocsp response is stale: since %#T",
+ &valid_until, FALSE);
+ *valid = VALIDATION_STALE;
+ }
+ }
+ else
+ {
+ *valid = VALIDATION_STALE;
+ cand->destroy(cand);
+ }
+ if (revoked)
+ { /* revoked always counts, even if stale */
+ *valid = VALIDATION_REVOKED;
+ }
+ return best;
+}
+
+/**
+ * validate a x509 certificate using OCSP
+ */
+static cert_validation_t check_ocsp(private_credential_manager_t *this,
+ x509_t *subject, x509_t *issuer,
+ auth_info_t *auth)
+{
+ enumerator_t *enumerator;
+ cert_validation_t valid = VALIDATION_SKIPPED;
+ certificate_t *best = NULL, *current;
+ identification_t *keyid = NULL;
+ public_key_t *public;
+ char *uri = NULL;
+
+ /** lookup cache for valid OCSP responses */
+ enumerator = create_cert_enumerator(this, CERT_X509_OCSP_RESPONSE,
+ KEY_ANY, NULL, FALSE);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ current->get_ref(current);
+ best = get_better_ocsp(this, current, best, subject, issuer,
+ &valid, FALSE);
+ if (best && valid != VALIDATION_STALE)
+ {
+ DBG1(DBG_CFG, " using cached ocsp response");
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ /* derive the authorityKeyIdentifier from the issuer's public key */
+ current = &issuer->interface;
+ public = current->get_public_key(current);
+ if (public)
+ {
+ keyid = public->get_id(public, ID_PUBKEY_SHA1);
+ }
+ /** fetch from configured OCSP responder URLs */
+ if (keyid && valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
+ {
+ enumerator = create_cdp_enumerator(this, CERT_X509_OCSP_RESPONSE, keyid);
+ while (enumerator->enumerate(enumerator, &uri))
+ {
+ current = fetch_ocsp(this, uri, &subject->interface,
+ &issuer->interface);
+ if (current)
+ {
+ best = get_better_ocsp(this, current, best, subject, issuer,
+ &valid, TRUE);
+ if (best && valid != VALIDATION_STALE)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ DESTROY_IF(public);
+
+ /* fallback to URL fetching from subject certificate's URIs */
+ if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
+ {
+ enumerator = subject->create_ocsp_uri_enumerator(subject);
+ while (enumerator->enumerate(enumerator, &uri))
+ {
+ current = fetch_ocsp(this, uri, &subject->interface,
+ &issuer->interface);
+ if (current)
+ {
+ best = get_better_ocsp(this, current, best, subject, issuer,
+ &valid, TRUE);
+ if (best && valid != VALIDATION_STALE)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ /* an uri was found, but no result. switch validation state to failed */
+ if (valid == VALIDATION_SKIPPED && uri)
+ {
+ valid = VALIDATION_FAILED;
+ }
+ if (auth)
+ {
+ auth->add_item(auth, AUTHZ_OCSP_VALIDATION, &valid);
+ }
+ DESTROY_IF(best);
+ return valid;
+}
+
+/**
+ * fetch a CRL from an URL
+ */
+static certificate_t* fetch_crl(private_credential_manager_t *this, char *url)
+{
+ certificate_t *crl;
+ chunk_t chunk;
+
+ DBG1(DBG_CFG, " fetching crl from '%s' ...", url);
+ if (lib->fetcher->fetch(lib->fetcher, url, &chunk, FETCH_END) != SUCCESS)
+ {
+ DBG1(DBG_CFG, "crl fetching failed");
+ return NULL;
+ }
+ crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+ BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+ if (!crl)
+ {
+ DBG1(DBG_CFG, "crl fetched successfully but parsing failed");
+ return NULL;
+ }
+ return crl;
+}
+
+/**
+ * check the signature of an CRL
+ */
+static bool verify_crl(private_credential_manager_t *this, certificate_t *crl)
+{
+ certificate_t *issuer;
+ enumerator_t *enumerator;
+ bool verified = FALSE;
+
+ enumerator = create_trusted_enumerator(this, KEY_ANY, crl->get_issuer(crl),
+ FALSE, FALSE);
+ while (enumerator->enumerate(enumerator, &issuer, NULL))
+ {
+ if (this->cache->issued_by(this->cache, crl, issuer))
+ {
+ DBG1(DBG_CFG, " crl correctly signed by \"%D\"",
+ issuer->get_subject(issuer));
+ verified = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return verified;
+}
+
+/**
+ * Get the better of two CRLs, and check for usable CRL info
+ */
+static certificate_t *get_better_crl(private_credential_manager_t *this,
+ certificate_t *cand, certificate_t *best,
+ x509_t *subject, x509_t *issuer,
+ cert_validation_t *valid, bool cache)
+{
+ enumerator_t *enumerator;
+ time_t revocation, valid_until;
+ crl_reason_t reason;
+ chunk_t serial;
+ crl_t *crl;
+
+ /* check CRL signature */
+ if (!verify_crl(this, cand))
+ {
+ DBG1(DBG_CFG, "crl response verification failed");
+ cand->destroy(cand);
+ return best;
+ }
+
+ crl = (crl_t*)cand;
+ enumerator = crl->create_enumerator(crl);
+ while (enumerator->enumerate(enumerator, &serial, &revocation, &reason))
+ {
+ if (chunk_equals(serial, subject->get_serial(subject)))
+ {
+ DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
+ &revocation, crl_reason_names, reason);
+ *valid = VALIDATION_REVOKED;
+ enumerator->destroy(enumerator);
+ DESTROY_IF(best);
+ return cand;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ /* select the better of the two CRLs */
+ if (best == NULL || cand->is_newer(cand, best))
+ {
+ DESTROY_IF(best);
+ best = cand;
+ if (best->get_validity(best, NULL, NULL, &valid_until))
+ {
+ DBG1(DBG_CFG, " crl is valid: until %#T", &valid_until, FALSE);
+ *valid = VALIDATION_GOOD;
+ if (cache)
+ { /* we cache non-stale crls only, as a stale crls are refetched */
+ cache_cert(this, best);
+ }
+ }
+ else
+ {
+ DBG1(DBG_CFG, " crl is stale: since %#T", &valid_until, FALSE);
+ *valid = VALIDATION_STALE;
+ }
+ }
+ else
+ {
+ *valid = VALIDATION_STALE;
+ cand->destroy(cand);
+ }
+ return best;
+}
+
+/**
+ * validate a x509 certificate using CRL
+ */
+static cert_validation_t check_crl(private_credential_manager_t *this,
+ x509_t *subject, x509_t *issuer,
+ auth_info_t *auth)
+{
+ cert_validation_t valid = VALIDATION_SKIPPED;
+ identification_t *keyid = NULL;
+ certificate_t *best = NULL;
+ certificate_t *current;
+ public_key_t *public;
+ enumerator_t *enumerator;
+ char *uri;
+
+ /* derive the authorityKeyIdentifier from the issuer's public key */
+ current = &issuer->interface;
+ public = current->get_public_key(current);
+ if (public)
+ {
+ keyid = public->get_id(public, ID_PUBKEY_SHA1);
+ }
+
+ /* find a cached crl by authorityKeyIdentifier */
+ if (keyid)
+ {
+ enumerator = create_cert_enumerator(this, CERT_X509_CRL, KEY_ANY,
+ keyid, FALSE);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ current->get_ref(current);
+ best = get_better_crl(this, current, best, subject, issuer,
+ &valid, FALSE);
+ if (best && valid != VALIDATION_STALE)
+ {
+ DBG1(DBG_CFG, " using cached crl");
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ /* fallback to fetching crls from credential sets cdps */
+ if (keyid && valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
+ {
+ enumerator = create_cdp_enumerator(this, CERT_X509_CRL, keyid);
+
+ while (enumerator->enumerate(enumerator, &uri))
+ {
+ current = fetch_crl(this, uri);
+ if (current)
+ {
+ best = get_better_crl(this, current, best, subject, issuer,
+ &valid, TRUE);
+ if (best && valid != VALIDATION_STALE)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ DESTROY_IF(public);
+
+ /* fallback to fetching crls from cdps from subject's certificate */
+ if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
+ {
+ enumerator = subject->create_crl_uri_enumerator(subject);
+
+ while (enumerator->enumerate(enumerator, &uri))
+ {
+ current = fetch_crl(this, uri);
+ if (current)
+ {
+ best = get_better_crl(this, current, best, subject, issuer,
+ &valid, TRUE);
+ if (best && valid != VALIDATION_STALE)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ /* an uri was found, but no result. switch validation state to failed */
+ if (valid == VALIDATION_SKIPPED && uri)
+ {
+ valid = VALIDATION_FAILED;
+ }
+ if (auth)
+ {
+ auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
+ }
+ DESTROY_IF(best);
+ return valid;
+}
+
+/**
+ * check a certificate for its lifetime
+ */
+static bool check_certificate(private_credential_manager_t *this,
+ certificate_t *subject, certificate_t *issuer,
+ bool crl, bool ocsp, auth_info_t *auth)
+{
+ time_t not_before, not_after;
+
+ if (!subject->get_validity(subject, NULL, &not_before, &not_after))
+ {
+ DBG1(DBG_CFG, "subject certificate invalid (valid from %T to %T)",
+ &not_before, &not_after);
+ return FALSE;
+ }
+ if (!issuer->get_validity(issuer, NULL, &not_before, &not_after))
+ {
+ DBG1(DBG_CFG, "issuer certificate invalid (valid from %T to %T)",
+ &not_before, &not_after);
+ return FALSE;
+ }
+ if (issuer->get_type(issuer) == CERT_X509 &&
+ subject->get_type(subject) == CERT_X509)
+ {
+ if (ocsp || crl)
+ {
+ DBG1(DBG_CFG, "checking certificate status of \"%D\"",
+ subject->get_subject(subject));
+ }
+ if (ocsp)
+ {
+ switch (check_ocsp(this, (x509_t*)subject, (x509_t*)issuer, auth))
+ {
+ case VALIDATION_GOOD:
+ DBG1(DBG_CFG, "certificate status is good");
+ return TRUE;
+ case VALIDATION_REVOKED:
+ /* has already been logged */
+ return FALSE;
+ case VALIDATION_SKIPPED:
+ DBG2(DBG_CFG, "ocsp check skipped, no ocsp found");
+ break;
+ case VALIDATION_STALE:
+ DBG1(DBG_CFG, "ocsp information stale, fallback to crl");
+ break;
+ case VALIDATION_FAILED:
+ DBG1(DBG_CFG, "ocsp check failed, fallback to crl");
+ break;
+ }
+ }
+ if (crl)
+ {
+ switch (check_crl(this, (x509_t*)subject, (x509_t*)issuer, auth))
+ {
+ case VALIDATION_GOOD:
+ DBG1(DBG_CFG, "certificate status is good");
+ return TRUE;
+ case VALIDATION_REVOKED:
+ /* has already been logged */
+ return FALSE;
+ case VALIDATION_FAILED:
+ case VALIDATION_SKIPPED:
+ DBG1(DBG_CFG, "certificate status is not available");
+ break;
+ case VALIDATION_STALE:
+ DBG1(DBG_CFG, "certificate status is unknown, crl is stale");
+ break;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Get a trusted certificate from a credential set
+ */
+static certificate_t *get_pretrusted_cert(private_credential_manager_t *this,
+ key_type_t type, identification_t *id)
+{
+ certificate_t *subject;
+ public_key_t *public;
+
+ subject = get_cert(this, CERT_ANY, type, id, TRUE);
+ if (!subject)
+ {
+ return NULL;
+ }
+ public = subject->get_public_key(subject);
+ if (!public)
+ {
+ subject->destroy(subject);
+ return NULL;
+ }
+ public->destroy(public);
+ return subject;
+}
+
+/**
+ * Get the issuing certificate of a subject certificate
+ */
+static certificate_t *get_issuer_cert(private_credential_manager_t *this,
+ certificate_t *subject, bool trusted)
+{
+ enumerator_t *enumerator;
+ certificate_t *issuer = NULL, *candidate;
+
+ enumerator = create_cert_enumerator(this, subject->get_type(subject), KEY_ANY,
+ subject->get_issuer(subject), trusted);
+ while (enumerator->enumerate(enumerator, &candidate))
+ {
+ if (this->cache->issued_by(this->cache, subject, candidate))
+ {
+ issuer = candidate->get_ref(candidate);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return issuer;
+}
+
+/**
+ * try to verify the trust chain of subject, return TRUE if trusted
+ */
+static bool verify_trust_chain(private_credential_manager_t *this,
+ certificate_t *subject, auth_info_t *result,
+ bool trusted, bool crl, bool ocsp)
+{
+ certificate_t *current, *issuer;
+ auth_info_t *auth;
+ u_int level = 0;
+
+ auth = auth_info_create();
+ current = subject->get_ref(subject);
+ while (level++ < MAX_CA_LEVELS)
+ {
+ issuer = get_issuer_cert(this, current, TRUE);
+ if (issuer)
+ {
+ /* accept only self-signed CAs as trust anchor */
+ if (this->cache->issued_by(this->cache, issuer, issuer))
+ {
+ auth->add_item(auth, AUTHZ_CA_CERT, issuer);
+ DBG1(DBG_CFG, " using trusted ca certificate \"%D\"",
+ issuer->get_subject(issuer));
+ trusted = TRUE;
+ }
+ else
+ {
+ auth->add_item(auth, AUTHZ_IM_CERT, issuer);
+ DBG1(DBG_CFG, " using trusted intermediate ca certificate "
+ "\"%D\"", issuer->get_subject(issuer));
+ }
+ }
+ else
+ {
+ issuer = get_issuer_cert(this, current, FALSE);
+ if (issuer)
+ {
+ if (current->equals(current, issuer))
+ {
+ DBG1(DBG_CFG, " self-signed certificate \"%D\" is not trusted",
+ current->get_subject(current));
+ issuer->destroy(issuer);
+ break;
+ }
+ auth->add_item(auth, AUTHZ_IM_CERT, issuer);
+ DBG1(DBG_CFG, " using untrusted intermediate certificate "
+ "\"%D\"", issuer->get_subject(issuer));
+ }
+ else
+ {
+ DBG1(DBG_CFG, "no issuer certificate found for \"%D\"",
+ current->get_subject(current));
+ break;
+ }
+ }
+ if (!check_certificate(this, current, issuer, crl, ocsp,
+ current == subject ? auth : NULL))
+ {
+ trusted = FALSE;
+ issuer->destroy(issuer);
+ break;
+ }
+ current->destroy(current);
+ current = issuer;
+ if (trusted)
+ {
+ break;
+ }
+ }
+ current->destroy(current);
+ if (level > MAX_CA_LEVELS)
+ {
+ DBG1(DBG_CFG, "maximum ca path length of %d levels reached", level);
+ }
+ if (trusted)
+ {
+ result->merge(result, auth);
+ }
+ auth->destroy(auth);
+ return trusted;
+}
+
+/**
+ * enumerator for trusted certificates
+ */
+typedef struct {
+ /** implements enumerator_t interface */
+ enumerator_t public;
+ /** enumerator over candidate peer certificates */
+ enumerator_t *candidates;
+ /** reference to the credential_manager */
+ private_credential_manager_t *this;
+ /** type of the requested key */
+ key_type_t type;
+ /** identity the requested key belongs to */
+ identification_t *id;
+ /** TRUE to do CRL checking */
+ bool crl;
+ /** TRUE to do OCSP checking */
+ bool ocsp;
+ /** pretrusted certificate we have served at first invocation */
+ certificate_t *pretrusted;
+ /** currently enumerating auth info */
+ auth_info_t *auth;
+} trusted_enumerator_t;
+
+/**
+ * Implements trusted_enumerator_t.enumerate
+ */
+static bool trusted_enumerate(trusted_enumerator_t *this,
+ certificate_t **cert, auth_info_t **auth)
+{
+ certificate_t *current;
+
+ DESTROY_IF(this->auth);
+ this->auth = auth_info_create();
+
+ if (!this->candidates)
+ {
+ /* first invocation, build enumerator for next one */
+ this->candidates = create_cert_enumerator(this->this, CERT_ANY,
+ this->type, this->id, FALSE);
+ /* check if we have a trusted certificate for that peer */
+ this->pretrusted = get_pretrusted_cert(this->this, this->type, this->id);
+ if (this->pretrusted)
+ {
+ /* if we find a trusted self signed certificate, we just accept it.
+ * However, in order to fulfill authorization rules, we try to build
+ * the trust chain if it is not self signed */
+ if (this->this->cache->issued_by(this->this->cache,
+ this->pretrusted, this->pretrusted) ||
+ verify_trust_chain(this->this, this->pretrusted, this->auth,
+ TRUE, this->crl, this->ocsp))
+ {
+ DBG1(DBG_CFG, " using trusted certificate \"%D\"",
+ this->pretrusted->get_subject(this->pretrusted));
+ *cert = this->pretrusted;
+ if (auth)
+ {
+ *auth = this->auth;
+ }
+ return TRUE;
+ }
+ }
+ }
+ /* try to verify the trust chain for each certificate found */
+ while (this->candidates->enumerate(this->candidates, &current))
+ {
+ if (this->pretrusted &&
+ this->pretrusted->equals(this->pretrusted, current))
+ { /* skip pretrusted certificate we already served */
+ continue;
+ }
+
+ DBG1(DBG_CFG, " using certificate \"%D\"",
+ current->get_subject(current));
+ if (verify_trust_chain(this->this, current, this->auth, FALSE,
+ this->crl, this->ocsp))
+ {
+ *cert = current;
+ if (auth)
+ {
+ *auth = this->auth;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * Implements trusted_enumerator_t.destroy
+ */
+static void trusted_destroy(trusted_enumerator_t *this)
+{
+ DESTROY_IF(this->pretrusted);
+ DESTROY_IF(this->auth);
+ DESTROY_IF(this->candidates);
+ free(this);
+}
+
+/**
+ * create an enumerator over trusted certificates and their trustchain
+ */
+static enumerator_t *create_trusted_enumerator(private_credential_manager_t *this,
+ key_type_t type, identification_t *id, bool crl, bool ocsp)
+{
+ trusted_enumerator_t *enumerator = malloc_thing(trusted_enumerator_t);
+
+ enumerator->public.enumerate = (void*)trusted_enumerate;
+ enumerator->public.destroy = (void*)trusted_destroy;
+
+ enumerator->candidates = NULL;
+ enumerator->this = this;
+ enumerator->type = type;
+ enumerator->id = id;
+ enumerator->crl = crl;
+ enumerator->ocsp = ocsp;
+ enumerator->pretrusted = NULL;
+ enumerator->auth = NULL;
+
+ return &enumerator->public;
+}
+
+/**
+ * enumerator for public keys
+ */
+typedef struct {
+ /** implements enumerator_t interface */
+ enumerator_t public;
+ /** enumerator over candidate peer certificates */
+ enumerator_t *inner;
+ /** reference to the credential_manager */
+ private_credential_manager_t *this;
+ /** currently enumerating key */
+ public_key_t *current;
+ /** credset wrapper around auth */
+ auth_info_wrapper_t *wrapper;
+} public_enumerator_t;
+
+/**
+ * Implements public_enumerator_t.enumerate
+ */
+static bool public_enumerate(public_enumerator_t *this,
+ public_key_t **key, auth_info_t **auth)
+{
+ certificate_t *cert;
+
+ while (this->inner->enumerate(this->inner, &cert, auth))
+ {
+ DESTROY_IF(this->current);
+ this->current = cert->get_public_key(cert);
+ if (this->current)
+ {
+ *key = this->current;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * Implements public_enumerator_t.destroy
+ */
+static void public_destroy(public_enumerator_t *this)
+{
+ DESTROY_IF(this->current);
+ this->inner->destroy(this->inner);
+ if (this->wrapper)
+ {
+ remove_local_set(this->this, &this->wrapper->set);
+ this->wrapper->destroy(this->wrapper);
+ }
+ pthread_rwlock_unlock(&this->this->lock);
+ free(this);
+}
+
+/**
+ * Implementation of credential_manager_t.create_public_enumerator.
+ */
+static enumerator_t* create_public_enumerator(private_credential_manager_t *this,
+ key_type_t type, identification_t *id, auth_info_t *auth)
+{
+ public_enumerator_t *enumerator = malloc_thing(public_enumerator_t);
+
+ enumerator->public.enumerate = (void*)public_enumerate;
+ enumerator->public.destroy = (void*)public_destroy;
+ enumerator->inner = create_trusted_enumerator(this, type, id, TRUE, TRUE);
+ enumerator->this = this;
+ enumerator->current = NULL;
+ enumerator->wrapper = NULL;
+ if (auth)
+ {
+ enumerator->wrapper = auth_info_wrapper_create(auth);
+ add_local_set(this, &enumerator->wrapper->set);
+ }
+ pthread_rwlock_rdlock(&this->lock);
+ return &enumerator->public;
+}
+
+/**
+ * Check if a certificate's keyid is contained in the auth helper
+ */
+static bool auth_contains_cacert(auth_info_t *auth, certificate_t *cert)
+{
+ enumerator_t *enumerator;
+ identification_t *value;
+ auth_item_t type;
+ bool found = FALSE;
+
+ enumerator = auth->create_item_enumerator(auth);
+ while (enumerator->enumerate(enumerator, &type, &value))
+ {
+ if (type == AUTHN_CA_CERT && cert->equals(cert, (certificate_t*)value))
+ {
+ found = TRUE;
+ break;
+ }
+ if (type == AUTHN_CA_CERT_KEYID)
+ {
+ public_key_t *public;
+ identification_t *certid, *keyid;
+
+ public = cert->get_public_key(cert);
+ if (public)
+ {
+ keyid = (identification_t*)value;
+ certid = public->get_id(public, keyid->get_type(keyid));
+ if (certid && certid->equals(certid, keyid))
+ {
+ public->destroy(public);
+ found = TRUE;
+ break;
+ }
+ public->destroy(public);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found;
+}
+
+/**
+ * build a trustchain from subject up to a trust anchor in trusted
+ */
+static auth_info_t *build_trustchain(private_credential_manager_t *this,
+ certificate_t *subject, auth_info_t *auth)
+{
+ certificate_t *issuer, *current;
+ auth_info_t *trustchain;
+ u_int level = 0;
+
+ trustchain = auth_info_create();
+
+ if (!auth->get_item(auth, AUTHN_CA_CERT, (void**)&current))
+ {
+ /* no trust anchor specified, return this cert only */
+ trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, subject);
+ return trustchain;
+ }
+ current = subject->get_ref(subject);
+ while (TRUE)
+ {
+ if (auth_contains_cacert(auth, current))
+ {
+ trustchain->add_item(trustchain, AUTHZ_CA_CERT, current);
+ current->destroy(current);
+ return trustchain;
+ }
+ if (subject == current)
+ {
+ trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, current);
+ }
+ else
+ {
+ trustchain->add_item(trustchain, AUTHZ_IM_CERT, current);
+ }
+ issuer = get_issuer_cert(this, current, FALSE);
+ if (!issuer || issuer->equals(issuer, current) || level > MAX_CA_LEVELS)
+ {
+ DESTROY_IF(issuer);
+ current->destroy(current);
+ break;
+ }
+ current->destroy(current);
+ current = issuer;
+ level++;
+ }
+ trustchain->destroy(trustchain);
+ return NULL;
+}
+
+/**
+ * find a private key of a give certificate
+ */
+static private_key_t *get_private_by_cert(private_credential_manager_t *this,
+ certificate_t *cert, key_type_t type)
+{
+ private_key_t *private = NULL;
+ identification_t* keyid;
+ public_key_t *public;
+
+ public = cert->get_public_key(cert);
+ if (public)
+ {
+ keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+ if (keyid)
+ {
+ private = get_private_by_keyid(this, type, keyid);
+ }
+ public->destroy(public);
+ }
+ return private;
+}
+
+/**
+ * Implementation of credential_manager_t.get_private.
+ */
+static private_key_t *get_private(private_credential_manager_t *this,
+ key_type_t type, identification_t *id,
+ auth_info_t *auth)
+{
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ private_key_t *private = NULL;
+ auth_info_t *trustchain;
+
+ /* check if this is a lookup by key ID, and do it if so */
+ if (id)
+ {
+ switch (id->get_type(id))
+ {
+ case ID_PUBKEY_SHA1:
+ case ID_PUBKEY_INFO_SHA1:
+ case ID_KEY_ID:
+ return get_private_by_keyid(this, type, id);
+ default:
+ break;
+ }
+ }
+
+ /* try to build a trustchain for each certificate found */
+ enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ private = get_private_by_cert(this, cert, type);
+ if (private)
+ {
+ trustchain = build_trustchain(this, cert, auth);
+ if (trustchain)
+ {
+ auth->merge(auth, trustchain);
+ trustchain->destroy(trustchain);
+ break;
+ }
+ private->destroy(private);
+ private = NULL;
+ }
+ }
+ enumerator->destroy(enumerator);
+ /* if no valid trustchain was found, fall back to the first usable cert */
+ if (!private)
+ {
+ enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ private = get_private_by_cert(this, cert, type);
+ if (private)
+ {
+ auth->add_item(auth, AUTHZ_SUBJECT_CERT, cert);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ return private;
+}
+
+/**
+ * Implementation of credential_manager_t.flush_cache.
+ */
+static void flush_cache(private_credential_manager_t *this,
+ certificate_type_t type)
+{
+ this->cache->flush(this->cache, type);
+}
+
+/**
+ * Implementation of credential_manager_t.add_set.
+ */
+static void add_set(private_credential_manager_t *this,
+ credential_set_t *set)
+{
+ pthread_rwlock_wrlock(&this->lock);
+ this->sets->insert_last(this->sets, set);
+ pthread_rwlock_unlock(&this->lock);
+}
+
+/**
+ * Implementation of credential_manager_t.remove_set.
+ */
+static void remove_set(private_credential_manager_t *this, credential_set_t *set)
+{
+ pthread_rwlock_wrlock(&this->lock);
+ this->sets->remove(this->sets, set, NULL);
+ pthread_rwlock_unlock(&this->lock);
+}
+
+/**
+ * Implementation of credential_manager_t.destroy
+ */
+static void destroy(private_credential_manager_t *this)
+{
+ this->sets->remove(this->sets, this->cache, NULL);
+ this->sets->destroy(this->sets);
+ pthread_key_delete(this->local_sets);
+ this->cache->destroy(this->cache);
+ pthread_rwlock_destroy(&this->lock);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+credential_manager_t *credential_manager_create()
+{
+ private_credential_manager_t *this = malloc_thing(private_credential_manager_t);
+
+ this->public.create_cert_enumerator = (enumerator_t *(*)(credential_manager_t *this,certificate_type_t cert, key_type_t key,identification_t *id,bool))create_cert_enumerator;
+ this->public.create_shared_enumerator = (enumerator_t *(*)(credential_manager_t *this, shared_key_type_t type,identification_t *me, identification_t *other))create_shared_enumerator;
+ this->public.create_cdp_enumerator = (enumerator_t *(*)(credential_manager_t*, certificate_type_t type, identification_t *id))create_cdp_enumerator;
+ this->public.get_cert = (certificate_t *(*)(credential_manager_t *this,certificate_type_t cert, key_type_t key,identification_t *, bool))get_cert;
+ this->public.get_shared = (shared_key_t *(*)(credential_manager_t *this,shared_key_type_t type,identification_t *me, identification_t *other))get_shared;
+ this->public.get_private = (private_key_t*(*)(credential_manager_t*, key_type_t type, identification_t *, auth_info_t*))get_private;
+ this->public.create_public_enumerator = (enumerator_t*(*)(credential_manager_t*, key_type_t type, identification_t *id, auth_info_t *aut))create_public_enumerator;
+ this->public.flush_cache = (void(*)(credential_manager_t*, certificate_type_t type))flush_cache;
+ this->public.cache_cert = (void(*)(credential_manager_t*, certificate_t *cert))cache_cert;
+ this->public.add_set = (void(*)(credential_manager_t*, credential_set_t *set))add_set;
+ this->public.remove_set = (void(*)(credential_manager_t*, credential_set_t *set))remove_set;
+ this->public.destroy = (void(*)(credential_manager_t*))destroy;
+
+ this->sets = linked_list_create();
+ pthread_key_create(&this->local_sets, (void*)this->sets->destroy);
+ this->cache = cert_cache_create();
+ this->sets->insert_first(this->sets, this->cache);
+ pthread_rwlock_init(&this->lock, NULL);
+
+ return &this->public;
+}
+
diff --git a/src/charon/credentials/credential_manager.h b/src/charon/credentials/credential_manager.h
new file mode 100644
index 000000000..3a64437e6
--- /dev/null
+++ b/src/charon/credentials/credential_manager.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2007-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: credential_manager.h 3835 2008-04-18 10:11:41Z tobias $
+ */
+
+/**
+ * @defgroup credential_manager credential_manager
+ * @{ @ingroup ccredentials
+ */
+
+#ifndef CREDENTIAL_MANAGER_H_
+#define CREDENTIAL_MANAGER_H_
+
+#include <utils/identification.h>
+#include <utils/enumerator.h>
+#include <credentials/auth_info.h>
+#include <credentials/credential_set.h>
+#include <credentials/keys/private_key.h>
+#include <credentials/keys/shared_key.h>
+#include <credentials/certificates/certificate.h>
+
+typedef struct credential_manager_t credential_manager_t;
+
+/**
+ * Manages credentials using credential_sets.
+ *
+ * The credential manager is the entry point of the credential framework. It
+ * uses so called "sets" to access credentials in a modular fashion, these
+ * are implemented through the credential_set_t interface.
+ * The manager additionally does trust chain verification and trust status
+ * chaching. A set may call the managers methods if it needs credentials itself,
+ * the manager uses recursive locking.
+ *
+ * @verbatim
+
+ +-------+ +----------------+
+ | A | | | +------------------+
+ | u | -----> | | ------> | +------------------+
+ | t | | credential- | | | +------------------+
+ | h | -----> | manager | ------> +--| | credential- | => IPC
+ | e | | | +--| sets |
+ | n | +--> | | ------> +------------------+
+ | t | | | | |
+ | i | | | | |
+ | c | | +----------------+ |
+ | a | | |
+ | t | +----------------------------------------------+
+ | o | may be recursive
+ | r |
+ +-------+
+
+ @endverbatim
+ *
+ * The credential manager uses rwlocks for performance reasons, credential
+ * sets must be fully thread save.
+ */
+struct credential_manager_t {
+
+ /**
+ * Create an enumerator over all certificates.
+ *
+ * @param cert kind of certificate
+ * @param key kind of key in certificate
+ * @param id subject this certificate belongs to
+ * @param trusted TRUE to list trusted certificates only
+ * @return enumerator over the certificates
+ */
+ enumerator_t *(*create_cert_enumerator)(credential_manager_t *this,
+ certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted);
+ /**
+ * Create an enumerator over all shared keys.
+ *
+ * The enumerator enumerates over:
+ * shared_key_t*, id_match_t me, id_match_t other
+ * But must accepts values for the id_matches.
+ *
+ * @param type kind of requested shared key
+ * @param first first subject between key is shared
+ * @param second second subject between key is shared
+ * @return enumerator over shared keys
+ */
+ enumerator_t *(*create_shared_enumerator)(credential_manager_t *this,
+ shared_key_type_t type,
+ identification_t *first, identification_t *second);
+ /**
+ * Create an enumerator over all Certificate Distribution Points.
+ *
+ * @param type kind of certificate the point distributes
+ * @param id identification of the distributed certificate
+ * @return enumerator of CDPs as char*
+ */
+ enumerator_t *(*create_cdp_enumerator)(credential_manager_t *this,
+ certificate_type_t type, identification_t *id);
+ /**
+ * Get a trusted or untrusted certificate.
+ *
+ * @param cert kind of certificate
+ * @param key kind of key in certificate
+ * @param id subject this certificate belongs to
+ * @param trusted TRUE to get a trusted certificate only
+ * @return certificate, if found, NULL otherwise
+ */
+ certificate_t *(*get_cert)(credential_manager_t *this,
+ certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted);
+ /**
+ * Get the best matching shared key for two IDs.
+ *
+ * @param type kind of requested shared key
+ * @param me own identity
+ * @param other peers identity
+ * @param auth auth_info helper
+ * @return shared_key_t, NULL if none found
+ */
+ shared_key_t *(*get_shared)(credential_manager_t *this, shared_key_type_t type,
+ identification_t *me, identification_t *other);
+ /**
+ * Get a private key to create a signature.
+ *
+ * The get_private() method gets a secret private key identified by either
+ * the keyid itself or an id the key belongs to.
+ * The auth parameter contains additional information, such as receipients
+ * trusted CA certs. Auth gets filled with subject and CA certificates
+ * needed to validate a created signature.
+ *
+ * @param type type of the key to get
+ * @param id identification the key belongs to
+ * @param auth auth_info helper, including trusted CA certificates
+ * @return private_key_t, NULL if none found
+ */
+ private_key_t* (*get_private)(credential_manager_t *this, key_type_t type,
+ identification_t *id, auth_info_t *auth);
+
+ /**
+ * Create an enumerator over trusted public keys.
+ *
+ * This method gets a an enumerator over trusted public keys to verify a
+ * signature created by id. The auth parameter contains additional
+ * authentication infos, e.g. peer and intermediate certificates.
+ * The resulting enumerator enumerates over public_key_t *, auth_info_t *,
+ * where the auth info contains gained privileges for the authorization
+ * process.
+ *
+ * @param type type of the key to get
+ * @param id owner of the key, signer of the signature
+ * @param auth authentication infos
+ * @return enumerator
+ */
+ enumerator_t* (*create_public_enumerator)(credential_manager_t *this,
+ key_type_t type, identification_t *id, auth_info_t *auth);
+
+ /**
+ * Cache a certificate by invoking cache_cert() on all registerd sets.
+ *
+ * @param cert certificate to cache
+ */
+ void (*cache_cert)(credential_manager_t *this, certificate_t *cert);
+
+ /**
+ * Flush the certificate cache.
+ *
+ * Only the managers local cache is flushed, but not the sets cache filled
+ * by the cache_cert() method.
+ *
+ * @param type type of certificate to flush, or CERT_ANY
+ */
+ void (*flush_cache)(credential_manager_t *this, certificate_type_t type);
+
+ /**
+ * Register a credential set to the manager.
+ *
+ * @param set set to register
+ */
+ void (*add_set)(credential_manager_t *this, credential_set_t *set);
+
+ /**
+ * Unregister a credential set from the manager.
+ *
+ * @param set set to unregister
+ */
+ void (*remove_set)(credential_manager_t *this, credential_set_t *set);
+
+ /**
+ * Destroy a credential_manager instance.
+ */
+ void (*destroy)(credential_manager_t *this);
+};
+
+/**
+ * Create a credential_manager instance.
+ */
+credential_manager_t *credential_manager_create();
+
+#endif /* CREDENTIAL_MANAGER_H_ @} */
diff --git a/src/charon/credentials/credential_set.h b/src/charon/credentials/credential_set.h
new file mode 100644
index 000000000..b5f3b95cd
--- /dev/null
+++ b/src/charon/credentials/credential_set.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: credential_set.h 3820 2008-04-17 11:22:37Z martin $
+ */
+
+/**
+ * @defgroup credential_set credential_set
+ * @{ @ingroup ccredentials
+ */
+
+#ifndef CREDENTIAL_SET_H_
+#define CREDENTIAL_SET_H_
+
+#include <credentials/keys/public_key.h>
+#include <credentials/keys/shared_key.h>
+#include <credentials/certificates/certificate.h>
+
+typedef struct credential_set_t credential_set_t;
+
+/**
+ * A set of credentials.
+ *
+ * Contains private keys, shared keys and different kinds of certificates.
+ * Enumerators are used because queries might return multiple matches.
+ * Filter parameters restrict enumeration over specific items only.
+ * See credential_manager_t for an overview of the credential framework.
+ */
+struct credential_set_t {
+
+ /**
+ * Create an enumerator over private keys (private_key_t).
+ *
+ * The id is either a key identifier of the requested key, or an identity
+ * of the key owner.
+ *
+ * @param type type of requested private key
+ * @param id key identifier/owner
+ * @return enumerator over private_key_t's.
+ */
+ enumerator_t *(*create_private_enumerator)(credential_set_t *this,
+ key_type_t type, identification_t *id);
+ /**
+ * Create an enumerator over certificates (certificate_t).
+ *
+ * @param cert kind of certificate
+ * @param key kind of key in certificate
+ * @param id identity (subject) this certificate belongs to
+ * @param trusted whether the certificate must be trustworthy
+ * @return enumerator as described above
+ */
+ enumerator_t *(*create_cert_enumerator)(credential_set_t *this,
+ certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted);
+ /**
+ * Create an enumerator over shared keys (shared_key_t).
+ *
+ * The enumerator enumerates over:
+ * shared_key_t*, id_match_t me, id_match_t other
+ * But must accept NULL values for the id_matches.
+ *
+ * @param type kind of requested shared key
+ * @param me own identity
+ * @param other other identity who owns that secret
+ * @return enumerator as described above
+ */
+ enumerator_t *(*create_shared_enumerator)(credential_set_t *this,
+ shared_key_type_t type,
+ identification_t *me, identification_t *other);
+
+ /**
+ * Create an enumerator over certificate distribution points.
+ *
+ * @param type type of the certificate to get a CDP
+ * @param id identification of the distributed certificate
+ * @return an enumerator over CDPs as char*
+ */
+ enumerator_t *(*create_cdp_enumerator)(credential_set_t *this,
+ certificate_type_t type, identification_t *id);
+
+ /**
+ * Cache a certificate in the credential set.
+ *
+ * The caching policy is implementation dependent, the sets may cache the
+ * certificate in-memory, persistent on disk or not at all.
+ *
+ * @param cert certificate to cache
+ */
+ void (*cache_cert)(credential_set_t *this, certificate_t *cert);
+};
+
+#endif /* CREDENTIAL_SET_H_ @} */
diff --git a/src/charon/credentials/sets/auth_info_wrapper.c b/src/charon/credentials/sets/auth_info_wrapper.c
new file mode 100644
index 000000000..32783ff93
--- /dev/null
+++ b/src/charon/credentials/sets/auth_info_wrapper.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include <daemon.h>
+
+#include "auth_info_wrapper.h"
+
+typedef struct private_auth_info_wrapper_t private_auth_info_wrapper_t;
+
+/**
+ * private data of auth_info_wrapper
+ */
+struct private_auth_info_wrapper_t {
+
+ /**
+ * public functions
+ */
+ auth_info_wrapper_t public;
+
+ /**
+ * wrapped auth info
+ */
+ auth_info_t *auth;
+};
+
+/**
+ * enumerator for auth_info_wrapper_t.create_cert_enumerator()
+ */
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** inner enumerator from auth_info */
+ enumerator_t *inner;
+ /** wrapped auth info */
+ auth_info_t *auth;
+ /** enumerated cert type */
+ certificate_type_t cert;
+ /** enumerated key type */
+ key_type_t key;
+ /** enumerated id */
+ identification_t *id;
+} wrapper_enumerator_t;
+
+/**
+ * Tries to fetch a certificate that was supplied as "Hash and URL" (replaces the
+ * item's type and value in place).
+ */
+static bool fetch_cert(wrapper_enumerator_t *enumerator, auth_item_t *type, void **value)
+{
+ char *url = (char*)*value;
+ if (!url)
+ {
+ /* fetching the certificate previously failed */
+ return FALSE;
+ }
+
+ chunk_t data;
+ certificate_t *cert;
+
+ DBG1(DBG_CFG, " fetching certificate from '%s' ...", url);
+ if (lib->fetcher->fetch(lib->fetcher, url, &data) != SUCCESS)
+ {
+ DBG1(DBG_CFG, " fetching certificate failed");
+ /* we set the item to NULL, so we can skip it */
+ enumerator->auth->replace_item(enumerator->inner, *type, NULL);
+ return FALSE;
+ }
+
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER, data, BUILD_END);
+
+ if (!cert)
+ {
+ DBG1(DBG_CFG, " parsing fetched certificate failed");
+ /* we set the item to NULL, so we can skip it */
+ enumerator->auth->replace_item(enumerator->inner, *type, NULL);
+ return FALSE;
+ }
+
+ DBG1(DBG_CFG, " fetched certificate \"%D\"", cert->get_subject(cert));
+ charon->credentials->cache_cert(charon->credentials, cert);
+
+ *type = (*type == AUTHN_IM_HASH_URL) ? AUTHN_IM_CERT : AUTHN_SUBJECT_CERT;
+ *value = cert;
+ enumerator->auth->replace_item(enumerator->inner, *type, cert);
+
+ return TRUE;
+}
+
+/**
+ * enumerate function for wrapper_enumerator_t
+ */
+static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert)
+{
+ auth_item_t type;
+ certificate_t *current;
+ public_key_t *public;
+
+ while (this->inner->enumerate(this->inner, &type, &current))
+ {
+ if (type == AUTHN_IM_HASH_URL ||
+ type == AUTHN_SUBJECT_HASH_URL)
+ {
+ if (!fetch_cert(this, &type, (void**)&current))
+ {
+ continue;
+ }
+ }
+ else if (type != AUTHN_SUBJECT_CERT &&
+ type != AUTHN_IM_CERT)
+ {
+ continue;
+ }
+
+ if (this->cert != CERT_ANY && this->cert != current->get_type(current))
+ { /* CERT type requested, but does not match */
+ continue;
+ }
+ public = current->get_public_key(current);
+ if (this->key != KEY_ANY && !public)
+ { /* key type requested, but no public key */
+ DESTROY_IF(public);
+ continue;
+ }
+ if (this->key != KEY_ANY && public && this->key != public->get_type(public))
+ { /* key type requested, but public key has another type */
+ DESTROY_IF(public);
+ continue;
+ }
+ DESTROY_IF(public);
+ if (this->id && !current->has_subject(current, this->id))
+ { /* subject requested, but does not match */
+ continue;
+ }
+ *cert = current;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * destroy function for wrapper_enumerator_t
+ */
+static void wrapper_enumerator_destroy(wrapper_enumerator_t *this)
+{
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+/**
+ * implementation of auth_info_wrapper_t.set.create_cert_enumerator
+ */
+static enumerator_t *create_enumerator(private_auth_info_wrapper_t *this,
+ certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
+{
+ wrapper_enumerator_t *enumerator;
+
+ if (trusted)
+ {
+ return NULL;
+ }
+ enumerator = malloc_thing(wrapper_enumerator_t);
+ enumerator->auth = this->auth;
+ enumerator->cert = cert;
+ enumerator->key = key;
+ enumerator->id = id;
+ enumerator->inner = this->auth->create_item_enumerator(this->auth);
+ enumerator->public.enumerate = (void*)enumerate;
+ enumerator->public.destroy = (void*)wrapper_enumerator_destroy;
+ return &enumerator->public;
+}
+
+/**
+ * Implementation of auth_info_wrapper_t.destroy
+ */
+static void destroy(private_auth_info_wrapper_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+auth_info_wrapper_t *auth_info_wrapper_create(auth_info_t *auth)
+{
+ private_auth_info_wrapper_t *this = malloc_thing(private_auth_info_wrapper_t);
+
+ this->public.set.create_private_enumerator = (void*)return_null;
+ this->public.set.create_cert_enumerator = (void*)create_enumerator;
+ this->public.set.create_shared_enumerator = (void*)return_null;
+ this->public.set.create_cdp_enumerator = (void*)return_null;
+ this->public.set.cache_cert = (void*)nop;
+ this->public.destroy = (void(*)(auth_info_wrapper_t*))destroy;
+
+ this->auth = auth;
+
+ return &this->public;
+}
+
diff --git a/src/charon/credentials/sets/auth_info_wrapper.h b/src/charon/credentials/sets/auth_info_wrapper.h
new file mode 100644
index 000000000..c382e9870
--- /dev/null
+++ b/src/charon/credentials/sets/auth_info_wrapper.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup auth_info_wrapper auth_info_wrapper
+ * @{ @ingroup sets
+ */
+
+#ifndef AUTH_INFO_WRAPPER_H_
+#define AUTH_INFO_WRAPPER_H_
+
+#include <credentials/credential_set.h>
+#include <credentials/auth_info.h>
+
+typedef struct auth_info_wrapper_t auth_info_wrapper_t;
+
+/**
+ * A wrapper around auth_info_t to handle it like a credential set.
+ */
+struct auth_info_wrapper_t {
+
+ /**
+ * implements credential_set_t
+ */
+ credential_set_t set;
+
+ /**
+ * Destroy a auth_info_wrapper instance.
+ */
+ void (*destroy)(auth_info_wrapper_t *this);
+};
+
+/**
+ * Create a auth_info_wrapper instance.
+ *
+ * @param auth the wrapped auth info
+ * @return wrapper around auth
+ */
+auth_info_wrapper_t *auth_info_wrapper_create(auth_info_t *auth);
+
+#endif /* AUTH_INFO_WRAPPER_H_ @}*/
diff --git a/src/charon/credentials/sets/cert_cache.c b/src/charon/credentials/sets/cert_cache.c
new file mode 100644
index 000000000..8af8bb619
--- /dev/null
+++ b/src/charon/credentials/sets/cert_cache.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "cert_cache.h"
+
+#include <daemon.h>
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+
+#define CACHE_SIZE 30
+
+typedef struct private_cert_cache_t private_cert_cache_t;
+typedef struct relation_t relation_t;
+
+/**
+ * private data of cert_cache
+ */
+struct private_cert_cache_t {
+
+ /**
+ * public functions
+ */
+ cert_cache_t public;
+
+ /**
+ * list of trusted subject-issuer relations, as relation_t
+ */
+ linked_list_t *relations;
+
+ /**
+ * do we have an active enumerator
+ */
+ bool enumerating;
+
+ /**
+ * have we increased the cache without a check_cache?
+ */
+ bool check_required;
+
+ /**
+ * mutex to lock relations list
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * A trusted relation between subject and issuer
+ */
+struct relation_t {
+ /** subject of this relation */
+ certificate_t *subject;
+ /** issuer of this relation */
+ certificate_t *issuer;
+ /** time of last use */
+ time_t last_use;
+};
+
+/**
+ * destroy a relation_t structure
+ */
+static void relation_destroy(relation_t *this)
+{
+ this->subject->destroy(this->subject);
+ this->issuer->destroy(this->issuer);
+ free(this);
+}
+
+/**
+ * check the cache for oversize
+ */
+static void check_cache(private_cert_cache_t *this)
+{
+ if (this->enumerating)
+ {
+ this->check_required = TRUE;
+ }
+ else
+ {
+ while (this->relations->get_count(this->relations) > CACHE_SIZE)
+ {
+ relation_t *oldest = NULL, *current;
+ enumerator_t *enumerator;
+
+ enumerator = this->relations->create_enumerator(this->relations);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (oldest == NULL || oldest->last_use <= current->last_use)
+ {
+ oldest = current;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->relations->remove(this->relations, oldest, NULL);
+ relation_destroy(oldest);
+ }
+ this->check_required = FALSE;
+ }
+}
+
+/**
+ * Implementation of cert_cache_t.issued_by.
+ */
+static bool issued_by(private_cert_cache_t *this,
+ certificate_t *subject, certificate_t *issuer)
+{
+ relation_t *found = NULL, *current;
+ enumerator_t *enumerator;
+
+ /* lookup cache */
+ this->mutex->lock(this->mutex);
+ enumerator = this->relations->create_enumerator(this->relations);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ bool match = FALSE;
+
+ /* check for equal certificates */
+ if (subject->equals(subject, current->subject))
+ {
+ match = TRUE;
+ subject = current->subject;
+ }
+ if (issuer->equals(issuer, current->issuer))
+ {
+ issuer = current->issuer;
+ /* if both certs match, we already have a relation */
+ if (match)
+ {
+ current->last_use = time(NULL);
+ found = current;
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ if (found)
+ {
+ return TRUE;
+ }
+ /* no cache hit, check signature */
+ if (!subject->issued_by(subject, issuer))
+ {
+ return FALSE;
+ }
+ /* cache if good, respect cache limit */
+ found = malloc_thing(relation_t);
+ found->subject = subject->get_ref(subject);
+ found->issuer = issuer->get_ref(issuer);
+ found->last_use = time(NULL);
+ this->mutex->lock(this->mutex);
+ this->relations->insert_last(this->relations, found);
+ check_cache(this);
+ this->mutex->unlock(this->mutex);
+ return TRUE;
+}
+
+/**
+ * data associated to a cert enumeration
+ */
+typedef struct {
+ /** type of requested certificate */
+ certificate_type_t cert;
+ /** type of requested key */
+ key_type_t key;
+ /** ID to get a cert from */
+ identification_t *id;
+ /** reverse pointer to cache */
+ private_cert_cache_t *this;
+} cert_data_t;
+
+/**
+ * filter function for certs enumerator
+ */
+static bool certs_filter(cert_data_t *data, relation_t **in, certificate_t **out)
+{
+ public_key_t *public;
+ certificate_t *cert;
+
+ cert = (*in)->subject;
+ if (data->key == KEY_ANY && data->id &&
+ (data->cert == CERT_ANY || data->cert == CERT_X509_CRL) &&
+ cert->get_type(cert) == CERT_X509_CRL)
+ { /* CRL lookup is done using issuer/authkeyidentifier */
+ if (cert->has_issuer(cert, data->id))
+ {
+ *out = cert;
+ return TRUE;
+ }
+ }
+
+ if ((data->cert == CERT_ANY || cert->get_type(cert) == data->cert) &&
+ (!data->id || cert->has_subject(cert, data->id)))
+ {
+ if (data->key == KEY_ANY)
+ {
+ *out = cert;
+ return TRUE;
+ }
+ public = cert->get_public_key(cert);
+ if (public)
+ {
+ if (public->get_type(public) == data->key)
+ {
+ public->destroy(public);
+ *out = cert;
+ return TRUE;
+ }
+ public->destroy(public);
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * clean up enumeration data
+ */
+static void certs_destroy(cert_data_t *data)
+{
+ data->this->enumerating--;
+ if (data->this->check_required)
+ {
+ check_cache(data->this);
+ }
+ data->this->mutex->unlock(data->this->mutex);
+ free(data);
+}
+
+/**
+ * implementation of credential_set_t.create_cert_enumerator
+ */
+static enumerator_t *create_enumerator(private_cert_cache_t *this,
+ certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
+{
+ cert_data_t *data;
+
+ if (trusted)
+ {
+ return NULL;
+ }
+ data = malloc_thing(cert_data_t);
+ data->cert = cert;
+ data->key = key;
+ data->id = id;
+ data->this = this;
+
+ this->mutex->lock(this->mutex);
+ this->enumerating++;
+ return enumerator_create_filter(
+ this->relations->create_enumerator(this->relations),
+ (void*)certs_filter, data, (void*)certs_destroy);
+}
+
+/**
+ * Implementation of credential_set_t.cache_cert.
+ */
+static void cache_cert(private_cert_cache_t *this, certificate_t *cert)
+{
+ /* TODO: implement caching */
+}
+
+/**
+ * Implementation of cert_cache_t.flush.
+ */
+static void flush(private_cert_cache_t *this, certificate_type_t type)
+{
+ enumerator_t *enumerator;
+ relation_t *relation;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->relations->create_enumerator(this->relations);
+ while (enumerator->enumerate(enumerator, &relation))
+ {
+ if (type == CERT_ANY ||
+ type == relation->subject->get_type(relation->subject))
+ {
+ this->relations->remove_at(this->relations, enumerator);
+ relation_destroy(relation);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of cert_cache_t.destroy
+ */
+static void destroy(private_cert_cache_t *this)
+{
+ this->relations->destroy_function(this->relations, (void*)relation_destroy);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+cert_cache_t *cert_cache_create()
+{
+ private_cert_cache_t *this = malloc_thing(private_cert_cache_t);
+
+ this->public.set.create_private_enumerator = (void*)return_null;
+ this->public.set.create_cert_enumerator = (void*)create_enumerator;
+ this->public.set.create_shared_enumerator = (void*)return_null;
+ this->public.set.create_cdp_enumerator = (void*)return_null;
+ this->public.set.cache_cert = (void*)cache_cert;
+ this->public.issued_by = (bool(*)(cert_cache_t*, certificate_t *subject, certificate_t *issuer))issued_by;
+ this->public.flush = (void(*)(cert_cache_t*, certificate_type_t type))flush;
+ this->public.destroy = (void(*)(cert_cache_t*))destroy;
+
+ this->relations = linked_list_create();
+ this->enumerating = FALSE;
+ this->check_required = FALSE;
+ this->mutex = mutex_create(MUTEX_RECURSIVE);
+
+ return &this->public;
+}
+
diff --git a/src/charon/credentials/sets/cert_cache.h b/src/charon/credentials/sets/cert_cache.h
new file mode 100644
index 000000000..281189d53
--- /dev/null
+++ b/src/charon/credentials/sets/cert_cache.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup cert_cache cert_cache
+ * @{ @ingroup sets
+ */
+
+#ifndef CERT_CACHE_H_
+#define CERT_CACHE_H_
+
+#include <credentials/credential_set.h>
+
+typedef struct cert_cache_t cert_cache_t;
+
+/**
+ * Certificate signature verification and certificate cache.
+ *
+ * This cache serves all certificates seen in its issued_by method
+ * and serves them as untrusted through the credential set interface. Further,
+ * it caches valid subject-issuer relationships to speed up the issued_by
+ * method.
+ */
+struct cert_cache_t {
+
+ /**
+ * Implements credential_set_t.
+ */
+ credential_set_t set;
+
+ /**
+ * Caching wrapper around certificate_t.issued_by.
+ *
+ * @param subject certificate to verify
+ * @param issuer issuing certificate to verify subject
+ * @return TRUE if subject issued by issuer
+ */
+ bool (*issued_by)(cert_cache_t *this,
+ certificate_t *subject, certificate_t *issuer);
+
+ /**
+ * Flush the certificate cache.
+ *
+ * @param type type of certificate to flush, or CERT_ANY
+ */
+ void (*flush)(cert_cache_t *this, certificate_type_t type);
+
+ /**
+ * Destroy a cert_cache instance.
+ */
+ void (*destroy)(cert_cache_t *this);
+};
+
+/**
+ * Create a cert_cache instance.
+ */
+cert_cache_t *cert_cache_create();
+
+#endif /* CERT_CACHE_H_ @}*/
diff --git a/src/charon/credentials/sets/ocsp_response_wrapper.c b/src/charon/credentials/sets/ocsp_response_wrapper.c
new file mode 100644
index 000000000..c4d3a5b0f
--- /dev/null
+++ b/src/charon/credentials/sets/ocsp_response_wrapper.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "ocsp_response_wrapper.h"
+
+typedef struct private_ocsp_response_wrapper_t private_ocsp_response_wrapper_t;
+
+/**
+ * private data of ocsp_response_wrapper
+ */
+struct private_ocsp_response_wrapper_t {
+
+ /**
+ * public functions
+ */
+ ocsp_response_wrapper_t public;
+
+ /**
+ * wrapped OCSP response
+ */
+ ocsp_response_t *response;
+};
+
+/**
+ * enumerator for ocsp_response_wrapper_t.create_cert_enumerator()
+ */
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** enumerator over ocsp response */
+ enumerator_t *inner;
+ /** type of cert */
+ certificate_type_t cert;
+ /** type of key */
+ key_type_t key;
+ /** filtering identity */
+ identification_t *id;
+} wrapper_enumerator_t;
+
+/**
+ * enumerate function wrapper_enumerator_t
+ */
+static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert)
+{
+ certificate_t *current;
+ public_key_t *public;
+
+ while (this->inner->enumerate(this->inner, &current))
+ {
+ if (this->cert != CERT_ANY && this->cert != current->get_type(current))
+ { /* CERT type requested, but does not match */
+ continue;
+ }
+ public = current->get_public_key(current);
+ if (this->key != KEY_ANY && !public)
+ { /* key type requested, but no public key */
+ DESTROY_IF(public);
+ continue;
+ }
+ if (this->key != KEY_ANY && public && this->key != public->get_type(public))
+ { /* key type requested, but public key has another type */
+ DESTROY_IF(public);
+ continue;
+ }
+ DESTROY_IF(public);
+ if (this->id && !current->has_subject(current, this->id))
+ { /* subject requested, but does not match */
+ continue;
+ }
+ *cert = current;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * destroy function for wrapper_enumerator_t
+ */
+static void enumerator_destroy(wrapper_enumerator_t *this)
+{
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+/**
+ * implementation of ocsp_response_wrapper_t.set.create_cert_enumerator
+ */
+static enumerator_t *create_enumerator(private_ocsp_response_wrapper_t *this,
+ certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
+{
+ wrapper_enumerator_t *enumerator;
+
+ if (trusted)
+ {
+ return NULL;
+ }
+
+ enumerator = malloc_thing(wrapper_enumerator_t);
+ enumerator->cert = cert;
+ enumerator->key = key;
+ enumerator->id = id;
+ enumerator->inner = this->response->create_cert_enumerator(this->response);
+ enumerator->public.enumerate = (void*)enumerate;
+ enumerator->public.destroy = (void*)enumerator_destroy;
+ return &enumerator->public;
+}
+
+/**
+ * Implementation of ocsp_response_wrapper_t.destroy
+ */
+static void destroy(private_ocsp_response_wrapper_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+ocsp_response_wrapper_t *ocsp_response_wrapper_create(ocsp_response_t *response)
+{
+ private_ocsp_response_wrapper_t *this = malloc_thing(private_ocsp_response_wrapper_t);
+
+ this->public.set.create_private_enumerator = (void*)return_null;
+ this->public.set.create_cert_enumerator = (void*)create_enumerator;
+ this->public.set.create_shared_enumerator = (void*)return_null;
+ this->public.set.create_cdp_enumerator = (void*)return_null;
+ this->public.set.cache_cert = (void*)nop;
+ this->public.destroy = (void(*)(ocsp_response_wrapper_t*))destroy;
+
+ this->response = response;
+
+ return &this->public;
+}
+
diff --git a/src/charon/credentials/sets/ocsp_response_wrapper.h b/src/charon/credentials/sets/ocsp_response_wrapper.h
new file mode 100644
index 000000000..6d32c2ca8
--- /dev/null
+++ b/src/charon/credentials/sets/ocsp_response_wrapper.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup ocsp_response_wrapper ocsp_response_wrapper
+ * @{ @ingroup sets
+ */
+
+#ifndef OCSP_RESPONSE_WRAPPER_H_
+#define OCSP_RESPONSE_WRAPPER_H_
+
+#include <credentials/credential_set.h>
+#include <credentials/certificates/ocsp_response.h>
+
+typedef struct ocsp_response_wrapper_t ocsp_response_wrapper_t;
+
+/**
+ * A wrapper around ocsp_response_t to handle it like a credential set.
+ */
+struct ocsp_response_wrapper_t {
+
+ /**
+ * implements credential_set_t
+ */
+ credential_set_t set;
+
+ /**
+ * Destroy a ocsp_response_wrapper instance.
+ */
+ void (*destroy)(ocsp_response_wrapper_t *this);
+};
+
+/**
+ * Create a ocsp_response_wrapper instance.
+ *
+ * @param response the wrapped OCSP response
+ * @return wrapper around response
+ */
+ocsp_response_wrapper_t *ocsp_response_wrapper_create(ocsp_response_t *response);
+
+#endif /* OCSP_RESPONSE_WRAPPER_H_ @}*/
diff --git a/src/charon/daemon.c b/src/charon/daemon.c
index ee9710424..1ab88104a 100644
--- a/src/charon/daemon.c
+++ b/src/charon/daemon.c
@@ -1,13 +1,7 @@
-/**
- * @file daemon.c
- *
- * @brief Implementation of daemon_t and main of IKEv2-Daemon.
- *
- */
-
-/* Copyright (C) 2006-2007 Tobias Brunner
+/*
+ * Copyright (C) 2006-2007 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -22,6 +16,11 @@
* for more details.
*/
+#ifdef HAVE_DLADDR
+# define _GNU_SOURCE
+# include <dlfcn.h>
+#endif /* HAVE_DLADDR */
+
#include <stdio.h>
#include <linux/capability.h>
#include <sys/prctl.h>
@@ -34,6 +33,8 @@
#include <string.h>
#include <getopt.h>
#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
#ifdef HAVE_BACKTRACE
# include <execinfo.h>
#endif /* HAVE_BACKTRACE */
@@ -41,11 +42,8 @@
#include "daemon.h"
#include <library.h>
-#include <crypto/ca.h>
-#include <utils/fetcher.h>
-#include <config/credentials/local_credential_store.h>
-#include <config/backends/local_backend.h>
-#include <sa/authenticators/eap/eap_method.h>
+#include <config/traffic_selector.h>
+#include <config/proposal.h>
/* on some distros, a capset definition is missing */
#ifdef NO_CAPSET_DEFINED
@@ -108,11 +106,14 @@ static void dbg_stderr(int level, char *fmt, ...)
{
va_list args;
- va_start(args, fmt);
- fprintf(stderr, "00[LIB] ");
- vfprintf(stderr, fmt, args);
- fprintf(stderr, "\n");
- va_end(args);
+ if (level <= 1)
+ {
+ va_start(args, fmt);
+ fprintf(stderr, "00[LIB] ");
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ va_end(args);
+ }
}
/**
@@ -171,17 +172,28 @@ static void run(private_daemon_t *this)
static void destroy(private_daemon_t *this)
{
/* terminate all idle threads */
- this->public.processor->set_threads(this->public.processor, 0);
+ if (this->public.processor)
+ {
+ this->public.processor->set_threads(this->public.processor, 0);
+ }
/* close all IKE_SAs */
+ if (this->public.ike_sa_manager)
+ {
+ this->public.ike_sa_manager->flush(this->public.ike_sa_manager);
+ }
+ /* unload plugins to release threads */
+ lib->plugins->unload(lib->plugins);
DESTROY_IF(this->public.ike_sa_manager);
DESTROY_IF(this->public.kernel_interface);
DESTROY_IF(this->public.scheduler);
- DESTROY_IF(this->public.interfaces);
-#ifdef P2P
+ DESTROY_IF(this->public.controller);
+ DESTROY_IF(this->public.eap);
+#ifdef ME
DESTROY_IF(this->public.connect_manager);
DESTROY_IF(this->public.mediation_manager);
-#endif /* P2P */
+#endif /* ME */
DESTROY_IF(this->public.backends);
+ DESTROY_IF(this->public.attributes);
DESTROY_IF(this->public.credentials);
DESTROY_IF(this->public.sender);
DESTROY_IF(this->public.receiver);
@@ -204,11 +216,17 @@ static void destroy(private_daemon_t *this)
static void kill_daemon(private_daemon_t *this, char *reason)
{
/* we send SIGTERM, so the daemon can cleanly shut down */
- DBG1(DBG_DMN, "killing daemon: %s", reason);
+ if (this->public.bus)
+ {
+ DBG1(DBG_DMN, "killing daemon: %s", reason);
+ }
+ else
+ {
+ fprintf(stderr, "killing daemon: %s\n", reason);
+ }
if (this->main_thread_id == pthread_self())
{
/* initialization failed, terminate daemon */
- destroy(this);
unlink(PID_FILE);
exit(-1);
}
@@ -230,22 +248,18 @@ static void drop_capabilities(private_daemon_t *this, bool full)
struct __user_cap_data_struct data;
/* CAP_NET_ADMIN is needed to use netlink */
- u_int32_t keep = (1<<CAP_NET_ADMIN);
+ u_int32_t keep = (1<<CAP_NET_ADMIN) | (1<<CAP_SYS_NICE);
if (full)
{
-# if IPSEC_GID
- if (setgid(IPSEC_GID) != 0)
+ if (setgid(charon->gid) != 0)
{
- kill_daemon(this, "changing GID to unprivileged group failed");
+ kill_daemon(this, "change to unprivileged group failed");
}
-# endif
-# if IPSEC_UID
- if (setuid(IPSEC_UID) != 0)
+ if (setuid(charon->uid) != 0)
{
- kill_daemon(this, "changing UID to unprivileged user failed");
+ kill_daemon(this, "change to unprivileged user failed");
}
-# endif
}
else
{
@@ -263,7 +277,13 @@ static void drop_capabilities(private_daemon_t *this, bool full)
keep |= (1<<CAP_SETGID);
}
+ /* we use the old capset version for now. For systems with version 2
+ * available, we specifiy version 1 excplicitly. */
+#ifdef _LINUX_CAPABILITY_VERSION_1
+ hdr.version = _LINUX_CAPABILITY_VERSION_1;
+#else
hdr.version = _LINUX_CAPABILITY_VERSION;
+#endif
hdr.pid = 0;
data.inheritable = data.effective = data.permitted = keep;
@@ -274,6 +294,39 @@ static void drop_capabilities(private_daemon_t *this, bool full)
}
/**
+ * lookup UID and GID
+ */
+static void lookup_uid_gid(private_daemon_t *this)
+{
+#ifdef IPSEC_USER
+ {
+ char buf[1024];
+ struct passwd passwd, *pwp;
+
+ if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
+ pwp == NULL)
+ {
+ kill_daemon(this, "resolving user '"IPSEC_USER"' failed");
+ }
+ charon->uid = pwp->pw_uid;
+ }
+#endif
+#ifdef IPSEC_GROUP
+ {
+ char buf[1024];
+ struct group group, *grp;
+
+ if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
+ grp == NULL)
+ {
+ kill_daemon(this, "reslvoing group '"IPSEC_GROUP"' failed");
+ }
+ charon->gid = grp->gr_gid;
+ }
+#endif
+}
+
+/**
* Initialize the daemon
*/
static bool initialize(private_daemon_t *this, bool syslog, level_t levels[])
@@ -321,31 +374,42 @@ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[])
return FALSE;
}
#endif /* INTEGRITY_TEST */
-
- this->public.ike_sa_manager = ike_sa_manager_create();
- this->public.processor = processor_create();
- this->public.scheduler = scheduler_create();
/* load secrets, ca certificates and crls */
- this->public.credentials = (credential_store_t*)local_credential_store_create();
- this->public.credentials->load_ca_certificates(this->public.credentials);
- this->public.credentials->load_aa_certificates(this->public.credentials);
- this->public.credentials->load_attr_certificates(this->public.credentials);
- this->public.credentials->load_ocsp_certificates(this->public.credentials);
- this->public.credentials->load_crls(this->public.credentials);
- this->public.credentials->load_secrets(this->public.credentials, FALSE);
-
- this->public.interfaces = interface_manager_create();
+ this->public.processor = processor_create();
+ this->public.scheduler = scheduler_create();
+ this->public.credentials = credential_manager_create();
+ this->public.controller = controller_create();
+ this->public.eap = eap_manager_create();
this->public.backends = backend_manager_create();
+ this->public.attributes = attribute_manager_create();
this->public.kernel_interface = kernel_interface_create();
this->public.socket = socket_create();
+
+ /* load plugins, further infrastructure may need it */
+ lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
+ lib->settings->get_str(lib->settings, "charon.load", PLUGINS));
+
+ this->public.ike_sa_manager = ike_sa_manager_create();
+ if (this->public.ike_sa_manager == NULL)
+ {
+ return FALSE;
+ }
this->public.sender = sender_create();
this->public.receiver = receiver_create();
+ if (this->public.receiver == NULL)
+ {
+ return FALSE;
+ }
-#ifdef P2P
+#ifdef ME
this->public.connect_manager = connect_manager_create();
+ if (this->public.connect_manager == NULL)
+ {
+ return FALSE;
+ }
this->public.mediation_manager = mediation_manager_create();
-#endif /* P2P */
+#endif /* ME */
return TRUE;
}
@@ -369,7 +433,25 @@ static void segv_handler(int signal)
for (i = 0; i < size; i++)
{
- DBG1(DBG_DMN, " %s", strings[i]);
+#ifdef HAVE_DLADDR
+ Dl_info info;
+
+ if (dladdr(array[i], &info))
+ {
+ void *ptr = array[i];
+ if (strstr(info.dli_fname, ".so"))
+ {
+ ptr = (void*)(array[i] - info.dli_fbase);
+ }
+ DBG1(DBG_DMN, " %s [%p]", info.dli_fname, ptr);
+ }
+ else
+ {
+#endif /* HAVE_DLADDR */
+ DBG1(DBG_DMN, " %s", strings[i]);
+#ifdef HAVE_DLADDR
+ }
+#endif /* HAVE_DLADDR */
}
free (strings);
#else /* !HAVE_BACKTRACE */
@@ -396,16 +478,24 @@ private_daemon_t *daemon_create(void)
this->public.ike_sa_manager = NULL;
this->public.credentials = NULL;
this->public.backends = NULL;
+ this->public.attributes = NULL;
this->public.sender= NULL;
this->public.receiver = NULL;
this->public.scheduler = NULL;
this->public.kernel_interface = NULL;
this->public.processor = NULL;
- this->public.interfaces = NULL;
+ this->public.controller = NULL;
+ this->public.eap = NULL;
this->public.bus = NULL;
this->public.outlog = NULL;
this->public.syslog = NULL;
this->public.authlog = NULL;
+#ifdef ME
+ this->public.connect_manager = NULL;
+ this->public.mediation_manager = NULL;
+#endif /* ME */
+ this->public.uid = 0;
+ this->public.gid = 0;
this->main_thread_id = pthread_self();
@@ -440,10 +530,6 @@ static void usage(const char *msg)
fprintf(stderr, "Usage: charon\n"
" [--help]\n"
" [--version]\n"
- " [--strictcrlpolicy]\n"
- " [--cachecrls]\n"
- " [--crlcheckinterval <interval>]\n"
- " [--eapdir <dir>]\n"
" [--use-syslog]\n"
" [--debug-<type> <level>]\n"
" <type>: log context type (dmn|mgr|ike|chd|job|cfg|knl|net|enc|lib)\n"
@@ -459,11 +545,7 @@ static void usage(const char *msg)
*/
int main(int argc, char *argv[])
{
- u_int crl_check_interval = 0;
- strict_t strict_crl_policy = STRICT_NO;
- bool cache_crls = FALSE;
bool use_syslog = FALSE;
- char *eapdir = IPSEC_EAPDIR;
private_daemon_t *private_charon;
FILE *pid_file;
@@ -471,9 +553,20 @@ int main(int argc, char *argv[])
level_t levels[DBG_MAX];
int signal;
+ /* logging for library during initialization, as we have no bus yet */
+ dbg = dbg_stderr;
+
+ /* initialize library */
+ library_init(STRONGSWAN_CONF);
+ lib->printf_hook->add_handler(lib->printf_hook, 'R',
+ traffic_selector_get_printf_hooks());
+ lib->printf_hook->add_handler(lib->printf_hook, 'P',
+ proposal_get_printf_hooks());
private_charon = daemon_create();
charon = (daemon_t*)private_charon;
+ lookup_uid_gid(private_charon);
+
/* drop the capabilities we won't need for initialization */
prctl(PR_SET_KEEPCAPS, 1);
drop_capabilities(private_charon, FALSE);
@@ -491,10 +584,6 @@ int main(int argc, char *argv[])
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "use-syslog", no_argument, NULL, 'l' },
- { "strictcrlpolicy", required_argument, NULL, 'r' },
- { "cachecrls", no_argument, NULL, 'C' },
- { "crlcheckinterval", required_argument, NULL, 'x' },
- { "eapdir", required_argument, NULL, 'e' },
/* TODO: handle "debug-all" */
{ "debug-dmn", required_argument, &signal, DBG_DMN },
{ "debug-mgr", required_argument, &signal, DBG_MGR },
@@ -523,18 +612,6 @@ int main(int argc, char *argv[])
case 'l':
use_syslog = TRUE;
continue;
- case 'r':
- strict_crl_policy = atoi(optarg);
- continue;
- case 'C':
- cache_crls = TRUE;
- continue;
- case 'x':
- crl_check_interval = atoi(optarg);
- continue;
- case 'e':
- eapdir = optarg;
- continue;
case 0:
/* option is in signal */
levels[signal] = atoi(optarg);
@@ -554,14 +631,6 @@ int main(int argc, char *argv[])
exit(-1);
}
- /* initialize fetcher_t class */
- fetcher_initialize();
- /* load pluggable EAP modules */
- eap_method_load(eapdir);
-
- /* set strict_crl_policy, cache_crls and crl_check_interval options */
- ca_info_set_options(strict_crl_policy, cache_crls, crl_check_interval);
-
/* check/setup PID file */
if (stat(PID_FILE, &stb) == 0)
{
@@ -573,7 +642,7 @@ int main(int argc, char *argv[])
if (pid_file)
{
fprintf(pid_file, "%d\n", getpid());
- fchown(fileno(pid_file), IPSEC_UID, IPSEC_GID);
+ fchown(fileno(pid_file), charon->uid, charon->gid);
fclose(pid_file);
}
@@ -581,17 +650,19 @@ int main(int argc, char *argv[])
drop_capabilities(private_charon, TRUE);
/* start the engine, go multithreaded */
- charon->processor->set_threads(charon->processor, WORKER_THREADS);
+ charon->processor->set_threads(charon->processor,
+ lib->settings->get_int(lib->settings, "charon.threads",
+ DEFAULT_THREADS));
/* run daemon */
run(private_charon);
- eap_method_unload();
- fetcher_finalize();
/* normal termination, cleanup and exit */
destroy(private_charon);
unlink(PID_FILE);
+ library_deinit();
+
return 0;
}
diff --git a/src/charon/daemon.h b/src/charon/daemon.h
index 33c63091d..5893e7332 100644
--- a/src/charon/daemon.h
+++ b/src/charon/daemon.h
@@ -1,14 +1,7 @@
-/**
- * @file daemon.h
- *
- * @brief Interface of daemon_t.
- *
- */
-
/*
* Copyright (C) 2006-2007 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -21,345 +14,189 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: daemon.h 3964 2008-05-15 14:01:26Z martin $
*/
-#ifndef DAEMON_H_
-#define DAEMON_H_
-
-typedef struct daemon_t daemon_t;
-
-#include <credential_store.h>
-
-#include <network/sender.h>
-#include <network/receiver.h>
-#include <network/socket.h>
-#include <processing/scheduler.h>
-#include <processing/processor.h>
-#include <kernel/kernel_interface.h>
-#include <control/interface_manager.h>
-#include <bus/bus.h>
-#include <bus/listeners/file_logger.h>
-#include <bus/listeners/sys_logger.h>
-#include <sa/ike_sa_manager.h>
-#include <config/backend_manager.h>
-
-#ifdef P2P
-#include <sa/connect_manager.h>
-#include <sa/mediation_manager.h>
-#endif /* P2P */
-
/**
* @defgroup charon charon
*
- * @brief IKEv2 keying daemon.
- *
- * All IKEv2 stuff is handled in charon. It uses a newer and more flexible
- * architecture than pluto. Charon uses a thread-pool (called processor),
- * which allows parallel execution SA-management. All threads originate
- * from the processor. Work is delegated to the processor by queueing jobs
- * to it.
- @verbatim
-
- +--------+ +-------+ +--------+ +-----------+ +-----------+
- | Stroke | | XML | | DBUS | | Local | | SQLite |
- +--------+ +-------+ +--------+ +-----------+ +-----------+
- | | | | |
- +---------------------------------+ +----------------------------+
- | Interfaces | | Backends |
- +---------------------------------+ +----------------------------+
-
-
- +------------+ +-----------+ +------+ +----------+
- | receiver | | | | | +------+ | CHILD_SA |
- +----+-------+ | Scheduler | | IKE- | | IKE- |--+----------+
- | | | | SA |--| SA | | CHILD_SA |
- +-------+--+ +-----------+ | | +------+ +----------+
- <->| socket | | | Man- |
- +-------+--+ +-----------+ | ager | +------+ +----------+
- | | | | | | IKE- |--| CHILD_SA |
- +----+-------+ | Processor |--------| |--| SA | +----------+
- | sender | | | | | +------+
- +------------+ +-----------+ +------+
-
-
- +---------------------------------+ +----------------------------+
- | Bus | | Kernel Interface |
- +---------------------------------+ +----------------------------+
- | | |
- +-------------+ +-------------+ V
- | File-Logger | | Sys-Logger | //////
- +-------------+ +-------------+
-
-
- @endverbatim
- * The scheduler is responsible to execute timed events. Jobs may be queued to
- * the scheduler to get executed at a defined time (e.g. rekeying). The scheduler
- * does not execute the jobs itself, it queues them to the processor.
- *
- * The IKE_SA manager managers all IKE_SA. It further handles the synchronization:
- * Each IKE_SA must be checked out strictly and checked in again after use. The
- * manager guarantees that only one thread may check out a single IKE_SA. This allows
- * us to write the (complex) IKE_SAs routines non-threadsave.
- * The IKE_SA contain the state and the logic of each IKE_SA and handle the messages.
- *
- * The CHILD_SA contains state about a IPsec security association and manages them.
- * An IKE_SA may have multiple CHILD_SAs. Communication to the kernel takes place
- * here through the kernel interface.
- *
- * The kernel interface installs IPsec security associations, policies routes and
- * virtual addresses. It further provides methods to enumerate interfaces and may notify
- * the daemon about state changes at lower layers.
- *
- * The bus receives signals from the different threads and relais them to interested
- * listeners. Debugging signals, but also important state changes or error messages are
- * sent over the bus.
- * It's listeners are not only for logging, but also to track the state of an IKE_SA.
- *
- * The interface manager loads pluggable controlling interfaces. These are written to control
- * the daemon from external inputs (e.g. initiate IKE_SA, close IKE_SA, ...). The interface
- * manager further provides a simple API to establish these tasks.
- * Backends are pluggable modules which provide configuration. They have to implement an API
- * which the daemon core uses to get configuration.
- */
-
-/**
* @defgroup bus bus
- *
- * Signaling bus and its listeners.
- *
* @ingroup charon
- */
-
-/**
- * @defgroup config config
- *
- * Classes implementing configuration related things.
+ *
+ * @defgroup listeners listeners
+ * @ingroup bus
*
+ * @defgroup config config
* @ingroup charon
- */
-
-/**
- * @defgroup backends backends
- *
- * Classes implementing configuration backends.
*
+ * @defgroup attributes attributes
* @ingroup config
- */
-
-/**
- * @defgroup credentials credentials
*
- * Trust chain verification and certificate store.
- *
- * @ingroup config
- */
-
-/**
* @defgroup control control
+ * @ingroup charon
*
- * Handling of loadable control interface modules.
- *
+ * @defgroup ccredentials credentials
* @ingroup charon
- */
-
-/**
- * @defgroup interfaces interfaces
*
- * Classes which control the daemon using IPC mechanisms.
+ * @defgroup sets sets
+ * @ingroup ccredentials
*
- * @ingroup control
- */
-
-/**
* @defgroup encoding encoding
- *
- * Classes used to encode and decode IKEv2 messages.
- *
* @ingroup charon
- */
-
- /**
- * @defgroup payloads payloads
- *
- * Classes representing specific IKEv2 payloads.
*
+ * @defgroup payloads payloads
* @ingroup encoding
- */
-
-/**
- * @defgroup kernel kernel
- *
- * Classes to configure and query the kernel.
*
+ * @defgroup kernel kernel
* @ingroup charon
- */
-
-/**
- * @defgroup network network
- *
- * Classes for sending and receiving UDP packets over the network.
*
+ * @defgroup network network
* @ingroup charon
- */
-
-/**
- * @defgroup processing processing
- *
- * Queueing, scheduling and processing of jobs
*
+ * @defgroup cplugins plugins
* @ingroup charon
- */
-
-/**
- * @defgroup jobs jobs
*
- * Jobs to queue, schedule and process.
+ * @defgroup processing processing
+ * @ingroup charon
*
+ * @defgroup jobs jobs
* @ingroup processing
- */
-
-/**
- * @defgroup sa sa
- *
- * Security associations for IKE and IPSec, and its helper classes.
*
+ * @defgroup sa sa
* @ingroup charon
- */
-
-/**
- * @defgroup authenticators authenticators
- *
- * Authenticator classes to prove identity of a peer.
*
+ * @defgroup authenticators authenticators
* @ingroup sa
- */
-
-/**
- * @defgroup eap eap
- *
- * EAP module loader, interface and it's implementations.
*
+ * @defgroup eap eap
* @ingroup authenticators
- */
-
-/**
+ *
* @defgroup tasks tasks
+ * @ingroup sa
*
- * Tasks process and build message payloads. They are used to create
- * and process multiple exchanges.
+ * @addtogroup charon
+ * @{
*
- * @ingroup sa
- */
-
-/**
- * Name of the daemon.
+ * IKEv2 keying daemon.
*
- * @ingroup charon
- */
-#define DAEMON_NAME "charon"
+ * All IKEv2 stuff is handled in charon. It uses a newer and more flexible
+ * architecture than pluto. Charon uses a thread-pool (called processor),
+ * which allows parallel execution SA-management. All threads originate
+ * from the processor. Work is delegated to the processor by queueing jobs
+ * to it.
+ @verbatim
+
+ +---------------------------------+ +----------------------------+
+ | controller | | config |
+ +---------------------------------+ +----------------------------+
+ | | | ^ ^ ^
+ V V V | | |
+
+ +----------+ +-----------+ +------+ +----------+ +----+
+ | receiver | | | | | +------+ | CHILD_SA | | K |
+ +---+------+ | Scheduler | | IKE- | | IKE- |--+----------+ | e |
+ | | | | SA |--| SA | | CHILD_SA | | r |
+ +------+---+ +-----------+ | | +------+ +----------+ | n |
+ <->| socket | | | Man- | | e |
+ +------+---+ +-----------+ | ager | +------+ +----------+ | l |
+ | | | | | | IKE- |--| CHILD_SA | | - |
+ +---+------+ | Processor |---| |--| SA | +----------+ | I |
+ | sender | | | | | +------+ | f |
+ +----------+ +-----------+ +------+ +----+
+
+ | | | | | |
+ V V V V V V
+ +---------------------------------+ +----------------------------+
+ | Bus | | credentials |
+ +---------------------------------+ +----------------------------+
-/**
- * @brief Number of threads in the thread pool.
+ @endverbatim
+ * The scheduler is responsible to execute timed events. Jobs may be queued to
+ * the scheduler to get executed at a defined time (e.g. rekeying). The
+ * scheduler does not execute the jobs itself, it queues them to the processor.
*
- * @ingroup charon
- */
-#define WORKER_THREADS 16
-
-/**
- * UDP Port on which the daemon will listen for incoming traffic.
+ * The IKE_SA manager managers all IKE_SA. It further handles the
+ * synchronization:
+ * Each IKE_SA must be checked out strictly and checked in again after use. The
+ * manager guarantees that only one thread may check out a single IKE_SA. This
+ * allows us to write the (complex) IKE_SAs routines non-threadsave.
+ * The IKE_SA contain the state and the logic of each IKE_SA and handle the
+ * messages.
*
- * @ingroup charon
- */
-#define IKEV2_UDP_PORT 500
-
-/**
- * UDP Port to which the daemon will float to if NAT is detected.
- *
- * @ingroup charon
- */
-#define IKEV2_NATT_PORT 4500
-
-/**
- * PID file, in which charon stores its process id
+ * The CHILD_SA contains state about a IPsec security association and manages
+ * them. An IKE_SA may have multiple CHILD_SAs. Communication to the kernel
+ * takes place here through the kernel interface.
*
- * @ingroup charon
- */
-#define PID_FILE IPSEC_PIDDIR "/charon.pid"
-
-/**
- * Configuration directory
+ * The kernel interface installs IPsec security associations, policies, routes
+ * and virtual addresses. It further provides methods to enumerate interfaces
+ * and may notify the daemon about state changes at lower layers.
*
- * @ingroup charon
+ * The bus receives signals from the different threads and relais them to interested
+ * listeners. Debugging signals, but also important state changes or error
+ * messages are sent over the bus.
+ * It's listeners are not only for logging, but also to track the state of an
+ * IKE_SA.
+ *
+ * The controller, credential_manager, bus and backend_manager (config) are
+ * places where a plugin ca register itself to privide information or observe
+ * and control the daemon.
*/
-#define CONFIG_DIR IPSEC_CONFDIR
-/**
- * Directory of IPsec relevant files
- *
- * @ingroup charon
- */
-#define IPSEC_D_DIR CONFIG_DIR "/ipsec.d"
+#ifndef DAEMON_H_
+#define DAEMON_H_
-/**
- * Default directory for private keys
- *
- * @ingroup charon
- */
-#define PRIVATE_KEY_DIR IPSEC_D_DIR "/private"
+typedef struct daemon_t daemon_t;
-/**
- * Default directory for end entity certificates
- *
- * @ingroup charon
- */
-#define CERTIFICATE_DIR IPSEC_D_DIR "/certs"
+#include <network/sender.h>
+#include <network/receiver.h>
+#include <network/socket.h>
+#include <processing/scheduler.h>
+#include <processing/processor.h>
+#include <kernel/kernel_interface.h>
+#include <control/controller.h>
+#include <bus/bus.h>
+#include <bus/listeners/file_logger.h>
+#include <bus/listeners/sys_logger.h>
+#include <sa/ike_sa_manager.h>
+#include <config/backend_manager.h>
+#include <config/attributes/attribute_manager.h>
+#include <credentials/credential_manager.h>
+#include <sa/authenticators/eap/eap_manager.h>
-/**
- * Default directory for trusted Certification Authority certificates
- *
- * @ingroup charon
- */
-#define CA_CERTIFICATE_DIR IPSEC_D_DIR "/cacerts"
+#ifdef ME
+#include <sa/connect_manager.h>
+#include <sa/mediation_manager.h>
+#endif /* ME */
/**
- * Default directory for Authorization Authority certificates
- *
- * @ingroup charon
+ * Name of the daemon.
*/
-#define AA_CERTIFICATE_DIR IPSEC_D_DIR "/aacerts"
+#define DAEMON_NAME "charon"
/**
- * Default directory for Attribute certificates
- *
- * @ingroup charon
+ * Number of threads in the thread pool, if not specified in config.
*/
-#define ATTR_CERTIFICATE_DIR IPSEC_D_DIR "/acerts"
+#define DEFAULT_THREADS 16
/**
- * Default directory for OCSP signing certificates
- *
- * @ingroup charon
+ * UDP Port on which the daemon will listen for incoming traffic.
*/
-#define OCSP_CERTIFICATE_DIR IPSEC_D_DIR "/ocspcerts"
+#define IKEV2_UDP_PORT 500
/**
- * Default directory for CRLs
- *
- * @ingroup charon
+ * UDP Port to which the daemon will float to if NAT is detected.
*/
-#define CRL_DIR IPSEC_D_DIR "/crls"
+#define IKEV2_NATT_PORT 4500
/**
- * Secrets files
- *
- * @ingroup charon
+ * PID file, in which charon stores its process id
*/
-#define SECRETS_FILE CONFIG_DIR "/ipsec.secrets"
+#define PID_FILE IPSEC_PIDDIR "/charon.pid"
+
/**
- * @brief Main class of daemon, contains some globals.
- *
- * @ingroup charon
+ * Main class of daemon, contains some globals.
*/
struct daemon_t {
@@ -379,9 +216,14 @@ struct daemon_t {
backend_manager_t *backends;
/**
- * A credential_store_t instance.
+ * Manager IKEv2 cfg payload attributes
+ */
+ attribute_manager_t *attributes;
+
+ /**
+ * Manager for the credential backends
*/
- credential_store_t *credentials;
+ credential_manager_t *credentials;
/**
* The Sender-Thread.
@@ -429,11 +271,16 @@ struct daemon_t {
kernel_interface_t *kernel_interface;
/**
- * Interfaces for IPC
+ * Controller to control the daemon
*/
- interface_manager_t *interfaces;
+ controller_t *controller;
-#ifdef P2P
+ /**
+ * EAP manager to maintain registered EAP methods
+ */
+ eap_manager_t *eap;
+
+#ifdef ME
/**
* Connect manager
*/
@@ -443,12 +290,21 @@ struct daemon_t {
* Mediation manager
*/
mediation_manager_t *mediation_manager;
-#endif /* P2P */
+#endif /* ME */
+
+ /**
+ * User ID the daemon will user after initialization
+ */
+ uid_t uid;
+
+ /**
+ * Group ID the daemon will use after initialization
+ */
+ gid_t gid;
/**
- * @brief Shut down the daemon.
+ * Shut down the daemon.
*
- * @param this the daemon to kill
* @param reason describtion why it will be killed
*/
void (*kill) (daemon_t *this, char *reason);
@@ -459,4 +315,4 @@ struct daemon_t {
*/
extern daemon_t *charon;
-#endif /*DAEMON_H_*/
+#endif /*DAEMON_H_ @} */
diff --git a/src/charon/encoding/generator.c b/src/charon/encoding/generator.c
index efa845bb3..3b68af84e 100644
--- a/src/charon/encoding/generator.c
+++ b/src/charon/encoding/generator.c
@@ -1,10 +1,3 @@
-/**
- * @file generator.c
- *
- * @brief Implementation of generator_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: generator.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdlib.h>
diff --git a/src/charon/encoding/generator.h b/src/charon/encoding/generator.h
index 8eff957cc..b6f2af2cb 100644
--- a/src/charon/encoding/generator.h
+++ b/src/charon/encoding/generator.h
@@ -1,10 +1,3 @@
-/**
- * @file generator.h
- *
- * @brief Interface of generator_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: generator.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup generator generator
+ * @{ @ingroup encoding
*/
#ifndef GENERATOR_H_
@@ -33,21 +33,17 @@ typedef struct generator_t generator_t;
/**
* Generating is done in a data buffer.
* This is thehe start size of this buffer in bytes.
- *
- * @ingroup enconding
*/
#define GENERATOR_DATA_BUFFER_SIZE 500
/**
* Number of bytes to increase the buffer, if it is to small.
- *
- * @ingroup enconding
*/
#define GENERATOR_DATA_BUFFER_INCREASE_VALUE 500
/**
- * @brief A generator_t class used to generate IKEv2 payloads.
+ * A generator_t class used to generate IKEv2 payloads.
*
* After creation, multiple payloads can be generated with the generate_payload
* method. The generated bytes are appended. After all payloads are added,
@@ -56,47 +52,36 @@ typedef struct generator_t generator_t;
* The generater uses a set of encoding rules, which it can get from
* the supplied payload. With this rules, the generater can generate
* the payload and all substructures automatically.
- *
- * @b Constructor:
- * - generator_create()
- *
- * @ingroup encoding
*/
struct generator_t {
/**
- * @brief Generates a specific payload from given payload object.
+ * Generates a specific payload from given payload object.
*
* Remember: Header and substructures are also handled as payloads.
*
- * @param this generator_t object
- * @param[in] payload interface payload_t implementing object
+ * @param payload interface payload_t implementing object
*/
void (*generate_payload) (generator_t *this,payload_t *payload);
/**
- * @brief Writes all generated data of the generator to a chunk.
+ * Writes all generated data of the generator to a chunk.
*
- * @param this generator_t object
- * @param[out] data chunk to write the data to
+ * @param data chunk to write the data to
*/
void (*write_to_chunk) (generator_t *this,chunk_t *data);
/**
- * @brief Destroys a generator_t object.
- *
- * @param this generator_t object
+ * Destroys a generator_t object.
*/
void (*destroy) (generator_t *this);
};
/**
- * @brief Constructor to create a generator.
+ * Constructor to create a generator.
*
* @return generator_t object.
- *
- * @ingroup encoding
*/
generator_t *generator_create(void);
-#endif /*GENERATOR_H_*/
+#endif /*GENERATOR_H_ @} */
diff --git a/src/charon/encoding/message.c b/src/charon/encoding/message.c
index 3dfa64fb9..af9483192 100644
--- a/src/charon/encoding/message.c
+++ b/src/charon/encoding/message.c
@@ -1,10 +1,3 @@
-/**
- * @file message.c
- *
- * @brief Implementation of message_t.
- *
- */
-
/*
* Copyright (C) 2006-2007 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
@@ -21,6 +14,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: message.c 3991 2008-05-21 17:56:21Z martin $
*/
#include <stdlib.h>
@@ -82,13 +77,31 @@ struct payload_rule_t {
bool sufficient;
};
+typedef struct payload_order_t payload_order_t;
+
+/**
+ * payload ordering structure allows us to reorder payloads according to RFC.
+ */
+struct payload_order_t {
+
+ /**
+ * payload type
+ */
+ payload_type_t type;
+
+ /**
+ * notify type, if payload == NOTIFY
+ */
+ notify_type_t notify;
+};
+
+
typedef struct message_rule_t message_rule_t;
/**
* A message rule defines the kind of a message,
* if it has encrypted contents and a list
- * of payload rules.
- *
+ * of payload ordering rules and payload parsing rules.
*/
struct message_rule_t {
/**
@@ -109,161 +122,398 @@ struct message_rule_t {
/**
* Number of payload rules which will follow
*/
- size_t payload_rule_count;
+ int payload_rule_count;
/**
* Pointer to first payload rule
*/
payload_rule_t *payload_rules;
+
+ /**
+ * Number of payload order rules
+ */
+ int payload_order_count;
+
+ /**
+ * payload ordering rules
+ */
+ payload_order_t *payload_order;
};
/**
* Message rule for IKE_SA_INIT from initiator.
*/
static payload_rule_t ike_sa_init_i_payload_rules[] = {
- {NOTIFY,0,MAX_NOTIFY_PAYLOADS,FALSE,FALSE},
- {SECURITY_ASSOCIATION,1,1,FALSE,FALSE},
- {KEY_EXCHANGE,1,1,FALSE,FALSE},
- {NONCE,1,1,FALSE,FALSE},
- {VENDOR_ID,0,10,FALSE,FALSE},
+/* payload type min max encr suff */
+ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, FALSE, FALSE},
+ {SECURITY_ASSOCIATION, 1, 1, FALSE, FALSE},
+ {KEY_EXCHANGE, 1, 1, FALSE, FALSE},
+ {NONCE, 1, 1, FALSE, FALSE},
+ {VENDOR_ID, 0, 10, FALSE, FALSE},
+};
+
+/**
+ * payload order for IKE_SA_INIT initiator
+ */
+static payload_order_t ike_sa_init_i_payload_order[] = {
+/* payload type notify type */
+ {NOTIFY, COOKIE},
+ {SECURITY_ASSOCIATION, 0},
+ {KEY_EXCHANGE, 0},
+ {NONCE, 0},
+ {NOTIFY, NAT_DETECTION_SOURCE_IP},
+ {NOTIFY, NAT_DETECTION_DESTINATION_IP},
+ {NOTIFY, 0},
+ {VENDOR_ID, 0},
};
/**
* Message rule for IKE_SA_INIT from responder.
*/
static payload_rule_t ike_sa_init_r_payload_rules[] = {
- {NOTIFY,0,MAX_NOTIFY_PAYLOADS,FALSE,TRUE},
- {SECURITY_ASSOCIATION,1,1,FALSE,FALSE},
- {KEY_EXCHANGE,1,1,FALSE,FALSE},
- {NONCE,1,1,FALSE,FALSE},
- {VENDOR_ID,0,10,FALSE,FALSE},
+/* payload type min max encr suff */
+ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, FALSE, TRUE},
+ {SECURITY_ASSOCIATION, 1, 1, FALSE, FALSE},
+ {KEY_EXCHANGE, 1, 1, FALSE, FALSE},
+ {NONCE, 1, 1, FALSE, FALSE},
+ {VENDOR_ID, 0, 10, FALSE, FALSE},
+};
+
+/**
+ * payload order for IKE_SA_INIT responder
+ */
+static payload_order_t ike_sa_init_r_payload_order[] = {
+/* payload type notify type */
+ {SECURITY_ASSOCIATION, 0},
+ {KEY_EXCHANGE, 0},
+ {NONCE, 0},
+ {NOTIFY, NAT_DETECTION_SOURCE_IP},
+ {NOTIFY, NAT_DETECTION_DESTINATION_IP},
+ {NOTIFY, HTTP_CERT_LOOKUP_SUPPORTED},
+ {CERTIFICATE_REQUEST, 0},
+ {NOTIFY, 0},
+ {VENDOR_ID, 0},
};
/**
* Message rule for IKE_AUTH from initiator.
*/
static payload_rule_t ike_auth_i_payload_rules[] = {
- {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
- {EXTENSIBLE_AUTHENTICATION,0,1,TRUE,TRUE},
- {AUTHENTICATION,0,1,TRUE,TRUE},
- {ID_INITIATOR,1,1,TRUE,FALSE},
- {CERTIFICATE,0,1,TRUE,FALSE},
- {CERTIFICATE_REQUEST,0,1,TRUE,FALSE},
- {ID_RESPONDER,0,1,TRUE,FALSE},
-#ifdef P2P
- {SECURITY_ASSOCIATION,0,1,TRUE,FALSE},
- {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE},
- {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE},
+/* payload type min max encr suff */
+ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
+ {EXTENSIBLE_AUTHENTICATION, 0, 1, TRUE, TRUE},
+ {AUTHENTICATION, 0, 1, TRUE, TRUE},
+ {ID_INITIATOR, 1, 1, TRUE, FALSE},
+ {CERTIFICATE, 0, 4, TRUE, FALSE},
+ {CERTIFICATE_REQUEST, 0, 1, TRUE, FALSE},
+ {ID_RESPONDER, 0, 1, TRUE, FALSE},
+#ifdef ME
+ {SECURITY_ASSOCIATION, 0, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_INITIATOR, 0, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_RESPONDER, 0, 1, TRUE, FALSE},
#else
- {SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
- {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE,FALSE},
- {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE,FALSE},
-#endif /* P2P */
- {CONFIGURATION,0,1,TRUE,FALSE},
- {VENDOR_ID,0,10,TRUE,FALSE},
+ {SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_INITIATOR, 1, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_RESPONDER, 1, 1, TRUE, FALSE},
+#endif /* ME */
+ {CONFIGURATION, 0, 1, TRUE, FALSE},
+ {VENDOR_ID, 0, 10, TRUE, FALSE},
+};
+
+/**
+ * payload order for IKE_AUTH initiator
+ */
+static payload_order_t ike_auth_i_payload_order[] = {
+/* payload type notify type */
+ {ID_INITIATOR, 0},
+ {CERTIFICATE, 0},
+ {NOTIFY, INITIAL_CONTACT},
+ {NOTIFY, HTTP_CERT_LOOKUP_SUPPORTED},
+ {CERTIFICATE_REQUEST, 0},
+ {ID_RESPONDER, 0},
+ {AUTHENTICATION, 0},
+ {EXTENSIBLE_AUTHENTICATION, 0},
+ {CONFIGURATION, 0},
+ {NOTIFY, IPCOMP_SUPPORTED},
+ {NOTIFY, USE_TRANSPORT_MODE},
+ {NOTIFY, ESP_TFC_PADDING_NOT_SUPPORTED},
+ {NOTIFY, NON_FIRST_FRAGMENTS_ALSO},
+ {SECURITY_ASSOCIATION, 0},
+ {TRAFFIC_SELECTOR_INITIATOR, 0},
+ {TRAFFIC_SELECTOR_RESPONDER, 0},
+ {NOTIFY, MOBIKE_SUPPORTED},
+ {NOTIFY, ADDITIONAL_IP4_ADDRESS},
+ {NOTIFY, ADDITIONAL_IP6_ADDRESS},
+ {NOTIFY, NO_ADDITIONAL_ADDRESSES},
+ {NOTIFY, 0},
+ {VENDOR_ID, 0},
};
/**
* Message rule for IKE_AUTH from responder.
*/
static payload_rule_t ike_auth_r_payload_rules[] = {
- {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
- {EXTENSIBLE_AUTHENTICATION,0,1,TRUE,TRUE},
- {CERTIFICATE,0,1,TRUE,FALSE},
- {ID_RESPONDER,0,1,TRUE,FALSE},
- {AUTHENTICATION,0,1,TRUE,FALSE},
- {SECURITY_ASSOCIATION,0,1,TRUE,FALSE},
- {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE},
- {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE},
- {CONFIGURATION,0,1,TRUE,FALSE},
- {VENDOR_ID,0,10,TRUE,FALSE},
+/* payload type min max encr suff */
+ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE},
+ {EXTENSIBLE_AUTHENTICATION, 0, 1, TRUE, TRUE},
+ {CERTIFICATE, 0, 4, TRUE, FALSE},
+ {ID_RESPONDER, 0, 1, TRUE, FALSE},
+ {AUTHENTICATION, 0, 1, TRUE, FALSE},
+ {SECURITY_ASSOCIATION, 0, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_INITIATOR, 0, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_RESPONDER, 0, 1, TRUE, FALSE},
+ {CONFIGURATION, 0, 1, TRUE, FALSE},
+ {VENDOR_ID, 0, 10, TRUE, FALSE},
};
+/**
+ * payload order for IKE_AUTH responder
+ */
+static payload_order_t ike_auth_r_payload_order[] = {
+/* payload type notify type */
+ {ID_RESPONDER, 0},
+ {CERTIFICATE, 0},
+ {AUTHENTICATION, 0},
+ {EXTENSIBLE_AUTHENTICATION, 0},
+ {CONFIGURATION, 0},
+ {NOTIFY, IPCOMP_SUPPORTED},
+ {NOTIFY, USE_TRANSPORT_MODE},
+ {NOTIFY, ESP_TFC_PADDING_NOT_SUPPORTED},
+ {NOTIFY, NON_FIRST_FRAGMENTS_ALSO},
+ {SECURITY_ASSOCIATION, 0},
+ {TRAFFIC_SELECTOR_INITIATOR, 0},
+ {TRAFFIC_SELECTOR_RESPONDER, 0},
+ {NOTIFY, AUTH_LIFETIME},
+ {NOTIFY, MOBIKE_SUPPORTED},
+ {NOTIFY, ADDITIONAL_IP4_ADDRESS},
+ {NOTIFY, ADDITIONAL_IP6_ADDRESS},
+ {NOTIFY, NO_ADDITIONAL_ADDRESSES},
+ {NOTIFY, 0},
+ {VENDOR_ID, 0},
+};
/**
* Message rule for INFORMATIONAL from initiator.
*/
static payload_rule_t informational_i_payload_rules[] = {
- {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
- {CONFIGURATION,0,1,TRUE,FALSE},
- {DELETE,0,1,TRUE,FALSE},
- {VENDOR_ID,0,10,TRUE,FALSE},
-
+/* payload type min max encr suff */
+ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
+ {CONFIGURATION, 0, 1, TRUE, FALSE},
+ {DELETE, 0, 1, TRUE, FALSE},
+ {VENDOR_ID, 0, 10, TRUE, FALSE},
+};
+
+/**
+ * payload order for INFORMATIONAL initiator
+ */
+static payload_order_t informational_i_payload_order[] = {
+/* payload type notify type */
+ {NOTIFY, UPDATE_SA_ADDRESSES},
+ {NOTIFY, NAT_DETECTION_SOURCE_IP},
+ {NOTIFY, NAT_DETECTION_DESTINATION_IP},
+ {NOTIFY, COOKIE2},
+ {NOTIFY, 0},
+ {DELETE, 0},
+ {CONFIGURATION, 0},
};
/**
* Message rule for INFORMATIONAL from responder.
*/
static payload_rule_t informational_r_payload_rules[] = {
- {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
- {CONFIGURATION,0,1,TRUE,FALSE},
- {DELETE,0,1,TRUE,FALSE},
- {VENDOR_ID,0,10,TRUE,FALSE},
+/* payload type min max encr suff */
+ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
+ {CONFIGURATION, 0, 1, TRUE, FALSE},
+ {DELETE, 0, 1, TRUE, FALSE},
+ {VENDOR_ID, 0, 10, TRUE, FALSE},
+};
+
+/**
+ * payload order for INFORMATIONAL responder
+ */
+static payload_order_t informational_r_payload_order[] = {
+/* payload type notify type */
+ {NOTIFY, UPDATE_SA_ADDRESSES},
+ {NOTIFY, NAT_DETECTION_SOURCE_IP},
+ {NOTIFY, NAT_DETECTION_DESTINATION_IP},
+ {NOTIFY, COOKIE2},
+ {NOTIFY, 0},
+ {DELETE, 0},
+ {CONFIGURATION, 0},
};
/**
* Message rule for CREATE_CHILD_SA from initiator.
*/
static payload_rule_t create_child_sa_i_payload_rules[] = {
- {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
- {SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
- {NONCE,1,1,TRUE,FALSE},
- {KEY_EXCHANGE,0,1,TRUE,FALSE},
- {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE},
- {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE},
- {CONFIGURATION,0,1,TRUE,FALSE},
- {VENDOR_ID,0,10,TRUE,FALSE},
+/* payload type min max encr suff */
+ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
+ {SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE},
+ {NONCE, 1, 1, TRUE, FALSE},
+ {KEY_EXCHANGE, 0, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_INITIATOR, 0, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_RESPONDER, 0, 1, TRUE, FALSE},
+ {CONFIGURATION, 0, 1, TRUE, FALSE},
+ {VENDOR_ID, 0, 10, TRUE, FALSE},
+};
+
+/**
+ * payload order for CREATE_CHILD_SA from initiator.
+ */
+static payload_order_t create_child_sa_i_payload_order[] = {
+/* payload type notify type */
+ {NOTIFY, REKEY_SA},
+ {NOTIFY, IPCOMP_SUPPORTED},
+ {NOTIFY, USE_TRANSPORT_MODE},
+ {NOTIFY, ESP_TFC_PADDING_NOT_SUPPORTED},
+ {NOTIFY, NON_FIRST_FRAGMENTS_ALSO},
+ {SECURITY_ASSOCIATION, 0},
+ {NONCE, 0},
+ {KEY_EXCHANGE, 0},
+ {TRAFFIC_SELECTOR_INITIATOR, 0},
+ {TRAFFIC_SELECTOR_RESPONDER, 0},
+ {NOTIFY, 0},
};
/**
* Message rule for CREATE_CHILD_SA from responder.
*/
static payload_rule_t create_child_sa_r_payload_rules[] = {
- {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
- {SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
- {NONCE,1,1,TRUE,FALSE},
- {KEY_EXCHANGE,0,1,TRUE,FALSE},
- {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE},
- {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE},
- {CONFIGURATION,0,1,TRUE,FALSE},
- {VENDOR_ID,0,10,TRUE,FALSE},
+/* payload type min max encr suff */
+ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE},
+ {SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE},
+ {NONCE, 1, 1, TRUE, FALSE},
+ {KEY_EXCHANGE, 0, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_INITIATOR, 0, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_RESPONDER, 0, 1, TRUE, FALSE},
+ {CONFIGURATION, 0, 1, TRUE, FALSE},
+ {VENDOR_ID, 0, 10, TRUE, FALSE},
};
-#ifdef P2P
/**
- * Message rule for P2P_CONNECT from initiator.
+ * payload order for CREATE_CHILD_SA from responder.
*/
-static payload_rule_t p2p_connect_i_payload_rules[] = {
- {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
- {ID_PEER,1,1,TRUE,FALSE},
- {VENDOR_ID,0,10,TRUE,FALSE}
+static payload_order_t create_child_sa_r_payload_order[] = {
+/* payload type notify type */
+ {NOTIFY, IPCOMP_SUPPORTED},
+ {NOTIFY, USE_TRANSPORT_MODE},
+ {NOTIFY, ESP_TFC_PADDING_NOT_SUPPORTED},
+ {NOTIFY, NON_FIRST_FRAGMENTS_ALSO},
+ {SECURITY_ASSOCIATION, 0},
+ {NONCE, 0},
+ {KEY_EXCHANGE, 0},
+ {TRAFFIC_SELECTOR_INITIATOR, 0},
+ {TRAFFIC_SELECTOR_RESPONDER, 0},
+ {NOTIFY, ADDITIONAL_TS_POSSIBLE},
+ {NOTIFY, 0},
};
+#ifdef ME
/**
- * Message rule for P2P_CONNECT from responder.
+ * Message rule for ME_CONNECT from initiator.
*/
-static payload_rule_t p2p_connect_r_payload_rules[] = {
- {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
- {VENDOR_ID,0,10,TRUE,FALSE}
+static payload_rule_t me_connect_i_payload_rules[] = {
+/* payload type min max encr suff */
+ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE},
+ {ID_PEER, 1, 1, TRUE, FALSE},
+ {VENDOR_ID, 0, 10, TRUE, FALSE}
};
-#endif /* P2P */
+
+/**
+ * payload order for ME_CONNECT from initiator.
+ */
+static payload_order_t me_connect_i_payload_order[] = {
+/* payload type notify type */
+ {NOTIFY, 0},
+ {ID_PEER, 0},
+ {VENDOR_ID, 0},
+};
+
+/**
+ * Message rule for ME_CONNECT from responder.
+ */
+static payload_rule_t me_connect_r_payload_rules[] = {
+/* payload type min max encr suff */
+ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE},
+ {VENDOR_ID, 0, 10, TRUE, FALSE}
+};
+
+/**
+ * payload order for ME_CONNECT from responder.
+ */
+static payload_order_t me_connect_r_payload_order[] = {
+/* payload type notify type */
+ {NOTIFY, 0},
+ {VENDOR_ID, 0},
+};
+#endif /* ME */
/**
* Message rules, defines allowed payloads.
*/
static message_rule_t message_rules[] = {
- {IKE_SA_INIT,TRUE,FALSE,(sizeof(ike_sa_init_i_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_i_payload_rules},
- {IKE_SA_INIT,FALSE,FALSE,(sizeof(ike_sa_init_r_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_r_payload_rules},
- {IKE_AUTH,TRUE,TRUE,(sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)),ike_auth_i_payload_rules},
- {IKE_AUTH,FALSE,TRUE,(sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)),ike_auth_r_payload_rules},
- {INFORMATIONAL,TRUE,TRUE,(sizeof(informational_i_payload_rules)/sizeof(payload_rule_t)),informational_i_payload_rules},
- {INFORMATIONAL,FALSE,TRUE,(sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)),informational_r_payload_rules},
- {CREATE_CHILD_SA,TRUE,TRUE,(sizeof(create_child_sa_i_payload_rules)/sizeof(payload_rule_t)),create_child_sa_i_payload_rules},
- {CREATE_CHILD_SA,FALSE,TRUE,(sizeof(create_child_sa_r_payload_rules)/sizeof(payload_rule_t)),create_child_sa_r_payload_rules},
-#ifdef P2P
- {P2P_CONNECT,TRUE,TRUE,(sizeof(p2p_connect_i_payload_rules)/sizeof(payload_rule_t)),p2p_connect_i_payload_rules},
- {P2P_CONNECT,FALSE,TRUE,(sizeof(p2p_connect_r_payload_rules)/sizeof(payload_rule_t)),p2p_connect_r_payload_rules},
-#endif /* P2P */
+ {IKE_SA_INIT, TRUE, FALSE,
+ (sizeof(ike_sa_init_i_payload_rules)/sizeof(payload_rule_t)),
+ ike_sa_init_i_payload_rules,
+ (sizeof(ike_sa_init_i_payload_order)/sizeof(payload_order_t)),
+ ike_sa_init_i_payload_order,
+ },
+ {IKE_SA_INIT, FALSE, FALSE,
+ (sizeof(ike_sa_init_r_payload_rules)/sizeof(payload_rule_t)),
+ ike_sa_init_r_payload_rules,
+ (sizeof(ike_sa_init_r_payload_order)/sizeof(payload_order_t)),
+ ike_sa_init_r_payload_order,
+ },
+ {IKE_AUTH, TRUE, TRUE,
+ (sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)),
+ ike_auth_i_payload_rules,
+ (sizeof(ike_auth_i_payload_order)/sizeof(payload_order_t)),
+ ike_auth_i_payload_order,
+ },
+ {IKE_AUTH, FALSE, TRUE,
+ (sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)),
+ ike_auth_r_payload_rules,
+ (sizeof(ike_auth_r_payload_order)/sizeof(payload_order_t)),
+ ike_auth_r_payload_order,
+ },
+ {INFORMATIONAL, TRUE, TRUE,
+ (sizeof(informational_i_payload_rules)/sizeof(payload_rule_t)),
+ informational_i_payload_rules,
+ (sizeof(informational_i_payload_order)/sizeof(payload_order_t)),
+ informational_i_payload_order,
+ },
+ {INFORMATIONAL, FALSE, TRUE,
+ (sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)),
+ informational_r_payload_rules,
+ (sizeof(informational_r_payload_order)/sizeof(payload_order_t)),
+ informational_r_payload_order,
+ },
+ {CREATE_CHILD_SA, TRUE, TRUE,
+ (sizeof(create_child_sa_i_payload_rules)/sizeof(payload_rule_t)),
+ create_child_sa_i_payload_rules,
+ (sizeof(create_child_sa_i_payload_order)/sizeof(payload_order_t)),
+ create_child_sa_i_payload_order,
+ },
+ {CREATE_CHILD_SA, FALSE, TRUE,
+ (sizeof(create_child_sa_r_payload_rules)/sizeof(payload_rule_t)),
+ create_child_sa_r_payload_rules,
+ (sizeof(create_child_sa_r_payload_order)/sizeof(payload_order_t)),
+ create_child_sa_r_payload_order,
+ },
+#ifdef ME
+ {ME_CONNECT, TRUE, TRUE,
+ (sizeof(me_connect_i_payload_rules)/sizeof(payload_rule_t)),
+ me_connect_i_payload_rules,
+ (sizeof(me_connect_i_payload_order)/sizeof(payload_order_t)),
+ me_connect_i_payload_order,
+ },
+ {ME_CONNECT, FALSE, TRUE,
+ (sizeof(me_connect_r_payload_rules)/sizeof(payload_rule_t)),
+ me_connect_r_payload_rules,
+ (sizeof(me_connect_r_payload_order)/sizeof(payload_order_t)),
+ me_connect_r_payload_order,
+ },
+#endif /* ME */
};
@@ -517,38 +767,19 @@ static bool is_encoded(private_message_t *this)
*/
static void add_payload(private_message_t *this, payload_t *payload)
{
- payload_t *last_payload, *first_payload;
-
- if ((this->is_request && payload->get_type(payload) == ID_INITIATOR) ||
- (!this->is_request && payload->get_type(payload) == ID_RESPONDER))
+ payload_t *last_payload;
+
+ if (this->payloads->get_count(this->payloads) > 0)
{
- /* HOTD: insert ID payload in the beginning to respect RFC */
- if (this->payloads->get_first(this->payloads,
- (void **)&first_payload) == SUCCESS)
- {
- payload->set_next_type(payload, first_payload->get_type(first_payload));
- }
- else
- {
- payload->set_next_type(payload, NO_PAYLOAD);
- }
- this->first_payload = payload->get_type(payload);
- this->payloads->insert_first(this->payloads, payload);
+ this->payloads->get_last(this->payloads, (void **)&last_payload);
+ last_payload->set_next_type(last_payload, payload->get_type(payload));
}
else
{
- if (this->payloads->get_count(this->payloads) > 0)
- {
- this->payloads->get_last(this->payloads,(void **) &last_payload);
- last_payload->set_next_type(last_payload, payload->get_type(payload));
- }
- else
- {
- this->first_payload = payload->get_type(payload);
- }
- payload->set_next_type(payload, NO_PAYLOAD);
- this->payloads->insert_last(this->payloads, payload);
+ this->first_payload = payload->get_type(payload);
}
+ payload->set_next_type(payload, NO_PAYLOAD);
+ this->payloads->insert_last(this->payloads, payload);
DBG2(DBG_ENC ,"added payload of type %N to message",
payload_type_names, payload->get_type(payload));
@@ -694,9 +925,65 @@ static char* get_string(private_message_t *this, char *buf, int len)
}
/**
+ * reorder payloads depending on reordering rules
+ */
+static void order_payloads(private_message_t *this)
+{
+ linked_list_t *list;
+ payload_t *payload;
+ int i;
+
+ /* move to temp list */
+ list = linked_list_create();
+ while (this->payloads->remove_last(this->payloads,
+ (void**)&payload) == SUCCESS)
+ {
+ list->insert_first(list, payload);
+ }
+ /* for each rule, ... */
+ for (i = 0; i < this->message_rule->payload_order_count; i++)
+ {
+ enumerator_t *enumerator;
+ notify_payload_t *notify;
+ payload_order_t order = this->message_rule->payload_order[i];
+
+ /* ... find all payload ... */
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &payload))
+ {
+ /* ... with that type ... */
+ if (payload->get_type(payload) == order.type)
+ {
+ notify = (notify_payload_t*)payload;
+
+ /**... and check notify for type. */
+ if (order.type != NOTIFY || order.notify == 0 ||
+ order.notify == notify->get_notify_type(notify))
+ {
+ list->remove_at(list, enumerator);
+ add_payload(this, payload);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ /* append all payloads without a rule to the end */
+ while (list->remove_last(list, (void**)&payload) == SUCCESS)
+ {
+ DBG1(DBG_ENC, "payload %N has no ordering rule in %N %s",
+ payload_type_names, payload->get_type(payload),
+ exchange_type_names, this->message_rule->exchange_type,
+ this->message_rule->is_request ? "request" : "response");
+ add_payload(this, payload);
+ }
+ list->destroy(list);
+}
+
+/**
* Implementation of private_message_t.encrypt_payloads.
*/
-static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, signer_t* signer)
+static status_t encrypt_payloads(private_message_t *this,
+ crypter_t *crypter, signer_t* signer)
{
encryption_payload_t *encryption_payload = NULL;
status_t status;
@@ -778,7 +1065,8 @@ static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, si
/**
* Implementation of message_t.generate.
*/
-static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* signer, packet_t **packet)
+static status_t generate(private_message_t *this, crypter_t *crypter,
+ signer_t* signer, packet_t **packet)
{
generator_t *generator;
ike_header_t *ike_header;
@@ -795,8 +1083,6 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
return SUCCESS;
}
- DBG1(DBG_ENC, "generating %s", get_string(this, str, sizeof(str)));
-
if (this->exchange_type == EXCHANGE_TYPE_UNDEFINED)
{
DBG1(DBG_ENC, "exchange type is not defined");
@@ -819,6 +1105,10 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
return NOT_SUPPORTED;
}
+ order_payloads(this);
+
+ DBG1(DBG_ENC, "generating %s", get_string(this, str, sizeof(str)));
+
/* going to encrypt all content which have to be encrypted */
status = encrypt_payloads(this, crypter, signer);
if (status != SUCCESS)
@@ -842,7 +1132,7 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
payload = (payload_t*)ike_header;
- /* generate every payload expect last one, this is doen later*/
+ /* generate every payload expect last one, this is done later*/
iterator = this->payloads->create_iterator(this->payloads, TRUE);
while(iterator->iterate(iterator, (void**)&next_payload))
{
@@ -1346,3 +1636,4 @@ message_t *message_create()
{
return message_create_from_packet(NULL);
}
+
diff --git a/src/charon/encoding/message.h b/src/charon/encoding/message.h
index 35b659f33..8cc604ea7 100644
--- a/src/charon/encoding/message.h
+++ b/src/charon/encoding/message.h
@@ -1,10 +1,3 @@
-/**
- * @file message.h
- *
- * @brief Interface of message_t.
- *
- */
-
/*
* Copyright (C) 2006-2007 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
@@ -21,6 +14,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: message.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup message message
+ * @{ @ingroup encoding
*/
#ifndef MESSAGE_H_
@@ -38,148 +38,126 @@ typedef struct message_t message_t;
#include <crypto/signers/signer.h>
/**
- * @brief This class is used to represent an IKEv2-Message.
+ * This class is used to represent an IKEv2-Message.
*
* The message handles parsing and generation of payloads
* via parser_t/generator_t. Encryption is done transparently
* via the encryption_payload_t. A set of rules for messages
* and payloads does check parsed messages.
- *
- * @b Constructors:
- * - message_create()
- * - message_create_from_packet()
- * - message_create_notify_reply()
- *
- * @ingroup encoding
*/
struct message_t {
/**
- * @brief Sets the IKE major version of the message.
+ * Sets the IKE major version of the message.
*
- * @param this message_t object
* @param major_version major version to set
*/
void (*set_major_version) (message_t *this,u_int8_t major_version);
/**
- * @brief Gets the IKE major version of the message.
+ * Gets the IKE major version of the message.
*
- * @param this message_t object
* @return major version of the message
*/
u_int8_t (*get_major_version) (message_t *this);
/**
- * @brief Sets the IKE minor version of the message.
+ * Sets the IKE minor version of the message.
*
- * @param this message_t object
* @param minor_version minor version to set
*/
void (*set_minor_version) (message_t *this,u_int8_t minor_version);
/**
- * @brief Gets the IKE minor version of the message.
+ * Gets the IKE minor version of the message.
*
- * @param this message_t object
* @return minor version of the message
*/
u_int8_t (*get_minor_version) (message_t *this);
/**
- * @brief Sets the Message ID of the message.
+ * Sets the Message ID of the message.
*
- * @param this message_t object
- * @param message_id message_id to set
+ * @param message_id message_id to set
*/
void (*set_message_id) (message_t *this,u_int32_t message_id);
/**
- * @brief Gets the Message ID of the message.
+ * Gets the Message ID of the message.
*
- * @param this message_t object
* @return message_id type of the message
*/
u_int32_t (*get_message_id) (message_t *this);
/**
- * @brief Gets the initiator SPI of the message.
+ * Gets the initiator SPI of the message.
*
- * @param this message_t object
* @return initiator spi of the message
*/
u_int64_t (*get_initiator_spi) (message_t *this);
/**
- * @brief Gets the responder SPI of the message.
+ * Gets the responder SPI of the message.
*
- * @param this message_t object
* @return responder spi of the message
*/
u_int64_t (*get_responder_spi) (message_t *this);
/**
- * @brief Sets the IKE_SA ID of the message.
+ * Sets the IKE_SA ID of the message.
*
* ike_sa_id gets cloned.
*
- * @param this message_t object
* @param ike_sa_id ike_sa_id to set
*/
void (*set_ike_sa_id) (message_t *this, ike_sa_id_t * ike_sa_id);
/**
- * @brief Gets the IKE_SA ID of the message.
+ * Gets the IKE_SA ID of the message.
*
* The ike_sa_id points to the message internal id, do not modify.
*
- * @param this message_t object
* @return ike_sa_id of message
*/
ike_sa_id_t *(*get_ike_sa_id) (message_t *this);
/**
- * @brief Sets the exchange type of the message.
+ * Sets the exchange type of the message.
*
- * @param this message_t object
* @param exchange_type exchange_type to set
*/
void (*set_exchange_type) (message_t *this,exchange_type_t exchange_type);
/**
- * @brief Gets the exchange type of the message.
+ * Gets the exchange type of the message.
*
- * @param this message_t object
* @return exchange type of the message
*/
exchange_type_t (*get_exchange_type) (message_t *this);
/**
- * @brief Gets the payload type of the first payload.
+ * Gets the payload type of the first payload.
*
- * @param this message_t object
* @return payload type of the first payload
*/
payload_type_t (*get_first_payload_type) (message_t *this);
/**
- * @brief Sets the request flag.
+ * Sets the request flag.
*
- * @param this message_t object
- * @param original_initiator TRUE if message is a request, FALSE if it is a reply
+ * @param request TRUE if message is a request, FALSE if it is a reply
*/
- void (*set_request) (message_t *this,bool request);
+ void (*set_request) (message_t *this, bool request);
/**
- * @brief Gets request flag.
+ * Gets request flag.
*
- * @param this message_t object
* @return TRUE if message is a request, FALSE if it is a reply
*/
bool (*get_request) (message_t *this);
/**
- * @brief Append a payload to the message.
+ * Append a payload to the message.
*
* If the payload must be encrypted is not specified here. Encryption
* of payloads is evaluated via internal rules for the messages and
@@ -187,19 +165,17 @@ struct message_t {
* all payloads to encrypt are added to the encryption payload, which is
* always the last one.
*
- * @param this message_t object
* @param payload payload to append
*/
void (*add_payload) (message_t *this, payload_t *payload);
/**
- * @brief Build a notify payload and add it to the message.
+ * Build a notify payload and add it to the message.
*
* This is a helper method to create notify messages or add
* notify payload to messages. The flush parameter specifies if existing
* payloads should get removed before appending the notify.
*
- * @param this message_t object
* @param flush TRUE to remove existing payloads
* @param type type of the notify
* @param data a chunk of data to add to the notify, gets cloned
@@ -208,13 +184,12 @@ struct message_t {
chunk_t data);
/**
- * @brief Parses header of message.
+ * Parses header of message.
*
* Begins parisng of a message created via message_create_from_packet().
* The parsing context is stored, so a subsequent call to parse_body()
* will continue the parsing process.
*
- * @param this message_t object
* @return
* - SUCCESS if header could be parsed
* - PARSE_ERROR if corrupted/invalid data found
@@ -223,7 +198,7 @@ struct message_t {
status_t (*parse_header) (message_t *this);
/**
- * @brief Parses body of message.
+ * Parses body of message.
*
* The body gets not only parsed, but rather it gets verified.
* All payloads are verified if they are allowed to exist in the message
@@ -234,7 +209,6 @@ struct message_t {
* Crypter/signer can be omitted (by passing NULL) when no encryption
* payload is expected.
*
- * @param this message_t object
* @param crypter crypter to decrypt encryption payloads
* @param signer signer to verifiy a message with an encryption payload
* @return
@@ -249,7 +223,7 @@ struct message_t {
status_t (*parse_body) (message_t *this, crypter_t *crypter, signer_t *signer);
/**
- * @brief Generates the UDP packet of specific message.
+ * Generates the UDP packet of specific message.
*
* Payloads which must be encrypted are generated first and added to
* an encryption payload. This encryption payload will get encrypted via
@@ -260,7 +234,6 @@ struct message_t {
* payload is expected.
* Generation is only done once, multiple calls will just return a packet copy.
*
- * @param this message_t object
* @param crypter crypter to use when a payload must be encrypted
* @param signer signer to build a mac
* @param packet copy of generated packet
@@ -273,103 +246,91 @@ struct message_t {
status_t (*generate) (message_t *this, crypter_t *crypter, signer_t *signer, packet_t **packet);
/**
- * @brief Gets the source host informations.
+ * Gets the source host informations.
*
* @warning Returned host_t object is not getting cloned,
* do not destroy nor modify.
*
- * @param this message_t object
* @return host_t object representing source host
*/
host_t * (*get_source) (message_t *this);
/**
- * @brief Sets the source host informations.
+ * Sets the source host informations.
*
* @warning host_t object is not getting cloned and gets destroyed by
* message_t.destroy or next call of message_t.set_source.
*
- * @param this message_t object
* @param host host_t object representing source host
*/
void (*set_source) (message_t *this, host_t *host);
/**
- * @brief Gets the destination host informations.
+ * Gets the destination host informations.
*
* @warning Returned host_t object is not getting cloned,
* do not destroy nor modify.
*
- * @param this message_t object
* @return host_t object representing destination host
*/
host_t * (*get_destination) (message_t *this);
/**
- * @brief Sets the destination host informations.
+ * Sets the destination host informations.
*
* @warning host_t object is not getting cloned and gets destroyed by
* message_t.destroy or next call of message_t.set_destination.
*
- * @param this message_t object
* @param host host_t object representing destination host
*/
void (*set_destination) (message_t *this, host_t *host);
/**
- * @brief Returns an iterator on all stored payloads.
+ * Returns an iterator on all stored payloads.
*
* @warning Don't insert payloads over this iterator.
* Use add_payload() instead.
*
- * @param this message_t object
* @return iterator_t object which has to get destroyd by the caller
*/
iterator_t * (*get_payload_iterator) (message_t *this);
/**
- * @brief Find a payload of a specific type.
+ * Find a payload of a specific type.
*
* Returns the first occurance.
*
- * @param this message_t object
* @param type type of the payload to find
* @return payload, or NULL if no such payload found
*/
payload_t* (*get_payload) (message_t *this, payload_type_t type);
/**
- * @brief Returns a clone of the internal stored packet_t object.
+ * Returns a clone of the internal stored packet_t object.
*
- * @param this message_t object
* @return packet_t object as clone of internal one
*/
packet_t * (*get_packet) (message_t *this);
/**
- * @brief Returns a clone of the internal stored packet_t data.
+ * Returns a clone of the internal stored packet_t data.
*
- * @param this message_t object
* @return clone of the internal stored packet_t data.
*/
chunk_t (*get_packet_data) (message_t *this);
/**
- * @brief Destroys a message and all including objects.
- *
- * @param this message_t object
+ * Destroys a message and all including objects.
*/
void (*destroy) (message_t *this);
};
/**
- * @brief Creates an message_t object from a incoming UDP Packet.
+ * Creates an message_t object from a incoming UDP Packet.
*
* @warning the given packet_t object is not copied and gets
* destroyed in message_t's destroy call.
*
- * @warning Packet is not parsed in here!
- *
* - exchange_type is set to NOT_SET
* - original_initiator is set to TRUE
* - is_request is set to TRUE
@@ -377,23 +338,19 @@ struct message_t {
*
* @param packet packet_t object which is assigned to message
* @return message_t object
- *
- * @ingroup encoding
*/
message_t * message_create_from_packet(packet_t *packet);
/**
- * @brief Creates an empty message_t object.
+ * Creates an empty message_t object.
*
* - exchange_type is set to NOT_SET
* - original_initiator is set to TRUE
* - is_request is set to TRUE
*
* @return message_t object
- *
- * @ingroup encoding
*/
message_t * message_create(void);
-#endif /*MESSAGE_H_*/
+#endif /*MESSAGE_H_ @} */
diff --git a/src/charon/encoding/parser.c b/src/charon/encoding/parser.c
index d7caf7099..1b03aacb2 100644
--- a/src/charon/encoding/parser.c
+++ b/src/charon/encoding/parser.c
@@ -1,10 +1,3 @@
-/**
- * @file parser.c
- *
- * @brief Implementation of parser_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: parser.c 4010 2008-05-23 18:23:17Z martin $
*/
#include <stdlib.h>
@@ -67,7 +62,7 @@ struct private_parser_t {
parser_t public;
/**
- * @brief Parse a 4-Bit unsigned integer from the current parsing position.
+ * Parse a 4-Bit unsigned integer from the current parsing position.
*
* @param this parser_t object
* @param rule_number number of current rule
@@ -79,7 +74,7 @@ struct private_parser_t {
status_t (*parse_uint4) (private_parser_t *this, int rule_number, u_int8_t *output_pos);
/**
- * @brief Parse a 8-Bit unsigned integer from the current parsing position.
+ * Parse a 8-Bit unsigned integer from the current parsing position.
*
* @param this parser_t object
* @param rule_number number of current rule
@@ -91,7 +86,7 @@ struct private_parser_t {
status_t (*parse_uint8) (private_parser_t *this, int rule_number, u_int8_t *output_pos);
/**
- * @brief Parse a 15-Bit unsigned integer from the current parsing position.
+ * Parse a 15-Bit unsigned integer from the current parsing position.
*
* This is a special case used for ATTRIBUTE_TYPE.
* Big-/Little-endian conversion is done here.
@@ -106,7 +101,7 @@ struct private_parser_t {
status_t (*parse_uint15) (private_parser_t *this, int rule_number, u_int16_t *output_pos);
/**
- * @brief Parse a 16-Bit unsigned integer from the current parsing position.
+ * Parse a 16-Bit unsigned integer from the current parsing position.
*
* Big-/Little-endian conversion is done here.
*
@@ -120,7 +115,7 @@ struct private_parser_t {
status_t (*parse_uint16) (private_parser_t *this, int rule_number, u_int16_t *output_pos);
/**
- * @brief Parse a 32-Bit unsigned integer from the current parsing position.
+ * Parse a 32-Bit unsigned integer from the current parsing position.
*
* Big-/Little-endian conversion is done here.
*
@@ -134,7 +129,7 @@ struct private_parser_t {
status_t (*parse_uint32) (private_parser_t *this, int rule_number, u_int32_t *output_pos);
/**
- * @brief Parse a 64-Bit unsigned integer from the current parsing position.
+ * Parse a 64-Bit unsigned integer from the current parsing position.
*
* @todo add support for big-endian machines.
*
@@ -148,7 +143,7 @@ struct private_parser_t {
status_t (*parse_uint64) (private_parser_t *this, int rule_number, u_int64_t *output_pos);
/**
- * @brief Parse a given amount of bytes and writes them to a specific location
+ * Parse a given amount of bytes and writes them to a specific location
*
* @param this parser_t object
* @param rule_number number of current rule
@@ -161,7 +156,7 @@ struct private_parser_t {
status_t (*parse_bytes) (private_parser_t *this, int rule_number, u_int8_t *output_pos,size_t bytes);
/**
- * @brief Parse a single Bit from the current parsing position
+ * Parse a single Bit from the current parsing position
*
* @param this parser_t object
* @param rule_number number of current rule
@@ -173,7 +168,7 @@ struct private_parser_t {
status_t (*parse_bit) (private_parser_t *this, int rule_number, bool *output_pos);
/**
- * @brief Parse substructures in a list
+ * Parse substructures in a list
*
* This function calls the parser recursively to parse contained substructures
* in a linked_list_t. The list must already be created. Payload defines
@@ -192,7 +187,7 @@ struct private_parser_t {
status_t (*parse_list) (private_parser_t *this, int rule_number, linked_list_t **output_pos, payload_type_t payload_ype, size_t length);
/**
- * @brief Parse data from current parsing position in a chunk.
+ * Parse data from current parsing position in a chunk.
*
* This function clones length number of bytes to output_pos, without
* modifiyng them. Space will be allocated and must be freed by caller.
@@ -690,6 +685,11 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
return PARSE_ERROR;
}
payload_length = *(u_int16_t*)(output + rule->offset);
+ if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH)
+ {
+ pld->destroy(pld);
+ return PARSE_ERROR;
+ }
break;
}
case HEADER_LENGTH:
@@ -722,8 +722,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case PROPOSALS:
{
- size_t proposals_length = payload_length - SA_PAYLOAD_HEADER_LENGTH;
- if (this->parse_list(this, rule_number, output + rule->offset, PROPOSAL_SUBSTRUCTURE, proposals_length) != SUCCESS)
+ if (payload_length < SA_PAYLOAD_HEADER_LENGTH ||
+ this->parse_list(this, rule_number, output + rule->offset, PROPOSAL_SUBSTRUCTURE,
+ payload_length - SA_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -732,8 +733,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case TRANSFORMS:
{
- size_t transforms_length = payload_length - spi_size - PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH;
- if (this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_SUBSTRUCTURE, transforms_length) != SUCCESS)
+ if (payload_length < spi_size + PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH ||
+ this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_SUBSTRUCTURE,
+ payload_length - spi_size - PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -742,8 +744,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case TRANSFORM_ATTRIBUTES:
{
- size_t transform_a_length = payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
- if (this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_ATTRIBUTE, transform_a_length) != SUCCESS)
+ if (payload_length < TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH ||
+ this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_ATTRIBUTE,
+ payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -752,8 +755,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case CONFIGURATION_ATTRIBUTES:
{
- size_t configuration_attributes_length = payload_length - CP_PAYLOAD_HEADER_LENGTH;
- if (this->parse_list(this, rule_number, output + rule->offset, CONFIGURATION_ATTRIBUTE, configuration_attributes_length) != SUCCESS)
+ if (payload_length < CP_PAYLOAD_HEADER_LENGTH ||
+ this->parse_list(this, rule_number, output + rule->offset, CONFIGURATION_ATTRIBUTE,
+ payload_length - CP_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -814,8 +818,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case NONCE_DATA:
{
- size_t nonce_length = payload_length - NONCE_PAYLOAD_HEADER_LENGTH;
- if (this->parse_chunk(this, rule_number, output + rule->offset, nonce_length) != SUCCESS)
+ if (payload_length < NONCE_PAYLOAD_HEADER_LENGTH ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - NONCE_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -824,8 +829,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case ID_DATA:
{
- size_t data_length = payload_length - ID_PAYLOAD_HEADER_LENGTH;
- if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
+ if (payload_length < ID_PAYLOAD_HEADER_LENGTH ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - ID_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -834,8 +840,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case AUTH_DATA:
{
- size_t data_length = payload_length - AUTH_PAYLOAD_HEADER_LENGTH;
- if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
+ if (payload_length < AUTH_PAYLOAD_HEADER_LENGTH ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - AUTH_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -844,8 +851,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case CERT_DATA:
{
- size_t data_length = payload_length - CERT_PAYLOAD_HEADER_LENGTH;
- if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
+ if (payload_length < CERT_PAYLOAD_HEADER_LENGTH ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - CERT_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -854,8 +862,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case CERTREQ_DATA:
{
- size_t data_length = payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH;
- if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
+ if (payload_length < CERTREQ_PAYLOAD_HEADER_LENGTH ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -864,8 +873,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case EAP_DATA:
{
- size_t data_length = payload_length - EAP_PAYLOAD_HEADER_LENGTH;
- if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
+ if (payload_length < EAP_PAYLOAD_HEADER_LENGTH ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - EAP_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -874,8 +884,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case SPIS:
{
- size_t data_length = payload_length - DELETE_PAYLOAD_HEADER_LENGTH;
- if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
+ if (payload_length < DELETE_PAYLOAD_HEADER_LENGTH ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - DELETE_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -884,8 +895,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case VID_DATA:
{
- size_t data_length = payload_length - VENDOR_ID_PAYLOAD_HEADER_LENGTH;
- if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
+ if (payload_length < VENDOR_ID_PAYLOAD_HEADER_LENGTH ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - VENDOR_ID_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -904,8 +916,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case KEY_EXCHANGE_DATA:
{
- size_t keydata_length = payload_length - KE_PAYLOAD_HEADER_LENGTH;
- if (this->parse_chunk(this, rule_number, output + rule->offset, keydata_length) != SUCCESS)
+ if (payload_length < KE_PAYLOAD_HEADER_LENGTH ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - KE_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -914,8 +927,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case NOTIFICATION_DATA:
{
- size_t notify_length = payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size;
- if (this->parse_chunk(this, rule_number, output + rule->offset, notify_length) != SUCCESS)
+ if (payload_length < NOTIFY_PAYLOAD_HEADER_LENGTH + spi_size ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -924,8 +938,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case ENCRYPTED_DATA:
{
- size_t data_length = payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH;
- if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
+ if (payload_length < ENCRYPTION_PAYLOAD_HEADER_LENGTH ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -954,18 +969,20 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case TRAFFIC_SELECTORS:
{
- size_t traffic_selectors_length = payload_length - TS_PAYLOAD_HEADER_LENGTH;
- if (this->parse_list(this, rule_number, output + rule->offset, TRAFFIC_SELECTOR_SUBSTRUCTURE, traffic_selectors_length) != SUCCESS)
+ if (payload_length < TS_PAYLOAD_HEADER_LENGTH ||
+ this->parse_list(this, rule_number, output + rule->offset, TRAFFIC_SELECTOR_SUBSTRUCTURE,
+ payload_length - TS_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
}
break;
}
- case UNKNOWN_PAYLOAD:
+ case UNKNOWN_DATA:
{
- size_t unknown_payload_data_length = payload_length - UNKNOWN_PAYLOAD_HEADER_LENGTH;
- if (this->parse_chunk(this, rule_number, output + rule->offset, unknown_payload_data_length) != SUCCESS)
+ if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH ||
+ this->parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - UNKNOWN_PAYLOAD_HEADER_LENGTH) != SUCCESS)
{
pld->destroy(pld);
return PARSE_ERROR;
diff --git a/src/charon/encoding/parser.h b/src/charon/encoding/parser.h
index e9978524c..58778b57a 100644
--- a/src/charon/encoding/parser.h
+++ b/src/charon/encoding/parser.h
@@ -1,10 +1,3 @@
-/**
- * @file parser.h
- *
- * @brief Interface of parser_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: parser.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup parser parser
+ * @{ @ingroup encoding
*/
#ifndef PARSER_H_
@@ -31,65 +31,51 @@ typedef struct parser_t parser_t;
#include <encoding/payloads/payload.h>
/**
- * @brief A parser_t class to parse IKEv2 payloads.
+ * A parser_t class to parse IKEv2 payloads.
*
* A parser is used for parsing one chunk of data. Multiple
* payloads can be parsed out of the chunk using parse_payload.
* The parser remains the state until destroyed.
- *
- * @b Constructors:
- * - parser_create()
- *
- * @ingroup encoding
*/
struct parser_t {
/**
- * @brief Parses the next payload.
+ * Parses the next payload.
*
* @warning Caller is responsible for freeing allocated payload.
*
* Rules for parsing are described in the payload definition.
*
- * @param this parser_t bject
- * @param payload_type payload type to parse
- * @param[out] payload pointer where parsed payload was allocated
+ * @param payload_type payload type to parse
+ * @param payload pointer where parsed payload was allocated
* @return
- * - SUCCESSFUL if succeeded,
- * - PARSE_ERROR if corrupted/invalid data found
+ * - SUCCESSFUL if succeeded,
+ * - PARSE_ERROR if corrupted/invalid data found
*/
status_t (*parse_payload) (parser_t *this, payload_type_t payload_type, payload_t **payload);
/**
* Gets the remaining byte count which is not currently parsed.
- *
- * @param parser parser_t object
*/
int (*get_remaining_byte_count) (parser_t *this);
/**
- * @brief Resets the current parser context.
- *
- * @param parser parser_t object
+ * Resets the current parser context.
*/
void (*reset_context) (parser_t *this);
/**
- * @brief Destroys a parser_t object.
- *
- * @param parser parser_t object
+ * Destroys a parser_t object.
*/
void (*destroy) (parser_t *this);
};
/**
- * @brief Constructor to create a parser_t object.
- *
- * @param data chunk of data to parse with this parser_t object
- * @return parser_t object
+ * Constructor to create a parser_t object.
*
- * @ingroup encoding
+ * @param data chunk of data to parse with this parser_t object
+ * @return parser_t object
*/
parser_t *parser_create(chunk_t data);
-#endif /*PARSER_H_*/
+#endif /*PARSER_H_ @} */
diff --git a/src/charon/encoding/payloads/auth_payload.c b/src/charon/encoding/payloads/auth_payload.c
index 256d6c8a4..f9ca23236 100644
--- a/src/charon/encoding/payloads/auth_payload.c
+++ b/src/charon/encoding/payloads/auth_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file auth_payload.h
- *
- * @brief Implementation of auth_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: auth_payload.c 4051 2008-06-10 09:08:27Z tobias $
*/
#include "auth_payload.h"
@@ -116,7 +111,8 @@ encoding_rule_t auth_payload_encodings[] = {
static status_t verify(private_auth_payload_t *this)
{
if (this->auth_method == 0 ||
- (this->auth_method >= 4 && this->auth_method <= 200))
+ (this->auth_method >= 4 && this->auth_method <= 8) ||
+ (this->auth_method >= 12 && this->auth_method <= 200))
{
/* reserved IDs */
return FAILED;
diff --git a/src/charon/encoding/payloads/auth_payload.h b/src/charon/encoding/payloads/auth_payload.h
index 2db82ec0b..bdbba9e35 100644
--- a/src/charon/encoding/payloads/auth_payload.h
+++ b/src/charon/encoding/payloads/auth_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file auth_payload.h
- *
- * @brief Interface of auth_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: auth_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup auth_payload auth_payload
+ * @{ @ingroup payloads
*/
#ifndef AUTH_PAYLOAD_H_
@@ -32,20 +32,13 @@ typedef struct auth_payload_t auth_payload_t;
/**
* Length of a auth payload without the auth data in bytes.
- *
- * @ingroup payloads
*/
#define AUTH_PAYLOAD_HEADER_LENGTH 8
/**
- * @brief Class representing an IKEv2 AUTH payload.
+ * Class representing an IKEv2 AUTH payload.
*
* The AUTH payload format is described in RFC section 3.8.
- *
- * @b Constructors:
- * - auth_payload_create()
- *
- * @ingroup payloads
*/
struct auth_payload_t {
@@ -55,67 +48,57 @@ struct auth_payload_t {
payload_t payload_interface;
/**
- * @brief Set the AUTH method.
+ * Set the AUTH method.
*
- * @param this calling auth_payload_t object
* @param method auth_method_t to use
*/
void (*set_auth_method) (auth_payload_t *this, auth_method_t method);
/**
- * @brief Get the AUTH method.
+ * Get the AUTH method.
*
- * @param this calling auth_payload_t object
* @return auth_method_t used
*/
auth_method_t (*get_auth_method) (auth_payload_t *this);
/**
- * @brief Set the AUTH data.
+ * Set the AUTH data.
*
- * Data are getting cloned.
+ * Data gets cloned.
*
- * @param this calling auth_payload_t object
* @param data AUTH data as chunk_t
*/
void (*set_data) (auth_payload_t *this, chunk_t data);
/**
- * @brief Get the AUTH data.
+ * Get the AUTH data.
*
* Returned data are a copy of the internal one.
*
- * @param this calling auth_payload_t object
* @return AUTH data as chunk_t
*/
chunk_t (*get_data_clone) (auth_payload_t *this);
/**
- * @brief Get the AUTH data.
+ * Get the AUTH data.
*
* Returned data are NOT copied
*
- * @param this calling auth_payload_t object
* @return AUTH data as chunk_t
*/
chunk_t (*get_data) (auth_payload_t *this);
/**
- * @brief Destroys an auth_payload_t object.
- *
- * @param this auth_payload_t object to destroy
+ * Destroys an auth_payload_t object.
*/
void (*destroy) (auth_payload_t *this);
};
/**
- * @brief Creates an empty auth_payload_t object.
+ * Creates an empty auth_payload_t object.
*
* @return auth_payload_t object
- *
- * @ingroup payloads
*/
auth_payload_t *auth_payload_create(void);
-
-#endif /* AUTH_PAYLOAD_H_ */
+#endif /* AUTH_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/cert_payload.c b/src/charon/encoding/payloads/cert_payload.c
index c456f4936..99f504c5e 100644
--- a/src/charon/encoding/payloads/cert_payload.c
+++ b/src/charon/encoding/payloads/cert_payload.c
@@ -1,12 +1,6 @@
-/**
- * @file cert_payload.c
- *
- * @brief Implementation of cert_payload_t.
- *
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -19,29 +13,32 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: cert_payload.c 3852 2008-04-18 21:27:08Z andreas $
*/
#include <stddef.h>
+#include <ctype.h>
-#include "cert_payload.h"
+#include <daemon.h>
+#include "cert_payload.h"
-ENUM(cert_encoding_names, CERT_NONE, CERT_OCSP_CONTENT,
- "CERT_NONE",
- "CERT_PKCS7_WRAPPED_X509",
- "CERT_PGP",
- "CERT_DNS_SIGNED_KEY",
- "CERT_X509_SIGNATURE",
- "CERT_X509_KEY_EXCHANGE",
- "CERT_KERBEROS_TOKENS",
- "CERT_CRL",
- "CERT_ARL",
- "CERT_SPKI",
- "CERT_X509_ATTRIBUTE",
- "CERT_RAW_RSA_KEY",
- "CERT_X509_HASH_AND_URL",
- "CERT_X509_HASH_AND_URL_BUNDLE",
- "CERT_OCSP_CONTENT",
+ENUM(cert_encoding_names, ENC_PKCS7_WRAPPED_X509, ENC_OCSP_CONTENT,
+ "ENC_PKCS7_WRAPPED_X509",
+ "ENC_PGP",
+ "ENC_DNS_SIGNED_KEY",
+ "ENC_X509_SIGNATURE",
+ "ENC_X509_KEY_EXCHANGE",
+ "ENC_KERBEROS_TOKENS",
+ "ENC_CRL",
+ "ENC_ARL",
+ "ENC_SPKI",
+ "ENC_X509_ATTRIBUTE",
+ "ENC_RAW_RSA_KEY",
+ "ENC_X509_HASH_AND_URL",
+ "ENC_X509_HASH_AND_URL_BUNDLE",
+ "ENC_OCSP_CONTENT",
);
typedef struct private_cert_payload_t private_cert_payload_t;
@@ -74,12 +71,17 @@ struct private_cert_payload_t {
/**
* Encoding of the CERT Data.
*/
- u_int8_t cert_encoding;
+ u_int8_t encoding;
/**
* The contained cert data value.
*/
- chunk_t cert_data;
+ chunk_t data;
+
+ /**
+ * TRUE if the "Hash and URL" data is invalid
+ */
+ bool invalid_hash_and_url;
};
/**
@@ -105,9 +107,9 @@ encoding_rule_t cert_payload_encodings[] = {
/* Length of the whole payload*/
{ PAYLOAD_LENGTH, offsetof(private_cert_payload_t, payload_length)},
/* 1 Byte CERT type*/
- { U_INT_8, offsetof(private_cert_payload_t, cert_encoding) },
+ { U_INT_8, offsetof(private_cert_payload_t, encoding) },
/* some cert data bytes, length is defined in PAYLOAD_LENGTH */
- { CERT_DATA, offsetof(private_cert_payload_t, cert_data) }
+ { CERT_DATA, offsetof(private_cert_payload_t, data) }
};
/*
@@ -128,11 +130,41 @@ encoding_rule_t cert_payload_encodings[] = {
*/
static status_t verify(private_cert_payload_t *this)
{
- if ((this->cert_encoding == 0) ||
- ((this->cert_encoding >= CERT_ROOF) && (this->cert_encoding <= 200)))
+ if (this->encoding == ENC_X509_HASH_AND_URL ||
+ this->encoding == ENC_X509_HASH_AND_URL_BUNDLE)
{
- /* reserved IDs */
- return FAILED;
+ /* coarse verification of "Hash and URL" encoded certificates */
+ if (this->data.len <= 20)
+ {
+ DBG1(DBG_ENC, "invalid payload length for hash-and-url (%d), ignore",
+ this->data.len);
+ this->invalid_hash_and_url = TRUE;
+ return SUCCESS;
+ }
+
+ int i = 20; /* skipping the hash */
+ for (; i < this->data.len; ++i)
+ {
+ if (this->data.ptr[i] == '\0')
+ {
+ /* null terminated, fine */
+ return SUCCESS;
+ }
+ else if (!isprint(this->data.ptr[i]))
+ {
+ DBG1(DBG_ENC, "non printable characters in url of hash-and-url"
+ " encoded certificate payload, ignore");
+ this->invalid_hash_and_url = TRUE;
+ return SUCCESS;
+ }
+ }
+
+ /* URL is not null terminated, correct that */
+ chunk_t data = chunk_alloc(this->data.len + 1);
+ memcpy(data.ptr, this->data.ptr, this->data.len);
+ data.ptr[this->data.len] = '\0';
+ chunk_free(&this->data);
+ this->data = data;
}
return SUCCESS;
}
@@ -140,7 +172,8 @@ static status_t verify(private_cert_payload_t *this)
/**
* Implementation of cert_payload_t.get_encoding_rules.
*/
-static void get_encoding_rules(private_cert_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
+static void get_encoding_rules(private_cert_payload_t *this,
+ encoding_rule_t **rules, size_t *rule_count)
{
*rules = cert_payload_encodings;
*rule_count = sizeof(cert_payload_encodings) / sizeof(encoding_rule_t);
@@ -159,7 +192,7 @@ static payload_type_t get_payload_type(private_cert_payload_t *this)
*/
static payload_type_t get_next_type(private_cert_payload_t *this)
{
- return (this->next_payload);
+ return this->next_payload;
}
/**
@@ -179,56 +212,56 @@ static size_t get_length(private_cert_payload_t *this)
}
/**
- * Implementation of cert_payload_t.set_cert_encoding.
- */
-static void set_cert_encoding (private_cert_payload_t *this, cert_encoding_t encoding)
-{
- this->cert_encoding = encoding;
-}
-
-/**
* Implementation of cert_payload_t.get_cert_encoding.
*/
-static cert_encoding_t get_cert_encoding (private_cert_payload_t *this)
+static cert_encoding_t get_cert_encoding(private_cert_payload_t *this)
{
- return (this->cert_encoding);
+ return this->encoding;
}
/**
- * Implementation of cert_payload_t.set_data.
+ * Implementation of cert_payload_t.get_cert.
*/
-static void set_data (private_cert_payload_t *this, chunk_t data)
+static certificate_t *get_cert(private_cert_payload_t *this)
{
- if (this->cert_data.ptr != NULL)
+ if (this->encoding != ENC_X509_SIGNATURE)
{
- chunk_free(&(this->cert_data));
+ return NULL;
}
- this->cert_data.ptr = clalloc(data.ptr,data.len);
- this->cert_data.len = data.len;
- this->payload_length = CERT_PAYLOAD_HEADER_LENGTH + this->cert_data.len;
+ return lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER, chunk_clone(this->data),
+ BUILD_END);
}
/**
- * Implementation of cert_payload_t.get_data.
+ * Implementation of cert_payload_t.get_hash.
*/
-static chunk_t get_data (private_cert_payload_t *this)
+static chunk_t get_hash(private_cert_payload_t *this)
{
- return (this->cert_data);
+ chunk_t hash = chunk_empty;
+ if ((this->encoding != ENC_X509_HASH_AND_URL &&
+ this->encoding != ENC_X509_HASH_AND_URL_BUNDLE) ||
+ this->invalid_hash_and_url)
+ {
+ return hash;
+ }
+ hash.ptr = this->data.ptr;
+ hash.len = 20;
+ return hash;
}
/**
- * Implementation of cert_payload_t.get_data_clone.
+ * Implementation of cert_payload_t.get_url.
*/
-static chunk_t get_data_clone (private_cert_payload_t *this)
+static char *get_url(private_cert_payload_t *this)
{
- chunk_t cloned_data;
- if (this->cert_data.ptr == NULL)
+ if ((this->encoding != ENC_X509_HASH_AND_URL &&
+ this->encoding != ENC_X509_HASH_AND_URL_BUNDLE) ||
+ this->invalid_hash_and_url)
{
- return (this->cert_data);
+ return NULL;
}
- cloned_data.ptr = clalloc(this->cert_data.ptr,this->cert_data.len);
- cloned_data.len = this->cert_data.len;
- return cloned_data;
+ return (char*)this->data.ptr + 20;
}
/**
@@ -236,11 +269,7 @@ static chunk_t get_data_clone (private_cert_payload_t *this)
*/
static void destroy(private_cert_payload_t *this)
{
- if (this->cert_data.ptr != NULL)
- {
- chunk_free(&(this->cert_data));
- }
-
+ chunk_free(&this->data);
free(this);
}
@@ -251,7 +280,6 @@ cert_payload_t *cert_payload_create()
{
private_cert_payload_t *this = malloc_thing(private_cert_payload_t);
- /* interface functions */
this->public.payload_interface.verify = (status_t (*) (payload_t*))verify;
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t*,encoding_rule_t**, size_t*))get_encoding_rules;
this->public.payload_interface.get_length = (size_t (*) (payload_t*))get_length;
@@ -260,31 +288,60 @@ cert_payload_t *cert_payload_create()
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t*))get_payload_type;
this->public.payload_interface.destroy = (void (*) (payload_t*))destroy;
- /* public functions */
this->public.destroy = (void (*) (cert_payload_t*))destroy;
- this->public.set_cert_encoding = (void (*) (cert_payload_t*,cert_encoding_t))set_cert_encoding;
+ this->public.get_cert = (certificate_t* (*) (cert_payload_t*))get_cert;
this->public.get_cert_encoding = (cert_encoding_t (*) (cert_payload_t*))get_cert_encoding;
- this->public.set_data = (void (*) (cert_payload_t*,chunk_t))set_data;
- this->public.get_data_clone = (chunk_t (*) (cert_payload_t*))get_data_clone;
- this->public.get_data = (chunk_t (*) (cert_payload_t*))get_data;
+ this->public.get_hash = (chunk_t (*) (cert_payload_t*))get_hash;
+ this->public.get_url = (char* (*) (cert_payload_t*))get_url;
- /* private variables */
this->critical = FALSE;
this->next_payload = NO_PAYLOAD;
this->payload_length = CERT_PAYLOAD_HEADER_LENGTH;
- this->cert_data = chunk_empty;
+ this->data = chunk_empty;
+ this->encoding = 0;
+ this->invalid_hash_and_url = FALSE;
- return (&(this->public));
+ return &this->public;
}
/*
* Described in header
*/
-cert_payload_t *cert_payload_create_from_x509(x509_t *cert)
+cert_payload_t *cert_payload_create_from_cert(certificate_t *cert)
{
- cert_payload_t *this = cert_payload_create();
+ private_cert_payload_t *this = (private_cert_payload_t*)cert_payload_create();
+
+ switch (cert->get_type(cert))
+ {
+ case CERT_X509:
+ this->encoding = ENC_X509_SIGNATURE;
+ break;
+ default:
+ DBG1(DBG_ENC, "embedding %N certificate in payload failed",
+ certificate_type_names, cert->get_type(cert));
+ free(this);
+ return NULL;
+ }
+ this->data = cert->get_encoding(cert);
+ this->payload_length = CERT_PAYLOAD_HEADER_LENGTH + this->data.len;
+ return &this->public;
+}
- this->set_cert_encoding(this, CERT_X509_SIGNATURE);
- this->set_data(this, cert->get_certificate(cert));
- return this;
+/*
+ * Described in header
+ */
+cert_payload_t *cert_payload_create_from_hash_and_url(chunk_t hash, char *url)
+{
+ private_cert_payload_t *this = (private_cert_payload_t*)cert_payload_create();
+ chunk_t url_chunk;
+
+ this->encoding = ENC_X509_HASH_AND_URL;
+
+ url_chunk.ptr = url;
+ url_chunk.len = strlen(url) + 1;
+
+ this->data = chunk_cat("cc", hash, url_chunk);
+ this->payload_length = CERT_PAYLOAD_HEADER_LENGTH + this->data.len;
+ return &this->public;
}
+
diff --git a/src/charon/encoding/payloads/cert_payload.h b/src/charon/encoding/payloads/cert_payload.h
index bcb961398..aa16104a8 100644
--- a/src/charon/encoding/payloads/cert_payload.h
+++ b/src/charon/encoding/payloads/cert_payload.h
@@ -1,12 +1,6 @@
-/**
- * @file cert_payload.h
- *
- * @brief Interface of cert_payload_t.
- *
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -19,69 +13,58 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: cert_payload.h 3838 2008-04-18 11:24:45Z tobias $
+ */
+
+/**
+ * @defgroup cert_payload cert_payload
+ * @{ @ingroup payloads
*/
#ifndef CERT_PAYLOAD_H_
#define CERT_PAYLOAD_H_
-typedef enum cert_encoding_t cert_encoding_t;
typedef struct cert_payload_t cert_payload_t;
+typedef enum cert_encoding_t cert_encoding_t;
#include <library.h>
-#include <crypto/x509.h>
+#include <credentials/certificates/certificate.h>
#include <encoding/payloads/payload.h>
/**
* Length of a cert payload without the cert data in bytes.
- *
- * @ingroup payloads
*/
#define CERT_PAYLOAD_HEADER_LENGTH 5
/**
- * @brief Certificate encoding, as described in IKEv2 RFC section 3.6
- *
- * @ingroup payloads
+ * Certifcate encodings, as in RFC4306
*/
enum cert_encoding_t {
- CERT_NONE = 0,
- CERT_PKCS7_WRAPPED_X509 = 1,
- CERT_PGP = 2,
- CERT_DNS_SIGNED_KEY = 3,
- CERT_X509_SIGNATURE = 4,
- CERT_KERBEROS_TOKEN = 6,
- CERT_CRL = 7,
- CERT_ARL = 8,
- CERT_SPKI = 9,
- CERT_X509_ATTRIBUTE = 10,
- CERT_RAW_RSA_KEY = 11,
- CERT_X509_HASH_AND_URL = 12,
- CERT_X509_HASH_AND_URL_BUNDLE = 13,
- CERT_OCSP_CONTENT = 14, /* from RFC 4806 */
- CERT_ROOF = 15
+ ENC_PKCS7_WRAPPED_X509 = 1,
+ ENC_PGP = 2,
+ ENC_DNS_SIGNED_KEY = 3,
+ ENC_X509_SIGNATURE = 4,
+ ENC_KERBEROS_TOKEN = 6,
+ ENC_CRL = 7,
+ ENC_ARL = 8,
+ ENC_SPKI = 9,
+ ENC_X509_ATTRIBUTE = 10,
+ ENC_RAW_RSA_KEY = 11,
+ ENC_X509_HASH_AND_URL = 12,
+ ENC_X509_HASH_AND_URL_BUNDLE = 13,
+ ENC_OCSP_CONTENT = 14, /* from RFC 4806 */
};
/**
- * string mappings for cert_encoding_t.
- *
- * @ingroup payloads
+ * Enum names for cert_encoding_t
*/
extern enum_name_t *cert_encoding_names;
/**
- * @brief Class representing an IKEv2 CERT payload.
+ * Class representing an IKEv2 CERT payload.
*
* The CERT payload format is described in RFC section 3.6.
- * This is just a dummy implementation to fullfill the standards
- * requirements. A full implementation would offer setters/getters
- * for the different encoding types.
- *
- * @b Constructors:
- * - cert_payload_create()
- *
- * @todo Implement setters/getters for the different certificate encodings.
- *
- * @ingroup payloads
*/
struct cert_payload_t {
@@ -89,78 +72,69 @@ struct cert_payload_t {
* The payload_t interface.
*/
payload_t payload_interface;
-
- /**
- * @brief Set the CERT encoding.
- *
- * @param this calling cert_payload_t object
- * @param encoding CERT encoding
- */
- void (*set_cert_encoding) (cert_payload_t *this, cert_encoding_t encoding);
/**
- * @brief Get the CERT encoding.
+ * Get the playoads encoded certifcate.
*
- * @param this calling cert_payload_t object
- * @return Encoding of the CERT
+ * @return certifcate copy
*/
- cert_encoding_t (*get_cert_encoding) (cert_payload_t *this);
+ certificate_t *(*get_cert)(cert_payload_t *this);
/**
- * @brief Set the CERT data.
+ * Get the encoding of the certificate.
*
- * Data are getting cloned.
- *
- * @param this calling cert_payload_t object
- * @param data CERT data as chunk_t
+ * @return encoding
*/
- void (*set_data) (cert_payload_t *this, chunk_t data);
+ cert_encoding_t (*get_cert_encoding)(cert_payload_t *this);
/**
- * @brief Get the CERT data.
+ * Get the hash if this is a hash and URL encoded certificate.
*
- * Returned data are a copy of the internal one.
- *
- * @param this calling cert_payload_t object
- * @return CERT data as chunk_t
+ * This function returns internal data, do not free.
+ *
+ * @return hash
*/
- chunk_t (*get_data_clone) (cert_payload_t *this);
+ chunk_t (*get_hash)(cert_payload_t *this);
/**
- * @brief Get the CERT data.
+ * Get the URL if this is a hash and URL encoded certificate.
*
- * Returned data are NOT copied.
- *
- * @param this calling cert_payload_t object
- * @return CERT data as chunk_t
+ * This function returns internal data, do not free.
+ *
+ * @return url
*/
- chunk_t (*get_data) (cert_payload_t *this);
+ char *(*get_url)(cert_payload_t *this);
+
/**
- * @brief Destroys an cert_payload_t object.
- *
- * @param this cert_payload_t object to destroy
+ * Destroys the cert_payload object.
*/
void (*destroy) (cert_payload_t *this);
};
/**
- * @brief Creates an empty cert_payload_t object.
+ * Creates an empty certificate payload.
*
+ * @param cert certificate to embed
* @return cert_payload_t object
- *
- * @ingroup payloads
*/
cert_payload_t *cert_payload_create(void);
/**
- * @brief Creates a cert_payload_t object with an X.509 certificate.
+ * Creates a certificate payload with an embedded certificate.
*
- * @param cert X.509 certificate
+ * @param cert certificate to embed
* @return cert_payload_t object
+ */
+cert_payload_t *cert_payload_create_from_cert(certificate_t *cert);
+
+/**
+ * Creates a certificate payload with hash and URL encoding of a certificate.
*
- * @ingroup payloads
+ * @param hash hash of the DER encoded certificate (get's cloned)
+ * @param url the URL to locate the certificate (get's cloned)
+ * @return cert_payload_t object
*/
-cert_payload_t *cert_payload_create_from_x509(x509_t *cert);
+cert_payload_t *cert_payload_create_from_hash_and_url(chunk_t hash, char *url);
-#endif /* CERT_PAYLOAD_H_ */
+#endif /* CERT_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/certreq_payload.c b/src/charon/encoding/payloads/certreq_payload.c
index 46663811a..1b499e9e8 100644
--- a/src/charon/encoding/payloads/certreq_payload.c
+++ b/src/charon/encoding/payloads/certreq_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file certreq_payload.c
- *
- * @brief Implementation of certreq_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,14 +12,15 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: certreq_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
-#include <string.h>
#include <daemon.h>
#include <crypto/hashers/hasher.h>
-#include <crypto/ca.h>
+#include <encoding/payloads/cert_payload.h>
#include "certreq_payload.h"
@@ -61,12 +55,12 @@ struct private_certreq_payload_t {
/**
* Encoding of the CERT Data.
*/
- u_int8_t cert_encoding;
+ u_int8_t encoding;
/**
* The contained certreq data value.
*/
- chunk_t certreq_data;
+ chunk_t data;
};
/**
@@ -90,11 +84,11 @@ encoding_rule_t certreq_payload_encodings[] = {
{ RESERVED_BIT, 0 },
{ RESERVED_BIT, 0 },
/* Length of the whole payload*/
- { PAYLOAD_LENGTH, offsetof(private_certreq_payload_t, payload_length)},
+ { PAYLOAD_LENGTH, offsetof(private_certreq_payload_t, payload_length) },
/* 1 Byte CERTREQ type*/
- { U_INT_8, offsetof(private_certreq_payload_t, cert_encoding)},
+ { U_INT_8, offsetof(private_certreq_payload_t, encoding) },
/* some certreq data bytes, length is defined in PAYLOAD_LENGTH */
- { CERTREQ_DATA, offsetof(private_certreq_payload_t, certreq_data)}
+ { CERTREQ_DATA, offsetof(private_certreq_payload_t, data) }
};
/*
@@ -115,11 +109,15 @@ encoding_rule_t certreq_payload_encodings[] = {
*/
static status_t verify(private_certreq_payload_t *this)
{
- if ((this->cert_encoding == 0) ||
- ((this->cert_encoding >= CERT_ROOF) && (this->cert_encoding <= 200)))
+ if (this->encoding == ENC_X509_SIGNATURE)
{
- /* reserved IDs */
- return FAILED;
+ if (this->data.len < HASH_SIZE_SHA1 ||
+ this->data.len % HASH_SIZE_SHA1)
+ {
+ DBG1(DBG_ENC, "invalid X509 hash length (%d) in certreq",
+ this->data.len);
+ return FAILED;
+ }
}
return SUCCESS;
}
@@ -164,58 +162,78 @@ static size_t get_length(private_certreq_payload_t *this)
{
return this->payload_length;
}
-
+
/**
- * Implementation of certreq_payload_t.set_cert_encoding.
+ * Implementation of certreq_payload_t.add_keyid.
*/
-static void set_cert_encoding (private_certreq_payload_t *this, cert_encoding_t encoding)
+static void add_keyid(private_certreq_payload_t *this, chunk_t keyid)
{
- this->cert_encoding = encoding;
+ this->data = chunk_cat("mc", this->data, keyid);
+ this->payload_length += keyid.len;
}
+typedef struct keyid_enumerator_t keyid_enumerator_t;
+
/**
- * Implementation of certreq_payload_t.get_cert_encoding.
+ * enumerator to enumerate keyids
*/
-static cert_encoding_t get_cert_encoding (private_certreq_payload_t *this)
-{
- return (this->cert_encoding);
-}
+struct keyid_enumerator_t {
+ enumerator_t public;
+ chunk_t full;
+ u_char *pos;
+};
/**
- * Implementation of certreq_payload_t.set_data.
+ * enumerate function for keyid_enumerator
*/
-static void set_data (private_certreq_payload_t *this, chunk_t data)
+static bool keyid_enumerate(keyid_enumerator_t *this, chunk_t *chunk)
{
- if (this->certreq_data.ptr != NULL)
+ if (this->pos == NULL)
+ {
+ this->pos = this->full.ptr;
+ }
+ else
{
- chunk_free(&(this->certreq_data));
+ this->pos += HASH_SIZE_SHA1;
+ if (this->pos > (this->full.ptr + this->full.len - HASH_SIZE_SHA1))
+ {
+ this->pos = NULL;
+ }
}
- this->certreq_data.ptr = clalloc(data.ptr,data.len);
- this->certreq_data.len = data.len;
- this->payload_length = CERTREQ_PAYLOAD_HEADER_LENGTH + this->certreq_data.len;
+ if (this->pos)
+ {
+ chunk->ptr = this->pos;
+ chunk->len = HASH_SIZE_SHA1;
+ return TRUE;
+ }
+ return FALSE;
}
/**
- * Implementation of certreq_payload_t.get_data.
+ * Implementation of certreq_payload_t.create_keyid_enumerator.
*/
-static chunk_t get_data (private_certreq_payload_t *this)
+static enumerator_t* create_keyid_enumerator(private_certreq_payload_t *this)
{
- return (this->certreq_data);
+ keyid_enumerator_t *enumerator = malloc_thing(keyid_enumerator_t);
+ enumerator->public.enumerate = (void*)keyid_enumerate;
+ enumerator->public.destroy = (void*)free;
+ enumerator->full = this->data;
+ enumerator->pos = NULL;
+ return &enumerator->public;
}
/**
- * Implementation of certreq_payload_t.get_data_clone.
+ * Implementation of certreq_payload_t.get_cert_type.
*/
-static chunk_t get_data_clone (private_certreq_payload_t *this)
+static certificate_type_t get_cert_type(private_certreq_payload_t *this)
{
- chunk_t cloned_data;
- if (this->certreq_data.ptr == NULL)
+ switch (this->encoding)
{
- return (this->certreq_data);
+ case ENC_X509_SIGNATURE:
+ return CERT_X509;
+ default:
+ return CERT_ANY;
}
- cloned_data.ptr = clalloc(this->certreq_data.ptr,this->certreq_data.len);
- cloned_data.len = this->certreq_data.len;
- return cloned_data;
}
/**
@@ -223,11 +241,7 @@ static chunk_t get_data_clone (private_certreq_payload_t *this)
*/
static void destroy(private_certreq_payload_t *this)
{
- if (this->certreq_data.ptr != NULL)
- {
- chunk_free(&(this->certreq_data));
- }
-
+ chunk_free(&this->data);
free(this);
}
@@ -249,87 +263,38 @@ certreq_payload_t *certreq_payload_create()
/* public functions */
this->public.destroy = (void (*) (certreq_payload_t*)) destroy;
- this->public.set_cert_encoding = (void (*) (certreq_payload_t*,cert_encoding_t))set_cert_encoding;
- this->public.get_cert_encoding = (cert_encoding_t (*) (certreq_payload_t*))get_cert_encoding;
- this->public.set_data = (void (*) (certreq_payload_t*,chunk_t))set_data;
- this->public.get_data_clone = (chunk_t (*) (certreq_payload_t*))get_data_clone;
- this->public.get_data = (chunk_t (*) (certreq_payload_t*))get_data;
+ this->public.create_keyid_enumerator = (enumerator_t*(*)(certreq_payload_t*))create_keyid_enumerator;
+ this->public.get_cert_type = (certificate_type_t(*)(certreq_payload_t*))get_cert_type;
+ this->public.add_keyid = (void(*)(certreq_payload_t*, chunk_t keyid))add_keyid;
/* private variables */
this->critical = FALSE;
this->next_payload = NO_PAYLOAD;
- this->payload_length =CERTREQ_PAYLOAD_HEADER_LENGTH;
- this->certreq_data = chunk_empty;
+ this->payload_length = CERTREQ_PAYLOAD_HEADER_LENGTH;
+ this->data = chunk_empty;
+ this->encoding = 0;
- return (&(this->public));
+ return &this->public;
}
/*
* Described in header
*/
-certreq_payload_t *certreq_payload_create_from_cacert(identification_t *id)
+certreq_payload_t *certreq_payload_create_type(certificate_type_t type)
{
- x509_t *cacert;
- rsa_public_key_t *pubkey;
- chunk_t keyid;
- certreq_payload_t *this;
+ private_certreq_payload_t *this = (private_certreq_payload_t*)certreq_payload_create();
- cacert = charon->credentials->get_auth_certificate(charon->credentials, AUTH_CA, id);
- if (cacert == NULL)
+ switch (type)
{
- /* no such CA cert */
- return NULL;
+ case CERT_X509:
+ this->encoding = ENC_X509_SIGNATURE;
+ break;
+ default:
+ DBG1(DBG_ENC, "certificate type %N not supported in requests",
+ certificate_type_names, type);
+ free(this);
+ return NULL;
}
-
- this = certreq_payload_create();
- pubkey = cacert->get_public_key(cacert);
- keyid = pubkey->get_keyid(pubkey);
-
- DBG2(DBG_IKE, "requesting certificate issued by '%D'", id);
- DBG2(DBG_IKE, " with keyid %#B", &keyid);
-
- this->set_cert_encoding(this, CERT_X509_SIGNATURE);
- this->set_data(this, keyid);
- return this;
+ return &this->public;
}
-/*
- * Described in header
- */
-certreq_payload_t *certreq_payload_create_from_cacerts(void)
-{
- certreq_payload_t *this;
- chunk_t keyids;
- u_char *pos;
- ca_info_t *cainfo;
-
- iterator_t *iterator = charon->credentials->create_cainfo_iterator(charon->credentials);
- int count = iterator->get_count(iterator);
-
- if (count == 0)
- {
- iterator->destroy(iterator);
- return NULL;
- }
-
- this = certreq_payload_create();
- keyids = chunk_alloc(count * HASH_SIZE_SHA1);
- pos = keyids.ptr;
-
- while (iterator->iterate(iterator, (void**)&cainfo))
- {
- x509_t *cacert = cainfo->get_certificate(cainfo);
- chunk_t keyid = cacert->get_keyid(cacert);
-
- DBG2(DBG_IKE, "requesting certificate issued by '%D'", cacert->get_subject(cacert));
- DBG2(DBG_IKE, " with keyid %#B", &keyid);
- memcpy(pos, keyid.ptr, keyid.len);
- pos += HASH_SIZE_SHA1;
- }
- iterator->destroy(iterator);
-
- this->set_cert_encoding(this, CERT_X509_SIGNATURE);
- this->set_data(this, keyids);
- free(keyids.ptr);
- return this;
-}
diff --git a/src/charon/encoding/payloads/certreq_payload.h b/src/charon/encoding/payloads/certreq_payload.h
index 2985fdae1..b835d7ad6 100644
--- a/src/charon/encoding/payloads/certreq_payload.h
+++ b/src/charon/encoding/payloads/certreq_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file certreq_payload.h
- *
- * @brief Interface of certreq_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: certreq_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup certreq_payload certreq_payload
+ * @{ @ingroup payloads
*/
#ifndef CERTREQ_PAYLOAD_H_
@@ -32,26 +32,13 @@ typedef struct certreq_payload_t certreq_payload_t;
/**
* Length of a CERTREQ payload without the CERTREQ data in bytes.
- *
- * @ingroup payloads
*/
#define CERTREQ_PAYLOAD_HEADER_LENGTH 5
-
/**
- * @brief Class representing an IKEv2 CERTREQ payload.
+ * Class representing an IKEv2 CERTREQ payload.
*
* The CERTREQ payload format is described in RFC section 3.7.
- * This is just a dummy implementation to fullfill the standards
- * requirements. A full implementation would offer setters/getters
- * for the different encoding types.
- *
- * @b Constructors:
- * - certreq_payload_create()
- *
- * @todo Implement payload functionality.
- *
- * @ingroup payloads
*/
struct certreq_payload_t {
/**
@@ -60,85 +47,46 @@ struct certreq_payload_t {
payload_t payload_interface;
/**
- * @brief Set the CERT encoding.
- *
- * @param this calling certreq_payload_t object
- * @param encoding CERT encoding
- */
- void (*set_cert_encoding) (certreq_payload_t *this, cert_encoding_t encoding);
-
- /**
- * @brief Get the CERT encoding.
- *
- * @param this calling certreq_payload_t object
- * @return Encoding of the CERT
- */
- cert_encoding_t (*get_cert_encoding) (certreq_payload_t *this);
-
- /**
- * @brief Set the CERTREQ data.
- *
- * Data are getting cloned.
+ * Create an enumerator over contained keyids.
*
- * @param this calling certreq_payload_t object
- * @param data CERTREQ data as chunk_t
+ * @return enumerator over chunk_t's.
*/
- void (*set_data) (certreq_payload_t *this, chunk_t data);
+ enumerator_t* (*create_keyid_enumerator)(certreq_payload_t *this);
/**
- * @brief Get the CERTREQ data.
- *
- * Returned data are a copy of the internal one.
+ * Get the type of contained certificate keyids.
*
- * @param this calling certreq_payload_t object
- * @return CERTREQ data as chunk_t
+ * @return certificate keyid type
*/
- chunk_t (*get_data_clone) (certreq_payload_t *this);
+ certificate_type_t (*get_cert_type)(certreq_payload_t *this);
/**
- * @brief Get the CERTREQ data.
- *
- * Returned data are NOT copied.
+ * Add a certificates keyid to the payload.
*
- * @param this calling certreq_payload_t object
- * @return CERTREQ data as chunk_t
+ * @param keyid keyid of the trusted certifcate
+ * @return
*/
- chunk_t (*get_data) (certreq_payload_t *this);
+ void (*add_keyid)(certreq_payload_t *this, chunk_t keyid);
/**
- * @brief Destroys an certreq_payload_t object.
- *
- * @param this certreq_payload_t object to destroy
+ * Destroys an certreq_payload_t object.
*/
void (*destroy) (certreq_payload_t *this);
};
/**
- * @brief Creates an empty certreq_payload_t object.
+ * Creates an empty certreq_payload_t object.
*
- * @return certreq_payload_t object
- *
- * @ingroup payloads
+ * @return certreq payload
*/
certreq_payload_t *certreq_payload_create(void);
/**
- * @brief Creates a certreq_payload_t object from a ca certificate
- *
- * @param id subject distinguished name of CA certificate
- * @return certreq_payload_t object
- *
- * @ingroup payloads
- */
-certreq_payload_t *certreq_payload_create_from_cacert(identification_t *id);
-
-/**
- * @brief Creates a certreq_payload_t object from all ca certificates
- *
- * @return certreq_payload_t object
+ * Creates an empty certreq_payload_t for a kind of certificates.
*
- * @ingroup payloads
+ * @param type type of the added keyids
+ * @return certreq payload
*/
-certreq_payload_t *certreq_payload_create_from_cacerts(void);
+certreq_payload_t *certreq_payload_create_type(certificate_type_t type);
-#endif /* CERTREQ_PAYLOAD_H_ */
+#endif /* CERTREQ_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/configuration_attribute.c b/src/charon/encoding/payloads/configuration_attribute.c
index afd08c6be..6b1cbffb4 100644
--- a/src/charon/encoding/payloads/configuration_attribute.c
+++ b/src/charon/encoding/payloads/configuration_attribute.c
@@ -1,10 +1,3 @@
-/**
- * @file configuration_attribute.c
- *
- * @brief Implementation of configuration_attribute_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: configuration_attribute.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/configuration_attribute.h b/src/charon/encoding/payloads/configuration_attribute.h
index 5c4f65b14..ade837107 100644
--- a/src/charon/encoding/payloads/configuration_attribute.h
+++ b/src/charon/encoding/payloads/configuration_attribute.h
@@ -1,10 +1,3 @@
-/**
- * @file configuration_attribute.h
- *
- * @brief Interface of configuration_attribute_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: configuration_attribute.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup configuration_attribute configuration_attribute
+ * @{ @ingroup payloads
*/
#ifndef CONFIGURATION_ATTRIBUTE_H_
@@ -33,15 +33,11 @@ typedef struct configuration_attribute_t configuration_attribute_t;
/**
* Configuration attribute header length in bytes.
- *
- * @ingroup payloads
*/
#define CONFIGURATION_ATTRIBUTE_HEADER_LENGTH 4
/**
* Type of the attribute, as in IKEv2 RFC 3.15.1.
- *
- * @ingroup payloads
*/
enum configuration_attribute_type_t {
INTERNAL_IP4_ADDRESS = 1,
@@ -62,20 +58,13 @@ enum configuration_attribute_type_t {
/**
* enum names for configuration_attribute_type_t.
- *
- * @ingroup payloads
*/
extern enum_name_t *configuration_attribute_type_names;
/**
- * @brief Class representing an IKEv2-CONFIGURATION Attribute.
+ * Class representing an IKEv2-CONFIGURATION Attribute.
*
* The CONFIGURATION ATTRIBUTE format is described in RFC section 3.15.1.
- *
- * @b Constructors:
- * - configuration_attribute_create()
- *
- * @ingroup payloads
*/
struct configuration_attribute_t {
/**
@@ -84,64 +73,55 @@ struct configuration_attribute_t {
payload_t payload_interface;
/**
- * @brief Returns the currently set value of the attribute.
+ * Returns the currently set value of the attribute.
*
* @warning Returned data are not copied.
*
- * @param this calling configuration_attribute_t object
* @return chunk_t pointing to the value
*/
chunk_t (*get_value) (configuration_attribute_t *this);
/**
- * @brief Sets the value of the attribute.
+ * Sets the value of the attribute.
*
- * @warning Value is getting copied.
+ * Value is getting copied.
*
- * @param this calling configuration_attribute_t object
* @param value chunk_t pointing to the value to set
*/
void (*set_value) (configuration_attribute_t *this, chunk_t value);
/**
- * @brief Sets the type of the attribute.
+ * Sets the type of the attribute.
*
- * @param this calling configuration_attribute_t object
* @param type type to set (most significant bit is set to zero)
*/
void (*set_type) (configuration_attribute_t *this, u_int16_t type);
/**
- * @brief get the type of the attribute.
+ * get the type of the attribute.
*
- * @param this calling configuration_attribute_t object
* @return type of the value
*/
u_int16_t (*get_type) (configuration_attribute_t *this);
/**
- * @brief get the length of an attribute.
+ * get the length of an attribute.
*
- * @param this calling configuration_attribute_t object
* @return type of the value
*/
u_int16_t (*get_length) (configuration_attribute_t *this);
/**
- * @brief Destroys an configuration_attribute_t object.
- *
- * @param this configuration_attribute_t object to destroy
+ * Destroys an configuration_attribute_t object.
*/
void (*destroy) (configuration_attribute_t *this);
};
/**
- * @brief Creates an empty configuration_attribute_t object.
+ * Creates an empty configuration_attribute_t object.
*
* @return created configuration_attribute_t object
- *
- * @ingroup payloads
*/
configuration_attribute_t *configuration_attribute_create(void);
-#endif /* CONFIGURATION_ATTRIBUTE_H_*/
+#endif /* CONFIGURATION_ATTRIBUTE_H_ @} */
diff --git a/src/charon/encoding/payloads/cp_payload.c b/src/charon/encoding/payloads/cp_payload.c
index 380ed9681..d39dc2a47 100644
--- a/src/charon/encoding/payloads/cp_payload.c
+++ b/src/charon/encoding/payloads/cp_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file cp_payload.c
- *
- * @brief Implementation of cp_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: cp_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/cp_payload.h b/src/charon/encoding/payloads/cp_payload.h
index 27ff41005..0ca75e71d 100644
--- a/src/charon/encoding/payloads/cp_payload.h
+++ b/src/charon/encoding/payloads/cp_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file cp_payload.h
- *
- * @brief Interface of cp_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: cp_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup cp_payload cp_payload
+ * @{ @ingroup payloads
*/
#ifndef CP_PAYLOAD_H_
@@ -34,15 +34,11 @@ typedef struct cp_payload_t cp_payload_t;
/**
* CP_PAYLOAD length in bytes without any proposal substructure.
- *
- * @ingroup payloads
*/
#define CP_PAYLOAD_HEADER_LENGTH 8
/**
* Config Type of an Configuration Payload.
- *
- * @ingroup payloads
*/
enum config_type_t {
CFG_REQUEST = 1,
@@ -53,20 +49,13 @@ enum config_type_t {
/**
* enum name for config_type_t.
- *
- * @ingroup payloads
*/
extern enum_name_t *config_type_names;
/**
- * @brief Class representing an IKEv2-CP Payload.
+ * Class representing an IKEv2-CP Payload.
*
* The CP Payload format is described in RFC section 3.15.
- *
- * @b Constructors:
- * - cp_payload_create()
- *
- * @ingroup payloads
*/
struct cp_payload_t {
/**
@@ -75,58 +64,50 @@ struct cp_payload_t {
payload_t payload_interface;
/**
- * @brief Creates an iterator of stored configuration_attribute_t objects.
+ * Creates an iterator of stored configuration_attribute_t objects.
*
* When deleting an attribute using this iterator, the length of this
* configuration_attribute_t has to be refreshed by calling get_length()!
*
- * @param this calling cp_payload_t object
* @return created iterator_t object
*/
iterator_t *(*create_attribute_iterator) (cp_payload_t *this);
/**
- * @brief Adds a configuration_attribute_t object to this object.
+ * Adds a configuration_attribute_t object to this object.
*
* The added configuration_attribute_t object is getting destroyed in
* destroy function of cp_payload_t.
*
- * @param this calling cp_payload_t object
* @param attribute configuration_attribute_t object to add
*/
void (*add_configuration_attribute) (cp_payload_t *this, configuration_attribute_t *attribute);
/**
- * @brief Set the config type.
+ * Set the config type.
*
- * @param this calling cp_payload_t object
* @param config_type config_type_t to set
*/
void (*set_config_type) (cp_payload_t *this,config_type_t config_type);
/**
- * @brief Get the config type.
+ * Get the config type.
*
- * @param this calling cp_payload_t object
* @return config_type_t
*/
config_type_t (*get_config_type) (cp_payload_t *this);
/**
- * @brief Destroys an cp_payload_t object.
- *
- * @param this cp_payload_t object to destroy
+ * Destroys an cp_payload_t object.
*/
void (*destroy) (cp_payload_t *this);
};
/**
- * @brief Creates an empty cp_payload_t object
+ * Creates an empty cp_payload_t object
*
* @return cp_payload_t object
- *
- * @ingroup payloads
*/
cp_payload_t *cp_payload_create(void);
-#endif /*CP_PAYLOAD_H_*/
+#endif /*CP_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/delete_payload.c b/src/charon/encoding/payloads/delete_payload.c
index 1d42a3af2..01ee7f027 100644
--- a/src/charon/encoding/payloads/delete_payload.c
+++ b/src/charon/encoding/payloads/delete_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file delete_payload.c
- *
- * @brief Implementation of delete_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: delete_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/delete_payload.h b/src/charon/encoding/payloads/delete_payload.h
index 508f7fba2..2c1a596b9 100644
--- a/src/charon/encoding/payloads/delete_payload.h
+++ b/src/charon/encoding/payloads/delete_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file delete_payload.h
- *
- * @brief Interface of delete_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: delete_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup delete_payload delete_payload
+ * @{ @ingroup payloads
*/
#ifndef DELETE_PAYLOAD_H_
@@ -32,22 +32,13 @@ typedef struct delete_payload_t delete_payload_t;
/**
* Length of a delete payload without the SPI in bytes.
- *
- * @ingroup payloads
*/
#define DELETE_PAYLOAD_HEADER_LENGTH 8
/**
- * @brief Class representing an IKEv2 DELETE payload.
+ * Class representing an IKEv2 DELETE payload.
*
* The DELETE payload format is described in RFC section 3.11.
- *
- * @b Constructors:
- * - delete_payload_create()
- *
- * @todo Implement better setter/getters
- *
- * @ingroup payloads
*/
struct delete_payload_t {
/**
@@ -56,47 +47,40 @@ struct delete_payload_t {
payload_t payload_interface;
/**
- * @brief Get the protocol ID.
+ * Get the protocol ID.
*
- * @param this calling delete_payload_t object
* @return protocol ID
*/
protocol_id_t (*get_protocol_id) (delete_payload_t *this);
/**
- * @brief Add an SPI to the list of deleted SAs.
+ * Add an SPI to the list of deleted SAs.
*
- * @param this calling delete_payload_t object
* @param spi spi to add
*/
void (*add_spi) (delete_payload_t *this, u_int32_t spi);
/**
- * @brief Get an iterator over the SPIs.
+ * Get an iterator over the SPIs.
*
* The iterate() function returns a pointer to a u_int32_t SPI.
*
- * @param this calling delete_payload_t object
* @return iterator over SPIs
*/
iterator_t *(*create_spi_iterator) (delete_payload_t *this);
/**
- * @brief Destroys an delete_payload_t object.
- *
- * @param this delete_payload_t object to destroy
+ * Destroys an delete_payload_t object.
*/
void (*destroy) (delete_payload_t *this);
};
/**
- * @brief Creates an empty delete_payload_t object.
+ * Creates an empty delete_payload_t object.
*
* @param protocol_id protocol, such as AH|ESP
* @return delete_payload_t object
- *
- * @ingroup payloads
*/
delete_payload_t *delete_payload_create(protocol_id_t protocol_id);
-#endif /* DELETE_PAYLOAD_H_ */
+#endif /* DELETE_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/eap_payload.c b/src/charon/encoding/payloads/eap_payload.c
index da2498c5e..d9a6fe6dd 100644
--- a/src/charon/encoding/payloads/eap_payload.c
+++ b/src/charon/encoding/payloads/eap_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file eap_payload.c
- *
- * @brief Implementation of eap_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/eap_payload.h b/src/charon/encoding/payloads/eap_payload.h
index e4f8663c2..23558053d 100644
--- a/src/charon/encoding/payloads/eap_payload.h
+++ b/src/charon/encoding/payloads/eap_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file eap_payload.h
- *
- * @brief Interface of eap_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup eap_payload eap_payload
+ * @{ @ingroup payloads
*/
#ifndef EAP_PAYLOAD_H_
@@ -32,20 +32,13 @@ typedef struct eap_payload_t eap_payload_t;
/**
* Length of a EAP payload without the EAP Message in bytes.
- *
- * @ingroup payloads
*/
#define EAP_PAYLOAD_HEADER_LENGTH 4
/**
- * @brief Class representing an IKEv2 EAP payload.
+ * Class representing an IKEv2 EAP payload.
*
* The EAP payload format is described in RFC section 3.16.
- *
- * @b Constructors:
- * - eap_payload_create()
- *
- * @ingroup payloads
*/
struct eap_payload_t {
@@ -55,79 +48,68 @@ struct eap_payload_t {
payload_t payload_interface;
/**
- * @brief Set the contained EAP data.
+ * Set the contained EAP data.
*
* This contains the FULL EAP message starting with "code".
* Chunk gets cloned.
*
- * @param this calling eap_payload_t object
* @param message EAP data
*/
void (*set_data) (eap_payload_t *this, chunk_t data);
/**
- * @brief Get the contained EAP data.
+ * Get the contained EAP data.
*
* This contains the FULL EAP message starting with "code".
*
- * @param this calling eap_payload_t object
* @return EAP data (pointer to internal data)
*/
chunk_t (*get_data) (eap_payload_t *this);
/**
- * @brief Get the EAP code.
+ * Get the EAP code.
*
- * @param this calling eap_payload_t object
* @return EAP message as chunk_t
*/
eap_code_t (*get_code) (eap_payload_t *this);
/**
- * @brief Get the EAP identifier.
+ * Get the EAP identifier.
*
- * @param this calling eap_payload_t object
* @return unique identifier
*/
u_int8_t (*get_identifier) (eap_payload_t *this);
/**
- * @brief Get the EAP method type.
+ * Get the EAP method type.
*
- * @param this calling eap_payload_t object
* @param vendor pointer receiving vendor identifier
* @return EAP method type, vendor specific if vendor != 0
*/
eap_type_t (*get_type) (eap_payload_t *this, u_int32_t *vendor);
/**
- * @brief Destroys an eap_payload_t object.
- *
- * @param this eap_payload_t object to destroy
+ * Destroys an eap_payload_t object.
*/
void (*destroy) (eap_payload_t *this);
};
/**
- * @brief Creates an empty eap_payload_t object.
+ * Creates an empty eap_payload_t object.
*
* @return eap_payload_t object
- *
- * @ingroup payloads
*/
eap_payload_t *eap_payload_create(void);
/**
- * @brief Creates an eap_payload_t object with data.
+ * Creates an eap_payload_t object with data.
*
* @return eap_payload_t object
- *
- * @ingroup payloads
*/
eap_payload_t *eap_payload_create_data(chunk_t data);
/**
- * @brief Creates an eap_payload_t object with a code.
+ * Creates an eap_payload_t object with a code.
*
* Could should be either EAP_SUCCESS/EAP_FAILURE, use
* constructor above otherwise.
@@ -135,19 +117,15 @@ eap_payload_t *eap_payload_create_data(chunk_t data);
* @param code EAP status code
* @param identifier EAP identifier to use in payload
* @return eap_payload_t object
- *
- * @ingroup payloads
*/
eap_payload_t *eap_payload_create_code(eap_code_t code, u_int8_t identifier);
/**
- * @brief Creates an eap_payload_t EAP_RESPONSE containing an EAP_NAK.
+ * Creates an eap_payload_t EAP_RESPONSE containing an EAP_NAK.
*
* @param identifier EAP identifier to use in payload
* @return eap_payload_t object
- *
- * @ingroup payloads
*/
eap_payload_t *eap_payload_create_nak(u_int8_t identifier);
-#endif /* EAP_PAYLOAD_H_ */
+#endif /* EAP_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/encodings.c b/src/charon/encoding/payloads/encodings.c
index 55a7cf132..66c1fd999 100644
--- a/src/charon/encoding/payloads/encodings.c
+++ b/src/charon/encoding/payloads/encodings.c
@@ -1,10 +1,3 @@
-/**
- * @file encodings.c
- *
- * @brief String mappings of encoding_type_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: encodings.c 3589 2008-03-13 14:14:44Z martin $
*/
diff --git a/src/charon/encoding/payloads/encodings.h b/src/charon/encoding/payloads/encodings.h
index 5e07fbfab..73c5f9c36 100644
--- a/src/charon/encoding/payloads/encodings.h
+++ b/src/charon/encoding/payloads/encodings.h
@@ -1,10 +1,3 @@
-/**
- * @file encodings.h
- *
- * @brief Definition of encoding_type_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: encodings.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup encodings encodings
+ * @{ @ingroup payloads
*/
#ifndef ENCODINGS_H_
@@ -30,7 +30,7 @@ typedef struct encoding_rule_t encoding_rule_t;
#include <library.h>
/**
- * @brief All different kinds of encoding types.
+ * All different kinds of encoding types.
*
* Each field of an IKEv2-Message (in header or payload)
* which has to be parsed or generated differently has its own
@@ -40,8 +40,6 @@ typedef struct encoding_rule_t encoding_rule_t;
* from PRIVATE USE space. Also the substructures
* of specific payload types get their own payload_id
* from PRIVATE_USE space. See IKEv2-Draft for more informations.
- *
- * @ingroup payloads
*/
enum encoding_type_t {
@@ -114,7 +112,7 @@ enum encoding_type_t {
U_INT_64,
/**
- * @brief represents a RESERVED_BIT used in FLAG-Bytes.
+ * represents a RESERVED_BIT used in FLAG-Bytes.
*
* When generating, the next bit is set to zero and the current write
* position is moved one bit forward.
@@ -128,7 +126,7 @@ enum encoding_type_t {
RESERVED_BIT,
/**
- * @brief represents a RESERVED_BYTE.
+ * represents a RESERVED_BYTE.
*
* When generating, the next byte is set to zero and the current write
* position is moved one byte forward.
@@ -499,21 +497,16 @@ enum encoding_type_t {
/**
* enum name for encoding_type_t
- *
- * @ingroup payloads
*/
extern enum_name_t *encoding_type_names;
/**
+ * Rule how to en-/decode a payload field.
+ *
* An encoding rule is a mapping of a specific encoding type to
* a location in the data struct where the current field is stored to
* or read from.
- *
- * For examples see files in this directory.
- *
* This rules are used by parser and generator.
- *
- * @ingroup payloads
*/
struct encoding_rule_t {
@@ -534,4 +527,4 @@ struct encoding_rule_t {
u_int32_t offset;
};
-#endif /*ENCODINGS_H_*/
+#endif /*ENCODINGS_H_ @} */
diff --git a/src/charon/encoding/payloads/encryption_payload.c b/src/charon/encoding/payloads/encryption_payload.c
index 23b6e8d9f..7237c69c5 100644
--- a/src/charon/encoding/payloads/encryption_payload.c
+++ b/src/charon/encoding/payloads/encryption_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file encryption_payload.c
- *
- * @brief Implementation of encryption_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: encryption_payload.c 3862 2008-04-22 07:14:24Z martin $
*/
#include <stddef.h>
@@ -32,7 +27,6 @@
#include <encoding/generator.h>
#include <encoding/parser.h>
#include <utils/iterator.h>
-#include <utils/randomizer.h>
#include <crypto/signers/signer.h>
@@ -327,8 +321,7 @@ static void generate(private_encryption_payload_t *this)
static status_t encrypt(private_encryption_payload_t *this)
{
chunk_t iv, padding, to_crypt, result;
- randomizer_t *randomizer;
- status_t status;
+ rng_t *rng;
size_t block_size;
if (this->signer == NULL || this->crypter == NULL)
@@ -338,8 +331,12 @@ static status_t encrypt(private_encryption_payload_t *this)
}
/* for random data in iv and padding */
- randomizer = randomizer_create();
-
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (!rng)
+ {
+ DBG1(DBG_ENC, "could not encrypt, no RNG found");
+ return FAILED;
+ }
/* build payload chunk */
generate(this);
@@ -349,12 +346,7 @@ static status_t encrypt(private_encryption_payload_t *this)
/* build padding */
block_size = this->crypter->get_block_size(this->crypter);
padding.len = block_size - ((this->decrypted.len + 1) % block_size);
- status = randomizer->allocate_pseudo_random_bytes(randomizer, padding.len, &padding);
- if (status != SUCCESS)
- {
- randomizer->destroy(randomizer);
- return status;
- }
+ rng->allocate_bytes(rng, padding.len, &padding);
/* concatenate payload data, padding, padding len */
to_crypt.len = this->decrypted.len + padding.len + 1;
@@ -366,28 +358,17 @@ static status_t encrypt(private_encryption_payload_t *this)
/* build iv */
iv.len = block_size;
- status = randomizer->allocate_pseudo_random_bytes(randomizer, iv.len, &iv);
- randomizer->destroy(randomizer);
- if (status != SUCCESS)
- {
- chunk_free(&to_crypt);
- chunk_free(&padding);
- return status;
- }
+ rng->allocate_bytes(rng, iv.len, &iv);
+ rng->destroy(rng);
DBG3(DBG_ENC, "data before encryption with padding %B", &to_crypt);
/* encrypt to_crypt chunk */
free(this->encrypted.ptr);
- status = this->crypter->encrypt(this->crypter, to_crypt, iv, &result);
+ this->crypter->encrypt(this->crypter, to_crypt, iv, &result);
free(padding.ptr);
free(to_crypt.ptr);
- if (status != SUCCESS)
- {
- DBG2(DBG_ENC, "encryption failed");
- free(iv.ptr);
- return status;
- }
+
DBG3(DBG_ENC, "data after encryption %B", &result);
/* build encrypted result with iv and signature */
@@ -459,7 +440,6 @@ static status_t decrypt(private_encryption_payload_t *this)
{
chunk_t iv, concatenated;
u_int8_t padding_length;
- status_t status;
DBG2(DBG_ENC, "decrypting encryption payload");
DBG3(DBG_ENC, "data before decryption with IV and (invalid) signature %B",
@@ -478,12 +458,11 @@ static status_t decrypt(private_encryption_payload_t *this)
/* point concatenated to data + padding + padding_length*/
concatenated.ptr = this->encrypted.ptr + iv.len;
- concatenated.len = this->encrypted.len - iv.len - this->signer->get_block_size(this->signer);
+ concatenated.len = this->encrypted.len - iv.len -
+ this->signer->get_block_size(this->signer);
- /* check the size of input:
- * concatenated must be at least on block_size of crypter
- */
- if (concatenated.len < iv.len)
+ /* concatenated must be a multiple of block_size of crypter */
+ if (concatenated.len < iv.len || concatenated.len % iv.len)
{
DBG1(DBG_ENC, "could not decrypt, invalid input");
return FAILED;
@@ -494,18 +473,14 @@ static status_t decrypt(private_encryption_payload_t *this)
DBG3(DBG_ENC, "data before decryption %B", &concatenated);
- status = this->crypter->decrypt(this->crypter, concatenated, iv, &(this->decrypted));
- if (status != SUCCESS)
- {
- DBG1(DBG_ENC, "could not decrypt, decryption failed");
- return FAILED;
- }
+ this->crypter->decrypt(this->crypter, concatenated, iv, &this->decrypted);
+
DBG3(DBG_ENC, "data after decryption with padding %B", &this->decrypted);
-
/* get padding length, sits just bevore signature */
padding_length = *(this->decrypted.ptr + this->decrypted.len - 1);
- /* add one byte to the padding length, since the padding_length field is not included */
+ /* add one byte to the padding length, since the padding_length field is
+ * not included */
padding_length++;
this->decrypted.len -= padding_length;
diff --git a/src/charon/encoding/payloads/encryption_payload.h b/src/charon/encoding/payloads/encryption_payload.h
index 7cf53619f..e20ff6acc 100644
--- a/src/charon/encoding/payloads/encryption_payload.h
+++ b/src/charon/encoding/payloads/encryption_payload.h
@@ -1,9 +1,3 @@
-/**
- * @file encryption_payload.h
- *
- * @brief Interface of encryption_payload_t.
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -18,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: encryption_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup encryption_payload encryption_payload
+ * @{ @ingroup payloads
*/
#ifndef ENCRYPTION_PAYLOAD_H_
@@ -33,14 +34,12 @@ typedef struct encryption_payload_t encryption_payload_t;
/**
* Encrpytion payload length in bytes without IV and following data.
- *
- * @ingroup payloads
*/
#define ENCRYPTION_PAYLOAD_HEADER_LENGTH 4
/**
- * @brief The encryption payload as described in RFC section 3.14.
+ * The encryption payload as described in RFC section 3.14.
*
* Before any crypt/decrypt/sign/verify operation can occur,
* the transforms must be set. After that, a parsed encryption payload
@@ -51,11 +50,6 @@ typedef struct encryption_payload_t encryption_payload_t;
* must be builded after generation of all payloads and the encryption
* of the encryption payload.
* Signature verificatin is done before decryption.
- *
- * @b Constructors:
- * - encryption_payload_create()
- *
- * @ingroup payloads
*/
struct encryption_payload_t {
/**
@@ -64,29 +58,26 @@ struct encryption_payload_t {
payload_t payload_interface;
/**
- * @brief Creates an iterator for all contained payloads.
+ * Creates an iterator for all contained payloads.
*
- * @warning iterator_t object has to get destroyed by the caller.
+ * iterator_t object has to get destroyed by the caller.
*
- * @param this calling encryption_payload_t object
- * @param[in] forward iterator direction (TRUE: front to end)
+ * @param forward iterator direction (TRUE: front to end)
* return created iterator_t object
*/
iterator_t *(*create_payload_iterator) (encryption_payload_t *this, bool forward);
/**
- * @brief Adds a payload to this encryption payload.
+ * Adds a payload to this encryption payload.
*
- * @param this calling encryption_payload_t object
* @param payload payload_t object to add
*/
void (*add_payload) (encryption_payload_t *this, payload_t *payload);
/**
- * @brief Reove the last payload in the contained payload list.
+ * Reove the last payload in the contained payload list.
*
- * @param this calling encryption_payload_t object
- * @param[out] payload removed payload
+ * @param payload removed payload
* @return
* - SUCCESS, or
* - NOT_FOUND if list empty
@@ -94,15 +85,14 @@ struct encryption_payload_t {
status_t (*remove_first_payload) (encryption_payload_t *this, payload_t **payload);
/**
- * @brief Get the number of payloads.
+ * Get the number of payloads.
*
- * @param this calling encryption_payload_t object
* @return number of contained payloads
*/
size_t (*get_payload_count) (encryption_payload_t *this);
/**
- * @brief Set transforms to use.
+ * Set transforms to use.
*
* To decryption, encryption, signature building and verifying,
* the payload needs a crypter and a signer object.
@@ -110,34 +100,29 @@ struct encryption_payload_t {
* @warning Do NOT call this function again after encryption, since
* the signer must be the same while encrypting and signature building!
*
- * @param this calling encryption_payload_t
* @param crypter crypter_t to use for data de-/encryption
* @param signer signer_t to use for data signing/verifying
*/
void (*set_transforms) (encryption_payload_t *this, crypter_t *crypter, signer_t *signer);
/**
- * @brief Generate and encrypt contained payloads.
+ * Generate and encrypt contained payloads.
*
* This function generates the content for added payloads
* and encrypts them. Signature is not built, since we need
* additional data (the full message).
*
- * @param this calling encryption_payload_t
- * @return
- * - SUCCESS, or
- * - INVALID_STATE if transforms not set
+ * @return SUCCESS, or INVALID_STATE if transforms not set
*/
status_t (*encrypt) (encryption_payload_t *this);
/**
- * @brief Decrypt and parse contained payloads.
+ * Decrypt and parse contained payloads.
*
* This function decrypts the contained data. After,
* the payloads are parsed internally and are accessible
* via the iterator.
*
- * @param this calling encryption_payload_t
* @return
* - SUCCESS, or
* - INVALID_STATE if transforms not set, or
@@ -146,13 +131,12 @@ struct encryption_payload_t {
status_t (*decrypt) (encryption_payload_t *this);
/**
- * @brief Build the signature.
+ * Build the signature.
*
* The signature is built over the FULL message, so the header
* and every payload (inclusive this one) must already be generated.
* The generated message is supplied via the data paramater.
*
- * @param this calling encryption_payload_t
* @param data chunk contains the already generated message
* @return
* - SUCCESS, or
@@ -161,13 +145,12 @@ struct encryption_payload_t {
status_t (*build_signature) (encryption_payload_t *this, chunk_t data);
/**
- * @brief Verify the signature.
+ * Verify the signature.
*
* Since the signature is built over the full message, we need
* this data to do the verification. The message data
* is supplied via the data argument.
*
- * @param this calling encryption_payload_t
* @param data chunk contains the message
* @return
* - SUCCESS, or
@@ -177,21 +160,16 @@ struct encryption_payload_t {
status_t (*verify_signature) (encryption_payload_t *this, chunk_t data);
/**
- * @brief Destroys an encryption_payload_t object.
- *
- * @param this encryption_payload_t object to destroy
+ * Destroys an encryption_payload_t object.
*/
void (*destroy) (encryption_payload_t *this);
};
/**
- * @brief Creates an empty encryption_payload_t object.
+ * Creates an empty encryption_payload_t object.
*
* @return encryption_payload_t object
- *
- * @ingroup payloads
*/
encryption_payload_t *encryption_payload_create(void);
-
-#endif /*ENCRYPTION_PAYLOAD_H_*/
+#endif /*ENCRYPTION_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/endpoint_notify.c b/src/charon/encoding/payloads/endpoint_notify.c
index 98bfb2ea0..c9ef47afb 100644
--- a/src/charon/encoding/payloads/endpoint_notify.c
+++ b/src/charon/encoding/payloads/endpoint_notify.c
@@ -1,10 +1,3 @@
-/**
- * @file endpoint_notify.c
- *
- * @brief Implementation of endpoint_notify_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: endpoint_notify.c 3735 2008-04-02 18:21:03Z tobias $
*/
#include "endpoint_notify.h"
@@ -46,12 +41,12 @@ struct private_endpoint_notify_t {
/**
* Family
*/
- p2p_endpoint_family_t family;
+ me_endpoint_family_t family;
/**
* Endpoint type
*/
- p2p_endpoint_type_t type;
+ me_endpoint_type_t type;
/**
* Endpoint
@@ -76,10 +71,10 @@ struct private_endpoint_notify_t {
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-ENUM(p2p_endpoint_type_names, HOST, RELAYED,
+ENUM(me_endpoint_type_names, HOST, RELAYED,
"HOST",
- "SERVER_REFLEXIVE",
"PEER_REFLEXIVE",
+ "SERVER_REFLEXIVE",
"RELAYED"
);
@@ -120,7 +115,7 @@ static status_t parse_uint32(u_int8_t **cur, u_int8_t *top, u_int32_t *val)
}
/**
- * Parses the notification data of a P2P_ENDPOINT notify
+ * Parses the notification data of a ME_ENDPOINT notify
*/
static status_t parse_notification_data(private_endpoint_notify_t *this, chunk_t data)
{
@@ -130,29 +125,29 @@ static status_t parse_notification_data(private_endpoint_notify_t *this, chunk_t
u_int8_t *cur = data.ptr;
u_int8_t *top = data.ptr + data.len;
- DBG3(DBG_IKE, "p2p_endpoint_data %B", &data);
+ DBG3(DBG_IKE, "me_endpoint_data %B", &data);
if (parse_uint32(&cur, top, &this->priority) != SUCCESS)
{
- DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid priority");
+ DBG1(DBG_IKE, "failed to parse ME_ENDPOINT: invalid priority");
return FAILED;
}
if (parse_uint8(&cur, top, &family) != SUCCESS || family >= MAX_FAMILY)
{
- DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid family");
+ DBG1(DBG_IKE, "failed to parse ME_ENDPOINT: invalid family");
return FAILED;
}
- this->family = (p2p_endpoint_family_t)family;
+ this->family = (me_endpoint_family_t)family;
if (parse_uint8(&cur, top, &type) != SUCCESS || type >= MAX_TYPE)
{
- DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid type");
+ DBG1(DBG_IKE, "failed to parse ME_ENDPOINT: invalid type");
return FAILED;
}
- this->type = (p2p_endpoint_type_t)type;
+ this->type = (me_endpoint_type_t)type;
addr_family = AF_INET;
addr.len = 4;
@@ -166,13 +161,13 @@ static status_t parse_notification_data(private_endpoint_notify_t *this, chunk_t
case IPv4:
if (parse_uint16(&cur, top, &port) != SUCCESS)
{
- DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid port");
+ DBG1(DBG_IKE, "failed to parse ME_ENDPOINT: invalid port");
return FAILED;
}
if (cur + addr.len > top)
{
- DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid IP address");
+ DBG1(DBG_IKE, "failed to parse ME_ENDPOINT: invalid IP address");
return FAILED;
}
@@ -190,7 +185,7 @@ static status_t parse_notification_data(private_endpoint_notify_t *this, chunk_t
/**
- * Generates the notification data of a P2P_ENDPOINT notify
+ * Generates the notification data of a ME_ENDPOINT notify
*/
static chunk_t build_notification_data(private_endpoint_notify_t *this)
{
@@ -222,7 +217,7 @@ static chunk_t build_notification_data(private_endpoint_notify_t *this)
/* data = prio | family | type | port | addr */
data = chunk_cat("ccccc", prio_chunk, family_chunk, type_chunk,
port_chunk, addr_chunk);
- DBG3(DBG_IKE, "p2p_endpoint_data %B", &data);
+ DBG3(DBG_IKE, "me_endpoint_data %B", &data);
return data;
}
@@ -236,7 +231,7 @@ static notify_payload_t *build_notify(private_endpoint_notify_t *this)
notify_payload_t *notify;
notify = notify_payload_create();
- notify->set_notify_type(notify, P2P_ENDPOINT);
+ notify->set_notify_type(notify, ME_ENDPOINT);
data = build_notification_data(this);
notify->set_notification_data(notify, data);
chunk_free(&data);
@@ -263,7 +258,7 @@ static void set_priority(private_endpoint_notify_t *this, u_int32_t priority)
/**
* Implementation of endpoint_notify_t.get_type.
*/
-static p2p_endpoint_type_t get_type(private_endpoint_notify_t *this)
+static me_endpoint_type_t get_type(private_endpoint_notify_t *this)
{
return this->type;
}
@@ -271,7 +266,7 @@ static p2p_endpoint_type_t get_type(private_endpoint_notify_t *this)
/**
* Implementation of endpoint_notify_t.get_family.
*/
-static p2p_endpoint_family_t get_family(private_endpoint_notify_t *this)
+static me_endpoint_family_t get_family(private_endpoint_notify_t *this)
{
return this->family;
}
@@ -321,6 +316,7 @@ static endpoint_notify_t *_clone(private_endpoint_notify_t *this)
static status_t destroy(private_endpoint_notify_t *this)
{
DESTROY_IF(this->endpoint);
+ DESTROY_IF(this->base);
free(this);
return SUCCESS;
}
@@ -335,8 +331,8 @@ endpoint_notify_t *endpoint_notify_create()
/* public functions */
this->public.get_priority = (u_int32_t (*) (endpoint_notify_t *)) get_priority;
this->public.set_priority = (void (*) (endpoint_notify_t *, u_int32_t)) set_priority;
- this->public.get_type = (p2p_endpoint_type_t (*) (endpoint_notify_t *)) get_type;
- this->public.get_family = (p2p_endpoint_family_t (*) (endpoint_notify_t *)) get_family;
+ this->public.get_type = (me_endpoint_type_t (*) (endpoint_notify_t *)) get_type;
+ this->public.get_family = (me_endpoint_family_t (*) (endpoint_notify_t *)) get_family;
this->public.get_host = (host_t *(*) (endpoint_notify_t *)) get_host;
this->public.get_base = (host_t *(*) (endpoint_notify_t *)) get_base;
this->public.build_notify = (notify_payload_t *(*) (endpoint_notify_t *)) build_notify;
@@ -356,7 +352,7 @@ endpoint_notify_t *endpoint_notify_create()
/**
* Described in header
*/
-endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, host_t *host, host_t *base)
+endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type, host_t *host, host_t *base)
{
private_endpoint_notify_t *this = (private_endpoint_notify_t*)endpoint_notify_create();
@@ -365,20 +361,21 @@ endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, ho
switch(type)
{
case HOST:
- this->priority = pow(2, 16) * P2P_PRIO_HOST;
- break;
- case SERVER_REFLEXIVE:
- this->priority = pow(2, 16) * P2P_PRIO_SERVER;
+ this->priority = pow(2, 16) * ME_PRIO_HOST;
break;
case PEER_REFLEXIVE:
- this->priority = pow(2, 16) * P2P_PRIO_PEER;
+ this->priority = pow(2, 16) * ME_PRIO_PEER;
+ break;
+ case SERVER_REFLEXIVE:
+ this->priority = pow(2, 16) * ME_PRIO_SERVER;
break;
case RELAYED:
default:
- this->priority = pow(2, 16) * P2P_PRIO_RELAY;
+ this->priority = pow(2, 16) * ME_PRIO_RELAY;
break;
}
+ /* FIXME: if there is more than one ip address we should vary this priority */
this->priority += 65535;
if (!host)
@@ -395,7 +392,7 @@ endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, ho
this->family = IPv6;
break;
default:
- /* unsupported family type, we do not set the hsot
+ /* unsupported family type, we do not set the host
* (family is set to NO_FAMILY) */
return &this->public;
}
@@ -415,7 +412,7 @@ endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, ho
*/
endpoint_notify_t *endpoint_notify_create_from_payload(notify_payload_t *notify)
{
- if (notify->get_notify_type(notify) != P2P_ENDPOINT)
+ if (notify->get_notify_type(notify) != ME_ENDPOINT)
{
return NULL;
}
diff --git a/src/charon/encoding/payloads/endpoint_notify.h b/src/charon/encoding/payloads/endpoint_notify.h
index 4a3a68f95..9a4a4d7a1 100644
--- a/src/charon/encoding/payloads/endpoint_notify.h
+++ b/src/charon/encoding/payloads/endpoint_notify.h
@@ -1,10 +1,3 @@
-/**
- * @file endpoint_notify.h
- *
- * @brief Interface of endpoint_notify_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,29 +11,33 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: endpoint_notify.h 3701 2008-03-31 10:56:49Z tobias $
*/
+/**
+ * @defgroup endpoint_notify endpoint_notify
+ * @{ @ingroup payloads
+ */
#ifndef ENDPOINT_NOTIFY_H_
#define ENDPOINT_NOTIFY_H_
-#define P2P_PRIO_HOST 255
-#define P2P_PRIO_SERVER 100
-#define P2P_PRIO_PEER 120
-#define P2P_PRIO_RELAY 0
+#define ME_PRIO_HOST 255
+#define ME_PRIO_PEER 128
+#define ME_PRIO_SERVER 64
+#define ME_PRIO_RELAY 0
-typedef enum p2p_endpoint_family_t p2p_endpoint_family_t;
-typedef enum p2p_endpoint_type_t p2p_endpoint_type_t;
+typedef enum me_endpoint_family_t me_endpoint_family_t;
+typedef enum me_endpoint_type_t me_endpoint_type_t;
typedef struct endpoint_notify_t endpoint_notify_t;
#include <encoding/payloads/notify_payload.h>
/**
- * @brief P2P endpoint families.
- *
- * @ingroup payloads
+ * ME endpoint families.
*/
-enum p2p_endpoint_family_t {
+enum me_endpoint_family_t {
NO_FAMILY = 0,
@@ -53,19 +50,17 @@ enum p2p_endpoint_family_t {
};
/**
- * @brief P2P endpoint types.
- *
- * @ingroup payloads
+ * ME endpoint types.
*/
-enum p2p_endpoint_type_t {
+enum me_endpoint_type_t {
NO_TYPE = 0,
HOST = 1,
- SERVER_REFLEXIVE = 2,
+ PEER_REFLEXIVE = 2,
- PEER_REFLEXIVE = 3,
+ SERVER_REFLEXIVE = 3,
RELAYED = 4,
@@ -74,129 +69,107 @@ enum p2p_endpoint_type_t {
};
/**
- * enum name for p2p_endpoint_type_t.
- *
- * @ingroup payloads
+ * enum name for me_endpoint_type_t.
*/
-extern enum_name_t *p2p_endpoint_type_names;
+extern enum_name_t *me_endpoint_type_names;
/**
- * @brief Class representing a P2P_ENDPOINT notify. In fact it's not
+ * Class representing a ME_ENDPOINT Notify payload. In fact it's not
* the notify per se, but the notification data of that notify that is
* handled with this class.
- *
- * @b Constructors:
- * - endpoint_notify_create()
- * - endpoint_notify_create_from_host()
- *
- * @ingroup payloads
*/
struct endpoint_notify_t {
/**
- * @brief Returns the priority of this endpoint.
+ * Returns the priority of this endpoint.
*
- * @param this object
* @return priority
*/
u_int32_t (*get_priority) (endpoint_notify_t *this);
/**
- * @brief Sets the priority of this endpoint.
+ * Sets the priority of this endpoint.
*
- * @param this object
* @param priority priority
*/
void (*set_priority) (endpoint_notify_t *this, u_int32_t priority);
/**
- * @brief Returns the endpoint type of this endpoint.
+ * Returns the endpoint type of this endpoint.
*
- * @param this object
* @return endpoint type
*/
- p2p_endpoint_type_t (*get_type) (endpoint_notify_t *this);
+ me_endpoint_type_t (*get_type) (endpoint_notify_t *this);
/**
- * @brief Returns the endpoint family of this endpoint.
+ * Returns the endpoint family of this endpoint.
*
- * @param this object
* @return endpoint family
*/
- p2p_endpoint_family_t (*get_family) (endpoint_notify_t *this);
+ me_endpoint_family_t (*get_family) (endpoint_notify_t *this);
/**
- * @brief Returns the host of this endpoint.
+ * Returns the host of this endpoint.
*
- * @param this object
* @return host
*/
host_t *(*get_host) (endpoint_notify_t *this);
/**
- * @brief Returns the base of this endpoint.
+ * Returns the base of this endpoint.
*
* If this is not a SERVER_REFLEXIVE endpoint, the returned host is the same
* as the one returned by get_host.
*
- * @param this object
* @return host
*/
host_t *(*get_base) (endpoint_notify_t *this);
/**
- * @brief Generates a notification payload from this endpoint.
+ * Generates a notification payload from this endpoint.
*
- * @param this object
* @return built notify_payload_t
*/
notify_payload_t *(*build_notify) (endpoint_notify_t *this);
/**
- * @brief Clones an endpoint_notify_t object.
+ * Clones an endpoint_notify_t object.
*
- * @param this endpoint_notify_t object to clone
- * @return cloned object
+ * @return cloned object
*/
endpoint_notify_t *(*clone) (endpoint_notify_t *this);
/**
- * @brief Destroys an endpoint_notify_t object.
- *
- * @param this endpoint_notify_t object to destroy
+ * Destroys an endpoint_notify_t object.
*/
void (*destroy) (endpoint_notify_t *this);
};
/**
- * @brief Creates an empty endpoint_notify_t object.
+ * Creates an empty endpoint_notify_t object.
*
* @return created endpoint_notify_t object
- *
- * @ingroup payloads
*/
endpoint_notify_t *endpoint_notify_create(void);
/**
- * @brief Creates an endpoint_notify_t object from a host.
+ * Creates an endpoint_notify_t object from a host.
*
* @param type the endpoint type
* @param host host to base the notify on (gets cloned)
* @param base base of the endpoint, applies only to reflexive endpoints (gets cloned)
* @return created endpoint_notify_t object
- *
- * @ingroup payloads
*/
-endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, host_t *host, host_t *base);
+endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type,
+ host_t *host, host_t *base);
/**
- * @brief Creates an endpoint_notify_t object from a notify payload.
+ * Creates an endpoint_notify_t object from a notify payload.
*
* @param notify the notify payload
* @return - created endpoint_notify_t object
* - NULL if invalid payload
- * @ingroup payloads
*/
endpoint_notify_t *endpoint_notify_create_from_payload(notify_payload_t *notify);
-#endif /*ENDPOINT_NOTIFY_H_*/
+#endif /*ENDPOINT_NOTIFY_H_ @} */
diff --git a/src/charon/encoding/payloads/id_payload.c b/src/charon/encoding/payloads/id_payload.c
index aef8f6b7e..347ad7563 100644
--- a/src/charon/encoding/payloads/id_payload.c
+++ b/src/charon/encoding/payloads/id_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file id_payload.h
- *
- * @brief Interface of id_payload_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
@@ -21,6 +14,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: id_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/id_payload.h b/src/charon/encoding/payloads/id_payload.h
index 8e9322b4a..49e6c214b 100644
--- a/src/charon/encoding/payloads/id_payload.h
+++ b/src/charon/encoding/payloads/id_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file id_payload.h
- *
- * @brief Interface of id_payload_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
@@ -20,8 +13,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: id_payload.h 3589 2008-03-13 14:14:44Z martin $
*/
+/**
+ * @defgroup id_payload id_payload
+ * @{ @ingroup payloads
+ */
#ifndef ID_PAYLOAD_H_
#define ID_PAYLOAD_H_
@@ -34,8 +33,6 @@ typedef struct id_payload_t id_payload_t;
/**
* Length of a id payload without the data in bytes.
- *
- * @ingroup payloads
*/
#define ID_PAYLOAD_HEADER_LENGTH 8
@@ -43,12 +40,6 @@ typedef struct id_payload_t id_payload_t;
* Object representing an IKEv2 ID payload.
*
* The ID payload format is described in RFC section 3.5.
- *
- * @b Constructors:
- * - id_payload_create_from_identification()
- * - id_payload_create()
- *
- * @ingroup payloads
*/
struct id_payload_t {
/**
@@ -57,90 +48,77 @@ struct id_payload_t {
payload_t payload_interface;
/**
- * @brief Set the ID type.
+ * Set the ID type.
*
- * @param this calling id_payload_t object
* @param type Type of ID
*/
void (*set_id_type) (id_payload_t *this, id_type_t type);
/**
- * @brief Get the ID type.
+ * Get the ID type.
*
- * @param this calling id_payload_t object
* @return type of the ID
*/
id_type_t (*get_id_type) (id_payload_t *this);
/**
- * @brief Set the ID data.
+ * Set the ID data.
*
* Data are getting cloned.
*
- * @param this calling id_payload_t object
* @param data ID data as chunk_t
*/
void (*set_data) (id_payload_t *this, chunk_t data);
/**
- * @brief Get the ID data.
+ * Get the ID data.
*
* Returned data are a copy of the internal one
*
- * @param this calling id_payload_t object
* @return ID data as chunk_t
*/
chunk_t (*get_data_clone) (id_payload_t *this);
/**
- * @brief Get the ID data.
+ * Get the ID data.
*
* Returned data are NOT copied.
*
- * @param this calling id_payload_t object
* @return ID data as chunk_t
*/
chunk_t (*get_data) (id_payload_t *this);
/**
- * @brief Creates an identification object of this id payload.
+ * Creates an identification object of this id payload.
*
* Returned object has to get destroyed by the caller.
*
- * @param this calling id_payload_t object
* @return identification_t object
*/
identification_t *(*get_identification) (id_payload_t *this);
/**
- * @brief Destroys an id_payload_t object.
- *
- * @param this id_payload_t object to destroy
+ * Destroys an id_payload_t object.
*/
void (*destroy) (id_payload_t *this);
};
/**
- * @brief Creates an empty id_payload_t object.
+ * Creates an empty id_payload_t object.
*
* @param payload_type one of ID_INITIATOR, ID_RESPONDER
* @return id_payload_t object
- *
- * @ingroup payloads
*/
id_payload_t *id_payload_create(payload_type_t payload_type);
/**
- * @brief Creates an id_payload_t from an existing identification_t object.
+ * Creates an id_payload_t from an existing identification_t object.
*
* @param payload_type one of ID_INITIATOR, ID_RESPONDER
* @param identification identification_t object
* @return id_payload_t object
- *
- * @ingroup payloads
*/
-id_payload_t *id_payload_create_from_identification(payload_type_t payload_type, identification_t *identification);
-
-
+id_payload_t *id_payload_create_from_identification(payload_type_t payload_type,
+ identification_t *identification);
-#endif /* ID_PAYLOAD_H_ */
+#endif /* ID_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/ike_header.c b/src/charon/encoding/payloads/ike_header.c
index 3a171b095..1db64f0e3 100644
--- a/src/charon/encoding/payloads/ike_header.c
+++ b/src/charon/encoding/payloads/ike_header.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_header.c
- *
- * @brief Implementation of ike_header_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
@@ -20,6 +13,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_header.c 3666 2008-03-26 18:40:19Z tobias $
*/
/* offsetof macro */
@@ -110,13 +105,13 @@ ENUM_NEXT(exchange_type_names, IKE_SA_INIT, INFORMATIONAL, EXCHANGE_TYPE_UNDEFIN
"IKE_AUTH",
"CREATE_CHILD_SA",
"INFORMATIONAL");
-#ifdef P2P
-ENUM_NEXT(exchange_type_names, P2P_CONNECT, P2P_CONNECT, INFORMATIONAL,
- "P2P_CONNECT");
-ENUM_END(exchange_type_names, P2P_CONNECT);
+#ifdef ME
+ENUM_NEXT(exchange_type_names, ME_CONNECT, ME_CONNECT, INFORMATIONAL,
+ "ME_CONNECT");
+ENUM_END(exchange_type_names, ME_CONNECT);
#else
ENUM_END(exchange_type_names, INFORMATIONAL);
-#endif /* P2P */
+#endif /* ME */
/**
* Encoding rules to parse or generate a IKEv2-Header.
@@ -181,9 +176,9 @@ static status_t verify(private_ike_header_t *this)
{
if ((this->exchange_type < IKE_SA_INIT) ||
((this->exchange_type > INFORMATIONAL)
-#ifdef P2P
- && (this->exchange_type != P2P_CONNECT)
-#endif /* P2P */
+#ifdef ME
+ && (this->exchange_type != ME_CONNECT)
+#endif /* ME */
))
{
/* unsupported exchange type */
@@ -191,11 +186,11 @@ static status_t verify(private_ike_header_t *this)
}
if (this->initiator_spi == 0
-#ifdef P2P
+#ifdef ME
/* we allow zero spi for INFORMATIONAL exchanges,
- * to allow P2P connectivity checks */
+ * to allow connectivity checks */
&& this->exchange_type != INFORMATIONAL
-#endif /* P2P */
+#endif /* ME */
)
{
/* initiator spi not set */
diff --git a/src/charon/encoding/payloads/ike_header.h b/src/charon/encoding/payloads/ike_header.h
index e80964482..5568f081b 100644
--- a/src/charon/encoding/payloads/ike_header.h
+++ b/src/charon/encoding/payloads/ike_header.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_header.h
- *
- * @brief Interface of ike_header_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
@@ -20,6 +13,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_header.h 3666 2008-03-26 18:40:19Z tobias $
+ */
+
+/**
+ * @defgroup ike_header ike_header
+ * @{ @ingroup payloads
*/
#ifndef IKE_HEADER_H_
@@ -33,38 +33,28 @@ typedef struct ike_header_t ike_header_t;
/**
* Major Version of IKEv2.
- *
- * @ingroup payloads
*/
#define IKE_MAJOR_VERSION 2
/**
* Minor Version of IKEv2.
- *
- * @ingroup payloads
*/
#define IKE_MINOR_VERSION 0
/**
* Flag in IKEv2-Header. Always 0.
- *
- * @ingroup payloads
*/
#define HIGHER_VERSION_SUPPORTED_FLAG 0
/**
* Length of IKE Header in Bytes.
- *
- * @ingroup payloads
*/
#define IKE_HEADER_LENGTH 28
/**
- * @brief Different types of IKE-Exchanges.
+ * Different types of IKE-Exchanges.
*
- * See Draft for different types.
- *
- * @ingroup payloads
+ * See RFC for different types.
*/
enum exchange_type_t{
@@ -92,33 +82,26 @@ enum exchange_type_t{
* INFORMATIONAL.
*/
INFORMATIONAL = 37,
-#ifdef P2P
+#ifdef ME
/**
- * P2P_CONNECT
+ * ME_CONNECT
*/
- P2P_CONNECT = 240
-#endif /* P2P */
+ ME_CONNECT = 240
+#endif /* ME */
};
/**
* enum name for exchange_type_t
- *
- * @ingroup payloads
*/
extern enum_name_t *exchange_type_names;
/**
- * @brief An object of this type represents an IKEv2 header and is used to
+ * An object of this type represents an IKEv2 header and is used to
* generate and parse IKEv2 headers.
*
* The header format of an IKEv2-Message is compatible to the
* ISAKMP-Header format to allow implementations supporting
* both versions of the IKE-protocol.
- *
- * @b Constructors:
- * - ike_header_create()
- *
- * @ingroup payloads
*/
struct ike_header_t {
/**
@@ -127,141 +110,121 @@ struct ike_header_t {
payload_t payload_interface;
/**
- * @brief Get the initiator spi.
+ * Get the initiator spi.
*
- * @param this ike_header_t object
* @return initiator_spi
*/
u_int64_t (*get_initiator_spi) (ike_header_t *this);
/**
- * @brief Set the initiator spi.
+ * Set the initiator spi.
*
- * @param this ike_header_t object
* @param initiator_spi initiator_spi
*/
void (*set_initiator_spi) (ike_header_t *this, u_int64_t initiator_spi);
/**
- * @brief Get the responder spi.
+ * Get the responder spi.
*
- * @param this ike_header_t object
* @return responder_spi
*/
u_int64_t (*get_responder_spi) (ike_header_t *this);
/**
- * @brief Set the responder spi.
+ * Set the responder spi.
*
- * @param this ike_header_t object
* @param responder_spi responder_spi
*/
void (*set_responder_spi) (ike_header_t *this, u_int64_t responder_spi);
/**
- * @brief Get the major version.
+ * Get the major version.
*
- * @param this ike_header_t object
* @return major version
*/
u_int8_t (*get_maj_version) (ike_header_t *this);
/**
- * @brief Get the minor version.
+ * Get the minor version.
*
- * @param this ike_header_t object
* @return minor version
*/
u_int8_t (*get_min_version) (ike_header_t *this);
/**
- * @brief Get the response flag.
+ * Get the response flag.
*
- * @param this ike_header_t object
* @return response flag
*/
bool (*get_response_flag) (ike_header_t *this);
/**
- * @brief Set the response flag-
+ * Set the response flag-
*
- * @param this ike_header_t object
* @param response response flag
*
*/
void (*set_response_flag) (ike_header_t *this, bool response);
/**
- * @brief Get "higher version supported"-flag.
+ * Get "higher version supported"-flag.
*
- * @param this ike_header_t object
* @return version flag
*/
bool (*get_version_flag) (ike_header_t *this);
/**
- * @brief Get the initiator flag.
+ * Get the initiator flag.
*
- * @param this ike_header_t object
* @return initiator flag
*/
bool (*get_initiator_flag) (ike_header_t *this);
/**
- * @brief Set the initiator flag.
+ * Set the initiator flag.
*
- * @param this ike_header_t object
* @param initiator initiator flag
- *
*/
void (*set_initiator_flag) (ike_header_t *this, bool initiator);
/**
- * @brief Get the exchange type.
+ * Get the exchange type.
*
- * @param this ike_header_t object
- * @return exchange type
+ * @return exchange type
*/
u_int8_t (*get_exchange_type) (ike_header_t *this);
/**
- * @brief Set the exchange type.
+ * Set the exchange type.
*
- * @param this ike_header_t object
* @param exchange_type exchange type
*/
void (*set_exchange_type) (ike_header_t *this, u_int8_t exchange_type);
/**
- * @brief Get the message id.
+ * Get the message id.
*
- * @param this ike_header_t object
* @return message id
*/
u_int32_t (*get_message_id) (ike_header_t *this);
/**
- * @brief Set the message id.
+ * Set the message id.
*
- * @param this ike_header_t object
* @param initiator_spi message id
*/
void (*set_message_id) (ike_header_t *this, u_int32_t message_id);
/**
- * @brief Destroys a ike_header_t object.
- *
- * @param this ike_header_t object to destroy
+ * Destroys a ike_header_t object.
*/
void (*destroy) (ike_header_t *this);
};
/**
- * @brief Create an ike_header_t object
+ * Create an ike_header_t object
*
* @return ike_header_t object
- *
- * @ingroup payloads
*/
ike_header_t *ike_header_create(void);
-#endif /*IKE_HEADER_H_*/
+#endif /*IKE_HEADER_H_ @} */
diff --git a/src/charon/encoding/payloads/ke_payload.c b/src/charon/encoding/payloads/ke_payload.c
index 8926b15f9..2f718e49c 100644
--- a/src/charon/encoding/payloads/ke_payload.c
+++ b/src/charon/encoding/payloads/ke_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file ke_payload.c
- *
- * @brief Implementation of ke_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ke_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/ke_payload.h b/src/charon/encoding/payloads/ke_payload.h
index 52be8ffe3..222d2ec7c 100644
--- a/src/charon/encoding/payloads/ke_payload.h
+++ b/src/charon/encoding/payloads/ke_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file ke_payload.h
- *
- * @brief Interface of ke_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ke_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ke_payload ke_payload
+ * @{ @ingroup payloads
*/
#ifndef KE_PAYLOAD_H_
@@ -34,20 +34,13 @@ typedef struct ke_payload_t ke_payload_t;
/**
* KE payload length in bytes without any key exchange data.
- *
- * @ingroup payloads
*/
#define KE_PAYLOAD_HEADER_LENGTH 8
/**
- * @brief Class representing an IKEv2-KE Payload.
+ * Class representing an IKEv2-KE Payload.
*
* The KE Payload format is described in RFC section 3.4.
- *
- * @b Constructors:
- * - ke_payload_create()
- *
- * @ingroup payloads
*/
struct ke_payload_t {
/**
@@ -56,66 +49,58 @@ struct ke_payload_t {
payload_t payload_interface;
/**
- * @brief Returns the currently set key exchange data of this KE payload.
+ * Returns the currently set key exchange data of this KE payload.
*
* @warning Returned data are not copied.
*
- * @param this calling ke_payload_t object
* @return chunk_t pointing to the value
*/
chunk_t (*get_key_exchange_data) (ke_payload_t *this);
/**
- * @brief Sets the key exchange data of this KE payload.
+ * Sets the key exchange data of this KE payload.
*
- * @warning Value is getting copied.
+ * Value is getting copied.
*
- * @param this calling ke_payload_t object
- * @param key_exchange_data chunk_t pointing to the value to set
+ * @param key_exchange_data chunk_t pointing to the value to set
*/
void (*set_key_exchange_data) (ke_payload_t *this, chunk_t key_exchange_data);
/**
- * @brief Gets the Diffie-Hellman Group Number of this KE payload.
+ * Gets the Diffie-Hellman Group Number of this KE payload.
*
- * @param this calling ke_payload_t object
- * @return DH Group Number of this payload
+ * @return DH Group Number of this payload
*/
diffie_hellman_group_t (*get_dh_group_number) (ke_payload_t *this);
/**
- * @brief Sets the Diffie-Hellman Group Number of this KE payload.
+ * Sets the Diffie-Hellman Group Number of this KE payload.
*
- * @param this calling ke_payload_t object
* @param dh_group_number DH Group to set
*/
- void (*set_dh_group_number) (ke_payload_t *this, diffie_hellman_group_t dh_group_number);
+ void (*set_dh_group_number) (ke_payload_t *this,
+ diffie_hellman_group_t dh_group_number);
/**
- * @brief Destroys an ke_payload_t object.
- *
- * @param this ke_payload_t object to destroy
+ * Destroys an ke_payload_t object.
*/
void (*destroy) (ke_payload_t *this);
};
/**
- * @brief Creates an empty ke_payload_t object
+ * Creates an empty ke_payload_t object
*
* @return ke_payload_t object
- *
- * @ingroup payloads
*/
ke_payload_t *ke_payload_create(void);
/**
- * @brief Creates a ke_payload_t from a diffie_hellman_t
+ * Creates a ke_payload_t from a diffie_hellman_t
*
* @param diffie_hellman diffie hellman object containing group and key
* @return ke_payload_t object
- *
- * @ingroup payloads
*/
-ke_payload_t *ke_payload_create_from_diffie_hellman(diffie_hellman_t *diffie_hellman);
+ke_payload_t *ke_payload_create_from_diffie_hellman(
+ diffie_hellman_t *diffie_hellman);
-#endif /* KE_PAYLOAD_H_ */
+#endif /* KE_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/nonce_payload.c b/src/charon/encoding/payloads/nonce_payload.c
index 8e1fc505e..da68ce4ab 100644
--- a/src/charon/encoding/payloads/nonce_payload.c
+++ b/src/charon/encoding/payloads/nonce_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file nonce_payload.h
- *
- * @brief Implementation of nonce_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: nonce_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
/* offsetof macro */
diff --git a/src/charon/encoding/payloads/nonce_payload.h b/src/charon/encoding/payloads/nonce_payload.h
index 96d83b028..f1679834e 100644
--- a/src/charon/encoding/payloads/nonce_payload.h
+++ b/src/charon/encoding/payloads/nonce_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file nonce_payload.h
- *
- * @brief Interface of nonce_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: nonce_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup nonce_payload nonce_payload
+ * @{ @ingroup payloads
*/
#ifndef NONCE_PAYLOAD_H_
@@ -31,17 +31,11 @@ typedef struct nonce_payload_t nonce_payload_t;
/**
* Nonce size in bytes for nonces sending to other peer.
- *
- * @warning Nonce size MUST be between 16 and 256 bytes.
- *
- * @ingroup payloads
*/
#define NONCE_SIZE 16
/**
* Length of a nonce payload without a nonce in bytes.
- *
- * @ingroup payloads
*/
#define NONCE_PAYLOAD_HEADER_LENGTH 4
@@ -49,11 +43,6 @@ typedef struct nonce_payload_t nonce_payload_t;
* Object representing an IKEv2 Nonce payload.
*
* The Nonce payload format is described in RFC section 3.3.
- *
- * @b Constructors:
- * - nonce_payload_create()
- *
- * @ingroup payloads
*/
struct nonce_payload_t {
/**
@@ -62,38 +51,30 @@ struct nonce_payload_t {
payload_t payload_interface;
/**
- * @brief Set the nonce value.
+ * Set the nonce value.
*
- * @param this calling nonce_payload_t object
* @param nonce chunk containing the nonce, will be cloned
*/
void (*set_nonce) (nonce_payload_t *this, chunk_t nonce);
/**
- * @brief Get the nonce value.
+ * Get the nonce value.
*
- * @param this calling nonce_payload_t object
* @return a chunk containing the cloned nonce
*/
chunk_t (*get_nonce) (nonce_payload_t *this);
/**
- * @brief Destroys an nonce_payload_t object.
- *
- * @param this nonce_payload_t object to destroy
+ * Destroys an nonce_payload_t object.
*/
void (*destroy) (nonce_payload_t *this);
};
/**
- * @brief Creates an empty nonce_payload_t object
+ * Creates an empty nonce_payload_t object
*
* @return nonce_payload_t object
- *
- * @ingroup payloads
*/
-
nonce_payload_t *nonce_payload_create(void);
-
-#endif /*NONCE_PAYLOAD_H_*/
+#endif /*NONCE_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/notify_payload.c b/src/charon/encoding/payloads/notify_payload.c
index d32257af6..defb0b98a 100644
--- a/src/charon/encoding/payloads/notify_payload.c
+++ b/src/charon/encoding/payloads/notify_payload.c
@@ -1,12 +1,5 @@
-/**
- * @file notify_payload.c
- *
- * @brief Implementation of notify_payload_t.
- *
- */
-
/*
- * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2006-2008 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -21,6 +14,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: notify_payload.c 3920 2008-05-08 16:19:11Z tobias $
*/
#include <stddef.h>
@@ -57,9 +52,9 @@ ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED, AUTH
"INVALID_SELECTORS",
"UNACCEPTABLE_ADDRESSES",
"UNEXPECTED_NAT_DETECTED");
-ENUM_NEXT(notify_type_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
- "P2P_CONNECT_FAILED");
-ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED,
+ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
+ "ME_CONNECT_FAILED");
+ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, ME_CONNECT_FAILED,
"INITIAL_CONTACT",
"SET_WINDOW_SIZE",
"ADDITIONAL_TS_POSSIBLE",
@@ -84,14 +79,15 @@ ENUM_NEXT(notify_type_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, A
"EAP_ONLY_AUTHENTICATION");
ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
"USE_BEET_MODE");
-ENUM_NEXT(notify_type_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
- "P2P_MEDIATION",
- "P2P_ENDPOINT",
- "P2P_CALLBACK",
- "P2P_SESSIONID",
- "P2P_SESSIONKEY",
- "P2P_RESPONSE");
-ENUM_END(notify_type_names, P2P_RESPONSE);
+ENUM_NEXT(notify_type_names, ME_MEDIATION, ME_RESPONSE, USE_BEET_MODE,
+ "ME_MEDIATION",
+ "ME_ENDPOINT",
+ "ME_CALLBACK",
+ "ME_CONNECTID",
+ "ME_CONNECTKEY",
+ "ME_CONNECTAUTH",
+ "ME_RESPONSE");
+ENUM_END(notify_type_names, ME_RESPONSE);
ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
@@ -120,9 +116,9 @@ ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED
"INVAL_SEL",
"UNACCEPT_ADDR",
"UNEXPECT_NAT");
-ENUM_NEXT(notify_type_short_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
- "P2P_CONN_FAIL");
-ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED,
+ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
+ "ME_CONN_FAIL");
+ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, ME_CONNECT_FAILED,
"INIT_CONTACT",
"SET_WINSIZE",
"ADD_TS_POSS",
@@ -147,14 +143,15 @@ ENUM_NEXT(notify_type_short_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICAT
"EAP_ONLY");
ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
"BEET_MODE");
-ENUM_NEXT(notify_type_short_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
- "P2P_MED",
- "P2P_EP",
- "P2P_CB",
- "P2P_SID",
- "P2P_SKEY",
- "P2P_R");
-ENUM_END(notify_type_short_names, P2P_RESPONSE);
+ENUM_NEXT(notify_type_short_names, ME_MEDIATION, ME_RESPONSE, USE_BEET_MODE,
+ "ME_MED",
+ "ME_EP",
+ "ME_CB",
+ "ME_CID",
+ "ME_CKEY",
+ "ME_CAUTH",
+ "ME_R");
+ENUM_END(notify_type_short_names, ME_RESPONSE);
typedef struct private_notify_payload_t private_notify_payload_t;
@@ -293,6 +290,7 @@ static status_t verify(private_notify_payload_t *this)
}
case NAT_DETECTION_SOURCE_IP:
case NAT_DETECTION_DESTINATION_IP:
+ case ME_CONNECTAUTH:
{
if (this->notification_data.len != HASH_SIZE_SHA1)
{
@@ -334,7 +332,36 @@ static status_t verify(private_notify_payload_t *this)
}
break;
}
- /* FIXME: check size of P2P-NAT-T payloads */
+ case IPCOMP_SUPPORTED:
+ {
+ if (this->notification_data.len != 3)
+ {
+ bad_length = TRUE;
+ }
+ break;
+ }
+ case ME_ENDPOINT:
+ if (this->notification_data.len != 8 &&
+ this->notification_data.len != 12 &&
+ this->notification_data.len != 24)
+ {
+ bad_length = TRUE;
+ }
+ break;
+ case ME_CONNECTID:
+ if (this->notification_data.len < 4 ||
+ this->notification_data.len > 16)
+ {
+ bad_length = TRUE;
+ }
+ break;
+ case ME_CONNECTKEY:
+ if (this->notification_data.len < 16 ||
+ this->notification_data.len > 32)
+ {
+ bad_length = TRUE;
+ }
+ break;
default:
/* TODO: verify */
break;
diff --git a/src/charon/encoding/payloads/notify_payload.h b/src/charon/encoding/payloads/notify_payload.h
index 03f61d473..f4a3bf27c 100644
--- a/src/charon/encoding/payloads/notify_payload.h
+++ b/src/charon/encoding/payloads/notify_payload.h
@@ -1,12 +1,5 @@
-/**
- * @file notify_payload.h
- *
- * @brief Interface of notify_payload_t.
- *
- */
-
/*
- * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2006-2008 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -21,8 +14,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: notify_payload.h 3670 2008-03-27 09:54:09Z tobias $
*/
+/**
+ * @defgroup notify_payload notify_payload
+ * @{ @ingroup payloads
+ */
#ifndef NOTIFY_PAYLOAD_H_
#define NOTIFY_PAYLOAD_H_
@@ -37,17 +36,13 @@ typedef struct notify_payload_t notify_payload_t;
/**
* Notify payload length in bytes without any spi and notification data.
- *
- * @ingroup payloads
*/
#define NOTIFY_PAYLOAD_HEADER_LENGTH 8
/**
- * @brief Notify message types.
+ * Notify message types.
*
* See IKEv2 RFC 3.10.1.
- *
- * @ingroup payloads
*/
enum notify_type_t {
/* notify error messages */
@@ -68,8 +63,8 @@ enum notify_type_t {
INVALID_SELECTORS = 39,
UNACCEPTABLE_ADDRESSES = 40,
UNEXPECTED_NAT_DETECTED = 41,
- /* P2P-NAT-T, private use */
- P2P_CONNECT_FAILED = 8192,
+ /* IKE-ME, private use */
+ ME_CONNECT_FAILED = 8192,
/* notify status messages */
INITIAL_CONTACT = 16384,
@@ -98,41 +93,30 @@ enum notify_type_t {
EAP_ONLY_AUTHENTICATION = 40960,
/* BEET mode, not even a draft yet. private use */
USE_BEET_MODE = 40961,
- /* P2P-NAT-T, private use */
- P2P_MEDIATION = 40962,
- P2P_ENDPOINT = 40963,
- P2P_CALLBACK = 40964,
- P2P_SESSIONID = 40965,
- P2P_SESSIONKEY = 40966,
- P2P_RESPONSE = 40967
+ /* IKE-ME, private use */
+ ME_MEDIATION = 40962,
+ ME_ENDPOINT = 40963,
+ ME_CALLBACK = 40964,
+ ME_CONNECTID = 40965,
+ ME_CONNECTKEY = 40966,
+ ME_CONNECTAUTH = 40967,
+ ME_RESPONSE = 40968
};
/**
* enum name for notify_type_t.
- *
- * @ingroup payloads
*/
extern enum_name_t *notify_type_names;
/**
* enum name for notify_type_t (shorter strings).
- *
- * @ingroup payloads
*/
extern enum_name_t *notify_type_short_names;
/**
- * @brief Class representing an IKEv2-Notify Payload.
+ * Class representing an IKEv2-Notify Payload.
*
* The Notify Payload format is described in Draft section 3.10.
- *
- * @b Constructors:
- * - notify_payload_create()
- * - notify_payload_create_from_protocol_and_type()
- *
- * @todo Build specified constructor/getter for notify's
- *
- * @ingroup payloads
*/
struct notify_payload_t {
/**
@@ -141,104 +125,91 @@ struct notify_payload_t {
payload_t payload_interface;
/**
- * @brief Gets the protocol id of this payload.
+ * Gets the protocol id of this payload.
*
- * @param this calling notify_payload_t object
* @return protocol id of this payload
*/
u_int8_t (*get_protocol_id) (notify_payload_t *this);
/**
- * @brief Sets the protocol id of this payload.
+ * Sets the protocol id of this payload.
*
- * @param this calling notify_payload_t object
* @param protocol_id protocol id to set
*/
void (*set_protocol_id) (notify_payload_t *this, u_int8_t protocol_id);
/**
- * @brief Gets the notify message type of this payload.
+ * Gets the notify message type of this payload.
*
- * @param this calling notify_payload_t object
* @return notify message type of this payload
*/
notify_type_t (*get_notify_type) (notify_payload_t *this);
/**
- * @brief Sets notify message type of this payload.
+ * Sets notify message type of this payload.
*
- * @param this calling notify_payload_t object
* @param type notify message type to set
*/
void (*set_notify_type) (notify_payload_t *this, notify_type_t type);
/**
- * @brief Returns the currently set spi of this payload.
+ * Returns the currently set spi of this payload.
*
* This is only valid for notifys with protocol AH|ESP
*
- * @param this calling notify_payload_t object
* @return SPI value
*/
u_int32_t (*get_spi) (notify_payload_t *this);
/**
- * @brief Sets the spi of this payload.
+ * Sets the spi of this payload.
*
* This is only valid for notifys with protocol AH|ESP
*
- * @param this calling notify_payload_t object
* @param spi SPI value
*/
void (*set_spi) (notify_payload_t *this, u_int32_t spi);
/**
- * @brief Returns the currently set notification data of payload.
+ * Returns the currently set notification data of payload.
*
- * @warning Returned data are not copied.
+ * Returned data are not copied.
*
- * @param this calling notify_payload_t object
* @return chunk_t pointing to the value
*/
chunk_t (*get_notification_data) (notify_payload_t *this);
/**
- * @brief Sets the notification data of this payload.
+ * Sets the notification data of this payload.
*
* @warning Value is getting copied.
*
- * @param this calling notify_payload_t object
* @param notification_data chunk_t pointing to the value to set
*/
- void (*set_notification_data) (notify_payload_t *this, chunk_t notification_data);
+ void (*set_notification_data) (notify_payload_t *this,
+ chunk_t notification_data);
/**
- * @brief Destroys an notify_payload_t object.
- *
- * @param this notify_payload_t object to destroy
+ * Destroys an notify_payload_t object.
*/
void (*destroy) (notify_payload_t *this);
};
/**
- * @brief Creates an empty notify_payload_t object
+ * Creates an empty notify_payload_t object
*
* @return created notify_payload_t object
- *
- * @ingroup payloads
*/
notify_payload_t *notify_payload_create(void);
/**
- * @brief Creates an notify_payload_t object of specific type for specific protocol id.
+ * Creates an notify_payload_t object of specific type for specific protocol id.
*
* @param protocol_id protocol id (IKE, AH or ESP)
* @param type notify type (see notify_type_t)
* @return notify_payload_t object
- *
- * @ingroup payloads
*/
-notify_payload_t *notify_payload_create_from_protocol_and_type(protocol_id_t protocol_id, notify_type_t type);
-
+notify_payload_t *notify_payload_create_from_protocol_and_type(
+ protocol_id_t protocol_id, notify_type_t type);
-#endif /*NOTIFY_PAYLOAD_H_*/
+#endif /*NOTIFY_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/payload.c b/src/charon/encoding/payloads/payload.c
index 2c51c60de..17986dd58 100644
--- a/src/charon/encoding/payloads/payload.c
+++ b/src/charon/encoding/payloads/payload.c
@@ -1,11 +1,3 @@
-/**
- * @file payload.c
- *
- * @brief Generic constructor to the payload_t interface.
- *
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
@@ -21,6 +13,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: payload.c 3666 2008-03-26 18:40:19Z tobias $
*/
@@ -64,13 +58,13 @@ ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, N
"ENCRYPTED",
"CONFIGURATION",
"EXTENSIBLE_AUTHENTICATION");
-#ifdef P2P
+#ifdef ME
ENUM_NEXT(payload_type_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION,
"ID_PEER");
ENUM_NEXT(payload_type_names, HEADER, UNKNOWN_PAYLOAD, ID_PEER,
#else
ENUM_NEXT(payload_type_names, HEADER, UNKNOWN_PAYLOAD, EXTENSIBLE_AUTHENTICATION,
-#endif /* P2P */
+#endif /* ME */
"HEADER",
"PROPOSAL_SUBSTRUCTURE",
"TRANSFORM_SUBSTRUCTURE",
@@ -100,13 +94,13 @@ ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICAT
"E",
"CP",
"EAP");
-#ifdef P2P
+#ifdef ME
ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION,
"IDp");
ENUM_NEXT(payload_type_short_names, HEADER, UNKNOWN_PAYLOAD, ID_PEER,
#else
ENUM_NEXT(payload_type_short_names, HEADER, UNKNOWN_PAYLOAD, EXTENSIBLE_AUTHENTICATION,
-#endif /* P2P */
+#endif /* ME */
"HDR",
"PROP",
"TRANS",
@@ -139,10 +133,10 @@ payload_t *payload_create(payload_type_t type)
return (payload_t*)id_payload_create(ID_INITIATOR);
case ID_RESPONDER:
return (payload_t*)id_payload_create(ID_RESPONDER);
-#ifdef P2P
+#ifdef ME
case ID_PEER:
return (payload_t*)id_payload_create(ID_PEER);
-#endif /* P2P */
+#endif /* ME */
case AUTHENTICATION:
return (payload_t*)auth_payload_create();
case CERTIFICATE:
diff --git a/src/charon/encoding/payloads/payload.h b/src/charon/encoding/payloads/payload.h
index ab902d755..abc79259a 100644
--- a/src/charon/encoding/payloads/payload.h
+++ b/src/charon/encoding/payloads/payload.h
@@ -1,10 +1,3 @@
-/**
- * @file payload.h
- *
- * @brief Interface payload_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
@@ -20,6 +13,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: payload.h 3666 2008-03-26 18:40:19Z tobias $
+ */
+
+/**
+ * @defgroup payload payload
+ * @{ @ingroup payloads
*/
#ifndef PAYLOAD_H_
@@ -33,12 +33,10 @@ typedef struct payload_t payload_t;
/**
- * @brief Payload-Types of a IKEv2-Message.
+ * Payload-Types of a IKEv2-Message.
*
* Header and substructures are also defined as
* payload types with values from PRIVATE USE space.
- *
- * @ingroup payloads
*/
enum payload_type_t{
@@ -127,13 +125,13 @@ enum payload_type_t{
*/
EXTENSIBLE_AUTHENTICATION = 48,
-#ifdef P2P
+#ifdef ME
/**
- * Identification payload for peers in P2P-NAT-T has a value from
+ * Identification payload for peers has a value from
* the PRIVATE USE space.
*/
ID_PEER = 128,
-#endif /* P2P */
+#endif /* ME */
/**
* Header has a value of PRIVATE USE space.
@@ -204,80 +202,65 @@ extern enum_name_t *payload_type_names;
extern enum_name_t *payload_type_short_names;
/**
- * @brief Generic interface for all payload types (incl.header and substructures).
+ * Generic interface for all payload types (incl.header and substructures).
*
* To handle all kinds of payloads on a generic way, this interface must
* be implemented by every payload. This allows parser_t/generator_t a simple
* handling of all payloads.
- *
- * @b Constructors:
- * - payload_create() with the payload to instantiate.
- *
- * @ingroup payloads
*/
struct payload_t {
/**
- * @brief Get encoding rules for this payload.
+ * Get encoding rules for this payload.
*
- * @param this calling object
- * @param[out] rules location to store pointer of first rule
- * @param[out] rule_count location to store number of rules
+ * @param rules location to store pointer of first rule
+ * @param rule_count location to store number of rules
*/
void (*get_encoding_rules) (payload_t *this, encoding_rule_t **rules, size_t *rule_count);
/**
- * @brief Get type of payload.
+ * Get type of payload.
*
- * @param this calling object
- * @return type of this payload
+ * @return type of this payload
*/
payload_type_t (*get_type) (payload_t *this);
/**
- * @brief Get type of next payload or NO_PAYLOAD (0) if this is the last one.
+ * Get type of next payload or NO_PAYLOAD (0) if this is the last one.
*
- * @param this calling object
- * @return type of next payload
+ * @return type of next payload
*/
payload_type_t (*get_next_type) (payload_t *this);
/**
- * @brief Set type of next payload.
+ * Set type of next payload.
*
- * @param this calling object
- * @param type type of next payload
+ * @param type type of next payload
*/
void (*set_next_type) (payload_t *this,payload_type_t type);
/**
- * @brief Get length of payload.
+ * Get length of payload.
*
- * @param this calling object
- * @return length of this payload
+ * @return length of this payload
*/
size_t (*get_length) (payload_t *this);
/**
- * @brief Verifies payload structure and makes consistence check.
+ * Verifies payload structure and makes consistence check.
*
- * @param this calling object
- * @return
- * - SUCCESS
- * - FAILED if consistence not given
+ * @return SUCCESS, FAILED if consistence not given
*/
status_t (*verify) (payload_t *this);
/**
- * @brief Destroys a payload and all included substructures.
- *
- * @param this payload to destroy
+ * Destroys a payload and all included substructures.
*/
void (*destroy) (payload_t *this);
};
/**
- * @brief Create an empty payload.
+ * Create an empty payload.
*
* Useful for the parser, who wants a generic constructor for all payloads.
* It supports all payload_t methods. If a payload type is not known,
@@ -288,4 +271,4 @@ struct payload_t {
*/
payload_t *payload_create(payload_type_t type);
-#endif /*PAYLOAD_H_*/
+#endif /*PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/proposal_substructure.c b/src/charon/encoding/payloads/proposal_substructure.c
index 182d2b6e8..daa015d3e 100644
--- a/src/charon/encoding/payloads/proposal_substructure.c
+++ b/src/charon/encoding/payloads/proposal_substructure.c
@@ -1,10 +1,3 @@
-/**
- * @file proposal_substructure.h
- *
- * @brief Implementation of proposal_substructure_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: proposal_substructure.c 3658 2008-03-26 10:06:45Z martin $
*/
#include <stddef.h>
@@ -521,60 +516,62 @@ proposal_substructure_t *proposal_substructure_create()
*/
proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal)
{
- private_proposal_substructure_t *this = (private_proposal_substructure_t*)
- proposal_substructure_create();
- iterator_t *iterator;
- algorithm_t *algo;
transform_substructure_t *transform;
+ private_proposal_substructure_t *this;
+ u_int16_t alg, key_size;
+ enumerator_t *enumerator;
+
+ this = (private_proposal_substructure_t*)proposal_substructure_create();
/* encryption algorithm is only availble in ESP */
- iterator = proposal->create_algorithm_iterator(proposal, ENCRYPTION_ALGORITHM);
- while (iterator->iterate(iterator, (void**)&algo))
+ enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM);
+ while (enumerator->enumerate(enumerator, &alg, &key_size))
{
transform = transform_substructure_create_type(ENCRYPTION_ALGORITHM,
- algo->algorithm, algo->key_size);
- this->public.add_transform_substructure(&(this->public), transform);
+ alg, key_size);
+ add_transform_substructure(this, transform);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* integrity algorithms */
- iterator = proposal->create_algorithm_iterator(proposal, INTEGRITY_ALGORITHM);
- while (iterator->iterate(iterator, (void**)&algo))
+ enumerator = proposal->create_enumerator(proposal, INTEGRITY_ALGORITHM);
+ while (enumerator->enumerate(enumerator, &alg, &key_size))
{
transform = transform_substructure_create_type(INTEGRITY_ALGORITHM,
- algo->algorithm, algo->key_size);
- this->public.add_transform_substructure(&(this->public), transform);
+ alg, key_size);
+ add_transform_substructure(this, transform);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* prf algorithms */
- iterator = proposal->create_algorithm_iterator(proposal, PSEUDO_RANDOM_FUNCTION);
- while (iterator->iterate(iterator, (void**)&algo))
+ enumerator = proposal->create_enumerator(proposal, PSEUDO_RANDOM_FUNCTION);
+ while (enumerator->enumerate(enumerator, &alg, &key_size))
{
transform = transform_substructure_create_type(PSEUDO_RANDOM_FUNCTION,
- algo->algorithm, algo->key_size);
- this->public.add_transform_substructure(&(this->public), transform);
+ alg, key_size);
+ add_transform_substructure(this, transform);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* dh groups */
- iterator = proposal->create_algorithm_iterator(proposal, DIFFIE_HELLMAN_GROUP);
- while (iterator->iterate(iterator, (void**)&algo))
+ enumerator = proposal->create_enumerator(proposal, DIFFIE_HELLMAN_GROUP);
+ while (enumerator->enumerate(enumerator, &alg, NULL))
{
- transform = transform_substructure_create_type(DIFFIE_HELLMAN_GROUP, algo->algorithm, 0);
- this->public.add_transform_substructure(&(this->public), transform);
+ transform = transform_substructure_create_type(DIFFIE_HELLMAN_GROUP,
+ alg, 0);
+ add_transform_substructure(this, transform);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* extended sequence numbers */
- iterator = proposal->create_algorithm_iterator(proposal, EXTENDED_SEQUENCE_NUMBERS);
- while (iterator->iterate(iterator, (void**)&algo))
+ enumerator = proposal->create_enumerator(proposal, EXTENDED_SEQUENCE_NUMBERS);
+ while (enumerator->enumerate(enumerator, &alg, NULL))
{
transform = transform_substructure_create_type(EXTENDED_SEQUENCE_NUMBERS,
- algo->algorithm, 0);
- this->public.add_transform_substructure(&(this->public), transform);
+ alg, 0);
+ add_transform_substructure(this, transform);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* add SPI, if necessary */
switch (proposal->get_protocol(proposal))
diff --git a/src/charon/encoding/payloads/proposal_substructure.h b/src/charon/encoding/payloads/proposal_substructure.h
index 93a8d7b2f..85daadddc 100644
--- a/src/charon/encoding/payloads/proposal_substructure.h
+++ b/src/charon/encoding/payloads/proposal_substructure.h
@@ -1,10 +1,3 @@
-/**
- * @file proposal_substructure.h
- *
- * @brief Interface of proposal_substructure_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: proposal_substructure.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup proposal_substructure proposal_substructure
+ * @{ @ingroup payloads
*/
#ifndef PROPOSAL_SUBSTRUCTURE_H_
@@ -35,20 +35,13 @@ typedef struct proposal_substructure_t proposal_substructure_t;
/**
* Length of the proposal substructure header (without spi).
- *
- * @ingroup payloads
*/
#define PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH 8
/**
- * @brief Class representing an IKEv2-PROPOSAL SUBSTRUCTURE.
+ * Class representing an IKEv2-PROPOSAL SUBSTRUCTURE.
*
* The PROPOSAL SUBSTRUCTURE format is described in RFC section 3.3.1.
- *
- * @b Constructors:
- * - proposal_substructure_create()
- *
- * @ingroup payloads
*/
struct proposal_substructure_t {
/**
@@ -57,150 +50,126 @@ struct proposal_substructure_t {
payload_t payload_interface;
/**
- * @brief Creates an iterator of stored transform_substructure_t objects.
- *
- * @warning The created iterator has to get destroyed by the caller!
- * When deleting any transform over this iterator, call
- * get_size to make sure the length and number values are ok.
+ * Creates an iterator of stored transform_substructure_t objects.
*
- * @param this calling proposal_substructure_t object
* @param forward iterator direction (TRUE: front to end)
* @return created iterator_t object
*/
- iterator_t *(*create_transform_substructure_iterator) (proposal_substructure_t *this, bool forward);
+ iterator_t *(*create_transform_substructure_iterator) (
+ proposal_substructure_t *this, bool forward);
/**
- * @brief Adds a transform_substructure_t object to this object.
- *
- * @warning The added transform_substructure_t object is
- * getting destroyed in destroy function of proposal_substructure_t.
+ * Adds a transform_substructure_t object to this object.
*
- * @param this calling proposal_substructure_t object
- * @param transform transform_substructure_t object to add
+ * @param transform transform_substructure_t object to add
*/
- void (*add_transform_substructure) (proposal_substructure_t *this,transform_substructure_t *transform);
+ void (*add_transform_substructure) (proposal_substructure_t *this,
+ transform_substructure_t *transform);
/**
- * @brief Sets the proposal number of current proposal.
+ * Sets the proposal number of current proposal.
*
- * @param this calling proposal_substructure_t object
- * @param id proposal number to set
+ * @param id proposal number to set
*/
- void (*set_proposal_number) (proposal_substructure_t *this,u_int8_t proposal_number);
+ void (*set_proposal_number) (proposal_substructure_t *this,
+ u_int8_t proposal_number);
/**
- * @brief get proposal number of current proposal.
+ * get proposal number of current proposal.
*
- * @param this calling proposal_substructure_t object
* @return proposal number of current proposal substructure.
*/
u_int8_t (*get_proposal_number) (proposal_substructure_t *this);
/**
- * @brief get the number of transforms in current proposal.
+ * get the number of transforms in current proposal.
*
- * @param this calling proposal_substructure_t object
* @return transform count in current proposal
*/
size_t (*get_transform_count) (proposal_substructure_t *this);
/**
- * @brief get size of the set spi in bytes.
+ * get size of the set spi in bytes.
*
- * @param this calling proposal_substructure_t object
* @return size of the spi in bytes
*/
size_t (*get_spi_size) (proposal_substructure_t *this);
/**
- * @brief Sets the protocol id of current proposal.
+ * Sets the protocol id of current proposal.
*
- * @param this calling proposal_substructure_t object
- * @param id protocol id to set
+ * @param id protocol id to set
*/
- void (*set_protocol_id) (proposal_substructure_t *this,u_int8_t protocol_id);
+ void (*set_protocol_id) (proposal_substructure_t *this,
+ u_int8_t protocol_id);
/**
- * @brief get protocol id of current proposal.
+ * get protocol id of current proposal.
*
- * @param this calling proposal_substructure_t object
* @return protocol id of current proposal substructure.
*/
u_int8_t (*get_protocol_id) (proposal_substructure_t *this);
/**
- * @brief Sets the next_payload field of this substructure
+ * Sets the next_payload field of this substructure
*
* If this is the last proposal, next payload field is set to 0,
* otherwise to 2
*
- * @param this calling proposal_substructure_t object
* @param is_last When TRUE, next payload field is set to 0, otherwise to 2
*/
void (*set_is_last_proposal) (proposal_substructure_t *this, bool is_last);
/**
- * @brief Returns the currently set SPI of this proposal.
- *
- * @warning Returned data are not copied
- *
- * @param this calling proposal_substructure_t object
- * @return chunk_t pointing to the value
+ * Returns the currently set SPI of this proposal.
+ *
+ * @return chunk_t pointing to the value
*/
chunk_t (*get_spi) (proposal_substructure_t *this);
/**
- * @brief Sets the SPI of the current proposal.
+ * Sets the SPI of the current proposal.
*
* @warning SPI is getting copied
*
- * @param this calling proposal_substructure_t object
- * @param spi chunk_t pointing to the value to set
+ * @param spi chunk_t pointing to the value to set
*/
void (*set_spi) (proposal_substructure_t *this, chunk_t spi);
/**
- * @brief Get a proposal_t from the propsal_substructure_t.
+ * Get a proposal_t from the propsal_substructure_t.
*
- * @param this calling proposal_substructure_t object
* @return proposal_t
*/
proposal_t * (*get_proposal) (proposal_substructure_t *this);
/**
- * @brief Clones an proposal_substructure_t object.
+ * Clones an proposal_substructure_t object.
*
- * @param this proposal_substructure_t object to clone
* @return cloned object
*/
proposal_substructure_t* (*clone) (proposal_substructure_t *this);
/**
- * @brief Destroys an proposal_substructure_t object.
- *
- * @param this proposal_substructure_t object to destroy
+ * Destroys an proposal_substructure_t object.
*/
void (*destroy) (proposal_substructure_t *this);
};
/**
- * @brief Creates an empty proposal_substructure_t object
+ * Creates an empty proposal_substructure_t object
*
* @return proposal_substructure_t object
- *
- * @ingroup payloads
*/
proposal_substructure_t *proposal_substructure_create(void);
/**
- * @brief Creates a proposal_substructure_t from a proposal_t.
+ * Creates a proposal_substructure_t from a proposal_t.
*
* @param proposal proposal to build a substruct out of it
* @return proposal_substructure_t object
- *
- * @ingroup payloads
*/
-proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal);
-
+proposal_substructure_t *proposal_substructure_create_from_proposal(
+ proposal_t *proposal);
-#endif /*PROPOSAL_SUBSTRUCTURE_H_*/
+#endif /*PROPOSAL_SUBSTRUCTURE_H_ @} */
diff --git a/src/charon/encoding/payloads/sa_payload.c b/src/charon/encoding/payloads/sa_payload.c
index 304f1b64c..ecc3b0f60 100644
--- a/src/charon/encoding/payloads/sa_payload.c
+++ b/src/charon/encoding/payloads/sa_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file sa_payload.c
- *
- * @brief Implementation of sa_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: sa_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/sa_payload.h b/src/charon/encoding/payloads/sa_payload.h
index 67d687857..34906c889 100644
--- a/src/charon/encoding/payloads/sa_payload.h
+++ b/src/charon/encoding/payloads/sa_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file sa_payload.h
- *
- * @brief Interface of sa_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: sa_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup sa_payload sa_payload
+ * @{ @ingroup payloads
*/
#ifndef SA_PAYLOAD_H_
@@ -33,24 +33,13 @@ typedef struct sa_payload_t sa_payload_t;
/**
* SA_PAYLOAD length in bytes without any proposal substructure.
- *
- * @ingroup payloads
*/
#define SA_PAYLOAD_HEADER_LENGTH 4
/**
- * @brief Class representing an IKEv2-SA Payload.
+ * Class representing an IKEv2-SA Payload.
*
* The SA Payload format is described in RFC section 3.3.
- *
- * @b Constructors:
- * - sa_payload_create()
- * - sa_payload_create_from_ike_proposals()
- * - sa_payload_create_from_proposal()
- *
- * @todo Add support of algorithms without specified keylength in get_proposals and get_ike_proposals.
- *
- * @ingroup payloads
*/
struct sa_payload_t {
/**
@@ -59,83 +48,70 @@ struct sa_payload_t {
payload_t payload_interface;
/**
- * @brief Creates an iterator of stored proposal_substructure_t objects.
+ * Creates an iterator of stored proposal_substructure_t objects.
*
- * @warning The created iterator has to get destroyed by the caller!
- *
- * @warning When deleting an proposal using this iterator,
- * the length of this transform substructure has to be refreshed
- * by calling get_length()!
+ * When deleting an proposal using this iterator,
+ * the length of this transform substructure has to be refreshed
+ * by calling get_length()!
*
- * @param this calling sa_payload_t object
- * @param[in] forward iterator direction (TRUE: front to end)
- * @return created iterator_t object
+ * @param forward iterator direction (TRUE: front to end)
+ * @return created iterator_t object
*/
- iterator_t *(*create_proposal_substructure_iterator) (sa_payload_t *this, bool forward);
+ iterator_t *(*create_proposal_substructure_iterator) (sa_payload_t *this,
+ bool forward);
/**
- * @brief Adds a proposal_substructure_t object to this object.
- *
- * @warning The added proposal_substructure_t object is
- * getting destroyed in destroy function of sa_payload_t.
+ * Adds a proposal_substructure_t object to this object.
*
- * @param this calling sa_payload_t object
* @param proposal proposal_substructure_t object to add
*/
- void (*add_proposal_substructure) (sa_payload_t *this,proposal_substructure_t *proposal);
+ void (*add_proposal_substructure) (sa_payload_t *this,
+ proposal_substructure_t *proposal);
/**
- * @brief Gets the proposals in this payload as a list.
+ * Gets the proposals in this payload as a list.
*
* @return a list containing proposal_t s
*/
linked_list_t *(*get_proposals) (sa_payload_t *this);
/**
- * @brief Add a child proposal (AH/ESP) to the payload.
+ * Add a child proposal (AH/ESP) to the payload.
*
* @param proposal child proposal to add to the payload
*/
void (*add_proposal) (sa_payload_t *this, proposal_t *proposal);
/**
- * @brief Destroys an sa_payload_t object.
- *
- * @param this sa_payload_t object to destroy
+ * Destroys an sa_payload_t object.
*/
void (*destroy) (sa_payload_t *this);
};
/**
- * @brief Creates an empty sa_payload_t object
+ * Creates an empty sa_payload_t object
*
* @return created sa_payload_t object
- *
- * @ingroup payloads
*/
sa_payload_t *sa_payload_create(void);
/**
- * @brief Creates a sa_payload_t object from a list of proposals.
+ * Creates a sa_payload_t object from a list of proposals.
*
* @param proposals list of proposals to build the payload from
* @return sa_payload_t object
- *
- * @ingroup payloads
*/
sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals);
/**
- * @brief Creates a sa_payload_t object from a single proposal.
+ * Creates a sa_payload_t object from a single proposal.
*
* This is only for convenience. Use sa_payload_create_from_proposal_list
* if you want to add more than one proposal.
*
* @param proposal proposal from which the payload should be built.
* @return sa_payload_t object
- *
- * @ingroup payloads
*/
sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal);
-#endif /*SA_PAYLOAD_H_*/
+#endif /*SA_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/traffic_selector_substructure.c b/src/charon/encoding/payloads/traffic_selector_substructure.c
index 573139bf3..f6042b4b6 100644
--- a/src/charon/encoding/payloads/traffic_selector_substructure.c
+++ b/src/charon/encoding/payloads/traffic_selector_substructure.c
@@ -1,10 +1,3 @@
-/**
- * @file traffic_selector_substructure.c
- *
- * @brief Interface of traffic_selector_substructure_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: traffic_selector_substructure.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "traffic_selector_substructure.h"
diff --git a/src/charon/encoding/payloads/traffic_selector_substructure.h b/src/charon/encoding/payloads/traffic_selector_substructure.h
index 14efccc89..2a2769fb6 100644
--- a/src/charon/encoding/payloads/traffic_selector_substructure.h
+++ b/src/charon/encoding/payloads/traffic_selector_substructure.h
@@ -1,10 +1,3 @@
-/**
- * @file traffic_selector_substructure.h
- *
- * @brief Interface of traffic_selector_substructure_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,8 +12,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: traffic_selector_substructure.h 3589 2008-03-13 14:14:44Z martin $
*/
+/**
+ * @defgroup traffic_selector_substructure traffic_selector_substructure
+ * @{ @ingroup payloads
+ */
#ifndef TRAFFIC_SELECTOR_SUBSTRUCTURE_H_
#define TRAFFIC_SELECTOR_SUBSTRUCTURE_H_
@@ -34,21 +33,13 @@ typedef struct traffic_selector_substructure_t traffic_selector_substructure_t;
/**
* Length of a TRAFFIC SELECTOR SUBSTRUCTURE without start and end address.
- *
- * @ingroup payloads
*/
#define TRAFFIC_SELECTOR_HEADER_LENGTH 8
/**
- * @brief Class representing an IKEv2 TRAFFIC SELECTOR.
+ * Class representing an IKEv2 TRAFFIC SELECTOR.
*
* The TRAFFIC SELECTOR format is described in RFC section 3.13.1.
- *
- * @b Constructors:
- * - traffic_selector_substructure_create()
- * - traffic_selector_substructure_create_from_traffic_selector()
- *
- * @ingroup payloads
*/
struct traffic_selector_substructure_t {
/**
@@ -57,116 +48,106 @@ struct traffic_selector_substructure_t {
payload_t payload_interface;
/**
- * @brief Get the type of Traffic selector.
+ * Get the type of Traffic selector.
*
- * @param this calling traffic_selector_substructure_t object
* @return type of traffic selector
*
*/
ts_type_t (*get_ts_type) (traffic_selector_substructure_t *this);
/**
- * @brief Set the type of Traffic selector.
+ * Set the type of Traffic selector.
*
- * @param this calling traffic_selector_substructure_t object
* @param ts_type type of traffic selector
*/
- void (*set_ts_type) (traffic_selector_substructure_t *this,ts_type_t ts_type);
+ void (*set_ts_type) (traffic_selector_substructure_t *this,
+ ts_type_t ts_type);
/**
- * @brief Get the IP protocol ID of Traffic selector.
+ * Get the IP protocol ID of Traffic selector.
*
- * @param this calling traffic_selector_substructure_t object
* @return type of traffic selector
*
*/
u_int8_t (*get_protocol_id) (traffic_selector_substructure_t *this);
/**
- * @brief Set the IP protocol ID of Traffic selector
+ * Set the IP protocol ID of Traffic selector
*
- * @param this calling traffic_selector_substructure_t object
* @param protocol_id protocol ID of traffic selector
*/
- void (*set_protocol_id) (traffic_selector_substructure_t *this,u_int8_t protocol_id);
+ void (*set_protocol_id) (traffic_selector_substructure_t *this,
+ u_int8_t protocol_id);
/**
- * @brief Get the start port and address as host_t object.
+ * Get the start port and address as host_t object.
*
* Returned host_t object has to get destroyed by the caller.
*
- * @param this calling traffic_selector_substructure_t object
* @return start host as host_t object
*
*/
host_t *(*get_start_host) (traffic_selector_substructure_t *this);
/**
- * @brief Set the start port and address as host_t object.
+ * Set the start port and address as host_t object.
*
- * @param this calling traffic_selector_substructure_t object
* @param start_host start host as host_t object
*/
- void (*set_start_host) (traffic_selector_substructure_t *this,host_t *start_host);
+ void (*set_start_host) (traffic_selector_substructure_t *this,
+ host_t *start_host);
/**
- * @brief Get the end port and address as host_t object.
+ * Get the end port and address as host_t object.
*
* Returned host_t object has to get destroyed by the caller.
*
- * @param this calling traffic_selector_substructure_t object
* @return end host as host_t object
*
*/
host_t *(*get_end_host) (traffic_selector_substructure_t *this);
/**
- * @brief Set the end port and address as host_t object.
+ * Set the end port and address as host_t object.
*
- * @param this calling traffic_selector_substructure_t object
* @param end_host end host as host_t object
*/
- void (*set_end_host) (traffic_selector_substructure_t *this,host_t *end_host);
+ void (*set_end_host) (traffic_selector_substructure_t *this,
+ host_t *end_host);
/**
- * @brief Get a traffic_selector_t from this substructure.
+ * Get a traffic_selector_t from this substructure.
*
* @warning traffic_selector_t must be destroyed after usage.
*
- * @param this calling traffic_selector_substructure_t object
* @return contained traffic_selector_t
*/
- traffic_selector_t *(*get_traffic_selector) (traffic_selector_substructure_t *this);
+ traffic_selector_t *(*get_traffic_selector) (
+ traffic_selector_substructure_t *this);
/**
- * @brief Destroys an traffic_selector_substructure_t object.
- *
- * @param this traffic_selector_substructure_t object to destroy
+ * Destroys an traffic_selector_substructure_t object.
*/
void (*destroy) (traffic_selector_substructure_t *this);
};
/**
- * @brief Creates an empty traffic_selector_substructure_t object.
+ * Creates an empty traffic_selector_substructure_t object.
*
* TS type is set to default TS_IPV4_ADDR_RANGE!
*
* @return traffic_selector_substructure_t object
- *
- * @ingroup payloads
*/
traffic_selector_substructure_t *traffic_selector_substructure_create(void);
/**
- * @brief Creates an initialized traffif selector substructure using
+ * Creates an initialized traffif selector substructure using
* the values from a traffic_selector_t.
*
* @param traffic_selector traffic_selector_t to use for initialization
* @return traffic_selector_substructure_t object
- *
- * @ingroup payloads
*/
-traffic_selector_substructure_t *traffic_selector_substructure_create_from_traffic_selector(traffic_selector_t *traffic_selector);
-
+traffic_selector_substructure_t *traffic_selector_substructure_create_from_traffic_selector(
+ traffic_selector_t *traffic_selector);
-#endif /* /TRAFFIC_SELECTOR_SUBSTRUCTURE_H_ */
+#endif /* /TRAFFIC_SELECTOR_SUBSTRUCTURE_H_ @} */
diff --git a/src/charon/encoding/payloads/transform_attribute.c b/src/charon/encoding/payloads/transform_attribute.c
index 066885c55..b9b5ff879 100644
--- a/src/charon/encoding/payloads/transform_attribute.c
+++ b/src/charon/encoding/payloads/transform_attribute.c
@@ -1,10 +1,3 @@
-/**
- * @file transform_attribute.c
- *
- * @brief Implementation of transform_attribute_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: transform_attribute.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <string.h>
diff --git a/src/charon/encoding/payloads/transform_attribute.h b/src/charon/encoding/payloads/transform_attribute.h
index 30583b23f..891155913 100644
--- a/src/charon/encoding/payloads/transform_attribute.h
+++ b/src/charon/encoding/payloads/transform_attribute.h
@@ -1,10 +1,3 @@
-/**
- * @file transform_attribute.h
- *
- * @brief Interface of transform_attribute_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: transform_attribute.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup transform_attribute transform_attribute
+ * @{ @ingroup payloads
*/
#ifndef TRANSFORM_ATTRIBUTE_H_
@@ -33,8 +33,6 @@ typedef struct transform_attribute_t transform_attribute_t;
/**
* Type of the attribute, as in IKEv2 RFC 3.3.5.
- *
- * @ingroup payloads
*/
enum transform_attribute_type_t {
ATTRIBUTE_UNDEFINED = 16384,
@@ -43,17 +41,13 @@ enum transform_attribute_type_t {
/**
* enum name for transform_attribute_type_t.
- *
- * @ingroup payloads
*/
extern enum_name_t *transform_attribute_type_names;
/**
- * @brief Class representing an IKEv2- TRANSFORM Attribute.
+ * Class representing an IKEv2- TRANSFORM Attribute.
*
* The TRANSFORM ATTRIBUTE format is described in RFC section 3.3.5.
- *
- * @ingroup payloads
*/
struct transform_attribute_t {
/**
@@ -62,93 +56,79 @@ struct transform_attribute_t {
payload_t payload_interface;
/**
- * @brief Returns the currently set value of the attribute.
+ * Returns the currently set value of the attribute.
*
- * @warning Returned data are not copied.
+ * Returned data are not copied.
*
- * @param this calling transform_attribute_t object
* @return chunk_t pointing to the value
*/
chunk_t (*get_value_chunk) (transform_attribute_t *this);
/**
- * @brief Returns the currently set value of the attribute.
+ * Returns the currently set value of the attribute.
*
- * @warning Returned data are not copied.
+ * Returned data are not copied.
*
- * @param this calling transform_attribute_t object
* @return value
*/
u_int16_t (*get_value) (transform_attribute_t *this);
/**
- * @brief Sets the value of the attribute.
+ * Sets the value of the attribute.
*
- * @warning Value is getting copied.
+ * Value is getting copied.
*
- * @param this calling transform_attribute_t object
* @param value chunk_t pointing to the value to set
*/
void (*set_value_chunk) (transform_attribute_t *this, chunk_t value);
/**
- * @brief Sets the value of the attribute.
+ * Sets the value of the attribute.
*
- * @param this calling transform_attribute_t object
* @param value value to set
*/
void (*set_value) (transform_attribute_t *this, u_int16_t value);
/**
- * @brief Sets the type of the attribute.
+ * Sets the type of the attribute.
*
- * @param this calling transform_attribute_t object
* @param type type to set (most significant bit is set to zero)
*/
void (*set_attribute_type) (transform_attribute_t *this, u_int16_t type);
/**
- * @brief get the type of the attribute.
+ * get the type of the attribute.
*
- * @param this calling transform_attribute_t object
* @return type of the value
*/
u_int16_t (*get_attribute_type) (transform_attribute_t *this);
/**
- * @brief Clones an transform_attribute_t object.
+ * Clones an transform_attribute_t object.
*
- * @param this transform_attribute_t object to clone
* @return cloned transform_attribute_t object
*/
transform_attribute_t * (*clone) (transform_attribute_t *this);
/**
- * @brief Destroys an transform_attribute_t object.
- *
- * @param this transform_attribute_t object to destroy
+ * Destroys an transform_attribute_t object.
*/
void (*destroy) (transform_attribute_t *this);
};
/**
- * @brief Creates an empty transform_attribute_t object.
+ * Creates an empty transform_attribute_t object.
*
* @return transform_attribute_t object
- *
- * @ingroup payloads
*/
transform_attribute_t *transform_attribute_create(void);
/**
- * @brief Creates an transform_attribute_t of type KEY_LENGTH.
+ * Creates an transform_attribute_t of type KEY_LENGTH.
*
* @param key_length key length in bytes
* @return transform_attribute_t object
- *
- * @ingroup payloads
*/
transform_attribute_t *transform_attribute_create_key_length(u_int16_t key_length);
-
-#endif /*TRANSFORM_ATTRIBUTE_H_*/
+#endif /*TRANSFORM_ATTRIBUTE_H_ @} */
diff --git a/src/charon/encoding/payloads/transform_substructure.c b/src/charon/encoding/payloads/transform_substructure.c
index d64d6c754..7c3d6421a 100644
--- a/src/charon/encoding/payloads/transform_substructure.c
+++ b/src/charon/encoding/payloads/transform_substructure.c
@@ -1,10 +1,3 @@
-/**
- * @file transform_substructure.h
- *
- * @brief Implementation of transform_substructure_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: transform_substructure.c 3971 2008-05-16 13:27:21Z tobias $
*/
#include <stddef.h>
@@ -395,14 +390,28 @@ transform_substructure_t *transform_substructure_create_type(transform_type_t tr
transform->set_transform_id(transform,transform_id);
/* a keylength attribute is only created for variable length algos */
- if (transform_type == ENCRYPTION_ALGORITHM &&
- (transform_id == ENCR_AES_CBC ||
- transform_id == ENCR_IDEA ||
- transform_id == ENCR_CAST ||
- transform_id == ENCR_BLOWFISH))
+ if (transform_type == ENCRYPTION_ALGORITHM)
{
- transform_attribute_t *attribute = transform_attribute_create_key_length(key_length);
- transform->add_transform_attribute(transform,attribute);
+ switch(transform_id)
+ {
+ case ENCR_AES_CBC:
+ case ENCR_IDEA:
+ case ENCR_CAST:
+ case ENCR_BLOWFISH:
+ case ENCR_AES_CCM_ICV8:
+ case ENCR_AES_CCM_ICV12:
+ case ENCR_AES_CCM_ICV16:
+ case ENCR_AES_GCM_ICV8:
+ case ENCR_AES_GCM_ICV12:
+ case ENCR_AES_GCM_ICV16:
+ {
+ transform_attribute_t *attribute = transform_attribute_create_key_length(key_length);
+ transform->add_transform_attribute(transform,attribute);
+ break;
+ }
+ default:
+ break;
+ }
}
return transform;
diff --git a/src/charon/encoding/payloads/transform_substructure.h b/src/charon/encoding/payloads/transform_substructure.h
index 97f587d5d..6be4b6d1e 100644
--- a/src/charon/encoding/payloads/transform_substructure.h
+++ b/src/charon/encoding/payloads/transform_substructure.h
@@ -1,10 +1,3 @@
-/**
- * @file transform_substructure.h
- *
- * @brief Interface of transform_substructure_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: transform_substructure.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup transform_substructure transform_substructure
+ * @{ @ingroup payloads
*/
#ifndef TRANSFORM_SUBSTRUCTURE_H_
@@ -39,25 +39,19 @@ typedef struct transform_substructure_t transform_substructure_t;
/**
* IKEv1 Value for a transform payload.
- *
- * @ingroup payloads
*/
#define TRANSFORM_TYPE_VALUE 3
/**
* Length of the transform substructure header in bytes.
- *
- * @ingroup payloads
*/
#define TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH 8
/**
- * @brief Class representing an IKEv2- TRANSFORM SUBSTRUCTURE.
+ * Class representing an IKEv2- TRANSFORM SUBSTRUCTURE.
*
* The TRANSFORM SUBSTRUCTURE format is described in RFC section 3.3.2.
- *
- * @ingroup payloads
*/
struct transform_substructure_t {
/**
@@ -66,121 +60,105 @@ struct transform_substructure_t {
payload_t payload_interface;
/**
- * @brief Creates an iterator of stored transform_attribute_t objects.
- *
- * @warning The created iterator has to get destroyed by the caller!
+ * Creates an iterator of stored transform_attribute_t objects.
*
- * @warning When deleting an transform attribute using this iterator,
- * the length of this transform substructure has to be refreshed
- * by calling get_length()!
+ * When deleting an transform attribute using this iterator,
+ * the length of this transform substructure has to be refreshed
+ * by calling get_length().
*
- * @param this calling transform_substructure_t object
- * @param[in] forward iterator direction (TRUE: front to end)
+ * @param forward iterator direction (TRUE: front to end)
* @return created iterator_t object.
*/
- iterator_t * (*create_transform_attribute_iterator) (transform_substructure_t *this, bool forward);
+ iterator_t * (*create_transform_attribute_iterator) (
+ transform_substructure_t *this, bool forward);
/**
- * @brief Adds a transform_attribute_t object to this object.
- *
- * @warning The added proposal_substructure_t object is
- * getting destroyed in destroy function of transform_substructure_t.
+ * Adds a transform_attribute_t object to this object.
*
- * @param this calling transform_substructure_t object
* @param proposal transform_attribute_t object to add
*/
- void (*add_transform_attribute) (transform_substructure_t *this,transform_attribute_t *attribute);
+ void (*add_transform_attribute) (transform_substructure_t *this,
+ transform_attribute_t *attribute);
/**
- * @brief Sets the next_payload field of this substructure
+ * Sets the next_payload field of this substructure
*
* If this is the last transform, next payload field is set to 0,
* otherwise to 3
*
- * @param this calling transform_substructure_t object
* @param is_last When TRUE, next payload field is set to 0, otherwise to 3
*/
void (*set_is_last_transform) (transform_substructure_t *this, bool is_last);
/**
- * @brief Checks if this is the last transform.
+ * Checks if this is the last transform.
*
- * @param this calling transform_substructure_t object
* @return TRUE if this is the last Transform, FALSE otherwise
*/
bool (*get_is_last_transform) (transform_substructure_t *this);
/**
- * @brief Sets transform type of the current transform substructure.
+ * Sets transform type of the current transform substructure.
*
- * @param this calling transform_substructure_t object
* @param type type value to set
*/
- void (*set_transform_type) (transform_substructure_t *this,u_int8_t type);
+ void (*set_transform_type) (transform_substructure_t *this, u_int8_t type);
/**
- * @brief get transform type of the current transform.
+ * get transform type of the current transform.
*
- * @param this calling transform_substructure_t object
* @return Transform type of current transform substructure.
*/
u_int8_t (*get_transform_type) (transform_substructure_t *this);
/**
- * @brief Sets transform id of the current transform substructure.
+ * Sets transform id of the current transform substructure.
*
- * @param this calling transform_substructure_t object
- * @param id transform id to set
+ * @param id transform id to set
*/
- void (*set_transform_id) (transform_substructure_t *this,u_int16_t id);
+ void (*set_transform_id) (transform_substructure_t *this, u_int16_t id);
/**
- * @brief get transform id of the current transform.
+ * get transform id of the current transform.
*
- * @param this calling transform_substructure_t object
* @return Transform id of current transform substructure.
*/
u_int16_t (*get_transform_id) (transform_substructure_t *this);
/**
- * @brief get transform id of the current transform.
+ * get transform id of the current transform.
*
- * @param this calling transform_substructure_t object
- * @param key_length The key length is written to this location
+ * @param key_length The key length is written to this location
* @return
* - SUCCESS if a key length attribute is contained
* - FAILED if no key length attribute is part of this
* transform or key length uses more then 16 bit!
*/
- status_t (*get_key_length) (transform_substructure_t *this,u_int16_t *key_length);
+ status_t (*get_key_length) (transform_substructure_t *this,
+ u_int16_t *key_length);
/**
- * @brief Clones an transform_substructure_t object.
+ * Clones an transform_substructure_t object.
*
- * @param this transform_substructure_t object to clone
* @return cloned transform_substructure_t object
*/
transform_substructure_t* (*clone) (transform_substructure_t *this);
/**
- * @brief Destroys an transform_substructure_t object.
- *
- * @param this transform_substructure_t object to destroy
+ * Destroys an transform_substructure_t object.
*/
void (*destroy) (transform_substructure_t *this);
};
/**
- * @brief Creates an empty transform_substructure_t object.
+ * Creates an empty transform_substructure_t object.
*
* @return created transform_substructure_t object
- *
- * @ingroup payloads
*/
transform_substructure_t *transform_substructure_create(void);
/**
- * @brief Creates an empty transform_substructure_t object.
+ * Creates an empty transform_substructure_t object.
*
* The key length is used for the transport types ENCRYPTION_ALGORITHM,
* PSEUDO_RANDOM_FUNCTION, INTEGRITY_ALGORITHM. For all
@@ -190,9 +168,9 @@ transform_substructure_t *transform_substructure_create(void);
* @param transform_id transform id specifying the specific algorithm of a transform type
* @param key_length Key length for key lenght attribute
* @return transform_substructure_t object
- *
- * @ingroup payloads
*/
-transform_substructure_t *transform_substructure_create_type(transform_type_t transform_type, u_int16_t transform_id, u_int16_t key_length);
+transform_substructure_t *transform_substructure_create_type(
+ transform_type_t transform_type, u_int16_t transform_id,
+ u_int16_t key_length);
-#endif /*TRANSFORM_SUBSTRUCTURE_H_*/
+#endif /*TRANSFORM_SUBSTRUCTURE_H_ @} */
diff --git a/src/charon/encoding/payloads/ts_payload.c b/src/charon/encoding/payloads/ts_payload.c
index ae89919f6..5d53793b1 100644
--- a/src/charon/encoding/payloads/ts_payload.c
+++ b/src/charon/encoding/payloads/ts_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file ts_payload.c
- *
- * @brief Implementation of ts_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ts_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/ts_payload.h b/src/charon/encoding/payloads/ts_payload.h
index 1addee22c..d8a108ddd 100644
--- a/src/charon/encoding/payloads/ts_payload.h
+++ b/src/charon/encoding/payloads/ts_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file ts_payload.h
- *
- * @brief Interface of ts_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ts_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ts_payload ts_payload
+ * @{ @ingroup payloads
*/
@@ -35,22 +35,14 @@ typedef struct ts_payload_t ts_payload_t;
/**
* Length of a TS payload without the Traffic selectors.
- *
- * @ingroup payloads
*/
#define TS_PAYLOAD_HEADER_LENGTH 8
/**
- * @brief Class representing an IKEv2 TS payload.
+ * Class representing an IKEv2 TS payload.
*
* The TS payload format is described in RFC section 3.13.
- *
- * @b Constructors:
- * - ts_payload_create()
- * - ts_payload_create_from_traffic_selectors()
- *
- * @ingroup payloads
*/
struct ts_payload_t {
/**
@@ -59,9 +51,8 @@ struct ts_payload_t {
payload_t payload_interface;
/**
- * @brief Get the type of TSpayload (TSi or TSr).
+ * Get the type of TSpayload (TSi or TSr).
*
- * @param this calling id_payload_t object
* @return
* - TRUE if this payload is of type TSi
* - FALSE if this payload is of type TSr
@@ -69,9 +60,8 @@ struct ts_payload_t {
bool (*get_initiator) (ts_payload_t *this);
/**
- * @brief Set the type of TS payload (TSi or TSr).
+ * Set the type of TS payload (TSi or TSr).
*
- * @param this calling id_payload_t object
* @param is_initiator
* - TRUE if this payload is of type TSi
* - FALSE if this payload is of type TSr
@@ -79,75 +69,61 @@ struct ts_payload_t {
void (*set_initiator) (ts_payload_t *this,bool is_initiator);
/**
- * @brief Adds a traffic_selector_substructure_t object to this object.
- *
- * @warning The added traffic_selector_substructure_t object is
- * getting destroyed in destroy function of ts_payload_t.
+ * Adds a traffic_selector_substructure_t object to this object.
*
- * @param this calling ts_payload_t object
* @param traffic_selector traffic_selector_substructure_t object to add
*/
- void (*add_traffic_selector_substructure) (ts_payload_t *this,traffic_selector_substructure_t *traffic_selector);
+ void (*add_traffic_selector_substructure) (ts_payload_t *this,
+ traffic_selector_substructure_t *traffic_selector);
/**
- * @brief Creates an iterator of stored traffic_selector_substructure_t objects.
+ * Creates an iterator of stored traffic_selector_substructure_t objects.
*
- * @warning The created iterator has to get destroyed by the caller!
- *
- * @warning When removing an traffic_selector_substructure_t object
- * using this iterator, the length of this payload
- * has to get refreshed by calling payload_t.get_length!
+ * When removing an traffic_selector_substructure_t object
+ * using this iterator, the length of this payload
+ * has to get refreshed by calling payload_t.get_length!
*
- * @param this calling ts_payload_t object
- * @param[in] forward iterator direction (TRUE: front to end)
+ * @param forward iterator direction (TRUE: front to end)
* @return created iterator_t object
*/
- iterator_t *(*create_traffic_selector_substructure_iterator) (ts_payload_t *this, bool forward);
+ iterator_t *(*create_traffic_selector_substructure_iterator) (
+ ts_payload_t *this, bool forward);
/**
- * @brief Get a list of nested traffic selectors as traffic_selector_t.
+ * Get a list of nested traffic selectors as traffic_selector_t.
*
* Resulting list and its traffic selectors must be destroyed after usage
*
- * @param this calling ts_payload_t object
* @return list of traffic selectors
*/
linked_list_t *(*get_traffic_selectors) (ts_payload_t *this);
/**
- * @brief Destroys an ts_payload_t object.
- *
- * @param this ts_payload_t object to destroy
+ * Destroys an ts_payload_t object.
*/
void (*destroy) (ts_payload_t *this);
};
/**
- * @brief Creates an empty ts_payload_t object.
- *
+ * Creates an empty ts_payload_t object.
*
* @param is_initiator
* - TRUE if this payload is of type TSi
* - FALSE if this payload is of type TSr
* @return ts_payload_t object
- *
- * @ingroup payloads
*/
ts_payload_t *ts_payload_create(bool is_initiator);
/**
- * @brief Creates ts_payload with a list of traffic_selector_t
- *
+ * Creates ts_payload with a list of traffic_selector_t
*
* @param is_initiator
* - TRUE if this payload is of type TSi
* - FALSE if this payload is of type TSr
* @param traffic_selectors list of traffic selectors to include
* @return ts_payload_t object
- *
- * @ingroup payloads
*/
-ts_payload_t *ts_payload_create_from_traffic_selectors(bool is_initiator, linked_list_t *traffic_selectors);
-
+ts_payload_t *ts_payload_create_from_traffic_selectors(bool is_initiator,
+ linked_list_t *traffic_selectors);
-#endif /* TS_PAYLOAD_H_ */
+#endif /* TS_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/unknown_payload.c b/src/charon/encoding/payloads/unknown_payload.c
index bbe736085..8a8db308d 100644
--- a/src/charon/encoding/payloads/unknown_payload.c
+++ b/src/charon/encoding/payloads/unknown_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file unknown_payload.c
- *
- * @brief Implementation of unknown_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: unknown_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/unknown_payload.h b/src/charon/encoding/payloads/unknown_payload.h
index 8d13a03a3..045448f06 100644
--- a/src/charon/encoding/payloads/unknown_payload.h
+++ b/src/charon/encoding/payloads/unknown_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file unknown_payload.h
- *
- * @brief Interface of unknown_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: unknown_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup unknown_payload unknown_payload
+ * @{ @ingroup payloads
*/
#ifndef UNKNOWN_PAYLOAD_H_
@@ -31,22 +31,15 @@ typedef struct unknown_payload_t unknown_payload_t;
/**
* Header length of the unknown payload.
- *
- * @ingroup payloads
*/
#define UNKNOWN_PAYLOAD_HEADER_LENGTH 4
/**
- * @brief Payload which can't be processed further.
+ * Payload which can't be processed further.
*
* When the parser finds an unknown payload, he builds an instance of
* this class. This allows further processing of this payload, such as
* a check for the critical bit in the header.
- *
- * @b Constructors:
- * - unknown_payload_create()
- *
- * @ingroup payloads
*/
struct unknown_payload_t {
@@ -56,40 +49,33 @@ struct unknown_payload_t {
payload_t payload_interface;
/**
- * @brief Get the raw data of this payload, without
+ * Get the raw data of this payload, without
* the generic payload header.
*
* Returned data are NOT copied and must not be freed.
*
- * @param this calling unknown_payload_t object
* @return data as chunk_t
*/
chunk_t (*get_data) (unknown_payload_t *this);
/**
- * @brief Get the critical flag.
+ * Get the critical flag.
*
- * @param this calling unknown_payload_t object
* @return TRUE if payload is critical, FALSE if not
*/
bool (*is_critical) (unknown_payload_t *this);
/**
- * @brief Destroys an unknown_payload_t object.
- *
- * @param this unknown_payload_t object to destroy
+ * Destroys an unknown_payload_t object.
*/
void (*destroy) (unknown_payload_t *this);
};
/**
- * @brief Creates an empty unknown_payload_t object.
+ * Creates an empty unknown_payload_t object.
*
* @return unknown_payload_t object
- *
- * @ingroup payloads
*/
unknown_payload_t *unknown_payload_create(void);
-
-#endif /* UNKNOWN_PAYLOAD_H_ */
+#endif /* UNKNOWN_PAYLOAD_H_ @} */
diff --git a/src/charon/encoding/payloads/vendor_id_payload.c b/src/charon/encoding/payloads/vendor_id_payload.c
index e3a4d2e1f..3eacc1a72 100644
--- a/src/charon/encoding/payloads/vendor_id_payload.c
+++ b/src/charon/encoding/payloads/vendor_id_payload.c
@@ -1,10 +1,3 @@
-/**
- * @file vendor_id_payload.c
- *
- * @brief Implementation of vendor_id_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: vendor_id_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/vendor_id_payload.h b/src/charon/encoding/payloads/vendor_id_payload.h
index c7eebc155..e489bfd5a 100644
--- a/src/charon/encoding/payloads/vendor_id_payload.h
+++ b/src/charon/encoding/payloads/vendor_id_payload.h
@@ -1,10 +1,3 @@
-/**
- * @file vendor_id_payload.h
- *
- * @brief Interface of vendor_id_payload_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: vendor_id_payload.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup vendor_id_payload vendor_id_payload
+ * @{ @ingroup payloads
*/
#ifndef VENDOR_ID_PAYLOAD_H_
@@ -31,21 +31,14 @@ typedef struct vendor_id_payload_t vendor_id_payload_t;
/**
* Length of a VENDOR ID payload without the VID data in bytes.
- *
- * @ingroup payloads
*/
#define VENDOR_ID_PAYLOAD_HEADER_LENGTH 4
/**
- * @brief Class representing an IKEv2 VENDOR ID payload.
+ * Class representing an IKEv2 VENDOR ID payload.
*
* The VENDOR ID payload format is described in RFC section 3.12.
- *
- * @b Constructors:
- * - vendor_id_payload_create()
- *
- * @ingroup payloads
*/
struct vendor_id_payload_t {
/**
@@ -54,51 +47,43 @@ struct vendor_id_payload_t {
payload_t payload_interface;
/**
- * @brief Set the VID data.
+ * Set the VID data.
*
* Data are getting cloned.
*
- * @param this calling vendor_id_payload_t object
* @param data VID data as chunk_t
*/
void (*set_data) (vendor_id_payload_t *this, chunk_t data);
/**
- * @brief Get the VID data.
+ * Get the VID data.
*
* Returned data are a copy of the internal one.
*
- * @param this calling vendor_id_payload_t object
* @return VID data as chunk_t
*/
chunk_t (*get_data_clone) (vendor_id_payload_t *this);
/**
- * @brief Get the VID data.
+ * Get the VID data.
*
* Returned data are NOT copied.
*
- * @param this calling vendor_id_payload_t object
* @return VID data as chunk_t
*/
chunk_t (*get_data) (vendor_id_payload_t *this);
/**
- * @brief Destroys an vendor_id_payload_t object.
- *
- * @param this vendor_id_payload_t object to destroy
+ * Destroys an vendor_id_payload_t object.
*/
void (*destroy) (vendor_id_payload_t *this);
};
/**
- * @brief Creates an empty vendor_id_payload_t object.
+ * Creates an empty vendor_id_payload_t object.
*
* @return vendor_id_payload_t object
- *
- * @ingroup payloads
*/
vendor_id_payload_t *vendor_id_payload_create(void);
-
-#endif /* VENDOR_ID_PAYLOAD_H_ */
+#endif /* VENDOR_ID_PAYLOAD_H_ @} */
diff --git a/src/charon/kernel/kernel_interface.c b/src/charon/kernel/kernel_interface.c
index b7f6a1def..f5cb40977 100644
--- a/src/charon/kernel/kernel_interface.c
+++ b/src/charon/kernel/kernel_interface.c
@@ -1,13 +1,6 @@
-/**
- * @file kernel_interface.c
- *
- * @brief Implementation of kernel_interface_t.
- *
- */
-
/*
+ * Copyright (C) 2006-2008 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
- * Copyright (C) 2006-2007 Tobias Brunner
* Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
@@ -25,6 +18,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: kernel_interface.c 4104 2008-06-24 15:35:09Z tobias $
*/
#include <sys/types.h>
@@ -116,26 +111,32 @@ struct kernel_algorithm_t {
/**
* Algorithms for encryption
*/
-kernel_algorithm_t encryption_algs[] = {
-/* {ENCR_DES_IV64, "***", 0}, */
- {ENCR_DES, "des", 64},
- {ENCR_3DES, "des3_ede", 192},
-/* {ENCR_RC5, "***", 0}, */
-/* {ENCR_IDEA, "***", 0}, */
- {ENCR_CAST, "cast128", 0},
- {ENCR_BLOWFISH, "blowfish", 0},
-/* {ENCR_3IDEA, "***", 0}, */
-/* {ENCR_DES_IV32, "***", 0}, */
- {ENCR_NULL, "cipher_null", 0},
- {ENCR_AES_CBC, "aes", 0},
-/* {ENCR_AES_CTR, "***", 0}, */
+static kernel_algorithm_t encryption_algs[] = {
+/* {ENCR_DES_IV64, "***", 0}, */
+ {ENCR_DES, "des", 64},
+ {ENCR_3DES, "des3_ede", 192},
+/* {ENCR_RC5, "***", 0}, */
+/* {ENCR_IDEA, "***", 0}, */
+ {ENCR_CAST, "cast128", 0},
+ {ENCR_BLOWFISH, "blowfish", 0},
+/* {ENCR_3IDEA, "***", 0}, */
+/* {ENCR_DES_IV32, "***", 0}, */
+ {ENCR_NULL, "cipher_null", 0},
+ {ENCR_AES_CBC, "aes", 0},
+/* {ENCR_AES_CTR, "***", 0}, */
+ {ENCR_AES_CCM_ICV8, "rfc4309(ccm(aes))", 64}, /* key_size = ICV size */
+ {ENCR_AES_CCM_ICV12, "rfc4309(ccm(aes))", 96}, /* key_size = ICV size */
+ {ENCR_AES_CCM_ICV16, "rfc4309(ccm(aes))", 128}, /* key_size = ICV size */
+ {ENCR_AES_GCM_ICV8, "rfc4106(gcm(aes))", 64}, /* key_size = ICV size */
+ {ENCR_AES_GCM_ICV12, "rfc4106(gcm(aes))", 96}, /* key_size = ICV size */
+ {ENCR_AES_GCM_ICV16, "rfc4106(gcm(aes))", 128}, /* key_size = ICV size */
{END_OF_LIST, NULL, 0},
};
/**
* Algorithms for integrity protection
*/
-kernel_algorithm_t integrity_algs[] = {
+static kernel_algorithm_t integrity_algs[] = {
{AUTH_HMAC_MD5_96, "md5", 128},
{AUTH_HMAC_SHA1_96, "sha1", 160},
{AUTH_HMAC_SHA2_256_128, "sha256", 256},
@@ -148,22 +149,29 @@ kernel_algorithm_t integrity_algs[] = {
};
/**
+ * Algorithms for IPComp
+ */
+static kernel_algorithm_t compression_algs[] = {
+/* {IPCOMP_OUI, "***", 0}, */
+ {IPCOMP_DEFLATE, "deflate", 0},
+ {IPCOMP_LZS, "lzs", 0},
+ {IPCOMP_LZJH, "lzjh", 0},
+ {END_OF_LIST, NULL, 0},
+};
+
+/**
* Look up a kernel algorithm name and its key size
*/
-char* lookup_algorithm(kernel_algorithm_t *kernel_algo,
- algorithm_t *ikev2_algo, u_int *key_size)
+static char* lookup_algorithm(kernel_algorithm_t *kernel_algo,
+ u_int16_t ikev2_algo, u_int16_t *key_size)
{
while (kernel_algo->ikev2_id != END_OF_LIST)
{
- if (ikev2_algo->algorithm == kernel_algo->ikev2_id)
+ if (ikev2_algo == kernel_algo->ikev2_id)
{
/* match, evaluate key length */
- if (ikev2_algo->key_size)
- { /* variable length */
- *key_size = ikev2_algo->key_size;
- }
- else
- { /* fixed length */
+ if (key_size && *key_size == 0)
+ { /* update key size if not set */
*key_size = kernel_algo->key_size;
}
return kernel_algo->name;
@@ -363,6 +371,21 @@ struct private_kernel_interface_t {
* time of the last roam_job
*/
struct timeval last_roam;
+
+ /**
+ * whether to install routes along policies
+ */
+ bool install_routes;
+
+ /**
+ * routing table to install routes
+ */
+ int routing_table;
+
+ /**
+ * priority of used routing table
+ */
+ int routing_table_prio;
};
/**
@@ -527,11 +550,20 @@ static void process_expire(private_kernel_interface_t *this, struct nlmsghdr *hd
struct xfrm_user_expire *expire;
expire = (struct xfrm_user_expire*)NLMSG_DATA(hdr);
- protocol = expire->state.id.proto == KERNEL_ESP ? PROTO_ESP : PROTO_AH;
+ protocol = expire->state.id.proto;
+ protocol = (protocol == KERNEL_ESP) ? PROTO_ESP : (protocol == KERNEL_AH) ? PROTO_AH : protocol;
spi = expire->state.id.spi;
reqid = expire->state.reqid;
DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE");
+
+ if (protocol != PROTO_ESP && protocol != PROTO_AH)
+ {
+ DBG2(DBG_KNL, "ignoring XFRM_MSG_EXPIRE for SA 0x%x (reqid %d) which is "
+ "not a CHILD_SA", ntohl(spi), reqid);
+ return;
+ }
+
DBG1(DBG_KNL, "creating %s job for %N CHILD_SA 0x%x (reqid %d)",
expire->hard ? "delete" : "rekey", protocol_id_names,
protocol, ntohl(spi), reqid);
@@ -1425,11 +1457,10 @@ static status_t manage_srcroute(private_kernel_interface_t *this, int nlmsg_type
struct rtmsg *msg;
chunk_t chunk;
-#if IPSEC_ROUTING_TABLE == 0
/* if route is 0.0.0.0/0, we can't install it, as it would
* overwrite the default route. Instead, we add two routes:
* 0.0.0.0/1 and 128.0.0.0/1 */
- if (route->prefixlen == 0)
+ if (this->routing_table == 0 && route->prefixlen == 0)
{
route_entry_t half;
status_t status;
@@ -1446,7 +1477,6 @@ static status_t manage_srcroute(private_kernel_interface_t *this, int nlmsg_type
status = manage_srcroute(this, nlmsg_type, flags, &half);
return status;
}
-#endif
memset(&request, 0, sizeof(request));
@@ -1458,7 +1488,7 @@ static status_t manage_srcroute(private_kernel_interface_t *this, int nlmsg_type
msg = (struct rtmsg*)NLMSG_DATA(hdr);
msg->rtm_family = route->src_ip->get_family(route->src_ip);
msg->rtm_dst_len = route->prefixlen;
- msg->rtm_table = IPSEC_ROUTING_TABLE;
+ msg->rtm_table = this->routing_table;
msg->rtm_protocol = RTPROT_STATIC;
msg->rtm_type = RTN_UNICAST;
msg->rtm_scope = RT_SCOPE_UNIVERSE;
@@ -1620,7 +1650,7 @@ static host_t *get_route(private_kernel_interface_t *this, host_t *dest,
* - is the default route or
* - its destination net contains our destination
*/
- if (msg->rtm_table != IPSEC_ROUTING_TABLE
+ if ((this->routing_table == 0 ||msg->rtm_table != this->routing_table)
&& msg->rtm_dst_len > best
&& (msg->rtm_dst_len == 0 || /* default route */
(rta_dst.ptr && addr_in_subnet(chunk, rta_dst, msg->rtm_dst_len))))
@@ -1639,6 +1669,13 @@ static host_t *get_route(private_kernel_interface_t *this, host_t *dest,
{
DESTROY_IF(src);
src = host_create_from_chunk(msg->rtm_family, rta_src, 0);
+ if (get_vip_refcount(this, src))
+ { /* skip source address if it is installed by us */
+ DESTROY_IF(src);
+ src = NULL;
+ current = NLMSG_NEXT(current, len);
+ continue;
+ }
}
else
{
@@ -1823,12 +1860,11 @@ static status_t del_ip(private_kernel_interface_t *this, host_t *virtual_ip)
}
/**
- * Implementation of kernel_interface_t.get_spi.
+ * Get an SPI for a specific protocol from the kernel.
*/
-static status_t get_spi(private_kernel_interface_t *this,
- host_t *src, host_t *dst,
- protocol_id_t protocol, u_int32_t reqid,
- u_int32_t *spi)
+static status_t get_spi_internal(private_kernel_interface_t *this,
+ host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max,
+ u_int32_t reqid, u_int32_t *spi)
{
unsigned char request[BUFFER_SIZE];
struct nlmsghdr *hdr, *out;
@@ -1838,8 +1874,6 @@ static status_t get_spi(private_kernel_interface_t *this,
memset(&request, 0, sizeof(request));
- DBG2(DBG_KNL, "getting SPI for reqid %d", reqid);
-
hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST;
hdr->nlmsg_type = XFRM_MSG_ALLOCSPI;
@@ -1848,12 +1882,12 @@ static status_t get_spi(private_kernel_interface_t *this,
userspi = (struct xfrm_userspi_info*)NLMSG_DATA(hdr);
host2xfrm(src, &userspi->info.saddr);
host2xfrm(dst, &userspi->info.id.daddr);
- userspi->info.id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
+ userspi->info.id.proto = proto;
userspi->info.mode = TRUE; /* tunnel mode */
userspi->info.reqid = reqid;
userspi->info.family = src->get_family(src);
- userspi->min = 0xc0000000;
- userspi->max = 0xcFFFFFFF;
+ userspi->min = min;
+ userspi->max = max;
if (netlink_send(this, this->socket_xfrm, hdr, &out, &len) == SUCCESS)
{
@@ -1889,13 +1923,57 @@ static status_t get_spi(private_kernel_interface_t *this,
if (received_spi == 0)
{
+ return FAILED;
+ }
+
+ *spi = received_spi;
+ return SUCCESS;
+}
+
+/**
+ * Implementation of kernel_interface_t.get_spi.
+ */
+static status_t get_spi(private_kernel_interface_t *this,
+ host_t *src, host_t *dst,
+ protocol_id_t protocol, u_int32_t reqid,
+ u_int32_t *spi)
+{
+ DBG2(DBG_KNL, "getting SPI for reqid %d", reqid);
+
+ if (get_spi_internal(this, src, dst,
+ (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH,
+ 0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS)
+ {
DBG1(DBG_KNL, "unable to get SPI for reqid %d", reqid);
return FAILED;
}
- DBG2(DBG_KNL, "got SPI 0x%x for reqid %d", received_spi, reqid);
+ DBG2(DBG_KNL, "got SPI 0x%x for reqid %d", *spi, reqid);
+
+ return SUCCESS;
+}
+
+/**
+ * Implementation of kernel_interface_t.get_cpi.
+ */
+static status_t get_cpi(private_kernel_interface_t *this,
+ host_t *src, host_t *dst,
+ u_int32_t reqid, u_int16_t *cpi)
+{
+ u_int32_t received_spi = 0;
+ DBG2(DBG_KNL, "getting CPI for reqid %d", reqid);
+
+ if (get_spi_internal(this, src, dst,
+ IPPROTO_COMP, 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS)
+ {
+ DBG1(DBG_KNL, "unable to get CPI for reqid %d", reqid);
+ return FAILED;
+ }
+
+ *cpi = htons((u_int16_t)ntohl(received_spi));
+
+ DBG2(DBG_KNL, "got CPI 0x%x for reqid %d", *cpi, reqid);
- *spi = received_spi;
return SUCCESS;
}
@@ -1906,19 +1984,21 @@ static status_t add_sa(private_kernel_interface_t *this,
host_t *src, host_t *dst, u_int32_t spi,
protocol_id_t protocol, u_int32_t reqid,
u_int64_t expire_soft, u_int64_t expire_hard,
- algorithm_t *enc_alg, algorithm_t *int_alg,
- prf_plus_t *prf_plus, mode_t mode, bool encap,
+ u_int16_t enc_alg, u_int16_t enc_size,
+ u_int16_t int_alg, u_int16_t int_size,
+ prf_plus_t *prf_plus, mode_t mode,
+ u_int16_t ipcomp, bool encap,
bool replace)
{
unsigned char request[BUFFER_SIZE];
char *alg_name;
- u_int key_size;
+ u_int16_t add_keymat = 32; /* additional 4 octets KEYMAT required for AES-GCM as of RFC4106 8.1. */
struct nlmsghdr *hdr;
struct xfrm_usersa_info *sa;
memset(&request, 0, sizeof(request));
- DBG2(DBG_KNL, "adding SAD entry with SPI 0x%x", spi);
+ DBG2(DBG_KNL, "adding SAD entry with SPI 0x%x and reqid %d", spi, reqid);
hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -1929,10 +2009,10 @@ static status_t add_sa(private_kernel_interface_t *this,
host2xfrm(src, &sa->saddr);
host2xfrm(dst, &sa->id.daddr);
sa->id.spi = spi;
- sa->id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
+ sa->id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : (protocol == PROTO_AH) ? KERNEL_AH : protocol;
sa->family = src->get_family(src);
sa->mode = mode;
- sa->replay_window = 32;
+ sa->replay_window = (protocol == IPPROTO_COMP) ? 0 : 32;
sa->reqid = reqid;
/* we currently do not expire SAs by volume/packet count */
sa->lft.soft_byte_limit = XFRM_INF;
@@ -1947,20 +2027,96 @@ static status_t add_sa(private_kernel_interface_t *this,
struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_usersa_info);
- if (enc_alg->algorithm != ENCR_UNDEFINED)
+ switch (enc_alg)
+ {
+ case ENCR_UNDEFINED:
+ /* no encryption */
+ break;
+ case ENCR_AES_CCM_ICV8:
+ case ENCR_AES_CCM_ICV12:
+ case ENCR_AES_CCM_ICV16:
+ /* AES-CCM needs only 3 additional octets KEYMAT as of RFC 4309 7.1. */
+ add_keymat = 24;
+ /* fall-through */
+ case ENCR_AES_GCM_ICV8:
+ case ENCR_AES_GCM_ICV12:
+ case ENCR_AES_GCM_ICV16:
+ {
+ u_int16_t icv_size = 0;
+ rthdr->rta_type = XFRMA_ALG_AEAD;
+ alg_name = lookup_algorithm(encryption_algs, enc_alg, &icv_size);
+ if (alg_name == NULL)
+ {
+ DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
+ encryption_algorithm_names, enc_alg);
+ return FAILED;
+ }
+ DBG2(DBG_KNL, " using encryption algorithm %N with key size %d",
+ encryption_algorithm_names, enc_alg, enc_size);
+
+ /* additional KEYMAT required */
+ enc_size += add_keymat;
+
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo_aead) + enc_size / 8);
+ hdr->nlmsg_len += rthdr->rta_len;
+ if (hdr->nlmsg_len > sizeof(request))
+ {
+ return FAILED;
+ }
+
+ struct xfrm_algo_aead* algo = (struct xfrm_algo_aead*)RTA_DATA(rthdr);
+ algo->alg_key_len = enc_size;
+ algo->alg_icv_len = icv_size;
+ strcpy(algo->alg_name, alg_name);
+ prf_plus->get_bytes(prf_plus, enc_size / 8, algo->alg_key);
+
+ rthdr = XFRM_RTA_NEXT(rthdr);
+ break;
+ }
+ default:
+ {
+ rthdr->rta_type = XFRMA_ALG_CRYPT;
+ alg_name = lookup_algorithm(encryption_algs, enc_alg, &enc_size);
+ if (alg_name == NULL)
+ {
+ DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
+ encryption_algorithm_names, enc_alg);
+ return FAILED;
+ }
+ DBG2(DBG_KNL, " using encryption algorithm %N with key size %d",
+ encryption_algorithm_names, enc_alg, enc_size);
+
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + enc_size / 8);
+ hdr->nlmsg_len += rthdr->rta_len;
+ if (hdr->nlmsg_len > sizeof(request))
+ {
+ return FAILED;
+ }
+
+ struct xfrm_algo* algo = (struct xfrm_algo*)RTA_DATA(rthdr);
+ algo->alg_key_len = enc_size;
+ strcpy(algo->alg_name, alg_name);
+ prf_plus->get_bytes(prf_plus, enc_size / 8, algo->alg_key);
+
+ rthdr = XFRM_RTA_NEXT(rthdr);
+ break;
+ }
+ }
+
+ if (int_alg != AUTH_UNDEFINED)
{
- rthdr->rta_type = XFRMA_ALG_CRYPT;
- alg_name = lookup_algorithm(encryption_algs, enc_alg, &key_size);
+ rthdr->rta_type = XFRMA_ALG_AUTH;
+ alg_name = lookup_algorithm(integrity_algs, int_alg, &int_size);
if (alg_name == NULL)
{
- DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- encryption_algorithm_names, enc_alg->algorithm);
+ DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
+ integrity_algorithm_names, int_alg);
return FAILED;
}
- DBG2(DBG_KNL, " using encryption algorithm %N with key size %d",
- encryption_algorithm_names, enc_alg->algorithm, key_size);
+ DBG2(DBG_KNL, " using integrity algorithm %N with key size %d",
+ integrity_algorithm_names, int_alg, int_size);
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + key_size);
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + int_size / 8);
hdr->nlmsg_len += rthdr->rta_len;
if (hdr->nlmsg_len > sizeof(request))
{
@@ -1968,27 +2124,27 @@ static status_t add_sa(private_kernel_interface_t *this,
}
struct xfrm_algo* algo = (struct xfrm_algo*)RTA_DATA(rthdr);
- algo->alg_key_len = key_size;
+ algo->alg_key_len = int_size;
strcpy(algo->alg_name, alg_name);
- prf_plus->get_bytes(prf_plus, key_size / 8, algo->alg_key);
+ prf_plus->get_bytes(prf_plus, int_size / 8, algo->alg_key);
rthdr = XFRM_RTA_NEXT(rthdr);
}
- if (int_alg->algorithm != AUTH_UNDEFINED)
+ if (ipcomp != IPCOMP_NONE)
{
- rthdr->rta_type = XFRMA_ALG_AUTH;
- alg_name = lookup_algorithm(integrity_algs, int_alg, &key_size);
+ rthdr->rta_type = XFRMA_ALG_COMP;
+ alg_name = lookup_algorithm(compression_algs, ipcomp, NULL);
if (alg_name == NULL)
{
DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- integrity_algorithm_names, int_alg->algorithm);
+ ipcomp_transform_names, ipcomp);
return FAILED;
}
- DBG2(DBG_KNL, " using integrity algorithm %N with key size %d",
- integrity_algorithm_names, int_alg->algorithm, key_size);
+ DBG2(DBG_KNL, " using compression algorithm %N",
+ ipcomp_transform_names, ipcomp);
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + key_size);
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo));
hdr->nlmsg_len += rthdr->rta_len;
if (hdr->nlmsg_len > sizeof(request))
{
@@ -1996,15 +2152,12 @@ static status_t add_sa(private_kernel_interface_t *this,
}
struct xfrm_algo* algo = (struct xfrm_algo*)RTA_DATA(rthdr);
- algo->alg_key_len = key_size;
+ algo->alg_key_len = 0;
strcpy(algo->alg_name, alg_name);
- prf_plus->get_bytes(prf_plus, key_size / 8, algo->alg_key);
rthdr = XFRM_RTA_NEXT(rthdr);
}
- /* TODO: add IPComp here */
-
if (encap)
{
rthdr->rta_type = XFRMA_ENCAP;
@@ -2042,6 +2195,91 @@ static status_t add_sa(private_kernel_interface_t *this,
}
/**
+ * Get the replay state (i.e. sequence numbers) of an SA.
+ */
+static status_t get_replay_state(private_kernel_interface_t *this,
+ u_int32_t spi, protocol_id_t protocol, host_t *dst,
+ struct xfrm_replay_state *replay)
+{
+ unsigned char request[BUFFER_SIZE];
+ struct nlmsghdr *hdr, *out = NULL;
+ struct xfrm_aevent_id *out_aevent = NULL, *aevent_id;
+ size_t len;
+ struct rtattr *rta;
+ size_t rtasize;
+
+ memset(&request, 0, sizeof(request));
+
+ DBG2(DBG_KNL, "querying replay state from SAD entry with SPI 0x%x", spi);
+
+ hdr = (struct nlmsghdr*)request;
+ hdr->nlmsg_flags = NLM_F_REQUEST;
+ hdr->nlmsg_type = XFRM_MSG_GETAE;
+ hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
+
+ aevent_id = (struct xfrm_aevent_id*)NLMSG_DATA(hdr);
+ aevent_id->flags = XFRM_AE_RVAL;
+
+ host2xfrm(dst, &aevent_id->sa_id.daddr);
+ aevent_id->sa_id.spi = spi;
+ aevent_id->sa_id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : (protocol == PROTO_AH) ? KERNEL_AH : protocol;
+ aevent_id->sa_id.family = dst->get_family(dst);
+
+ if (netlink_send(this, this->socket_xfrm, hdr, &out, &len) == SUCCESS)
+ {
+ hdr = out;
+ while (NLMSG_OK(hdr, len))
+ {
+ switch (hdr->nlmsg_type)
+ {
+ case XFRM_MSG_NEWAE:
+ {
+ out_aevent = NLMSG_DATA(hdr);
+ break;
+ }
+ case NLMSG_ERROR:
+ {
+ struct nlmsgerr *err = NLMSG_DATA(hdr);
+ DBG1(DBG_KNL, "querying replay state from SAD entry failed: %s (%d)",
+ strerror(-err->error), -err->error);
+ break;
+ }
+ default:
+ hdr = NLMSG_NEXT(hdr, len);
+ continue;
+ case NLMSG_DONE:
+ break;
+ }
+ break;
+ }
+ }
+
+ if (out_aevent == NULL)
+ {
+ DBG1(DBG_KNL, "unable to query replay state from SAD entry with SPI 0x%x", spi);
+ free(out);
+ return FAILED;
+ }
+
+ rta = XFRM_RTA(out, struct xfrm_aevent_id);
+ rtasize = XFRM_PAYLOAD(out, struct xfrm_aevent_id);
+ while(RTA_OK(rta, rtasize))
+ {
+ if (rta->rta_type == XFRMA_REPLAY_VAL)
+ {
+ memcpy(replay, RTA_DATA(rta), rta->rta_len);
+ free(out);
+ return SUCCESS;
+ }
+ rta = RTA_NEXT(rta, rtasize);
+ }
+
+ DBG1(DBG_KNL, "unable to query replay state from SAD entry with SPI 0x%x", spi);
+ free(out);
+ return FAILED;
+}
+
+/**
* Implementation of kernel_interface_t.update_sa.
*/
static status_t update_sa(private_kernel_interface_t *this,
@@ -2057,6 +2295,8 @@ static status_t update_sa(private_kernel_interface_t *this,
struct rtattr *rta;
size_t rtasize;
struct xfrm_encap_tmpl* tmpl = NULL;
+ bool got_replay_state;
+ struct xfrm_replay_state replay;
memset(&request, 0, sizeof(request));
@@ -2071,7 +2311,7 @@ static status_t update_sa(private_kernel_interface_t *this,
sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
host2xfrm(dst, &sa_id->daddr);
sa_id->spi = spi;
- sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
+ sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : (protocol == PROTO_AH) ? KERNEL_AH : protocol;
sa_id->family = dst->get_family(dst);
if (netlink_send(this, this->socket_xfrm, hdr, &out, &len) == SUCCESS)
@@ -2102,14 +2342,25 @@ static status_t update_sa(private_kernel_interface_t *this,
break;
}
}
- if (out_sa == NULL ||
- this->public.del_sa(&this->public, dst, spi, protocol) != SUCCESS)
+ if (out_sa == NULL)
{
DBG1(DBG_KNL, "unable to update SAD entry with SPI 0x%x", spi);
free(out);
return FAILED;
}
+ /* try to get the replay state */
+ got_replay_state = (get_replay_state(
+ this, spi, protocol, dst, &replay) == SUCCESS);
+
+ /* delete the old SA */
+ if (this->public.del_sa(&this->public, dst, spi, protocol) != SUCCESS)
+ {
+ DBG1(DBG_KNL, "unable to delete old SAD entry with SPI 0x%x", spi);
+ free(out);
+ return FAILED;
+ }
+
DBG2(DBG_KNL, "updating SAD entry with SPI 0x%x from %#H..%#H to %#H..%#H",
spi, src, dst, new_src, new_dst);
@@ -2146,22 +2397,46 @@ static status_t update_sa(private_kernel_interface_t *this,
tmpl->encap_dport = ntohs(new_dst->get_port(new_dst));
}
memcpy(pos, rta, rta->rta_len);
- pos += rta->rta_len;
- hdr->nlmsg_len += rta->rta_len;
+ pos += RTA_ALIGN(rta->rta_len);
+ hdr->nlmsg_len += RTA_ALIGN(rta->rta_len);
}
rta = RTA_NEXT(rta, rtasize);
}
+
+ rta = (struct rtattr*)pos;
if (tmpl == NULL && encap)
{ /* add tmpl if we are enabling it */
- rta = (struct rtattr*)pos;
rta->rta_type = XFRMA_ENCAP;
rta->rta_len = RTA_LENGTH(sizeof(struct xfrm_encap_tmpl));
+
hdr->nlmsg_len += rta->rta_len;
+ if (hdr->nlmsg_len > sizeof(request))
+ {
+ return FAILED;
+ }
+
tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rta);
tmpl->encap_type = UDP_ENCAP_ESPINUDP;
tmpl->encap_sport = ntohs(new_src->get_port(new_src));
tmpl->encap_dport = ntohs(new_dst->get_port(new_dst));
memset(&tmpl->encap_oa, 0, sizeof (xfrm_address_t));
+
+ rta = XFRM_RTA_NEXT(rta);
+ }
+
+ if (got_replay_state)
+ { /* copy the replay data if available */
+ rta->rta_type = XFRMA_REPLAY_VAL;
+ rta->rta_len = RTA_LENGTH(sizeof(struct xfrm_replay_state));
+
+ hdr->nlmsg_len += rta->rta_len;
+ if (hdr->nlmsg_len > sizeof(request))
+ {
+ return FAILED;
+ }
+ memcpy(RTA_DATA(rta), &replay, sizeof(replay));
+
+ rta = XFRM_RTA_NEXT(rta);
}
if (netlink_send_ack(this, this->socket_xfrm, hdr) != SUCCESS)
@@ -2199,7 +2474,7 @@ static status_t query_sa(private_kernel_interface_t *this, host_t *dst,
sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
host2xfrm(dst, &sa_id->daddr);
sa_id->spi = spi;
- sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
+ sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : (protocol == PROTO_AH) ? KERNEL_AH : protocol;
sa_id->family = dst->get_family(dst);
if (netlink_send(this, this->socket_xfrm, hdr, &out, &len) == SUCCESS)
@@ -2265,7 +2540,7 @@ static status_t del_sa(private_kernel_interface_t *this, host_t *dst,
sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
host2xfrm(dst, &sa_id->daddr);
sa_id->spi = spi;
- sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
+ sa_id->proto = (protocol == PROTO_ESP) ? KERNEL_ESP : (protocol == PROTO_AH) ? KERNEL_AH : protocol;
sa_id->family = dst->get_family(dst);
if (netlink_send_ack(this, this->socket_xfrm, hdr) != SUCCESS)
@@ -2285,7 +2560,8 @@ static status_t add_policy(private_kernel_interface_t *this,
traffic_selector_t *src_ts,
traffic_selector_t *dst_ts,
policy_dir_t direction, protocol_id_t protocol,
- u_int32_t reqid, bool high_prio, mode_t mode)
+ u_int32_t reqid, bool high_prio, mode_t mode,
+ u_int16_t ipcomp)
{
iterator_t *iterator;
policy_entry_t *current, *policy;
@@ -2310,7 +2586,7 @@ static status_t add_policy(private_kernel_interface_t *this,
{
/* use existing policy */
current->refcount++;
- DBG2(DBG_KNL, "policy %R===%R already exists, increasing ",
+ DBG2(DBG_KNL, "policy %R===%R already exists, increasing "
"refcount", src_ts, dst_ts);
free(policy);
policy = current;
@@ -2357,10 +2633,8 @@ static status_t add_policy(private_kernel_interface_t *this,
struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_info);
rthdr->rta_type = XFRMA_TMPL;
-
- rthdr->rta_len = sizeof(struct xfrm_user_tmpl);
- rthdr->rta_len = RTA_LENGTH(rthdr->rta_len);
-
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_user_tmpl));
+
hdr->nlmsg_len += rthdr->rta_len;
if (hdr->nlmsg_len > sizeof(request))
{
@@ -2368,6 +2642,30 @@ static status_t add_policy(private_kernel_interface_t *this,
}
struct xfrm_user_tmpl *tmpl = (struct xfrm_user_tmpl*)RTA_DATA(rthdr);
+
+ if (ipcomp != IPCOMP_NONE)
+ {
+ tmpl->reqid = reqid;
+ tmpl->id.proto = IPPROTO_COMP;
+ tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
+ tmpl->mode = mode;
+ tmpl->optional = direction != POLICY_OUT;
+ tmpl->family = src->get_family(src);
+
+ host2xfrm(src, &tmpl->saddr);
+ host2xfrm(dst, &tmpl->id.daddr);
+
+ /* add an additional xfrm_user_tmpl */
+ rthdr->rta_len += RTA_LENGTH(sizeof(struct xfrm_user_tmpl));
+ hdr->nlmsg_len += RTA_LENGTH(sizeof(struct xfrm_user_tmpl));
+ if (hdr->nlmsg_len > sizeof(request))
+ {
+ return FAILED;
+ }
+
+ tmpl++;
+ }
+
tmpl->reqid = reqid;
tmpl->id.proto = (protocol == PROTO_AH) ? KERNEL_AH : KERNEL_ESP;
tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
@@ -2388,9 +2686,11 @@ static status_t add_policy(private_kernel_interface_t *this,
* - this is a forward policy (to just get one for each child)
* - we are in tunnel mode
* - we are not using IPv6 (does not work correctly yet!)
+ * - routing is not disabled via strongswan.conf
*/
if (policy->route == NULL && direction == POLICY_FWD &&
- mode != MODE_TRANSPORT && src->get_family(src) != AF_INET6)
+ mode != MODE_TRANSPORT && src->get_family(src) != AF_INET6 &&
+ this->install_routes)
{
policy->route = malloc_thing(route_entry_t);
if (get_address_by_ts(this, dst_ts, &policy->route->src_ip) == SUCCESS)
@@ -2575,7 +2875,11 @@ static status_t del_policy(private_kernel_interface_t *this,
*/
static void destroy(private_kernel_interface_t *this)
{
- manage_rule(this, RTM_DELRULE, IPSEC_ROUTING_TABLE, IPSEC_ROUTING_TABLE_PRIO);
+ if (this->routing_table)
+ {
+ manage_rule(this, RTM_DELRULE, this->routing_table,
+ this->routing_table_prio);
+ }
this->job->cancel(this->job);
close(this->socket_xfrm_events);
@@ -2597,11 +2901,12 @@ kernel_interface_t *kernel_interface_create()
/* public functions */
this->public.get_spi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,protocol_id_t,u_int32_t,u_int32_t*))get_spi;
- this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,algorithm_t*,algorithm_t*,prf_plus_t*,mode_t,bool,bool))add_sa;
+ this->public.get_cpi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
+ this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,u_int16_t,u_int16_t,u_int16_t,prf_plus_t*,mode_t,u_int16_t,bool,bool))add_sa;
this->public.update_sa = (status_t(*)(kernel_interface_t*,u_int32_t,protocol_id_t,host_t*,host_t*,host_t*,host_t*,bool))update_sa;
this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t*))query_sa;
this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t))del_sa;
- this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,protocol_id_t,u_int32_t,bool,mode_t))add_policy;
+ this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,protocol_id_t,u_int32_t,bool,mode_t,u_int16_t))add_policy;
this->public.query_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
this->public.del_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t))del_policy;
this->public.get_interface = (char*(*)(kernel_interface_t*,host_t*))get_interface_name;
@@ -2620,7 +2925,12 @@ kernel_interface_t *kernel_interface_create()
pthread_mutex_init(&this->nl_mutex, NULL);
pthread_cond_init(&this->cond, NULL);
timerclear(&this->last_roam);
-
+ this->install_routes = lib->settings->get_bool(lib->settings,
+ "charon.install_routes", TRUE);
+ this->routing_table = lib->settings->get_int(lib->settings,
+ "charon.routing_table", IPSEC_ROUTING_TABLE);
+ this->routing_table_prio = lib->settings->get_int(lib->settings,
+ "charon.routing_table_prio", IPSEC_ROUTING_TABLE_PRIO);
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
@@ -2682,10 +2992,13 @@ kernel_interface_t *kernel_interface_create()
charon->kill(charon, "unable to get interface list");
}
- if (manage_rule(this, RTM_NEWRULE, IPSEC_ROUTING_TABLE,
- IPSEC_ROUTING_TABLE_PRIO) != SUCCESS)
+ if (this->routing_table)
{
- DBG1(DBG_KNL, "unable to create routing table rule");
+ if (manage_rule(this, RTM_NEWRULE, this->routing_table,
+ this->routing_table_prio) != SUCCESS)
+ {
+ DBG1(DBG_KNL, "unable to create routing table rule");
+ }
}
return &this->public;
diff --git a/src/charon/kernel/kernel_interface.h b/src/charon/kernel/kernel_interface.h
index 256c20797..49928c74b 100644
--- a/src/charon/kernel/kernel_interface.h
+++ b/src/charon/kernel/kernel_interface.h
@@ -1,12 +1,6 @@
-/**
- * @file kernel_interface.h
- *
- * @brief Interface of kernel_interface_t.
- *
- */
-
/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006-2008 Tobias Brunner
+ * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -20,6 +14,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: kernel_interface.h 3920 2008-05-08 16:19:11Z tobias $
+ */
+
+/**
+ * @defgroup kernel_interface kernel_interface
+ * @{ @ingroup kernel
*/
#ifndef KERNEL_INTERFACE_H_
@@ -37,8 +38,6 @@ typedef struct kernel_interface_t kernel_interface_t;
* Direction of a policy. These are equal to those
* defined in xfrm.h, but we want to stay implementation
* neutral here.
- *
- * @ingroup kernel
*/
enum policy_dir_t {
/** Policy for inbound traffic */
@@ -50,7 +49,7 @@ enum policy_dir_t {
};
/**
- * @brief Interface to the kernel.
+ * Interface to the kernel.
*
* The kernel interface handles the communication with the kernel
* for SA and policy management. It allows setup of these, and provides
@@ -59,36 +58,40 @@ enum policy_dir_t {
* reference counting. The Linux kernel does not allow the same policy
* installed twice, but we need this as CHILD_SA exist multiple times
* when rekeying. Thats why we do reference counting of policies.
- *
- * @b Constructors:
- * - kernel_interface_create()
- *
- * @ingroup kernel
*/
struct kernel_interface_t {
/**
- * @brief Get a SPI from the kernel.
+ * Get a SPI from the kernel.
*
* @warning get_spi() implicitely creates an SA with
* the allocated SPI, therefore the replace flag
* in add_sa() must be set when installing this SA.
*
- * @param this calling object
* @param src source address of SA
* @param dst destination address of SA
* @param protocol protocol for SA (ESP/AH)
* @param reqid unique ID for this SA
- * @param[out] spi allocated spi
- * @return
- * - SUCCESS
- * - FAILED if kernel comm failed
+ * @param spi allocated spi
+ * @return SUCCESS if operation completed
*/
status_t (*get_spi)(kernel_interface_t *this, host_t *src, host_t *dst,
protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi);
/**
- * @brief Add an SA to the SAD.
+ * Get a Compression Parameter Index (CPI) from the kernel.
+ *
+ * @param src source address of SA
+ * @param dst destination address of SA
+ * @param reqid unique ID for the corresponding SA
+ * @param cpi allocated cpi
+ * @return SUCCESS if operation completed
+ */
+ status_t (*get_cpi)(kernel_interface_t *this, host_t *src, host_t *dst,
+ u_int32_t reqid, u_int16_t *cpi);
+
+ /**
+ * Add an SA to the SAD.
*
* add_sa() may update an already allocated
* SPI (via get_spi). In this case, the replace
@@ -98,7 +101,6 @@ struct kernel_interface_t {
* gets the keys itself from the PRF, as we don't know
* his algorithms and key sizes.
*
- * @param this calling object
* @param src source address for this SA
* @param dst destination address for this SA
* @param spi SPI allocated by us or remote peer
@@ -107,32 +109,34 @@ struct kernel_interface_t {
* @param expire_soft lifetime in seconds before rekeying
* @param expire_hard lieftime in seconds before delete
* @param enc_alg Algorithm to use for encryption (ESP only)
+ * @param enc_size key length of encryption algorithm, if dynamic
* @param int_alg Algorithm to use for integrity protection
+ * @param int_size key length of integrity algorithm, if dynamic
* @param prf_plus PRF to derive keys from
* @param mode mode of the SA (tunnel, transport)
+ * @param ipcomp IPComp transform to use
* @param encap enable UDP encapsulation for NAT traversal
* @param replace Should an already installed SA be updated?
- * @return
- * - SUCCESS
- * - FAILED if kernel comm failed
+ * @return SUCCESS if operation completed
*/
status_t (*add_sa) (kernel_interface_t *this,
host_t *src, host_t *dst, u_int32_t spi,
protocol_id_t protocol, u_int32_t reqid,
u_int64_t expire_soft, u_int64_t expire_hard,
- algorithm_t *enc_alg, algorithm_t *int_alg,
- prf_plus_t *prf_plus, mode_t mode, bool encap,
+ u_int16_t enc_alg, u_int16_t enc_size,
+ u_int16_t int_alg, u_int16_t int_size,
+ prf_plus_t *prf_plus, mode_t mode,
+ u_int16_t ipcomp, bool encap,
bool update);
/**
- * @brief Update the hosts on an installed SA.
+ * Update the hosts on an installed SA.
*
* We cannot directly update the destination address as the kernel
* requires the spi, the protocol AND the destination address (and family)
* to identify SAs. Therefore if the destination address changed we
* create a new SA and delete the old one.
*
- * @param this calling object
* @param spi SPI of the SA
* @param protocol protocol for this SA (ESP/AH)
* @param src current source address
@@ -140,9 +144,7 @@ struct kernel_interface_t {
* @param new_src new source address
* @param new_dst new destination address
* @param encap use UDP encapsulation
- * @return
- * - SUCCESS
- * - FAILED if kernel comm failed
+ * @return SUCCESS if operation completed
*/
status_t (*update_sa)(kernel_interface_t *this,
u_int32_t spi, protocol_id_t protocol,
@@ -150,44 +152,37 @@ struct kernel_interface_t {
host_t *new_src, host_t *new_dst, bool encap);
/**
- * @brief Query the use time of an SA.
+ * Query the use time of an SA.
*
* The use time of an SA is not the time of the last usage, but
* the time of the first usage of the SA.
*
- * @param this calling object
* @param dst destination address for this SA
* @param spi SPI allocated by us or remote peer
* @param protocol protocol for this SA (ESP/AH)
- * @param[out] use_time the time of this SA's last use
- * @return
- * - SUCCESS
- * - FAILED if kernel comm failed
+ * @param use_time pointer receives the time of this SA's last use
+ * @return SUCCESS if operation completed
*/
status_t (*query_sa) (kernel_interface_t *this, host_t *dst, u_int32_t spi,
protocol_id_t protocol, u_int32_t *use_time);
/**
- * @brief Delete a previusly installed SA from the SAD.
+ * Delete a previusly installed SA from the SAD.
*
- * @param this calling object
* @param dst destination address for this SA
* @param spi SPI allocated by us or remote peer
* @param protocol protocol for this SA (ESP/AH)
- * @return
- * - SUCCESS
- * - FAILED if kernel comm failed
+ * @return SUCCESS if operation completed
*/
status_t (*del_sa) (kernel_interface_t *this, host_t *dst, u_int32_t spi,
protocol_id_t protocol);
/**
- * @brief Add a policy to the SPD.
+ * Add a policy to the SPD.
*
* A policy is always associated to an SA. Traffic which matches a
* policy is handled by the SA with the same reqid.
*
- * @param this calling object
* @param src source address of SA
* @param dst dest address of SA
* @param src_ts traffic selector to match traffic source
@@ -197,31 +192,28 @@ struct kernel_interface_t {
* @param reqid uniqe ID of an SA to use to enforce policy
* @param high_prio if TRUE, uses a higher priority than any with FALSE
* @param mode mode of SA (tunnel, transport)
- * @return
- * - SUCCESS
- * - FAILED if kernel comm failed
+ * @param ipcomp the IPComp transform used
+ * @return SUCCESS if operation completed
*/
status_t (*add_policy) (kernel_interface_t *this,
host_t *src, host_t *dst,
traffic_selector_t *src_ts,
traffic_selector_t *dst_ts,
policy_dir_t direction, protocol_id_t protocol,
- u_int32_t reqid, bool high_prio, mode_t mode);
+ u_int32_t reqid, bool high_prio, mode_t mode,
+ u_int16_t ipcomp);
/**
- * @brief Query the use time of a policy.
+ * Query the use time of a policy.
*
* The use time of a policy is the time the policy was used
* for the last time.
*
- * @param this calling object
* @param src_ts traffic selector to match traffic source
* @param dst_ts traffic selector to match traffic dest
* @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
* @param[out] use_time the time of this SA's last use
- * @return
- * - SUCCESS
- * - FAILED if kernel comm failed
+ * @return SUCCESS if operation completed
*/
status_t (*query_policy) (kernel_interface_t *this,
traffic_selector_t *src_ts,
@@ -229,20 +221,17 @@ struct kernel_interface_t {
policy_dir_t direction, u_int32_t *use_time);
/**
- * @brief Remove a policy from the SPD.
+ * Remove a policy from the SPD.
*
* The kernel interface implements reference counting for policies.
* If the same policy is installed multiple times (in the case of rekeying),
* the reference counter is increased. del_policy() decreases the ref counter
* and removes the policy only when no more references are available.
*
- * @param this calling object
* @param src_ts traffic selector to match traffic source
* @param dst_ts traffic selector to match traffic dest
* @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
- * @return
- * - SUCCESS
- * - FAILED if kernel comm failed
+ * @return SUCCESS if operation completed
*/
status_t (*del_policy) (kernel_interface_t *this,
traffic_selector_t *src_ts,
@@ -250,82 +239,69 @@ struct kernel_interface_t {
policy_dir_t direction);
/**
- * @brief Get our outgoing source address for a destination.
+ * Get our outgoing source address for a destination.
*
* Does a route lookup to get the source address used to reach dest.
* The returned host is allocated and must be destroyed.
*
- * @param this calling object
* @param dest target destination address
* @return outgoing source address, NULL if unreachable
*/
host_t* (*get_source_addr)(kernel_interface_t *this, host_t *dest);
/**
- * @brief Get the interface name of a local address.
+ * Get the interface name of a local address.
*
- * @param this calling object
* @param host address to get interface name from
* @return allocated interface name, or NULL if not found
*/
char* (*get_interface) (kernel_interface_t *this, host_t *host);
/**
- * @brief Creates an iterator over all local addresses.
+ * Creates an iterator over all local addresses.
*
* This function blocks an internal cached address list until the
* iterator gets destroyed.
* These hosts are read-only, do not modify or free.
*
- * @param this calling object
* @return iterator over host_t's
*/
iterator_t *(*create_address_iterator) (kernel_interface_t *this);
/**
- * @brief Add a virtual IP to an interface.
+ * Add a virtual IP to an interface.
*
* Virtual IPs are attached to an interface. If an IP is added multiple
* times, the IP is refcounted and not removed until del_ip() was called
* as many times as add_ip().
* The virtual IP is attached to the interface where the iface_ip is found.
*
- * @param this calling object
* @param virtual_ip virtual ip address to assign
* @param iface_ip IP of an interface to attach virtual IP
- * @return
- * - SUCCESS
- * - FAILED if kernel comm failed
+ * @return SUCCESS if operation completed
*/
status_t (*add_ip) (kernel_interface_t *this, host_t *virtual_ip,
host_t *iface_ip);
/**
- * @brief Remove a virtual IP from an interface.
+ * Remove a virtual IP from an interface.
*
* The kernel interface uses refcounting, see add_ip().
*
- * @param this calling object
* @param virtual_ip virtual ip address to assign
- * @return
- * - SUCCESS
- * - FAILED if kernel comm failed
+ * @return SUCCESS if operation completed
*/
status_t (*del_ip) (kernel_interface_t *this, host_t *virtual_ip);
/**
- * @brief Destroys a kernel_interface object.
- *
- * @param kernel_interface_t calling object
+ * Destroys a kernel_interface object.
*/
void (*destroy) (kernel_interface_t *kernel_interface);
};
/**
- * @brief Creates an object of type kernel_interface_t.
- *
- * @ingroup kernel
+ * Creates an object of type kernel_interface_t.
*/
kernel_interface_t *kernel_interface_create(void);
-#endif /*KERNEL_INTERFACE_H_*/
+#endif /*KERNEL_INTERFACE_H_ @} */
diff --git a/src/charon/network/packet.c b/src/charon/network/packet.c
index f2fa91569..b47e6322f 100644
--- a/src/charon/network/packet.c
+++ b/src/charon/network/packet.c
@@ -1,10 +1,3 @@
-/**
- * @file packet.c
- *
- * @brief Implementation of packet_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,12 +12,12 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: packet.c 3589 2008-03-13 14:14:44Z martin $
*/
-
#include "packet.h"
-
typedef struct private_packet_t private_packet_t;
/**
diff --git a/src/charon/network/packet.h b/src/charon/network/packet.h
index acf953032..2f126d465 100644
--- a/src/charon/network/packet.h
+++ b/src/charon/network/packet.h
@@ -1,10 +1,3 @@
-/**
- * @file packet.h
- *
- * @brief Interface of packet_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: packet.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup packet packet
+ * @{ @ingroup network
*/
#ifndef PACKET_H_
@@ -30,105 +30,88 @@ typedef struct packet_t packet_t;
#include <utils/host.h>
/**
- * @brief Abstraction of an UDP-Packet, contains data, sender and receiver.
- *
- * @b Constructors:
- * - packet_create()
- *
- * @ingroup network
+ * Abstraction of an UDP-Packet, contains data, sender and receiver.
*/
struct packet_t {
/**
- * @brief Set the source address.
+ * Set the source address.
*
* Set host_t is now owned by packet_t, it will destroy
* it if necessary.
*
- * @param this calling object
* @param source address to set as source
*/
void (*set_source) (packet_t *packet, host_t *source);
/**
- * @brief Set the destination address.
+ * Set the destination address.
*
* Set host_t is now owned by packet_t, it will destroy
* it if necessary.
*
- * @param this calling object
* @param source address to set as destination
*/
void (*set_destination) (packet_t *packet, host_t *destination);
/**
- * @brief Get the source address.
+ * Get the source address.
*
* Set host_t is still owned by packet_t, clone it
* if needed.
*
- * @param this calling object
* @return source address
*/
host_t *(*get_source) (packet_t *packet);
/**
- * @brief Get the destination address.
+ * Get the destination address.
*
* Set host_t is still owned by packet_t, clone it
* if needed.
*
- * @param this calling object
* @return destination address
*/
host_t *(*get_destination) (packet_t *packet);
/**
- * @brief Get the data from the packet.
+ * Get the data from the packet.
*
* The data pointed by the chunk is still owned
* by the packet. Clone it if needed.
*
- * @param this calling object
* @return chunk containing the data
*/
chunk_t (*get_data) (packet_t *packet);
/**
- * @brief Set the data in the packet.
+ * Set the data in the packet.
*
* Supplied chunk data is now owned by the
* packet. It will free it.
*
- * @param this calling object
* @param data chunk with data to set
*/
void (*set_data) (packet_t *packet, chunk_t data);
/**
- * @brief Clones a packet_t object.
+ * Clones a packet_t object.
*
- * @param packet calling object
- * @param clone pointer to a packet_t object pointer where the new object is stored
+ * @param clone clone of the packet
*/
packet_t* (*clone) (packet_t *packet);
/**
- * @brief Destroy the packet, freeing contained data.
- *
- * @param packet packet to destroy
+ * Destroy the packet, freeing contained data.
*/
void (*destroy) (packet_t *packet);
};
/**
- * @brief create an empty packet
+ * create an empty packet
*
* @return packet_t object
- *
- * @ingroup network
*/
packet_t *packet_create(void);
-
-#endif /*PACKET_H_*/
+#endif /*PACKET_H_ @} */
diff --git a/src/charon/network/receiver.c b/src/charon/network/receiver.c
index 1de1dd3d2..885280a62 100644
--- a/src/charon/network/receiver.c
+++ b/src/charon/network/receiver.c
@@ -1,10 +1,3 @@
-/**
- * @file receiver.c
- *
- * @brief Implementation of receiver_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: receiver.c 3994 2008-05-21 21:52:59Z andreas $
*/
#include <stdlib.h>
@@ -33,9 +28,8 @@
#include <processing/jobs/job.h>
#include <processing/jobs/process_message_job.h>
#include <processing/jobs/callback_job.h>
+#include <crypto/hashers/hasher.h>
-/** length of the full cookie, including time (u_int32_t + SHA1()) */
-#define COOKIE_LENGTH 24
/** lifetime of a cookie, in seconds */
#define COOKIE_LIFETIME 10
/** how many times to reuse the secret */
@@ -94,9 +88,9 @@ struct private_receiver_t {
u_int32_t secret_offset;
/**
- * the randomizer to use for secret generation
+ * the RNG to use for secret generation
*/
- randomizer_t *randomizer;
+ rng_t *rng;
/**
* hasher to use for cookie calculation
@@ -145,11 +139,12 @@ static chunk_t cookie_build(private_receiver_t *this, message_t *message,
{
u_int64_t spi = message->get_initiator_spi(message);
host_t *ip = message->get_source(message);
- chunk_t input, hash = chunk_alloca(this->hasher->get_hash_size(this->hasher));
+ chunk_t input, hash;
/* COOKIE = t | sha1( IPi | SPIi | t | secret ) */
input = chunk_cata("cccc", ip->get_address(ip), chunk_from_thing(spi),
chunk_from_thing(t), secret);
+ hash = chunk_alloca(this->hasher->get_hash_size(this->hasher));
this->hasher->get_hash(this->hasher, input, hash.ptr);
return chunk_cat("cc", chunk_from_thing(t), hash);
}
@@ -167,7 +162,8 @@ static bool cookie_verify(private_receiver_t *this, message_t *message,
now = time(NULL);
t = *(u_int32_t*)cookie.ptr;
- if (cookie.len != COOKIE_LENGTH ||
+ if (cookie.len != sizeof(u_int32_t) +
+ this->hasher->get_hash_size(this->hasher) ||
t < now - this->secret_offset - COOKIE_LIFETIME)
{
DBG2(DBG_NET, "received cookie lifetime expired, rejecting");
@@ -212,7 +208,8 @@ static bool cookie_required(private_receiver_t *this, message_t *message)
packet_t *packet = message->get_packet(message);
chunk_t data = packet->get_data(packet);
if (data.len <
- IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH + COOKIE_LENGTH ||
+ IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH +
+ sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher) ||
*(data.ptr + 16) != NOTIFY ||
*(u_int16_t*)(data.ptr + IKE_HEADER_LENGTH + 6) != htons(COOKIE))
{
@@ -222,7 +219,7 @@ static bool cookie_required(private_receiver_t *this, message_t *message)
else
{
data.ptr += IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH;
- data.len = COOKIE_LENGTH;
+ data.len = sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher);
if (!cookie_verify(this, message, data))
{
DBG2(DBG_NET, "found cookie, but content invalid");
@@ -307,8 +304,7 @@ static job_requeue_t receive_packets(private_receiver_t *this)
DBG1(DBG_NET, "generating new cookie secret after %d uses",
this->secret_used);
memcpy(this->secret_old, this->secret, SECRET_LENGTH);
- this->randomizer->get_pseudo_random_bytes(this->randomizer,
- SECRET_LENGTH, this->secret);
+ this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret);
this->secret_switch = now;
this->secret_used = 0;
}
@@ -320,7 +316,7 @@ static job_requeue_t receive_packets(private_receiver_t *this)
if (peer_to_aggressive(this, message))
{
DBG1(DBG_NET, "ignoring IKE_SA setup from %H, "
- "peer to aggressive", message->get_source(message));
+ "peer too aggressive", message->get_source(message));
message->destroy(message);
return JOB_REQUEUE_DIRECT;
}
@@ -336,7 +332,7 @@ static job_requeue_t receive_packets(private_receiver_t *this)
static void destroy(private_receiver_t *this)
{
this->job->cancel(this->job);
- this->randomizer->destroy(this->randomizer);
+ this->rng->destroy(this->rng);
this->hasher->destroy(this->hasher);
free(this);
}
@@ -351,13 +347,25 @@ receiver_t *receiver_create()
this->public.destroy = (void(*)(receiver_t*)) destroy;
- this->randomizer = randomizer_create();
- this->hasher = hasher_create(HASH_SHA1);
+ this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_PREFERRED);
+ if (this->hasher == NULL)
+ {
+ DBG1(DBG_NET, "creating cookie hasher failed, no hashers supported");
+ free(this);
+ return NULL;
+ }
+ this->rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ if (this->rng == NULL)
+ {
+ DBG1(DBG_NET, "creating cookie RNG failed, no RNG supported");
+ this->hasher->destroy(this->hasher);
+ free(this);
+ return NULL;
+ }
this->secret_switch = now;
this->secret_offset = random() % now;
this->secret_used = 0;
- this->randomizer->get_pseudo_random_bytes(this->randomizer, SECRET_LENGTH,
- this->secret);
+ this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret);
memcpy(this->secret_old, this->secret, SECRET_LENGTH);
this->job = callback_job_create((callback_job_cb_t)receive_packets,
diff --git a/src/charon/network/receiver.h b/src/charon/network/receiver.h
index 1bfa7b764..810a51849 100644
--- a/src/charon/network/receiver.h
+++ b/src/charon/network/receiver.h
@@ -1,10 +1,3 @@
-/**
- * @file receiver.h
- *
- * @brief Interface of receiver_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: receiver.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup receiver receiver
+ * @{ @ingroup network
*/
#ifndef RECEIVER_H_
@@ -30,7 +30,7 @@ typedef struct receiver_t receiver_t;
#include <utils/host.h>
/**
- * @brief Receives packets from the socket and adds them to the job queue.
+ * Receives packets from the socket and adds them to the job queue.
*
* The receiver starts a thread, wich reads on the blocking socket. A received
* packet is preparsed and a process_message_job is queued in the job queue.
@@ -50,32 +50,23 @@ typedef struct receiver_t receiver_t;
*
* Further, the number of half-initiated IKE_SAs is limited per peer. This
* mades it impossible for a peer to flood the server with its real IP address.
- *
- * @b Constructors:
- * - receiver_create()
- *
- * @ingroup network
*/
struct receiver_t {
/**
- * @brief Destroys a receiver_t object.
- *
- * @param receiver receiver object
+ * Destroys a receiver_t object.
*/
void (*destroy) (receiver_t *receiver);
};
/**
- * @brief Create a receiver_t object.
+ * Create a receiver_t object.
*
* The receiver thread will start working, get data
* from the socket and add those packets to the job queue.
*
- * @return receiver_t object
- *
- * @ingroup network
+ * @return receiver_t object, NULL if initialization fails
*/
receiver_t * receiver_create(void);
-#endif /*RECEIVER_H_*/
+#endif /*RECEIVER_H_ @} */
diff --git a/src/charon/network/sender.c b/src/charon/network/sender.c
index f934dc509..60a08d0c3 100644
--- a/src/charon/network/sender.c
+++ b/src/charon/network/sender.c
@@ -1,10 +1,3 @@
-/**
- * @file sender.c
- *
- * @brief Implementation of sender_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: sender.c 3742 2008-04-03 09:19:12Z tobias $
*/
#include <stdlib.h>
@@ -58,9 +53,14 @@ struct private_sender_t {
pthread_mutex_t mutex;
/**
- * condvar to signal for packets in list
+ * condvar to signal for packets added to list
*/
- pthread_cond_t condvar;
+ pthread_cond_t gotone;
+
+ /**
+ * condvar to signal for packets sent
+ */
+ pthread_cond_t sentone;
};
/**
@@ -76,8 +76,8 @@ static void send_(private_sender_t *this, packet_t *packet)
pthread_mutex_lock(&this->mutex);
this->list->insert_last(this->list, packet);
+ pthread_cond_signal(&this->gotone);
pthread_mutex_unlock(&this->mutex);
- pthread_cond_signal(&this->condvar);
}
/**
@@ -95,12 +95,13 @@ static job_requeue_t send_packets(private_sender_t * this)
pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, (void*)&this->mutex);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
- pthread_cond_wait(&this->condvar, &this->mutex);
+ pthread_cond_wait(&this->gotone, &this->mutex);
pthread_setcancelstate(oldstate, NULL);
pthread_cleanup_pop(0);
}
this->list->remove_first(this->list, (void**)&packet);
+ pthread_cond_signal(&this->sentone);
pthread_mutex_unlock(&this->mutex);
charon->socket->send(charon->socket, packet);
@@ -114,10 +115,13 @@ static job_requeue_t send_packets(private_sender_t * this)
static void destroy(private_sender_t *this)
{
/* send all packets in the queue */
+ pthread_mutex_lock(&this->mutex);
while (this->list->get_count(this->list))
{
- sched_yield();
+ pthread_cond_wait(&this->sentone, &this->mutex);
}
+ pthread_mutex_unlock(&this->mutex);
+ pthread_mutex_destroy(&this->mutex);
this->job->cancel(this->job);
this->list->destroy(this->list);
free(this);
@@ -135,7 +139,8 @@ sender_t * sender_create()
this->list = linked_list_create();
pthread_mutex_init(&this->mutex, NULL);
- pthread_cond_init(&this->condvar, NULL);
+ pthread_cond_init(&this->gotone, NULL);
+ pthread_cond_init(&this->sentone, NULL);
this->job = callback_job_create((callback_job_cb_t)send_packets,
this, NULL, NULL);
diff --git a/src/charon/network/sender.h b/src/charon/network/sender.h
index 8d611cc90..4a67c7e72 100644
--- a/src/charon/network/sender.h
+++ b/src/charon/network/sender.h
@@ -1,10 +1,3 @@
-/**
- * @file sender.h
- *
- * @brief Interface of sender_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: sender.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup sender sender
+ * @{ @ingroup network
*/
#ifndef SENDER_H_
@@ -30,45 +30,35 @@ typedef struct sender_t sender_t;
#include <network/packet.h>
/**
- * @brief Thread responsible for sending packets over the socket.
- *
- * @b Constructors:
- * - sender_create()
- *
- * @ingroup network
+ * Thread responsible for sending packets over the socket.
*/
struct sender_t {
/**
- * @brief Send a packet over the network.
+ * Send a packet over the network.
*
* This function is non blocking and adds the packet to a queue.
* Whenever the sender thread thinks it's good to send the packet,
* it'll do so.
*
- * @param this calling object
* @param packet packet to send
*/
void (*send) (sender_t *this, packet_t *packet);
/**
- * @brief Destroys a sender object.
- *
- * @param this calling object
+ * Destroys a sender object.
*/
void (*destroy) (sender_t *this);
};
/**
- * @brief Create the sender thread.
+ * Create the sender thread.
*
* The thread will start to work, getting packets
* from its queue and sends them out.
*
* @return created sender object
- *
- * @ingroup network
*/
sender_t * sender_create(void);
-#endif /*SENDER_H_*/
+#endif /*SENDER_H_ @} */
diff --git a/src/charon/network/socket-raw.c b/src/charon/network/socket-raw.c
index 3b76ae570..5d1623ffd 100644
--- a/src/charon/network/socket-raw.c
+++ b/src/charon/network/socket-raw.c
@@ -1,10 +1,3 @@
-/**
- * @file socket.c
- *
- * @brief Implementation of socket_t.
- *
- */
-
/*
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
@@ -20,8 +13,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: socket-raw.c 3870 2008-04-24 13:49:20Z martin $
*/
+/* for struct in6_pktinfo */
+#define _GNU_SOURCE
+
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/src/charon/network/socket.c b/src/charon/network/socket.c
index a4c407579..60ea5f7c8 100644
--- a/src/charon/network/socket.c
+++ b/src/charon/network/socket.c
@@ -1,10 +1,3 @@
-/**
- * @file socket.c
- *
- * @brief Implementation of socket_t.
- *
- */
-
/*
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
* Copyright (C) 2005-2007 Martin Willi
@@ -20,8 +13,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: socket.c 3870 2008-04-24 13:49:20Z martin $
*/
+/* for struct in6_pktinfo */
+#define _GNU_SOURCE
+
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/src/charon/network/socket.h b/src/charon/network/socket.h
index 4d8251325..077da4bba 100644
--- a/src/charon/network/socket.h
+++ b/src/charon/network/socket.h
@@ -1,10 +1,3 @@
-/**
- * @file socket.h
- *
- * @brief Interface for socket_t.
- *
- */
-
/*
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
@@ -20,6 +13,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: socket.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup socket socket
+ * @{ @ingroup network
*/
#ifndef SOCKET_H_
@@ -33,38 +33,36 @@ typedef struct socket_t socket_t;
#include <utils/linked_list.h>
/**
- * @brief Maximum size of a packet.
- *
- * 3000 Bytes should be sufficient, see IKEv2 RFC.
+ * Maximum size of a packet.
*
- * @ingroup network
+ * 3000 Bytes should be sufficient, see IKEv2 RFC. However, we currently
+ * do not support HASH_AND_URL certificates, so we require to transmit
+ * the full certificates. To run our multi-CA test with 2 intermediate CAs,
+ * 5000 bytes is sufficient.
*/
-#define MAX_PACKET 3000
+#define MAX_PACKET 5000
/**
- * @brief Abstraction of all sockets (IPv6/IPv6 send/receive).
+ * Abstraction of all sockets (IPv4/IPv6 send/receive).
*
* All available sockets are bound and the receive function
- * reads from them. To allow binding of other daemons (pluto) to
- * UDP/500, this implementation uses RAW sockets. An installed
- * "Linux socket filter" filters out all non-IKEv2 traffic and handles
- * just IKEv2 messages. An other daemon (pluto) must handle all traffic
- * seperatly, e.g. ignore IKEv2 traffic, since charon handles that.
- *
- * @b Constructors:
- * - socket_create()
- *
- * @ingroup network
+ * reads from them. There are actually two implementations:
+ * The first uses raw sockets to allow binding of other daemons (pluto) to
+ * UDP/500. An installed "Linux socket filter" filters out all non-IKEv2
+ * traffic and handles just IKEv2 messages. An other daemon (pluto) must
+ * handle all traffic seperatly, e.g. ignore IKEv2 traffic, since charon
+ * handles that.
+ * The other implementation uses normal sockets and is built if
+ * --disable-pluto is given to the configure script.
*/
struct socket_t {
/**
- * @brief Receive a packet.
+ * Receive a packet.
*
* Reads a packet from the socket and sets source/dest
* appropriately.
*
- * @param this socket_t object to work on
* @param packet pinter gets address from allocated packet_t
* @return
* - SUCCESS when packet successfully received
@@ -73,14 +71,13 @@ struct socket_t {
status_t (*receive) (socket_t *this, packet_t **packet);
/**
- * @brief Send a packet.
+ * Send a packet.
*
* Sends a packet to the net using destination from the packet.
* Packet is sent using default routing mechanisms, thus the
* source address in packet is ignored.
*
- * @param this socket_t object to work on
- * @param packet[out] packet_t to send
+ * @param packet packet_t to send
* @return
* - SUCCESS when packet successfully sent
* - FAILED when unable to send
@@ -88,23 +85,16 @@ struct socket_t {
status_t (*send) (socket_t *this, packet_t *packet);
/**
- * @brief Destroy sockets.
- *
- * close sockets and destroy socket_t object
- *
- * @param this socket_t to destroy
+ * Destroy socket.
*/
void (*destroy) (socket_t *this);
};
/**
- * @brief Create a socket_t, wich binds multiple sockets.
+ * Create a socket_t, wich binds multiple sockets.
*
* @return socket_t object
- *
- * @ingroup network
*/
socket_t *socket_create();
-
-#endif /*SOCKET_H_*/
+#endif /*SOCKET_H_ @} */
diff --git a/src/charon/plugins/eap_aka/Makefile.am b/src/charon/plugins/eap_aka/Makefile.am
new file mode 100644
index 000000000..e1ad1eaf9
--- /dev/null
+++ b/src/charon/plugins/eap_aka/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-eapaka.la
+
+libstrongswan_eapaka_la_SOURCES = eap_aka_plugin.h eap_aka_plugin.c eap_aka.h eap_aka.c
+libstrongswan_eapaka_la_LDFLAGS = -module
+libstrongswan_eapaka_la_LIBADD = -lgmp
+
diff --git a/src/charon/plugins/eap_aka/Makefile.in b/src/charon/plugins/eap_aka/Makefile.in
new file mode 100644
index 000000000..ad28b0247
--- /dev/null
+++ b/src/charon/plugins/eap_aka/Makefile.in
@@ -0,0 +1,496 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@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/charon/plugins/eap_aka
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_eapaka_la_DEPENDENCIES =
+am_libstrongswan_eapaka_la_OBJECTS = eap_aka_plugin.lo eap_aka.lo
+libstrongswan_eapaka_la_OBJECTS = \
+ $(am_libstrongswan_eapaka_la_OBJECTS)
+libstrongswan_eapaka_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_eapaka_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+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_eapaka_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_eapaka_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+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_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-eapaka.la
+libstrongswan_eapaka_la_SOURCES = eap_aka_plugin.h eap_aka_plugin.c eap_aka.h eap_aka.c
+libstrongswan_eapaka_la_LDFLAGS = -module
+libstrongswan_eapaka_la_LIBADD = -lgmp
+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 \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/eap_aka/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/eap_aka/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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-eapaka.la: $(libstrongswan_eapaka_la_OBJECTS) $(libstrongswan_eapaka_la_DEPENDENCIES)
+ $(libstrongswan_eapaka_la_LINK) -rpath $(plugindir) $(libstrongswan_eapaka_la_OBJECTS) $(libstrongswan_eapaka_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_aka.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_aka_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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)
+
+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-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
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-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/charon/sa/authenticators/eap/eap_aka.c b/src/charon/plugins/eap_aka/eap_aka.c
index 8fb1f85cd..9e35de9e1 100644
--- a/src/charon/sa/authenticators/eap/eap_aka.c
+++ b/src/charon/plugins/eap_aka/eap_aka.c
@@ -1,10 +1,3 @@
-/**
- * @file eap_aka.c
- *
- * @brief Implementation of eap_aka_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_aka.c 4008 2008-05-23 15:49:43Z martin $
*/
@@ -44,14 +39,13 @@
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
+#include <gmp.h>
#include "eap_aka.h"
#include <daemon.h>
#include <library.h>
-#include <utils/randomizer.h>
#include <crypto/hashers/hasher.h>
-#include <crypto/prfs/fips_prf.h>
/* Use test vectors specified in S.S0055
#define TEST_VECTORS */
@@ -84,6 +78,54 @@
#define F5 0x47
#define F5STAR 0x48
+typedef enum aka_subtype_t aka_subtype_t;
+typedef enum aka_attribute_t aka_attribute_t;
+
+/**
+ * Subtypes of AKA messages
+ */
+enum aka_subtype_t {
+ AKA_CHALLENGE = 1,
+ AKA_AUTHENTICATION_REJECT = 2,
+ AKA_SYNCHRONIZATION_FAILURE = 4,
+ AKA_IDENTITY = 5,
+ AKA_NOTIFICATION = 12,
+ AKA_REAUTHENTICATION = 13,
+ AKA_CLIENT_ERROR = 14,
+};
+
+/**
+ * Attribute types in AKA messages
+ */
+enum aka_attribute_t {
+ /** defines the end of attribute list */
+ AT_END = -1,
+ AT_RAND = 1,
+ AT_AUTN = 2,
+ AT_RES = 3,
+ AT_AUTS = 4,
+ AT_PADDING = 6,
+ AT_NONCE_MT = 7,
+ AT_PERMANENT_ID_REQ = 10,
+ AT_MAC = 11,
+ AT_NOTIFICATION = 12,
+ AT_ANY_ID_REQ = 13,
+ AT_IDENTITY = 14,
+ AT_VERSION_LIST = 15,
+ AT_SELECTED_VERSION = 16,
+ AT_FULLAUTH_ID_REQ = 17,
+ AT_COUNTER = 19,
+ AT_COUNTER_TOO_SMALL = 20,
+ AT_NONCE_S = 21,
+ AT_CLIENT_ERROR_CODE = 22,
+ AT_IV = 129,
+ AT_ENCR_DATA = 130,
+ AT_NEXT_PSEUDONYM = 132,
+ AT_NEXT_REAUTH_ID = 133,
+ AT_CHECKCODE = 134,
+ AT_RESULT_IND = 135,
+};
+
ENUM_BEGIN(aka_subtype_names, AKA_CHALLENGE, AKA_IDENTITY,
"AKA_CHALLENGE",
"AKA_AUTHENTICATION_REJECT",
@@ -156,6 +198,26 @@ struct private_eap_aka_t {
identification_t *peer;
/**
+ * SHA11 hasher
+ */
+ hasher_t *sha1;
+
+ /**
+ * MAC function used in EAP-AKA
+ */
+ signer_t *signer;
+
+ /**
+ * pseudo random function used in EAP-aka
+ */
+ prf_t *prf;
+
+ /**
+ * Special keyed SHA1 hasher used in EAP-AKA, implemented as PRF
+ */
+ prf_t *keyed_prf;
+
+ /**
* Key for EAP MAC
*/
chunk_t k_auth;
@@ -347,7 +409,7 @@ static void mpz_mod_poly(mpz_t r, mpz_t a, mpz_t b)
* Step 4 of the various fx() functions:
* Polynomial whiten calculations
*/
-static void step4(u_int8_t x[])
+static void step4(private_eap_aka_t *this, u_int8_t x[])
{
mpz_t xm, am, bm, gm;
@@ -377,24 +439,35 @@ static void step4(u_int8_t x[])
* Step 3 of the various fx() functions:
* XOR the key into the SHA1 IV
*/
-static void step3(chunk_t k, chunk_t payload, u_int8_t h[])
+static void step3(private_eap_aka_t *this,
+ chunk_t k, chunk_t payload, u_int8_t h[])
{
- u_int8_t iv[] = {
- 0x67,0x45,0x23,0x01,0xEF,0xCD,0xAB,0x89,0x98,0xBA,
- 0xDC,0xFE,0x10,0x32,0x54,0x76,0xC3,0xD2,0xE1,0xF0,
- };
+ u_int8_t buf[64];
- /* XOR key into IV */
- memxor(iv, k.ptr, k.len);
+ if (payload.len < sizeof(buf))
+ {
+ /* pad c with zeros */
+ memset(buf, 0, sizeof(buf));
+ memcpy(buf, payload.ptr, payload.len);
+ payload.ptr = buf;
+ payload.len = sizeof(buf);
+ }
+ else
+ {
+ /* not more than 512 bits can be G()-ed */
+ payload.len = sizeof(buf);
+ }
- /* hash it with the G() function defined in FIPS 186-2 from fips_prf.h */
- g_sha1(iv, payload, h);
+ /* use the keyed hasher to build the hash */
+ this->keyed_prf->set_key(this->keyed_prf, k);
+ this->keyed_prf->get_bytes(this->keyed_prf, payload, h);
}
/**
* Calculation function for f2(), f3(), f4()
*/
-static void fx(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t out[])
+static void fx(private_eap_aka_t *this,
+ u_int8_t f, chunk_t k, chunk_t rand, u_int8_t out[])
{
chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
u_int8_t h[HASH_SIZE_SHA1];
@@ -412,8 +485,8 @@ static void fx(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t out[])
payload.ptr[35] ^= i;
payload.ptr[51] ^= i;
- step3(k, payload, h);
- step4(h);
+ step3(this, k, payload, h);
+ step4(this, h);
memcpy(out + i * 8, h, 8);
}
}
@@ -421,7 +494,8 @@ static void fx(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t out[])
/**
* Calculation function of f1() and f1star()
*/
-static void f1x(u_int8_t f, chunk_t k, chunk_t rand, chunk_t sqn,
+static void f1x(private_eap_aka_t *this,
+ u_int8_t f, chunk_t k, chunk_t rand, chunk_t sqn,
chunk_t amf, u_int8_t mac[])
{
/* generate MAC = f1(FMK, SQN, RAND, AMF)
@@ -438,15 +512,16 @@ static void f1x(u_int8_t f, chunk_t k, chunk_t rand, chunk_t sqn,
memxor(payload.ptr + 34, sqn.ptr, sqn.len);
memxor(payload.ptr + 42, amf.ptr, amf.len);
- step3(k, payload, h);
- step4(h);
+ step3(this, k, payload, h);
+ step4(this, h);
memcpy(mac, h, MAC_LENGTH);
}
/**
* Calculation function of f5() and f5star()
*/
-static void f5x(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t ak[])
+static void f5x(private_eap_aka_t *this,
+ u_int8_t f, chunk_t k, chunk_t rand, u_int8_t ak[])
{
chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
u_int8_t h[HASH_SIZE_SHA1];
@@ -456,81 +531,81 @@ static void f5x(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t ak[])
memxor(payload.ptr + 12, fmk.ptr, fmk.len);
memxor(payload.ptr + 16, rand.ptr, rand.len);
- step3(k, payload, h);
- step4(h);
+ step3(this, k, payload, h);
+ step4(this, h);
memcpy(ak, h, AK_LENGTH);
}
/**
* Calculate the MAC from a RAND, SQN, AMF value using K
*/
-static void f1(chunk_t k, chunk_t rand, chunk_t sqn, chunk_t amf, u_int8_t mac[])
+static void f1(private_eap_aka_t *this, chunk_t k, chunk_t rand, chunk_t sqn,
+ chunk_t amf, u_int8_t mac[])
{
- f1x(F1, k, rand, sqn, amf, mac);
+ f1x(this, F1, k, rand, sqn, amf, mac);
DBG3(DBG_IKE, "MAC %b", mac, MAC_LENGTH);
}
/**
* Calculate the MACS from a RAND, SQN, AMF value using K
*/
-static void f1star(chunk_t k, chunk_t rand, chunk_t sqn, chunk_t amf, u_int8_t macs[])
+static void f1star(private_eap_aka_t *this, chunk_t k, chunk_t rand,
+ chunk_t sqn, chunk_t amf, u_int8_t macs[])
{
- f1x(F1STAR, k, rand, sqn, amf, macs);
+ f1x(this, F1STAR, k, rand, sqn, amf, macs);
DBG3(DBG_IKE, "MACS %b", macs, MAC_LENGTH);
}
/**
* Calculate RES from RAND using K
*/
-static void f2(chunk_t k, chunk_t rand, u_int8_t res[])
+static void f2(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t res[])
{
- fx(F2, k, rand, res);
+ fx(this, F2, k, rand, res);
DBG3(DBG_IKE, "RES %b", res, RES_LENGTH);
}
/**
* Calculate CK from RAND using K
*/
-static void f3(chunk_t k, chunk_t rand, u_int8_t ck[])
+static void f3(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t ck[])
{
- fx(F3, k, rand, ck);
+ fx(this, F3, k, rand, ck);
DBG3(DBG_IKE, "CK %b", ck, CK_LENGTH);
}
/**
* Calculate IK from RAND using K
*/
-static void f4(chunk_t k, chunk_t rand, u_int8_t ik[])
+static void f4(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t ik[])
{
- fx(F4, k, rand, ik);
+ fx(this, F4, k, rand, ik);
DBG3(DBG_IKE, "IK %b", ik, IK_LENGTH);
}
/**
* Calculate AK from a RAND using K
*/
-static void f5(chunk_t k, chunk_t rand, u_int8_t ak[])
+static void f5(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t ak[])
{
- f5x(F5, k, rand, ak);
+ f5x(this, F5, k, rand, ak);
DBG3(DBG_IKE, "AK %b", ak, AK_LENGTH);
}
/**
* Calculate AKS from a RAND using K
*/
-static void f5star(chunk_t k, chunk_t rand, u_int8_t aks[])
+static void f5star(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t aks[])
{
- f5x(F5STAR, k, rand, aks);
+ f5x(this, F5STAR, k, rand, aks);
DBG3(DBG_IKE, "AKS %b", aks, AK_LENGTH);
}
/**
* derive the keys needed for EAP_AKA
*/
-static void derive_keys(private_eap_aka_t *this, identification_t *id)
+static bool derive_keys(private_eap_aka_t *this, identification_t *id)
{
- hasher_t *hasher;
- prf_t *prf;
chunk_t ck, ik, mk, identity, tmp;
ck = chunk_alloca(CK_LENGTH);
@@ -539,26 +614,22 @@ static void derive_keys(private_eap_aka_t *this, identification_t *id)
identity = id->get_encoding(id);
/* MK = SHA1( Identity | IK | CK ) */
- f3(this->k, this->rand, ck.ptr);
- f4(this->k, this->rand, ik.ptr);
+ f3(this, this->k, this->rand, ck.ptr);
+ f4(this, this->k, this->rand, ik.ptr);
DBG3(DBG_IKE, "Identity %B", &identity);
tmp = chunk_cata("ccc", identity, ik, ck);
DBG3(DBG_IKE, "Identity|IK|CK %B", &tmp);
- hasher = hasher_create(HASH_SHA1);
- hasher->get_hash(hasher, tmp, mk.ptr);
- hasher->destroy(hasher);
+ this->sha1->get_hash(this->sha1, tmp, mk.ptr);
/* K_encr | K_auth | MSK | EMSK = prf(0) | prf(0)
* FIPS PRF has 320 bit block size, we need 160 byte for keys
* => run prf four times */
- prf = prf_create(PRF_FIPS_SHA1_160);
- prf->set_key(prf, mk);
- tmp = chunk_alloca(prf->get_block_size(prf) * 4);
- prf->get_bytes(prf, chunk_empty, tmp.ptr);
- prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 1);
- prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 2);
- prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 3);
- prf->destroy(prf);
+ this->prf->set_key(this->prf, mk);
+ tmp = chunk_alloca(this->prf->get_block_size(this->prf) * 4);
+ this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr);
+ this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr + tmp.len / 4 * 1);
+ this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr + tmp.len / 4 * 2);
+ this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr + tmp.len / 4 * 3);
chunk_free(&this->k_encr);
chunk_free(&this->k_auth);
chunk_free(&this->msk);
@@ -571,6 +642,7 @@ static void derive_keys(private_eap_aka_t *this, identification_t *id)
DBG3(DBG_IKE, "K_auth %B", &this->k_auth);
DBG3(DBG_IKE, "MSK %B", &this->msk);
DBG3(DBG_IKE, "EMSK %B", &this->emsk);
+ return TRUE;
}
/*
@@ -582,18 +654,21 @@ static void derive_keys(private_eap_aka_t *this, identification_t *id)
*/
static status_t load_key(identification_t *me, identification_t *other, chunk_t *k)
{
- chunk_t shared_key;
+ shared_key_t *shared;
+ chunk_t key;
- if (charon->credentials->get_eap_key(charon->credentials, me,
- other, &shared_key) != SUCCESS)
+ shared = charon->credentials->get_shared(charon->credentials, SHARED_EAP,
+ me, other);
+ if (shared == NULL)
{
return NOT_FOUND;
}
+ key = shared->get_key(shared);
chunk_free(k);
*k = chunk_alloc(K_LENGTH);
memset(k->ptr, '\0', k->len);
- memcpy(k->ptr, shared_key.ptr, min(shared_key.len, k->len));
- chunk_free(&shared_key);
+ memcpy(k->ptr, key.ptr, min(key.len, k->len));
+ shared->destroy(shared);
return SUCCESS;
}
@@ -739,13 +814,11 @@ static eap_payload_t *build_aka_payload(private_eap_aka_t *this, eap_code_t code
/* create MAC if AT_MAC attribte was included */
if (mac_pos)
{
- signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
- signer->set_key(signer, this->k_auth);
+ this->signer->set_key(this->signer, this->k_auth);
DBG3(DBG_IKE, "AT_MAC signature of %B", &message);
DBG3(DBG_IKE, "using key %B", &this->k_auth);
- signer->get_signature(signer, message, mac_pos);
+ this->signer->get_signature(this->signer, message, mac_pos);
DBG3(DBG_IKE, "is %b", mac_pos, AT_MAC_LENGTH);
- signer->destroy(signer);
}
/* payload constructor takes data with some bytes skipped */
@@ -758,10 +831,10 @@ static eap_payload_t *build_aka_payload(private_eap_aka_t *this, eap_code_t code
/**
* Initiate a AKA-Challenge using SQN
*/
-static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn, eap_payload_t **out)
+static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn,
+ eap_payload_t **out)
{
- randomizer_t *randomizer;
- status_t status;
+ rng_t *rng;
chunk_t mac, ak, autn;
mac = chunk_alloca(MAC_LENGTH);
@@ -770,16 +843,16 @@ static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn,
chunk_free(&this->xres);
/* generate RAND:
- * we use our standard randomizer, not f0() proposed in S.S0055
+ * we use a registered RNG, not f0() proposed in S.S0055
*/
- randomizer = randomizer_create();
- status = randomizer->allocate_pseudo_random_bytes(randomizer, RAND_LENGTH, &this->rand);
- randomizer->destroy(randomizer);
- if (status != SUCCESS)
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (!rng)
{
DBG1(DBG_IKE, "generating RAND for EAP-AKA authentication failed");
return FAILED;
}
+ rng->allocate_bytes(rng, RAND_LENGTH, &this->rand);
+ rng->destroy(rng);
# ifdef TEST_VECTORS
/* Test vector for RAND */
@@ -808,14 +881,14 @@ static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn,
# endif /* TEST_VECTORS */
/* generate MAC */
- f1(this->k, this->rand, sqn, amf, mac.ptr);
+ f1(this, this->k, this->rand, sqn, amf, mac.ptr);
/* generate AK */
- f5(this->k, this->rand, ak.ptr);
+ f5(this, this->k, this->rand, ak.ptr);
/* precalculate XRES as expected from client */
this->xres = chunk_alloc(RES_LENGTH);
- f2(this->k, this->rand, this->xres.ptr);
+ f2(this, this->k, this->rand, this->xres.ptr);
/* calculate AUTN = (SQN xor AK) || AMF || MAC */
autn = chunk_cata("ccc", sqn, amf, mac);
@@ -896,7 +969,7 @@ static status_t server_process_synchronize(private_eap_aka_t *this,
chunk_split(auts, "mm", SQN_LENGTH, &sqn, MAC_LENGTH, &macs);
aks = chunk_alloca(AK_LENGTH);
- f5star(this->k, this->rand, aks.ptr);
+ f5star(this, this->k, this->rand, aks.ptr);
/* decrypt serial number by XORing AKS */
memxor(sqn.ptr, aks.ptr, aks.len);
@@ -905,7 +978,7 @@ static status_t server_process_synchronize(private_eap_aka_t *this,
amf = chunk_alloca(AMF_LENGTH);
/* an AMF of zero is used for MACS calculation */
memset(amf.ptr, 0, amf.len);
- f1star(this->k, this->rand, sqn, amf, xmacs.ptr);
+ f1star(this, this->k, this->rand, sqn, amf, xmacs.ptr);
if (!chunk_equals(macs, xmacs))
{
DBG1(DBG_IKE, "received MACS does not match XMACS");
@@ -974,14 +1047,10 @@ static status_t server_process_challenge(private_eap_aka_t *this, eap_payload_t
/* verify EAP message MAC AT_MAC */
{
- bool valid;
- signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
- signer->set_key(signer, this->k_auth);
+ this->signer->set_key(this->signer, this->k_auth);
DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
DBG3(DBG_IKE, "using key %B", &this->k_auth);
- valid = signer->verify_signature(signer, message, at_mac);
- signer->destroy(signer);
- if (!valid)
+ if (!this->signer->verify_signature(this->signer, message, at_mac))
{
DBG1(DBG_IKE, "MAC in AT_MAC attribute verification failed");
return FAILED;
@@ -1135,7 +1204,7 @@ static status_t peer_process_challenge(private_eap_aka_t *this,
# endif /* TEST_VECTORS */
/* calculate anonymity key AK */
- f5(this->k, this->rand, ak.ptr);
+ f5(this, this->k, this->rand, ak.ptr);
DBG3(DBG_IKE, "using rand %B", &this->rand);
DBG3(DBG_IKE, "using ak %B", &ak);
/* XOR AK into SQN to decrypt it */
@@ -1147,7 +1216,7 @@ static status_t peer_process_challenge(private_eap_aka_t *this,
DBG3(DBG_IKE, "using sqn %B", &sqn);
/* calculate expected MAC and compare against received one */
- f1(this->k, this->rand, sqn, amf, xmac.ptr);
+ f1(this, this->k, this->rand, sqn, amf, xmac.ptr);
if (!chunk_equals(mac, xmac))
{
*out = build_aka_payload(this, EAP_RESPONSE, identifier,
@@ -1171,9 +1240,9 @@ static status_t peer_process_challenge(private_eap_aka_t *this,
/* AMF is set to zero in AKA_SYNCHRONIZATION_FAILURE */
memset(amf.ptr, 0, amf.len);
/* AKS = f5*(RAND) */
- f5star(this->k, this->rand, aks.ptr);
+ f5star(this, this->k, this->rand, aks.ptr);
/* MACS = f1*(RAND) */
- f1star(this->k, this->rand, peer_sqn, amf, macs.ptr);
+ f1star(this, this->k, this->rand, peer_sqn, amf, macs.ptr);
/* AUTS = SQN xor AKS | MACS */
memxor(aks.ptr, peer_sqn.ptr, aks.len);
auts = chunk_cata("cc", aks, macs);
@@ -1190,33 +1259,26 @@ static status_t peer_process_challenge(private_eap_aka_t *this,
/* derive K_encr, K_auth, MSK, EMSK */
derive_keys(this, this->peer);
-
+
/* verify EAP message MAC AT_MAC */
+ DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
+ DBG3(DBG_IKE, "using key %B", &this->k_auth);
+ this->signer->set_key(this->signer, this->k_auth);
+ if (!this->signer->verify_signature(this->signer, message, at_mac))
{
- bool valid;
- signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
- signer->set_key(signer, this->k_auth);
-
- DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
- DBG3(DBG_IKE, "using key %B", &this->k_auth);
- valid = signer->verify_signature(signer, message, at_mac);
- signer->destroy(signer);
- if (!valid)
- {
- *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
- AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
- DBG1(DBG_IKE, "MAC in AT_MAC attribute verification "
- "failed, sending %N %d", aka_attribute_names,
- AT_CLIENT_ERROR_CODE, 0);
- return NEED_MORE;
- }
+ *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
+ AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
+ DBG1(DBG_IKE, "MAC in AT_MAC attribute verification "
+ "failed, sending %N %d", aka_attribute_names,
+ AT_CLIENT_ERROR_CODE, 0);
+ return NEED_MORE;
}
/* update stored SQN to the received one */
memcpy(peer_sqn.ptr, sqn.ptr, sqn.len);
/* calculate RES */
- f2(this->k, this->rand, res.ptr);
+ f2(this, this->k, this->rand, res.ptr);
/* build response */
*out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CHALLENGE,
@@ -1387,6 +1449,10 @@ static bool is_mutual(private_eap_aka_t *this)
*/
static void destroy(private_eap_aka_t *this)
{
+ DESTROY_IF(this->sha1);
+ DESTROY_IF(this->signer);
+ DESTROY_IF(this->prf);
+ DESTROY_IF(this->keyed_prf);
chunk_free(&this->k_encr);
chunk_free(&this->k_auth);
chunk_free(&this->msk);
@@ -1397,29 +1463,16 @@ static void destroy(private_eap_aka_t *this)
free(this);
}
-/*
- * Described in header.
+/**
+ * generic constructor used by client & server
*/
-eap_aka_t *eap_create(eap_role_t role,
- identification_t *server, identification_t *peer)
+static private_eap_aka_t *eap_aka_create_generic(identification_t *server,
+ identification_t *peer)
{
private_eap_aka_t *this = malloc_thing(private_eap_aka_t);
- /* public functions */
- switch (role)
- {
- case EAP_SERVER:
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))server_initiate;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))server_process;
- break;
- case EAP_PEER:
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))peer_initiate;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))peer_process;
- break;
- default:
- free(this);
- return NULL;
- }
+ this->public.eap_method_interface.initiate = NULL;
+ this->public.eap_method_interface.process = NULL;
this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
@@ -1436,5 +1489,51 @@ eap_aka_t *eap_create(eap_role_t role,
this->k = chunk_empty;
this->rand = chunk_empty;
- return &this->public;
+ this->sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA1_128);
+ this->prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160);
+ this->keyed_prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1);
+
+ if (!this->sha1 || !this->signer || !this->prf || !this->keyed_prf)
+ {
+ DBG1(DBG_IKE, "unable to initiate EAP-AKA, FIPS-PRF/SHA1 not supported");
+ DESTROY_IF(this->sha1);
+ DESTROY_IF(this->signer);
+ DESTROY_IF(this->prf);
+ DESTROY_IF(this->keyed_prf);
+ destroy(this);
+ return NULL;
+ }
+ return this;
+}
+
+/*
+ * Described in header.
+ */
+eap_aka_t *eap_aka_create_server(identification_t *server, identification_t *peer)
+{
+ private_eap_aka_t *this = eap_aka_create_generic(server, peer);
+
+ if (this)
+ {
+ this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))server_initiate;
+ this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))server_process;
+ }
+ return (eap_aka_t*)this;
}
+
+/*
+ * Described in header.
+ */
+eap_aka_t *eap_aka_create_peer(identification_t *server, identification_t *peer)
+{
+ private_eap_aka_t *this = eap_aka_create_generic(server, peer);
+
+ if (this)
+ {
+ this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))peer_initiate;
+ this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))peer_process;
+ }
+ return (eap_aka_t*)this;
+}
+
diff --git a/src/charon/sa/authenticators/eap/eap_aka.h b/src/charon/plugins/eap_aka/eap_aka.h
index a886863be..118f2c44f 100644
--- a/src/charon/sa/authenticators/eap/eap_aka.h
+++ b/src/charon/plugins/eap_aka/eap_aka.h
@@ -1,12 +1,5 @@
-/**
- * @file eap_aka.h
- *
- * @brief Interface of eap_aka_t.
- *
- */
-
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,80 +11,29 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_aka.h 3491 2008-02-22 14:04:00Z martin $
+ */
+
+/**
+ * @defgroup eap_aka_i eap_aka
+ * @{ @ingroup eap_aka
*/
#ifndef EAP_AKA_H_
#define EAP_AKA_H_
typedef struct eap_aka_t eap_aka_t;
-typedef enum aka_subtype_t aka_subtype_t;
-typedef enum aka_attribute_t aka_attribute_t;
#include <sa/authenticators/eap/eap_method.h>
-
-/**
- * Subtypes of AKA messages
- */
-enum aka_subtype_t {
- AKA_CHALLENGE = 1,
- AKA_AUTHENTICATION_REJECT = 2,
- AKA_SYNCHRONIZATION_FAILURE = 4,
- AKA_IDENTITY = 5,
- AKA_NOTIFICATION = 12,
- AKA_REAUTHENTICATION = 13,
- AKA_CLIENT_ERROR = 14,
-};
-
-/**
- * enum names for aka_subtype_t
- */
-extern enum_name_t *aka_subtype_names;
-
-/**
- * Attribute types in AKA messages
- */
-enum aka_attribute_t {
- /** defines the end of attribute list */
- AT_END = -1,
- AT_RAND = 1,
- AT_AUTN = 2,
- AT_RES = 3,
- AT_AUTS = 4,
- AT_PADDING = 6,
- AT_NONCE_MT = 7,
- AT_PERMANENT_ID_REQ = 10,
- AT_MAC = 11,
- AT_NOTIFICATION = 12,
- AT_ANY_ID_REQ = 13,
- AT_IDENTITY = 14,
- AT_VERSION_LIST = 15,
- AT_SELECTED_VERSION = 16,
- AT_FULLAUTH_ID_REQ = 17,
- AT_COUNTER = 19,
- AT_COUNTER_TOO_SMALL = 20,
- AT_NONCE_S = 21,
- AT_CLIENT_ERROR_CODE = 22,
- AT_IV = 129,
- AT_ENCR_DATA = 130,
- AT_NEXT_PSEUDONYM = 132,
- AT_NEXT_REAUTH_ID = 133,
- AT_CHECKCODE = 134,
- AT_RESULT_IND = 135,
-};
-
-/**
- * enum names for aka_attribute_t
- */
-extern enum_name_t *aka_attribute_names;
-
/** check SEQ values as client for validity, disabled by default */
#ifndef SEQ_CHECK
# define SEQ_CHECK 0
#endif
/**
- * @brief Implementation of the eap_method_t interface using EAP-AKA.
+ * Implementation of the eap_method_t interface using EAP-AKA.
*
* EAP-AKA uses 3rd generation mobile phone standard authentication
* mechanism for authentication. It is a mutual authentication
@@ -111,12 +53,6 @@ extern enum_name_t *aka_attribute_names;
* any SEQ numbers. This allows an attacker to do replay attacks. But since
* the server has proven his identity via IKE, such an attack is only
* possible between server and AAA (if any).
- *
- * @b Constructors:
- * - eap_aka_create()
- * - eap_client_create() using eap_method EAP_AKA
- *
- * @ingroup eap
*/
struct eap_aka_t {
@@ -127,15 +63,21 @@ struct eap_aka_t {
};
/**
- * @brief Creates the EAP method EAP-AKA.
+ * Creates the server implementation of the EAP method EAP-AKA.
*
* @param server ID of the EAP server
* @param peer ID of the EAP client
* @return eap_aka_t object
+ */
+eap_aka_t *eap_aka_create_server(identification_t *server, identification_t *peer);
+
+/**
+ * Creates the peer implementation of the EAP method EAP-AKA.
*
- * @ingroup eap
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_aka_t object
*/
-eap_aka_t *eap_create(eap_role_t role,
- identification_t *server, identification_t *peer);
+eap_aka_t *eap_aka_create_peer(identification_t *server, identification_t *peer);
-#endif /* EAP_AKA_H_ */
+#endif /* EAP_AKA_H_ @}*/
diff --git a/src/charon/plugins/eap_aka/eap_aka_plugin.c b/src/charon/plugins/eap_aka/eap_aka_plugin.c
new file mode 100644
index 000000000..5c15b6d7e
--- /dev/null
+++ b/src/charon/plugins/eap_aka/eap_aka_plugin.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: eap_aka_plugin.c 3491 2008-02-22 14:04:00Z martin $
+ */
+
+#include "eap_aka_plugin.h"
+
+#include "eap_aka.h"
+
+#include <daemon.h>
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(eap_aka_plugin_t *this)
+{
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_aka_create_server);
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_aka_create_peer);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ eap_aka_plugin_t *this = malloc_thing(eap_aka_plugin_t);
+
+ this->plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ charon->eap->add_method(charon->eap, EAP_AKA, 0, EAP_SERVER,
+ (eap_constructor_t)eap_aka_create_server);
+ charon->eap->add_method(charon->eap, EAP_AKA, 0, EAP_PEER,
+ (eap_constructor_t)eap_aka_create_peer);
+
+ return &this->plugin;
+}
+
diff --git a/src/charon/plugins/eap_aka/eap_aka_plugin.h b/src/charon/plugins/eap_aka/eap_aka_plugin.h
new file mode 100644
index 000000000..506d47f98
--- /dev/null
+++ b/src/charon/plugins/eap_aka/eap_aka_plugin.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: eap_aka_plugin.h 3491 2008-02-22 14:04:00Z martin $
+ */
+
+/**
+ * @defgroup eap_aka eap_aka
+ * @ingroup cplugins
+ *
+ * @defgroup eap_aka_plugin eap_aka_plugin
+ * @{ @ingroup eap_aka
+ */
+
+#ifndef EAP_AKA_PLUGIN_H_
+#define EAP_AKA_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct eap_aka_plugin_t eap_aka_plugin_t;
+
+/**
+ * EAP-AKA plugin
+ */
+struct eap_aka_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a eap_aka_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* EAP_AKA_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/eap_identity/Makefile.am b/src/charon/plugins/eap_identity/Makefile.am
new file mode 100644
index 000000000..dbf66e74b
--- /dev/null
+++ b/src/charon/plugins/eap_identity/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-eapidentity.la
+libstrongswan_eapidentity_la_SOURCES = \
+ eap_identity_plugin.h eap_identity_plugin.c eap_identity.h eap_identity.c
+libstrongswan_eapidentity_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/eap_identity/Makefile.in b/src/charon/plugins/eap_identity/Makefile.in
new file mode 100644
index 000000000..37f3505f2
--- /dev/null
+++ b/src/charon/plugins/eap_identity/Makefile.in
@@ -0,0 +1,499 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@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/charon/plugins/eap_identity
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_eapidentity_la_LIBADD =
+am_libstrongswan_eapidentity_la_OBJECTS = eap_identity_plugin.lo \
+ eap_identity.lo
+libstrongswan_eapidentity_la_OBJECTS = \
+ $(am_libstrongswan_eapidentity_la_OBJECTS)
+libstrongswan_eapidentity_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_eapidentity_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+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_eapidentity_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_eapidentity_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+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_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-eapidentity.la
+libstrongswan_eapidentity_la_SOURCES = \
+ eap_identity_plugin.h eap_identity_plugin.c eap_identity.h eap_identity.c
+
+libstrongswan_eapidentity_la_LDFLAGS = -module
+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 \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/eap_identity/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/eap_identity/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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-eapidentity.la: $(libstrongswan_eapidentity_la_OBJECTS) $(libstrongswan_eapidentity_la_DEPENDENCIES)
+ $(libstrongswan_eapidentity_la_LINK) -rpath $(plugindir) $(libstrongswan_eapidentity_la_OBJECTS) $(libstrongswan_eapidentity_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_identity.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_identity_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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)
+
+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-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
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-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/charon/sa/authenticators/eap/eap_identity.c b/src/charon/plugins/eap_identity/eap_identity.c
index 12a8bf7cc..0c90e8a04 100644
--- a/src/charon/sa/authenticators/eap/eap_identity.c
+++ b/src/charon/plugins/eap_identity/eap_identity.c
@@ -1,10 +1,3 @@
-/**
- * @file eap_identity.c
- *
- * @brief Implementation of eap_identity_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_identity.c 3491 2008-02-22 14:04:00Z martin $
*/
#include "eap_identity.h"
@@ -76,8 +71,9 @@ static status_t initiate(private_eap_identity_t *this, eap_payload_t **out)
/**
* Implementation of eap_method_t.get_type.
*/
-static eap_type_t get_type(private_eap_identity_t *this)
+static eap_type_t get_type(private_eap_identity_t *this, u_int32_t *vendor)
{
+ *vendor = 0;
return EAP_IDENTITY;
}
@@ -108,22 +104,15 @@ static void destroy(private_eap_identity_t *this)
/*
* Described in header.
*/
-eap_identity_t *eap_create(eap_role_t role,
- identification_t *server, identification_t *peer)
+eap_identity_t *eap_identity_create_peer(identification_t *server,
+ identification_t *peer)
{
- private_eap_identity_t *this;
-
- if (role != EAP_PEER)
- {
- return NULL;
- }
-
- this = malloc_thing(private_eap_identity_t);
+ private_eap_identity_t *this = malloc_thing(private_eap_identity_t);
/* public functions */
this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate;
this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process;
- this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*))get_type;
+ this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
@@ -133,3 +122,4 @@ eap_identity_t *eap_create(eap_role_t role,
return &this->public;
}
+
diff --git a/src/charon/sa/authenticators/eap/eap_identity.h b/src/charon/plugins/eap_identity/eap_identity.h
index 20f0f0b67..9de89e6e3 100644
--- a/src/charon/sa/authenticators/eap/eap_identity.h
+++ b/src/charon/plugins/eap_identity/eap_identity.h
@@ -1,12 +1,5 @@
-/**
- * @file eap_identity.h
- *
- * @brief Interface of eap_identity_t.
- *
- */
-
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_identity.h 3491 2008-02-22 14:04:00Z martin $
+ */
+
+/**
+ * @defgroup eap_identity_i eap_identity
+ * @{ @ingroup eap_identity
*/
#ifndef EAP_IDENTITY_H_
@@ -28,13 +28,7 @@ typedef struct eap_identity_t eap_identity_t;
#include <sa/authenticators/eap/eap_method.h>
/**
- * @brief Implementation of the eap_method_t interface using EAP Identity.
- *
- * @b Constructors:
- * - eap_identity_create()
- * - eap_client_create() using eap_method EAP_IDENTITY
- *
- * @ingroup eap
+ * Implementation of the eap_method_t interface using EAP Identity.
*/
struct eap_identity_t {
@@ -45,15 +39,13 @@ struct eap_identity_t {
};
/**
- * @brief Creates the EAP method EAP Identity.
+ * Creates the EAP method EAP Identity, acting as peer.
*
* @param server ID of the EAP server
* @param peer ID of the EAP client
* @return eap_identity_t object
- *
- * @ingroup eap
*/
-eap_identity_t *eap_create(eap_role_t role,
- identification_t *server, identification_t *peer);
+eap_identity_t *eap_identity_create_peer(identification_t *server,
+ identification_t *peer);
-#endif /* EAP_IDENTITY_H_ */
+#endif /* EAP_IDENTITY_H_ @}*/
diff --git a/src/charon/plugins/eap_identity/eap_identity_plugin.c b/src/charon/plugins/eap_identity/eap_identity_plugin.c
new file mode 100644
index 000000000..38a19d784
--- /dev/null
+++ b/src/charon/plugins/eap_identity/eap_identity_plugin.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: eap_identity_plugin.c 3491 2008-02-22 14:04:00Z martin $
+ */
+
+#include "eap_identity_plugin.h"
+
+#include "eap_identity.h"
+
+#include <daemon.h>
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(eap_identity_plugin_t *this)
+{
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_identity_create_peer);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ eap_identity_plugin_t *this = malloc_thing(eap_identity_plugin_t);
+
+ this->plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ 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/charon/control/interfaces/dbus_interface.h b/src/charon/plugins/eap_identity/eap_identity_plugin.h
index 0ce57bbbc..d7fa525ce 100644
--- a/src/charon/control/interfaces/dbus_interface.h
+++ b/src/charon/plugins/eap_identity/eap_identity_plugin.h
@@ -1,12 +1,5 @@
-/**
- * @file dbus_interface.h
- *
- * @brief Interface of dbus_interface_t.
- *
- */
-
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,40 +11,39 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_identity_plugin.h 3491 2008-02-22 14:04:00Z martin $
+ */
+
+/**
+ * @defgroup eap_identity eap_identity
+ * @ingroup cplugins
+ *
+ * @defgroup eap_identity_plugin eap_identity_plugin
+ * @{ @ingroup eap_identity
*/
-#ifndef DBUS_INTERFACE_H_
-#define DBUS_INTERFACE_H_
+#ifndef EAP_IDENTITY_PLUGIN_H_
+#define EAP_IDENTITY_PLUGIN_H_
-typedef struct dbus_interface_t dbus_interface_t;
+#include <plugins/plugin.h>
-#include <control/interfaces/interface.h>
+typedef struct eap_identity_plugin_t eap_identity_plugin_t;
/**
- * @brief The DBUS interface uses the DBUS system bus to communicate.
- *
- * @b Constructors:
- * - dbus_interface_create()
- *
- * @ingroup interfaces
+ * EAP-IDENTITY plugin.
*/
-struct dbus_interface_t {
-
+struct eap_identity_plugin_t {
+
/**
- * implements interface_t.
+ * implements plugin interface
*/
- interface_t interface;
+ plugin_t plugin;
};
-
/**
- * @brief Create the DBUS interface.
- *
- * @return stroke_t object
- *
- * @ingroup interfaces
+ * Create a eap_identity_plugin instance.
*/
-interface_t *interface_create();
-
-#endif /* DBUS_INTERFACE_H_ */
+plugin_t *plugin_create();
+#endif /* EAP_IDENTITY_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/eap_md5/Makefile.am b/src/charon/plugins/eap_md5/Makefile.am
new file mode 100644
index 000000000..d7964fee9
--- /dev/null
+++ b/src/charon/plugins/eap_md5/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-eapmd5.la
+
+libstrongswan_eapmd5_la_SOURCES = eap_md5_plugin.h eap_md5_plugin.c eap_md5.h eap_md5.c
+libstrongswan_eapmd5_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/eap_md5/Makefile.in b/src/charon/plugins/eap_md5/Makefile.in
new file mode 100644
index 000000000..d48fb2c44
--- /dev/null
+++ b/src/charon/plugins/eap_md5/Makefile.in
@@ -0,0 +1,495 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@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/charon/plugins/eap_md5
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_eapmd5_la_LIBADD =
+am_libstrongswan_eapmd5_la_OBJECTS = eap_md5_plugin.lo eap_md5.lo
+libstrongswan_eapmd5_la_OBJECTS = \
+ $(am_libstrongswan_eapmd5_la_OBJECTS)
+libstrongswan_eapmd5_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_eapmd5_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+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_eapmd5_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_eapmd5_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+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_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-eapmd5.la
+libstrongswan_eapmd5_la_SOURCES = eap_md5_plugin.h eap_md5_plugin.c eap_md5.h eap_md5.c
+libstrongswan_eapmd5_la_LDFLAGS = -module
+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 \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/eap_md5/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/eap_md5/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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-eapmd5.la: $(libstrongswan_eapmd5_la_OBJECTS) $(libstrongswan_eapmd5_la_DEPENDENCIES)
+ $(libstrongswan_eapmd5_la_LINK) -rpath $(plugindir) $(libstrongswan_eapmd5_la_OBJECTS) $(libstrongswan_eapmd5_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_md5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_md5_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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)
+
+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-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
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-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/charon/sa/authenticators/eap/eap_md5.c b/src/charon/plugins/eap_md5/eap_md5.c
index 0ca9fc566..990d64011 100644
--- a/src/charon/sa/authenticators/eap/eap_md5.c
+++ b/src/charon/plugins/eap_md5/eap_md5.c
@@ -1,10 +1,3 @@
-/**
- * @file eap_md5.c
- *
- * @brief Implementation of eap_md5_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,12 +11,15 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_md5.c 3806 2008-04-15 05:56:35Z martin $
*/
-
+
#include "eap_md5.h"
#include <daemon.h>
#include <library.h>
+#include <crypto/hashers/hasher.h>
typedef struct private_eap_md5_t private_eap_md5_t;
@@ -85,20 +81,28 @@ struct eap_md5_header_t {
* Hash the challenge string, create response
*/
static status_t hash_challenge(private_eap_md5_t *this, chunk_t *response)
-{
- chunk_t concat, secret;
+{
+ shared_key_t *shared;
+ chunk_t concat;
hasher_t *hasher;
-
- if (charon->credentials->get_eap_key(charon->credentials, this->server,
- this->peer, &secret) != SUCCESS)
+
+ shared = charon->credentials->get_shared(charon->credentials, SHARED_EAP,
+ this->server, this->peer);
+ if (shared == NULL)
{
DBG1(DBG_IKE, "no EAP key found for hosts '%D' - '%D'",
this->server, this->peer);
return NOT_FOUND;
}
- concat = chunk_cata("cmc", chunk_from_thing(this->identifier),
- secret, this->challenge);
- hasher = hasher_create(HASH_MD5);
+ concat = chunk_cata("ccc", chunk_from_thing(this->identifier),
+ shared->get_key(shared), this->challenge);
+ shared->destroy(shared);
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
+ if (hasher == NULL)
+ {
+ DBG1(DBG_IKE, "EAP-MD5 failed, MD5 not supported");
+ return FAILED;
+ }
hasher->allocate_hash(hasher, concat, response);
hasher->destroy(hasher);
return SUCCESS;
@@ -118,18 +122,16 @@ static status_t initiate_peer(private_eap_md5_t *this, eap_payload_t **out)
*/
static status_t initiate_server(private_eap_md5_t *this, eap_payload_t **out)
{
- randomizer_t *randomizer;
- status_t status;
+ rng_t *rng;
eap_md5_header_t *req;
- randomizer = randomizer_create();
- status = randomizer->allocate_pseudo_random_bytes(randomizer, CHALLENGE_LEN,
- &this->challenge);
- randomizer->destroy(randomizer);
- if (status != SUCCESS)
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (!rng)
{
return FAILED;
}
+ rng->allocate_bytes(rng, CHALLENGE_LEN, &this->challenge);
+ rng->destroy(rng);
req = alloca(PAYLOAD_LEN);
req->length = htons(PAYLOAD_LEN);
@@ -244,29 +246,16 @@ static void destroy(private_eap_md5_t *this)
free(this);
}
-/*
- * Described in header.
+/**
+ * Generic constructor
*/
-eap_md5_t *eap_create(eap_role_t role,
- identification_t *server, identification_t *peer)
+static private_eap_md5_t *eap_md5_create_generic(identification_t *server,
+ identification_t *peer)
{
private_eap_md5_t *this = malloc_thing(private_eap_md5_t);
- /* public functions */
- switch (role)
- {
- case EAP_SERVER:
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_server;
- break;
- case EAP_PEER:
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_peer;
- break;
- default:
- free(this);
- return NULL;
- }
+ this->public.eap_method_interface.initiate = NULL;
+ this->public.eap_method_interface.process = NULL;
this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
@@ -278,5 +267,32 @@ eap_md5_t *eap_create(eap_role_t role,
this->challenge = chunk_empty;
this->identifier = random();
+ return this;
+}
+
+/*
+ * see header
+ */
+eap_md5_t *eap_md5_create_server(identification_t *server, identification_t *peer)
+{
+ private_eap_md5_t *this = eap_md5_create_generic(server, peer);
+
+ this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server;
+ this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_server;
+
+ return &this->public;
+}
+
+/*
+ * see header
+ */
+eap_md5_t *eap_md5_create_peer(identification_t *server, identification_t *peer)
+{
+ private_eap_md5_t *this = eap_md5_create_generic(server, peer);
+
+ this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer;
+ this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_peer;
+
return &this->public;
}
+
diff --git a/src/charon/sa/authenticators/eap/eap_md5.h b/src/charon/plugins/eap_md5/eap_md5.h
index 260210b59..421e1e602 100644
--- a/src/charon/sa/authenticators/eap/eap_md5.h
+++ b/src/charon/plugins/eap_md5/eap_md5.h
@@ -1,12 +1,5 @@
-/**
- * @file eap_md5.h
- *
- * @brief Interface of eap_md5_t.
- *
- */
-
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_md5.h 3491 2008-02-22 14:04:00Z martin $
+ */
+
+/**
+ * @defgroup eap_md5_i eap_md5
+ * @{ @ingroup eap_md5
*/
#ifndef EAP_MD5_H_
@@ -28,13 +28,7 @@ typedef struct eap_md5_t eap_md5_t;
#include <sa/authenticators/eap/eap_method.h>
/**
- * @brief Implementation of the eap_method_t interface using EAP-MD5 (CHAP).
- *
- * @b Constructors:
- * - eap_md5_create()
- * - eap_client_create() using eap_method EAP_MD5
- *
- * @ingroup eap
+ * Implementation of the eap_method_t interface using EAP-MD5 (CHAP).
*/
struct eap_md5_t {
@@ -45,15 +39,21 @@ struct eap_md5_t {
};
/**
- * @brief Creates the EAP method EAP-MD5.
+ * Creates the EAP method EAP-MD5 acting as server.
*
* @param server ID of the EAP server
* @param peer ID of the EAP client
* @return eap_md5_t object
+ */
+eap_md5_t *eap_md5_create_server(identification_t *server, identification_t *peer);
+
+/**
+ * Creates the EAP method EAP-MD5 acting as peer.
*
- * @ingroup eap
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_md5_t object
*/
-eap_md5_t *eap_create(eap_role_t role,
- identification_t *server, identification_t *peer);
+eap_md5_t *eap_md5_create_peer(identification_t *server, identification_t *peer);
-#endif /* EAP_MD5_H_ */
+#endif /* EAP_MD5_H_ @}*/
diff --git a/src/charon/plugins/eap_md5/eap_md5_plugin.c b/src/charon/plugins/eap_md5/eap_md5_plugin.c
new file mode 100644
index 000000000..cb6a9bd7c
--- /dev/null
+++ b/src/charon/plugins/eap_md5/eap_md5_plugin.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: eap_md5_plugin.c 3491 2008-02-22 14:04:00Z martin $
+ */
+
+#include "eap_md5_plugin.h"
+
+#include "eap_md5.h"
+
+#include <daemon.h>
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(eap_md5_plugin_t *this)
+{
+ 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);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ eap_md5_plugin_t *this = malloc_thing(eap_md5_plugin_t);
+
+ this->plugin.destroy = (void(*)(plugin_t*))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/charon/plugins/eap_md5/eap_md5_plugin.h b/src/charon/plugins/eap_md5/eap_md5_plugin.h
new file mode 100644
index 000000000..d13794f2e
--- /dev/null
+++ b/src/charon/plugins/eap_md5/eap_md5_plugin.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: eap_md5_plugin.h 3491 2008-02-22 14:04:00Z martin $
+ */
+
+/**
+ * @defgroup eap_md5 eap_md5
+ * @ingroup cplugins
+ *
+ * @defgroup eap_md5_plugin eap_md5_plugin
+ * @{ @ingroup eap_md5
+ */
+
+#ifndef EAP_MD5_PLUGIN_H_
+#define EAP_MD5_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct eap_md5_plugin_t eap_md5_plugin_t;
+
+/**
+ * EAP-MD5 plugin
+ */
+struct eap_md5_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a eap_md5_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* EAP_MD5_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/eap_sim/Makefile.am b/src/charon/plugins/eap_sim/Makefile.am
new file mode 100644
index 000000000..63267b9d3
--- /dev/null
+++ b/src/charon/plugins/eap_sim/Makefile.am
@@ -0,0 +1,13 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DSIM_READER_LIB=\"${simreader}\"
+
+plugin_LTLIBRARIES = libstrongswan-eapsim.la libeapsim-file.la
+
+libstrongswan_eapsim_la_SOURCES = eap_sim_plugin.h eap_sim_plugin.c eap_sim.h eap_sim.c
+libstrongswan_eapsim_la_LDFLAGS = -module
+
+libeapsim_file_la_SOURCES = eap_sim_file.c
+libeapsim_file_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/eap_sim/Makefile.in b/src/charon/plugins/eap_sim/Makefile.in
new file mode 100644
index 000000000..e70f8457c
--- /dev/null
+++ b/src/charon/plugins/eap_sim/Makefile.in
@@ -0,0 +1,508 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@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/charon/plugins/eap_sim
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libeapsim_file_la_LIBADD =
+am_libeapsim_file_la_OBJECTS = eap_sim_file.lo
+libeapsim_file_la_OBJECTS = $(am_libeapsim_file_la_OBJECTS)
+libeapsim_file_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libeapsim_file_la_LDFLAGS) $(LDFLAGS) -o $@
+libstrongswan_eapsim_la_LIBADD =
+am_libstrongswan_eapsim_la_OBJECTS = eap_sim_plugin.lo eap_sim.lo
+libstrongswan_eapsim_la_OBJECTS = \
+ $(am_libstrongswan_eapsim_la_OBJECTS)
+libstrongswan_eapsim_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_eapsim_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+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 = $(libeapsim_file_la_SOURCES) \
+ $(libstrongswan_eapsim_la_SOURCES)
+DIST_SOURCES = $(libeapsim_file_la_SOURCES) \
+ $(libstrongswan_eapsim_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+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_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DSIM_READER_LIB=\"${simreader}\"
+plugin_LTLIBRARIES = libstrongswan-eapsim.la libeapsim-file.la
+libstrongswan_eapsim_la_SOURCES = eap_sim_plugin.h eap_sim_plugin.c eap_sim.h eap_sim.c
+libstrongswan_eapsim_la_LDFLAGS = -module
+libeapsim_file_la_SOURCES = eap_sim_file.c
+libeapsim_file_la_LDFLAGS = -module
+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 \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/eap_sim/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/eap_sim/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libeapsim-file.la: $(libeapsim_file_la_OBJECTS) $(libeapsim_file_la_DEPENDENCIES)
+ $(libeapsim_file_la_LINK) -rpath $(plugindir) $(libeapsim_file_la_OBJECTS) $(libeapsim_file_la_LIBADD) $(LIBS)
+libstrongswan-eapsim.la: $(libstrongswan_eapsim_la_OBJECTS) $(libstrongswan_eapsim_la_DEPENDENCIES)
+ $(libstrongswan_eapsim_la_LINK) -rpath $(plugindir) $(libstrongswan_eapsim_la_OBJECTS) $(libstrongswan_eapsim_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_sim.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_sim_file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_sim_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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)
+
+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-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
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-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/charon/sa/authenticators/eap/eap_sim.c b/src/charon/plugins/eap_sim/eap_sim.c
index 90898fb46..b14076f34 100644
--- a/src/charon/sa/authenticators/eap/eap_sim.c
+++ b/src/charon/plugins/eap_sim/eap_sim.c
@@ -1,10 +1,3 @@
-/**
- * @file eap_sim.c
- *
- * @brief Implementation of eap_sim_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_sim.c 3806 2008-04-15 05:56:35Z martin $
*/
#include "eap_sim.h"
@@ -140,6 +135,21 @@ struct private_eap_sim_t {
identification_t *peer;
/**
+ * hashing function
+ */
+ hasher_t *hasher;
+
+ /**
+ * prf
+ */
+ prf_t *prf;
+
+ /**
+ * MAC function
+ */
+ signer_t *signer;
+
+ /**
* SIM cardreader function loaded from library
*/
sim_algo_t alg;
@@ -403,13 +413,11 @@ static eap_payload_t *build_payload(private_eap_sim_t *this, u_int8_t identifier
* chunk mac_data to "to-sign" chunk */
if (mac_pos)
{
- signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
- signer->set_key(signer, this->k_auth);
+ this->signer->set_key(this->signer, this->k_auth);
mac_data = chunk_cata("cc", message, mac_data);
- signer->get_signature(signer, mac_data, mac_pos);
+ this->signer->get_signature(this->signer, mac_data, mac_pos);
DBG3(DBG_IKE, "AT_MAC signature of %B\n is %b",
&mac_data, mac_pos, MAC_LEN);
- signer->destroy(signer);
}
payload = eap_payload_create_data(message);
@@ -520,30 +528,24 @@ static status_t peer_process_start(private_eap_sim_t *this, eap_payload_t *in,
static void derive_keys(private_eap_sim_t *this, chunk_t kcs)
{
chunk_t tmp, mk;
- hasher_t *hasher;
- prf_t *prf;
int i;
/* build MK = SHA1(Identity|n*Kc|NONCE_MT|Version List|Selected Version) */
tmp = chunk_cata("ccccc", this->peer->get_encoding(this->peer), kcs,
this->nonce, this->version_list, this->version);
- hasher = hasher_create(HASH_SHA1);
- mk = chunk_alloca(hasher->get_hash_size(hasher));
- hasher->get_hash(hasher, tmp, mk.ptr);
- hasher->destroy(hasher);
+ mk = chunk_alloca(this->hasher->get_hash_size(this->hasher));
+ this->hasher->get_hash(this->hasher, tmp, mk.ptr);
DBG3(DBG_IKE, "MK = SHA1(%B\n) = %B", &tmp, &mk);
/* K_encr | K_auth | MSK | EMSK = prf() | prf() | prf() | prf()
* FIPS PRF has 320 bit block size, we need 160 byte for keys
* => run prf four times */
- prf = prf_create(PRF_FIPS_SHA1_160);
- prf->set_key(prf, mk);
- tmp = chunk_alloca(prf->get_block_size(prf) * 4);
+ this->prf->set_key(this->prf, mk);
+ tmp = chunk_alloca(this->prf->get_block_size(this->prf) * 4);
for (i = 0; i < 4; i++)
{
- prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * i);
+ this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr + tmp.len / 4 * i);
}
- prf->destroy(prf);
chunk_free(&this->k_encr);
chunk_free(&this->k_auth);
chunk_free(&this->msk);
@@ -564,7 +566,6 @@ static status_t peer_process_challenge(private_eap_sim_t *this,
sim_attribute_t attribute;
u_int8_t identifier;
chunk_t mac = chunk_empty, rands = chunk_empty;
- signer_t *signer;
if (this->tries-- <= 0)
{
@@ -670,19 +671,16 @@ static status_t peer_process_challenge(private_eap_sim_t *this,
derive_keys(this, kcs);
/* verify AT_MAC attribute, signature is over "EAP packet | NONCE_MT" */
- signer = signer_create(AUTH_HMAC_SHA1_128);
- signer->set_key(signer, this->k_auth);
+ this->signer->set_key(this->signer, this->k_auth);
tmp = chunk_cata("cc", in->get_data(in), this->nonce);
- if (!signer->verify_signature(signer, tmp, mac))
+ if (!this->signer->verify_signature(this->signer, tmp, mac))
{
DBG1(DBG_IKE, "AT_MAC verification failed");
- signer->destroy(signer);
*out = build_payload(this, identifier, SIM_CLIENT_ERROR,
AT_CLIENT_ERROR_CODE, client_error_general,
AT_END);
return NEED_MORE;
}
- signer->destroy(signer);
/* build response, AT_MAC is built over "EAP packet | n*SRES" */
*out = build_payload(this, identifier, SIM_CHALLENGE,
@@ -700,7 +698,6 @@ static status_t server_process_challenge(private_eap_sim_t *this,
chunk_t message, data;
sim_attribute_t attribute;
chunk_t mac = chunk_empty, tmp;
- signer_t *signer;
message = in->get_data(in);
read_header(&message);
@@ -729,16 +726,13 @@ static status_t server_process_challenge(private_eap_sim_t *this,
return FAILED;
}
/* verify AT_MAC attribute, signature is over "EAP packet | n*SRES" */
- signer = signer_create(AUTH_HMAC_SHA1_128);
- signer->set_key(signer, this->k_auth);
+ this->signer->set_key(this->signer, this->k_auth);
tmp = chunk_cata("cc", in->get_data(in), this->sreses);
- if (!signer->verify_signature(signer, tmp, mac))
+ if (!this->signer->verify_signature(this->signer, tmp, mac))
{
DBG1(DBG_IKE, "AT_MAC verification failed");
- signer->destroy(signer);
return FAILED;
}
- signer->destroy(signer);
return SUCCESS;
}
@@ -942,7 +936,7 @@ static status_t peer_process(private_eap_sim_t *this,
* Implementation of eap_method_t.process for the server
*/
static status_t server_process(private_eap_sim_t *this,
- eap_payload_t *in, eap_payload_t **out)
+ eap_payload_t *in, eap_payload_t **out)
{
sim_subtype_t type;
chunk_t message;
@@ -1023,6 +1017,9 @@ static bool is_mutual(private_eap_sim_t *this)
static void destroy(private_eap_sim_t *this)
{
dlclose(this->handle);
+ DESTROY_IF(this->hasher);
+ DESTROY_IF(this->prf);
+ DESTROY_IF(this->signer);
chunk_free(&this->nonce);
chunk_free(&this->sreses);
chunk_free(&this->version_list);
@@ -1033,14 +1030,14 @@ static void destroy(private_eap_sim_t *this)
free(this);
}
-/*
- * Described in header.
+/**
+ * Generic constructor for both roles
*/
-eap_sim_t *eap_create(eap_role_t role,
- identification_t *server, identification_t *peer)
+eap_sim_t *eap_sim_create_generic(eap_role_t role, identification_t *server,
+ identification_t *peer)
{
private_eap_sim_t *this;
- randomizer_t *randomizer;
+ rng_t *rng;
void *symbol;
char *name;
@@ -1101,16 +1098,15 @@ eap_sim_t *eap_create(eap_role_t role,
this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))peer_process;
this->alg = symbol;
this->type = EAP_RESPONSE;
- randomizer = randomizer_create();
- if (randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_LEN,
- &this->nonce))
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (!rng)
{
- DBG1(DBG_IKE, "unable to generate NONCE for EAP_SIM");
- randomizer->destroy(randomizer);
+ DBG1(DBG_IKE, "unable to generate NONCE for EAP_SIM");
free(this);
return NULL;
}
- randomizer->destroy(randomizer);
+ rng->allocate_bytes(rng, NONCE_LEN, &this->nonce);
+ rng->destroy(rng);
break;
default:
free(this);
@@ -1121,5 +1117,33 @@ eap_sim_t *eap_create(eap_role_t role,
this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
+ this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ this->prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160);
+ this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA1_128);
+ if (!this->hasher || !this->prf || !this->signer)
+ {
+ DBG1(DBG_IKE, "initiating EAP-SIM failed, FIPS-PRF/SHA1 not supported");
+ destroy(this);
+ return NULL;
+ }
return &this->public;
}
+
+/*
+ * Described in header.
+ */
+eap_sim_t *eap_sim_create_server(identification_t *server,
+ identification_t *peer)
+{
+ return eap_sim_create_generic(EAP_SERVER, server, peer);
+}
+
+/*
+ * Described in header.
+ */
+eap_sim_t *eap_sim_create_peer(identification_t *server,
+ identification_t *peer)
+{
+ return eap_sim_create_generic(EAP_PEER, server, peer);
+}
+
diff --git a/src/charon/sa/authenticators/eap/eap_sim.h b/src/charon/plugins/eap_sim/eap_sim.h
index d50cf7397..65020aa64 100644
--- a/src/charon/sa/authenticators/eap/eap_sim.h
+++ b/src/charon/plugins/eap_sim/eap_sim.h
@@ -1,12 +1,5 @@
-/**
- * @file eap_sim.h
- *
- * @brief Interface of eap_sim_t.
- *
- */
-
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2007-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,6 +13,11 @@
* for more details.
*/
+/**
+ * @defgroup eap_sim_i eap_sim
+ * @{ @ingroup eap_sim
+ */
+
#ifndef EAP_SIM_H_
#define EAP_SIM_H_
@@ -33,7 +31,7 @@ typedef struct eap_sim_t eap_sim_t;
#endif /* SIM_READER_LIB */
/**
- * @brief Cardreaders SIM function.
+ * Cardreaders SIM function.
*
* @param rand RAND to run algo with
* @param rand_length length of value in rand
@@ -53,7 +51,7 @@ typedef int (*sim_algo_t)(const unsigned char *rand, int rand_length,
#endif /* SIM_READER_ALG */
/**
- * @brief Function to get a SIM triplet.
+ * Function to get a SIM triplet.
*
* @param identity identity (imsi) to get a triplet for
* @param rand buffer to get RAND
@@ -75,7 +73,7 @@ typedef int (*sim_get_triplet_t)(char *identity,
#endif /* SIM_READER_GET_TRIPLET */
/**
- * @brief Implementation of the eap_method_t interface using EAP-SIM.
+ * Implementation of the eap_method_t interface using EAP-SIM.
*
* This EAP-SIM client implementation uses another pluggable library to
* access the SIM card/triplet provider. This module is specified using the
@@ -83,12 +81,6 @@ typedef int (*sim_get_triplet_t)(char *identity,
* calculate a triplet (client), and/or a sim_get_triplet() function to get
* a triplet (server). These functions are named to the SIM_READER_ALG and
* the SIM_READER_GET_TRIPLET definitions.
- *
- * @b Constructors:
- * - eap_create() of this module
- * - eap_client_create() using eap_method EAP_SIM
- *
- * @ingroup eap
*/
struct eap_sim_t {
@@ -99,16 +91,21 @@ struct eap_sim_t {
};
/**
- * @brief Creates the EAP method EAP-SIM.
+ * Creates the EAP method EAP-SIM acting as server.
*
- * @param role role of the module, client/server
* @param server ID of the EAP server
* @param peer ID of the EAP client
* @return eap_sim_t object
+ */
+eap_sim_t *eap_sim_create_server(identification_t *server, identification_t *peer);
+
+/**
+ * Creates the EAP method EAP-SIM acting as peer.
*
- * @ingroup eap
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_sim_t object
*/
-eap_sim_t *eap_create(eap_role_t role,
- identification_t *server, identification_t *peer);
+eap_sim_t *eap_sim_create_peer(identification_t *server, identification_t *peer);
-#endif /* EAP_SIM_H_ */
+#endif /* EAP_SIM_H_ @}*/
diff --git a/src/charon/sa/authenticators/eap/sim/eap_sim_file.c b/src/charon/plugins/eap_sim/eap_sim_file.c
index 2ab45a578..fc4c1af26 100644
--- a/src/charon/sa/authenticators/eap/sim/eap_sim_file.c
+++ b/src/charon/plugins/eap_sim/eap_sim_file.c
@@ -1,10 +1,3 @@
-/**
- * @file eap_sim.h
- *
- * @brief Interface of eap_sim_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -17,7 +10,9 @@
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * for more details.
+ *
+ * $Id: eap_sim_file.c 3491 2008-02-22 14:04:00Z martin $
*/
#include <string.h>
diff --git a/src/charon/plugins/eap_sim/eap_sim_plugin.c b/src/charon/plugins/eap_sim/eap_sim_plugin.c
new file mode 100644
index 000000000..d937c57b4
--- /dev/null
+++ b/src/charon/plugins/eap_sim/eap_sim_plugin.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: eap_sim_plugin.c 3491 2008-02-22 14:04:00Z martin $
+ */
+
+#include "eap_sim_plugin.h"
+
+#include "eap_sim.h"
+
+#include <daemon.h>
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(eap_sim_plugin_t *this)
+{
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_sim_create_server);
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_sim_create_peer);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ eap_sim_plugin_t *this = malloc_thing(eap_sim_plugin_t);
+
+ this->plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ charon->eap->add_method(charon->eap, EAP_SIM, 0, EAP_SERVER,
+ (eap_constructor_t)eap_sim_create_server);
+ charon->eap->add_method(charon->eap, EAP_SIM, 0, EAP_PEER,
+ (eap_constructor_t)eap_sim_create_peer);
+
+ return &this->plugin;
+}
+
diff --git a/src/charon/plugins/eap_sim/eap_sim_plugin.h b/src/charon/plugins/eap_sim/eap_sim_plugin.h
new file mode 100644
index 000000000..938807884
--- /dev/null
+++ b/src/charon/plugins/eap_sim/eap_sim_plugin.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: eap_sim_plugin.h 3491 2008-02-22 14:04:00Z martin $
+ */
+
+/**
+ * @defgroup eap_sim eap_sim
+ * @ingroup cplugins
+ *
+ * @defgroup eap_sim_plugin eap_sim_plugin
+ * @{ @ingroup eap_sim
+ */
+
+#ifndef EAP_SIM_PLUGIN_H_
+#define EAP_SIM_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct eap_sim_plugin_t eap_sim_plugin_t;
+
+/**
+ * EAP-sim plugin
+ */
+struct eap_sim_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a eap_sim_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* EAP_SIM_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/medcli/Makefile.am b/src/charon/plugins/medcli/Makefile.am
new file mode 100644
index 000000000..f15950af9
--- /dev/null
+++ b/src/charon/plugins/medcli/Makefile.am
@@ -0,0 +1,12 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-medcli.la
+libstrongswan_medcli_la_SOURCES = medcli_plugin.h medcli_plugin.c \
+ medcli_creds.h medcli_creds.c \
+ medcli_config.h medcli_config.c \
+ medcli_listener.h medcli_listener.c
+libstrongswan_medcli_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/medcli/Makefile.in b/src/charon/plugins/medcli/Makefile.in
new file mode 100644
index 000000000..85be6bae7
--- /dev/null
+++ b/src/charon/plugins/medcli/Makefile.in
@@ -0,0 +1,502 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@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/charon/plugins/medcli
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_medcli_la_LIBADD =
+am_libstrongswan_medcli_la_OBJECTS = medcli_plugin.lo medcli_creds.lo \
+ medcli_config.lo medcli_listener.lo
+libstrongswan_medcli_la_OBJECTS = \
+ $(am_libstrongswan_medcli_la_OBJECTS)
+libstrongswan_medcli_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_medcli_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+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_medcli_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_medcli_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+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_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-medcli.la
+libstrongswan_medcli_la_SOURCES = medcli_plugin.h medcli_plugin.c \
+ medcli_creds.h medcli_creds.c \
+ medcli_config.h medcli_config.c \
+ medcli_listener.h medcli_listener.c
+
+libstrongswan_medcli_la_LDFLAGS = -module
+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 \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/medcli/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/medcli/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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-medcli.la: $(libstrongswan_medcli_la_OBJECTS) $(libstrongswan_medcli_la_DEPENDENCIES)
+ $(libstrongswan_medcli_la_LINK) -rpath $(plugindir) $(libstrongswan_medcli_la_OBJECTS) $(libstrongswan_medcli_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medcli_config.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medcli_creds.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medcli_listener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medcli_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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)
+
+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-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
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-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/charon/plugins/medcli/medcli_config.c b/src/charon/plugins/medcli/medcli_config.c
new file mode 100644
index 000000000..96dfa7c94
--- /dev/null
+++ b/src/charon/plugins/medcli/medcli_config.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+
+#include "medcli_config.h"
+
+#include <daemon.h>
+#include <processing/jobs/callback_job.h>
+
+typedef struct private_medcli_config_t private_medcli_config_t;
+
+/**
+ * Private data of an medcli_config_t object
+ */
+struct private_medcli_config_t {
+
+ /**
+ * Public part
+ */
+ medcli_config_t public;
+
+ /**
+ * database connection
+ */
+ database_t *db;
+
+ /**
+ * rekey time
+ */
+ int rekey;
+
+ /**
+ * dpd delay
+ */
+ int dpd;
+
+ /**
+ * default ike config
+ */
+ ike_cfg_t *ike;
+};
+
+/**
+ * create a traffic selector from a CIDR notation string
+ */
+static traffic_selector_t *ts_from_string(char *str)
+{
+ if (str)
+ {
+ int netbits = 32;
+ host_t *net;
+ char *pos;
+
+ str = strdupa(str);
+ pos = strchr(str, '/');
+ if (pos)
+ {
+ *pos++ = '\0';
+ netbits = atoi(pos);
+ }
+ else
+ {
+ if (strchr(str, ':'))
+ {
+ netbits = 128;
+ }
+ }
+ net = host_create_from_string(str, 0);
+ if (net)
+ {
+ return traffic_selector_create_from_subnet(net, netbits, 0, 0);
+ }
+ }
+ 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)
+{
+ enumerator_t *e;
+ peer_cfg_t *peer_cfg, *med_cfg;
+ ike_cfg_t *ike_cfg;
+ child_cfg_t *child_cfg;
+ chunk_t me, other;
+ char *address, *local_net, *remote_net;
+
+ /* query mediation server config:
+ * - build ike_cfg/peer_cfg for mediation connection on-the-fly
+ */
+ e = this->db->query(this->db,
+ "SELECT Address, ClientConfig.KeyId, MediationServerConfig.KeyId "
+ "FROM MediationServerConfig JOIN ClientConfig",
+ DB_TEXT, DB_BLOB, DB_BLOB);
+ if (!e || !e->enumerate(e, &address, &me, &other))
+ {
+ DESTROY_IF(e);
+ return NULL;
+ }
+ ike_cfg = ike_cfg_create(FALSE, FALSE, "0.0.0.0", address);
+ ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+ med_cfg = peer_cfg_create(
+ "mediation", 2, ike_cfg,
+ identification_create_from_encoding(ID_KEY_ID, me),
+ identification_create_from_encoding(ID_KEY_ID, other),
+ CERT_NEVER_SEND, UNIQUE_REPLACE, CONF_AUTH_PUBKEY,
+ 0, 0, /* EAP method, vendor */
+ 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);
+
+ /* query mediated config:
+ * - use any-any ike_cfg
+ * - build peer_cfg on-the-fly using med_cfg
+ * - add a child_cfg
+ */
+ e = this->db->query(this->db,
+ "SELECT ClientConfig.KeyId, Connection.KeyId, "
+ "Connection.LocalSubnet, Connection.RemoteSubnet "
+ "FROM ClientConfig JOIN Connection "
+ "WHERE Active AND Alias = ?", DB_TEXT, name,
+ DB_BLOB, DB_BLOB, DB_TEXT, DB_TEXT);
+ if (!e || !e->enumerate(e, &me, &other, &local_net, &remote_net))
+ {
+ DESTROY_IF(e);
+ return NULL;
+ }
+ peer_cfg = peer_cfg_create(
+ name, 2, this->ike->get_ref(this->ike),
+ identification_create_from_encoding(ID_KEY_ID, me),
+ identification_create_from_encoding(ID_KEY_ID, other),
+ CERT_NEVER_SEND, UNIQUE_REPLACE, CONF_AUTH_PUBKEY,
+ 0, 0, /* EAP method, vendor */
+ 1, this->rekey*60, 0, /* keytries, rekey, reauth */
+ this->rekey*5, this->rekey*3, /* jitter, overtime */
+ TRUE, this->dpd, /* mobike, dpddelay */
+ NULL, NULL, /* vip, pool */
+ FALSE, med_cfg, /* mediation, med by */
+ identification_create_from_encoding(ID_KEY_ID, other));
+
+ child_cfg = child_cfg_create(name, this->rekey*60 + this->rekey,
+ this->rekey*60, this->rekey, NULL, TRUE,
+ MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE);
+ child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+ child_cfg->add_traffic_selector(child_cfg, TRUE, ts_from_string(local_net));
+ child_cfg->add_traffic_selector(child_cfg, FALSE, ts_from_string(remote_net));
+ peer_cfg->add_child_cfg(peer_cfg, child_cfg);
+ e->destroy(e);
+ 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)
+{
+ return enumerator_create_single(this->ike, NULL);
+}
+
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** currently enumerated peer config */
+ peer_cfg_t *current;
+ /** ike cfg to use in peer cfg */
+ ike_cfg_t *ike;
+ /** rekey time */
+ int rekey;
+ /** dpd time */
+ 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)
+{
+ char *name, *local_net, *remote_net;
+ chunk_t me, other;
+ child_cfg_t *child_cfg;
+
+ DESTROY_IF(this->current);
+ if (!this->inner->enumerate(this->inner, &name, &me, &other,
+ &local_net, &remote_net))
+ {
+ this->current = NULL;
+ return FALSE;
+ }
+ this->current = peer_cfg_create(
+ name, 2, this->ike->get_ref(this->ike),
+ identification_create_from_encoding(ID_KEY_ID, me),
+ identification_create_from_encoding(ID_KEY_ID, other),
+ CERT_NEVER_SEND, UNIQUE_REPLACE, AUTH_RSA,
+ 0, 0, /* EAP method, vendor */
+ 1, this->rekey*60, 0, /* keytries, rekey, reauth */
+ this->rekey*5, this->rekey*3, /* jitter, overtime */
+ TRUE, this->dpd, /* mobike, dpddelay */
+ NULL, NULL, /* vip, pool */
+ FALSE, NULL, NULL); /* mediation, med by, peer id */
+ child_cfg = child_cfg_create(
+ name, this->rekey*60 + this->rekey,
+ this->rekey*60, this->rekey, NULL, TRUE,
+ MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE);
+ child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+ child_cfg->add_traffic_selector(child_cfg, TRUE, ts_from_string(local_net));
+ child_cfg->add_traffic_selector(child_cfg, FALSE, ts_from_string(remote_net));
+ this->current->add_child_cfg(this->current, child_cfg);
+ *cfg = this->current;
+ return TRUE;
+}
+
+/**
+ * Implementation of peer_enumerator_t.public.destroy
+ */
+static void peer_enumerator_destroy(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)
+{
+ 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;
+
+ /* filter on IDs: NULL or ANY or matching KEY_ID */
+ e->inner = this->db->query(this->db,
+ "SELECT Alias, ClientConfig.KeyId, Connection.KeyId, "
+ "Connection.LocalSubnet, Connection.RemoteSubnet "
+ "FROM ClientConfig JOIN Connection "
+ "WHERE Active AND "
+ "(? OR ClientConfig.KeyId = ?) AND (? OR Connection.KeyId = ?)",
+ DB_INT, me == NULL || me->get_type(me) == ID_ANY,
+ DB_BLOB, me && me->get_type(me) == ID_KEY_ID ?
+ me->get_encoding(me) : chunk_empty,
+ DB_INT, other == NULL || other->get_type(other) == ID_ANY,
+ DB_BLOB, other && other->get_type(other) == ID_KEY_ID ?
+ other->get_encoding(other) : chunk_empty,
+ DB_TEXT, DB_BLOB, DB_BLOB, DB_TEXT, DB_TEXT);
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * initiate a peer config
+ */
+static job_requeue_t initiate_config(peer_cfg_t *peer_cfg)
+{
+ enumerator_t *enumerator;
+ child_cfg_t *child_cfg = NULL;;
+
+ enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
+ enumerator->enumerate(enumerator, &child_cfg);
+ if (child_cfg)
+ {
+ child_cfg->get_ref(child_cfg);
+ peer_cfg->get_ref(peer_cfg);
+ enumerator->destroy(enumerator);
+ charon->controller->initiate(charon->controller,
+ peer_cfg, child_cfg, NULL, NULL);
+ }
+ else
+ {
+ enumerator->destroy(enumerator);
+ }
+ return JOB_REQUEUE_NONE;
+}
+
+/**
+ * schedule initation of all "active" connections
+ */
+static void schedule_autoinit(private_medcli_config_t *this)
+{
+ enumerator_t *e;
+ char *name;
+
+ e = this->db->query(this->db, "SELECT Alias FROM Connection WHERE Active",
+ DB_TEXT);
+ if (e)
+ {
+ while (e->enumerate(e, &name))
+ {
+ peer_cfg_t *peer_cfg;
+
+ peer_cfg = get_peer_cfg_by_name(this, name);
+ if (peer_cfg)
+ {
+ /* schedule asynchronous initiation job */
+ charon->processor->queue_job(charon->processor,
+ (job_t*)callback_job_create(
+ (callback_job_cb_t)initiate_config,
+ peer_cfg, (void*)peer_cfg->destroy, NULL));
+ }
+ }
+ e->destroy(e);
+ }
+}
+
+/**
+ * Implementation of medcli_config_t.destroy.
+ */
+static void destroy(private_medcli_config_t *this)
+{
+ this->ike->destroy(this->ike);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+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_int(lib->settings,
+ "medclient.rekey", 20) * 60;
+ this->dpd = lib->settings->get_int(lib->settings, "medclient.dpd", 300);
+ this->ike = ike_cfg_create(FALSE, FALSE, "0.0.0.0", "0.0.0.0");
+ this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
+
+ schedule_autoinit(this);
+
+ return &this->public;
+}
+
diff --git a/src/charon/config/backends/sqlite_backend.h b/src/charon/plugins/medcli/medcli_config.h
index 4bc146583..789a73243 100644
--- a/src/charon/config/backends/sqlite_backend.h
+++ b/src/charon/plugins/medcli/medcli_config.h
@@ -1,12 +1,5 @@
-/**
- * @file sqlite_backend.h
- *
- * @brief Interface of sqlite_backend_t.
- *
- */
-
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,41 +11,45 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup medcli_config_i medcli_config
+ * @{ @ingroup medcli
*/
-
-#ifndef SQLITE_BACKEND_H_
-#define SQLITE_BACKEND_H_
-typedef struct sqlite_backend_t sqlite_backend_t;
+#ifndef MEDCLI_CONFIG_H_
+#define MEDCLI_CONFIG_H_
-#include <library.h>
+#include <config/backend.h>
+#include <database/database.h>
-#include "backend.h"
+typedef struct medcli_config_t medcli_config_t;
/**
- * @brief An SQLite based configuration backend.
- *
- * @b Constructors:
- * - sqlite_backend_create()
- *
- * @ingroup backends
+ * Mediation client configuration backend.
*/
-struct sqlite_backend_t {
-
+struct medcli_config_t {
+
/**
* Implements backend_t interface
*/
backend_t backend;
+
+ /**
+ * Destroy the backend.
+ */
+ void (*destroy)(medcli_config_t *this);
};
/**
- * @brief Create a backend_t instance implemented as sqlite backend.
+ * Create a medcli_config backend instance.
*
- * @return backend instance
- *
- * @ingroup backends
+ * @param db underlying database
+ * @return backend instance
*/
-backend_t *backend_create(void);
-
-#endif /* SQLITE_BACKEND_H_ */
+medcli_config_t *medcli_config_create(database_t *db);
+#endif /* MEDCLI_CONFIG_H_ @}*/
diff --git a/src/charon/plugins/medcli/medcli_creds.c b/src/charon/plugins/medcli/medcli_creds.c
new file mode 100644
index 000000000..685f34271
--- /dev/null
+++ b/src/charon/plugins/medcli/medcli_creds.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "medcli_creds.h"
+
+#include <daemon.h>
+#include <library.h>
+#include <utils/enumerator.h>
+
+typedef struct private_medcli_creds_t private_medcli_creds_t;
+
+/**
+ * Private data of an medcli_creds_t object
+ */
+struct private_medcli_creds_t {
+
+ /**
+ * Public part
+ */
+ medcli_creds_t public;
+
+ /**
+ * underlying database handle
+ */
+ database_t *db;
+};
+
+/**
+ * enumerator over private keys
+ */
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** currently enumerated private key */
+ 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)
+{
+ chunk_t chunk;
+
+ DESTROY_IF(this->current);
+ while (this->inner->enumerate(this->inner, &chunk))
+ {
+ this->current = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB_ASN1_DER, chunk_clone(chunk),
+ BUILD_END);
+ if (this->current)
+ {
+ *key = this->current;
+ return TRUE;
+ }
+ }
+ this->current = NULL;
+ return FALSE;
+}
+
+/**
+ * Implementation of private_enumerator_t.public.destroy
+ */
+static void private_enumerator_destroy(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)
+{
+ private_enumerator_t *e;
+
+ if ((type != KEY_RSA && type != KEY_ANY) ||
+ id == NULL || id->get_type(id) != ID_KEY_ID)
+ {
+ DBG1(DBG_CFG, "%N - %D", key_type_names, type, id);
+ 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;
+ e->inner = this->db->query(this->db,
+ "SELECT PrivateKey FROM ClientConfig WHERE KeyId = ?",
+ DB_BLOB, id->get_encoding(id),
+ DB_BLOB);
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * enumerator over certificates
+ */
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** currently enumerated cert */
+ certificate_t *current;
+ /** type of requested key */
+ 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)
+{
+ public_key_t *public;
+ chunk_t chunk;
+
+ DESTROY_IF(this->current);
+ while (this->inner->enumerate(this->inner, &chunk))
+ {
+ public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+ BUILD_BLOB_ASN1_DER, chunk_clone(chunk),
+ BUILD_END);
+ if (public)
+ {
+ if (this->type == KEY_ANY || this->type == public->get_type(public))
+ {
+ this->current = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
+ BUILD_PUBLIC_KEY, public, BUILD_END);
+ if (this->current)
+ {
+ *cert = this->current;
+ return TRUE;
+ }
+ continue;
+ }
+ public->destroy(public);
+ }
+ }
+ this->current = NULL;
+ return FALSE;
+}
+
+/**
+ * Implementation of cert_enumerator_t.public.destroy
+ */
+static void cert_enumerator_destroy(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)
+{
+ cert_enumerator_t *e;
+
+ if ((cert != CERT_TRUSTED_PUBKEY && cert != CERT_ANY) ||
+ id == NULL || id->get_type(id) != ID_KEY_ID)
+ {
+ 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 PublicKey FROM ClientConfig WHERE KeyId = ? UNION "
+ "SELECT PublicKey FROM MediationServerConfig WHERE KeyId = ? UNION "
+ "SELECT PublicKey FROM Connection WHERE KeyId = ?",
+ DB_BLOB, id->get_encoding(id),
+ DB_BLOB, id->get_encoding(id),
+ DB_BLOB, id->get_encoding(id),
+ DB_BLOB);
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * Implementation of backend_t.destroy.
+ */
+static void destroy(private_medcli_creds_t *this)
+{
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+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;
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/medcli/medcli_creds.h b/src/charon/plugins/medcli/medcli_creds.h
new file mode 100644
index 000000000..5a81edaf2
--- /dev/null
+++ b/src/charon/plugins/medcli/medcli_creds.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup medcli_creds_i medcli_creds
+ * @{ @ingroup medcli
+ */
+
+#ifndef MEDCLI_CREDS_H_
+#define MEDCLI_CREDS_H_
+
+#include <credentials/credential_set.h>
+#include <database/database.h>
+
+typedef struct medcli_creds_t medcli_creds_t;
+
+/**
+ * Mediation client credentials database.
+ */
+struct medcli_creds_t {
+
+ /**
+ * Implements credential_set_t interface
+ */
+ credential_set_t set;
+
+ /**
+ * Destroy the credentials databse.
+ */
+ void (*destroy)(medcli_creds_t *this);
+};
+
+/**
+ * Create the medcli credential set.
+ *
+ * @param database underlying database
+ * @return credential set implementation on that database
+ */
+medcli_creds_t *medcli_creds_create(database_t *database);
+
+#endif /* MEDCLI_CREDS_H_ @}*/
diff --git a/src/charon/plugins/medcli/medcli_listener.c b/src/charon/plugins/medcli/medcli_listener.c
new file mode 100644
index 000000000..cb370ba2a
--- /dev/null
+++ b/src/charon/plugins/medcli/medcli_listener.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "medcli_listener.h"
+
+#include <daemon.h>
+#include <library.h>
+
+typedef struct private_medcli_listener_t private_medcli_listener_t;
+typedef enum mediated_state_t mediated_state_t;
+
+/**
+ * state of a mediated connection
+ */
+enum mediated_state_t {
+ STATE_DOWN = 1,
+ STATE_CONNECTING = 2,
+ STATE_UP = 3,
+};
+
+/**
+ * Private data of an medcli_listener_t object
+ */
+struct private_medcli_listener_t {
+
+ /**
+ * Public part
+ */
+ medcli_listener_t public;
+
+ /**
+ * underlying database handle
+ */
+ database_t *db;
+};
+
+/**
+ * Implementation of bus_listener_t.signal.
+ */
+static bool signal_(private_medcli_listener_t *this, signal_t signal, level_t level,
+ int thread, ike_sa_t* ike_sa, char *format, va_list args)
+{
+ mediated_state_t state;
+
+ if (!ike_sa)
+ {
+ return TRUE;
+ }
+
+ switch (signal)
+ {
+ case IKE_UP_START:
+ state = STATE_CONNECTING;
+ break;
+ case IKE_UP_FAILED:
+ case IKE_DOWN_SUCCESS:
+ case IKE_DOWN_FAILED:
+ state = STATE_DOWN;
+ break;
+ case IKE_UP_SUCCESS:
+ state = STATE_UP;
+ break;
+ default:
+ return TRUE;
+ }
+ this->db->execute(this->db, NULL,
+ "UPDATE Connection SET Status = ? WHERE Alias = ?",
+ DB_UINT, state, DB_TEXT, ike_sa->get_name(ike_sa));
+ return TRUE;
+}
+
+/**
+ * Implementation of backend_t.destroy.
+ */
+static void destroy(private_medcli_listener_t *this)
+{
+ this->db->execute(this->db, NULL, "UPDATE Connection SET Status = ?",
+ DB_UINT, STATE_DOWN);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+medcli_listener_t *medcli_listener_create(database_t *db)
+{
+ private_medcli_listener_t *this = malloc_thing(private_medcli_listener_t);
+
+ this->public.listener.signal = (bool(*)(bus_listener_t*,signal_t,level_t,int,ike_sa_t*,char*,va_list))signal_;
+ this->public.destroy = (void (*)(medcli_listener_t*))destroy;
+
+ this->db = db;
+ db->execute(db, NULL, "UPDATE Connection SET Status = ?",
+ DB_UINT, STATE_DOWN);
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/medcli/medcli_listener.h b/src/charon/plugins/medcli/medcli_listener.h
new file mode 100644
index 000000000..f07218d78
--- /dev/null
+++ b/src/charon/plugins/medcli/medcli_listener.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup medcli_listener_i medcli_listener
+ * @{ @ingroup medcli
+ */
+
+#ifndef MEDCLI_LISTENER_H_
+#define MEDCLI_LISTENER_H_
+
+#include <bus/bus.h>
+#include <database/database.h>
+
+typedef struct medcli_listener_t medcli_listener_t;
+
+/**
+ * Mediation client listener, writes connection status to database
+ */
+struct medcli_listener_t {
+
+ /**
+ * Implements bus_listener_t interface
+ */
+ bus_listener_t listener;
+
+ /**
+ * Destroy the credentials databse.
+ */
+ void (*destroy)(medcli_listener_t *this);
+};
+
+/**
+ * Create the medcli credential set.
+ *
+ * @param database underlying database
+ * @return listener
+ */
+medcli_listener_t *medcli_listener_create(database_t *database);
+
+#endif /* MEDCLI_LISTENER_H_ @}*/
diff --git a/src/charon/plugins/medcli/medcli_plugin.c b/src/charon/plugins/medcli/medcli_plugin.c
new file mode 100644
index 000000000..1642ed2fe
--- /dev/null
+++ b/src/charon/plugins/medcli/medcli_plugin.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "medcli_plugin.h"
+
+#include "medcli_creds.h"
+#include "medcli_config.h"
+#include "medcli_listener.h"
+
+#include <daemon.h>
+
+typedef struct private_medcli_plugin_t private_medcli_plugin_t;
+
+/**
+ * private data of medcli plugin
+ */
+struct private_medcli_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ medcli_plugin_t public;
+
+ /**
+ * database connection instance
+ */
+ database_t *db;
+
+ /**
+ * medcli credential set instance
+ */
+ medcli_creds_t *creds;
+
+ /**
+ * medcli config database
+ */
+ medcli_config_t *config;
+
+ /**
+ * Listener to update database connection state
+ */
+ medcli_listener_t *listener;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_medcli_plugin_t *this)
+{
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ charon->backends->remove_backend(charon->backends, &this->config->backend);
+ charon->credentials->remove_set(charon->credentials, &this->creds->set);
+ this->listener->destroy(this->listener);
+ this->config->destroy(this->config);
+ this->creds->destroy(this->creds);
+ this->db->destroy(this->db);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ char *uri;
+ private_medcli_plugin_t *this = malloc_thing(private_medcli_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ uri = lib->settings->get_str(lib->settings,
+ "medcli.database", NULL);
+ if (!uri)
+ {
+ DBG1(DBG_CFG, "mediation client database URI not defined, skipped");
+ free(this);
+ return NULL;
+ }
+
+ this->db = lib->db->create(lib->db, uri);
+ if (this->db == NULL)
+ {
+ DBG1(DBG_CFG, "opening mediation client database failed");
+ free(this);
+ return NULL;
+ }
+
+ this->creds = medcli_creds_create(this->db);
+ this->config = medcli_config_create(this->db);
+ this->listener = medcli_listener_create(this->db);
+
+ charon->credentials->add_set(charon->credentials, &this->creds->set);
+ charon->backends->add_backend(charon->backends, &this->config->backend);
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/medcli/medcli_plugin.h b/src/charon/plugins/medcli/medcli_plugin.h
new file mode 100644
index 000000000..1a8c5b5e7
--- /dev/null
+++ b/src/charon/plugins/medcli/medcli_plugin.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup medcli medcli
+ * @ingroup cplugins
+ *
+ * @defgroup medcli_plugin medcli_plugin
+ * @{ @ingroup medcli
+ */
+
+#ifndef MEDCLI_PLUGIN_H_
+#define MEDCLI_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct medcli_plugin_t medcli_plugin_t;
+
+/**
+ * Mediation client database plugin.
+ */
+struct medcli_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a medcli_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* MEDCLI_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/medsrv/Makefile.am b/src/charon/plugins/medsrv/Makefile.am
new file mode 100644
index 000000000..476da1878
--- /dev/null
+++ b/src/charon/plugins/medsrv/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-medsrv.la
+libstrongswan_medsrv_la_SOURCES = medsrv_plugin.h medsrv_plugin.c \
+ medsrv_creds.h medsrv_creds.c \
+ medsrv_config.h medsrv_config.c
+libstrongswan_medsrv_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/medsrv/Makefile.in b/src/charon/plugins/medsrv/Makefile.in
new file mode 100644
index 000000000..b6561e15e
--- /dev/null
+++ b/src/charon/plugins/medsrv/Makefile.in
@@ -0,0 +1,500 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@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/charon/plugins/medsrv
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_medsrv_la_LIBADD =
+am_libstrongswan_medsrv_la_OBJECTS = medsrv_plugin.lo medsrv_creds.lo \
+ medsrv_config.lo
+libstrongswan_medsrv_la_OBJECTS = \
+ $(am_libstrongswan_medsrv_la_OBJECTS)
+libstrongswan_medsrv_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_medsrv_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+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_medsrv_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_medsrv_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+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_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-medsrv.la
+libstrongswan_medsrv_la_SOURCES = medsrv_plugin.h medsrv_plugin.c \
+ medsrv_creds.h medsrv_creds.c \
+ medsrv_config.h medsrv_config.c
+
+libstrongswan_medsrv_la_LDFLAGS = -module
+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 \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/medsrv/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/medsrv/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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-medsrv.la: $(libstrongswan_medsrv_la_OBJECTS) $(libstrongswan_medsrv_la_DEPENDENCIES)
+ $(libstrongswan_medsrv_la_LINK) -rpath $(plugindir) $(libstrongswan_medsrv_la_OBJECTS) $(libstrongswan_medsrv_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medsrv_config.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medsrv_creds.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/medsrv_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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)
+
+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-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
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-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/charon/plugins/medsrv/medsrv_config.c b/src/charon/plugins/medsrv/medsrv_config.c
new file mode 100644
index 000000000..1017b9de0
--- /dev/null
+++ b/src/charon/plugins/medsrv/medsrv_config.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include <string.h>
+
+#include "medsrv_config.h"
+
+#include <daemon.h>
+
+typedef struct private_medsrv_config_t private_medsrv_config_t;
+
+/**
+ * Private data of an medsrv_config_t object
+ */
+struct private_medsrv_config_t {
+
+ /**
+ * Public part
+ */
+ medsrv_config_t public;
+
+ /**
+ * database connection
+ */
+ database_t *db;
+
+ /**
+ * rekey time
+ */
+ int rekey;
+
+ /**
+ * dpd delay
+ */
+ int dpd;
+
+ /**
+ * default ike config
+ */
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ enumerator_t *e;
+
+ if (!me || !other || other->get_type(other) != ID_KEY_ID)
+ {
+ return NULL;
+ }
+ e = this->db->query(this->db,
+ "SELECT CONCAT(peer.alias, CONCAT('@', user.login)) FROM "
+ "peer JOIN user ON peer.user = user.id "
+ "WHERE peer.keyid = ?", DB_BLOB, other->get_encoding(other),
+ DB_TEXT);
+ if (e)
+ {
+ peer_cfg_t *peer_cfg;
+ char *name;
+
+ if (e->enumerate(e, &name))
+ {
+ peer_cfg = peer_cfg_create(
+ name, 2, this->ike->get_ref(this->ike),
+ me->clone(me), other->clone(other),
+ CERT_NEVER_SEND, UNIQUE_REPLACE, CONF_AUTH_PUBKEY,
+ 0, 0, /* EAP method, vendor */
+ 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);
+ return enumerator_create_single(peer_cfg, (void*)peer_cfg->destroy);
+ }
+ e->destroy(e);
+ }
+ return NULL;
+}
+
+/**
+ * Implementation of medsrv_config_t.destroy.
+ */
+static void destroy(private_medsrv_config_t *this)
+{
+ this->ike->destroy(this->ike);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+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_int(lib->settings,
+ "medsrv.rekey", 20) * 60;
+ this->dpd = lib->settings->get_int(lib->settings, "medsrv.dpd", 300);
+ this->ike = ike_cfg_create(FALSE, FALSE, "0.0.0.0", "0.0.0.0");
+ this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/medsrv/medsrv_config.h b/src/charon/plugins/medsrv/medsrv_config.h
new file mode 100644
index 000000000..ebb62037e
--- /dev/null
+++ b/src/charon/plugins/medsrv/medsrv_config.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup medsrv_config_i medsrv_config
+ * @{ @ingroup medsrv
+ */
+
+#ifndef MEDSRV_CONFIG_H_
+#define MEDSRV_CONFIG_H_
+
+#include <config/backend.h>
+#include <database/database.h>
+
+typedef struct medsrv_config_t medsrv_config_t;
+
+/**
+ * Mediation server configuration backend.
+ */
+struct medsrv_config_t {
+
+ /**
+ * Implements backend_t interface
+ */
+ backend_t backend;
+
+ /**
+ * Destroy the backend.
+ */
+ void (*destroy)(medsrv_config_t *this);
+};
+
+/**
+ * Create a medsrv_config backend instance.
+ *
+ * @param db underlying database
+ * @return backend instance
+ */
+medsrv_config_t *medsrv_config_create(database_t *db);
+
+#endif /* MEDSRV_CONFIG_H_ @}*/
diff --git a/src/charon/plugins/medsrv/medsrv_creds.c b/src/charon/plugins/medsrv/medsrv_creds.c
new file mode 100644
index 000000000..48e05c38e
--- /dev/null
+++ b/src/charon/plugins/medsrv/medsrv_creds.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: medsrv_creds.c 4061 2008-06-11 14:13:24Z martin $
+ */
+
+#include "medsrv_creds.h"
+
+#include <daemon.h>
+#include <library.h>
+#include <utils/enumerator.h>
+
+typedef struct private_medsrv_creds_t private_medsrv_creds_t;
+
+/**
+ * Private data of an medsrv_creds_t object
+ */
+struct private_medsrv_creds_t {
+
+ /**
+ * Public part
+ */
+ medsrv_creds_t public;
+
+ /**
+ * underlying database handle
+ */
+ database_t *db;
+};
+
+/**
+ * enumerator over certificates
+ */
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** currently enumerated cert */
+ certificate_t *current;
+ /** type of requested key */
+ 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)
+{
+ certificate_t *trusted;
+ public_key_t *public;
+ chunk_t chunk;
+
+ DESTROY_IF(this->current);
+ while (this->inner->enumerate(this->inner, &chunk))
+ {
+ public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+ BUILD_BLOB_ASN1_DER, chunk_clone(chunk),
+ BUILD_END);
+ if (public)
+ {
+ if (this->type == KEY_ANY || this->type == public->get_type(public))
+ {
+ trusted = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
+ BUILD_PUBLIC_KEY, public, BUILD_END);
+ if (trusted)
+ {
+ *cert = this->current = trusted;
+ return TRUE;
+ }
+ continue;
+ }
+ public->destroy(public);
+ }
+ }
+ this->current = NULL;
+ return FALSE;
+}
+
+/**
+ * Implementation of cert_enumerator_t.public.destroy
+ */
+static void cert_enumerator_destroy(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)
+{
+ cert_enumerator_t *e;
+
+ if ((cert != CERT_TRUSTED_PUBKEY && cert != CERT_ANY) ||
+ id == NULL || id->get_type(id) != ID_KEY_ID)
+ {
+ 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);
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * Implementation of backend_t.destroy.
+ */
+static void destroy(private_medsrv_creds_t *this)
+{
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+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;
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/medsrv/medsrv_creds.h b/src/charon/plugins/medsrv/medsrv_creds.h
new file mode 100644
index 000000000..f65e98411
--- /dev/null
+++ b/src/charon/plugins/medsrv/medsrv_creds.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: medsrv_creds.h 3915 2008-05-08 12:11:30Z martin $
+ */
+
+/**
+ * @defgroup medsrv_creds_i medsrv_creds
+ * @{ @ingroup medsrv
+ */
+
+#ifndef MEDSRV_CREDS_H_
+#define MEDSRV_CREDS_H_
+
+#include <credentials/credential_set.h>
+#include <database/database.h>
+
+typedef struct medsrv_creds_t medsrv_creds_t;
+
+/**
+ * Mediation credentials database.
+ */
+struct medsrv_creds_t {
+
+ /**
+ * Implements credential_set_t interface
+ */
+ credential_set_t set;
+
+ /**
+ * Destroy the credentials databse.
+ */
+ void (*destroy)(medsrv_creds_t *this);
+};
+
+/**
+ * Create the medsrv credentials db.
+ *
+ * @param database underlying database
+ * @return credential set implementation on that database
+ */
+medsrv_creds_t *medsrv_creds_create(database_t *database);
+
+#endif /* MEDSRV_CREDS_H_ @}*/
diff --git a/src/charon/plugins/medsrv/medsrv_plugin.c b/src/charon/plugins/medsrv/medsrv_plugin.c
new file mode 100644
index 000000000..f29120337
--- /dev/null
+++ b/src/charon/plugins/medsrv/medsrv_plugin.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: medsrv_plugin.c 3915 2008-05-08 12:11:30Z martin $
+ */
+
+#include "medsrv_plugin.h"
+
+#include "medsrv_creds.h"
+#include "medsrv_config.h"
+
+#include <daemon.h>
+
+typedef struct private_medsrv_plugin_t private_medsrv_plugin_t;
+
+/**
+ * private data of medsrv plugin
+ */
+struct private_medsrv_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ medsrv_plugin_t public;
+
+ /**
+ * database connection instance
+ */
+ database_t *db;
+
+ /**
+ * medsrv credential set instance
+ */
+ medsrv_creds_t *creds;
+
+ /**
+ * medsrv config database
+ */
+ medsrv_config_t *config;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_medsrv_plugin_t *this)
+{
+ charon->backends->remove_backend(charon->backends, &this->config->backend);
+ charon->credentials->remove_set(charon->credentials, &this->creds->set);
+ this->config->destroy(this->config);
+ this->creds->destroy(this->creds);
+ this->db->destroy(this->db);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ char *uri;
+ private_medsrv_plugin_t *this = malloc_thing(private_medsrv_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ uri = lib->settings->get_str(lib->settings,
+ "medmanager.database", NULL);
+ if (!uri)
+ {
+ DBG1(DBG_CFG, "mediation database URI not defined, skipped");
+ free(this);
+ return NULL;
+ }
+
+ this->db = lib->db->create(lib->db, uri);
+ if (this->db == NULL)
+ {
+ DBG1(DBG_CFG, "opening mediation server database failed");
+ free(this);
+ return NULL;
+ }
+
+ this->creds = medsrv_creds_create(this->db);
+ this->config = medsrv_config_create(this->db);
+
+ charon->credentials->add_set(charon->credentials, &this->creds->set);
+ charon->backends->add_backend(charon->backends, &this->config->backend);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/medsrv/medsrv_plugin.h b/src/charon/plugins/medsrv/medsrv_plugin.h
new file mode 100644
index 000000000..8aa56d607
--- /dev/null
+++ b/src/charon/plugins/medsrv/medsrv_plugin.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: medsrv_plugin.h 3915 2008-05-08 12:11:30Z martin $
+ */
+
+/**
+ * @defgroup medsrv medsrv
+ * @ingroup cplugins
+ *
+ * @defgroup medsrv_plugin medsrv_plugin
+ * @{ @ingroup medsrv
+ */
+
+#ifndef MEDSRV_PLUGIN_H_
+#define MEDSRV_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct medsrv_plugin_t medsrv_plugin_t;
+
+/**
+ * Mediation server database plugin.
+ */
+struct medsrv_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a medsrv_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* MEDSRV_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/smp/Makefile.am b/src/charon/plugins/smp/Makefile.am
new file mode 100644
index 000000000..1679f1c68
--- /dev/null
+++ b/src/charon/plugins/smp/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon ${xml_CFLAGS}
+
+AM_CFLAGS = -rdynamic -DIPSEC_PIDDIR=\"${piddir}\"
+
+plugin_LTLIBRARIES = libstrongswan-smp.la
+libstrongswan_smp_la_SOURCES = smp.h smp.c
+libstrongswan_smp_la_LDFLAGS = -module
+libstrongswan_smp_la_LIBADD = ${xml_LIBS}
+
diff --git a/src/charon/plugins/smp/Makefile.in b/src/charon/plugins/smp/Makefile.in
new file mode 100644
index 000000000..198526abb
--- /dev/null
+++ b/src/charon/plugins/smp/Makefile.in
@@ -0,0 +1,495 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@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/charon/plugins/smp
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libstrongswan_smp_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libstrongswan_smp_la_OBJECTS = smp.lo
+libstrongswan_smp_la_OBJECTS = $(am_libstrongswan_smp_la_OBJECTS)
+libstrongswan_smp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_smp_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+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_smp_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_smp_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+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_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon ${xml_CFLAGS}
+AM_CFLAGS = -rdynamic -DIPSEC_PIDDIR=\"${piddir}\"
+plugin_LTLIBRARIES = libstrongswan-smp.la
+libstrongswan_smp_la_SOURCES = smp.h smp.c
+libstrongswan_smp_la_LDFLAGS = -module
+libstrongswan_smp_la_LIBADD = ${xml_LIBS}
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/smp/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/smp/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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-smp.la: $(libstrongswan_smp_la_OBJECTS) $(libstrongswan_smp_la_DEPENDENCIES)
+ $(libstrongswan_smp_la_LINK) -rpath $(plugindir) $(libstrongswan_smp_la_OBJECTS) $(libstrongswan_smp_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smp.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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)
+
+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-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
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-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/charon/control/interfaces/xml_interface.c b/src/charon/plugins/smp/smp.c
index aa2a554a0..3b7fa0070 100644
--- a/src/charon/control/interfaces/xml_interface.c
+++ b/src/charon/plugins/smp/smp.c
@@ -1,10 +1,3 @@
-/**
- * @file xml_interface.c
- *
- * @brief Implementation of xml_interface_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,11 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: smp.c 4073 2008-06-20 07:14:35Z martin $
*/
#include <stdlib.h>
-#include "xml_interface.h"
+#include "smp.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -40,17 +35,17 @@
#include <processing/jobs/callback_job.h>
-typedef struct private_xml_interface_t private_xml_interface_t;
+typedef struct private_smp_t private_smp_t;
/**
- * Private data of an xml_interface_t object.
+ * Private data of an smp_t object.
*/
-struct private_xml_interface_t {
+struct private_smp_t {
/**
- * Public part of xml_t object.
+ * Public part of smp_t object.
*/
- xml_interface_t public;
+ smp_t public;
/**
* XML unix socket fd
@@ -151,12 +146,12 @@ static void write_address(xmlTextWriterPtr writer, char *element, host_t *host)
static void write_networks(xmlTextWriterPtr writer, char *element,
linked_list_t *list)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
traffic_selector_t *ts;
xmlTextWriterStartElement(writer, element);
- iterator = list->create_iterator(list, TRUE);
- while (iterator->iterate(iterator, (void**)&ts))
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, (void**)&ts))
{
xmlTextWriterStartElement(writer, "network");
xmlTextWriterWriteAttribute(writer, "type",
@@ -164,7 +159,7 @@ static void write_networks(xmlTextWriterPtr writer, char *element,
xmlTextWriterWriteFormatString(writer, "%R", ts);
xmlTextWriterEndElement(writer);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
xmlTextWriterEndElement(writer);
}
@@ -215,14 +210,14 @@ static void write_child(xmlTextWriterPtr writer, child_sa_t *child)
*/
static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
ike_sa_t *ike_sa;
/* <ikesalist> */
xmlTextWriterStartElement(writer, "ikesalist");
- iterator = charon->ike_sa_manager->create_iterator(charon->ike_sa_manager);
- while (iterator->iterate(iterator, (void**)&ike_sa))
+ enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ while (enumerator->enumerate(enumerator, &ike_sa))
{
ike_sa_id_t *id;
host_t *local, *remote;
@@ -288,7 +283,7 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer
/* </ikesa> */
xmlTextWriterEndElement(writer);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* </ikesalist> */
xmlTextWriterEndElement(writer);
@@ -299,16 +294,16 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer
*/
static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
peer_cfg_t *peer_cfg;
/* <configlist> */
xmlTextWriterStartElement(writer, "configlist");
- iterator = charon->backends->create_iterator(charon->backends);
- while (iterator->iterate(iterator, (void**)&peer_cfg))
+ enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
+ while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
{
- iterator_t *children;
+ enumerator_t *children;
child_cfg_t *child_cfg;
ike_cfg_t *ike_cfg;
linked_list_t *list;
@@ -327,15 +322,15 @@ static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr write
/* <ikeconfig> */
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
xmlTextWriterStartElement(writer, "ikeconfig");
- write_address(writer, "local", ike_cfg->get_my_host(ike_cfg));
- write_address(writer, "remote", ike_cfg->get_other_host(ike_cfg));
+ xmlTextWriterWriteElement(writer, "local", ike_cfg->get_my_addr(ike_cfg));
+ xmlTextWriterWriteElement(writer, "remote", ike_cfg->get_other_addr(ike_cfg));
xmlTextWriterEndElement(writer);
/* </ikeconfig> */
/* <childconfiglist> */
xmlTextWriterStartElement(writer, "childconfiglist");
- children = peer_cfg->create_child_cfg_iterator(peer_cfg);
- while (children->iterate(children, (void**)&child_cfg))
+ children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
+ while (children->enumerate(children, &child_cfg))
{
/* <childconfig> */
xmlTextWriterStartElement(writer, "childconfig");
@@ -356,7 +351,7 @@ static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr write
/* </peerconfig> */
xmlTextWriterEndElement(writer);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* </configlist> */
xmlTextWriterEndElement(writer);
}
@@ -395,26 +390,50 @@ static void request_control_terminate(xmlTextReaderPtr reader,
status_t status;
str = xmlTextReaderConstValue(reader);
- if (str == NULL || !(id = atoi(str)))
+ if (str == NULL)
{
DBG1(DBG_CFG, "error parsing XML id string");
return;
}
+ id = atoi(str);
+ if (!id)
+ {
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+
+ enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ if (streq(str, ike_sa->get_name(ike_sa)))
+ {
+ ike = TRUE;
+ id = ike_sa->get_unique_id(ike_sa);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ if (!id)
+ {
+ DBG1(DBG_CFG, "error parsing XML id string");
+ return;
+ }
+
DBG1(DBG_CFG, "terminating %s_SA %d", ike ? "IKE" : "CHILD", id);
/* <log> */
xmlTextWriterStartElement(writer, "log");
if (ike)
{
- status = charon->interfaces->terminate_ike(
- charon->interfaces, id,
- (interface_manager_cb_t)xml_callback, writer);
+ status = charon->controller->terminate_ike(
+ charon->controller, id,
+ (controller_cb_t)xml_callback, writer);
}
else
{
- status = charon->interfaces->terminate_child(
- charon->interfaces, id,
- (interface_manager_cb_t)xml_callback, writer);
+ status = charon->controller->terminate_child(
+ charon->controller, id,
+ (controller_cb_t)xml_callback, writer);
}
/* </log> */
xmlTextWriterEndElement(writer);
@@ -435,7 +454,7 @@ static void request_control_initiate(xmlTextReaderPtr reader,
status_t status = FAILED;
peer_cfg_t *peer;
child_cfg_t *child = NULL;
- iterator_t *iterator;
+ enumerator_t *enumerator;
str = xmlTextReaderConstValue(reader);
if (str == NULL)
@@ -450,10 +469,10 @@ static void request_control_initiate(xmlTextReaderPtr reader,
peer = charon->backends->get_peer_cfg_by_name(charon->backends, (char*)str);
if (peer)
{
- iterator = peer->create_child_cfg_iterator(peer);
+ enumerator = peer->create_child_cfg_enumerator(peer);
if (ike)
{
- if (!iterator->iterate(iterator, (void**)&child))
+ if (!enumerator->enumerate(enumerator, &child))
{
child = NULL;
}
@@ -461,7 +480,7 @@ static void request_control_initiate(xmlTextReaderPtr reader,
}
else
{
- while (iterator->iterate(iterator, (void**)&child))
+ while (enumerator->enumerate(enumerator, &child))
{
if (streq(child->get_name(child), str))
{
@@ -471,11 +490,11 @@ static void request_control_initiate(xmlTextReaderPtr reader,
child = NULL;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
if (child)
{
- status = charon->interfaces->initiate(charon->interfaces,
- peer, child, (interface_manager_cb_t)xml_callback,
+ status = charon->controller->initiate(charon->controller,
+ peer, child, (controller_cb_t)xml_callback,
writer);
}
else
@@ -667,7 +686,7 @@ static job_requeue_t process(int *fdp)
/**
* accept from XML socket and create jobs to process connections
*/
-static job_requeue_t dispatch(private_xml_interface_t *this)
+static job_requeue_t dispatch(private_smp_t *this)
{
struct sockaddr_un strokeaddr;
int oldstate, fd, *fdp, strokeaddrlen = sizeof(strokeaddr);
@@ -696,7 +715,7 @@ static job_requeue_t dispatch(private_xml_interface_t *this)
/**
* Implementation of itnerface_t.destroy.
*/
-static void destroy(private_xml_interface_t *this)
+static void destroy(private_smp_t *this)
{
this->job->cancel(this->job);
close(this->socket);
@@ -706,13 +725,13 @@ static void destroy(private_xml_interface_t *this)
/*
* Described in header file
*/
-interface_t *interface_create()
+plugin_t *plugin_create()
{
struct sockaddr_un unix_addr = { AF_UNIX, IPSEC_PIDDIR "/charon.xml"};
- private_xml_interface_t *this = malloc_thing(private_xml_interface_t);
+ private_smp_t *this = malloc_thing(private_smp_t);
mode_t old;
- this->public.interface.destroy = (void (*)(interface_t*))destroy;
+ this->public.plugin.destroy = (void (*)(plugin_t*))destroy;
/* set up unix socket */
this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -733,7 +752,7 @@ interface_t *interface_create()
return NULL;
}
umask(old);
- if (chown(unix_addr.sun_path, IPSEC_UID, IPSEC_GID) != 0)
+ if (chown(unix_addr.sun_path, charon->uid, charon->gid) != 0)
{
DBG1(DBG_CFG, "changing XML socket permissions failed: %s", strerror(errno));
}
@@ -749,6 +768,6 @@ interface_t *interface_create()
this->job = callback_job_create((callback_job_cb_t)dispatch, this, NULL, NULL);
charon->processor->queue_job(charon->processor, (job_t*)this->job);
- return &this->public.interface;
+ return &this->public.plugin;
}
diff --git a/src/charon/control/interfaces/xml_interface.h b/src/charon/plugins/smp/smp.h
index 6d88c3842..e65d5ea2c 100644
--- a/src/charon/control/interfaces/xml_interface.h
+++ b/src/charon/plugins/smp/smp.h
@@ -1,12 +1,5 @@
-/**
- * @file xml_interface.h
- *
- * @brief Interface of xml_interface_t.
- *
- */
-
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2007-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,40 +11,42 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: smp.h 3689 2008-03-28 12:44:01Z martin $
*/
-#ifndef XML_INTERFACE_H_
-#define XML_INTERFACE_H_
+/**
+ * @defgroup smp smp
+ * @ingroup cplugins
+ *
+ * @defgroup smp_i smp
+ * @{ @ingroup smp
+ */
+
+#ifndef SMP_H_
+#define SMP_H_
-typedef struct xml_interface_t xml_interface_t;
+#include <plugins/plugin.h>
-#include <control/interfaces/interface.h>
+typedef struct smp_t smp_t;
/**
- * @brief The XML interface uses a socket to communicate using XML.
- *
- * @b Constructors:
- * - xml_interface_create()
- *
- * @ingroup interfaces
+ * SMP configuration and control interface.
+ *
+ * The SMP interface uses a socket and a to communicate. The syntax is strict
+ * XML, defined in the schema.xml specification.
*/
-struct xml_interface_t {
-
+struct smp_t {
+
/**
- * implements interface_t.
+ * implements the plugin interface.
*/
- interface_t interface;
+ plugin_t plugin;
};
-
/**
- * @brief Create the XML interface.
- *
- * @return stroke_t object
- *
- * @ingroup interfaces
+ * Create a smp plugin instance.
*/
-interface_t *interface_create(void);
-
-#endif /* XML_INTERFACE_H_ */
+plugin_t *plugin_create();
+#endif /* XML_H_ @}*/
diff --git a/src/charon/plugins/sql/Makefile.am b/src/charon/plugins/sql/Makefile.am
new file mode 100644
index 000000000..ea39ce0d5
--- /dev/null
+++ b/src/charon/plugins/sql/Makefile.am
@@ -0,0 +1,17 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\" \
+ -DPLUGINS=\""${libstrongswan_plugins}\""
+
+plugin_LTLIBRARIES = libstrongswan-sql.la
+libstrongswan_sql_la_SOURCES = sql_plugin.h sql_plugin.c \
+ sql_config.h sql_config.c sql_cred.h sql_cred.c \
+ sql_attribute.h sql_attribute.c sql_logger.h sql_logger.c
+libstrongswan_sql_la_LDFLAGS = -module
+
+ipsec_PROGRAMS = pool
+pool_SOURCES = pool.c
+pool_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
diff --git a/src/charon/plugins/sql/Makefile.in b/src/charon/plugins/sql/Makefile.in
new file mode 100644
index 000000000..babc11ecb
--- /dev/null
+++ b/src/charon/plugins/sql/Makefile.in
@@ -0,0 +1,549 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ipsec_PROGRAMS = pool$(EXEEXT)
+subdir = src/charon/plugins/sql
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(ipsecdir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_sql_la_LIBADD =
+am_libstrongswan_sql_la_OBJECTS = sql_plugin.lo sql_config.lo \
+ sql_cred.lo sql_attribute.lo sql_logger.lo
+libstrongswan_sql_la_OBJECTS = $(am_libstrongswan_sql_la_OBJECTS)
+libstrongswan_sql_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_sql_la_LDFLAGS) $(LDFLAGS) -o $@
+ipsecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(ipsec_PROGRAMS)
+am_pool_OBJECTS = pool.$(OBJEXT)
+pool_OBJECTS = $(am_pool_OBJECTS)
+pool_DEPENDENCIES = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+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_sql_la_SOURCES) $(pool_SOURCES)
+DIST_SOURCES = $(libstrongswan_sql_la_SOURCES) $(pool_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+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_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\" \
+ -DPLUGINS=\""${libstrongswan_plugins}\""
+
+plugin_LTLIBRARIES = libstrongswan-sql.la
+libstrongswan_sql_la_SOURCES = sql_plugin.h sql_plugin.c \
+ sql_config.h sql_config.c sql_cred.h sql_cred.c \
+ sql_attribute.h sql_attribute.c sql_logger.h sql_logger.c
+
+libstrongswan_sql_la_LDFLAGS = -module
+pool_SOURCES = pool.c
+pool_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/sql/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/sql/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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-sql.la: $(libstrongswan_sql_la_OBJECTS) $(libstrongswan_sql_la_DEPENDENCIES)
+ $(libstrongswan_sql_la_LINK) -rpath $(plugindir) $(libstrongswan_sql_la_OBJECTS) $(libstrongswan_sql_la_LIBADD) $(LIBS)
+install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipsecdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsecdir)"
+ @list='$(ipsec_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(ipsecPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(ipsecdir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(ipsecPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(ipsecdir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-ipsecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipsec_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(ipsecdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(ipsecdir)/$$f"; \
+ done
+
+clean-ipsecPROGRAMS:
+ @list='$(ipsec_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+pool$(EXEEXT): $(pool_OBJECTS) $(pool_DEPENDENCIES)
+ @rm -f pool$(EXEEXT)
+ $(LINK) $(pool_OBJECTS) $(pool_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql_attribute.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql_config.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql_logger.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(ipsecdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+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-ipsecPROGRAMS clean-libtool \
+ 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
+
+info: info-am
+
+info-am:
+
+install-data-am: install-ipsecPROGRAMS install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-ipsecPROGRAMS uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-ipsecPROGRAMS clean-libtool 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-ipsecPROGRAMS 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-ipsecPROGRAMS \
+ 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/charon/plugins/sql/pool.c b/src/charon/plugins/sql/pool.c
new file mode 100644
index 000000000..86ceddeee
--- /dev/null
+++ b/src/charon/plugins/sql/pool.c
@@ -0,0 +1,726 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#define _GNU_SOURCE
+#include <getopt.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <time.h>
+
+#include <debug.h>
+#include <library.h>
+#include <utils/host.h>
+
+/**
+ * global database handle
+ */
+database_t *db;
+
+/**
+ * --start/--end addresses of various subcommands
+ */
+host_t *start = NULL, *end = NULL;
+
+/**
+ * create a host from a blob
+ */
+static host_t *host_create_from_blob(chunk_t blob)
+{
+ return host_create_from_chunk(blob.len == 4 ? AF_INET : AF_INET6, blob, 0);
+}
+
+/**
+ * calculate the size of a pool using start and end address chunk
+ */
+static u_int get_pool_size(chunk_t start, chunk_t end)
+{
+ u_int *start_ptr, *end_ptr;
+
+ if (start.len < sizeof(u_int) || end.len < sizeof(u_int))
+ {
+ return 0;
+ }
+ start_ptr = (u_int*)(start.ptr + start.len - sizeof(u_int));
+ end_ptr = (u_int*)(end.ptr + end.len - sizeof(u_int));
+ return ntohl(*end_ptr) - ntohl(*start_ptr) + 1;
+}
+
+/**
+ * print usage info
+ */
+static void usage(void)
+{
+ printf("\
+Usage:\n\
+ ipsec pool --status|--add|--del|--resize|--purge [options]\n\
+ \n\
+ ipsec pool --status\n\
+ Show a list of installed pools with statistics.\n\
+ \n\
+ ipsec pool --add <name> --start <start> --end <end> [--timeout <timeout>]\n\
+ Add a new pool to the database.\n\
+ name: Name of the pool, as used in ipsec.conf rightsourceip=%%name\n\
+ start: Start address of the pool\n\
+ end: End address of the pool\n\
+ timeout: Lease time in hours, 0 for static leases\n\
+ \n\
+ ipsec pool --del <name>\n\
+ Delete a pool from the database.\n\
+ name: Name of the pool to delete\n\
+ \n\
+ ipsec pool --resize <name> --end <end>\n\
+ Grow or shrink an existing pool.\n\
+ name: Name of the pool to resize\n\
+ end: New end address for the pool\n\
+ \n\
+ ipsec pool --leases <name> [--filter <filter>] [--utc]\n\
+ Show lease information using filters:\n\
+ name: Name of the pool to show leases from\n\
+ filter: Filter string containing comma separated key=value filters,\n\
+ e.g. id=alice@strongswan.org,addr=1.1.1.1\n\
+ pool: name of the pool\n\
+ id: assigned identity of the lease\n\
+ addr: lease IP address\n\
+ tstamp: UNIX timestamp when lease was valid, as integer\n\
+ status: status of the lease: online|valid|expired\n\
+ utc: Show times in UTC instead of local time\n\
+ \n\
+ ipsec pool --purge <name>\n\
+ Delete expired leases of a pool:\n\
+ name: Name of the pool to purge\n\
+ \n");
+ exit(0);
+}
+
+/**
+ * ipsec pool --status - show pool overview
+ */
+static void status(void)
+{
+ enumerator_t *pool, *lease;
+ bool found = FALSE;
+
+ pool = db->query(db, "SELECT id, name, start, end, timeout FROM pools",
+ DB_INT, DB_TEXT, DB_BLOB, DB_BLOB, DB_UINT);
+ if (pool)
+ {
+ char *name;
+ chunk_t start_chunk, end_chunk;
+ host_t *start, *end;
+ u_int id, timeout, online = 0, used = 0, size = 0;
+
+ while (pool->enumerate(pool, &id, &name,
+ &start_chunk, &end_chunk, &timeout))
+ {
+ if (!found)
+ {
+ printf("%8s %15s %15s %8s %6s %11s %11s\n",
+ "name", "start", "end", "timeout", "size", "online", "leases");
+ found = TRUE;
+ }
+
+ start = host_create_from_blob(start_chunk);
+ end = host_create_from_blob(end_chunk);
+ size = get_pool_size(start_chunk, end_chunk);
+ printf("%8s %15H %15H ", name, start, end);
+ if (timeout)
+ {
+ printf("%7dh ", timeout/3600);
+ }
+ else
+ {
+ printf("%8s ", "static");
+ }
+ printf("%6d ", size);
+ /* get number of online hosts */
+ lease = db->query(db, "SELECT COUNT(*) FROM leases "
+ "WHERE pool = ? AND released IS NULL",
+ DB_UINT, id, DB_INT);
+ if (lease)
+ {
+ lease->enumerate(lease, &online);
+ lease->destroy(lease);
+ }
+ printf("%5d (%2d%%) ", online, online*100/size);
+ /* get number of online or valid lieases */
+ lease = db->query(db, "SELECT COUNT(*) FROM leases JOIN pools "
+ "ON leases.pool = pools.id "
+ "WHERE pools.id = ? "
+ "AND (released IS NULL OR released > ? - timeout) ",
+ DB_UINT, id, DB_UINT, time(NULL), DB_UINT);
+ if (lease)
+ {
+ lease->enumerate(lease, &used);
+ lease->destroy(lease);
+ }
+ printf("%5d (%2d%%) ", used, used*100/size);
+
+ printf("\n");
+ DESTROY_IF(start);
+ DESTROY_IF(end);
+ }
+ pool->destroy(pool);
+ }
+ if (!found)
+ {
+ printf("no pools found.\n");
+ }
+ exit(0);
+}
+
+/**
+ * ipsec pool --add - add a new pool
+ */
+static void add(char *name, host_t *start, host_t *end, int timeout)
+{
+ chunk_t start_addr, end_addr;
+
+ start_addr = start->get_address(start);
+ end_addr = end->get_address(end);
+
+ if (start_addr.len != end_addr.len ||
+ memcmp(start_addr.ptr, end_addr.ptr, start_addr.len) > 0)
+ {
+ fprintf(stderr, "invalid start/end pair specified.\n");
+ exit(-1);
+ }
+ if (db->execute(db, NULL,
+ "INSERT INTO pools (name, start, end, next, timeout) "
+ "VALUES (?, ?, ?, ?, ?)",
+ DB_TEXT, name, DB_BLOB, start_addr,
+ DB_BLOB, end_addr, DB_BLOB, start_addr,
+ DB_INT, timeout*3600) != 1)
+ {
+ fprintf(stderr, "creating pool failed.\n");
+ exit(-1);
+ }
+ exit(0);
+}
+
+/**
+ * ipsec pool --del - delete a pool
+ */
+static void del(char *name)
+{
+ enumerator_t *query;
+ u_int id;
+ bool found = FALSE;
+
+ query = db->query(db, "SELECT id FROM pools WHERE name = ?",
+ DB_TEXT, name, DB_UINT);
+ if (!query)
+ {
+ fprintf(stderr, "deleting pool failed.\n");
+ exit(-1);
+ }
+ while (query->enumerate(query, &id))
+ {
+ found = TRUE;
+ if (db->execute(db, NULL,
+ "DELETE FROM pools WHERE id = ?", DB_UINT, id) != 1 ||
+ db->execute(db, NULL,
+ "DELETE FROM leases WHERE pool = ?", DB_UINT, id) < 0)
+ {
+ fprintf(stderr, "deleting pool failed.\n");
+ query->destroy(query);
+ exit(-1);
+ }
+ }
+ query->destroy(query);
+ if (!found)
+ {
+ fprintf(stderr, "pool '%s' not found.\n", name);
+ exit(-1);
+ }
+ exit(0);
+}
+
+/**
+ * ipsec pool --resize - resize a pool
+ */
+static void resize(char *name, host_t *end)
+{
+ enumerator_t *query;
+ chunk_t next_addr, end_addr;
+
+ end_addr = end->get_address(end);
+
+ query = db->query(db, "SELECT next FROM pools WHERE name = ?",
+ DB_TEXT, name, DB_BLOB);
+ if (!query || !query->enumerate(query, &next_addr))
+ {
+ DESTROY_IF(query);
+ fprintf(stderr, "resizing pool failed.\n");
+ exit(-1);
+ }
+ if (next_addr.len != end_addr.len ||
+ memcmp(end_addr.ptr, next_addr.ptr, end_addr.len) < 0)
+ {
+ end = host_create_from_blob(next_addr);
+ fprintf(stderr, "pool addresses up to %H in use, resizing failed.\n", end);
+ end->destroy(end);
+ query->destroy(query);
+ exit(-1);
+ }
+ query->destroy(query);
+
+ if (db->execute(db, NULL,
+ "UPDATE pools SET end = ? WHERE name = ?",
+ DB_BLOB, end_addr, DB_TEXT, name) <= 0)
+ {
+ fprintf(stderr, "pool '%s' not found.\n", name);
+ exit(-1);
+ }
+ exit(0);
+}
+
+/**
+ * create the lease query using the filter string
+ */
+static enumerator_t *create_lease_query(char *filter)
+{
+ enumerator_t *query;
+ identification_t *id = NULL;
+ host_t *addr = NULL;
+ u_int tstamp = 0;
+ bool online = FALSE, valid = FALSE, expired = FALSE;
+ char *value, *pos, *pool = NULL;
+ enum {
+ FIL_POOL = 0,
+ FIL_ID,
+ FIL_ADDR,
+ FIL_TSTAMP,
+ FIL_STATE,
+ };
+ char *const token[] = {
+ [FIL_POOL] = "pool",
+ [FIL_ID] = "id",
+ [FIL_ADDR] = "addr",
+ [FIL_TSTAMP] = "tstamp",
+ [FIL_STATE] = "status",
+ NULL
+ };
+
+ /* if the filter string contains a distinguished name as a ID, we replace
+ * ", " by "/ " in order to not confuse the getsubopt parser */
+ pos = filter;
+ while ((pos = strchr(pos, ',')))
+ {
+ if (pos[1] == ' ')
+ {
+ pos[0] = '/';
+ }
+ pos++;
+ }
+
+ while (filter && *filter != '\0')
+ {
+ switch (getsubopt(&filter, token, &value))
+ {
+ case FIL_POOL:
+ if (value)
+ {
+ pool = value;
+ }
+ break;
+ case FIL_ID:
+ if (value)
+ {
+ id = identification_create_from_string(value);
+ }
+ if (!id)
+ {
+ fprintf(stderr, "invalid 'id' in filter string.\n");
+ exit(-1);
+ }
+ break;
+ case FIL_ADDR:
+ if (value)
+ {
+ addr = host_create_from_string(value, 0);
+ }
+ if (!addr)
+ {
+ fprintf(stderr, "invalid 'addr' in filter string.\n");
+ exit(-1);
+ }
+ break;
+ case FIL_TSTAMP:
+ if (value)
+ {
+ tstamp = atoi(value);
+ }
+ if (tstamp == 0)
+ {
+ online = TRUE;
+ }
+ break;
+ case FIL_STATE:
+ if (value)
+ {
+ if (streq(value, "online"))
+ {
+ online = TRUE;
+ }
+ else if (streq(value, "valid"))
+ {
+ valid = TRUE;
+ }
+ else if (streq(value, "expired"))
+ {
+ expired = TRUE;
+ }
+ else
+ {
+ fprintf(stderr, "invalid 'state' in filter string.\n");
+ exit(-1);
+ }
+ }
+ break;
+ default:
+ fprintf(stderr, "invalid filter string.\n");
+ exit(-1);
+ break;
+ }
+ }
+ query = db->query(db,
+ "SELECT name, address, identities.type, "
+ "identities.data, acquired, released, timeout "
+ "FROM leases JOIN pools ON leases.pool = pools.id "
+ "JOIN identities ON leases.identity = identities.id "
+ "WHERE (? OR name = ?) "
+ "AND (? OR (identities.type = ? AND identities.data = ?)) "
+ "AND (? OR address = ?) "
+ "AND (? OR (? >= acquired AND (? <= released OR released IS NULL))) "
+ "AND (? OR released IS NULL) "
+ "AND (? OR released > ? - timeout) "
+ "AND (? OR released < ? - timeout)",
+ DB_INT, pool == NULL, DB_TEXT, pool,
+ DB_INT, id == NULL,
+ DB_INT, id ? id->get_type(id) : 0,
+ DB_BLOB, id ? id->get_encoding(id) : chunk_empty,
+ DB_INT, addr == NULL,
+ DB_BLOB, addr ? addr->get_address(addr) : chunk_empty,
+ DB_INT, tstamp == 0, DB_UINT, tstamp, DB_UINT, tstamp,
+ DB_INT, !online,
+ DB_INT, !valid, DB_INT, time(NULL),
+ DB_INT, !expired, DB_INT, time(NULL),
+ DB_TEXT, DB_BLOB, DB_INT, DB_BLOB, DB_UINT, DB_UINT, DB_UINT);
+ /* id and addr leak but we can't destroy them until query is destroyed. */
+ return query;
+}
+
+/**
+ * ipsec pool --leases - show lease information of a pool
+ */
+static void leases(char *filter, bool utc)
+{
+ enumerator_t *query;
+ chunk_t address_chunk, identity_chunk;
+ int identity_type;
+ char *name;
+ u_int acquired, released, timeout;
+ host_t *address;
+ identification_t *identity;
+ bool found = FALSE;
+
+ query = create_lease_query(filter);
+ if (!query)
+ {
+ fprintf(stderr, "querying leases failed.\n");
+ exit(-1);
+ }
+ while (query->enumerate(query, &name, &address_chunk, &identity_type,
+ &identity_chunk, &acquired, &released, &timeout))
+ {
+ if (!found)
+ {
+ int len = utc ? 25 : 21;
+
+ found = TRUE;
+ printf("%-8s %-15s %-7s %-*s %-*s %s\n",
+ "name", "address", "status", len, "start", len, "end", "identity");
+ }
+ address = host_create_from_blob(address_chunk);
+ identity = identification_create_from_encoding(identity_type, identity_chunk);
+
+ printf("%-8s %-15H ", name, address);
+ if (released == 0)
+ {
+ printf("%-7s ", "online");
+ }
+ else if (timeout == 0)
+ {
+ printf("%-7s ", "static");
+ }
+ else if (released >= time(NULL) - timeout)
+ {
+ printf("%-7s ", "valid");
+ }
+ else
+ {
+ printf("%-7s ", "expired");
+ }
+
+ printf(" %#T ", &acquired, utc);
+ if (released)
+ {
+ printf("%#T ", &released, utc);
+ }
+ else
+ {
+ printf(" ");
+ if (utc)
+ {
+ printf(" ");
+ }
+ }
+ printf("%D\n", identity);
+ DESTROY_IF(address);
+ identity->destroy(identity);
+ }
+ query->destroy(query);
+ if (!found)
+ {
+ fprintf(stderr, "no matching leases found.\n");
+ exit(-1);
+ }
+ exit(0);
+}
+
+/**
+ * ipsec pool --purge - delete expired leases
+ */
+static void purge(char *name)
+{
+ enumerator_t *query;
+ u_int id, timeout, purged = 0;
+
+ query = db->query(db, "SELECT id, timeout FROM pools WHERE name = ?",
+ DB_TEXT, name, DB_UINT, DB_UINT);
+ if (!query)
+ {
+ fprintf(stderr, "purging pool failed.\n");
+ exit(-1);
+ }
+ /* we have to keep one lease if we purge. It wouldn't be reallocateable
+ * as we move on the "next" address for speedy allocation */
+ if (query->enumerate(query, &id, &timeout))
+ {
+ timeout = time(NULL) - timeout;
+ purged = db->execute(db, NULL,
+ "DELETE FROM leases WHERE pool = ? "
+ "AND released IS NOT NULL AND released < ? AND id NOT IN ("
+ " SELECT id FROM leases "
+ " WHERE released IS NOT NULL and released < ? "
+ " GROUP BY address)",
+ DB_UINT, id, DB_UINT, timeout, DB_UINT, timeout);
+ }
+ query->destroy(query);
+ fprintf(stderr, "purged %d leases in pool '%s'.\n", purged, name);
+ exit(0);
+}
+
+/**
+ * atexit handler to close db on shutdown
+ */
+static void cleanup(void)
+{
+ db->destroy(db);
+ DESTROY_IF(start);
+ DESTROY_IF(end);
+}
+
+/**
+ * Logging hook for library logs, using stderr output
+ */
+static void dbg_stderr(int level, char *fmt, ...)
+{
+ va_list args;
+
+ if (level <= 1)
+ {
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ va_end(args);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ char *uri, *name = "", *filter = "";
+ int timeout = 0;
+ bool utc = FALSE;
+ enum {
+ OP_USAGE,
+ OP_STATUS,
+ OP_ADD,
+ OP_DEL,
+ OP_RESIZE,
+ OP_LEASES,
+ OP_PURGE,
+ } operation = OP_USAGE;
+
+ dbg = dbg_stderr;
+ library_init(STRONGSWAN_CONF);
+ atexit(library_deinit);
+ lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
+ lib->settings->get_str(lib->settings, "pool.load", PLUGINS));
+
+ uri = lib->settings->get_str(lib->settings, "charon.plugins.sql.database", NULL);
+ if (!uri)
+ {
+ fprintf(stderr, "database URI charon.plugins.sql.database not set.\n");
+ exit(-1);
+ }
+ db = lib->db->create(lib->db, uri);
+ if (!db)
+ {
+ fprintf(stderr, "opening database failed.\n");
+ exit(-1);
+ }
+ atexit(cleanup);
+
+ while (TRUE)
+ {
+ int c;
+
+ struct option long_opts[] = {
+ { "help", no_argument, NULL, 'h' },
+
+ { "utc", no_argument, NULL, 'u' },
+ { "status", no_argument, NULL, 'w' },
+ { "add", required_argument, NULL, 'a' },
+ { "del", required_argument, NULL, 'd' },
+ { "resize", required_argument, NULL, 'r' },
+ { "leases", no_argument, NULL, 'l' },
+ { "purge", required_argument, NULL, 'p' },
+
+ { "start", required_argument, NULL, 's' },
+ { "end", required_argument, NULL, 'e' },
+ { "timeout", required_argument, NULL, 't' },
+ { "filter", required_argument, NULL, 'f' },
+ { 0,0,0,0 }
+ };
+
+ c = getopt_long(argc, argv, "", long_opts, NULL);
+ switch (c)
+ {
+ case EOF:
+ break;
+ case 'h':
+ break;
+ case 'w':
+ operation = OP_STATUS;
+ break;
+ case 'u':
+ utc = TRUE;
+ continue;
+ case 'a':
+ operation = OP_ADD;
+ name = optarg;
+ continue;
+ case 'd':
+ operation = OP_DEL;
+ name = optarg;
+ continue;
+ case 'r':
+ operation = OP_RESIZE;
+ name = optarg;
+ continue;
+ case 'l':
+ operation = OP_LEASES;
+ continue;
+ case 'p':
+ operation = OP_PURGE;
+ name = optarg;
+ continue;
+ case 's':
+ start = host_create_from_string(optarg, 0);
+ if (start == NULL)
+ {
+ fprintf(stderr, "invalid start address: '%s'.\n", optarg);
+ operation = OP_USAGE;
+ break;
+ }
+ continue;
+ case 'e':
+ end = host_create_from_string(optarg, 0);
+ if (end == NULL)
+ {
+ fprintf(stderr, "invalid end address: '%s'.\n", optarg);
+ operation = OP_USAGE;
+ break;
+ }
+ continue;
+ case 't':
+ timeout = atoi(optarg);
+ if (timeout == 0 && strcmp(optarg, "0") != 0)
+ {
+ fprintf(stderr, "invalid timeout '%s'.\n", optarg);
+ operation = OP_USAGE;
+ break;
+ }
+ continue;
+ case 'f':
+ filter = optarg;
+ continue;
+ default:
+ operation = OP_USAGE;
+ break;
+ }
+ break;
+ }
+
+ switch (operation)
+ {
+ case OP_USAGE:
+ usage();
+ break;
+ case OP_STATUS:
+ status();
+ break;
+ case OP_ADD:
+ if (start == NULL || end == NULL)
+ {
+ fprintf(stderr, "missing arguments.\n");
+ usage();
+ }
+ add(name, start, end, timeout);
+ break;
+ case OP_DEL:
+ del(name);
+ break;
+ case OP_RESIZE:
+ if (end == NULL)
+ {
+ fprintf(stderr, "missing arguments.\n");
+ usage();
+ }
+ resize(name, end);
+ break;
+ case OP_LEASES:
+ leases(filter, utc);
+ break;
+ case OP_PURGE:
+ purge(name);
+ break;
+ }
+ exit(0);
+}
+
diff --git a/src/charon/plugins/sql/sql_attribute.c b/src/charon/plugins/sql/sql_attribute.c
new file mode 100644
index 000000000..45c0750c7
--- /dev/null
+++ b/src/charon/plugins/sql/sql_attribute.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "sql_attribute.h"
+
+#include <daemon.h>
+#include <utils/mutex.h>
+
+typedef struct private_sql_attribute_t private_sql_attribute_t;
+
+/**
+ * private data of sql_attribute
+ */
+struct private_sql_attribute_t {
+
+ /**
+ * public functions
+ */
+ sql_attribute_t public;
+
+ /**
+ * database connection
+ */
+ database_t *db;
+
+ /**
+ * mutex to simulate transactions
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * convert a address blob to an ip of the correct family
+ */
+static host_t *ip_from_chunk(chunk_t address)
+{
+ switch (address.len)
+ {
+ case 4:
+ return host_create_from_chunk(AF_INET, address, 0);
+ case 16:
+ return host_create_from_chunk(AF_INET6, address, 0);
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * increment a chunk, as it would reprensent a network order integer
+ */
+static void increment_chunk(chunk_t chunk)
+{
+ int i;
+
+ for (i = chunk.len - 1; i >= 0; i++)
+ {
+ if (++chunk.ptr[i] != 0)
+ {
+ return;
+ }
+ }
+}
+
+/**
+ * Lookup if we have an existing lease
+ */
+static host_t* get_lease(private_sql_attribute_t *this,
+ char *name, identification_t *id)
+{
+ enumerator_t *e;
+ chunk_t address;
+ host_t *ip = NULL;
+ int lease;
+
+ /* transaction simulation, see create_lease() */
+ this->mutex->lock(this->mutex);
+
+ /* select a lease for "id" which still valid */
+ e = this->db->query(this->db,
+ "SELECT l.id, l.address FROM leases AS l "
+ "JOIN pools AS p ON l.pool = p.id "
+ "JOIN identities AS i ON l.identity = i.id "
+ "WHERE p.name = ? AND i.type = ? AND i.data = ? "
+ "AND (l.released IS NULL OR p.timeout = 0 "
+ " OR (l.released >= (? - p.timeout))) "
+ "ORDER BY l.acquired LIMIT 1", DB_TEXT, name,
+ DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
+ DB_UINT, time(NULL),
+ DB_UINT, DB_BLOB);
+ if (e)
+ {
+ if (e->enumerate(e, &lease, &address))
+ {
+ /* found one, set the lease to active */
+ if (this->db->execute(this->db, NULL,
+ "UPDATE leases SET released = NULL WHERE id = ?",
+ DB_UINT, lease) > 0)
+ {
+ ip = ip_from_chunk(address);
+ DBG1(DBG_CFG, "reassigning address from valid lease "
+ "from pool '%s'", name);
+ }
+ }
+ e->destroy(e);
+ }
+ this->mutex->unlock(this->mutex);
+ return ip;
+}
+
+/**
+ * Create a new lease entry for client
+ */
+static host_t* create_lease(private_sql_attribute_t *this,
+ char *name, identification_t *id)
+{
+ enumerator_t *e;
+ chunk_t address;
+ host_t *ip = NULL;
+ u_int pool, identity = 0, released, timeout;
+ bool new = FALSE;
+
+ /* we currently do not use database transactions. While this would be
+ * the clean way, there is no real advantage, but some disadvantages:
+ * - we would require InnoDB for mysql, as MyISAM does not support trans.
+ * - the mysql plugin uses connection pooling, and we would need a
+ * mechanism to lock transactions to a single connection.
+ */
+ this->mutex->lock(this->mutex);
+
+ /* find an address which has outdated leases only. The HAVING clause filters
+ * out leases which are active (released = NULL) or not expired */
+ e = this->db->query(this->db,
+ "SELECT pool, address, released, timeout FROM leases "
+ "JOIN pools ON leases.pool = pools.id "
+ "WHERE name = ? and timeout > 0 "
+ "GROUP BY address HAVING COUNT(released) = COUNT(*) "
+ "AND MAX(released) < (? - timeout) LIMIT 1",
+ DB_TEXT, name, DB_UINT, time(NULL),
+ DB_UINT, DB_BLOB, DB_UINT, DB_UINT);
+
+ if (!e || !e->enumerate(e, &pool, &address, &released, &timeout))
+ {
+ DESTROY_IF(e);
+ /* no outdated lease found, acquire new address */
+ e = this->db->query(this->db,
+ "SELECT id, next FROM pools WHERE name = ? AND next <= end",
+ DB_TEXT, name,
+ DB_UINT, DB_BLOB);
+ if (!e || !e->enumerate(e, &pool, &address))
+ {
+ /* pool seems full */
+ DESTROY_IF(e);
+ this->mutex->unlock(this->mutex);
+ return NULL;
+ }
+ new = TRUE;
+ }
+ address = chunk_clonea(address);
+ e->destroy(e);
+
+ /* look for peer identity in the identities table */
+ e = this->db->query(this->db,
+ "SELECT id FROM identities WHERE type = ? AND data = ?",
+ DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
+ DB_UINT);
+ if (!e || !e->enumerate(e, &identity))
+ {
+ DESTROY_IF(e);
+ /* not found, insert new one */
+ this->db->execute(this->db, &identity,
+ "INSERT INTO identities (type, data) VALUES (?, ?)",
+ DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id));
+ }
+ else
+ {
+ e->destroy(e);
+ }
+ /* if we have an identity, insert a new lease */
+ if (identity)
+ {
+ if (this->db->execute(this->db, NULL,
+ "INSERT INTO leases (pool, address, identity, acquired) "
+ "VALUES (?, ?, ?, ?)",
+ DB_UINT, pool, DB_BLOB, address, DB_UINT, identity,
+ DB_UINT, time(NULL)) > 0)
+ {
+ ip = ip_from_chunk(address);
+ if (new)
+ { /* update next address, as we have consumed one */
+ increment_chunk(address);
+ this->db->execute(this->db, NULL,
+ "UPDATE pools SET next = ? WHERE id = ?",
+ DB_BLOB, address, DB_UINT, pool);
+ DBG1(DBG_CFG, "assigning lease with new address "
+ "from pool '%s'", name);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "reassigning address from expired lease "
+ "from pool '%s'", name);
+ }
+ }
+ }
+ this->mutex->unlock(this->mutex);
+ return ip;
+}
+
+/**
+ * Implementation of attribute_provider_t.acquire_address
+ */
+static host_t* acquire_address(private_sql_attribute_t *this,
+ char *name, identification_t *id,
+ auth_info_t *auth, host_t *requested)
+{
+ host_t *ip;
+
+ ip = get_lease(this, name, id);
+ if (!ip)
+ {
+ ip = create_lease(this, name, id);
+ }
+ return ip;
+}
+
+/**
+ * Implementation of attribute_provider_t.release_address
+ */
+static bool release_address(private_sql_attribute_t *this,
+ char *name, host_t *address)
+{
+ if (this->db->execute(this->db, NULL,
+ "UPDATE leases SET released = ? WHERE "
+ "pool IN (SELECT id FROM pools WHERE name = ?) AND "
+ "address = ? AND released IS NULL",
+ DB_UINT, time(NULL),
+ DB_TEXT, name, DB_BLOB, address->get_address(address)) > 0)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of sql_attribute_t.destroy
+ */
+static void destroy(private_sql_attribute_t *this)
+{
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+sql_attribute_t *sql_attribute_create(database_t *db)
+{
+ private_sql_attribute_t *this = malloc_thing(private_sql_attribute_t);
+
+ this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,auth_info_t *, host_t *))acquire_address;
+ this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *))release_address;
+ this->public.destroy = (void(*)(sql_attribute_t*))destroy;
+
+ this->db = db;
+ this->mutex = mutex_create(MUTEX_DEFAULT);
+
+ /* close any "online" leases in the case we crashed */
+ this->db->execute(this->db, NULL,
+ "UPDATE leases SET released = ? WHERE released IS NULL",
+ DB_UINT, time(NULL));
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/sql/sql_attribute.h b/src/charon/plugins/sql/sql_attribute.h
new file mode 100644
index 000000000..211204ced
--- /dev/null
+++ b/src/charon/plugins/sql/sql_attribute.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup sql_attribute sql_attribute
+ * @{ @ingroup sql
+ */
+
+#ifndef SQL_ATTRIBUTE_H_
+#define SQL_ATTRIBUTE_H_
+
+#include <config/attributes/attribute_provider.h>
+
+typedef struct sql_attribute_t sql_attribute_t;
+
+/**
+ * SQL database based IKEv2 cfg attribute provider.
+ */
+struct sql_attribute_t {
+
+ /**
+ * Implements attribute provider interface
+ */
+ attribute_provider_t provider;
+
+ /**
+ * Destroy a sql_attribute instance.
+ */
+ void (*destroy)(sql_attribute_t *this);
+};
+
+/**
+ * Create a sql_attribute instance.
+ */
+sql_attribute_t *sql_attribute_create(database_t *db);
+
+#endif /* SQL_ATTRIBUTE_H_ @}*/
diff --git a/src/charon/plugins/sql/sql_config.c b/src/charon/plugins/sql/sql_config.c
new file mode 100644
index 000000000..3785839cf
--- /dev/null
+++ b/src/charon/plugins/sql/sql_config.c
@@ -0,0 +1,517 @@
+/*
+ * Copyright (C) 2006-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: sql_config.c 4044 2008-06-06 15:05:54Z martin $
+ */
+
+#include <string.h>
+
+#include "sql_config.h"
+
+#include <daemon.h>
+
+typedef struct private_sql_config_t private_sql_config_t;
+
+/**
+ * Private data of an sql_config_t object
+ */
+struct private_sql_config_t {
+
+ /**
+ * Public part
+ */
+ sql_config_t public;
+
+ /**
+ * database connection
+ */
+ database_t *db;
+};
+
+/**
+ * forward declaration
+ */
+static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
+ identification_t *me, identification_t *other);
+
+/**
+ * build a traffic selector from a SQL query
+ */
+static traffic_selector_t *build_traffic_selector(private_sql_config_t *this,
+ enumerator_t *e, bool *local)
+{
+ int type, protocol, start_port, end_port;
+ chunk_t start_addr, end_addr;
+ traffic_selector_t *ts;
+ enum {
+ TS_LOCAL = 0,
+ TS_REMOTE = 1,
+ TS_LOCAL_DYNAMIC = 2,
+ TS_REMOTE_DYNAMIC = 3,
+ } kind;
+
+ while (e->enumerate(e, &kind, &type, &protocol,
+ &start_addr, &end_addr, &start_port, &end_port))
+ {
+ *local = FALSE;
+ switch (kind)
+ {
+ case TS_LOCAL:
+ *local = TRUE;
+ /* FALL */
+ case TS_REMOTE:
+ ts = traffic_selector_create_from_bytes(protocol, type,
+ start_addr, start_port, end_addr, end_port);
+ break;
+ case TS_LOCAL_DYNAMIC:
+ *local = TRUE;
+ /* FALL */
+ case TS_REMOTE_DYNAMIC:
+ ts = traffic_selector_create_dynamic(protocol,
+ start_port, end_port);
+ break;
+ default:
+ continue;
+ }
+ if (ts)
+ {
+ return ts;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Add traffic selectors to a child config
+ */
+static void add_traffic_selectors(private_sql_config_t *this,
+ child_cfg_t *child, int id)
+{
+ enumerator_t *e;
+ traffic_selector_t *ts;
+ bool local;
+
+ e = this->db->query(this->db,
+ "SELECT kind, type, protocol, "
+ "start_addr, end_addr, start_port, end_port "
+ "FROM traffic_selectors JOIN child_config_traffic_selector "
+ "ON id = traffic_selector WHERE child_cfg = ?",
+ DB_INT, id,
+ DB_INT, DB_INT, DB_INT,
+ DB_BLOB, DB_BLOB, DB_INT, DB_INT);
+ if (e)
+ {
+ while ((ts = build_traffic_selector(this, e, &local)))
+ {
+ child->add_traffic_selector(child, local, ts);
+ }
+ e->destroy(e);
+ }
+}
+
+/**
+ * build a Child configuration from a SQL query
+ */
+static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
+{
+ int id, lifetime, rekeytime, jitter, hostaccess, mode, dpd, close, ipcomp;
+ char *name, *updown;
+ child_cfg_t *child_cfg;
+
+ if (e->enumerate(e, &id, &name, &lifetime, &rekeytime, &jitter,
+ &updown, &hostaccess, &mode, &dpd, &close, &ipcomp))
+ {
+ child_cfg = child_cfg_create(name, lifetime, rekeytime, jitter,
+ updown, hostaccess, mode, dpd, close, ipcomp);
+ /* TODO: read proposal from db */
+ child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+ add_traffic_selectors(this, child_cfg, id);
+ return child_cfg;
+ }
+ return NULL;
+}
+
+/**
+ * Add child configs to peer config
+ */
+static void add_child_cfgs(private_sql_config_t *this, peer_cfg_t *peer, int id)
+{
+ enumerator_t *e;
+ child_cfg_t *child_cfg;
+
+ e = this->db->query(this->db,
+ "SELECT id, name, lifetime, rekeytime, jitter, "
+ "updown, hostaccess, mode, dpd_action, close_action, ipcomp "
+ "FROM child_configs JOIN peer_config_child_config ON id = child_cfg "
+ "WHERE peer_cfg = ?",
+ DB_INT, id,
+ DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT,
+ DB_TEXT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT);
+ if (e)
+ {
+ while ((child_cfg = build_child_cfg(this, e)))
+ {
+ peer->add_child_cfg(peer, child_cfg);
+ }
+ e->destroy(e);
+ }
+}
+
+/**
+ * build a ike configuration from a SQL query
+ */
+static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
+ host_t *my_host, host_t *other_host)
+{
+ int certreq, force_encap;
+ char *local, *remote;
+
+ while (e->enumerate(e, &certreq, &force_encap, &local, &remote))
+ {
+ ike_cfg_t *ike_cfg;
+
+ ike_cfg = ike_cfg_create(certreq, force_encap, local, remote);
+ /* TODO: read proposal from db */
+ ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+ return ike_cfg;
+ }
+ return NULL;
+}
+
+/**
+ * Query a IKE config by its id
+ */
+static ike_cfg_t* get_ike_cfg_by_id(private_sql_config_t *this, int id)
+{
+ enumerator_t *e;
+ ike_cfg_t *ike_cfg = NULL;
+
+ e = this->db->query(this->db,
+ "SELECT certreq, force_encap, local, remote "
+ "FROM ike_configs WHERE id = ?",
+ DB_INT, id,
+ DB_INT, DB_INT, DB_TEXT, DB_TEXT);
+ if (e)
+ {
+ ike_cfg = build_ike_cfg(this, e, NULL, NULL);
+ e->destroy(e);
+ }
+ return ike_cfg;
+}
+
+/**
+ * Query a peer config by its id
+ */
+static peer_cfg_t *get_peer_cfg_by_id(private_sql_config_t *this, int id)
+{
+ enumerator_t *e;
+ peer_cfg_t *peer_cfg = NULL;
+
+ e = this->db->query(this->db,
+ "SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
+ "cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
+ "keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
+ "dpd_delay, virtual, pool, "
+ "mediation, mediated_by, COALESCE(p.type, 0), p.data "
+ "FROM peer_configs AS c "
+ "JOIN identities AS l ON local_id = l.id "
+ "JOIN identities AS r ON remote_id = r.id "
+ "LEFT JOIN identities AS p ON peer_id = p.id "
+ "WHERE id = ?",
+ DB_INT, id,
+ DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
+ DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_TEXT, DB_TEXT,
+ DB_INT, DB_INT, DB_INT, DB_BLOB);
+ if (e)
+ {
+ peer_cfg = build_peer_cfg(this, e, NULL, NULL);
+ e->destroy(e);
+ }
+ return peer_cfg;
+}
+
+/**
+ * build a peer configuration from a SQL query
+ */
+static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
+ identification_t *me, identification_t *other)
+{
+ int id, ike_cfg, l_type, r_type,
+ cert_policy, uniqueid, auth_method, eap_type, eap_vendor, keyingtries,
+ rekeytime, reauthtime, jitter, overtime, mobike, dpd_delay,
+ mediation, mediated_by, p_type;
+ chunk_t l_data, r_data, p_data;
+ char *name, *virtual, *pool;
+
+ while (e->enumerate(e,
+ &id, &name, &ike_cfg, &l_type, &l_data, &r_type, &r_data,
+ &cert_policy, &uniqueid, &auth_method, &eap_type, &eap_vendor,
+ &keyingtries, &rekeytime, &reauthtime, &jitter, &overtime, &mobike,
+ &dpd_delay, &virtual, &pool,
+ &mediation, &mediated_by, &p_type, &p_data))
+ {
+ identification_t *local_id, *remote_id, *peer_id = NULL;
+ peer_cfg_t *peer_cfg, *mediated_cfg;
+ ike_cfg_t *ike;
+ host_t *vip = NULL;
+
+ local_id = identification_create_from_encoding(l_type, l_data);
+ remote_id = identification_create_from_encoding(r_type, r_data);
+ if ((me && !me->matches(me, local_id)) ||
+ (other && !other->matches(other, remote_id)))
+ {
+ local_id->destroy(local_id);
+ remote_id->destroy(remote_id);
+ continue;
+ }
+ ike = get_ike_cfg_by_id(this, ike_cfg);
+ mediated_cfg = mediated_by ? get_peer_cfg_by_id(this, mediated_by) : NULL;
+ if (p_type)
+ {
+ peer_id = identification_create_from_encoding(p_type, p_data);
+ }
+ if (virtual)
+ {
+ vip = host_create_from_string(virtual, 0);
+ }
+ if (ike)
+ {
+ peer_cfg = peer_cfg_create(
+ name, 2, ike, local_id, remote_id, cert_policy, uniqueid,
+ auth_method, eap_type, eap_vendor, keyingtries,
+ rekeytime, reauthtime, jitter, overtime, mobike,
+ dpd_delay, vip, pool,
+ mediation, mediated_cfg, peer_id);
+ add_child_cfgs(this, peer_cfg, id);
+ return peer_cfg;
+ }
+ DESTROY_IF(ike);
+ DESTROY_IF(mediated_cfg);
+ DESTROY_IF(peer_id);
+ DESTROY_IF(local_id);
+ DESTROY_IF(remote_id);
+ }
+ return NULL;
+}
+
+/**
+ * implements backend_t.get_peer_cfg_by_name.
+ */
+static peer_cfg_t *get_peer_cfg_by_name(private_sql_config_t *this, char *name)
+{
+ enumerator_t *e;
+ peer_cfg_t *peer_cfg = NULL;
+
+ e = this->db->query(this->db,
+ "SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
+ "cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
+ "keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
+ "dpd_delay, virtual, pool, "
+ "mediation, mediated_by, COALESCE(p.type, 0), p.data "
+ "FROM peer_configs AS c "
+ "JOIN identities AS l ON local_id = l.id "
+ "JOIN identities AS r ON remote_id = r.id "
+ "LEFT JOIN identities AS p ON peer_id = p.id "
+ "WHERE ike_version = ? AND name = ?",
+ DB_INT, 2, DB_TEXT, name,
+ DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
+ DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_TEXT, DB_TEXT,
+ DB_INT, DB_INT, DB_INT, DB_BLOB);
+ if (e)
+ {
+ peer_cfg = build_peer_cfg(this, e, NULL, NULL);
+ e->destroy(e);
+ }
+ return peer_cfg;
+}
+
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** reference to context */
+ private_sql_config_t *this;
+ /** filtering own host */
+ host_t *me;
+ /** filtering remote host */
+ host_t *other;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** currently enumerated peer config */
+ ike_cfg_t *current;
+} ike_enumerator_t;
+
+/**
+ * Implementation of ike_enumerator_t.public.enumerate
+ */
+static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg)
+{
+ DESTROY_IF(this->current);
+ this->current = build_ike_cfg(this->this, this->inner, this->me, this->other);
+ if (this->current)
+ {
+ *cfg = this->current;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of ike_enumerator_t.public.destroy
+ */
+static void ike_enumerator_destroy(ike_enumerator_t *this)
+{
+ DESTROY_IF(this->current);
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+/**
+ * Implementation of backend_t.create_ike_cfg_enumerator.
+ */
+static enumerator_t* create_ike_cfg_enumerator(private_sql_config_t *this,
+ host_t *me, host_t *other)
+{
+ ike_enumerator_t *e = malloc_thing(ike_enumerator_t);
+
+ e->this = this;
+ e->me = me;
+ e->other = other;
+ e->current = NULL;
+ e->public.enumerate = (void*)ike_enumerator_enumerate;
+ e->public.destroy = (void*)ike_enumerator_destroy;
+
+ e->inner = this->db->query(this->db,
+ "SELECT certreq, force_encap, local, remote "
+ "FROM ike_configs",
+ DB_INT, DB_INT, DB_TEXT, DB_TEXT);
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** reference to context */
+ private_sql_config_t *this;
+ /** filtering own identity */
+ identification_t *me;
+ /** filtering remote identity */
+ identification_t *other;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** currently enumerated peer config */
+ peer_cfg_t *current;
+} peer_enumerator_t;
+
+/**
+ * Implementation of peer_enumerator_t.public.enumerate
+ */
+static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
+{
+ DESTROY_IF(this->current);
+ this->current = build_peer_cfg(this->this, this->inner, this->me, this->other);
+ if (this->current)
+ {
+ *cfg = this->current;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of peer_enumerator_t.public.destroy
+ */
+static void peer_enumerator_destroy(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_sql_config_t *this,
+ identification_t *me,
+ identification_t *other)
+{
+ peer_enumerator_t *e = malloc_thing(peer_enumerator_t);
+
+ e->this = this;
+ e->me = me;
+ e->other = other;
+ e->current = NULL;
+ e->public.enumerate = (void*)peer_enumerator_enumerate;
+ e->public.destroy = (void*)peer_enumerator_destroy;
+
+ /* TODO: only get configs whose IDs match exactly or contain wildcards */
+ e->inner = this->db->query(this->db,
+ "SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
+ "cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
+ "keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
+ "dpd_delay, virtual, pool, "
+ "mediation, mediated_by, COALESCE(p.type, 0), p.data "
+ "FROM peer_configs AS c "
+ "JOIN identities AS l ON local_id = l.id "
+ "JOIN identities AS r ON remote_id = r.id "
+ "LEFT JOIN identities AS p ON peer_id = p.id "
+ "WHERE ike_version = ?",
+ DB_INT, 2,
+ DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
+ DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+ DB_INT, DB_TEXT, DB_TEXT,
+ DB_INT, DB_INT, DB_INT, DB_BLOB);
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * Implementation of sql_config_t.destroy.
+ */
+static void destroy(private_sql_config_t *this)
+{
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+sql_config_t *sql_config_create(database_t *db)
+{
+ private_sql_config_t *this = malloc_thing(private_sql_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(*)(sql_config_t*))destroy;
+
+ this->db = db;
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/sql/sql_config.h b/src/charon/plugins/sql/sql_config.h
new file mode 100644
index 000000000..d34705c71
--- /dev/null
+++ b/src/charon/plugins/sql/sql_config.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: sql_config.h 3594 2008-03-13 14:53:57Z martin $
+ */
+
+/**
+ * @defgroup sql_config_i sql_config
+ * @{ @ingroup sql
+ */
+
+#ifndef SQL_CONFIG_H_
+#define SQL_CONFIG_H_
+
+#include <config/backend.h>
+#include <database/database.h>
+
+typedef struct sql_config_t sql_config_t;
+
+/**
+ * SQL database configuration backend.
+ */
+struct sql_config_t {
+
+ /**
+ * Implements backend_t interface
+ */
+ backend_t backend;
+
+ /**
+ * Destry the backend.
+ */
+ void (*destroy)(sql_config_t *this);
+};
+
+/**
+ * Create a sql_config backend instance.
+ *
+ * @param db underlying database
+ * @return backend instance
+ */
+sql_config_t *sql_config_create(database_t *db);
+
+#endif /* SQL_CONFIG_H_ @}*/
diff --git a/src/charon/plugins/sql/sql_cred.c b/src/charon/plugins/sql/sql_cred.c
new file mode 100644
index 000000000..9d91973c2
--- /dev/null
+++ b/src/charon/plugins/sql/sql_cred.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: sql_cred.c 3589 2008-03-13 14:14:44Z martin $
+ */
+
+#include <string.h>
+
+#include "sql_cred.h"
+
+#include <daemon.h>
+
+typedef struct private_sql_cred_t private_sql_cred_t;
+
+/**
+ * Private data of an sql_cred_t object
+ */
+struct private_sql_cred_t {
+
+ /**
+ * Public part
+ */
+ sql_cred_t public;
+
+ /**
+ * database connection
+ */
+ database_t *db;
+};
+
+/**
+ * enumerator over private keys
+ */
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** currently enumerated private key */
+ 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)
+{
+ chunk_t blob;
+ int type;
+
+ DESTROY_IF(this->current);
+ while (this->inner->enumerate(this->inner, &type, &blob))
+ {
+ this->current = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
+ BUILD_BLOB_ASN1_DER, chunk_clone(blob),
+ BUILD_END);
+ if (this->current)
+ {
+ *key = this->current;
+ return TRUE;
+ }
+ }
+ this->current = NULL;
+ return FALSE;
+}
+
+/**
+ * Implementation of private_enumerator_t.public.destroy
+ */
+static void private_enumerator_destroy(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_sql_cred_t *this,
+ key_type_t type,
+ identification_t *id)
+{
+ private_enumerator_t *e;
+
+ e = malloc_thing(private_enumerator_t);
+ e->current = NULL;
+ e->public.enumerate = (void*)private_enumerator_enumerate;
+ e->public.destroy = (void*)private_enumerator_destroy;
+ if (id && id->get_type(id) != ID_ANY)
+ {
+ e->inner = this->db->query(this->db,
+ "SELECT p.type, p.data FROM private_keys AS p "
+ "JOIN private_key_identity AS pi ON p.id = pi.private_key "
+ "JOIN identities AS i ON pi.identity = i.id "
+ "WHERE i.type = ? AND i.data = ? AND (? OR p.type = ?)",
+ DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
+ DB_INT, type == KEY_ANY, DB_INT, type,
+ DB_INT, DB_BLOB);
+ }
+ else
+ {
+ e->inner = this->db->query(this->db,
+ "SELECT type, data FROM private_keys WHERE (? OR type = ?)",
+ DB_INT, type == KEY_ANY, DB_INT, type,
+ DB_INT, DB_BLOB);
+ }
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * enumerator over certificates
+ */
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** currently enumerated cert */
+ certificate_t *current;
+} cert_enumerator_t;
+
+/**
+ * Implementation of cert_enumerator_t.public.enumerate
+ */
+static bool cert_enumerator_enumerate(cert_enumerator_t *this,
+ certificate_t **cert)
+{
+ chunk_t blob;
+ int type;
+
+ DESTROY_IF(this->current);
+ while (this->inner->enumerate(this->inner, &type, &blob))
+ {
+ this->current = lib->creds->create(lib->creds, CRED_CERTIFICATE, type,
+ BUILD_BLOB_ASN1_DER, chunk_clone(blob),
+ BUILD_END);
+ if (this->current)
+ {
+ *cert = this->current;
+ return TRUE;
+ }
+ }
+ this->current = NULL;
+ return FALSE;
+}
+
+/**
+ * Implementation of cert_enumerator_t.public.destroy
+ */
+static void cert_enumerator_destroy(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_sql_cred_t *this,
+ certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
+{
+ cert_enumerator_t *e;
+
+ e = malloc_thing(cert_enumerator_t);
+ e->current = NULL;
+ e->public.enumerate = (void*)cert_enumerator_enumerate;
+ e->public.destroy = (void*)cert_enumerator_destroy;
+ if (id && id->get_type(id) != ID_ANY)
+ {
+ e->inner = this->db->query(this->db,
+ "SELECT c.type, c.data FROM certificates AS c "
+ "JOIN certificate_identity AS ci ON c.id = ci.certificate "
+ "JOIN identities AS i ON ci.identity = i.id "
+ "WHERE i.type = ? AND i.data = ? AND "
+ "(? OR c.type = ?) AND (? OR c.keytype = ?)",
+ DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
+ DB_INT, cert == CERT_ANY, DB_INT, cert,
+ DB_INT, key == KEY_ANY, DB_INT, key,
+ DB_INT, DB_BLOB);
+ }
+ else
+ {
+ e->inner = this->db->query(this->db,
+ "SELECT type, data FROM certificates WHERE "
+ "(? OR type = ?) AND (? OR keytype = ?)",
+ DB_INT, cert == CERT_ANY, DB_INT, cert,
+ DB_INT, key == KEY_ANY, DB_INT, key,
+ DB_INT, DB_BLOB);
+ }
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * enumerator over shared keys
+ */
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** own identity */
+ identification_t *me;
+ /** remote identity */
+ identification_t *other;
+ /** currently enumerated private key */
+ shared_key_t *current;
+} shared_enumerator_t;
+
+/**
+ * Implementation of shared_enumerator_t.public.enumerate
+ */
+static bool shared_enumerator_enumerate(shared_enumerator_t *this,
+ shared_key_t **shared,
+ id_match_t *me, id_match_t *other)
+{
+ chunk_t blob;
+ int type;
+
+ DESTROY_IF(this->current);
+ while (this->inner->enumerate(this->inner, &type, &blob))
+ {
+ this->current = shared_key_create(type, chunk_clone(blob));
+ if (this->current)
+ {
+ *shared = this->current;
+ if (me)
+ {
+ *me = this->me ? ID_MATCH_PERFECT : ID_MATCH_ANY;
+ }
+ if (other)
+ {
+ *other = this->other ? ID_MATCH_PERFECT : ID_MATCH_ANY;
+ }
+ return TRUE;
+ }
+ }
+ this->current = NULL;
+ return FALSE;
+}
+
+/**
+ * Implementation of shared_enumerator_t.public.destroy
+ */
+static void shared_enumerator_destroy(shared_enumerator_t *this)
+{
+ DESTROY_IF(this->current);
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+/**
+ * Implementation of credential_set_t.create_shared_enumerator.
+ */
+static enumerator_t* create_shared_enumerator(private_sql_cred_t *this,
+ shared_key_type_t type,
+ identification_t *me, identification_t *other)
+{
+ shared_enumerator_t *e;
+
+ e = malloc_thing(shared_enumerator_t);
+ e->me = me;
+ e->other = other;
+ e->current = NULL;
+ e->public.enumerate = (void*)shared_enumerator_enumerate;
+ e->public.destroy = (void*)shared_enumerator_destroy;
+ if (!me && !other)
+ {
+ e->inner = this->db->query(this->db,
+ "SELECT type, data FROM shared_secrets WHERE (? OR type = ?)",
+ DB_INT, type == SHARED_ANY, DB_INT, type,
+ DB_INT, DB_BLOB);
+ }
+ else if (me && other)
+ {
+ e->inner = this->db->query(this->db,
+ "SELECT s.type, s.data FROM shared_secrets AS s "
+ "JOIN shared_secret_identity AS sm ON s.id = sm.shared_secret "
+ "JOIN identities AS m ON sm.identity = m.id "
+ "JOIN shared_secret_identity AS so ON s.id = so.shared_secret "
+ "JOIN identities AS o ON so.identity = o.id "
+ "WHERE m.type = ? AND m.data = ? AND o.type = ? AND o.data = ? "
+ "AND (? OR s.type = ?)",
+ DB_INT, me->get_type(me), DB_BLOB, me->get_encoding(me),
+ DB_INT, other->get_type(other), DB_BLOB, other->get_encoding(other),
+ DB_INT, type == SHARED_ANY, DB_INT, type,
+ DB_INT, DB_BLOB);
+ }
+ else
+ {
+ identification_t *id = me ? me : other;
+
+ e->inner = this->db->query(this->db,
+ "SELECT s.type, s.data FROM shared_secrets AS s "
+ "JOIN shared_secret_identity AS si ON s.id = si.shared_secret "
+ "JOIN identities AS i ON si.identity = i.id "
+ "WHERE i.type = ? AND i.data = ? AND (? OR s.type = ?)",
+ DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
+ DB_INT, type == SHARED_ANY, DB_INT, type,
+ DB_INT, DB_BLOB);
+ }
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * Implementation of credential_set_t.cache_cert.
+ */
+static void cache_cert(private_sql_cred_t *this, certificate_t *cert)
+{
+ /* TODO: implement CRL caching to database */
+}
+
+/**
+ * Implementation of sql_cred_t.destroy.
+ */
+static void destroy(private_sql_cred_t *this)
+{
+ free(this);
+}
+/**
+ * Described in header.
+ */
+sql_cred_t *sql_cred_create(database_t *db)
+{
+ private_sql_cred_t *this = malloc_thing(private_sql_cred_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*)cache_cert;
+ this->public.destroy = (void(*)(sql_cred_t*))destroy;
+
+ this->db = db;
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/sql/sql_cred.h b/src/charon/plugins/sql/sql_cred.h
new file mode 100644
index 000000000..e251abe00
--- /dev/null
+++ b/src/charon/plugins/sql/sql_cred.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: sql_cred.h 3594 2008-03-13 14:53:57Z martin $
+ */
+
+/**
+ * @defgroup sql_cred_i sql_cred
+ * @{ @ingroup sql
+ */
+
+#ifndef SQL_CRED_H_
+#define SQL_CRED_H_
+
+#include <credentials/credential_set.h>
+#include <database/database.h>
+
+typedef struct sql_cred_t sql_cred_t;
+
+/**
+ * SQL database credential set.
+ */
+struct sql_cred_t {
+
+ /**
+ * Implements credential_set_t interface
+ */
+ credential_set_t set;
+
+ /**
+ * Destry the backend.
+ */
+ void (*destroy)(sql_cred_t *this);
+};
+
+/**
+ * Create a sql_cred backend instance.
+ *
+ * @param db underlying database
+ * @return credential set
+ */
+sql_cred_t *sql_cred_create(database_t *db);
+
+#endif /* SQL_CRED_H_ @}*/
diff --git a/src/charon/plugins/sql/sql_logger.c b/src/charon/plugins/sql/sql_logger.c
new file mode 100644
index 000000000..2fb5844b3
--- /dev/null
+++ b/src/charon/plugins/sql/sql_logger.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: sql_logger.c 3589 2008-03-13 14:14:44Z martin $
+ */
+
+#include <string.h>
+
+#include "sql_logger.h"
+
+#include <daemon.h>
+
+typedef struct private_sql_logger_t private_sql_logger_t;
+
+/**
+ * Private data of an sql_logger_t object
+ */
+struct private_sql_logger_t {
+
+ /**
+ * Public part
+ */
+ sql_logger_t public;
+
+ /**
+ * database connection
+ */
+ database_t *db;
+
+ /**
+ * logging level
+ */
+ int level;
+
+ /**
+ * avoid recursive logging
+ */
+ bool recursive;
+};
+
+
+/**
+ * Implementation of bus_listener_t.signal.
+ */
+static bool signal_(private_sql_logger_t *this, signal_t signal, level_t level,
+ int thread, ike_sa_t* ike_sa, char *format, va_list args)
+{
+ if (this->recursive)
+ {
+ return TRUE;
+ }
+ this->recursive = TRUE;
+
+ if (ike_sa && level <= this->level)
+ {
+ char buffer[8192];
+ chunk_t local_spi, remote_spi;
+ host_t *local_host, *remote_host;
+ identification_t *local_id, *remote_id;
+ u_int64_t ispi, rspi;
+ ike_sa_id_t *id;
+
+ id = ike_sa->get_id(ike_sa);
+ ispi = id->get_initiator_spi(id);
+ rspi = id->get_responder_spi(id);
+ if (id->is_initiator(id))
+ {
+ local_spi.ptr = (char*)&ispi;
+ remote_spi.ptr = (char*)&rspi;
+ }
+ else
+ {
+ local_spi.ptr = (char*)&rspi;
+ remote_spi.ptr = (char*)&ispi;
+ }
+ local_spi.len = remote_spi.len = sizeof(ispi);
+ local_id = ike_sa->get_my_id(ike_sa);
+ remote_id = ike_sa->get_other_id(ike_sa);
+ local_host = ike_sa->get_my_host(ike_sa);
+ remote_host = ike_sa->get_other_host(ike_sa);
+
+ vsnprintf(buffer, sizeof(buffer), format, args);
+
+ this->db->execute(this->db, NULL, "REPLACE INTO ike_sas ("
+ "local_spi, remote_spi, id, initiator, "
+ "local_id_type, local_id_data, "
+ "remote_id_type, remote_id_data, "
+ "host_family, local_host_data, remote_host_data) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ DB_BLOB, local_spi, DB_BLOB, remote_spi,
+ DB_INT, ike_sa->get_unique_id(ike_sa),
+ DB_INT, id->is_initiator(id),
+ DB_INT, local_id->get_type(local_id),
+ DB_BLOB, local_id->get_encoding(local_id),
+ DB_INT, remote_id->get_type(remote_id),
+ DB_BLOB, remote_id->get_encoding(remote_id),
+ DB_INT, local_host->get_family(local_host),
+ DB_BLOB, local_host->get_address(local_host),
+ DB_BLOB, remote_host->get_address(remote_host));
+ this->db->execute(this->db, NULL, "INSERT INTO logs ("
+ "local_spi, signal, level, msg) VALUES (?, ?, ?, ?)",
+ DB_BLOB, local_spi, DB_INT, signal, DB_INT, level,
+ DB_TEXT, buffer);
+ }
+ this->recursive = FALSE;
+ /* always stay registered */
+ return TRUE;
+}
+
+/**
+ * Implementation of sql_logger_t.destroy.
+ */
+static void destroy(private_sql_logger_t *this)
+{
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+sql_logger_t *sql_logger_create(database_t *db)
+{
+ private_sql_logger_t *this = malloc_thing(private_sql_logger_t);
+
+ this->public.listener.signal = (bool(*)(bus_listener_t*,signal_t,level_t,int,ike_sa_t*,char*,va_list))signal_;
+ 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);
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/sql/sql_logger.h b/src/charon/plugins/sql/sql_logger.h
new file mode 100644
index 000000000..30507bcaf
--- /dev/null
+++ b/src/charon/plugins/sql/sql_logger.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: sql_logger.h 3594 2008-03-13 14:53:57Z martin $
+ */
+
+/**
+ * @defgroup sql_logger_i sql_logger
+ * @{ @ingroup sql
+ */
+
+#ifndef SQL_LOGGER_H_
+#define SQL_LOGGER_H_
+
+#include <bus/bus.h>
+#include <database/database.h>
+
+typedef struct sql_logger_t sql_logger_t;
+
+/**
+ * SQL database logger.
+ */
+struct sql_logger_t {
+
+ /**
+ * Implements bus_listener_t interface
+ */
+ bus_listener_t listener;
+
+ /**
+ * Destry the backend.
+ */
+ void (*destroy)(sql_logger_t *this);
+};
+
+/**
+ * Create a sql_logger instance.
+ *
+ * @param db underlying database
+ * @return logger instance
+ */
+sql_logger_t *sql_logger_create(database_t *db);
+
+#endif /* SQL_LOGGER_H_ @}*/
diff --git a/src/charon/plugins/sql/sql_plugin.c b/src/charon/plugins/sql/sql_plugin.c
new file mode 100644
index 000000000..8c4f20f74
--- /dev/null
+++ b/src/charon/plugins/sql/sql_plugin.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: sql_plugin.c 3826 2008-04-17 15:08:48Z martin $
+ */
+
+#include "sql_plugin.h"
+
+#include <daemon.h>
+#include "sql_config.h"
+#include "sql_cred.h"
+#include "sql_attribute.h"
+#include "sql_logger.h"
+
+typedef struct private_sql_plugin_t private_sql_plugin_t;
+
+/**
+ * private data of sql plugin
+ */
+struct private_sql_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ sql_plugin_t public;
+
+ /**
+ * database connection instance
+ */
+ database_t *db;
+
+ /**
+ * configuration backend
+ */
+ sql_config_t *config;
+
+ /**
+ * credential set
+ */
+ sql_cred_t *cred;
+
+ /**
+ * CFG attributes
+ */
+ sql_attribute_t *attribute;
+
+ /**
+ * bus listener/logger
+ */
+ sql_logger_t *logger;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_sql_plugin_t *this)
+{
+ charon->backends->remove_backend(charon->backends, &this->config->backend);
+ charon->credentials->remove_set(charon->credentials, &this->cred->set);
+ charon->bus->remove_listener(charon->bus, &this->logger->listener);
+ this->config->destroy(this->config);
+ this->cred->destroy(this->cred);
+ this->attribute->destroy(this->attribute);
+ this->logger->destroy(this->logger);
+ this->db->destroy(this->db);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ char *uri;
+ private_sql_plugin_t *this;
+
+ uri = lib->settings->get_str(lib->settings, "charon.plugins.sql.database", NULL);
+ if (!uri)
+ {
+ DBG1(DBG_CFG, "sql plugin: database URI not set");
+ return NULL;
+ }
+
+ this = malloc_thing(private_sql_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ this->db = lib->db->create(lib->db, uri);
+ if (!this->db)
+ {
+ DBG1(DBG_CFG, "sql plugin failed to connect to database");
+ free(this);
+ return NULL;
+ }
+ this->config = sql_config_create(this->db);
+ this->cred = sql_cred_create(this->db);
+ this->attribute = sql_attribute_create(this->db);
+ this->logger = sql_logger_create(this->db);
+
+ charon->backends->add_backend(charon->backends, &this->config->backend);
+ charon->credentials->add_set(charon->credentials, &this->cred->set);
+ charon->attributes->add_provider(charon->attributes, &this->attribute->provider);
+ charon->bus->add_listener(charon->bus, &this->logger->listener);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/sql/sql_plugin.h b/src/charon/plugins/sql/sql_plugin.h
new file mode 100644
index 000000000..8a7ba3e85
--- /dev/null
+++ b/src/charon/plugins/sql/sql_plugin.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: sql_plugin.h 3577 2008-03-12 14:38:35Z martin $
+ */
+
+/**
+ * @defgroup sql sql
+ * @ingroup cplugins
+ *
+ * @defgroup sql_plugin sql_plugin
+ * @{ @ingroup sql
+ */
+
+#ifndef SQL_PLUGIN_H_
+#define SQL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sql_plugin_t sql_plugin_t;
+
+/**
+ * SQL database configuration plugin
+ */
+struct sql_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a sql_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SQL_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/stroke/Makefile.am b/src/charon/plugins/stroke/Makefile.am
new file mode 100644
index 000000000..7a341102b
--- /dev/null
+++ b/src/charon/plugins/stroke/Makefile.am
@@ -0,0 +1,19 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke
+
+AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
+
+plugin_LTLIBRARIES = libstrongswan-stroke.la
+
+libstrongswan_stroke_la_SOURCES = stroke_plugin.h stroke_plugin.c \
+ stroke_socket.h stroke_socket.c \
+ stroke_config.h stroke_config.c \
+ stroke_control.h stroke_control.c \
+ stroke_cred.h stroke_cred.c \
+ stroke_ca.h stroke_ca.c \
+ stroke_attribute.h stroke_attribute.c \
+ stroke_list.h stroke_list.c \
+ stroke_shared_key.h stroke_shared_key.c
+
+libstrongswan_stroke_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/stroke/Makefile.in b/src/charon/plugins/stroke/Makefile.in
new file mode 100644
index 000000000..a528377d0
--- /dev/null
+++ b/src/charon/plugins/stroke/Makefile.in
@@ -0,0 +1,513 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@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/charon/plugins/stroke
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_stroke_la_LIBADD =
+am_libstrongswan_stroke_la_OBJECTS = stroke_plugin.lo stroke_socket.lo \
+ stroke_config.lo stroke_control.lo stroke_cred.lo stroke_ca.lo \
+ stroke_attribute.lo stroke_list.lo stroke_shared_key.lo
+libstrongswan_stroke_la_OBJECTS = \
+ $(am_libstrongswan_stroke_la_OBJECTS)
+libstrongswan_stroke_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_stroke_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+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_stroke_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_stroke_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+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_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke
+AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
+plugin_LTLIBRARIES = libstrongswan-stroke.la
+libstrongswan_stroke_la_SOURCES = stroke_plugin.h stroke_plugin.c \
+ stroke_socket.h stroke_socket.c \
+ stroke_config.h stroke_config.c \
+ stroke_control.h stroke_control.c \
+ stroke_cred.h stroke_cred.c \
+ stroke_ca.h stroke_ca.c \
+ stroke_attribute.h stroke_attribute.c \
+ stroke_list.h stroke_list.c \
+ stroke_shared_key.h stroke_shared_key.c
+
+libstrongswan_stroke_la_LDFLAGS = -module
+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 \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/stroke/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/stroke/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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-stroke.la: $(libstrongswan_stroke_la_OBJECTS) $(libstrongswan_stroke_la_DEPENDENCIES)
+ $(libstrongswan_stroke_la_LINK) -rpath $(plugindir) $(libstrongswan_stroke_la_OBJECTS) $(libstrongswan_stroke_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_attribute.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_ca.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_config.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_control.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_cred.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_list.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_shared_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_socket.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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)
+
+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-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
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-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/charon/plugins/stroke/stroke_attribute.c b/src/charon/plugins/stroke/stroke_attribute.c
new file mode 100644
index 000000000..71b56bc8a
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_attribute.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "stroke_attribute.h"
+
+#include <daemon.h>
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+
+#define POOL_LIMIT 16
+
+typedef struct private_stroke_attribute_t private_stroke_attribute_t;
+
+/**
+ * private data of stroke_attribute
+ */
+struct private_stroke_attribute_t {
+
+ /**
+ * public functions
+ */
+ stroke_attribute_t public;
+
+ /**
+ * list of pools, contains pool_t
+ */
+ linked_list_t *pools;
+
+ /**
+ * mutex to lock access to pools
+ */
+ mutex_t *mutex;
+};
+
+typedef struct {
+ /** name of the pool */
+ char *name;
+ /** base address of the pool */
+ host_t *base;
+ /** number of entries in the pool */
+ int count;
+ /** array of in-use flags, TODO: use bit fields */
+ u_int8_t *in_use;
+} pool_t;
+
+/**
+ * destroy a pool_t
+ */
+static void pool_destroy(pool_t *this)
+{
+ DESTROY_IF(this->base);
+ free(this->name);
+ free(this->in_use);
+ free(this);
+}
+
+/**
+ * find a pool by name
+ */
+static pool_t *find_pool(private_stroke_attribute_t *this, char *name)
+{
+ enumerator_t *enumerator;
+ pool_t *current, *found = NULL;
+
+ enumerator = this->pools->create_enumerator(this->pools);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (streq(name, current->name))
+ {
+ found = current;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found;
+}
+
+/**
+ * convert an pool offset to an address
+ */
+host_t* offset2host(pool_t *pool, int offset)
+{
+ chunk_t addr;
+ host_t *host;
+ u_int32_t *pos;
+
+ if (offset > pool->count)
+ {
+ return NULL;
+ }
+
+ addr = chunk_clone(pool->base->get_address(pool->base));
+ if (pool->base->get_family(pool->base) == AF_INET6)
+ {
+ pos = (u_int32_t*)(addr.ptr + 12);
+ }
+ else
+ {
+ pos = (u_int32_t*)addr.ptr;
+ }
+ *pos = htonl(offset + ntohl(*pos));
+ host = host_create_from_chunk(pool->base->get_family(pool->base), addr, 0);
+ free(addr.ptr);
+ return host;
+}
+
+/**
+ * convert a host to a pool offset
+ */
+int host2offset(pool_t *pool, host_t *addr)
+{
+ chunk_t host, base;
+ u_int32_t hosti, basei;
+
+ if (addr->get_family(addr) != pool->base->get_family(pool->base))
+ {
+ return -1;
+ }
+ host = addr->get_address(addr);
+ base = pool->base->get_address(pool->base);
+ if (addr->get_family(addr) == AF_INET6)
+ {
+ /* only look at last /32 block */
+ if (!memeq(host.ptr, base.ptr, 12))
+ {
+ return -1;
+ }
+ host = chunk_skip(host, 12);
+ base = chunk_skip(base, 12);
+ }
+ hosti = ntohl(*(u_int32_t*)(host.ptr));
+ basei = ntohl(*(u_int32_t*)(base.ptr));
+ if (hosti > basei + pool->count)
+ {
+ return -1;
+ }
+ return hosti - basei;
+}
+
+/**
+ * Implementation of attribute_provider_t.acquire_address
+ */
+static host_t* acquire_address(private_stroke_attribute_t *this,
+ char *name, identification_t *id,
+ auth_info_t *auth, host_t *requested)
+{
+ pool_t *pool;
+ host_t *host = NULL;
+ int i;
+
+ this->mutex->lock(this->mutex);
+ pool = find_pool(this, name);
+ if (pool)
+ {
+ if (requested && !requested->is_anyaddr(requested))
+ {
+ if (pool->count == 0)
+ { /* %config, give any */
+ host = requested->clone(requested);
+ }
+ else
+ {
+ i = host2offset(pool, requested);
+ if (i >= 0 && !pool->in_use[i])
+ {
+ pool->in_use[i] = TRUE;
+ host = requested->clone(requested);
+ }
+ }
+ }
+ if (!host)
+ {
+ for (i = 0; i < pool->count; i++)
+ {
+ if (!pool->in_use[i])
+ {
+ pool->in_use[i] = TRUE;
+ host = offset2host(pool, i);
+ break;
+ }
+ }
+ }
+ }
+ this->mutex->unlock(this->mutex);
+ return host;
+}
+
+/**
+ * Implementation of attribute_provider_t.release_address
+ */
+static bool release_address(private_stroke_attribute_t *this,
+ char *name, host_t *address)
+{
+ pool_t *pool;
+ bool found = FALSE;
+ int i;
+
+ this->mutex->lock(this->mutex);
+ pool = find_pool(this, name);
+ if (pool)
+ {
+ if (pool->count != 0)
+ {
+ i = host2offset(pool, address);
+ if (i >= 0 && pool->in_use[i])
+ {
+ pool->in_use[i] = FALSE;
+ found = TRUE;
+ }
+ }
+ }
+ this->mutex->unlock(this->mutex);
+ return found;
+}
+
+/**
+ * Implementation of stroke_attribute_t.add_pool.
+ */
+static void add_pool(private_stroke_attribute_t *this, stroke_msg_t *msg)
+{
+ if (msg->add_conn.other.sourceip_size)
+ {
+ pool_t *pool;
+
+ if (msg->add_conn.other.sourceip)
+ {
+ u_int32_t bits;
+ int family;
+
+ DBG1(DBG_CFG, "adding virtual IP address pool '%s': %s/%d",
+ msg->add_conn.name, msg->add_conn.other.sourceip,
+ msg->add_conn.other.sourceip_size);
+
+ pool = malloc_thing(pool_t);
+ pool->base = host_create_from_string(msg->add_conn.other.sourceip, 0);
+ if (!pool->base)
+ {
+ free(pool);
+ DBG1(DBG_CFG, "virtual IP address invalid, discarded");
+ return;
+ }
+ pool->name = strdup(msg->add_conn.name);
+ family = pool->base->get_family(pool->base);
+ bits = (family == AF_INET ? 32 : 128) - msg->add_conn.other.sourceip_size;
+ if (bits > POOL_LIMIT)
+ {
+ bits = POOL_LIMIT;
+ DBG1(DBG_CFG, "virtual IP pool to large, limiting to %s/%d",
+ msg->add_conn.other.sourceip,
+ (family == AF_INET ? 32 : 128) - bits);
+ }
+ pool->count = 1 << (bits);
+ pool->in_use = calloc(pool->count, sizeof(u_int8_t));
+
+ if (pool->count > 2)
+ { /* do not use first and last addresses of a block */
+ pool->in_use[0] = TRUE;
+ pool->in_use[pool->count-1] = TRUE;
+ }
+ }
+ else
+ { /* %config, add an empty pool */
+ pool = malloc_thing(pool_t);
+ pool->name = strdup(msg->add_conn.name);
+ pool->base = NULL;
+ pool->count = 0;
+ pool->in_use = NULL;
+ }
+ this->mutex->lock(this->mutex);
+ this->pools->insert_last(this->pools, pool);
+ this->mutex->unlock(this->mutex);
+ }
+}
+
+/**
+ * Implementation of stroke_attribute_t.del_pool.
+ */
+static void del_pool(private_stroke_attribute_t *this, stroke_msg_t *msg)
+{
+ enumerator_t *enumerator;
+ pool_t *pool;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->pools->create_enumerator(this->pools);
+ while (enumerator->enumerate(enumerator, &pool))
+ {
+ if (streq(msg->del_conn.name, pool->name))
+ {
+ this->pools->remove_at(this->pools, enumerator);
+ pool_destroy(pool);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of stroke_attribute_t.destroy
+ */
+static void destroy(private_stroke_attribute_t *this)
+{
+ this->mutex->destroy(this->mutex);
+ this->pools->destroy_function(this->pools, (void*)pool_destroy);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+stroke_attribute_t *stroke_attribute_create()
+{
+ private_stroke_attribute_t *this = malloc_thing(private_stroke_attribute_t);
+
+ this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,auth_info_t *, host_t *))acquire_address;
+ this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *))release_address;
+ this->public.add_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))add_pool;
+ this->public.del_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))del_pool;
+ this->public.destroy = (void(*)(stroke_attribute_t*))destroy;
+
+ this->pools = linked_list_create();
+ this->mutex = mutex_create(MUTEX_DEFAULT);
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/stroke/stroke_attribute.h b/src/charon/plugins/stroke/stroke_attribute.h
new file mode 100644
index 000000000..f871d5a13
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_attribute.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup stroke_attribute stroke_attribute
+ * @{ @ingroup stroke
+ */
+
+#ifndef STROKE_ATTRIBUTE_H_
+#define STROKE_ATTRIBUTE_H_
+
+#include <stroke_msg.h>
+#include <config/attributes/attribute_provider.h>
+
+typedef struct stroke_attribute_t stroke_attribute_t;
+
+/**
+ * Stroke IKEv2 cfg attribute provider
+ */
+struct stroke_attribute_t {
+
+ /**
+ * Implements attribute provider interface
+ */
+ attribute_provider_t provider;
+
+ /**
+ * Add a virtual IP address.
+ *
+ * @param msg stroke message
+ * @param end end of stroke message that contains virtual IP.
+ */
+ void (*add_pool)(stroke_attribute_t *this, stroke_msg_t *msg);
+
+ /**
+ * Remove a virtual IP address.
+ *
+ * @param msg stroke message
+ */
+ void (*del_pool)(stroke_attribute_t *this, stroke_msg_t *msg);
+
+ /**
+ * Destroy a stroke_attribute instance.
+ */
+ void (*destroy)(stroke_attribute_t *this);
+};
+
+/**
+ * Create a stroke_attribute instance.
+ */
+stroke_attribute_t *stroke_attribute_create();
+
+#endif /* STROKE_ATTRIBUTE_H_ @}*/
diff --git a/src/charon/plugins/stroke/stroke_ca.c b/src/charon/plugins/stroke/stroke_ca.c
new file mode 100644
index 000000000..897365eb0
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_ca.c
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "stroke_ca.h"
+#include "stroke_cred.h"
+
+#include <utils/mutex.h>
+#include <utils/linked_list.h>
+#include <crypto/hashers/hasher.h>
+
+#include <daemon.h>
+
+typedef struct private_stroke_ca_t private_stroke_ca_t;
+
+/**
+ * private data of stroke_ca
+ */
+struct private_stroke_ca_t {
+
+ /**
+ * public functions
+ */
+ stroke_ca_t public;
+
+ /**
+ * mutex to lock access to list
+ */
+ mutex_t *mutex;
+
+ /**
+ * list of starters CA sections and its certificates (ca_section_t)
+ */
+ linked_list_t *sections;
+
+ /**
+ * stroke credentials, stores our CA certificates
+ */
+ stroke_cred_t *cred;
+};
+
+typedef struct ca_section_t ca_section_t;
+
+/**
+ * loaded ipsec.conf CA sections
+ */
+struct ca_section_t {
+
+ /**
+ * name of the CA section
+ */
+ char *name;
+
+ /**
+ * reference to cert in trusted_credential_t
+ */
+ certificate_t *cert;
+
+ /**
+ * CRL URIs
+ */
+ linked_list_t *crl;
+
+ /**
+ * OCSP URIs
+ */
+ linked_list_t *ocsp;
+
+ /**
+ * Hashes of certificates issued by this CA
+ */
+ linked_list_t *hashes;
+
+ /**
+ * Base URI used for certificates from this CA
+ */
+ char *certuribase;
+};
+
+/**
+ * create a new CA section
+ */
+static ca_section_t *ca_section_create(char *name, certificate_t *cert)
+{
+ ca_section_t *ca = malloc_thing(ca_section_t);
+
+ ca->name = strdup(name);
+ ca->crl = linked_list_create();
+ ca->ocsp = linked_list_create();
+ ca->cert = cert;
+ ca->hashes = linked_list_create();
+ ca->certuribase = NULL;
+ return ca;
+}
+
+/**
+ * destroy a ca section entry
+ */
+static void ca_section_destroy(ca_section_t *this)
+{
+ this->crl->destroy_function(this->crl, free);
+ this->ocsp->destroy_function(this->ocsp, free);
+ this->hashes->destroy_offset(this->hashes, offsetof(identification_t, destroy));
+ free(this->certuribase);
+ free(this->name);
+ free(this);
+}
+
+/**
+ * data to pass to create_inner_cdp
+ */
+typedef struct {
+ private_stroke_ca_t *this;
+ certificate_type_t type;
+ identification_t *id;
+} cdp_data_t;
+
+/**
+ * destroy cdp enumerator data and unlock list
+ */
+static void cdp_data_destroy(cdp_data_t *data)
+{
+ data->this->mutex->unlock(data->this->mutex);
+ free(data);
+}
+
+/**
+ * inner enumerator constructor for CDP URIs
+ */
+static enumerator_t *create_inner_cdp(ca_section_t *section, cdp_data_t *data)
+{
+ public_key_t *public;
+ identification_t *keyid;
+ enumerator_t *enumerator = NULL;
+ linked_list_t *list;
+
+ if (data->type == CERT_X509_OCSP_RESPONSE)
+ {
+ list = section->ocsp;
+ }
+ else
+ {
+ list = section->crl;
+ }
+
+ public = section->cert->get_public_key(section->cert);
+ if (public)
+ {
+ if (!data->id)
+ {
+ enumerator = list->create_enumerator(list);
+ }
+ else
+ {
+ keyid = public->get_id(public, data->id->get_type(data->id));
+ if (keyid && keyid->matches(keyid, data->id))
+ {
+ enumerator = list->create_enumerator(list);
+ }
+ }
+ public->destroy(public);
+ }
+ return enumerator;
+}
+
+/**
+ * inner enumerator constructor for "Hash and URL"
+ */
+static enumerator_t *create_inner_cdp_hashandurl(ca_section_t *section, cdp_data_t *data)
+{
+ enumerator_t *enumerator = NULL, *hash_enum;
+ identification_t *current;
+
+ if (!data->id || !section->certuribase)
+ {
+ return NULL;
+ }
+
+ hash_enum = section->hashes->create_enumerator(section->hashes);
+ while (hash_enum->enumerate(hash_enum, &current))
+ {
+ if (current->matches(current, data->id))
+ {
+ char *url, *hash;
+
+ url = malloc(strlen(section->certuribase) + 40 + 1);
+ strcpy(url, section->certuribase);
+ hash = chunk_to_hex(current->get_encoding(current), NULL, FALSE).ptr;
+ strncat(url, hash, 40);
+ free(hash);
+
+ enumerator = enumerator_create_single(url, free);
+ break;
+ }
+ }
+ hash_enum->destroy(hash_enum);
+ return enumerator;
+}
+
+/**
+ * Implementation of credential_set_t.create_cdp_enumerator.
+ */
+static enumerator_t *create_cdp_enumerator(private_stroke_ca_t *this,
+ certificate_type_t type, identification_t *id)
+{
+ cdp_data_t *data;
+
+ switch (type)
+ { /* we serve CRLs, OCSP responders and URLs for "Hash and URL" */
+ case CERT_X509:
+ case CERT_X509_CRL:
+ case CERT_X509_OCSP_RESPONSE:
+ case CERT_ANY:
+ break;
+ default:
+ return NULL;
+ }
+ data = malloc_thing(cdp_data_t);
+ data->this = this;
+ data->type = type;
+ data->id = id;
+
+ this->mutex->lock(this->mutex);
+ return enumerator_create_nested(this->sections->create_enumerator(this->sections),
+ (type == CERT_X509) ? (void*)create_inner_cdp_hashandurl : (void*)create_inner_cdp,
+ data, (void*)cdp_data_destroy);
+}
+/**
+ * Implementation of stroke_ca_t.add.
+ */
+static void add(private_stroke_ca_t *this, stroke_msg_t *msg)
+{
+ certificate_t *cert;
+ ca_section_t *ca;
+
+ if (msg->add_ca.cacert == NULL)
+ {
+ DBG1(DBG_CFG, "missing cacert parameter");
+ return;
+ }
+ cert = this->cred->load_ca(this->cred, msg->add_ca.cacert);
+ if (cert)
+ {
+ ca = ca_section_create(msg->add_ca.name, cert);
+ if (msg->add_ca.crluri)
+ {
+ ca->crl->insert_last(ca->crl, strdup(msg->add_ca.crluri));
+ }
+ if (msg->add_ca.crluri2)
+ {
+ ca->crl->insert_last(ca->crl, strdup(msg->add_ca.crluri2));
+ }
+ if (msg->add_ca.ocspuri)
+ {
+ ca->ocsp->insert_last(ca->ocsp, strdup(msg->add_ca.ocspuri));
+ }
+ if (msg->add_ca.ocspuri2)
+ {
+ ca->ocsp->insert_last(ca->ocsp, strdup(msg->add_ca.ocspuri2));
+ }
+ if (msg->add_ca.certuribase)
+ {
+ ca->certuribase = strdup(msg->add_ca.certuribase);
+ }
+ this->mutex->lock(this->mutex);
+ this->sections->insert_last(this->sections, ca);
+ this->mutex->unlock(this->mutex);
+ DBG1(DBG_CFG, "added ca '%s'", msg->add_ca.name);
+ }
+}
+
+/**
+ * Implementation of stroke_ca_t.del.
+ */
+static void del(private_stroke_ca_t *this, stroke_msg_t *msg)
+{
+ enumerator_t *enumerator;
+ ca_section_t *ca = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->sections->create_enumerator(this->sections);
+ while (enumerator->enumerate(enumerator, &ca))
+ {
+ if (streq(ca->name, msg->del_ca.name))
+ {
+ this->sections->remove_at(this->sections, enumerator);
+ break;
+ }
+ ca = NULL;
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ if (ca == NULL)
+ {
+ DBG1(DBG_CFG, "no ca named '%s' found\n", msg->del_ca.name);
+ return;
+ }
+ ca_section_destroy(ca);
+ /* TODO: flush cached certs */
+}
+
+/**
+ * list crl or ocsp URIs
+ */
+static void list_uris(linked_list_t *list, char *label, FILE *out)
+{
+ bool first = TRUE;
+ char *uri;
+ enumerator_t *enumerator;
+
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, (void**)&uri))
+ {
+ if (first)
+ {
+ fprintf(out, label);
+ first = FALSE;
+ }
+ else
+ {
+ fprintf(out, " ");
+ }
+ fprintf(out, "'%s'\n", uri);
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * Implementation of stroke_ca_t.check_for_hash_and_url.
+ */
+static void check_for_hash_and_url(private_stroke_ca_t *this, certificate_t* cert)
+{
+ ca_section_t *section;
+ enumerator_t *enumerator;
+
+ hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher == NULL)
+ {
+ DBG1(DBG_IKE, "unable to use hash-and-url: sha1 not supported");
+ return;
+ }
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->sections->create_enumerator(this->sections);
+ while (enumerator->enumerate(enumerator, (void**)&section))
+ {
+ if (section->certuribase && cert->issued_by(cert, section->cert))
+ {
+ chunk_t hash, encoded = cert->get_encoding(cert);
+ hasher->allocate_hash(hasher, encoded, &hash);
+ section->hashes->insert_last(section->hashes,
+ identification_create_from_encoding(ID_CERT_DER_SHA1, hash));
+ chunk_free(&hash);
+ chunk_free(&encoded);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+
+ hasher->destroy(hasher);
+}
+
+/**
+ * Implementation of stroke_ca_t.list.
+ */
+static void list(private_stroke_ca_t *this, stroke_msg_t *msg, FILE *out)
+{
+ bool first = TRUE;
+ ca_section_t *section;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->sections->create_enumerator(this->sections);
+ while (enumerator->enumerate(enumerator, (void**)&section))
+ {
+ certificate_t *cert = section->cert;
+ public_key_t *public = cert->get_public_key(cert);
+
+ if (first)
+ {
+ fprintf(out, "\n");
+ fprintf(out, "List of CA Information Sections:\n");
+ first = FALSE;
+ }
+ fprintf(out, "\n");
+ fprintf(out, " authname: \"%D\"\n", cert->get_subject(cert));
+
+ /* list authkey and keyid */
+ if (public)
+ {
+ fprintf(out, " authkey: %D\n",
+ public->get_id(public, ID_PUBKEY_SHA1));
+ fprintf(out, " keyid: %D\n",
+ public->get_id(public, ID_PUBKEY_INFO_SHA1));
+ public->destroy(public);
+ }
+ list_uris(section->crl, " crluris: ", out);
+ list_uris(section->ocsp, " ocspuris: ", out);
+ if (section->certuribase)
+ {
+ fprintf(out, " certuribase: '%s'\n", section->certuribase);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of stroke_ca_t.destroy
+ */
+static void destroy(private_stroke_ca_t *this)
+{
+ this->sections->destroy_function(this->sections, (void*)ca_section_destroy);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+stroke_ca_t *stroke_ca_create(stroke_cred_t *cred)
+{
+ private_stroke_ca_t *this = malloc_thing(private_stroke_ca_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*)create_cdp_enumerator;
+ this->public.set.cache_cert = (void*)nop;
+ this->public.add = (void(*)(stroke_ca_t*, stroke_msg_t *msg))add;
+ this->public.del = (void(*)(stroke_ca_t*, stroke_msg_t *msg))del;
+ this->public.list = (void(*)(stroke_ca_t*, stroke_msg_t *msg, FILE *out))list;
+ this->public.check_for_hash_and_url = (void(*)(stroke_ca_t*, certificate_t*))check_for_hash_and_url;
+ this->public.destroy = (void(*)(stroke_ca_t*))destroy;
+
+ this->sections = linked_list_create();
+ this->mutex = mutex_create(MUTEX_RECURSIVE);
+ this->cred = cred;
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/stroke/stroke_ca.h b/src/charon/plugins/stroke/stroke_ca.h
new file mode 100644
index 000000000..882446afe
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_ca.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup stroke_ca stroke_ca
+ * @{ @ingroup stroke
+ */
+
+#ifndef STROKE_CA_H_
+#define STROKE_CA_H_
+
+#include <stroke_msg.h>
+
+#include "stroke_cred.h"
+
+typedef struct stroke_ca_t stroke_ca_t;
+
+/**
+ * ipsec.conf ca section handling.
+ */
+struct stroke_ca_t {
+
+ /**
+ * Implements credential_set_t
+ */
+ credential_set_t set;
+
+ /**
+ * Add a CA to the set using a stroke_msg_t.
+ *
+ * @param msg stroke message containing CA info
+ */
+ void (*add)(stroke_ca_t *this, stroke_msg_t *msg);
+
+ /**
+ * Remove a CA from the set using a stroke_msg_t.
+ *
+ * @param msg stroke message containing CA info
+ */
+ void (*del)(stroke_ca_t *this, stroke_msg_t *msg);
+
+ /**
+ * List CA sections to stroke console.
+ *
+ * @param msg stroke message
+ */
+ void (*list)(stroke_ca_t *this, stroke_msg_t *msg, FILE *out);
+
+ /**
+ * Check if a certificate can be made available through hash and URL.
+ *
+ * @param cert peer certificate
+ */
+ void (*check_for_hash_and_url)(stroke_ca_t *this, certificate_t* cert);
+
+ /**
+ * Destroy a stroke_ca instance.
+ */
+ void (*destroy)(stroke_ca_t *this);
+};
+
+/**
+ * Create a stroke_ca instance.
+ */
+stroke_ca_t *stroke_ca_create(stroke_cred_t *cred);
+
+#endif /* STROKE_CA_H_ @}*/
diff --git a/src/charon/plugins/stroke/stroke_config.c b/src/charon/plugins/stroke/stroke_config.c
new file mode 100644
index 000000000..0069191b5
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_config.c
@@ -0,0 +1,844 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "stroke_config.h"
+
+#include <daemon.h>
+#include <utils/mutex.h>
+
+typedef struct private_stroke_config_t private_stroke_config_t;
+
+/**
+ * private data of stroke_config
+ */
+struct private_stroke_config_t {
+
+ /**
+ * public functions
+ */
+ stroke_config_t public;
+
+ /**
+ * list of peer_cfg_t
+ */
+ linked_list_t *list;
+
+ /**
+ * mutex to lock config list
+ */
+ mutex_t *mutex;
+
+ /**
+ * ca sections
+ */
+ stroke_ca_t *ca;
+
+ /**
+ * credentials
+ */
+ stroke_cred_t *cred;
+};
+
+/**
+ * data to pass peer_filter
+ */
+typedef struct {
+ private_stroke_config_t *this;
+ identification_t *me;
+ identification_t *other;
+} peer_data_t;
+
+/**
+ * destroy id enumerator data and unlock list
+ */
+static void peer_data_destroy(peer_data_t *data)
+{
+ data->this->mutex->unlock(data->this->mutex);
+ free(data);
+}
+
+/**
+ * filter function for peer configs
+ */
+static bool peer_filter(peer_data_t *data, peer_cfg_t **in, peer_cfg_t **out)
+{
+ bool match_me = FALSE, match_other = FALSE;
+ identification_t *me, *other;
+
+ me = (*in)->get_my_id(*in);
+ other = (*in)->get_other_id(*in);
+
+ /* own ID may have wildcards in data (no IDr payload) or in config */
+ match_me = (!data->me || data->me->matches(data->me, me) ||
+ me->matches(me, data->me));
+ /* others ID has wildcards in config only */
+ match_other = (!data->other || data->other->matches(data->other, other));
+
+ if (match_me && match_other)
+ {
+ *out = *in;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of backend_t.create_peer_cfg_enumerator.
+ */
+static enumerator_t* create_peer_cfg_enumerator(private_stroke_config_t *this,
+ identification_t *me,
+ identification_t *other)
+{
+ peer_data_t *data;
+
+ data = malloc_thing(peer_data_t);
+ data->this = this;
+ data->me = me;
+ data->other = other;
+
+ this->mutex->lock(this->mutex);
+ return enumerator_create_filter(this->list->create_enumerator(this->list),
+ (void*)peer_filter, data,
+ (void*)peer_data_destroy);
+}
+
+/**
+ * data to pass ike_filter
+ */
+typedef struct {
+ private_stroke_config_t *this;
+ host_t *me;
+ host_t *other;
+} ike_data_t;
+
+/**
+ * destroy id enumerator data and unlock list
+ */
+static void ike_data_destroy(ike_data_t *data)
+{
+ data->this->mutex->unlock(data->this->mutex);
+ free(data);
+}
+
+/**
+ * filter function for ike configs
+ */
+static bool ike_filter(ike_data_t *data, peer_cfg_t **in, ike_cfg_t **out)
+{
+ *out = (*in)->get_ike_cfg(*in);
+ return TRUE;
+}
+
+/**
+ * Implementation of backend_t.create_ike_cfg_enumerator.
+ */
+static enumerator_t* create_ike_cfg_enumerator(private_stroke_config_t *this,
+ host_t *me, host_t *other)
+{
+ ike_data_t *data;
+
+ data = malloc_thing(ike_data_t);
+ data->this = this;
+ data->me = me;
+ data->other = other;
+
+ this->mutex->lock(this->mutex);
+ return enumerator_create_filter(this->list->create_enumerator(this->list),
+ (void*)ike_filter, data,
+ (void*)ike_data_destroy);
+}
+
+/**
+ * implements backend_t.get_peer_cfg_by_name.
+ */
+static peer_cfg_t *get_peer_cfg_by_name(private_stroke_config_t *this, char *name)
+{
+ enumerator_t *e1, *e2;
+ peer_cfg_t *current, *found = NULL;
+ child_cfg_t *child;
+
+ this->mutex->lock(this->mutex);
+ e1 = this->list->create_enumerator(this->list);
+ while (e1->enumerate(e1, &current))
+ {
+ /* compare peer_cfgs name first */
+ if (streq(current->get_name(current), name))
+ {
+ found = current;
+ found->get_ref(found);
+ break;
+ }
+ /* compare all child_cfg names otherwise */
+ e2 = current->create_child_cfg_enumerator(current);
+ while (e2->enumerate(e2, &child))
+ {
+ if (streq(child->get_name(child), name))
+ {
+ found = current;
+ found->get_ref(found);
+ break;
+ }
+ }
+ e2->destroy(e2);
+ if (found)
+ {
+ break;
+ }
+ }
+ e1->destroy(e1);
+ this->mutex->unlock(this->mutex);
+ return found;
+}
+
+/**
+ * check if a certificate has an ID
+ */
+static identification_t *update_peerid(certificate_t *cert, identification_t *id)
+{
+ if (!cert->has_subject(cert, id))
+ {
+ DBG1(DBG_CFG, " peerid %D not confirmed by certificate, "
+ "defaulting to subject DN", id);
+ id->destroy(id);
+ id = cert->get_subject(cert);
+ return id->clone(id);
+ }
+ return id;
+}
+
+/**
+ * parse a proposal string, either into ike_cfg or child_cfg
+ */
+static void add_proposals(private_stroke_config_t *this, char *string,
+ ike_cfg_t *ike_cfg, child_cfg_t *child_cfg)
+{
+ if (string)
+ {
+ char *single;
+ char *strict;
+ proposal_t *proposal;
+ protocol_id_t proto = PROTO_ESP;
+
+ if (ike_cfg)
+ {
+ proto = PROTO_IKE;
+ }
+ strict = string + strlen(string) - 1;
+ if (*strict == '!')
+ {
+ *strict = '\0';
+ }
+ else
+ {
+ strict = NULL;
+ }
+ while ((single = strsep(&string, ",")))
+ {
+ proposal = proposal_create_from_string(proto, single);
+ if (proposal)
+ {
+ if (ike_cfg)
+ {
+ ike_cfg->add_proposal(ike_cfg, proposal);
+ }
+ else
+ {
+ child_cfg->add_proposal(child_cfg, proposal);
+ }
+ continue;
+ }
+ DBG1(DBG_CFG, "skipped invalid proposal string: %s", single);
+ }
+ if (strict)
+ {
+ return;
+ }
+ /* add default porposal to the end if not strict */
+ }
+ if (ike_cfg)
+ {
+ ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+ }
+ else
+ {
+ child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+ }
+}
+
+/**
+ * Build an IKE config from a stroke message
+ */
+static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg)
+{
+ stroke_end_t tmp_end;
+ ike_cfg_t *ike_cfg;
+ char *interface;
+ host_t *host;
+
+ host = host_create_from_dns(msg->add_conn.other.address, 0, 0);
+ if (host)
+ {
+ interface = charon->kernel_interface->get_interface(
+ charon->kernel_interface, host);
+ host->destroy(host);
+ if (interface)
+ {
+ DBG2(DBG_CFG, "left is other host, swapping ends");
+ tmp_end = msg->add_conn.me;
+ msg->add_conn.me = msg->add_conn.other;
+ msg->add_conn.other = tmp_end;
+ free(interface);
+ }
+ else
+ {
+ host = host_create_from_dns(msg->add_conn.me.address, 0, 0);
+ if (host)
+ {
+ interface = charon->kernel_interface->get_interface(
+ charon->kernel_interface, host);
+ host->destroy(host);
+ if (!interface)
+ {
+ DBG1(DBG_CFG, "left nor right host is our side, "
+ "assuming left=local");
+ }
+ else
+ {
+ free(interface);
+ }
+
+ }
+ }
+ }
+ ike_cfg = ike_cfg_create(msg->add_conn.other.sendcert != CERT_NEVER_SEND,
+ msg->add_conn.force_encap,
+ msg->add_conn.me.address,
+ msg->add_conn.other.address);
+ add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL);
+ return ike_cfg;
+}
+/**
+ * build a peer_cfg from a stroke msg
+ */
+static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
+ stroke_msg_t *msg, ike_cfg_t *ike_cfg)
+{
+ identification_t *me, *other, *peer_id = NULL;
+ peer_cfg_t *mediated_by = NULL;
+ host_t *vip = NULL;
+ certificate_t *cert;
+ unique_policy_t unique;
+ u_int32_t rekey = 0, reauth = 0, over, jitter;
+
+ me = identification_create_from_string(msg->add_conn.me.id ?
+ msg->add_conn.me.id : msg->add_conn.me.address);
+ if (!me)
+ {
+ DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.me.id);
+ return NULL;
+ }
+ other = identification_create_from_string(msg->add_conn.other.id ?
+ msg->add_conn.other.id : msg->add_conn.other.address);
+ if (!other)
+ {
+ DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.other.id);
+ me->destroy(me);
+ return NULL;
+ }
+
+
+#ifdef ME
+ if (msg->add_conn.ikeme.mediation && msg->add_conn.ikeme.mediated_by)
+ {
+ DBG1(DBG_CFG, "a mediation connection cannot be a"
+ " mediated connection at the same time, aborting");
+ me->destroy(me);
+ other->destroy(other);
+ return NULL;
+ }
+
+ if (msg->add_conn.ikeme.mediated_by)
+ {
+ mediated_by = charon->backends->get_peer_cfg_by_name(charon->backends,
+ msg->add_conn.ikeme.mediated_by);
+ if (!mediated_by)
+ {
+ DBG1(DBG_CFG, "mediation connection '%s' not found, aborting",
+ msg->add_conn.ikeme.mediated_by);
+ me->destroy(me);
+ other->destroy(other);
+ return NULL;
+ }
+
+ if (!mediated_by->is_mediation(mediated_by))
+ {
+ DBG1(DBG_CFG, "connection '%s' as referred to by '%s' is"
+ "no mediation connection, aborting",
+ msg->add_conn.ikeme.mediated_by, msg->add_conn.name);
+ mediated_by->destroy(mediated_by);
+ me->destroy(me);
+ other->destroy(other);
+ return NULL;
+ }
+ }
+
+ if (msg->add_conn.ikeme.peerid)
+ {
+ peer_id = identification_create_from_string(msg->add_conn.ikeme.peerid);
+ if (!peer_id)
+ {
+ DBG1(DBG_CFG, "invalid peer ID: %s\n", msg->add_conn.ikeme.peerid);
+ mediated_by->destroy(mediated_by);
+ me->destroy(me);
+ other->destroy(other);
+ return NULL;
+ }
+ }
+ else
+ {
+ /* no peer ID supplied, assume right ID */
+ peer_id = other->clone(other);
+ }
+#endif /* ME */
+
+ if (msg->add_conn.me.cert)
+ {
+ cert = this->cred->load_peer(this->cred, msg->add_conn.me.cert);
+ if (cert)
+ {
+ this->ca->check_for_hash_and_url(this->ca, cert);
+ me = update_peerid(cert, me);
+ cert->destroy(cert);
+ }
+ }
+ if (msg->add_conn.other.cert)
+ {
+ cert = this->cred->load_peer(this->cred, msg->add_conn.other.cert);
+ if (cert)
+ {
+ other = update_peerid(cert, other);
+ cert->destroy(cert);
+ }
+ }
+ jitter = msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100;
+ over = msg->add_conn.rekey.margin;
+ if (msg->add_conn.rekey.reauth)
+ {
+ reauth = msg->add_conn.rekey.ike_lifetime - over;
+ }
+ else
+ {
+ rekey = msg->add_conn.rekey.ike_lifetime - over;
+ }
+ if (msg->add_conn.me.sourceip_size)
+ {
+ if (msg->add_conn.me.sourceip)
+ {
+ vip = host_create_from_string(msg->add_conn.me.sourceip, 0);
+ }
+ if (!vip)
+ { /* if it is set to something like %poolname, request an address */
+ if (msg->add_conn.me.subnets)
+ { /* use the same address as in subnet, if any */
+ if (strchr(msg->add_conn.me.subnets, '.'))
+ {
+ vip = host_create_any(AF_INET);
+ }
+ else
+ {
+ vip = host_create_any(AF_INET6);
+ }
+ }
+ else
+ {
+ if (strchr(ike_cfg->get_my_addr(ike_cfg), ':'))
+ {
+ vip = host_create_any(AF_INET6);
+ }
+ else
+ {
+ vip = host_create_any(AF_INET);
+ }
+ }
+ }
+ }
+ switch (msg->add_conn.unique)
+ {
+ case 1: /* yes */
+ case 2: /* replace */
+ unique = UNIQUE_REPLACE;
+ break;
+ case 3: /* keep */
+ unique = UNIQUE_KEEP;
+ break;
+ default: /* no */
+ unique = UNIQUE_NO;
+ break;
+ }
+ if (msg->add_conn.dpd.action == 0)
+ { /* dpdaction=none disables DPD */
+ msg->add_conn.dpd.delay = 0;
+ }
+
+ /* other.sourceip is managed in stroke_attributes. If it is set, we define
+ * the pool name as the connection name, which the attribute provider
+ * uses to serve pool addresses. */
+ return peer_cfg_create(msg->add_conn.name,
+ msg->add_conn.ikev2 ? 2 : 1, ike_cfg, me, other,
+ msg->add_conn.me.sendcert, unique, msg->add_conn.auth_method,
+ msg->add_conn.eap_type, msg->add_conn.eap_vendor,
+ msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
+ msg->add_conn.mobike, msg->add_conn.dpd.delay,
+ vip, msg->add_conn.other.sourceip_size ?
+ msg->add_conn.name : msg->add_conn.other.sourceip,
+ msg->add_conn.ikeme.mediation, mediated_by, peer_id);
+}
+
+/**
+ * fill in auth_info from stroke message
+ */
+static void build_auth_info(private_stroke_config_t *this,
+ stroke_msg_t *msg, auth_info_t *auth)
+{
+ identification_t *my_ca = NULL, *other_ca = NULL;
+ bool my_ca_same = FALSE;
+ bool other_ca_same = FALSE;
+ cert_validation_t valid;
+
+ if (msg->add_conn.other.groups)
+ {
+ /* TODO: AC groups */
+ }
+
+ switch (msg->add_conn.crl_policy)
+ {
+ case CRL_STRICT_YES:
+ valid = VALIDATION_GOOD;
+ auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
+ break;
+ case CRL_STRICT_IFURI:
+ valid = VALIDATION_SKIPPED;
+ auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
+ break;
+ default:
+ break;
+ }
+
+ if (msg->add_conn.me.ca)
+ {
+ if (streq(msg->add_conn.me.ca, "%same"))
+ {
+ my_ca_same = TRUE;
+ }
+ else
+ {
+ my_ca = identification_create_from_string(msg->add_conn.me.ca);
+ }
+ }
+ if (msg->add_conn.other.ca)
+ {
+ if (streq(msg->add_conn.other.ca, "%same"))
+ {
+ other_ca_same = TRUE;
+ }
+ else
+ {
+ other_ca = identification_create_from_string(msg->add_conn.other.ca);
+ }
+ }
+ if (other_ca_same && my_ca)
+ {
+ other_ca = my_ca->clone(my_ca);
+ }
+ else if (my_ca_same && other_ca)
+ {
+ my_ca = other_ca->clone(other_ca);
+ }
+
+ if (other_ca)
+ {
+ DBG2(DBG_CFG, " other ca: %D", other_ca);
+ certificate_t *cert = charon->credentials->get_cert(charon->credentials,
+ CERT_X509, KEY_ANY, other_ca, TRUE);
+ if (cert)
+ {
+ auth->add_item(auth, AUTHZ_CA_CERT, cert);
+ cert->destroy(cert);
+ }
+ else
+ {
+ auth->add_item(auth, AUTHZ_CA_CERT_NAME, other_ca);
+ }
+ other_ca->destroy(other_ca);
+ }
+ if (my_ca)
+ {
+ DBG2(DBG_CFG, " my ca: %D", my_ca);
+ certificate_t *cert = charon->credentials->get_cert(charon->credentials,
+ CERT_X509, KEY_ANY, my_ca, TRUE);
+ if (cert)
+ {
+ auth->add_item(auth, AUTHN_CA_CERT, cert);
+ cert->destroy(cert);
+ }
+ else
+ {
+ auth->add_item(auth, AUTHN_CA_CERT_NAME, my_ca);
+ }
+ my_ca->destroy(my_ca);
+ }
+}
+
+/**
+ * build a traffic selector from a stroke_end
+ */
+static void add_ts(private_stroke_config_t *this,
+ stroke_end_t *end, child_cfg_t *child_cfg, bool local)
+{
+ traffic_selector_t *ts;
+
+ if (end->tohost)
+ {
+ ts = traffic_selector_create_dynamic(end->protocol,
+ end->port ? end->port : 0, end->port ? end->port : 65535);
+ child_cfg->add_traffic_selector(child_cfg, local, ts);
+ }
+ else
+ {
+ host_t *net;
+
+ if (!end->subnets)
+ {
+ net = host_create_from_string(end->address, IKEV2_UDP_PORT);
+ if (net)
+ {
+ ts = traffic_selector_create_from_subnet(net, 0, end->protocol,
+ end->port);
+ child_cfg->add_traffic_selector(child_cfg, local, ts);
+ }
+ }
+ else
+ {
+ char *del, *start, *bits;
+
+ start = end->subnets;
+ do
+ {
+ int intbits = 0;
+
+ del = strchr(start, ',');
+ if (del)
+ {
+ *del = '\0';
+ }
+ bits = strchr(start, '/');
+ if (bits)
+ {
+ *bits = '\0';
+ intbits = atoi(bits + 1);
+ }
+
+ net = host_create_from_string(start, IKEV2_UDP_PORT);
+ if (net)
+ {
+ ts = traffic_selector_create_from_subnet(net, intbits,
+ end->protocol, end->port);
+ child_cfg->add_traffic_selector(child_cfg, local, ts);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "invalid subnet: %s, skipped", start);
+ }
+ start = del + 1;
+ }
+ while (del);
+ }
+ }
+}
+
+/**
+ * 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;
+
+ 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, msg->add_conn.rekey.ipsec_lifetime,
+ msg->add_conn.rekey.ipsec_lifetime - msg->add_conn.rekey.margin,
+ msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100,
+ msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
+ msg->add_conn.mode, dpd, ACTION_NONE, msg->add_conn.ipcomp);
+
+ add_ts(this, &msg->add_conn.me, child_cfg, TRUE);
+ add_ts(this, &msg->add_conn.other, child_cfg, FALSE);
+
+ add_proposals(this, msg->add_conn.algorithms.esp, NULL, child_cfg);
+
+ return child_cfg;
+}
+
+/**
+ * Implementation of stroke_config_t.add.
+ */
+static void add(private_stroke_config_t *this, stroke_msg_t *msg)
+{
+ ike_cfg_t *ike_cfg, *existing_ike;
+ peer_cfg_t *peer_cfg, *existing;
+ child_cfg_t *child_cfg;
+ enumerator_t *enumerator;
+ bool use_existing = FALSE;
+
+ ike_cfg = build_ike_cfg(this, msg);
+ if (!ike_cfg)
+ {
+ return;
+ }
+ peer_cfg = build_peer_cfg(this, msg, ike_cfg);
+ if (!peer_cfg)
+ {
+ ike_cfg->destroy(ike_cfg);
+ return;
+ }
+
+ build_auth_info(this, msg, peer_cfg->get_auth(peer_cfg));
+ enumerator = create_peer_cfg_enumerator(this, NULL, NULL);
+ while (enumerator->enumerate(enumerator, &existing))
+ {
+ existing_ike = existing->get_ike_cfg(existing);
+ if (existing->equals(existing, peer_cfg) &&
+ existing_ike->equals(existing_ike, peer_cfg->get_ike_cfg(peer_cfg)))
+ {
+ use_existing = TRUE;
+ peer_cfg->destroy(peer_cfg);
+ peer_cfg = existing;
+ peer_cfg->get_ref(peer_cfg);
+ DBG1(DBG_CFG, "added child to existing configuration '%s'",
+ peer_cfg->get_name(peer_cfg));
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ child_cfg = build_child_cfg(this, msg);
+ if (!child_cfg)
+ {
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
+ peer_cfg->add_child_cfg(peer_cfg, child_cfg);
+
+ if (use_existing)
+ {
+ peer_cfg->destroy(peer_cfg);
+ }
+ else
+ {
+ /* add config to backend */
+ DBG1(DBG_CFG, "added configuration '%s': %s[%D]...%s[%D]", msg->add_conn.name,
+ ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg),
+ ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg));
+ this->mutex->lock(this->mutex);
+ this->list->insert_last(this->list, peer_cfg);
+ this->mutex->unlock(this->mutex);
+ }
+}
+
+/**
+ * Implementation of stroke_config_t.del.
+ */
+static void del(private_stroke_config_t *this, stroke_msg_t *msg)
+{
+ enumerator_t *enumerator, *children;
+ peer_cfg_t *peer;
+ child_cfg_t *child;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, (void**)&peer))
+ {
+ /* remove peer config with such a name */
+ if (streq(peer->get_name(peer), msg->del_conn.name))
+ {
+ this->list->remove_at(this->list, enumerator);
+ peer->destroy(peer);
+ continue;
+ }
+ /* remove any child with such a name */
+ children = peer->create_child_cfg_enumerator(peer);
+ while (children->enumerate(children, &child))
+ {
+ if (streq(child->get_name(child), msg->del_conn.name))
+ {
+ peer->remove_child_cfg(peer, enumerator);
+ child->destroy(child);
+ }
+ }
+ children->destroy(children);
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+
+ DBG1(DBG_CFG, "deleted connection '%s'", msg->del_conn.name);
+}
+
+/**
+ * Implementation of stroke_config_t.destroy
+ */
+static void destroy(private_stroke_config_t *this)
+{
+ this->list->destroy_offset(this->list, offsetof(peer_cfg_t, destroy));
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred)
+{
+ private_stroke_config_t *this = malloc_thing(private_stroke_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.add = (void(*)(stroke_config_t*, stroke_msg_t *msg))add;
+ this->public.del = (void(*)(stroke_config_t*, stroke_msg_t *msg))del;
+ this->public.destroy = (void(*)(stroke_config_t*))destroy;
+
+ this->list = linked_list_create();
+ this->mutex = mutex_create(MUTEX_RECURSIVE);
+ this->ca = ca;
+ this->cred = cred;
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/stroke/stroke_config.h b/src/charon/plugins/stroke/stroke_config.h
new file mode 100644
index 000000000..22b493cd2
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_config.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup stroke_config stroke_config
+ * @{ @ingroup stroke
+ */
+
+#ifndef STROKE_CONFIG_H_
+#define STROKE_CONFIG_H_
+
+#include <config/backend.h>
+#include <stroke_msg.h>
+#include "stroke_ca.h"
+#include "stroke_cred.h"
+
+typedef struct stroke_config_t stroke_config_t;
+
+/**
+ * Stroke in-memory configuration backend
+ */
+struct stroke_config_t {
+
+ /**
+ * Implements the backend_t interface
+ */
+ backend_t backend;
+
+ /**
+ * Add a configuration to the backend.
+ *
+ * @param msg received stroke message containing config
+ */
+ void (*add)(stroke_config_t *this, stroke_msg_t *msg);
+
+ /**
+ * Remove a configuration from the backend.
+ *
+ * @param msg received stroke message containing config name
+ */
+ void (*del)(stroke_config_t *this, stroke_msg_t *msg);
+
+ /**
+ * Destroy a stroke_config instance.
+ */
+ void (*destroy)(stroke_config_t *this);
+};
+
+/**
+ * Create a stroke_config instance.
+ */
+stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred);
+
+#endif /* STROKE_CONFIG_H_ @}*/
diff --git a/src/charon/plugins/stroke/stroke_control.c b/src/charon/plugins/stroke/stroke_control.c
new file mode 100644
index 000000000..2956b1576
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_control.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "stroke_control.h"
+
+#include <daemon.h>
+
+typedef struct private_stroke_control_t private_stroke_control_t;
+
+/**
+ * private data of stroke_control
+ */
+struct private_stroke_control_t {
+
+ /**
+ * public functions
+ */
+ stroke_control_t public;
+};
+
+
+typedef struct stroke_log_info_t stroke_log_info_t;
+
+/**
+ * helper struct to say what and where to log when using controller callback
+ */
+struct stroke_log_info_t {
+
+ /**
+ * level to log up to
+ */
+ level_t level;
+
+ /**
+ * where to write log
+ */
+ FILE* out;
+};
+
+/**
+ * logging to the stroke interface
+ */
+static bool stroke_log(stroke_log_info_t *info, signal_t signal, level_t level,
+ ike_sa_t *ike_sa, char *format, va_list args)
+{
+ if (level <= info->level)
+ {
+ if (vfprintf(info->out, format, args) < 0 ||
+ fprintf(info->out, "\n") < 0 ||
+ fflush(info->out) != 0)
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * get the child_cfg with the same name as the peer cfg
+ */
+static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
+{
+ child_cfg_t *current, *found = NULL;
+ enumerator_t *enumerator;
+
+ enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (streq(current->get_name(current), name))
+ {
+ found = current;
+ found->get_ref(found);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found;
+}
+
+/**
+ * Implementation of stroke_control_t.initiate.
+ */
+static void initiate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+{
+ peer_cfg_t *peer_cfg;
+ child_cfg_t *child_cfg;
+ stroke_log_info_t info;
+
+ peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
+ msg->initiate.name);
+ if (peer_cfg == NULL)
+ {
+ DBG1(DBG_CFG, "no config named '%s'\n", msg->initiate.name);
+ return;
+ }
+ if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ {
+ DBG1(DBG_CFG, "ignoring initiation request for IKEv%d config",
+ peer_cfg->get_ike_version(peer_cfg));
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
+
+ child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
+ if (child_cfg == NULL)
+ {
+ DBG1(DBG_CFG, "no child config named '%s'\n", msg->initiate.name);
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
+
+ if (msg->output_verbosity < 0)
+ {
+ charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
+ NULL, NULL);
+ }
+ else
+ {
+ info.out = out;
+ info.level = msg->output_verbosity;
+ charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
+ (controller_cb_t)stroke_log, &info);
+ }
+}
+
+/**
+ * Implementation of stroke_control_t.terminate.
+ */
+static void terminate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+{
+ char *string, *pos = NULL, *name = NULL;
+ u_int32_t id = 0;
+ bool child;
+ int len;
+ ike_sa_t *ike_sa;
+ enumerator_t *enumerator;
+ stroke_log_info_t info;
+
+ string = msg->terminate.name;
+
+ len = strlen(string);
+ if (len < 1)
+ {
+ DBG1(DBG_CFG, "error parsing string");
+ return;
+ }
+ switch (string[len-1])
+ {
+ case '}':
+ child = TRUE;
+ pos = strchr(string, '{');
+ break;
+ case ']':
+ child = FALSE;
+ pos = strchr(string, '[');
+ break;
+ default:
+ name = string;
+ child = FALSE;
+ break;
+ }
+
+ if (name)
+ {
+ /* is a single name */
+ }
+ else if (pos == string + len - 2)
+ { /* is name[] or name{} */
+ string[len-2] = '\0';
+ name = string;
+ }
+ else
+ { /* is name[123] or name{23} */
+ string[len-1] = '\0';
+ id = atoi(pos + 1);
+ if (id == 0)
+ {
+ DBG1(DBG_CFG, "error parsing string");
+ return;
+ }
+ }
+
+ info.out = out;
+ info.level = msg->output_verbosity;
+
+ enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ child_sa_t *child_sa;
+ iterator_t *children;
+
+ if (child)
+ {
+ children = ike_sa->create_child_sa_iterator(ike_sa);
+ while (children->iterate(children, (void**)&child_sa))
+ {
+ if ((name && streq(name, child_sa->get_name(child_sa))) ||
+ (id && id == child_sa->get_reqid(child_sa)))
+ {
+ id = child_sa->get_reqid(child_sa);
+ children->destroy(children);
+ enumerator->destroy(enumerator);
+
+ charon->controller->terminate_child(charon->controller, id,
+ (controller_cb_t)stroke_log, &info);
+ return;
+ }
+ }
+ children->destroy(children);
+ }
+ else if ((name && streq(name, ike_sa->get_name(ike_sa))) ||
+ (id && id == ike_sa->get_unique_id(ike_sa)))
+ {
+ id = ike_sa->get_unique_id(ike_sa);
+ /* unlock manager first */
+ enumerator->destroy(enumerator);
+
+ charon->controller->terminate_ike(charon->controller, id,
+ (controller_cb_t)stroke_log, &info);
+ return;
+ }
+
+ }
+ enumerator->destroy(enumerator);
+ DBG1(DBG_CFG, "no such SA found");
+}
+
+/**
+ * Implementation of stroke_control_t.route.
+ */
+static void route(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+{
+ peer_cfg_t *peer_cfg;
+ child_cfg_t *child_cfg;
+ stroke_log_info_t info;
+
+ peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
+ msg->route.name);
+ if (peer_cfg == NULL)
+ {
+ fprintf(out, "no config named '%s'\n", msg->route.name);
+ return;
+ }
+ if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ {
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
+
+ child_cfg = get_child_from_peer(peer_cfg, msg->route.name);
+ if (child_cfg == NULL)
+ {
+ fprintf(out, "no child config named '%s'\n", msg->route.name);
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
+
+ info.out = out;
+ info.level = msg->output_verbosity;
+ charon->controller->route(charon->controller, peer_cfg, child_cfg,
+ (controller_cb_t)stroke_log, &info);
+ peer_cfg->destroy(peer_cfg);
+ child_cfg->destroy(child_cfg);
+}
+
+/**
+ * Implementation of stroke_control_t.unroute.
+ */
+static void unroute(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+{
+ char *name;
+ ike_sa_t *ike_sa;
+ enumerator_t *enumerator;
+ stroke_log_info_t info;
+
+ name = msg->terminate.name;
+
+ info.out = out;
+ info.level = msg->output_verbosity;
+
+ enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ child_sa_t *child_sa;
+ iterator_t *children;
+ u_int32_t id;
+
+ children = ike_sa->create_child_sa_iterator(ike_sa);
+ while (children->iterate(children, (void**)&child_sa))
+ {
+ if (child_sa->get_state(child_sa) == CHILD_ROUTED &&
+ streq(name, child_sa->get_name(child_sa)))
+ {
+ id = child_sa->get_reqid(child_sa);
+ children->destroy(children);
+ enumerator->destroy(enumerator);
+ charon->controller->unroute(charon->controller, id,
+ (controller_cb_t)stroke_log, &info);
+ return;
+ }
+ }
+ children->destroy(children);
+ }
+ enumerator->destroy(enumerator);
+ DBG1(DBG_CFG, "no such SA found");
+}
+
+/**
+ * Implementation of stroke_control_t.destroy
+ */
+static void destroy(private_stroke_control_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+stroke_control_t *stroke_control_create()
+{
+ private_stroke_control_t *this = malloc_thing(private_stroke_control_t);
+
+ this->public.initiate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))initiate;
+ this->public.terminate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate;
+ this->public.route = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))route;
+ this->public.unroute = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))unroute;
+ this->public.destroy = (void(*)(stroke_control_t*))destroy;
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/stroke/stroke_control.h b/src/charon/plugins/stroke/stroke_control.h
new file mode 100644
index 000000000..917679209
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_control.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup stroke_control stroke_control
+ * @{ @ingroup stroke
+ */
+
+#ifndef STROKE_CONTROL_H_
+#define STROKE_CONTROL_H_
+
+#include <stroke_msg.h>
+#include <library.h>
+#include <stdio.h>
+
+typedef struct stroke_control_t stroke_control_t;
+
+/**
+ * Process stroke control messages
+ */
+struct stroke_control_t {
+
+ /**
+ * Initiate a connection.
+ *
+ * @param msg stroke message
+ */
+ void (*initiate)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
+
+ /**
+ * Terminate a connection.
+ *
+ * @param msg stroke message
+ */
+ void (*terminate)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
+
+ /**
+ * Route a connection.
+ *
+ * @param msg stroke message
+ */
+ void (*route)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
+
+ /**
+ * Unroute a connection.
+ *
+ * @param msg stroke message
+ */
+ void (*unroute)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
+
+ /**
+ * Destroy a stroke_control instance.
+ */
+ void (*destroy)(stroke_control_t *this);
+};
+
+/**
+ * Create a stroke_control instance.
+ */
+stroke_control_t *stroke_control_create();
+
+#endif /* STROKE_CONTROL_H_ @}*/
diff --git a/src/charon/plugins/stroke/stroke_cred.c b/src/charon/plugins/stroke/stroke_cred.c
new file mode 100644
index 000000000..223500488
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_cred.c
@@ -0,0 +1,977 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "stroke_cred.h"
+#include "stroke_shared_key.h"
+
+#include <sys/stat.h>
+#include <limits.h>
+
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+#include <credentials/certificates/ac.h>
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+#include <utils/lexparser.h>
+#include <asn1/pem.h>
+#include <daemon.h>
+
+/* configuration directories and files */
+#define CONFIG_DIR IPSEC_CONFDIR
+#define IPSEC_D_DIR CONFIG_DIR "/ipsec.d"
+#define PRIVATE_KEY_DIR IPSEC_D_DIR "/private"
+#define CERTIFICATE_DIR IPSEC_D_DIR "/certs"
+#define CA_CERTIFICATE_DIR IPSEC_D_DIR "/cacerts"
+#define AA_CERTIFICATE_DIR IPSEC_D_DIR "/aacerts"
+#define ATTR_CERTIFICATE_DIR IPSEC_D_DIR "/acerts"
+#define OCSP_CERTIFICATE_DIR IPSEC_D_DIR "/ocspcerts"
+#define CRL_DIR IPSEC_D_DIR "/crls"
+#define SECRETS_FILE CONFIG_DIR "/ipsec.secrets"
+
+typedef struct private_stroke_cred_t private_stroke_cred_t;
+
+/**
+ * private data of stroke_cred
+ */
+struct private_stroke_cred_t {
+
+ /**
+ * public functions
+ */
+ stroke_cred_t public;
+
+ /**
+ * list of trusted peer/signer/CA certificates (certificate_t)
+ */
+ linked_list_t *certs;
+
+ /**
+ * list of shared secrets (private_shared_key_t)
+ */
+ linked_list_t *shared;
+
+ /**
+ * list of private keys (private_key_t)
+ */
+ linked_list_t *private;
+
+ /**
+ * mutex to lock lists above
+ */
+ mutex_t *mutex;
+
+ /**
+ * cache CRLs to disk?
+ */
+ bool cachecrl;
+};
+
+/**
+ * data to pass to various filters
+ */
+typedef struct {
+ private_stroke_cred_t *this;
+ identification_t *id;
+} id_data_t;
+
+/**
+ * destroy id enumerator data and unlock list
+ */
+static void id_data_destroy(id_data_t *data)
+{
+ data->this->mutex->unlock(data->this->mutex);
+ free(data);
+}
+
+/**
+ * filter function for private key enumerator
+ */
+static bool private_filter(id_data_t *data,
+ private_key_t **in, private_key_t **out)
+{
+ identification_t *candidate;
+ id_type_t type;
+
+ if (data->id == NULL)
+ {
+ *out = *in;
+ return TRUE;
+ }
+ type = data->id->get_type(data->id);
+ if (type == ID_KEY_ID)
+ { /* handle ID_KEY_ID as a ID_PUBKEY_SHA1 */
+ type = ID_PUBKEY_SHA1;
+ }
+ candidate = (*in)->get_id(*in, type);
+ if (candidate &&
+ chunk_equals(candidate->get_encoding(candidate),
+ data->id->get_encoding(data->id)))
+ {
+ *out = *in;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implements credential_set_t.create_private_enumerator
+ */
+static enumerator_t* create_private_enumerator(private_stroke_cred_t *this,
+ key_type_t type, identification_t *id)
+{
+ id_data_t *data;
+
+ data = malloc_thing(id_data_t);
+ data->this = this;
+ data->id = id;
+
+ this->mutex->lock(this->mutex);
+ return enumerator_create_filter(this->private->create_enumerator(this->private),
+ (void*)private_filter, data,
+ (void*)id_data_destroy);
+}
+
+/**
+ * filter function for certs enumerator
+ */
+static bool certs_filter(id_data_t *data, certificate_t **in, certificate_t **out)
+{
+ public_key_t *public;
+ identification_t *candidate;
+ certificate_t *cert = *in;
+ certificate_type_t type = cert->get_type(cert);
+
+ if (type == CERT_X509_CRL || type == CERT_X509_AC)
+ {
+ return FALSE;
+ }
+
+ if (data->id == NULL || cert->has_subject(cert, data->id))
+ {
+ *out = *in;
+ return TRUE;
+ }
+
+ public = (cert)->get_public_key(cert);
+ if (public)
+ {
+ candidate = public->get_id(public, data->id->get_type(data->id));
+ if (candidate && data->id->equals(data->id, candidate))
+ {
+ public->destroy(public);
+ *out = *in;
+ return TRUE;
+ }
+ public->destroy(public);
+ }
+ return FALSE;
+}
+
+/**
+ * filter function for crl enumerator
+ */
+static bool crl_filter(id_data_t *data, certificate_t **in, certificate_t **out)
+{
+ certificate_t *cert = *in;
+
+ if (cert->get_type(cert) != CERT_X509_CRL)
+ {
+ return FALSE;
+ }
+
+ if (data->id == NULL || cert->has_issuer(cert, data->id))
+ {
+ *out = *in;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * filter function for attribute certificate enumerator
+ */
+static bool ac_filter(id_data_t *data, certificate_t **in, certificate_t **out)
+{
+ certificate_t *cert = *in;
+
+ if (cert->get_type(cert) != CERT_X509_AC)
+ {
+ return FALSE;
+ }
+
+ if (data->id == NULL || cert->has_subject(cert, data->id))
+ {
+ *out = *in;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implements credential_set_t.create_cert_enumerator
+ */
+static enumerator_t* create_cert_enumerator(private_stroke_cred_t *this,
+ certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
+{
+ id_data_t *data;
+
+ if (cert == CERT_X509_CRL || cert == CERT_X509_AC)
+ {
+ if (trusted)
+ {
+ return NULL;
+ }
+ data = malloc_thing(id_data_t);
+ data->this = this;
+ data->id = id;
+
+ this->mutex->lock(this->mutex);
+ return enumerator_create_filter(this->certs->create_enumerator(this->certs),
+ (cert == CERT_X509_CRL)? (void*)crl_filter : (void*)ac_filter,
+ data, (void*)id_data_destroy);
+ }
+ if (cert != CERT_X509 && cert != CERT_ANY)
+ { /* we only have X509 certificates. TODO: ACs? */
+ return NULL;
+ }
+ data = malloc_thing(id_data_t);
+ data->this = this;
+ data->id = id;
+
+ this->mutex->lock(this->mutex);
+ return enumerator_create_filter(this->certs->create_enumerator(this->certs),
+ (void*)certs_filter, data,
+ (void*)id_data_destroy);
+}
+
+typedef struct {
+ private_stroke_cred_t *this;
+ identification_t *me;
+ identification_t *other;
+ shared_key_type_t type;
+} shared_data_t;
+
+/**
+ * free shared key enumerator data and unlock list
+ */
+static void shared_data_destroy(shared_data_t *data)
+{
+ data->this->mutex->unlock(data->this->mutex);
+ free(data);
+}
+
+/**
+ * filter function for certs enumerator
+ */
+static bool shared_filter(shared_data_t *data,
+ stroke_shared_key_t **in, shared_key_t **out,
+ void **unused1, id_match_t *me,
+ void **unused2, id_match_t *other)
+{
+ id_match_t my_match, other_match;
+ stroke_shared_key_t *stroke = *in;
+ shared_key_t *shared = &stroke->shared;
+
+ if (data->type != SHARED_ANY && shared->get_type(shared) != data->type)
+ {
+ return FALSE;
+ }
+
+ my_match = stroke->has_owner(stroke, data->me);
+ other_match = stroke->has_owner(stroke, data->other);
+ if (!my_match && !other_match)
+ {
+ return FALSE;
+ }
+ *out = shared;
+ if (me)
+ {
+ *me = my_match;
+ }
+ if (other)
+ {
+ *other = other_match;
+ }
+ return TRUE;
+}
+
+/**
+ * Implements credential_set_t.create_shared_enumerator
+ */
+static enumerator_t* create_shared_enumerator(private_stroke_cred_t *this,
+ shared_key_type_t type, identification_t *me,
+ identification_t *other)
+{
+ shared_data_t *data = malloc_thing(shared_data_t);
+
+ data->this = this;
+ data->me = me;
+ data->other = other;
+ data->type = type;
+ this->mutex->lock(this->mutex);
+ return enumerator_create_filter(this->shared->create_enumerator(this->shared),
+ (void*)shared_filter, data,
+ (void*)shared_data_destroy);
+}
+
+/**
+ * Add a certificate to chain
+ */
+static certificate_t* add_cert(private_stroke_cred_t *this, certificate_t *cert)
+{
+ certificate_t *current;
+ enumerator_t *enumerator;
+ bool new = TRUE;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->certs->create_enumerator(this->certs);
+ while (enumerator->enumerate(enumerator, (void**)&current))
+ {
+ if (current->equals(current, cert))
+ {
+ /* cert already in queue */
+ cert->destroy(cert);
+ cert = current;
+ new = FALSE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (new)
+ {
+ this->certs->insert_last(this->certs, cert);
+ }
+ this->mutex->unlock(this->mutex);
+ return cert;
+}
+
+/**
+ * Implementation of stroke_cred_t.load_ca.
+ */
+static certificate_t* load_ca(private_stroke_cred_t *this, char *filename)
+{
+ certificate_t *cert;
+ char path[PATH_MAX];
+
+ if (*filename == '/')
+ {
+ snprintf(path, sizeof(path), "%s", filename);
+ }
+ else
+ {
+ snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
+ }
+
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, path,
+ BUILD_X509_FLAG, X509_CA,
+ BUILD_END);
+ if (cert)
+ {
+ return (certificate_t*)add_cert(this, cert);
+ }
+ return NULL;
+}
+
+/**
+ * Add X.509 CRL to chain
+ */
+static bool add_crl(private_stroke_cred_t *this, crl_t* crl)
+{
+ certificate_t *current, *cert = &crl->certificate;
+ enumerator_t *enumerator;
+ bool new = TRUE, found = FALSE;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->certs->create_enumerator(this->certs);
+ while (enumerator->enumerate(enumerator, (void**)&current))
+ {
+ if (current->get_type(current) == CERT_X509_CRL)
+ {
+ crl_t *crl_c = (crl_t*)current;
+ identification_t *authkey = crl->get_authKeyIdentifier(crl);
+ identification_t *authkey_c = crl_c->get_authKeyIdentifier(crl_c);
+
+ /* if compare authorityKeyIdentifiers if available */
+ if (authkey != NULL && authkey_c != NULL &&
+ authkey->equals(authkey, authkey_c))
+ {
+ found = TRUE;
+ }
+ else
+ {
+ identification_t *issuer = cert->get_issuer(cert);
+ identification_t *issuer_c = current->get_issuer(current);
+
+ /* otherwise compare issuer distinguished names */
+ if (issuer->equals(issuer, issuer_c))
+ {
+ found = TRUE;
+ }
+ }
+ if (found)
+ {
+ new = cert->is_newer(cert, current);
+ if (new)
+ {
+ this->certs->remove_at(this->certs, enumerator);
+ }
+ else
+ {
+ cert->destroy(cert);
+ }
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (new)
+ {
+ this->certs->insert_last(this->certs, cert);
+ }
+ this->mutex->unlock(this->mutex);
+ return new;
+}
+
+/**
+ * Add X.509 attribute certificate to chain
+ */
+static bool add_ac(private_stroke_cred_t *this, ac_t* ac)
+{
+ certificate_t *cert = &ac->certificate;
+
+ this->mutex->lock(this->mutex);
+ this->certs->insert_last(this->certs, cert);
+ this->mutex->unlock(this->mutex);
+ return TRUE;
+}
+
+/**
+ * Implementation of stroke_cred_t.load_peer.
+ */
+static certificate_t* load_peer(private_stroke_cred_t *this, char *filename)
+{
+ certificate_t *cert;
+ char path[PATH_MAX];
+
+ 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_X509,
+ BUILD_FROM_FILE, path,
+ BUILD_X509_FLAG, 0,
+ BUILD_END);
+ if (cert)
+ {
+ cert = add_cert(this, cert);
+ return cert->get_ref(cert);
+ }
+ return NULL;
+}
+
+/**
+ * load trusted certificates from a directory
+ */
+static void load_certdir(private_stroke_cred_t *this, char *path,
+ certificate_type_t type, x509_flag_t flag)
+{
+ struct stat st;
+ char *file;
+
+ enumerator_t *enumerator = enumerator_create_directory(path);
+
+ if (!enumerator)
+ {
+ DBG1(DBG_CFG, " reading directory failed");
+ return;
+ }
+
+ while (enumerator->enumerate(enumerator, NULL, &file, &st))
+ {
+ certificate_t *cert;
+
+ if (!S_ISREG(st.st_mode))
+ {
+ /* skip special file */
+ continue;
+ }
+ switch (type)
+ {
+ case CERT_X509:
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file,
+ BUILD_X509_FLAG, flag,
+ BUILD_END);
+ if (cert)
+ {
+ add_cert(this, cert);
+ }
+ break;
+ case CERT_X509_CRL:
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509_CRL,
+ BUILD_FROM_FILE, file,
+ BUILD_END);
+ if (cert)
+ {
+ add_crl(this, (crl_t*)cert);
+ }
+ break;
+ case CERT_X509_AC:
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509_AC,
+ BUILD_FROM_FILE, file,
+ BUILD_END);
+ if (cert)
+ {
+ add_ac(this, (ac_t*)cert);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * Implementation of credential_set_t.cache_cert.
+ */
+static void cache_cert(private_stroke_cred_t *this, certificate_t *cert)
+{
+ if (cert->get_type(cert) == CERT_X509_CRL && this->cachecrl)
+ {
+ /* CRLs get written to /etc/ipsec.d/crls/authkeyId.crl */
+ crl_t *crl = (crl_t*)cert;
+
+ cert->get_ref(cert);
+ if (add_crl(this, crl))
+ {
+ char buf[256];
+ chunk_t chunk, hex;
+ identification_t *id;
+
+ id = crl->get_authKeyIdentifier(crl);
+ chunk = id->get_encoding(id);
+ hex = chunk_to_hex(chunk, NULL, FALSE);
+ snprintf(buf, sizeof(buf), "%s/%s.crl", CRL_DIR, hex);
+ free(hex.ptr);
+
+ chunk = cert->get_encoding(cert);
+ if (chunk_write(chunk, buf, 022, TRUE))
+ {
+ DBG1(DBG_CFG, " written crl to '%s'", buf);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " writing crl to '%s' failed", buf);
+ }
+ free(chunk.ptr);
+ }
+ }
+}
+
+/**
+ * Implementation of stroke_cred_t.cachecrl.
+ */
+static void cachecrl(private_stroke_cred_t *this, bool enabled)
+{
+ DBG1(DBG_CFG, "crl caching to %s %s",
+ CRL_DIR, enabled ? "enabled" : "disabled");
+ this->cachecrl = enabled;
+}
+
+
+/**
+ * Convert a string of characters into a binary secret
+ * A string between single or double quotes is treated as ASCII characters
+ * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
+ */
+static err_t extract_secret(chunk_t *secret, chunk_t *line)
+{
+ chunk_t raw_secret;
+ char delimiter = ' ';
+ bool quotes = FALSE;
+
+ if (!eat_whitespace(line))
+ {
+ return "missing secret";
+ }
+
+ if (*line->ptr == '\'' || *line->ptr == '"')
+ {
+ quotes = TRUE;
+ delimiter = *line->ptr;
+ line->ptr++; line->len--;
+ }
+
+ if (!extract_token(&raw_secret, delimiter, line))
+ {
+ if (delimiter == ' ')
+ {
+ raw_secret = *line;
+ }
+ else
+ {
+ return "missing second delimiter";
+ }
+ }
+
+ if (quotes)
+ {
+ /* treat as an ASCII string */
+ *secret = chunk_clone(raw_secret);
+ return NULL;
+ }
+ /* treat 0x as hex, 0s as base64 */
+ if (raw_secret.len > 2)
+ {
+ if (strncasecmp("0x", raw_secret.ptr, 2) == 0)
+ {
+ *secret = chunk_from_hex(chunk_skip(raw_secret, 2), NULL);
+ return NULL;
+ }
+ if (strncasecmp("0s", raw_secret.ptr, 2) == 0)
+ {
+ *secret = chunk_from_base64(chunk_skip(raw_secret, 2), NULL);
+ return NULL;
+ }
+ }
+ *secret = chunk_clone(raw_secret);
+ return NULL;
+}
+
+/**
+ * reload ipsec.secrets
+ */
+static void load_secrets(private_stroke_cred_t *this)
+{
+ size_t bytes;
+ int line_nr = 0;
+ chunk_t chunk, src, line;
+ FILE *fd;
+ private_key_t *private;
+ shared_key_t *shared;
+
+ DBG1(DBG_CFG, "loading secrets from '%s'", SECRETS_FILE);
+
+ fd = fopen(SECRETS_FILE, "r");
+ if (fd == NULL)
+ {
+ DBG1(DBG_CFG, "opening secrets file '%s' failed");
+ return;
+ }
+
+ /* TODO: do error checks */
+ fseek(fd, 0, SEEK_END);
+ chunk.len = ftell(fd);
+ rewind(fd);
+ chunk.ptr = malloc(chunk.len);
+ bytes = fread(chunk.ptr, 1, chunk.len, fd);
+ fclose(fd);
+ src = chunk;
+
+ this->mutex->lock(this->mutex);
+ while (this->shared->remove_last(this->shared,
+ (void**)&shared) == SUCCESS)
+ {
+ shared->destroy(shared);
+ }
+ while (this->private->remove_last(this->private,
+ (void**)&private) == SUCCESS)
+ {
+ private->destroy(private);
+ }
+
+ while (fetchline(&src, &line))
+ {
+ chunk_t ids, token;
+ shared_key_type_t type;
+
+ line_nr++;
+
+ if (!eat_whitespace(&line))
+ {
+ continue;
+ }
+ if (!extract_last_token(&ids, ':', &line))
+ {
+ DBG1(DBG_CFG, "line %d: missing ':' separator", line_nr);
+ goto error;
+ }
+ /* NULL terminate the ids string by replacing the : separator */
+ *(ids.ptr + ids.len) = '\0';
+
+ if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
+ {
+ DBG1(DBG_CFG, "line %d: missing token", line_nr);
+ goto error;
+ }
+ if (match("RSA", &token) || match("ECDSA", &token))
+ {
+ char path[PATH_MAX];
+ chunk_t filename;
+ chunk_t secret = chunk_empty;
+ private_key_t *key;
+ bool pgp = FALSE;
+ chunk_t chunk = chunk_empty;
+ key_type_t key_type = match("RSA", &token) ? KEY_RSA : KEY_ECDSA;
+
+ err_t ugh = extract_value(&filename, &line);
+
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
+ goto error;
+ }
+ if (filename.len == 0)
+ {
+ DBG1(DBG_CFG, "line %d: empty filename", line_nr);
+ goto error;
+ }
+ if (*filename.ptr == '/')
+ {
+ /* absolute path name */
+ snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
+ }
+ else
+ {
+ /* relative path name */
+ snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR,
+ filename.len, filename.ptr);
+ }
+
+ /* check for optional passphrase */
+ if (eat_whitespace(&line))
+ {
+ ugh = extract_secret(&secret, &line);
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
+ goto error;
+ }
+ }
+
+ if (pem_asn1_load_file(path, &secret, &chunk, &pgp))
+ {
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type,
+ BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+ if (key)
+ {
+ DBG1(DBG_CFG, " loaded private key file '%s'", path);
+ this->private->insert_last(this->private, key);
+ }
+ }
+ chunk_clear(&secret);
+ }
+ else if ((match("PSK", &token) && (type = SHARED_IKE)) ||
+ (match("EAP", &token) && (type = SHARED_EAP)) ||
+ (match("XAUTH", &token) && (type = SHARED_EAP)) ||
+ (match("PIN", &token) && (type = SHARED_PIN)))
+ {
+ stroke_shared_key_t *shared_key;
+ chunk_t secret = chunk_empty;
+ bool any = TRUE;
+
+ err_t ugh = extract_secret(&secret, &line);
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
+ goto error;
+ }
+ shared_key = stroke_shared_key_create(type, secret);
+ DBG1(DBG_CFG, " loaded %N secret for %s", shared_key_type_names, type,
+ ids.len > 0 ? (char*)ids.ptr : "%any");
+ DBG4(DBG_CFG, " secret: %#B", &secret);
+
+ this->shared->insert_last(this->shared, shared_key);
+ while (ids.len > 0)
+ {
+ chunk_t id;
+ identification_t *peer_id;
+
+ ugh = extract_value(&id, &ids);
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
+ goto error;
+ }
+ if (id.len == 0)
+ {
+ continue;
+ }
+
+ /* NULL terminate the ID string */
+ *(id.ptr + id.len) = '\0';
+
+ peer_id = identification_create_from_string(id.ptr);
+ if (peer_id == NULL)
+ {
+ DBG1(DBG_CFG, "line %d: malformed ID: %s", line_nr, id.ptr);
+ goto error;
+ }
+ if (peer_id->get_type(peer_id) == ID_ANY)
+ {
+ peer_id->destroy(peer_id);
+ continue;
+ }
+
+ shared_key->add_owner(shared_key, peer_id);
+ any = FALSE;
+ }
+ if (any)
+ {
+ shared_key->add_owner(shared_key,
+ identification_create_from_encoding(ID_ANY, chunk_empty));
+ }
+ }
+ else
+ {
+ DBG1(DBG_CFG, "line %d: token must be either "
+ "RSA, EC, PSK, EAP, or PIN", line_nr);
+ goto error;
+ }
+ }
+error:
+ this->mutex->unlock(this->mutex);
+ chunk_clear(&chunk);
+}
+
+/**
+ * load all certificates from ipsec.d
+ */
+static void load_certs(private_stroke_cred_t *this)
+{
+ DBG1(DBG_CFG, "loading ca certificates from '%s'",
+ CA_CERTIFICATE_DIR);
+ load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
+
+ DBG1(DBG_CFG, "loading aa certificates from '%s'",
+ AA_CERTIFICATE_DIR);
+ load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
+
+ DBG1(DBG_CFG, "loading ocsp signer certificates from '%s'",
+ OCSP_CERTIFICATE_DIR);
+ load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509, X509_OCSP_SIGNER);
+
+ DBG1(DBG_CFG, "loading attribute certificates from '%s'",
+ ATTR_CERTIFICATE_DIR);
+ load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0);
+
+ DBG1(DBG_CFG, "loading crls from '%s'",
+ CRL_DIR);
+ 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)
+{
+ if (msg->reread.flags & REREAD_SECRETS)
+ {
+ DBG1(DBG_CFG, "rereading secrets");
+ load_secrets(this);
+ }
+ if (msg->reread.flags & REREAD_CACERTS)
+ {
+ DBG1(DBG_CFG, "rereading ca certificates from '%s'",
+ CA_CERTIFICATE_DIR);
+ load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
+ }
+ if (msg->reread.flags & REREAD_OCSPCERTS)
+ {
+ DBG1(DBG_CFG, "rereading ocsp signer certificates from '%s'",
+ OCSP_CERTIFICATE_DIR);
+ load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509,
+ X509_OCSP_SIGNER);
+ }
+ if (msg->reread.flags & REREAD_AACERTS)
+ {
+ DBG1(DBG_CFG, "rereading aa certificates from '%s'",
+ AA_CERTIFICATE_DIR);
+ load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
+ }
+ if (msg->reread.flags & REREAD_ACERTS)
+ {
+ DBG1(DBG_CFG, "rereading attribute certificates from '%s'",
+ ATTR_CERTIFICATE_DIR);
+ load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0);
+ }
+ if (msg->reread.flags & REREAD_CRLS)
+ {
+ DBG1(DBG_CFG, "rereading crls from '%s'",
+ CRL_DIR);
+ load_certdir(this, CRL_DIR, CERT_X509_CRL, 0);
+ }
+}
+
+/**
+ * Implementation of stroke_cred_t.destroy
+ */
+static void destroy(private_stroke_cred_t *this)
+{
+ this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
+ this->shared->destroy_offset(this->shared, offsetof(shared_key_t, destroy));
+ this->private->destroy_offset(this->private, offsetof(private_key_t, destroy));
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+stroke_cred_t *stroke_cred_create()
+{
+ private_stroke_cred_t *this = malloc_thing(private_stroke_cred_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*)cache_cert;
+ this->public.reread = (void(*)(stroke_cred_t*, stroke_msg_t *msg))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->certs = linked_list_create();
+ this->shared = linked_list_create();
+ this->private = linked_list_create();
+ this->mutex = mutex_create(MUTEX_RECURSIVE);
+
+ load_certs(this);
+ load_secrets(this);
+
+ this->cachecrl = FALSE;
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/stroke/stroke_cred.h b/src/charon/plugins/stroke/stroke_cred.h
new file mode 100644
index 000000000..1b9ef986e
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_cred.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup stroke_cred stroke_cred
+ * @{ @ingroup stroke
+ */
+
+#ifndef STROKE_CRED_H_
+#define STROKE_CRED_H_
+
+#include <stroke_msg.h>
+#include <credentials/credential_set.h>
+#include <credentials/certificates/certificate.h>
+
+typedef struct stroke_cred_t stroke_cred_t;
+
+/**
+ * Stroke in-memory credential storage.
+ */
+struct stroke_cred_t {
+
+ /**
+ * Implements credential_set_t
+ */
+ credential_set_t set;
+
+ /**
+ * Reread secrets from config files.
+ *
+ * @param msg stroke message
+ */
+ void (*reread)(stroke_cred_t *this, stroke_msg_t *msg);
+
+ /**
+ * Load a CA certificate, and serve it through the credential_set.
+ *
+ * @param filename file to load CA cert from
+ * @return reference to loaded certificate, or NULL
+ */
+ certificate_t* (*load_ca)(stroke_cred_t *this, char *filename);
+
+ /**
+ * Load a peer certificate and serve it rhrough the credential_set.
+ *
+ * @param filename file to load peer cert from
+ * @return reference to loaded certificate, or NULL
+ */
+ certificate_t* (*load_peer)(stroke_cred_t *this, char *filename);
+
+ /**
+ * Enable/Disable CRL caching to disk.
+ *
+ * @param enabled TRUE to enable, FALSE to disable
+ */
+ void (*cachecrl)(stroke_cred_t *this, bool enabled);
+
+ /**
+ * Destroy a stroke_cred instance.
+ */
+ void (*destroy)(stroke_cred_t *this);
+};
+
+/**
+ * Create a stroke_cred instance.
+ */
+stroke_cred_t *stroke_cred_create();
+
+#endif /* STROKE_CRED_H_ @}*/
diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c
new file mode 100644
index 000000000..44699ba0a
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_list.c
@@ -0,0 +1,729 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "stroke_list.h"
+
+#include <daemon.h>
+#include <utils/linked_list.h>
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/ac.h>
+#include <credentials/certificates/crl.h>
+
+/* warning intervals for list functions */
+#define CERT_WARNING_INTERVAL 30 /* days */
+#define CRL_WARNING_INTERVAL 7 /* days */
+#define AC_WARNING_INTERVAL 1 /* day */
+
+typedef struct private_stroke_list_t private_stroke_list_t;
+
+/**
+ * private data of stroke_list
+ */
+struct private_stroke_list_t {
+
+ /**
+ * public functions
+ */
+ stroke_list_t public;
+
+ /**
+ * timestamp of daemon start
+ */
+ time_t uptime;
+};
+
+/**
+ * log an IKE_SA to out
+ */
+static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
+{
+ ike_sa_id_t *id = ike_sa->get_id(ike_sa);
+
+ fprintf(out, "%12s[%d]: %N, %H[%D]...%H[%D]\n",
+ ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
+ ike_sa_state_names, ike_sa->get_state(ike_sa),
+ ike_sa->get_my_host(ike_sa), ike_sa->get_my_id(ike_sa),
+ ike_sa->get_other_host(ike_sa), ike_sa->get_other_id(ike_sa));
+
+ if (all)
+ {
+ char *ike_proposal = ike_sa->get_proposal(ike_sa);
+
+ fprintf(out, "%12s[%d]: IKE SPIs: %.16llx_i%s %.16llx_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) ? "" : "*");
+
+
+ if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED)
+ {
+ u_int32_t rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY_TIME);
+ u_int32_t reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH_TIME);
+
+ if (rekey)
+ {
+ fprintf(out, ", rekeying in %V", &rekey);
+ }
+ if (reauth)
+ {
+ fprintf(out, ", reauthentication in %V", &reauth);
+ }
+ if (!rekey && !reauth)
+ {
+ fprintf(out, ", rekeying disabled");
+ }
+ }
+ fprintf(out, "\n");
+
+ if (ike_proposal)
+ {
+ fprintf(out, "%12s[%d]: IKE proposal: %s\n",
+ ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
+ ike_proposal);
+ }
+ }
+}
+
+/**
+ * log an CHILD_SA to out
+ */
+static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
+{
+ u_int32_t rekey, now = time(NULL);
+ u_int32_t use_in, use_out, use_fwd;
+ encryption_algorithm_t encr_alg;
+ integrity_algorithm_t int_alg;
+ size_t encr_len, int_len;
+ mode_t mode;
+
+ child_sa->get_stats(child_sa, &mode, &encr_alg, &encr_len,
+ &int_alg, &int_len, &rekey, &use_in, &use_out,
+ &use_fwd);
+
+ fprintf(out, "%12s{%d}: %N, %N",
+ child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ child_sa_state_names, child_sa->get_state(child_sa),
+ mode_names, mode);
+
+ if (child_sa->get_state(child_sa) == CHILD_INSTALLED)
+ {
+ fprintf(out, ", %N SPIs: %.8x_i %.8x_o",
+ protocol_id_names, child_sa->get_protocol(child_sa),
+ htonl(child_sa->get_spi(child_sa, TRUE)),
+ htonl(child_sa->get_spi(child_sa, FALSE)));
+
+ if (all)
+ {
+ fprintf(out, "\n%12s{%d}: ", child_sa->get_name(child_sa),
+ child_sa->get_reqid(child_sa));
+
+
+ if (child_sa->get_protocol(child_sa) == PROTO_ESP)
+ {
+ fprintf(out, "%N", encryption_algorithm_names, encr_alg);
+
+ if (encr_len)
+ {
+ fprintf(out, "-%d", encr_len);
+ }
+ if (int_alg != AUTH_UNDEFINED)
+ {
+ fprintf(out, "/");
+ }
+ }
+
+ if (int_alg != AUTH_UNDEFINED)
+ {
+ fprintf(out, "%N", integrity_algorithm_names, int_alg);
+ if (int_len)
+ {
+ fprintf(out, "-%d", int_len);
+ }
+ }
+ fprintf(out, ", rekeying ");
+
+ if (rekey)
+ {
+ fprintf(out, "in %#V", &now, &rekey);
+ }
+ else
+ {
+ fprintf(out, "disabled");
+ }
+
+ fprintf(out, ", last use: ");
+ use_in = max(use_in, use_fwd);
+ if (use_in)
+ {
+ fprintf(out, "%ds_i ", now - use_in);
+ }
+ else
+ {
+ fprintf(out, "no_i ");
+ }
+ if (use_out)
+ {
+ fprintf(out, "%ds_o ", now - use_out);
+ }
+ else
+ {
+ fprintf(out, "no_o ");
+ }
+ }
+ }
+
+ fprintf(out, "\n%12s{%d}: %#R=== %#R\n",
+ child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ child_sa->get_traffic_selectors(child_sa, TRUE),
+ child_sa->get_traffic_selectors(child_sa, FALSE));
+}
+
+/**
+ * Implementation of stroke_list_t.status.
+ */
+static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all)
+{
+ enumerator_t *enumerator, *children;
+ iterator_t *iterator;
+ host_t *host;
+ peer_cfg_t *peer_cfg;
+ ike_cfg_t *ike_cfg;
+ child_cfg_t *child_cfg;
+ ike_sa_t *ike_sa;
+ char *name = NULL, *plugin;
+ bool found = FALSE;
+ time_t uptime;
+
+ name = msg->status.name;
+
+ if (all)
+ {
+ uptime = time(NULL) - this->uptime;
+ fprintf(out, "Performance:\n");
+ fprintf(out, " uptime: %V, since %#T\n", &uptime, &this->uptime, FALSE);
+ fprintf(out, " worker threads: %d idle of %d,",
+ charon->processor->get_idle_threads(charon->processor),
+ charon->processor->get_total_threads(charon->processor));
+ fprintf(out, " job queue load: %d,",
+ charon->processor->get_job_load(charon->processor));
+ fprintf(out, " scheduled events: %d\n",
+ charon->scheduler->get_job_load(charon->scheduler));
+ fprintf(out, " loaded plugins: ");
+ enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
+ while (enumerator->enumerate(enumerator, &plugin))
+ {
+ fprintf(out, "%s ", plugin);
+ }
+ enumerator->destroy(enumerator);
+ fprintf(out, "\n");
+
+ iterator = charon->kernel_interface->create_address_iterator(
+ charon->kernel_interface);
+ fprintf(out, "Listening IP addresses:\n");
+ while (iterator->iterate(iterator, (void**)&host))
+ {
+ fprintf(out, " %H\n", host);
+ }
+ iterator->destroy(iterator);
+
+ fprintf(out, "Connections:\n");
+ enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
+ while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
+ {
+ if (peer_cfg->get_ike_version(peer_cfg) != 2 ||
+ (name && !streq(name, peer_cfg->get_name(peer_cfg))))
+ {
+ continue;
+ }
+
+ ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
+ fprintf(out, "%12s: %s[%D]...%s[%D]\n", peer_cfg->get_name(peer_cfg),
+ ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg),
+ ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg));
+ /* TODO: list CAs and groups */
+ 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: %#R=== %#R\n", child_cfg->get_name(child_cfg),
+ my_ts, other_ts);
+ my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
+ other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
+ }
+ children->destroy(children);
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ fprintf(out, "Security Associations:\n");
+ enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ bool ike_printed = FALSE;
+ child_sa_t *child_sa;
+ iterator_t *children = ike_sa->create_child_sa_iterator(ike_sa);
+
+ if (name == NULL || streq(name, ike_sa->get_name(ike_sa)))
+ {
+ log_ike_sa(out, ike_sa, all);
+ found = TRUE;
+ ike_printed = TRUE;
+ }
+
+ while (children->iterate(children, (void**)&child_sa))
+ {
+ if (name == NULL || streq(name, child_sa->get_name(child_sa)))
+ {
+ if (!ike_printed)
+ {
+ log_ike_sa(out, ike_sa, all);
+ found = TRUE;
+ ike_printed = TRUE;
+ }
+ log_child_sa(out, child_sa, all);
+ }
+ }
+ children->destroy(children);
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ if (name)
+ {
+ fprintf(out, " no match\n");
+ }
+ else
+ {
+ fprintf(out, " none\n");
+ }
+ }
+}
+
+/**
+ * create a unique certificate list without duplicates
+ * certicates having the same issuer are grouped together.
+ */
+static linked_list_t* create_unique_cert_list(certificate_type_t type)
+{
+ linked_list_t *list = linked_list_create();
+ enumerator_t *enumerator = charon->credentials->create_cert_enumerator(
+ charon->credentials, type, KEY_ANY,
+ NULL, FALSE);
+ certificate_t *cert;
+
+ while (enumerator->enumerate(enumerator, (void**)&cert))
+ {
+ iterator_t *iterator = list->create_iterator(list, TRUE);
+ identification_t *issuer = cert->get_issuer(cert);
+ bool previous_same, same = FALSE, last = TRUE;
+ certificate_t *list_cert;
+
+ while (iterator->iterate(iterator, (void**)&list_cert))
+ {
+ /* exit if we have a duplicate? */
+ if (list_cert->equals(list_cert, cert))
+ {
+ last = FALSE;
+ 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;
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+
+ if (last)
+ {
+ list->insert_last(list, (void *)cert->get_ref(cert));
+ }
+ }
+ enumerator->destroy(enumerator);
+ return list;
+}
+
+/**
+ * list all X.509 certificates matching the flags
+ */
+static void stroke_list_certs(linked_list_t *list, char *label,
+ x509_flag_t flags, bool utc, FILE *out)
+{
+ bool first = TRUE;
+ time_t now = time(NULL);
+ enumerator_t *enumerator = list->create_enumerator(list);
+ certificate_t *cert;
+
+ while (enumerator->enumerate(enumerator, (void**)&cert))
+ {
+ x509_t *x509 = (x509_t*)cert;
+ x509_flag_t x509_flags = x509->get_flags(x509);
+
+ /* list only if flag is set, or flags == 0 (ignoring self-signed) */
+ if ((x509_flags & flags) || (flags == (x509_flags & ~X509_SELF_SIGNED)))
+ {
+ enumerator_t *enumerator;
+ identification_t *altName;
+ bool first_altName = TRUE;
+ chunk_t serial = x509->get_serial(x509);
+ identification_t *authkey = x509->get_authKeyIdentifier(x509);
+ time_t notBefore, notAfter;
+ public_key_t *public = cert->get_public_key(cert);
+
+ if (first)
+ {
+ fprintf(out, "\n");
+ fprintf(out, "List of %s:\n", label);
+ first = FALSE;
+ }
+ fprintf(out, "\n");
+
+ /* list subjectAltNames */
+ enumerator = x509->create_subjectAltName_enumerator(x509);
+ while (enumerator->enumerate(enumerator, (void**)&altName))
+ {
+ if (first_altName)
+ {
+ fprintf(out, " altNames: ");
+ first_altName = FALSE;
+ }
+ else
+ {
+ fprintf(out, ", ");
+ }
+ fprintf(out, "%D", altName);
+ }
+ if (!first_altName)
+ {
+ fprintf(out, "\n");
+ }
+ enumerator->destroy(enumerator);
+
+ fprintf(out, " subject: \"%D\"\n", cert->get_subject(cert));
+ fprintf(out, " issuer: \"%D\"\n", cert->get_issuer(cert));
+ fprintf(out, " serial: %#B\n", &serial);
+
+ /* list validity */
+ cert->get_validity(cert, &now, &notBefore, &notAfter);
+ 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 information */
+ if (public)
+ {
+ private_key_t *private = NULL;
+ identification_t *id, *keyid;
+
+ id = public->get_id(public, ID_PUBKEY_SHA1);
+ keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+
+ private = charon->credentials->get_private(
+ charon->credentials,
+ public->get_type(public), keyid, NULL);
+ fprintf(out, " pubkey: %N %d bits%s\n",
+ key_type_names, public->get_type(public),
+ public->get_keysize(public) * 8,
+ private ? ", has private key" : "");
+ fprintf(out, " keyid: %D\n", keyid);
+ fprintf(out, " subjkey: %D\n", id);
+ DESTROY_IF(private);
+ public->destroy(public);
+ }
+
+ /* list optional authorityKeyIdentifier */
+ if (authkey)
+ {
+ fprintf(out, " authkey: %D\n", authkey);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * list all X.509 attribute certificates
+ */
+static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
+{
+ bool first = TRUE;
+ time_t thisUpdate, nextUpdate, now = time(NULL);
+ enumerator_t *enumerator = list->create_enumerator(list);
+ certificate_t *cert;
+
+ while (enumerator->enumerate(enumerator, (void**)&cert))
+ {
+ ac_t *ac = (ac_t*)cert;
+ chunk_t serial = ac->get_serial(ac);
+ chunk_t holderSerial = ac->get_holderSerial(ac);
+ identification_t *holderIssuer = ac->get_holderIssuer(ac);
+ identification_t *authkey = ac->get_authKeyIdentifier(ac);
+ identification_t *entityName = cert->get_subject(cert);
+
+ if (first)
+ {
+ fprintf(out, "\n");
+ fprintf(out, "List of X.509 Attribute Certificates:\n");
+ first = FALSE;
+ }
+ fprintf(out, "\n");
+
+ if (entityName)
+ {
+ fprintf(out, " holder: \"%D\"\n", entityName);
+ }
+ if (holderIssuer)
+ {
+ fprintf(out, " hissuer: \"%D\"\n", holderIssuer);
+ }
+ if (holderSerial.ptr)
+ {
+ fprintf(out, " hserial: %#B\n", &holderSerial);
+ }
+ fprintf(out, " issuer: \"%D\"\n", cert->get_issuer(cert));
+ fprintf(out, " serial: %#B\n", &serial);
+
+ /* list validity */
+ cert->get_validity(cert, &now, &thisUpdate, &nextUpdate);
+ fprintf(out, " updates: this %#T\n", &thisUpdate, utc);
+ fprintf(out, " next %#T, ", &nextUpdate, utc);
+ if (now > nextUpdate)
+ {
+ fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate);
+ }
+ else
+ {
+ fprintf(out, "ok");
+ if (now > nextUpdate - AC_WARNING_INTERVAL * 60 * 60 * 24)
+ {
+ fprintf(out, " (expires in %#V)", &now, &nextUpdate);
+ }
+ fprintf(out, " \n");
+ }
+
+ /* list optional authorityKeyIdentifier */
+ if (authkey)
+ {
+ fprintf(out, " authkey: %D\n", authkey);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * list all X.509 CRLs
+ */
+static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out)
+{
+ bool first = TRUE;
+ time_t thisUpdate, nextUpdate, now = time(NULL);
+ enumerator_t *enumerator = list->create_enumerator(list);
+ certificate_t *cert;
+
+ while (enumerator->enumerate(enumerator, (void**)&cert))
+ {
+ crl_t *crl = (crl_t*)cert;
+ chunk_t serial = crl->get_serial(crl);
+ identification_t *authkey = crl->get_authKeyIdentifier(crl);
+
+ if (first)
+ {
+ fprintf(out, "\n");
+ fprintf(out, "List of X.509 CRLs:\n");
+ first = FALSE;
+ }
+ fprintf(out, "\n");
+
+ fprintf(out, " issuer: \"%D\"\n", cert->get_issuer(cert));
+
+ /* list optional crlNumber */
+ if (serial.ptr)
+ {
+ fprintf(out, " serial: %#B\n", &serial);
+ }
+
+ /* count the number of revoked certificates */
+ {
+ int count = 0;
+ enumerator_t *enumerator = crl->create_enumerator(crl);
+
+ while (enumerator->enumerate(enumerator, NULL, NULL, NULL))
+ {
+ count++;
+ }
+ fprintf(out, " revoked: %d certificate%s\n", count,
+ (count == 1)? "" : "s");
+ enumerator->destroy(enumerator);
+ }
+
+ /* list validity */
+ cert->get_validity(cert, &now, &thisUpdate, &nextUpdate);
+ fprintf(out, " updates: this %#T\n", &thisUpdate, utc);
+ fprintf(out, " next %#T, ", &nextUpdate, utc);
+ if (now > nextUpdate)
+ {
+ fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate);
+ }
+ else
+ {
+ fprintf(out, "ok");
+ if (now > nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
+ {
+ fprintf(out, " (expires in %#V)", &now, &nextUpdate);
+ }
+ fprintf(out, " \n");
+ }
+
+ /* list optional authorityKeyIdentifier */
+ if (authkey)
+ {
+ fprintf(out, " authkey: %D\n", authkey);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * list all OCSP responses
+ */
+static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out)
+{
+ bool first = TRUE;
+ enumerator_t *enumerator = list->create_enumerator(list);
+ certificate_t *cert;
+
+ while (enumerator->enumerate(enumerator, (void**)&cert))
+ {
+ if (first)
+ {
+ fprintf(out, "\n");
+ fprintf(out, "List of OCSP responses:\n");
+ fprintf(out, "\n");
+ first = FALSE;
+ }
+
+ fprintf(out, " signer: \"%D\"\n", cert->get_issuer(cert));
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * Implementation of stroke_list_t.list.
+ */
+static void list(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
+{
+ linked_list_t *cert_list = NULL;
+
+ if (msg->list.flags & (LIST_CERTS | LIST_CACERTS | LIST_OCSPCERTS | LIST_AACERTS))
+ {
+ cert_list = create_unique_cert_list(CERT_X509);
+ }
+ if (msg->list.flags & LIST_CERTS)
+ {
+ stroke_list_certs(cert_list, "X.509 End Entity Certificates",
+ 0, msg->list.utc, out);
+ }
+ if (msg->list.flags & LIST_CACERTS)
+ {
+ stroke_list_certs(cert_list, "X.509 CA Certificates",
+ X509_CA, msg->list.utc, out);
+ }
+ if (msg->list.flags & LIST_OCSPCERTS)
+ {
+ stroke_list_certs(cert_list, "X.509 OCSP Signer Certificates",
+ X509_OCSP_SIGNER, msg->list.utc, out);
+ }
+ if (msg->list.flags & LIST_AACERTS)
+ {
+ stroke_list_certs(cert_list, "X.509 AA Certificates",
+ X509_AA, msg->list.utc, out);
+ }
+ if (msg->list.flags & LIST_ACERTS)
+ {
+ linked_list_t *ac_list = create_unique_cert_list(CERT_X509_AC);
+
+ stroke_list_acerts(ac_list, msg->list.utc, out);
+ ac_list->destroy_offset(ac_list, offsetof(certificate_t, destroy));
+ }
+ if (msg->list.flags & LIST_CRLS)
+ {
+ linked_list_t *crl_list = create_unique_cert_list(CERT_X509_CRL);
+
+ stroke_list_crls(crl_list, msg->list.utc, out);
+ crl_list->destroy_offset(crl_list, offsetof(certificate_t, destroy));
+ }
+ if (msg->list.flags & LIST_OCSP)
+ {
+ linked_list_t *ocsp_list = create_unique_cert_list(CERT_X509_OCSP_RESPONSE);
+
+ stroke_list_ocsp(ocsp_list, msg->list.utc, out);
+ ocsp_list->destroy_offset(ocsp_list, offsetof(certificate_t, destroy));
+ }
+ DESTROY_OFFSET_IF(cert_list, offsetof(certificate_t, destroy));
+}
+
+/**
+ * Implementation of stroke_list_t.destroy
+ */
+static void destroy(private_stroke_list_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+stroke_list_t *stroke_list_create()
+{
+ private_stroke_list_t *this = malloc_thing(private_stroke_list_t);
+
+ this->public.list = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out))list;
+ this->public.status = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out,bool))status;
+ this->public.destroy = (void(*)(stroke_list_t*))destroy;
+
+ this->uptime = time(NULL);
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/stroke/stroke_list.h b/src/charon/plugins/stroke/stroke_list.h
new file mode 100644
index 000000000..dabdbff39
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_list.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup stroke_list stroke_list
+ * @{ @ingroup stroke
+ */
+
+#ifndef STROKE_LIST_H_
+#define STROKE_LIST_H_
+
+#include <stroke_msg.h>
+#include <library.h>
+
+typedef struct stroke_list_t stroke_list_t;
+
+/**
+ * Log status information to stroke console
+ */
+struct stroke_list_t {
+
+ /**
+ * List certificate information to stroke console.
+ *
+ * @param msg stroke message
+ * @param out stroke console stream
+ */
+ void (*list)(stroke_list_t *this, stroke_msg_t *msg, FILE *out);
+
+ /**
+ * Log status information to stroke console.
+ *
+ * @param msg stroke message
+ * @param out stroke console stream
+ * @param all TRUE for "statusall"
+ */
+ void (*status)(stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all);
+
+ /**
+ * Destroy a stroke_list instance.
+ */
+ void (*destroy)(stroke_list_t *this);
+};
+
+/**
+ * Create a stroke_list instance.
+ */
+stroke_list_t *stroke_list_create();
+
+#endif /* STROKE_LIST_H_ @}*/
diff --git a/src/charon/plugins/stroke/stroke_plugin.c b/src/charon/plugins/stroke/stroke_plugin.c
new file mode 100644
index 000000000..6933fc074
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_plugin.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "stroke_plugin.h"
+
+#include <library.h>
+#include "stroke_socket.h"
+
+typedef struct private_stroke_plugin_t private_stroke_plugin_t;
+
+/**
+ * private data of stroke_plugin
+ */
+struct private_stroke_plugin_t {
+
+ /**
+ * public functions
+ */
+ stroke_plugin_t public;
+
+ /**
+ * stroke socket, receives strokes
+ */
+ stroke_socket_t *socket;
+};
+
+/**
+ * Implementation of stroke_plugin_t.destroy
+ */
+static void destroy(private_stroke_plugin_t *this)
+{
+ this->socket->destroy(this->socket);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_stroke_plugin_t *this = malloc_thing(private_stroke_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ this->socket = stroke_socket_create();
+ if (this->socket == NULL)
+ {
+ free(this);
+ return NULL;
+ }
+ return &this->public.plugin;
+}
+
diff --git a/src/charon/control/interfaces/stroke_interface.h b/src/charon/plugins/stroke/stroke_plugin.h
index f1b68023a..7ea18b8af 100644
--- a/src/charon/control/interfaces/stroke_interface.h
+++ b/src/charon/plugins/stroke/stroke_plugin.h
@@ -1,12 +1,5 @@
-/**
- * @file stroke_interface.h
- *
- * @brief Interface of stroke_t.
- *
- */
-
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,43 +11,42 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: stroke.h 3589 2008-03-13 14:14:44Z martin $
*/
-#ifndef STROKE_INTERFACE_H_
-#define STROKE_INTERFACE_H_
+/**
+ * @defgroup stroke stroke
+ * @ingroup cplugins
+ *
+ * @defgroup stroke_plugin stroke_plugin
+ * @{ @ingroup stroke
+ */
+
+#ifndef STROKE_PLUGIN_H_
+#define STROKE_PLUGIN_H_
-typedef struct stroke_interface_t stroke_interface_t;
+#include <plugins/plugin.h>
-#include <control/interfaces/interface.h>
+typedef struct stroke_plugin_t stroke_plugin_t;
/**
- * @brief Simple configuration interface using unix-sockets.
- *
+ * strongSwan 2.x style configuration and control interface.
+ *
* Stroke is a home-brewed communication interface inspired by whack. It
* uses a unix socket (/var/run/charon.ctl).
- *
- * @b Constructors:
- * - stroke_create()
- *
- * @ingroup interfaces
*/
-struct stroke_interface_t {
-
+struct stroke_plugin_t {
+
/**
- * implements interface_t.
+ * implements plugin interface
*/
- interface_t interface;
+ plugin_t plugin;
};
-
/**
- * @brief Create the stroke interface and listen on the socket.
- *
- * @return interface_t for the stroke interface
- *
- * @ingroup interfaces
+ * Instanciate stroke plugin.
*/
-interface_t *interface_create(void);
-
-#endif /* STROKE_INTERFACE_H_ */
+plugin_t *plugin_create();
+#endif /* STROKE_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/stroke/stroke_shared_key.c b/src/charon/plugins/stroke/stroke_shared_key.c
new file mode 100644
index 000000000..9c21eb830
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_shared_key.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "stroke_shared_key.h"
+
+#include <utils/linked_list.h>
+
+typedef struct private_stroke_shared_key_t private_stroke_shared_key_t;
+
+/**
+ * private data of shared_key
+ */
+struct private_stroke_shared_key_t {
+
+ /**
+ * implements shared_key_t
+ */
+ stroke_shared_key_t public;
+
+ /**
+ * type of this key
+ */
+ shared_key_type_t type;
+
+ /**
+ * data of the key
+ */
+ chunk_t key;
+
+ /**
+ * list of key owners, as identification_t
+ */
+ linked_list_t *owners;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * Implementation of shared_key_t.get_type.
+ */
+static shared_key_type_t get_type(private_stroke_shared_key_t *this)
+{
+ return this->type;
+}
+
+/**
+ * Implementation of shared_key_t.get_ref.
+ */
+static private_stroke_shared_key_t* get_ref(private_stroke_shared_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of shared_key_t.get_key.
+ */
+static chunk_t get_key(private_stroke_shared_key_t *this)
+{
+ return this->key;
+}
+
+/**
+ * Implementation of stroke_shared_key_t.has_owner.
+ */
+static id_match_t has_owner(private_stroke_shared_key_t *this, identification_t *owner)
+{
+ enumerator_t *enumerator;
+ id_match_t match, best = ID_MATCH_NONE;
+ identification_t *current;
+
+ enumerator = this->owners->create_enumerator(this->owners);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ match = owner->matches(owner, current);
+ if (match > best)
+ {
+ best = match;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return best;
+}
+/**
+ * Implementation of stroke_shared_key_t.add_owner.
+ */
+static void add_owner(private_stroke_shared_key_t *this, identification_t *owner)
+{
+ this->owners->insert_last(this->owners, owner);
+}
+
+/**
+ * Implementation of stroke_shared_key_t.destroy
+ */
+static void destroy(private_stroke_shared_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->owners->destroy_offset(this->owners, offsetof(identification_t, destroy));
+ chunk_free(&this->key);
+ free(this);
+ }
+}
+
+/**
+ * create a shared key
+ */
+stroke_shared_key_t *stroke_shared_key_create(shared_key_type_t type, chunk_t key)
+{
+ private_stroke_shared_key_t *this = malloc_thing(private_stroke_shared_key_t);
+
+ this->public.shared.get_type = (shared_key_type_t(*)(shared_key_t*))get_type;
+ this->public.shared.get_key = (chunk_t(*)(shared_key_t*))get_key;
+ this->public.shared.get_ref = (shared_key_t*(*)(shared_key_t*))get_ref;
+ this->public.shared.destroy = (void(*)(shared_key_t*))destroy;
+ this->public.add_owner = (void(*)(stroke_shared_key_t*, identification_t *owner))add_owner;
+ this->public.has_owner = (id_match_t(*)(stroke_shared_key_t*, identification_t *owner))has_owner;
+
+ this->owners = linked_list_create();
+ this->type = type;
+ this->key = key;
+ this->ref = 1;
+
+ return &this->public;
+}
diff --git a/src/charon/plugins/stroke/stroke_shared_key.h b/src/charon/plugins/stroke/stroke_shared_key.h
new file mode 100644
index 000000000..e93d8cee2
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_shared_key.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup stroke_shared_key stroke_shared_key
+ * @{ @ingroup stroke
+ */
+
+#ifndef STROKE_SHARED_KEY_H_
+#define STROKE_SHARED_KEY_H_
+
+#include <utils/identification.h>
+#include <credentials/keys/shared_key.h>
+
+typedef struct stroke_shared_key_t stroke_shared_key_t;
+
+/**
+ * Shared key implementation for keys read from ipsec.secrets
+ */
+struct stroke_shared_key_t {
+
+ /**
+ * Implements the shared_key_t interface.
+ */
+ shared_key_t shared;
+
+ /**
+ * Add an owner to the key.
+ *
+ * @param owner owner to add
+ */
+ void (*add_owner)(stroke_shared_key_t *this, identification_t *owner);
+
+ /**
+ * Check if a key has a specific owner.
+ *
+ * @param owner owner to check
+ * @return best match found
+ */
+ id_match_t (*has_owner)(stroke_shared_key_t *this, identification_t *owner);
+};
+
+/**
+ * Create a stroke_shared_key instance.
+ */
+stroke_shared_key_t *stroke_shared_key_create(shared_key_type_t type, chunk_t key);
+
+#endif /* STROKE_SHARED_KEY_H_ @}*/
diff --git a/src/charon/plugins/stroke/stroke_socket.c b/src/charon/plugins/stroke/stroke_socket.c
new file mode 100644
index 000000000..92e295a0c
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_socket.c
@@ -0,0 +1,602 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "stroke_socket.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <processing/jobs/callback_job.h>
+#include <daemon.h>
+
+#include "stroke_config.h"
+#include "stroke_control.h"
+#include "stroke_cred.h"
+#include "stroke_ca.h"
+#include "stroke_attribute.h"
+#include "stroke_list.h"
+
+typedef struct stroke_job_context_t stroke_job_context_t;
+typedef struct private_stroke_socket_t private_stroke_socket_t;
+
+/**
+ * private data of stroke_socket
+ */
+struct private_stroke_socket_t {
+
+ /**
+ * public functions
+ */
+ stroke_socket_t public;
+
+ /**
+ * Unix socket to listen for strokes
+ */
+ int socket;
+
+ /**
+ * job accepting stroke messages
+ */
+ callback_job_t *job;
+
+ /**
+ * configuration backend
+ */
+ stroke_config_t *config;
+
+ /**
+ * attribute provider
+ */
+ stroke_attribute_t *attribute;
+
+ /**
+ * controller to control daemon
+ */
+ stroke_control_t *control;
+
+ /**
+ * credential set
+ */
+ stroke_cred_t *cred;
+
+ /**
+ * CA sections
+ */
+ stroke_ca_t *ca;
+
+ /**
+ * Status information logging
+ */
+ stroke_list_t *list;
+};
+
+/**
+ * job context to pass to processing thread
+ */
+struct stroke_job_context_t {
+
+ /**
+ * file descriptor to read from
+ */
+ int fd;
+
+ /**
+ * global stroke interface
+ */
+ private_stroke_socket_t *this;
+};
+
+/**
+ * Helper function which corrects the string pointers
+ * in a stroke_msg_t. Strings in a stroke_msg sent over "wire"
+ * contains RELATIVE addresses (relative to the beginning of the
+ * stroke_msg). They must be corrected if they reach our address
+ * space...
+ */
+static void pop_string(stroke_msg_t *msg, char **string)
+{
+ if (*string == NULL)
+ {
+ return;
+ }
+
+ /* check for sanity of string pointer and string */
+ if (string < (char**)msg ||
+ string > (char**)msg + sizeof(stroke_msg_t) ||
+ (unsigned long)*string < (unsigned long)((char*)msg->buffer - (char*)msg) ||
+ (unsigned long)*string > msg->length)
+ {
+ *string = "(invalid pointer in stroke msg)";
+ }
+ else
+ {
+ *string = (char*)msg + (unsigned long)*string;
+ }
+}
+
+/**
+ * Pop the strings of a stroke_end_t struct and log them for debugging purposes
+ */
+static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
+{
+ pop_string(msg, &end->address);
+ pop_string(msg, &end->subnets);
+ pop_string(msg, &end->sourceip);
+ pop_string(msg, &end->id);
+ pop_string(msg, &end->cert);
+ pop_string(msg, &end->ca);
+ pop_string(msg, &end->groups);
+ pop_string(msg, &end->updown);
+
+ DBG2(DBG_CFG, " %s=%s", label, end->address);
+ DBG2(DBG_CFG, " %ssubnet=%s", label, end->subnets);
+ DBG2(DBG_CFG, " %ssourceip=%s", label, end->sourceip);
+ DBG2(DBG_CFG, " %sid=%s", label, end->id);
+ DBG2(DBG_CFG, " %scert=%s", label, end->cert);
+ DBG2(DBG_CFG, " %sca=%s", label, end->ca);
+ DBG2(DBG_CFG, " %sgroups=%s", label, end->groups);
+ DBG2(DBG_CFG, " %supdown=%s", label, end->updown);
+}
+
+/**
+ * Add a connection to the configuration list
+ */
+static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg)
+{
+ pop_string(msg, &msg->add_conn.name);
+ DBG1(DBG_CFG, "received stroke: add connection '%s'", msg->add_conn.name);
+
+ DBG2(DBG_CFG, "conn %s", msg->add_conn.name);
+ pop_end(msg, "left", &msg->add_conn.me);
+ pop_end(msg, "right", &msg->add_conn.other);
+ pop_string(msg, &msg->add_conn.algorithms.ike);
+ pop_string(msg, &msg->add_conn.algorithms.esp);
+ pop_string(msg, &msg->add_conn.ikeme.mediated_by);
+ pop_string(msg, &msg->add_conn.ikeme.peerid);
+ DBG2(DBG_CFG, " ike=%s", msg->add_conn.algorithms.ike);
+ DBG2(DBG_CFG, " esp=%s", msg->add_conn.algorithms.esp);
+ DBG2(DBG_CFG, " mediation=%s", msg->add_conn.ikeme.mediation ? "yes" : "no");
+ DBG2(DBG_CFG, " mediated_by=%s", msg->add_conn.ikeme.mediated_by);
+ DBG2(DBG_CFG, " me_peerid=%s", msg->add_conn.ikeme.peerid);
+
+ this->config->add(this->config, msg);
+ this->attribute->add_pool(this->attribute, msg);
+}
+
+/**
+ * Delete a connection from the list
+ */
+static void stroke_del_conn(private_stroke_socket_t *this, stroke_msg_t *msg)
+{
+ pop_string(msg, &msg->del_conn.name);
+ DBG1(DBG_CFG, "received stroke: delete connection '%s'", msg->del_conn.name);
+
+ this->config->del(this->config, msg);
+ this->attribute->del_pool(this->attribute, msg);
+}
+
+/**
+ * initiate a connection by name
+ */
+static void stroke_initiate(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
+{
+ pop_string(msg, &msg->initiate.name);
+ DBG1(DBG_CFG, "received stroke: initiate '%s'", msg->initiate.name);
+
+ this->control->initiate(this->control, msg, out);
+}
+
+/**
+ * terminate a connection by name
+ */
+static void stroke_terminate(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
+{
+ pop_string(msg, &msg->terminate.name);
+ DBG1(DBG_CFG, "received stroke: terminate '%s'", msg->terminate.name);
+
+ this->control->terminate(this->control, msg, out);
+}
+
+/**
+ * route a policy (install SPD entries)
+ */
+static void stroke_route(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
+{
+ pop_string(msg, &msg->route.name);
+ DBG1(DBG_CFG, "received stroke: route '%s'", msg->route.name);
+
+ this->control->route(this->control, msg, out);
+}
+
+/**
+ * unroute a policy
+ */
+static void stroke_unroute(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
+{
+ pop_string(msg, &msg->terminate.name);
+ DBG1(DBG_CFG, "received stroke: unroute '%s'", msg->route.name);
+
+ this->control->unroute(this->control, msg, out);
+}
+
+/**
+ * Add a ca information record to the cainfo list
+ */
+static void stroke_add_ca(private_stroke_socket_t *this,
+ stroke_msg_t *msg, FILE *out)
+{
+ pop_string(msg, &msg->add_ca.name);
+ DBG1(DBG_CFG, "received stroke: add ca '%s'", msg->add_ca.name);
+
+ pop_string(msg, &msg->add_ca.cacert);
+ pop_string(msg, &msg->add_ca.crluri);
+ pop_string(msg, &msg->add_ca.crluri2);
+ pop_string(msg, &msg->add_ca.ocspuri);
+ pop_string(msg, &msg->add_ca.ocspuri2);
+ pop_string(msg, &msg->add_ca.certuribase);
+ DBG2(DBG_CFG, "ca %s", msg->add_ca.name);
+ DBG2(DBG_CFG, " cacert=%s", msg->add_ca.cacert);
+ DBG2(DBG_CFG, " crluri=%s", msg->add_ca.crluri);
+ DBG2(DBG_CFG, " crluri2=%s", msg->add_ca.crluri2);
+ DBG2(DBG_CFG, " ocspuri=%s", msg->add_ca.ocspuri);
+ DBG2(DBG_CFG, " ocspuri2=%s", msg->add_ca.ocspuri2);
+ DBG2(DBG_CFG, " certuribase=%s", msg->add_ca.certuribase);
+
+ this->ca->add(this->ca, msg);
+}
+
+/**
+ * Delete a ca information record from the cainfo list
+ */
+static void stroke_del_ca(private_stroke_socket_t *this,
+ stroke_msg_t *msg, FILE *out)
+{
+ pop_string(msg, &msg->del_ca.name);
+ DBG1(DBG_CFG, "received stroke: delete ca '%s'", msg->del_ca.name);
+
+ this->ca->del(this->ca, msg);
+}
+
+
+/**
+ * show status of daemon
+ */
+static void stroke_status(private_stroke_socket_t *this,
+ stroke_msg_t *msg, FILE *out, bool all)
+{
+ pop_string(msg, &(msg->status.name));
+
+ this->list->status(this->list, msg, out, all);
+}
+
+/**
+ * list various information
+ */
+static void stroke_list(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
+{
+ if (msg->list.flags & LIST_CAINFOS)
+ {
+ this->ca->list(this->ca, msg, out);
+ }
+ this->list->list(this->list, msg, out);
+}
+
+/**
+ * reread various information
+ */
+static void stroke_reread(private_stroke_socket_t *this,
+ stroke_msg_t *msg, FILE *out)
+{
+ this->cred->reread(this->cred, msg);
+}
+
+/**
+ * purge various information
+ */
+static void stroke_purge(private_stroke_socket_t *this,
+ stroke_msg_t *msg, FILE *out)
+{
+ charon->credentials->flush_cache(charon->credentials,
+ CERT_X509_OCSP_RESPONSE);
+}
+
+signal_t get_signal_from_logtype(char *type)
+{
+ if (strcasecmp(type, "any") == 0) return SIG_ANY;
+ else if (strcasecmp(type, "mgr") == 0) return DBG_MGR;
+ else if (strcasecmp(type, "ike") == 0) return DBG_IKE;
+ else if (strcasecmp(type, "chd") == 0) return DBG_CHD;
+ else if (strcasecmp(type, "job") == 0) return DBG_JOB;
+ else if (strcasecmp(type, "cfg") == 0) return DBG_CFG;
+ else if (strcasecmp(type, "knl") == 0) return DBG_KNL;
+ else if (strcasecmp(type, "net") == 0) return DBG_NET;
+ else if (strcasecmp(type, "enc") == 0) return DBG_ENC;
+ else if (strcasecmp(type, "lib") == 0) return DBG_LIB;
+ else return -1;
+}
+
+/**
+ * set the verbosity debug output
+ */
+static void stroke_loglevel(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
+{
+ signal_t signal;
+
+ pop_string(msg, &(msg->loglevel.type));
+ DBG1(DBG_CFG, "received stroke: loglevel %d for %s",
+ msg->loglevel.level, msg->loglevel.type);
+
+ signal = get_signal_from_logtype(msg->loglevel.type);
+ if (signal < 0)
+ {
+ fprintf(out, "invalid type (%s)!\n", msg->loglevel.type);
+ return;
+ }
+
+ charon->outlog->set_level(charon->outlog, signal, msg->loglevel.level);
+ charon->syslog->set_level(charon->syslog, signal, msg->loglevel.level);
+}
+
+/**
+ * set various config options
+ */
+static void stroke_config(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
+{
+ this->cred->cachecrl(this->cred, msg->config.cachecrl);
+}
+
+/**
+ * destroy a job context
+ */
+static void stroke_job_context_destroy(stroke_job_context_t *this)
+{
+ if (this->fd)
+ {
+ close(this->fd);
+ }
+ free(this);
+}
+
+/**
+ * process a stroke request from the socket pointed by "fd"
+ */
+static job_requeue_t process(stroke_job_context_t *ctx)
+{
+ stroke_msg_t *msg;
+ u_int16_t msg_length;
+ ssize_t bytes_read;
+ FILE *out;
+ private_stroke_socket_t *this = ctx->this;
+ int strokefd = ctx->fd;
+
+ /* peek the length */
+ bytes_read = recv(strokefd, &msg_length, sizeof(msg_length), MSG_PEEK);
+ if (bytes_read != sizeof(msg_length))
+ {
+ DBG1(DBG_CFG, "reading length of stroke message failed: %s",
+ strerror(errno));
+ return JOB_REQUEUE_NONE;
+ }
+
+ /* read message */
+ msg = alloca(msg_length);
+ bytes_read = recv(strokefd, msg, msg_length, 0);
+ if (bytes_read != msg_length)
+ {
+ DBG1(DBG_CFG, "reading stroke message failed: %s", strerror(errno));
+ return JOB_REQUEUE_NONE;
+ }
+
+ out = fdopen(strokefd, "w");
+ if (out == NULL)
+ {
+ DBG1(DBG_CFG, "opening stroke output channel failed: %s", strerror(errno));
+ return JOB_REQUEUE_NONE;
+ }
+
+ DBG3(DBG_CFG, "stroke message %b", (void*)msg, msg_length);
+
+ switch (msg->type)
+ {
+ case STR_INITIATE:
+ stroke_initiate(this, msg, out);
+ break;
+ case STR_ROUTE:
+ stroke_route(this, msg, out);
+ break;
+ case STR_UNROUTE:
+ stroke_unroute(this, msg, out);
+ break;
+ case STR_TERMINATE:
+ stroke_terminate(this, msg, out);
+ break;
+ case STR_STATUS:
+ stroke_status(this, msg, out, FALSE);
+ break;
+ case STR_STATUS_ALL:
+ stroke_status(this, msg, out, TRUE);
+ break;
+ case STR_ADD_CONN:
+ stroke_add_conn(this, msg);
+ break;
+ case STR_DEL_CONN:
+ stroke_del_conn(this, msg);
+ break;
+ case STR_ADD_CA:
+ stroke_add_ca(this, msg, out);
+ break;
+ case STR_DEL_CA:
+ stroke_del_ca(this, msg, out);
+ break;
+ case STR_LOGLEVEL:
+ stroke_loglevel(this, msg, out);
+ break;
+ case STR_CONFIG:
+ stroke_config(this, msg, out);
+ break;
+ case STR_LIST:
+ stroke_list(this, msg, out);
+ break;
+ case STR_REREAD:
+ stroke_reread(this, msg, out);
+ break;
+ case STR_PURGE:
+ stroke_purge(this, msg, out);
+ break;
+ default:
+ DBG1(DBG_CFG, "received unknown stroke");
+ break;
+ }
+ fclose(out);
+ /* fclose() closes underlying FD */
+ ctx->fd = 0;
+ return JOB_REQUEUE_NONE;
+}
+
+/**
+ * Implementation of private_stroke_socket_t.stroke_receive.
+ */
+static job_requeue_t receive(private_stroke_socket_t *this)
+{
+ struct sockaddr_un strokeaddr;
+ int strokeaddrlen = sizeof(strokeaddr);
+ int strokefd;
+ int oldstate;
+ callback_job_t *job;
+ stroke_job_context_t *ctx;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
+ strokefd = accept(this->socket, (struct sockaddr *)&strokeaddr, &strokeaddrlen);
+ pthread_setcancelstate(oldstate, NULL);
+
+ if (strokefd < 0)
+ {
+ DBG1(DBG_CFG, "accepting stroke connection failed: %s", strerror(errno));
+ 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);
+ charon->processor->queue_job(charon->processor, (job_t*)job);
+
+ return JOB_REQUEUE_FAIR;
+}
+
+
+/**
+ * initialize and open stroke socket
+ */
+static bool open_socket(private_stroke_socket_t *this)
+{
+ struct sockaddr_un socket_addr = { AF_UNIX, STROKE_SOCKET};
+ mode_t old;
+
+ /* set up unix socket */
+ this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (this->socket == -1)
+ {
+ DBG1(DBG_CFG, "could not create stroke socket");
+ return FALSE;
+ }
+
+ unlink(socket_addr.sun_path);
+ old = umask(~(S_IRWXU | S_IRWXG));
+ if (bind(this->socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr)) < 0)
+ {
+ DBG1(DBG_CFG, "could not bind stroke socket: %s", strerror(errno));
+ close(this->socket);
+ return FALSE;
+ }
+ umask(old);
+ if (chown(socket_addr.sun_path, charon->uid, charon->gid) != 0)
+ {
+ DBG1(DBG_CFG, "changing stroke socket permissions failed: %s",
+ strerror(errno));
+ }
+
+ if (listen(this->socket, 0) < 0)
+ {
+ DBG1(DBG_CFG, "could not listen on stroke socket: %s", strerror(errno));
+ close(this->socket);
+ unlink(socket_addr.sun_path);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Implementation of stroke_socket_t.destroy
+ */
+static void destroy(private_stroke_socket_t *this)
+{
+ this->job->cancel(this->job);
+ charon->credentials->remove_set(charon->credentials, &this->ca->set);
+ charon->credentials->remove_set(charon->credentials, &this->cred->set);
+ charon->backends->remove_backend(charon->backends, &this->config->backend);
+ charon->attributes->remove_provider(charon->attributes, &this->attribute->provider);
+ this->cred->destroy(this->cred);
+ this->ca->destroy(this->ca);
+ this->config->destroy(this->config);
+ this->attribute->destroy(this->attribute);
+ this->control->destroy(this->control);
+ this->list->destroy(this->list);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+stroke_socket_t *stroke_socket_create()
+{
+ private_stroke_socket_t *this = malloc_thing(private_stroke_socket_t);
+
+ this->public.destroy = (void(*)(stroke_socket_t*))destroy;
+
+ if (!open_socket(this))
+ {
+ free(this);
+ return NULL;
+ }
+
+ this->cred = stroke_cred_create();
+ this->attribute = stroke_attribute_create();
+ this->ca = stroke_ca_create(this->cred);
+ this->config = stroke_config_create(this->ca, this->cred);
+ this->control = stroke_control_create();
+ this->list = stroke_list_create();
+
+ charon->credentials->add_set(charon->credentials, &this->ca->set);
+ charon->credentials->add_set(charon->credentials, &this->cred->set);
+ charon->backends->add_backend(charon->backends, &this->config->backend);
+ charon->attributes->add_provider(charon->attributes, &this->attribute->provider);
+
+ this->job = callback_job_create((callback_job_cb_t)receive,
+ this, NULL, NULL);
+ charon->processor->queue_job(charon->processor, (job_t*)this->job);
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/stroke/stroke_socket.h b/src/charon/plugins/stroke/stroke_socket.h
new file mode 100644
index 000000000..7bc96686f
--- /dev/null
+++ b/src/charon/plugins/stroke/stroke_socket.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup stroke_socket stroke_socket
+ * @{ @ingroup stroke
+ */
+
+#ifndef STROKE_SOCKET_H_
+#define STROKE_SOCKET_H_
+
+typedef struct stroke_socket_t stroke_socket_t;
+
+/**
+ * Stroke socket, opens UNIX communication socket, reads and dispatches.
+ */
+struct stroke_socket_t {
+
+ /**
+ * Destroy a stroke_socket instance.
+ */
+ void (*destroy)(stroke_socket_t *this);
+};
+
+/**
+ * Create a stroke_socket instance.
+ */
+stroke_socket_t *stroke_socket_create();
+
+#endif /* STROKE_SOCKET_H_ @}*/
diff --git a/src/charon/plugins/uci/Makefile.am b/src/charon/plugins/uci/Makefile.am
new file mode 100644
index 000000000..47a55ae17
--- /dev/null
+++ b/src/charon/plugins/uci/Makefile.am
@@ -0,0 +1,13 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-uci.la
+libstrongswan_uci_la_SOURCES = \
+ uci_plugin.h uci_plugin.c uci_parser.h uci_parser.c \
+ uci_config.h uci_config.c uci_creds.h uci_creds.c
+libstrongswan_uci_la_LDFLAGS = -module
+libstrongswan_uci_la_LIBADD = -luci
+
+
diff --git a/src/charon/plugins/uci/Makefile.in b/src/charon/plugins/uci/Makefile.in
new file mode 100644
index 000000000..297f25768
--- /dev/null
+++ b/src/charon/plugins/uci/Makefile.in
@@ -0,0 +1,501 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@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/charon/plugins/uci
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_uci_la_DEPENDENCIES =
+am_libstrongswan_uci_la_OBJECTS = uci_plugin.lo uci_parser.lo \
+ uci_config.lo uci_creds.lo
+libstrongswan_uci_la_OBJECTS = $(am_libstrongswan_uci_la_OBJECTS)
+libstrongswan_uci_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_uci_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+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_uci_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_uci_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+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_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-uci.la
+libstrongswan_uci_la_SOURCES = \
+ uci_plugin.h uci_plugin.c uci_parser.h uci_parser.c \
+ uci_config.h uci_config.c uci_creds.h uci_creds.c
+
+libstrongswan_uci_la_LDFLAGS = -module
+libstrongswan_uci_la_LIBADD = -luci
+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 \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/uci/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/uci/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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-uci.la: $(libstrongswan_uci_la_OBJECTS) $(libstrongswan_uci_la_DEPENDENCIES)
+ $(libstrongswan_uci_la_LINK) -rpath $(plugindir) $(libstrongswan_uci_la_OBJECTS) $(libstrongswan_uci_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uci_config.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uci_creds.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uci_parser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uci_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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)
+
+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-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
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-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/charon/plugins/uci/uci_config.c b/src/charon/plugins/uci/uci_config.c
new file mode 100644
index 000000000..cc44eaa9b
--- /dev/null
+++ b/src/charon/plugins/uci/uci_config.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+
+#include "uci_config.h"
+#include "uci_parser.h"
+
+#include <daemon.h>
+
+typedef struct private_uci_config_t private_uci_config_t;
+
+/**
+ * Private data of an uci_config_t object
+ */
+struct private_uci_config_t {
+
+ /**
+ * Public part
+ */
+ uci_config_t public;
+
+ /**
+ * UCI parser context
+ */
+ uci_parser_t *parser;
+};
+
+/**
+ * enumerator implementation for create_peer_cfg_enumerator
+ */
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** currently enumerated peer config */
+ peer_cfg_t *peer_cfg;
+ /** inner uci_parser section enumerator */
+ enumerator_t *inner;
+} peer_enumerator_t;
+
+/**
+ * create a proposal from a string, with fallback to default
+ */
+static proposal_t *create_proposal(char *string, protocol_id_t proto)
+{
+ proposal_t *proposal = NULL;
+
+ if (string)
+ {
+ proposal = proposal_create_from_string(proto, string);
+ }
+ if (!proposal)
+ { /* UCI default is aes/sha1 only */
+ if (proto == PROTO_IKE)
+ {
+ proposal = proposal_create_from_string(proto,
+ "aes128-aes192-aes256-sha1-modp1536-modp2048");
+ }
+ else
+ {
+ proposal = proposal_create_from_string(proto,
+ "aes128-aes192-aes256-sha1");
+ }
+ }
+ return proposal;
+}
+
+/**
+ * create an identity, with fallback to %any
+ */
+static identification_t *create_id(char *string)
+{
+ identification_t *id = NULL;
+
+ if (string)
+ {
+ id = identification_create_from_string(string);
+ }
+ if (!id)
+ {
+ id = identification_create_from_encoding(ID_ANY, chunk_empty);
+ }
+ return id;
+}
+
+/**
+ * create an traffic selector, fallback to dynamic
+ */
+static traffic_selector_t *create_ts(char *string)
+{
+ if (string)
+ {
+ int netbits = 32;
+ host_t *net;
+ char *pos;
+
+ string = strdupa(string);
+ pos = strchr(string, '/');
+ if (pos)
+ {
+ *pos++ = '\0';
+ netbits = atoi(pos);
+ }
+ else
+ {
+ if (strchr(string, ':'))
+ {
+ netbits = 128;
+ }
+ }
+ net = host_create_from_string(string, 0);
+ if (net)
+ {
+ return traffic_selector_create_from_subnet(net, netbits, 0, 0);
+ }
+ }
+ return traffic_selector_create_dynamic(0, 0, 65535);
+}
+
+/**
+ * create a rekey time from a string with hours, with fallback
+ */
+static u_int create_rekey(char *string)
+{
+ u_int rekey = 0;
+
+ if (string)
+ {
+ rekey = atoi(string);
+ if (rekey)
+ {
+ return rekey * 3600;
+ }
+ }
+ /* every 12 hours */
+ return 12 * 3600;
+}
+
+/**
+ * Implementation of peer_enumerator_t.public.enumerate
+ */
+static bool peer_enumerator_enumerate(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;
+ char *remote_id, *remote_addr, *remote_net;
+ child_cfg_t *child_cfg;
+ ike_cfg_t *ike_cfg;
+
+ /* defaults */
+ name = "unnamed";
+ local_id = NULL;
+ remote_id = NULL;
+ local_addr = "0.0.0.0";
+ remote_addr = "0.0.0.0";
+ local_net = NULL;
+ remote_net = NULL;
+ ike_proposal = NULL;
+ esp_proposal = NULL;
+ ike_rekey = NULL;
+ esp_rekey = NULL;
+
+ if (this->inner->enumerate(this->inner, &name, &local_id, &remote_id,
+ &local_addr, &remote_addr, &local_net, &remote_net,
+ &ike_proposal, &esp_proposal, &ike_rekey, &esp_rekey))
+ {
+ DESTROY_IF(this->peer_cfg);
+ ike_cfg = ike_cfg_create(FALSE, FALSE, local_addr, remote_addr);
+ ike_cfg->add_proposal(ike_cfg, create_proposal(ike_proposal, PROTO_IKE));
+ this->peer_cfg = peer_cfg_create(
+ name, 2, ike_cfg, create_id(local_id), create_id(remote_id),
+ CERT_SEND_IF_ASKED, UNIQUE_NO, CONF_AUTH_PSK,
+ 0, 0, /* EAP method, vendor */
+ 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 */
+ child_cfg = child_cfg_create(name,
+ create_rekey(esp_rekey) + 300, create_rekey(ike_rekey), 300,
+ NULL, TRUE, MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE);
+ child_cfg->add_proposal(child_cfg, create_proposal(esp_proposal, PROTO_ESP));
+ child_cfg->add_traffic_selector(child_cfg, TRUE, create_ts(local_net));
+ child_cfg->add_traffic_selector(child_cfg, FALSE, create_ts(remote_net));
+ this->peer_cfg->add_child_cfg(this->peer_cfg, child_cfg);
+ *cfg = this->peer_cfg;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of peer_enumerator_t.public.destroy
+ */
+static void peer_enumerator_destroy(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)
+{
+ 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,
+ "local_id", "remote_id", "local_addr", "remote_addr",
+ "local_net", "remote_net", "ike_proposal", "esp_proposal",
+ "ike_rekey", "esp_rekey", NULL);
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * enumerator implementation for create_ike_cfg_enumerator
+ */
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** currently enumerated ike config */
+ ike_cfg_t *ike_cfg;
+ /** inner uci_parser section enumerator */
+ 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)
+{
+ char *local_addr, *remote_addr, *ike_proposal;
+
+ /* defaults */
+ local_addr = "0.0.0.0";
+ remote_addr = "0.0.0.0";
+ ike_proposal = NULL;
+
+ if (this->inner->enumerate(this->inner, NULL,
+ &local_addr, &remote_addr, &ike_proposal))
+ {
+ DESTROY_IF(this->ike_cfg);
+ this->ike_cfg = ike_cfg_create(FALSE, FALSE, local_addr, remote_addr);
+ this->ike_cfg->add_proposal(this->ike_cfg,
+ create_proposal(ike_proposal, PROTO_IKE));
+
+ *cfg = this->ike_cfg;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of ike_enumerator_t.public.destroy
+ */
+static void ike_enumerator_destroy(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)
+{
+ 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);
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ 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)
+{
+ enumerator_t *enumerator;
+ peer_cfg_t *current, *found = NULL;
+
+ enumerator = create_peer_cfg_enumerator(this, NULL, NULL);
+ if (enumerator)
+ {
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (streq(name, current->get_name(current)))
+ {
+ found = current->get_ref(current);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ return found;
+}
+
+/**
+ * Implementation of uci_config_t.destroy.
+ */
+static void destroy(private_uci_config_t *this)
+{
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+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;
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/uci/uci_config.h b/src/charon/plugins/uci/uci_config.h
new file mode 100644
index 000000000..4d8b286c6
--- /dev/null
+++ b/src/charon/plugins/uci/uci_config.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup uci_config_t uci_config
+ * @{ @ingroup uci
+ */
+
+#ifndef UCI_CONFIG_H_
+#define UCI_CONFIG_H_
+
+#include "uci_parser.h"
+
+#include <config/backend.h>
+
+typedef struct uci_config_t uci_config_t;
+
+/**
+ * OpenWRT UCI configuration backend.
+ */
+struct uci_config_t {
+
+ /**
+ * Implements backend_t interface
+ */
+ backend_t backend;
+
+ /**
+ * Destroy the backend.
+ */
+ void (*destroy)(uci_config_t *this);
+};
+
+/**
+ * Create a UCI based configuration backend.
+ *
+ * @param parser UCI parser to use
+ * @return configuration backend
+ */
+uci_config_t *uci_config_create(uci_parser_t *parser);
+
+#endif /* UCI_CONFIG_H_ @}*/
diff --git a/src/charon/plugins/uci/uci_creds.c b/src/charon/plugins/uci/uci_creds.c
new file mode 100644
index 000000000..60f6fc934
--- /dev/null
+++ b/src/charon/plugins/uci/uci_creds.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "uci_creds.h"
+
+#include <daemon.h>
+#include <credentials/keys/shared_key.h>
+#include <utils/identification.h>
+
+typedef struct private_uci_creds_t private_uci_creds_t;
+
+/**
+ * Private data of an uci_creds_t object
+ */
+struct private_uci_creds_t {
+ /**
+ * Public part
+ */
+ uci_creds_t public;
+
+ /**
+ * UCI parser context
+ */
+ uci_parser_t *parser;
+};
+
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** inneer UCI enumerator */
+ enumerator_t *inner;
+ /** currently enumerated shared shared */
+ shared_key_t *current;
+ /** local ID to match */
+ identification_t *me;
+ /** remote ID to match */
+ 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)
+{
+ char *local_id, *remote_id, *psk;
+ identification_t *local, *remote;
+
+ while (TRUE)
+ {
+ /* defaults */
+ local_id = "%any";
+ remote_id = "%any";
+ psk = NULL;
+
+ if (!this->inner->enumerate(this->inner, NULL,
+ &local_id, &remote_id, &psk))
+ {
+ return FALSE;
+ }
+ if (psk == NULL)
+ {
+ continue;
+ }
+ if (me)
+ {
+ local = identification_create_from_string(local_id);
+ if (!local)
+ {
+ continue;
+ }
+ *me = this->me ? this->me->matches(this->me, local)
+ : ID_MATCH_ANY;
+ local->destroy(local);
+ if (!*me)
+ {
+ continue;
+ }
+ }
+ if (other)
+ {
+ remote = identification_create_from_string(remote_id);
+ if (!remote)
+ {
+ continue;
+ }
+ *other = this->other ? this->other->matches(this->other, remote)
+ : ID_MATCH_ANY;
+ remote->destroy(remote);
+ if (!*other)
+ {
+ continue;
+ }
+ }
+ break;
+ }
+ DESTROY_IF(this->current);
+ this->current = shared_key_create(SHARED_IKE,
+ chunk_clone(chunk_create(psk, strlen(psk))));
+ *key = this->current;
+ return TRUE;
+}
+
+/**
+ * Implementation of shared_enumerator_t.public.destroy
+ */
+static void shared_enumerator_destroy(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)
+{
+ shared_enumerator_t *e;
+
+ if (type != SHARED_IKE)
+ {
+ 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);
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * Implementation of uci_creds_t.destroy
+ */
+static void destroy(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;
+
+ this->parser = parser;
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/uci/uci_creds.h b/src/charon/plugins/uci/uci_creds.h
new file mode 100644
index 000000000..cf82f1c07
--- /dev/null
+++ b/src/charon/plugins/uci/uci_creds.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup uci_creds_t uci_creds
+ * @{ @ingroup uci
+ */
+
+#ifndef UCI_CREDS_H_
+#define UCI_CREDS_H_
+
+#include "uci_parser.h"
+
+#include <credentials/credential_set.h>
+
+typedef struct uci_creds_t uci_creds_t;
+
+/**
+ * OpenWRT UCI credential set implementation.
+ */
+struct uci_creds_t {
+
+ /**
+ * Implements credential set interface.
+ */
+ credential_set_t credential_set;
+
+ /**
+ * Destroy the backend.
+ */
+ void (*destroy)(uci_creds_t *this);
+};
+
+/**
+ * Create a UCI based credential set.
+ *
+ * @param parser UCI parser to use
+ * @return credential set
+ */
+uci_creds_t *uci_creds_create(uci_parser_t *parser);
+
+#endif /* UCI_CREDS_H_ @}*/
diff --git a/src/charon/plugins/uci/uci_parser.c b/src/charon/plugins/uci/uci_parser.c
new file mode 100644
index 000000000..796d2993a
--- /dev/null
+++ b/src/charon/plugins/uci/uci_parser.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "uci_parser.h"
+
+#include <stdarg.h>
+
+#include <library.h>
+#include <uci.h>
+
+typedef struct private_uci_parser_t private_uci_parser_t;
+
+/**
+ * Private data of an uci_parser_t object
+ */
+struct private_uci_parser_t {
+
+ /**
+ * Public part
+ */
+ uci_parser_t public;
+
+ /**
+ * UCI package name this parser reads
+ */
+ char *package;
+};
+
+/**
+ * enumerator implementation create_section_enumerator
+ */
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** currently enumerated uci section */
+ struct uci_element *current;
+ /** all uci ipsec config sections */
+ struct uci_list *list;
+ /** uci conntext */
+ struct uci_context *ctx;
+ /** ipsec uci package */
+ struct uci_package *package;
+ /** NULL terminated list of keywords */
+ char *keywords[];
+} section_enumerator_t;
+
+/**
+ * Implementation of section_enumerator_t.enumerate
+ */
+static bool section_enumerator_enumerate(section_enumerator_t *this, ...)
+{
+ struct uci_element *element;
+ char **value;
+ va_list args;
+ int i;
+
+ if (&this->current->list == this->list)
+ {
+ return FALSE;
+ }
+
+ va_start(args, this);
+
+ /* name is first parameter */
+ value = va_arg(args, char**);
+ if (value)
+ {
+ *value = uci_to_section(this->current)->type;
+ }
+
+ /* followed by keyword parameters */
+ for (i = 0; this->keywords[i]; i++)
+ {
+ value = va_arg(args, char**);
+ if (value && uci_lookup(this->ctx, &element, this->package,
+ this->current->name, this->keywords[i]) == UCI_OK)
+ {
+ *value = uci_to_option(element)->value;
+ }
+ }
+ va_end(args);
+
+ this->current = list_to_element(this->current->list.next);
+ return TRUE;
+}
+
+/**
+ * Implementation of section_enumerator_t.public.destroy
+ */
+static void section_enumerator_destroy(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, ...)
+{
+ section_enumerator_t *e;
+ va_list args;
+ int i;
+
+ /* allocate enumerator large enought to hold keyword pointers */
+ i = 1;
+ va_start(args, this);
+ while (va_arg(args, char*))
+ {
+ i++;
+ }
+ va_end(args);
+ e = malloc(sizeof(section_enumerator_t) + sizeof(char*) * i);
+ i = 0;
+ va_start(args, this);
+ do
+ {
+ e->keywords[i] = va_arg(args, char*);
+ }
+ while (e->keywords[i++]);
+ va_end(args);
+
+ e->public.enumerate = (void*)section_enumerator_enumerate;
+ e->public.destroy = (void*)section_enumerator_destroy;
+
+ /* load uci context */
+ e->ctx = uci_alloc_context();
+ if (uci_load(e->ctx, this->package, &e->package) != UCI_OK)
+ {
+ section_enumerator_destroy(e);
+ return NULL;
+ }
+ e->list = &e->package->sections;
+ e->current = list_to_element(e->list->next);
+ if (e->current->type != UCI_TYPE_SECTION)
+ {
+ section_enumerator_destroy(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+/**
+ * Implementation of uci_parser_t.destroy.
+ */
+static void destroy(private_uci_parser_t *this)
+{
+ free(this->package);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+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);
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/uci/uci_parser.h b/src/charon/plugins/uci/uci_parser.h
new file mode 100644
index 000000000..a8633ca2e
--- /dev/null
+++ b/src/charon/plugins/uci/uci_parser.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup uci_parser_t uci_parser
+ * @{ @ingroup uci
+ */
+
+#ifndef UCI_PARSER_H_
+#define UCI_PARSER_H_
+
+#include <utils/enumerator.h>
+
+typedef struct uci_parser_t uci_parser_t;
+
+/**
+ * Wrapper to parse UCI sections with an enumerator.
+ */
+struct uci_parser_t {
+
+ /**
+ * Create an enumerator over a section.
+ *
+ * The enumerator returns a section name followed by values for the keywords
+ * specified in the variable argument list of this function.
+ *
+ * @param ... variable argument list with keywords, NULL terminated
+ * @return enumerator over sections
+ */
+ enumerator_t* (*create_section_enumerator)(uci_parser_t *this, ...);
+
+ /**
+ * Destroy the parser.
+ */
+ void (*destroy)(uci_parser_t *this);
+};
+
+/**
+ * Create a UCI parser.
+ *
+ * @param package UCI package this parser should read
+ * @return parser context
+ */
+uci_parser_t *uci_parser_create(char *package);
+
+#endif /* UCI_PARSER_H_ @}*/
+
diff --git a/src/charon/plugins/uci/uci_plugin.c b/src/charon/plugins/uci/uci_plugin.c
new file mode 100644
index 000000000..918523826
--- /dev/null
+++ b/src/charon/plugins/uci/uci_plugin.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "uci_plugin.h"
+#include "uci_config.h"
+#include "uci_creds.h"
+
+#include <daemon.h>
+
+/**
+ * UCI package name to use for lookups
+ */
+#define UCI_PACKAGE "strongswan"
+
+typedef struct private_uci_plugin_t private_uci_plugin_t;
+
+/**
+ * private data of uci plugin
+ */
+struct private_uci_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ uci_plugin_t public;
+
+ /**
+ * UCI configuration backend
+ */
+ uci_config_t *config;
+
+ /**
+ * UCI credential set implementation
+ */
+ uci_creds_t *creds;
+
+ /**
+ * UCI parser wrapper
+ */
+ uci_parser_t *parser;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_uci_plugin_t *this)
+{
+ charon->backends->remove_backend(charon->backends, &this->config->backend);
+ charon->credentials->remove_set(charon->credentials, &this->creds->credential_set);
+ this->config->destroy(this->config);
+ this->creds->destroy(this->creds);
+ this->parser->destroy(this->parser);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_uci_plugin_t *this = malloc_thing(private_uci_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ this->parser = uci_parser_create(UCI_PACKAGE);
+ this->config = uci_config_create(this->parser);
+ this->creds = uci_creds_create(this->parser);
+ charon->backends->add_backend(charon->backends, &this->config->backend);
+ charon->credentials->add_set(charon->credentials, &this->creds->credential_set);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/uci/uci_plugin.h b/src/charon/plugins/uci/uci_plugin.h
new file mode 100644
index 000000000..cac95dc13
--- /dev/null
+++ b/src/charon/plugins/uci/uci_plugin.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup uci uci
+ * @ingroup cplugins
+ *
+ * @defgroup uci_plugin uci_plugin
+ * @{ @ingroup uci
+ */
+
+#ifndef UCI_PLUGIN_H_
+#define UCI_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct uci_plugin_t uci_plugin_t;
+
+/**
+ * OpenWRT UCI (Unified Configuration Interface) configuration plugin.
+ */
+struct uci_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a uci_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* UCI_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/unit_tester/Makefile.am b/src/charon/plugins/unit_tester/Makefile.am
new file mode 100644
index 000000000..2487cf207
--- /dev/null
+++ b/src/charon/plugins/unit_tester/Makefile.am
@@ -0,0 +1,21 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-unit-tester.la
+
+libstrongswan_unit_tester_la_SOURCES = unit_tester.c unit_tester.h \
+ tests/test_enumerator.c \
+ tests/test_auth_info.c \
+ tests/test_fips_prf.c \
+ tests/test_curl.c \
+ tests/test_mysql.c \
+ tests/test_sqlite.c \
+ tests/test_mutex.c \
+ tests/test_rsa_gen.c \
+ tests/test_med_db.c \
+ tests/test_aes.c \
+ tests/test_chunk.c
+libstrongswan_unit_tester_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/unit_tester/Makefile.in b/src/charon/plugins/unit_tester/Makefile.in
new file mode 100644
index 000000000..fe5dfa6cf
--- /dev/null
+++ b/src/charon/plugins/unit_tester/Makefile.in
@@ -0,0 +1,598 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@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/charon/plugins/unit_tester
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_unit_tester_la_LIBADD =
+am_libstrongswan_unit_tester_la_OBJECTS = unit_tester.lo \
+ test_enumerator.lo test_auth_info.lo test_fips_prf.lo \
+ test_curl.lo test_mysql.lo test_sqlite.lo test_mutex.lo \
+ test_rsa_gen.lo test_med_db.lo test_aes.lo test_chunk.lo
+libstrongswan_unit_tester_la_OBJECTS = \
+ $(am_libstrongswan_unit_tester_la_OBJECTS)
+libstrongswan_unit_tester_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_unit_tester_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+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_unit_tester_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_unit_tester_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+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_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-unit-tester.la
+libstrongswan_unit_tester_la_SOURCES = unit_tester.c unit_tester.h \
+ tests/test_enumerator.c \
+ tests/test_auth_info.c \
+ tests/test_fips_prf.c \
+ tests/test_curl.c \
+ tests/test_mysql.c \
+ tests/test_sqlite.c \
+ tests/test_mutex.c \
+ tests/test_rsa_gen.c \
+ tests/test_med_db.c \
+ tests/test_aes.c \
+ tests/test_chunk.c
+
+libstrongswan_unit_tester_la_LDFLAGS = -module
+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 \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/unit_tester/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/unit_tester/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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-unit-tester.la: $(libstrongswan_unit_tester_la_OBJECTS) $(libstrongswan_unit_tester_la_DEPENDENCIES)
+ $(libstrongswan_unit_tester_la_LINK) -rpath $(plugindir) $(libstrongswan_unit_tester_la_OBJECTS) $(libstrongswan_unit_tester_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_aes.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_info.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_chunk.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_curl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_enumerator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fips_prf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_med_db.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_mutex.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_mysql.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_rsa_gen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_sqlite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unit_tester.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(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@ mv -f $(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@ mv -f $(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 $@ $<
+
+test_enumerator.lo: tests/test_enumerator.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_enumerator.lo -MD -MP -MF $(DEPDIR)/test_enumerator.Tpo -c -o test_enumerator.lo `test -f 'tests/test_enumerator.c' || echo '$(srcdir)/'`tests/test_enumerator.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_enumerator.Tpo $(DEPDIR)/test_enumerator.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_enumerator.c' object='test_enumerator.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_enumerator.lo `test -f 'tests/test_enumerator.c' || echo '$(srcdir)/'`tests/test_enumerator.c
+
+test_auth_info.lo: tests/test_auth_info.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_auth_info.lo -MD -MP -MF $(DEPDIR)/test_auth_info.Tpo -c -o test_auth_info.lo `test -f 'tests/test_auth_info.c' || echo '$(srcdir)/'`tests/test_auth_info.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_auth_info.Tpo $(DEPDIR)/test_auth_info.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_auth_info.c' object='test_auth_info.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_auth_info.lo `test -f 'tests/test_auth_info.c' || echo '$(srcdir)/'`tests/test_auth_info.c
+
+test_fips_prf.lo: tests/test_fips_prf.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_fips_prf.lo -MD -MP -MF $(DEPDIR)/test_fips_prf.Tpo -c -o test_fips_prf.lo `test -f 'tests/test_fips_prf.c' || echo '$(srcdir)/'`tests/test_fips_prf.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_fips_prf.Tpo $(DEPDIR)/test_fips_prf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_fips_prf.c' object='test_fips_prf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_fips_prf.lo `test -f 'tests/test_fips_prf.c' || echo '$(srcdir)/'`tests/test_fips_prf.c
+
+test_curl.lo: tests/test_curl.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_curl.lo -MD -MP -MF $(DEPDIR)/test_curl.Tpo -c -o test_curl.lo `test -f 'tests/test_curl.c' || echo '$(srcdir)/'`tests/test_curl.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_curl.Tpo $(DEPDIR)/test_curl.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_curl.c' object='test_curl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_curl.lo `test -f 'tests/test_curl.c' || echo '$(srcdir)/'`tests/test_curl.c
+
+test_mysql.lo: tests/test_mysql.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_mysql.lo -MD -MP -MF $(DEPDIR)/test_mysql.Tpo -c -o test_mysql.lo `test -f 'tests/test_mysql.c' || echo '$(srcdir)/'`tests/test_mysql.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_mysql.Tpo $(DEPDIR)/test_mysql.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_mysql.c' object='test_mysql.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_mysql.lo `test -f 'tests/test_mysql.c' || echo '$(srcdir)/'`tests/test_mysql.c
+
+test_sqlite.lo: tests/test_sqlite.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_sqlite.lo -MD -MP -MF $(DEPDIR)/test_sqlite.Tpo -c -o test_sqlite.lo `test -f 'tests/test_sqlite.c' || echo '$(srcdir)/'`tests/test_sqlite.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_sqlite.Tpo $(DEPDIR)/test_sqlite.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_sqlite.c' object='test_sqlite.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_sqlite.lo `test -f 'tests/test_sqlite.c' || echo '$(srcdir)/'`tests/test_sqlite.c
+
+test_mutex.lo: tests/test_mutex.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_mutex.lo -MD -MP -MF $(DEPDIR)/test_mutex.Tpo -c -o test_mutex.lo `test -f 'tests/test_mutex.c' || echo '$(srcdir)/'`tests/test_mutex.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_mutex.Tpo $(DEPDIR)/test_mutex.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_mutex.c' object='test_mutex.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_mutex.lo `test -f 'tests/test_mutex.c' || echo '$(srcdir)/'`tests/test_mutex.c
+
+test_rsa_gen.lo: tests/test_rsa_gen.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_rsa_gen.lo -MD -MP -MF $(DEPDIR)/test_rsa_gen.Tpo -c -o test_rsa_gen.lo `test -f 'tests/test_rsa_gen.c' || echo '$(srcdir)/'`tests/test_rsa_gen.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_rsa_gen.Tpo $(DEPDIR)/test_rsa_gen.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_rsa_gen.c' object='test_rsa_gen.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_rsa_gen.lo `test -f 'tests/test_rsa_gen.c' || echo '$(srcdir)/'`tests/test_rsa_gen.c
+
+test_med_db.lo: tests/test_med_db.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_med_db.lo -MD -MP -MF $(DEPDIR)/test_med_db.Tpo -c -o test_med_db.lo `test -f 'tests/test_med_db.c' || echo '$(srcdir)/'`tests/test_med_db.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_med_db.Tpo $(DEPDIR)/test_med_db.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_med_db.c' object='test_med_db.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_med_db.lo `test -f 'tests/test_med_db.c' || echo '$(srcdir)/'`tests/test_med_db.c
+
+test_aes.lo: tests/test_aes.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_aes.lo -MD -MP -MF $(DEPDIR)/test_aes.Tpo -c -o test_aes.lo `test -f 'tests/test_aes.c' || echo '$(srcdir)/'`tests/test_aes.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_aes.Tpo $(DEPDIR)/test_aes.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_aes.c' object='test_aes.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_aes.lo `test -f 'tests/test_aes.c' || echo '$(srcdir)/'`tests/test_aes.c
+
+test_chunk.lo: tests/test_chunk.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_chunk.lo -MD -MP -MF $(DEPDIR)/test_chunk.Tpo -c -o test_chunk.lo `test -f 'tests/test_chunk.c' || echo '$(srcdir)/'`tests/test_chunk.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_chunk.Tpo $(DEPDIR)/test_chunk.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_chunk.c' object='test_chunk.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_chunk.lo `test -f 'tests/test_chunk.c' || echo '$(srcdir)/'`tests/test_chunk.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ 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)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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)
+
+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-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
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-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/charon/plugins/unit_tester/tests/test_aes.c b/src/charon/plugins/unit_tester/tests/test_aes.c
new file mode 100644
index 000000000..06e891d83
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_aes.c
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <daemon.h>
+#include <library.h>
+#include <utils/mutex.h>
+
+#include <unistd.h>
+#include <sched.h>
+#include <pthread.h>
+
+/**
+ * run a test using given values
+ */
+static bool do_aes_test(u_char *key, int keysize, u_char *iv,
+ u_char *plain, u_char *cipher, int len)
+{
+ crypter_t *crypter;
+ chunk_t enc, dec;
+ bool good = TRUE;
+
+ crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, keysize);
+ if (!crypter)
+ {
+ return FALSE;
+ }
+ crypter->set_key(crypter, chunk_create(key, keysize));
+ crypter->encrypt(crypter,
+ chunk_create(plain, len), chunk_create(iv, 16), &enc);
+ if (!memeq(enc.ptr, cipher, len))
+ {
+ good = FALSE;
+ }
+ crypter->decrypt(crypter, enc, chunk_create(iv, 16), &dec);
+ if (!memeq(dec.ptr, plain, len))
+ {
+ good = FALSE;
+ }
+ free(enc.ptr);
+ free(dec.ptr);
+ crypter->destroy(crypter);
+ return good;
+}
+
+/*******************************************************************************
+ * AES-128 test
+ ******************************************************************************/
+bool test_aes128()
+{
+ /*
+ * Test 1 of RFC3602
+ * Key : 0x06a9214036b8a15b512e03d534120006
+ * IV : 0x3dafba429d9eb430b422da802c9fac41
+ * Plaintext : "Single block msg"
+ * Ciphertext: 0xe353779c1079aeb82708942dbe77181a
+ */
+ u_char key1[] = {
+ 0x06,0xa9,0x21,0x40,0x36,0xb8,0xa1,0x5b,
+ 0x51,0x2e,0x03,0xd5,0x34,0x12,0x00,0x06
+ };
+ u_char iv1[] = {
+ 0x3d,0xaf,0xba,0x42,0x9d,0x9e,0xb4,0x30,
+ 0xb4,0x22,0xda,0x80,0x2c,0x9f,0xac,0x41
+ };
+ u_char plain1[] = {
+ 'S','i','n','g','l','e',' ','b','l','o','c','k',' ','m','s','g'
+ };
+ u_char cipher1[] = {
+ 0xe3,0x53,0x77,0x9c,0x10,0x79,0xae,0xb8,
+ 0x27,0x08,0x94,0x2d,0xbe,0x77,0x18,0x1a
+ };
+ if (!do_aes_test(key1, 16, iv1, plain1, cipher1, sizeof(plain1)))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Test 2 of RFC3602
+ * Key : 0xc286696d887c9aa0611bbb3e2025a45a
+ * IV : 0x562e17996d093d28ddb3ba695a2e6f58
+ * Plaintext : 0x000102030405060708090a0b0c0d0e0f
+ * 101112131415161718191a1b1c1d1e1f
+ * Ciphertext: 0xd296cd94c2cccf8a3a863028b5e1dc0a
+ * 7586602d253cfff91b8266bea6d61ab1
+ */
+ u_char key2[] = {
+ 0xc2,0x86,0x69,0x6d,0x88,0x7c,0x9a,0xa0,
+ 0x61,0x1b,0xbb,0x3e,0x20,0x25,0xa4,0x5a
+ };
+ u_char iv2[] = {
+ 0x56,0x2e,0x17,0x99,0x6d,0x09,0x3d,0x28,
+ 0xdd,0xb3,0xba,0x69,0x5a,0x2e,0x6f,0x58
+ };
+ u_char plain2[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
+ };
+ u_char cipher2[] = {
+ 0xd2,0x96,0xcd,0x94,0xc2,0xcc,0xcf,0x8a,
+ 0x3a,0x86,0x30,0x28,0xb5,0xe1,0xdc,0x0a,
+ 0x75,0x86,0x60,0x2d,0x25,0x3c,0xff,0xf9,
+ 0x1b,0x82,0x66,0xbe,0xa6,0xd6,0x1a,0xb1
+ };
+ if (!do_aes_test(key2, 16, iv2, plain2, cipher2, sizeof(plain2)))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Test 3 of RFC3603
+ * Key : 0x56e47a38c5598974bc46903dba290349
+ * IV : 0x8ce82eefbea0da3c44699ed7db51b7d9
+ * Plaintext : 0xa0a1a2a3a4a5a6a7a8a9aaabacadaeaf
+ * b0b1b2b3b4b5b6b7b8b9babbbcbdbebf
+ * c0c1c2c3c4c5c6c7c8c9cacbcccdcecf
+ * d0d1d2d3d4d5d6d7d8d9dadbdcdddedf
+ * Ciphertext: 0xc30e32ffedc0774e6aff6af0869f71aa
+ * 0f3af07a9a31a9c684db207eb0ef8e4e
+ * 35907aa632c3ffdf868bb7b29d3d46ad
+ * 83ce9f9a102ee99d49a53e87f4c3da55
+ */
+ u_char key3[] = {
+ 0x56,0xe4,0x7a,0x38,0xc5,0x59,0x89,0x74,
+ 0xbc,0x46,0x90,0x3d,0xba,0x29,0x03,0x49
+ };
+ u_char iv3[] = {
+ 0x8c,0xe8,0x2e,0xef,0xbe,0xa0,0xda,0x3c,
+ 0x44,0x69,0x9e,0xd7,0xdb,0x51,0xb7,0xd9
+ };
+ u_char plain3[] = {
+ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
+ 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,
+ 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+ 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,
+ 0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
+ 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,
+ 0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf
+ };
+ u_char cipher3[] = {
+ 0xc3,0x0e,0x32,0xff,0xed,0xc0,0x77,0x4e,
+ 0x6a,0xff,0x6a,0xf0,0x86,0x9f,0x71,0xaa,
+ 0x0f,0x3a,0xf0,0x7a,0x9a,0x31,0xa9,0xc6,
+ 0x84,0xdb,0x20,0x7e,0xb0,0xef,0x8e,0x4e,
+ 0x35,0x90,0x7a,0xa6,0x32,0xc3,0xff,0xdf,
+ 0x86,0x8b,0xb7,0xb2,0x9d,0x3d,0x46,0xad,
+ 0x83,0xce,0x9f,0x9a,0x10,0x2e,0xe9,0x9d,
+ 0x49,0xa5,0x3e,0x87,0xf4,0xc3,0xda,0x55
+ };
+ if (!do_aes_test(key3, 16, iv3, plain3, cipher3, sizeof(plain3)))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * run a single xcbc test for prf and signer
+ */
+static bool do_xcbc_test(u_int8_t *key, size_t keylen, u_int8_t *mac,
+ u_int8_t *plain, size_t len)
+{
+ signer_t *signer;
+ prf_t *prf;
+ u_int8_t res[16];
+
+ prf = lib->crypto->create_prf(lib->crypto, PRF_AES128_XCBC);
+ if (!prf)
+ {
+ return FALSE;
+ }
+ prf->set_key(prf, chunk_create(key, keylen));
+ prf->get_bytes(prf, chunk_create(plain, len), res);
+ if (!memeq(res, mac, 16))
+ {
+ DBG1(DBG_CFG, "expected %b\ngot %b", mac, 16, res, 16);
+ prf->destroy(prf);
+ return FALSE;
+ }
+ prf->destroy(prf);
+
+ signer = lib->crypto->create_signer(lib->crypto, AUTH_AES_XCBC_96);
+ if (!signer)
+ {
+ return FALSE;
+ }
+ signer->set_key(signer, chunk_create(key, keylen));
+ if (!signer->verify_signature(signer, chunk_create(plain, len),
+ chunk_create(mac, 12)))
+ {
+ return FALSE;
+ }
+ signer->destroy(signer);
+ return TRUE;
+}
+
+
+/*******************************************************************************
+ * AES_XCBC mac test
+ ******************************************************************************/
+bool test_aes_xcbc()
+{
+ /* Vectors from RFC 3566 */
+
+ /* Test Case #1 : AES-XCBC-MAC-96 with 0-byte input
+ * Key (K) : 000102030405060708090a0b0c0d0e0f
+ * Message (M) : <empty string>
+ * AES-XCBC-MAC : 75f0251d528ac01c4573dfd584d79f29
+ * AES-XCBC-MAC-96: 75f0251d528ac01c4573dfd5
+ */
+ u_char key1[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+ };
+ u_char plain1[] = {
+ };
+ u_char mac1[] = {
+ 0x75,0xf0,0x25,0x1d,0x52,0x8a,0xc0,0x1c,
+ 0x45,0x73,0xdf,0xd5,0x84,0xd7,0x9f,0x29
+ };
+ if (!do_xcbc_test(key1, 16, mac1, plain1, sizeof(plain1)))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Test Case #2 : AES-XCBC-MAC-96 with 3-byte input
+ * Key (K) : 000102030405060708090a0b0c0d0e0f
+ * Message (M) : 000102
+ * AES-XCBC-MAC : 5b376580ae2f19afe7219ceef172756f
+ * AES-XCBC-MAC-96: 5b376580ae2f19afe7219cee
+ */
+ u_char key2[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+ };
+ u_char plain2[] = {
+ 0x00,0x01,0x02
+ };
+ u_char mac2[] = {
+ 0x5b,0x37,0x65,0x80,0xae,0x2f,0x19,0xaf,
+ 0xe7,0x21,0x9c,0xee,0xf1,0x72,0x75,0x6f
+ };
+ if (!do_xcbc_test(key2, 16, mac2, plain2, sizeof(plain2)))
+ {
+ return FALSE;
+ }
+
+ /* Test Case #3 : AES-XCBC-MAC-96 with 16-byte input
+ * Key (K) : 000102030405060708090a0b0c0d0e0f
+ * Message (M) : 000102030405060708090a0b0c0d0e0f
+ * AES-XCBC-MAC : d2a246fa349b68a79998a4394ff7a263
+ * AES-XCBC-MAC-96: d2a246fa349b68a79998a439
+ */
+ u_char key3[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+ };
+ u_char plain3[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+ };
+ u_char mac3[] = {
+ 0xd2,0xa2,0x46,0xfa,0x34,0x9b,0x68,0xa7,
+ 0x99,0x98,0xa4,0x39,0x4f,0xf7,0xa2,0x63
+ };
+ if (!do_xcbc_test(key3, 16, mac3, plain3, sizeof(plain3)))
+ {
+ return FALSE;
+ }
+
+ /* Test Case #4 : AES-XCBC-MAC-96 with 20-byte input
+ * Key (K) : 000102030405060708090a0b0c0d0e0f
+ * Message (M) : 000102030405060708090a0b0c0d0e0f10111213
+ * AES-XCBC-MAC : 47f51b4564966215b8985c63055ed308
+ * AES-XCBC-MAC-96: 47f51b4564966215b8985c63
+ */
+ u_char key4[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+ };
+ u_char plain4[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13
+ };
+ u_char mac4[] = {
+ 0x47,0xf5,0x1b,0x45,0x64,0x96,0x62,0x15,
+ 0xb8,0x98,0x5c,0x63,0x05,0x5e,0xd3,0x08
+ };
+ if (!do_xcbc_test(key4, 16, mac4, plain4, sizeof(plain4)))
+ {
+ return FALSE;
+ }
+
+ /* Test Case #5 : AES-XCBC-MAC-96 with 32-byte input
+ * Key (K) : 000102030405060708090a0b0c0d0e0f
+ * Message (M) : 000102030405060708090a0b0c0d0e0f10111213141516171819
+ * 1a1b1c1d1e1f
+ * AES-XCBC-MAC : f54f0ec8d2b9f3d36807734bd5283fd4
+ * AES-XCBC-MAC-96: f54f0ec8d2b9f3d36807734b
+ */
+ u_char key5[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+ };
+ u_char plain5[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
+ };
+ u_char mac5[] = {
+ 0xf5,0x4f,0x0e,0xc8,0xd2,0xb9,0xf3,0xd3,
+ 0x68,0x07,0x73,0x4b,0xd5,0x28,0x3f,0xd4
+ };
+ if (!do_xcbc_test(key5, 16, mac5, plain5, sizeof(plain5)))
+ {
+ return FALSE;
+ }
+
+ /* Test Case #7 : AES-XCBC-MAC-96 with 1000-byte input
+ * Key (K) : 000102030405060708090a0b0c0d0e0f
+ * Message (M) : 00000000000000000000 ... 00000000000000000000
+ * [1000 bytes]
+ * AES-XCBC-MAC : f0dafee895db30253761103b5d84528f
+ * AES-XCBC-MAC-96: f0dafee895db30253761103b
+ */
+ u_char key7[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+ };
+ u_char plain7[1000];
+ memset(plain7, 0, 1000);
+ u_char mac7[] = {
+ 0xf0,0xda,0xfe,0xe8,0x95,0xdb,0x30,0x25,
+ 0x37,0x61,0x10,0x3b,0x5d,0x84,0x52,0x8f
+ };
+ if (!do_xcbc_test(key7, 16, mac7, plain7, sizeof(plain7)))
+ {
+ return FALSE;
+ }
+
+ /* variable key test, RFC4434 */
+
+ /* Test Case AES-XCBC-PRF-128 with 20-byte input
+ * Key : 00010203040506070809
+ * Message : 000102030405060708090a0b0c0d0e0f10111213
+ * PRF Output : 0fa087af7d866e7653434e602fdde835
+ */
+ u_char key8[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,
+ };
+ u_char plain8[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13
+ };
+ u_char mac8[] = {
+ 0x0f,0xa0,0x87,0xaf,0x7d,0x86,0x6e,0x76,
+ 0x53,0x43,0x4e,0x60,0x2f,0xdd,0xe8,0x35
+ };
+ if (!do_xcbc_test(key8, 10, mac8, plain8, sizeof(plain8)))
+ {
+ return FALSE;
+ }
+
+ /* Test Case AES-XCBC-PRF-128 with 20-byte input
+ * Key : 000102030405060708090a0b0c0d0e0fedcb
+ * Message : 000102030405060708090a0b0c0d0e0f10111213
+ * PRF Output : 8cd3c93ae598a9803006ffb67c40e9e4
+ */
+ u_char key9[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0xed,0xcb
+ };
+ u_char plain9[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13
+ };
+ u_char mac9[] = {
+ 0x8c,0xd3,0xc9,0x3a,0xe5,0x98,0xa9,0x80,
+ 0x30,0x06,0xff,0xb6,0x7c,0x40,0xe9,0xe4
+ };
+ if (!do_xcbc_test(key9, 18, mac9, plain9, sizeof(plain9)))
+ {
+ return FALSE;
+ }
+
+
+ /* Test Case #10 : AES-XCBC-MAC-96 with 32-byte input using append mode
+ * Key (K) : 000102030405060708090a0b0c0d0e0f
+ * Message (M) : 000102030405060708090a0b0c0d0e0f10111213141516171819
+ * 1a1b1c1d1e1f
+ * AES-XCBC-MAC : f54f0ec8d2b9f3d36807734bd5283fd4
+ * AES-XCBC-MAC-96: f54f0ec8d2b9f3d36807734b
+ */
+ u_char key10[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+ };
+ u_char plain10[] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
+ };
+ u_char mac10[] = {
+ 0xf5,0x4f,0x0e,0xc8,0xd2,0xb9,0xf3,0xd3,
+ 0x68,0x07,0x73,0x4b,0xd5,0x28,0x3f,0xd4
+ };
+ int i;
+ prf_t *prf = lib->crypto->create_prf(lib->crypto, PRF_AES128_XCBC);
+ u_char res[16];
+ if (!prf)
+ {
+ return FALSE;
+ }
+ prf->set_key(prf, chunk_create(key10, sizeof(key10)));
+ for (i = 0; i < 4; i++)
+ { /* bytes 0 - 3, 1 byte at once */
+ prf->get_bytes(prf, chunk_create(plain10 + i, 1), NULL);
+ }
+ for (i = 4; i < 5; i+=8)
+ { /* bytes 4 - 11, at once */
+ prf->get_bytes(prf, chunk_create(plain10 + i, 8), NULL);
+ }
+ for (i = 12; i < 24; i+=4)
+ { /* bytes 12 - 23, in blocks of 4 */
+ prf->get_bytes(prf, chunk_create(plain10 + i, 4), NULL);
+ }
+ for (i = 0; i < 4; i++)
+ { /* 4 zero blobs */
+ prf->get_bytes(prf, chunk_create(NULL, 0), NULL);
+ }
+ for (i = 24; i < 25; i+=8)
+ { /* bytes 24 - 32, at once */
+ prf->get_bytes(prf, chunk_create(plain10 + i, 8), res);
+ }
+ if (!memeq(res, mac10, 16))
+ {
+ DBG1(DBG_CFG, "expected %b\ngot %b", mac10, 16, res, 16);
+ prf->destroy(prf);
+ return FALSE;
+ }
+ prf->destroy(prf);
+
+ return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_auth_info.c b/src/charon/plugins/unit_tester/tests/test_auth_info.c
new file mode 100644
index 000000000..2640c951c
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_auth_info.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <daemon.h>
+#include <library.h>
+#include <credentials/auth_info.h>
+
+
+char buf[] = {0x01,0x02,0x03,0x04};
+chunk_t chunk = chunk_from_buf(buf);
+char certbuf[] = {
+ 0x30,0x82,0x02,0xfa,0x30,0x82,0x01,0xe2,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x5a,
+ 0xf2,0x65,0xae,0x78,0xff,0x23,0xde,0xf7,0xa6,0xa3,0x94,0x8c,0x3f,0xa0,0xc1,0x30,
+ 0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x39,
+ 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x19,0x30,
+ 0x17,0x06,0x03,0x55,0x04,0x0a,0x13,0x10,0x4c,0x69,0x6e,0x75,0x78,0x20,0x73,0x74,
+ 0x72,0x6f,0x6e,0x67,0x53,0x77,0x61,0x6e,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,
+ 0x03,0x13,0x06,0x6d,0x61,0x72,0x74,0x69,0x6e,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,
+ 0x34,0x32,0x37,0x30,0x37,0x31,0x34,0x32,0x36,0x5a,0x17,0x0d,0x31,0x32,0x30,0x34,
+ 0x32,0x35,0x30,0x37,0x31,0x34,0x32,0x36,0x5a,0x30,0x39,0x31,0x0b,0x30,0x09,0x06,
+ 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,
+ 0x0a,0x13,0x10,0x4c,0x69,0x6e,0x75,0x78,0x20,0x73,0x74,0x72,0x6f,0x6e,0x67,0x53,
+ 0x77,0x61,0x6e,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x6d,0x61,
+ 0x72,0x74,0x69,0x6e,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
+ 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,
+ 0x02,0x82,0x01,0x01,0x00,0xd7,0xb9,0xba,0x4d,0xe2,0x3b,0x3d,0x35,0x7a,0x3f,0x88,
+ 0x67,0x95,0xe7,0xfd,0x9f,0xe9,0x0a,0x0d,0x79,0x3a,0x9e,0x21,0x8f,0xcb,0xe4,0x67,
+ 0x24,0xae,0x0c,0xda,0xb3,0xcc,0xec,0x36,0xb4,0xa8,0x4d,0xf1,0x3d,0xad,0xe4,0x8c,
+ 0x63,0x92,0x54,0xb7,0xb2,0x02,0xa2,0x00,0x62,0x8b,0x04,0xac,0xa0,0x17,0xad,0x17,
+ 0x9a,0x05,0x0d,0xd7,0xb3,0x08,0x02,0xc5,0x26,0xcf,0xdd,0x05,0x42,0xfc,0x13,0x6d,
+ 0x9f,0xb1,0xf3,0x4f,0x82,0x1d,0xef,0x01,0xc9,0x91,0xea,0x37,0x1b,0x79,0x28,0xfa,
+ 0xbf,0x9f,0xb3,0xeb,0x82,0x4f,0x10,0xc6,0x4b,0xa4,0x08,0xf7,0x8e,0xf2,0x00,0xea,
+ 0x04,0x97,0x80,0x9f,0x65,0x86,0xde,0x6b,0xc7,0xda,0x83,0xfc,0xad,0x4a,0xaf,0x52,
+ 0x8b,0x4d,0x33,0xee,0x49,0x87,0x2f,0x3b,0x60,0x45,0x66,0x8f,0xe6,0x89,0xcc,0xb1,
+ 0x92,0x02,0x17,0x2b,0x7b,0x8e,0x90,0x47,0x84,0x84,0x59,0x95,0x81,0xd8,0xe0,0xf3,
+ 0x87,0xe0,0x04,0x09,0xfd,0xcc,0x3a,0x21,0x34,0xfa,0xec,0xbe,0xf5,0x9c,0xcf,0x55,
+ 0x80,0x7b,0xe3,0x75,0x9d,0x36,0x68,0xab,0x83,0xe3,0xad,0x01,0x53,0x0d,0x8a,0x9a,
+ 0xa6,0xb0,0x15,0xc9,0xc5,0xf8,0x9b,0x51,0x32,0xcf,0x97,0x6c,0xfe,0x4a,0x56,0x3c,
+ 0xc8,0x8f,0x4a,0x70,0x23,0x4f,0xf6,0xf7,0xe6,0x9f,0x09,0xcd,0x8f,0xea,0x20,0x7d,
+ 0x34,0xc0,0xc5,0xc0,0x34,0x06,0x6f,0x8b,0xeb,0x04,0x54,0x3f,0x0e,0xcd,0xe2,0x85,
+ 0xab,0x94,0x3e,0x91,0x6c,0x18,0x6f,0x96,0x5d,0xf2,0x8b,0x10,0xe9,0x90,0x43,0xb0,
+ 0x61,0x52,0xac,0xcf,0x75,0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,
+ 0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x09,0x63,
+ 0x42,0xad,0xe5,0xa3,0xf6,0xc9,0x5d,0x08,0xf2,0x78,0x7b,0xeb,0x8a,0xef,0x50,0x00,
+ 0xc8,0xeb,0xe9,0x26,0x94,0xcb,0x84,0x10,0x7e,0x42,0x6b,0x86,0x38,0x57,0xa6,0x02,
+ 0x98,0x5a,0x2c,0x8f,0x44,0x32,0x1b,0x97,0x8c,0x7e,0x4b,0xd8,0xe8,0xe8,0x0f,0x4a,
+ 0xb9,0x31,0x9f,0xf6,0x9f,0x0e,0x67,0x26,0x05,0x2a,0x99,0x14,0x35,0x41,0x47,0x9a,
+ 0xfa,0x12,0x94,0x0b,0xe9,0x27,0x7c,0x71,0x20,0xd7,0x8d,0x3b,0x97,0x19,0x2d,0x15,
+ 0xff,0xa4,0xf3,0x89,0x8d,0x29,0x5f,0xf6,0x3f,0x93,0xaf,0x78,0x61,0xe4,0xe1,0x2e,
+ 0x75,0xc1,0x2c,0xc4,0x76,0x95,0x19,0xf8,0x37,0xdc,0xd8,0x00,0x7a,0x3c,0x0f,0x49,
+ 0x2e,0x88,0x09,0x16,0xb3,0x92,0x33,0xdf,0x77,0x83,0x4f,0xb5,0x9e,0x30,0x8c,0x48,
+ 0x1d,0xd8,0x84,0xfb,0xf1,0xb9,0xa0,0xbe,0x25,0xff,0x4c,0xeb,0xef,0x2b,0xcd,0xfa,
+ 0x0b,0x94,0x66,0x3b,0x28,0x08,0x3f,0x3a,0xda,0x41,0xd0,0x6b,0xab,0x5e,0xbb,0x8a,
+ 0x9f,0xdc,0x98,0x3e,0x59,0x37,0x48,0xbe,0x69,0xde,0x85,0x82,0xf2,0x53,0x8b,0xe4,
+ 0x44,0xe4,0x71,0x91,0x14,0x85,0x0e,0x1e,0x79,0xdd,0x62,0xf5,0xdc,0x25,0x89,0xab,
+ 0x50,0x5b,0xaa,0xae,0xe3,0x64,0x6a,0x23,0x34,0xd7,0x30,0xe2,0x2a,0xc8,0x81,0x0c,
+ 0xec,0xd2,0x31,0xc6,0x1e,0xb6,0xc0,0x57,0xd9,0xe1,0x14,0x06,0x9b,0xf8,0x51,0x69,
+ 0x47,0xf0,0x9c,0xcd,0x69,0xef,0x8e,0x5f,0x62,0xda,0x10,0xf7,0x3c,0x6d,0x0f,0x33,
+ 0xec,0x6f,0xfd,0x94,0x07,0x16,0x41,0x32,0x06,0xa4,0xe1,0x08,0x31,0x87,
+};
+chunk_t certchunk = chunk_from_buf(certbuf);
+
+/*******************************************************************************
+ * auth info test
+ ******************************************************************************/
+bool test_auth_info()
+{
+ auth_info_t *auth = auth_info_create(), *auth2;
+ certificate_t *c1, *c2;
+ enumerator_t *enumerator;
+ int round = 0;
+ void *value;
+ auth_item_t type;
+
+ c1 = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER, chunk_clone(certchunk),
+ BUILD_END);
+ if (!c1)
+ {
+ return FALSE;
+ }
+
+ auth->add_item(auth, AUTHN_SUBJECT_CERT, c1);
+ if (!auth->get_item(auth, AUTHN_SUBJECT_CERT, (void**)&c2))
+ {
+ return FALSE;
+ }
+ if (!c1->equals(c1, c2))
+ {
+ return FALSE;
+ }
+
+ enumerator = auth->create_item_enumerator(auth);
+ while (enumerator->enumerate(enumerator, &type, &value))
+ {
+ round++;
+ if (round == 1 && type == AUTHN_SUBJECT_CERT && value == c1)
+ {
+ continue;
+ }
+ return FALSE;
+ }
+ enumerator->destroy(enumerator);
+
+ auth2 = auth_info_create();
+ auth2->add_item(auth2, AUTHN_CA_CERT, c1);
+ auth2->merge(auth2, auth);
+
+ round = 0;
+ enumerator = auth2->create_item_enumerator(auth2);
+ while (enumerator->enumerate(enumerator, &type, &value))
+ {
+ round++;
+ if (round == 1 && type == AUTHN_CA_CERT && value == c1)
+ {
+ continue;
+ }
+ if (round == 2 && type == AUTHN_SUBJECT_CERT && value == c1)
+ {
+ continue;
+ }
+ return FALSE;
+ }
+ enumerator->destroy(enumerator);
+ auth->destroy(auth);
+ auth2->destroy(auth2);
+ c1->destroy(c1);
+ return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_chunk.c b/src/charon/plugins/unit_tester/tests/test_chunk.c
new file mode 100644
index 000000000..e7a8586c9
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_chunk.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <library.h>
+#include <daemon.h>
+
+#define countof(array) (sizeof(array)/sizeof(typeof(array[0])))
+
+/*******************************************************************************
+ * Base64 encoding/decoding test
+ ******************************************************************************/
+bool test_chunk_base64()
+{
+ /* test vectors from RFC4648:
+ *
+ * BASE64("") = ""
+ * BASE64("f") = "Zg=="
+ * BASE64("fo") = "Zm8="
+ * BASE64("foo") = "Zm9v"
+ * BASE64("foob") = "Zm9vYg=="
+ * BASE64("fooba") = "Zm9vYmE="
+ * BASE64("foobar") = "Zm9vYmFy"
+ */
+
+ typedef struct {
+ char *in;
+ char *out;
+ } testdata_t;
+
+ testdata_t test[] = {
+ {"", ""},
+ {"f", "Zg=="},
+ {"fo", "Zm8="},
+ {"foo", "Zm9v"},
+ {"foob", "Zm9vYg=="},
+ {"fooba", "Zm9vYmE="},
+ {"foobar", "Zm9vYmFy"},
+ };
+ int i;
+
+ for (i = 0; i < countof(test); i++)
+ {
+ chunk_t out;
+
+ out = chunk_to_base64(chunk_create(test[i].in, strlen(test[i].in)), NULL);
+
+ if (!streq(out.ptr, test[i].out))
+ {
+ DBG1(DBG_CFG, "base64 conversion error - should %s, is %s",
+ test[i].out, out.ptr);
+ return FALSE;
+ }
+ free(out.ptr);
+ }
+
+ for (i = 0; i < countof(test); i++)
+ {
+ chunk_t out;
+
+ out = chunk_from_base64(chunk_create(test[i].out, strlen(test[i].out)), NULL);
+
+ if (!strneq(out.ptr, test[i].in, out.len))
+ {
+ DBG1(DBG_CFG, "base64 conversion error - should %s, is %#B",
+ test[i].in, &out);
+ return FALSE;
+ }
+ free(out.ptr);
+ }
+ return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_curl.c b/src/charon/plugins/unit_tester/tests/test_curl.c
new file mode 100644
index 000000000..c011617a7
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_curl.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <daemon.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+/*******************************************************************************
+ * curl get test
+ ******************************************************************************/
+
+bool test_curl_get()
+{
+ chunk_t chunk;
+
+ if (lib->fetcher->fetch(lib->fetcher, "http://www.strongswan.org",
+ &chunk, FETCH_END) != SUCCESS)
+ {
+ return FALSE;
+ }
+ free(chunk.ptr);
+
+ if (lib->fetcher->fetch(lib->fetcher, "http://www.google.com",
+ &chunk, FETCH_END) != SUCCESS)
+ {
+ return FALSE;
+ }
+ free(chunk.ptr);
+ return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_enumerator.c b/src/charon/plugins/unit_tester/tests/test_enumerator.c
new file mode 100644
index 000000000..d17d62bef
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_enumerator.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <utils/linked_list.h>
+
+
+/*******************************************************************************
+ * linked list remove test
+ ******************************************************************************/
+bool test_list_remove()
+{
+ void *a = (void*)1, *b = (void*)2;
+ linked_list_t *list;
+
+ list = linked_list_create();
+ list->insert_last(list, a);
+ if (list->remove(list, a, NULL) != 1)
+ {
+ return FALSE;
+ }
+ list->insert_last(list, a);
+ list->insert_first(list, a);
+ list->insert_last(list, a);
+ list->insert_last(list, b);
+ if (list->remove(list, a, NULL) != 3)
+ {
+ return FALSE;
+ }
+ if (list->remove(list, a, NULL) != 0)
+ {
+ return FALSE;
+ }
+ if (list->get_count(list) != 1)
+ {
+ return FALSE;
+ }
+ if (list->remove(list, b, NULL) != 1)
+ {
+ return FALSE;
+ }
+ if (list->remove(list, b, NULL) != 0)
+ {
+ return FALSE;
+ }
+ list->destroy(list);
+ return TRUE;
+}
+
+/*******************************************************************************
+ * Simple insert first/last and enumerate test
+ ******************************************************************************/
+bool test_enumerate()
+{
+ int round, x;
+ void *a = (void*)4, *b = (void*)3, *c = (void*)2, *d = (void*)5, *e = (void*)1;
+ linked_list_t *list;
+ enumerator_t *enumerator;
+
+ list = linked_list_create();
+
+ list->insert_last(list, a);
+ list->insert_first(list, b);
+ list->insert_first(list, c);
+ list->insert_last(list, d);
+ list->insert_first(list, e);
+
+ round = 1;
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &x))
+ {
+ if (round != x)
+ {
+ return FALSE;
+ }
+ round++;
+ }
+ enumerator->destroy(enumerator);
+
+ list->destroy(list);
+ return TRUE;
+}
+
+/*******************************************************************************
+ * nested enumerator test
+ ******************************************************************************/
+
+static bool bad_data;
+
+static enumerator_t* create_inner(linked_list_t *outer, void *data)
+{
+ if (data != (void*)101)
+ {
+ bad_data = TRUE;
+ }
+ return outer->create_enumerator(outer);
+}
+
+
+static void destroy_data(void *data)
+{
+ if (data != (void*)101)
+ {
+ bad_data = TRUE;
+ }
+}
+
+bool test_enumerate_nested()
+{
+ int round, x;
+ void *a = (void*)1, *b = (void*)2, *c = (void*)3, *d = (void*)4, *e = (void*)5;
+ linked_list_t *list, *l1, *l2, *l3;
+ enumerator_t *enumerator;
+
+ bad_data = FALSE;
+ list = linked_list_create();
+ l1 = linked_list_create();
+ l2 = linked_list_create();
+ l3 = linked_list_create();
+ list->insert_last(list, l1);
+ list->insert_last(list, l2);
+ list->insert_last(list, l3);
+
+ l1->insert_last(l1, a);
+ l1->insert_last(l1, b);
+ l3->insert_last(l3, c);
+ l3->insert_last(l3, d);
+ l3->insert_last(l3, e);
+
+ round = 1;
+ enumerator = enumerator_create_nested(list->create_enumerator(list),
+ (void*)create_inner, (void*)101, destroy_data);
+ while (enumerator->enumerate(enumerator, &x))
+ {
+ if (round != x)
+ {
+ return FALSE;
+ }
+ round++;
+ }
+ enumerator->destroy(enumerator);
+
+ list->destroy(list);
+ l1->destroy(l1);
+ l2->destroy(l2);
+ l3->destroy(l3);
+ return !bad_data;
+}
+
+
+/*******************************************************************************
+ * filtered enumerator test
+ ******************************************************************************/
+static bool filter(void *data, int *v, int *vo, int *w, int *wo,
+ int *x, int *xo, int *y, int *yo, int *z, int *zo)
+{
+ int val = *v;
+
+ *vo = val++;
+ *wo = val++;
+ *xo = val++;
+ *yo = val++;
+ *zo = val++;
+ if (data != (void*)101)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool test_enumerate_filtered()
+{
+ int round, v, w, x, y, z;
+ void *a = (void*)1, *b = (void*)2, *c = (void*)3, *d = (void*)4, *e = (void*)5;
+ linked_list_t *list;
+ enumerator_t *enumerator;
+
+ bad_data = FALSE;
+ list = linked_list_create();
+
+ list->insert_last(list, a);
+ list->insert_last(list, b);
+ list->insert_last(list, c);
+ list->insert_last(list, d);
+ list->insert_last(list, e);
+
+ round = 1;
+ enumerator = enumerator_create_filter(list->create_enumerator(list),
+ (void*)filter, (void*)101, destroy_data);
+ while (enumerator->enumerate(enumerator, &v, &w, &x, &y, &z))
+ {
+ if (v != round || w != round + 1 || x != round + 2 ||
+ y != round + 3 || z != round + 4)
+ {
+ return FALSE;
+ }
+ round++;
+ }
+ enumerator->destroy(enumerator);
+
+ list->destroy(list);
+ return !bad_data;
+}
diff --git a/src/charon/plugins/unit_tester/tests/test_fips_prf.c b/src/charon/plugins/unit_tester/tests/test_fips_prf.c
new file mode 100644
index 000000000..29612143e
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_fips_prf.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <utils/linked_list.h>
+#include <daemon.h>
+
+/*******************************************************************************
+ * fips prf known value test
+ ******************************************************************************/
+bool fips_prf_test()
+{
+ prf_t *prf;
+ u_int8_t key_buf[] = {
+ 0xbd, 0x02, 0x9b, 0xbe, 0x7f, 0x51, 0x96, 0x0b,
+ 0xcf, 0x9e, 0xdb, 0x2b, 0x61, 0xf0, 0x6f, 0x0f,
+ 0xeb, 0x5a, 0x38, 0xb6
+ };
+ u_int8_t seed_buf[] = {
+ 0x00
+ };
+ u_int8_t result_buf[] = {
+ 0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f,
+ 0xde, 0x1c, 0x0f, 0xfc, 0x7b, 0x2e, 0x3b, 0x49,
+ 0x8b, 0x26, 0x06, 0x14, 0x3c, 0x6c, 0x18, 0xba,
+ 0xcb, 0x0f, 0x6c, 0x55, 0xba, 0xbb, 0x13, 0x78,
+ 0x8e, 0x20, 0xd7, 0x37, 0xa3, 0x27, 0x51, 0x16
+ };
+ chunk_t key = chunk_from_buf(key_buf);
+ chunk_t seed = chunk_from_buf(seed_buf);
+ chunk_t expected = chunk_from_buf(result_buf);
+ chunk_t result;
+
+ prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160);
+ if (prf == NULL)
+ {
+ DBG1(DBG_CFG, "FIPS PRF implementation not found");
+ return FALSE;
+ }
+ prf->set_key(prf, key);
+ prf->allocate_bytes(prf, seed, &result);
+ prf->destroy(prf);
+ if (!chunk_equals(result, expected))
+ {
+ DBG1(DBG_CFG, "FIPS PRF result invalid:\nexpected: %Bresult: %B",
+ &expected, &result);
+ chunk_free(&result);
+ return FALSE;
+ }
+ chunk_free(&result);
+ return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_med_db.c b/src/charon/plugins/unit_tester/tests/test_med_db.c
new file mode 100644
index 000000000..d65eb0cc4
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_med_db.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <library.h>
+#include <daemon.h>
+#include <utils/enumerator.h>
+
+#include <unistd.h>
+
+/*******************************************************************************
+ * fetch public key from mediation database
+ ******************************************************************************/
+
+bool test_med_db()
+{
+ char keyid_buf[] = {
+ 0xed,0x90,0xe6,0x4f,0xec,0xa2,0x1f,0x4b,
+ 0x68,0x97,0x99,0x24,0x22,0xe0,0xde,0x21,
+ 0xb9,0xd6,0x26,0x29
+ };
+ chunk_t keyid = chunk_from_buf(keyid_buf);
+ identification_t *id, *found;
+ enumerator_t *enumerator;
+ auth_info_t *auth;
+ public_key_t *public;
+ bool good = FALSE;
+
+ id = identification_create_from_encoding(ID_KEY_ID, keyid);
+ enumerator = charon->credentials->create_public_enumerator(
+ charon->credentials, KEY_ANY, id, NULL);
+ while (enumerator->enumerate(enumerator, &public, &auth))
+ {
+ found = public->get_id(public, ID_PUBKEY_SHA1);
+ good = chunk_equals(id->get_encoding(id), found->get_encoding(found));
+ }
+ enumerator->destroy(enumerator);
+ id->destroy(id);
+ return good;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_mutex.c b/src/charon/plugins/unit_tester/tests/test_mutex.c
new file mode 100644
index 000000000..a305d5082
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_mutex.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <library.h>
+#include <utils/mutex.h>
+
+#include <unistd.h>
+#include <sched.h>
+#include <pthread.h>
+
+
+static mutex_t *mutex;
+
+static int locked = 0;
+
+static bool failed = FALSE;
+
+static pthread_barrier_t barrier;
+
+static void* run(void* null)
+{
+ int i;
+
+ /* wait for all threads before getting in action */
+ pthread_barrier_wait(&barrier);
+
+ for (i = 0; i < 100; i++)
+ {
+ mutex->lock(mutex);
+ mutex->lock(mutex);
+ mutex->lock(mutex);
+ locked++;
+ sched_yield();
+ if (locked > 1)
+ {
+ failed = TRUE;
+ }
+ locked--;
+ mutex->unlock(mutex);
+ mutex->unlock(mutex);
+ mutex->unlock(mutex);
+ }
+ return NULL;
+}
+
+#define THREADS 20
+
+/*******************************************************************************
+ * mutex test
+ ******************************************************************************/
+bool test_mutex()
+{
+ int i;
+ pthread_t threads[THREADS];
+
+ mutex = mutex_create(MUTEX_RECURSIVE);
+
+ for (i = 0; i < 10; i++)
+ {
+ mutex->lock(mutex);
+ mutex->unlock(mutex);
+ }
+ for (i = 0; i < 10; i++)
+ {
+ mutex->lock(mutex);
+ }
+ for (i = 0; i < 10; i++)
+ {
+ mutex->unlock(mutex);
+ }
+
+ pthread_barrier_init(&barrier, NULL, THREADS);
+
+ for (i = 0; i < THREADS; i++)
+ {
+ pthread_create(&threads[i], NULL, run, NULL);
+ }
+ for (i = 0; i < THREADS; i++)
+ {
+ pthread_join(threads[i], NULL);
+ }
+ pthread_barrier_destroy(&barrier);
+
+ mutex->destroy(mutex);
+
+ return !failed;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_mysql.c b/src/charon/plugins/unit_tester/tests/test_mysql.c
new file mode 100644
index 000000000..ff3d38ad8
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_mysql.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <library.h>
+#include <daemon.h>
+#include <utils/enumerator.h>
+
+/*******************************************************************************
+ * mysql simple test
+ ******************************************************************************/
+bool test_mysql()
+{
+ database_t *db;
+ char *txt = "I'm a superduper test";
+ char buf[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
+ chunk_t data = chunk_from_buf(buf);
+ int row;
+ chunk_t qdata;
+ char *qtxt;
+ bool good = FALSE;
+ enumerator_t *enumerator;
+
+ db = lib->db->create(lib->db, "mysql://testuser:testpass@localhost/test");
+ if (!db)
+ {
+ return FALSE;
+ }
+ if (db->execute(db, NULL, "CREATE TABLE test ("
+ "id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, "
+ "txt TEXT, data BLOB)") < 0)
+ {
+ return FALSE;
+ }
+ if (db->execute(db, &row, "INSERT INTO test (txt, data) VALUES (?,?)",
+ DB_TEXT, txt, DB_BLOB, data) < 0)
+ {
+ return FALSE;
+ }
+ if (row != 1)
+ {
+ return FALSE;
+ }
+ enumerator = db->query(db, "SELECT txt, data FROM test WHERE id = ?",
+ DB_INT, row,
+ DB_TEXT, DB_BLOB);
+ if (!enumerator)
+ {
+ return FALSE;
+ }
+ while (enumerator->enumerate(enumerator, &qtxt, &qdata))
+ {
+ if (good)
+ { /* only one row */
+ good = FALSE;
+ break;
+ }
+ if (streq(qtxt, txt) && chunk_equals(data, qdata))
+ {
+ good = TRUE;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!good)
+ {
+ return FALSE;
+ }
+ if (db->execute(db, NULL, "DELETE FROM test WHERE id = ?", DB_INT, row) != 1)
+ {
+ return FALSE;
+ }
+ if (db->execute(db, NULL, "DROP TABLE test") < 0)
+ {
+ return FALSE;
+ }
+ db->destroy(db);
+ return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_rsa_gen.c b/src/charon/plugins/unit_tester/tests/test_rsa_gen.c
new file mode 100644
index 000000000..783a4c913
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_rsa_gen.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <library.h>
+#include <daemon.h>
+
+/*******************************************************************************
+ * RSA key generation and signature
+ ******************************************************************************/
+bool test_rsa_gen()
+{
+ char buf[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
+ chunk_t data = chunk_from_buf(buf), sig;
+ private_key_t *private;
+ public_key_t *public;
+ u_int key_size;
+
+ for (key_size = 512; key_size <= 2048; key_size *= 2)
+ {
+ private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_KEY_SIZE, key_size, BUILD_END);
+ if (!private)
+ {
+ DBG1(DBG_CFG, "generating %d bit RSA key failed");
+ return FALSE;
+ }
+ public = private->get_public_key(private);
+ if (!public)
+ {
+ DBG1(DBG_CFG, "generating public from private key failed");
+ return FALSE;
+ }
+ if (!private->sign(private, SIGN_RSA_EMSA_PKCS1_SHA1, data, &sig))
+ {
+ DBG1(DBG_CFG, "creating RSA signature failed");
+ return FALSE;
+ }
+ if (!public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, data, sig))
+ {
+ DBG1(DBG_CFG, "verifying RSA signature failed");
+ return FALSE;
+ }
+ sig.ptr[sig.len-1]++;
+ if (public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, data, sig))
+ {
+ DBG1(DBG_CFG, "verifying faked RSA signature succeeded!");
+ return FALSE;
+ }
+ free(sig.ptr);
+ public->destroy(public);
+ private->destroy(private);
+ }
+ return TRUE;
+}
+
+
+/*******************************************************************************
+ * Load a subjectPubkeyInfo wrapped key (RSA in this case)
+ ******************************************************************************/
+static char public_any[] = {
+ 0x30,0x82,0x01,0x20,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
+ 0x01,0x05,0x00,0x03,0x82,0x01,0x0d,0x00,0x30,0x82,0x01,0x08,0x02,0x82,0x01,0x01,
+ 0x00,0xc6,0x68,0x99,0x1d,0xc8,0x06,0xdb,0xcf,0x1c,0x66,0xbb,0x91,0xc3,0xd4,0x10,
+ 0xb2,0x08,0xa9,0xc5,0x71,0x39,0x1c,0xbe,0x5b,0x1d,0xce,0xfd,0x1b,0xfa,0xec,0x04,
+ 0x89,0x9f,0x79,0xc8,0x46,0x00,0xd2,0x71,0xfb,0x22,0x16,0x52,0x2f,0xda,0xbf,0x0f,
+ 0xe7,0x16,0xb1,0xd7,0x6a,0xa5,0xa5,0xfc,0xee,0xff,0x84,0x4c,0x81,0x3f,0xab,0x84,
+ 0x0e,0xed,0x4a,0x26,0x59,0xd0,0x9b,0xb5,0xe1,0xec,0x61,0xc4,0xd3,0x15,0x4c,0x29,
+ 0x51,0xa0,0xde,0x33,0x07,0x58,0x6c,0x36,0x1b,0x18,0x61,0xd9,0x56,0x18,0x39,0x54,
+ 0x8b,0xd2,0xea,0x4e,0x87,0x28,0x58,0xb9,0x88,0x3d,0x30,0xbc,0xfc,0x6d,0xad,0xab,
+ 0x43,0x26,0x09,0x48,0x4e,0x6e,0x8a,0x8b,0x88,0xb3,0xf0,0x29,0x25,0x79,0xb6,0xb6,
+ 0x71,0x3c,0x93,0x59,0xd2,0x36,0x94,0xd5,0xfc,0xf3,0x62,0x2b,0x69,0xa3,0x7a,0x47,
+ 0x4e,0x53,0xa2,0x35,0x1b,0x26,0x89,0xaa,0x09,0xfd,0x56,0xd7,0x75,0x2a,0xd4,0x91,
+ 0xc0,0xf2,0x78,0xd7,0x05,0xca,0x12,0x1d,0xd9,0xd4,0x81,0x23,0xb2,0x3c,0x38,0xd9,
+ 0xb4,0xdc,0x21,0xe0,0xe5,0x2d,0xd4,0xbe,0x61,0x39,0x8a,0x46,0x90,0x46,0x73,0x31,
+ 0xba,0x48,0xbb,0x51,0xbb,0x91,0xd5,0x62,0xad,0xd1,0x53,0x5b,0x85,0xc9,0x1d,0xa7,
+ 0xf6,0xa0,0xe1,0x0e,0x6c,0x22,0x5d,0x29,0x9a,0xe7,0x0f,0xe8,0x0a,0x50,0xa7,0x19,
+ 0x11,0xc2,0x8b,0xe0,0x8a,0xfd,0x2b,0x94,0x31,0x7a,0x78,0x9c,0x9b,0x75,0x63,0x49,
+ 0xa9,0xe5,0x58,0xe6,0x3a,0x99,0xcb,0x2b,0xdd,0x0e,0xdc,0x7d,0x1b,0x98,0x80,0xc3,
+ 0x9f,0x02,0x01,0x23,
+};
+
+bool test_rsa_load_any()
+{
+ chunk_t chunk = chunk_from_buf(public_any);
+ public_key_t *public;
+
+ public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+ BUILD_BLOB_ASN1_DER, chunk_clone(chunk),
+ BUILD_END);
+ if (!public || public->get_keysize(public) != 256)
+ {
+ return FALSE;
+ }
+ public->destroy(public);
+ return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_sqlite.c b/src/charon/plugins/unit_tester/tests/test_sqlite.c
new file mode 100644
index 000000000..d152fc594
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_sqlite.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <library.h>
+#include <daemon.h>
+#include <utils/enumerator.h>
+
+#include <unistd.h>
+
+
+#define DBFILE "/tmp/strongswan-test.db"
+
+/*******************************************************************************
+ * sqlite simple test
+ ******************************************************************************/
+bool test_sqlite()
+{
+ database_t *db;
+ char *txt = "I'm a superduper test";
+ char buf[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
+ chunk_t data = chunk_from_buf(buf);
+ int row;
+ chunk_t qdata;
+ char *qtxt;
+ bool good = FALSE;
+ enumerator_t *enumerator;
+
+ db = lib->db->create(lib->db, "sqlite://" DBFILE);
+ if (!db)
+ {
+ return FALSE;
+ }
+ if (db->execute(db, NULL, "CREATE TABLE test (txt TEXT, data BLOB)") < 0)
+ {
+ return FALSE;
+ }
+ if (db->execute(db, &row, "INSERT INTO test (txt, data) VALUES (?,?)",
+ DB_TEXT, txt, DB_BLOB, data) < 0)
+ {
+ return FALSE;
+ }
+ if (row != 1)
+ {
+ return FALSE;
+ }
+ enumerator = db->query(db, "SELECT txt, data FROM test WHERE oid = ?",
+ DB_INT, row,
+ DB_TEXT, DB_BLOB);
+ if (!enumerator)
+ {
+ return FALSE;
+ }
+ while (enumerator->enumerate(enumerator, &qtxt, &qdata))
+ {
+ if (good)
+ { /* only one row */
+ good = FALSE;
+ break;
+ }
+ if (streq(qtxt, txt) && chunk_equals(data, qdata))
+ {
+ good = TRUE;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!good)
+ {
+ return FALSE;
+ }
+ if (db->execute(db, NULL, "DELETE FROM test WHERE oid = ?", DB_INT, row) != 1)
+ {
+ return FALSE;
+ }
+ if (db->execute(db, NULL, "DROP TABLE test") < 0)
+ {
+ return FALSE;
+ }
+ db->destroy(db);
+ unlink(DBFILE);
+ return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/unit_tester.c b/src/charon/plugins/unit_tester/unit_tester.c
new file mode 100644
index 000000000..28c6b4c11
--- /dev/null
+++ b/src/charon/plugins/unit_tester/unit_tester.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: unit_tester.c 3491 2008-02-22 14:04:00Z martin $
+ */
+
+#include "unit_tester.h"
+
+#include <daemon.h>
+
+typedef struct private_unit_tester_t private_unit_tester_t;
+typedef struct unit_test_t unit_test_t;
+typedef enum test_status_t test_status_t;
+
+/**
+ * private data of unit_tester
+ */
+struct private_unit_tester_t {
+
+ /**
+ * public functions
+ */
+ unit_tester_t public;
+};
+
+struct unit_test_t {
+
+ /**
+ * name of the test
+ */
+ char *name;
+
+ /**
+ * test function
+ */
+ bool (*test)(void);
+
+ /**
+ * run the test?
+ */
+ bool enabled;
+};
+
+#undef DEFINE_TEST
+#define DEFINE_TEST(name, function, enabled) bool function();
+#include <plugins/unit_tester/tests.h>
+#undef DEFINE_TEST
+#define DEFINE_TEST(name, function, enabled) {name, function, enabled},
+static unit_test_t tests[] = {
+#include <plugins/unit_tester/tests.h>
+};
+
+static void run_tests(private_unit_tester_t *this)
+{
+ int i, run = 0, failed = 0, success = 0, skipped = 0;
+
+ DBG1(DBG_CFG, "running unit tests, %d tests registered",
+ sizeof(tests)/sizeof(unit_test_t));
+
+ for (i = 0; i < sizeof(tests)/sizeof(unit_test_t); i++)
+ {
+ if (tests[i].enabled)
+ {
+ run++;
+ if (tests[i].test())
+ {
+ DBG1(DBG_CFG, "test '%s' successful", tests[i].name);
+ success++;
+ }
+ else
+ {
+ DBG1(DBG_CFG, "test '%s' failed", tests[i].name);
+ failed++;
+ }
+ }
+ else
+ {
+ DBG1(DBG_CFG, "test '%s' disabled", tests[i].name);
+ skipped++;
+ }
+ }
+ DBG1(DBG_CFG, "%d/%d tests successful (%d failed, %d disabled)",
+ success, run, failed, skipped);
+}
+
+/**
+ * Implementation of 2007_t.destroy
+ */
+static void destroy(private_unit_tester_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_unit_tester_t *this = malloc_thing(private_unit_tester_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ run_tests(this);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/unit_tester/unit_tester.h b/src/charon/plugins/unit_tester/unit_tester.h
new file mode 100644
index 000000000..af946c2e0
--- /dev/null
+++ b/src/charon/plugins/unit_tester/unit_tester.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: unit_tester.h 3491 2008-02-22 14:04:00Z martin $
+ */
+
+/**
+ * @defgroup unit_tester unit_tester
+ * @{ @ingroup cplugins
+ */
+
+#ifndef UNIT_TESTER_H_
+#define UNIT_TESTER_H_
+
+#include <plugins/plugin.h>
+
+typedef struct unit_tester_t unit_tester_t;
+
+/**
+ * Unit testing plugin.
+ *
+ * The unit testing plugin runs tests on plugin initialization. Tests are
+ * defined in tests.h using the DEFINE_TEST macro. Implementation of the
+ * tests is done in the tests folder. Each test has uses a function which
+ * returns TRUE for success or FALSE for failure.
+ */
+struct unit_tester_t {
+
+ /**
+ * Implements the plugin interface.
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a unit_tester plugin.
+ */
+plugin_t *plugin_create();
+
+#endif /* UNIT_TESTER_H_ @}*/
diff --git a/src/charon/processing/jobs/acquire_job.c b/src/charon/processing/jobs/acquire_job.c
index 48a77f558..b39e8e680 100644
--- a/src/charon/processing/jobs/acquire_job.c
+++ b/src/charon/processing/jobs/acquire_job.c
@@ -1,10 +1,3 @@
-/**
- * @file acquire_job.c
- *
- * @brief Implementation of acquire_job_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: acquire_job.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "acquire_job.h"
diff --git a/src/charon/processing/jobs/acquire_job.h b/src/charon/processing/jobs/acquire_job.h
index 226966215..17c993d8e 100644
--- a/src/charon/processing/jobs/acquire_job.h
+++ b/src/charon/processing/jobs/acquire_job.h
@@ -1,10 +1,3 @@
-/**
- * @file acquire_job.h
- *
- * @brief Interface of acquire_job_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: acquire_job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup acquire_job acquire_job
+ * @{ @ingroup jobs
*/
#ifndef ACQUIRE_JOB_H_
@@ -29,14 +29,9 @@ typedef struct acquire_job_t acquire_job_t;
#include <processing/jobs/job.h>
/**
- * @brief Class representing an ACQUIRE Job.
+ * Class representing an ACQUIRE Job.
*
* This job initiates a CHILD SA on kernel request.
- *
- * @b Constructors:
- * - acquire_job_create()
- *
- * @ingroup jobs
*/
struct acquire_job_t {
/**
@@ -46,15 +41,13 @@ struct acquire_job_t {
};
/**
- * @brief Creates a job of type ACQUIRE.
+ * Creates a job of type ACQUIRE.
*
* We use the reqid to find the routed CHILD_SA.
*
* @param reqid reqid of the CHILD_SA to acquire
* @return acquire_job_t object
- *
- * @ingroup jobs
*/
acquire_job_t *acquire_job_create(u_int32_t reqid);
-#endif /* REKEY_CHILD_SA_JOB_H_ */
+#endif /* REKEY_CHILD_SA_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/callback_job.c b/src/charon/processing/jobs/callback_job.c
index 53297916e..e8892ee82 100644
--- a/src/charon/processing/jobs/callback_job.c
+++ b/src/charon/processing/jobs/callback_job.c
@@ -1,10 +1,3 @@
-/**
- * @file callback_job.c
- *
- * @brief Implementation of callback_job_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: callback_job.c 3742 2008-04-03 09:19:12Z tobias $
*/
#include "callback_job.h"
@@ -61,11 +56,6 @@ struct private_callback_job_t {
pthread_mutex_t mutex;
/**
- * condvar to synchronize thread startup/cancellation
- */
- pthread_cond_t condvar;
-
- /**
* list of asociated child jobs
*/
linked_list_t *children;
@@ -145,7 +135,6 @@ static void execute(private_callback_job_t *this)
pthread_mutex_lock(&this->mutex);
this->thread = pthread_self();
- pthread_cond_signal(&this->condvar);
pthread_mutex_unlock(&this->mutex);
pthread_cleanup_push((void*)destroy, this);
@@ -192,7 +181,6 @@ callback_job_t *callback_job_create(callback_job_cb_t cb, void *data,
/* private variables */
pthread_mutex_init(&this->mutex, NULL);
- pthread_cond_init(&this->condvar, NULL);
this->callback = cb;
this->data = data;
this->cleanup = cleanup;
diff --git a/src/charon/processing/jobs/callback_job.h b/src/charon/processing/jobs/callback_job.h
index 169f2d207..4e2eab235 100644
--- a/src/charon/processing/jobs/callback_job.h
+++ b/src/charon/processing/jobs/callback_job.h
@@ -1,10 +1,3 @@
-/**
- * @file callback_job.h
- *
- * @brief Interface of callback_job_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: callback_job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup callback_job callback_job
+ * @{ @ingroup jobs
*/
#ifndef CALLBACK_JOB_H_
@@ -32,12 +32,10 @@ typedef struct callback_job_t callback_job_t;
typedef enum job_requeue_t job_requeue_t;
/**
- * @brief Job requeueing policy
+ * Job requeueing policy
*
* The job requeueing policy defines how a job is handled when the callback
* function returns.
- *
- * @ingroup jobs
*/
enum job_requeue_t {
@@ -58,20 +56,18 @@ enum job_requeue_t {
};
/**
- * @brief The callback function to use for the callback job.
+ * The callback function to use for the callback job.
*
* This is the function to use as callback for a callback job. It receives
* a parameter supplied to the callback jobs constructor.
*
* @param data param supplied to job
* @return requeing policy how to requeue the job
- *
- * @ingroup jobs
*/
typedef job_requeue_t (*callback_job_cb_t)(void *data);
/**
- * @brief Cleanup function to use for data cleanup.
+ * Cleanup function to use for data cleanup.
*
* The callback has an optional user argument which receives data. However,
* this data may be cleaned up if it is allocated. This is the function
@@ -79,22 +75,15 @@ typedef job_requeue_t (*callback_job_cb_t)(void *data);
*
* @param data param supplied to job
* @return requeing policy how to requeue the job
- *
- * @ingroup jobs
*/
typedef void (*callback_job_cleanup_t)(void *data);
/**
- * @brief Class representing an callback Job.
+ * Class representing an callback Job.
*
* This is a special job which allows a simple callback function to
* be executed by a thread of the thread pool. This allows simple execution
* of asynchronous methods, without to manage threads.
- *
- * @b Constructors:
- * - callback_job_create()
- *
- * @ingroup jobs
*/
struct callback_job_t {
/**
@@ -103,15 +92,13 @@ struct callback_job_t {
job_t job_interface;
/**
- * @brief Cancel the jobs thread and wait for its termination.
- *
- * @param this calling object
+ * Cancel the jobs thread and wait for its termination.
*/
void (*cancel)(callback_job_t *this);
};
/**
- * @brief Creates a callback job.
+ * Creates a callback job.
*
* The cleanup function is called when the job gets destroyed to destroy
* the associated data.
@@ -124,12 +111,9 @@ struct callback_job_t {
* @param cleanup destructor for data on destruction, or NULL
* @param parent parent of this job
* @return callback_job_t object
- *
- * @ingroup jobs
*/
callback_job_t *callback_job_create(callback_job_cb_t cb, void *data,
callback_job_cleanup_t cleanup,
callback_job_t *parent);
-#endif /* CALLBACK_JOB_H_ */
-
+#endif /* CALLBACK_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/delete_child_sa_job.c b/src/charon/processing/jobs/delete_child_sa_job.c
index 23f330293..26f538d67 100644
--- a/src/charon/processing/jobs/delete_child_sa_job.c
+++ b/src/charon/processing/jobs/delete_child_sa_job.c
@@ -1,10 +1,3 @@
-/**
- * @file delete_child_sa_job.c
- *
- * @brief Implementation of delete_child_sa_job_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: delete_child_sa_job.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "delete_child_sa_job.h"
diff --git a/src/charon/processing/jobs/delete_child_sa_job.h b/src/charon/processing/jobs/delete_child_sa_job.h
index 0b90e008d..c11e8fab4 100644
--- a/src/charon/processing/jobs/delete_child_sa_job.h
+++ b/src/charon/processing/jobs/delete_child_sa_job.h
@@ -1,10 +1,3 @@
-/**
- * @file delete_child_sa_job.h
- *
- * @brief Interface of delete_child_sa_job_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: delete_child_sa_job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup delete_child_sa_job delete_child_sa_job
+ * @{ @ingroup jobs
*/
#ifndef DELETE_CHILD_SA_JOB_H_
@@ -32,14 +32,9 @@ typedef struct delete_child_sa_job_t delete_child_sa_job_t;
/**
- * @brief Class representing an DELETE_CHILD_SA Job.
+ * Class representing an DELETE_CHILD_SA Job.
*
* This job initiates the delete of a CHILD SA.
- *
- * @b Constructors:
- * - delete_child_sa_job_create()
- *
- * @ingroup jobs
*/
struct delete_child_sa_job_t {
/**
@@ -49,7 +44,7 @@ struct delete_child_sa_job_t {
};
/**
- * @brief Creates a job of type DELETE_CHILD_SA.
+ * Creates a job of type DELETE_CHILD_SA.
*
* The CHILD_SA is identified by its reqid, protocol (AH/ESP) and its
* inbound SPI.
@@ -58,11 +53,9 @@ struct delete_child_sa_job_t {
* @param protocol protocol of the CHILD_SA
* @param spi security parameter index of the CHILD_SA
* @return delete_child_sa_job_t object
- *
- * @ingroup jobs
*/
delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
protocol_id_t protocol,
u_int32_t spi);
-#endif /* DELETE_CHILD_SA_JOB_H_ */
+#endif /* DELETE_CHILD_SA_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/delete_ike_sa_job.c b/src/charon/processing/jobs/delete_ike_sa_job.c
index 8d8c0cf36..95b60ad01 100644
--- a/src/charon/processing/jobs/delete_ike_sa_job.c
+++ b/src/charon/processing/jobs/delete_ike_sa_job.c
@@ -1,10 +1,3 @@
-/**
- * @file delete_ike_sa_job.c
- *
- * @brief Implementation of delete_ike_sa_job_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: delete_ike_sa_job.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "delete_ike_sa_job.h"
diff --git a/src/charon/processing/jobs/delete_ike_sa_job.h b/src/charon/processing/jobs/delete_ike_sa_job.h
index 11bb46e73..cf666bb48 100644
--- a/src/charon/processing/jobs/delete_ike_sa_job.h
+++ b/src/charon/processing/jobs/delete_ike_sa_job.h
@@ -1,10 +1,3 @@
-/**
- * @file delete_ike_sa_job.h
- *
- * @brief Interface of delete_ike_sa_job_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: delete_ike_sa_job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup delete_child_sa_job delete_child_sa_job
+ * @{ @ingroup jobs
*/
#ifndef DELETE_IKE_SA_JOB_H_
@@ -32,16 +32,11 @@ typedef struct delete_ike_sa_job_t delete_ike_sa_job_t;
/**
- * @brief Class representing an DELETE_IKE_SA Job.
+ * Class representing an DELETE_IKE_SA Job.
*
* This job is responsible for deleting established or half open IKE_SAs.
* A half open IKE_SA is every IKE_SA which hasn't reache the SA_ESTABLISHED
* state.
- *
- * @b Constructors:
- * - delete_ike_sa_job_create()
- *
- * @ingroup jobs
*/
struct delete_ike_sa_job_t {
@@ -52,15 +47,13 @@ struct delete_ike_sa_job_t {
};
/**
- * @brief Creates a job of type DELETE_IKE_SA.
+ * Creates a job of type DELETE_IKE_SA.
*
* @param ike_sa_id id of the IKE_SA to delete
* @param delete_if_established should the IKE_SA be deleted if it is established?
* @return created delete_ike_sa_job_t object
- *
- * @ingroup jobs
*/
delete_ike_sa_job_t *delete_ike_sa_job_create(ike_sa_id_t *ike_sa_id,
bool delete_if_established);
-#endif /* DELETE_IKE_SA_JOB_H_ */
+#endif /* DELETE_IKE_SA_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/initiate_mediation_job.c b/src/charon/processing/jobs/initiate_mediation_job.c
index b8d516e22..de97daafa 100644
--- a/src/charon/processing/jobs/initiate_mediation_job.c
+++ b/src/charon/processing/jobs/initiate_mediation_job.c
@@ -1,12 +1,5 @@
-/**
- * @file initiate_mediation_job.c
- *
- * @brief Implementation of initiate_mediation_job_t.
- *
- */
-
/*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,9 +11,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: initiate_mediation_job.c 3792 2008-04-10 12:51:04Z tobias $
*/
-
#include "initiate_mediation_job.h"
#include <sa/ike_sa.h>
@@ -44,11 +38,6 @@ struct private_initiate_mediation_job_t {
ike_sa_id_t *mediated_sa_id;
/**
- * Child config of the CHILD_SA of the mediated connection.
- */
- child_cfg_t *mediated_child;
-
- /**
* ID of the IKE_SA of the mediation connection.
*/
ike_sa_id_t *mediation_sa_id;
@@ -61,7 +50,6 @@ static void destroy(private_initiate_mediation_job_t *this)
{
DESTROY_IF(this->mediation_sa_id);
DESTROY_IF(this->mediated_sa_id);
- DESTROY_IF(this->mediated_child);
free(this);
}
@@ -100,11 +88,12 @@ static void initiate(private_initiate_mediation_job_t *this)
charon->ike_sa_manager->checkin(charon->ike_sa_manager, mediated_sa);
mediation_cfg = mediated_cfg->get_mediated_by(mediated_cfg);
+ mediation_cfg->get_ref(mediation_cfg);
if (charon->connect_manager->check_and_register(charon->connect_manager,
mediation_cfg->get_my_id(mediation_cfg),
mediated_cfg->get_peer_id(mediated_cfg),
- this->mediated_sa_id, this->mediated_child))
+ this->mediated_sa_id))
{
mediated_cfg->destroy(mediated_cfg);
mediation_cfg->destroy(mediation_cfg);
@@ -121,8 +110,8 @@ static void initiate(private_initiate_mediation_job_t *this)
* we do not check the status, but NEED_MORE would be returned on success
* because the registered callback returns FALSE then
* this->mediation_sa_id is set in the callback */
- charon->interfaces->initiate(charon->interfaces,
- mediation_cfg, NULL, (interface_manager_cb_t)initiate_callback, this);
+ charon->controller->initiate(charon->controller,
+ mediation_cfg, NULL, (controller_cb_t)initiate_callback, this);
if (!this->mediation_sa_id)
{
DBG1(DBG_JOB, "initiating mediation connection '%s' failed",
@@ -216,7 +205,6 @@ static private_initiate_mediation_job_t *initiate_mediation_job_create_empty()
/* private variables */
this->mediation_sa_id = NULL;
this->mediated_sa_id = NULL;
- this->mediated_child = NULL;
return this;
}
@@ -224,16 +212,13 @@ static private_initiate_mediation_job_t *initiate_mediation_job_create_empty()
/*
* Described in header
*/
-initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id,
- child_cfg_t *child_cfg)
+initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id)
{
private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty();
this->public.job_interface.execute = (void (*) (job_t *)) initiate;
this->mediated_sa_id = ike_sa_id->clone(ike_sa_id);
- child_cfg->get_ref(child_cfg);
- this->mediated_child = child_cfg;
return &this->public;
}
diff --git a/src/charon/processing/jobs/initiate_mediation_job.h b/src/charon/processing/jobs/initiate_mediation_job.h
index 9fb3b0f7d..966da95d3 100644
--- a/src/charon/processing/jobs/initiate_mediation_job.h
+++ b/src/charon/processing/jobs/initiate_mediation_job.h
@@ -1,11 +1,5 @@
-/**
- * @file initiate_mediation_job.h
- *
- * @brief Interface of initiate_mediation_job_t.
- */
-
/*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -17,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: initiate_mediation_job.h 3792 2008-04-10 12:51:04Z tobias $
+ */
+
+/**
+ * @defgroup initiate_mediation_job initiate_mediation_job
+ * @{ @ingroup jobs
*/
#ifndef INITIATE_MEDIATION_JOB_H_
@@ -25,19 +26,13 @@
typedef struct initiate_mediation_job_t initiate_mediation_job_t;
#include <processing/jobs/job.h>
-#include <config/child_cfg.h>
#include <sa/ike_sa_id.h>
/**
- * @brief Class representing a INITIATE_MEDIATION Job.
+ * Class representing a INITIATE_MEDIATION Job.
*
* This job will initiate a mediation on behalf of a mediated connection.
* If required the mediation connection is established.
- *
- * @b Constructors:
- * - initiate_mediation_job_create()
- *
- * @ingroup jobs
*/
struct initiate_mediation_job_t {
/**
@@ -47,28 +42,22 @@ struct initiate_mediation_job_t {
};
/**
- * @brief Creates a job of type INITIATE_MEDIATION.
+ * Creates a job of type INITIATE_MEDIATION.
*
* @param ike_sa_id identification of the ike_sa as ike_sa_id_t object (gets cloned)
- * @param child_cfg child config of the child_sa (gets cloned)
* @return job object
- *
- * @ingroup jobs
*/
-initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id,
- child_cfg_t *child_cfg);
+initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id);
/**
- * @brief Creates a special job of type INITIATE_MEDIATION that reinitiates a
+ * Creates a special job of type INITIATE_MEDIATION that reinitiates a
* specific connection.
*
* @param mediation_sa_id identification of the mediation sa (gets cloned)
* @param mediated_sa_id identification of the mediated sa (gets cloned)
* @return job object
- *
- * @ingroup jobs
*/
initiate_mediation_job_t *reinitiate_mediation_job_create(ike_sa_id_t *mediation_sa_id,
ike_sa_id_t *mediated_sa_id);
-#endif /*INITIATE_MEDIATION_JOB_H_*/
+#endif /*INITIATE_MEDIATION_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/job.h b/src/charon/processing/jobs/job.h
index 1826c53b4..61f639936 100644
--- a/src/charon/processing/jobs/job.h
+++ b/src/charon/processing/jobs/job.h
@@ -1,10 +1,3 @@
-/**
- * @file job.h
- *
- * @brief Interface job_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup job job
+ * @{ @ingroup jobs
*/
#ifndef JOB_H_
@@ -28,38 +28,27 @@ typedef struct job_t job_t;
#include <library.h>
-
/**
- * @brief Job-Interface as it is stored in the job queue.
- *
- * @b Constructors:
- * - None, use specific implementation of the interface.
- *
- * @ingroup jobs
+ * Job-Interface as it is stored in the job queue.
*/
struct job_t {
/**
- * @brief Execute a job.
+ * Execute a job.
*
* The processing facility executes a job using this method. Jobs are
* one-shot, they destroy themself after execution, so don't use a job
* once it has been executed.
- *
- * @param this calling object
*/
void (*execute) (job_t *this);
/**
- * @brief Destroy a job.
+ * Destroy a job.
*
* Is only called whenever a job was not executed (e.g. due daemon shutdown).
* After execution, jobs destroy themself.
- *
- * @param job_t calling object
*/
void (*destroy) (job_t *job);
};
-#endif /* JOB_H_ */
-
+#endif /* JOB_H_ @} */
diff --git a/src/charon/processing/jobs/mediation_job.c b/src/charon/processing/jobs/mediation_job.c
index 3b9d363d7..c177d8db3 100644
--- a/src/charon/processing/jobs/mediation_job.c
+++ b/src/charon/processing/jobs/mediation_job.c
@@ -1,10 +1,3 @@
-/**
- * @file mediation_job.c
- *
- * @brief Implementation of mediation_job_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,9 +11,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: mediation_job.c 3666 2008-03-26 18:40:19Z tobias $
*/
-
#include "mediation_job.h"
#include <encoding/payloads/endpoint_notify.h>
@@ -49,14 +43,14 @@ struct private_mediation_job_t {
identification_t *source;
/**
- * P2P_SESSIONID
+ * ME_CONNECTID
*/
- chunk_t session_id;
+ chunk_t connect_id;
/**
- * P2P_SESSIONKEY
+ * ME_CONNECTKEY
*/
- chunk_t session_key;
+ chunk_t connect_key;
/**
* Submitted endpoints
@@ -81,8 +75,8 @@ static void destroy(private_mediation_job_t *this)
{
DESTROY_IF(this->target);
DESTROY_IF(this->source);
- chunk_free(&this->session_id);
- chunk_free(&this->session_key);
+ chunk_free(&this->connect_id);
+ chunk_free(&this->connect_key);
DESTROY_OFFSET_IF(this->endpoints, offsetof(endpoint_notify_t, destroy));
free(this);
}
@@ -117,8 +111,8 @@ static void execute(private_mediation_job_t *this)
else
{
/* normal mediation between two peers */
- if (target_sa->relay(target_sa, this->source, this->session_id,
- this->session_key, this->endpoints, this->response) != SUCCESS)
+ if (target_sa->relay(target_sa, this->source, this->connect_id,
+ this->connect_key, this->endpoints, this->response) != SUCCESS)
{
DBG1(DBG_JOB, "mediation between '%D' and '%D' failed",
this->source, this->target);
@@ -160,8 +154,8 @@ static private_mediation_job_t *mediation_job_create_empty()
this->target = NULL;
this->source = NULL;
this->callback = FALSE;
- this->session_id = chunk_empty;
- this->session_key = chunk_empty;
+ this->connect_id = chunk_empty;
+ this->connect_key = chunk_empty;
this->endpoints = NULL;
this->response = FALSE;
@@ -172,15 +166,15 @@ static private_mediation_job_t *mediation_job_create_empty()
* Described in header
*/
mediation_job_t *mediation_job_create(identification_t *peer_id,
- identification_t *requester, chunk_t session_id, chunk_t session_key,
+ identification_t *requester, chunk_t connect_id, chunk_t connect_key,
linked_list_t *endpoints, bool response)
{
private_mediation_job_t *this = mediation_job_create_empty();
this->target = peer_id->clone(peer_id);
this->source = requester->clone(requester);
- this->session_id = chunk_clone(session_id);
- this->session_key = chunk_clone(session_key);
+ this->connect_id = chunk_clone(connect_id);
+ this->connect_key = chunk_clone(connect_key);
this->endpoints = endpoints->clone_offset(endpoints, offsetof(endpoint_notify_t, clone));
this->response = response;
diff --git a/src/charon/processing/jobs/mediation_job.h b/src/charon/processing/jobs/mediation_job.h
index 6130b2e27..0e2901180 100644
--- a/src/charon/processing/jobs/mediation_job.h
+++ b/src/charon/processing/jobs/mediation_job.h
@@ -1,9 +1,3 @@
-/**
- * @file mediation_job.h
- *
- * @brief Interface of mediation_job_t.
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -17,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: mediation_job.h 3666 2008-03-26 18:40:19Z tobias $
+ */
+
+/**
+ * @defgroup mediation_job mediation_job
+ * @{ @ingroup jobs
*/
#ifndef MEDIATION_JOB_H_
@@ -30,14 +31,9 @@ typedef struct mediation_job_t mediation_job_t;
#include <utils/linked_list.h>
/**
- * @brief Class representing a MEDIATION Job.
+ * Class representing a MEDIATION Job.
*
* This job handles the mediation on the mediation server.
- *
- * @b Constructors:
- * - mediation_job_create()
- *
- * @ingroup jobs
*/
struct mediation_job_t {
/**
@@ -47,27 +43,25 @@ struct mediation_job_t {
};
/**
- * @brief Creates a job of type MEDIATION.
+ * Creates a job of type MEDIATION.
*
* Parameters get cloned.
*
* @param peer_id ID of the requested peer
* @param requester ID of the requesting peer
- * @param session_id content of P2P_SESSIONID (could be NULL)
- * @param session_key content of P2P_SESSIONKEY
+ * @param connect_id content of ME_CONNECTID (could be NULL)
+ * @param connect_key content of ME_CONNECTKEY
* @param endpoints list of submitted endpoints
* @param response TRUE if this is a response
* @return job object
- *
- * @ingroup jobs
*/
mediation_job_t *mediation_job_create(identification_t *peer_id,
- identification_t *requester, chunk_t session_id, chunk_t session_key,
+ identification_t *requester, chunk_t connect_id, chunk_t connect_key,
linked_list_t *endpoints, bool response);
/**
- * @brief Creates a special job of type MEDIATION that is used to send a callback
+ * Creates a special job of type MEDIATION that is used to send a callback
* notification to a peer.
*
* Parameters get cloned.
@@ -75,10 +69,8 @@ mediation_job_t *mediation_job_create(identification_t *peer_id,
* @param requester ID of the waiting peer
* @param peer_id ID of the requested peer
* @return job object
- *
- * @ingroup jobs
*/
mediation_job_t *mediation_callback_job_create(identification_t *requester,
identification_t *peer_id);
-#endif /*MEDIATION_JOB_H_*/
+#endif /*MEDIATION_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/process_message_job.c b/src/charon/processing/jobs/process_message_job.c
index 91e7a80bf..33bcae6f0 100644
--- a/src/charon/processing/jobs/process_message_job.c
+++ b/src/charon/processing/jobs/process_message_job.c
@@ -1,10 +1,3 @@
-/**
- * @file process_message_job.h
- *
- * @brief Implementation of process_message_job_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,9 +12,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: process_message_job.c 3666 2008-03-26 18:40:19Z tobias $
*/
-
#include "process_message_job.h"
#include <daemon.h>
@@ -59,7 +53,7 @@ static void execute(private_process_message_job_t *this)
{
ike_sa_t *ike_sa;
-#ifdef P2P
+#ifdef ME
/* if this is an unencrypted INFORMATIONAL exchange it is likely a
* connectivity check. */
if (this->message->get_exchange_type(this->message) == INFORMATIONAL &&
@@ -74,7 +68,7 @@ static void execute(private_process_message_job_t *this)
destroy(this);
return;
}
-#endif /* P2P */
+#endif /* ME */
ike_sa = charon->ike_sa_manager->checkout_by_message(charon->ike_sa_manager,
this->message);
diff --git a/src/charon/processing/jobs/process_message_job.h b/src/charon/processing/jobs/process_message_job.h
index 5bb18155a..920444db1 100644
--- a/src/charon/processing/jobs/process_message_job.h
+++ b/src/charon/processing/jobs/process_message_job.h
@@ -1,10 +1,3 @@
-/**
- * @file process_message_job.h
- *
- * @brief Interface of process_message_job_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: process_message_job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup process_message_job process_message_job
+ * @{ @ingroup jobs
*/
#ifndef PROCESS_MESSAGE_JOB_H_
@@ -31,12 +31,7 @@ typedef struct process_message_job_t process_message_job_t;
#include <processing/jobs/job.h>
/**
- * @brief Class representing an PROCESS_MESSAGE job.
- *
- * @b Constructors:
- * - process_message_job_create()
- *
- * @ingroup jobs
+ * Class representing an PROCESS_MESSAGE job.
*/
struct process_message_job_t {
/**
@@ -46,13 +41,11 @@ struct process_message_job_t {
};
/**
- * @brief Creates a job of type PROCESS_MESSAGE.
+ * Creates a job of type PROCESS_MESSAGE.
*
* @param message message to process
* @return created process_message_job_t object
- *
- * @ingroup jobs
*/
process_message_job_t *process_message_job_create(message_t *message);
-#endif /*PROCESS_MESSAGE_JOB_H_*/
+#endif /*PROCESS_MESSAGE_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/rekey_child_sa_job.c b/src/charon/processing/jobs/rekey_child_sa_job.c
index f754e5a1f..42bf79d26 100644
--- a/src/charon/processing/jobs/rekey_child_sa_job.c
+++ b/src/charon/processing/jobs/rekey_child_sa_job.c
@@ -1,10 +1,3 @@
-/**
- * @file rekey_child_sa_job.c
- *
- * @brief Implementation of rekey_child_sa_job_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: rekey_child_sa_job.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "rekey_child_sa_job.h"
diff --git a/src/charon/processing/jobs/rekey_child_sa_job.h b/src/charon/processing/jobs/rekey_child_sa_job.h
index df86070bc..38fd04f10 100644
--- a/src/charon/processing/jobs/rekey_child_sa_job.h
+++ b/src/charon/processing/jobs/rekey_child_sa_job.h
@@ -1,10 +1,3 @@
-/**
- * @file rekey_child_sa_job.h
- *
- * @brief Interface of rekey_child_sa_job_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: rekey_child_sa_job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup rekey_child_sa_job rekey_child_sa_job
+ * @{ @ingroup jobs
*/
#ifndef REKEY_CHILD_SA_JOB_H_
@@ -31,14 +31,9 @@ typedef struct rekey_child_sa_job_t rekey_child_sa_job_t;
#include <config/proposal.h>
/**
- * @brief Class representing an REKEY_CHILD_SA Job.
+ * Class representing an REKEY_CHILD_SA Job.
*
* This job initiates the rekeying of a CHILD SA.
- *
- * @b Constructors:
- * - rekey_child_sa_job_create()
- *
- * @ingroup jobs
*/
struct rekey_child_sa_job_t {
/**
@@ -48,7 +43,7 @@ struct rekey_child_sa_job_t {
};
/**
- * @brief Creates a job of type REKEY_CHILD_SA.
+ * Creates a job of type REKEY_CHILD_SA.
*
* The CHILD_SA is identified by its protocol (AH/ESP) and its
* inbound SPI.
@@ -57,9 +52,8 @@ struct rekey_child_sa_job_t {
* @param protocol protocol of the CHILD_SA
* @param spi security parameter index of the CHILD_SA
* @return rekey_child_sa_job_t object
- *
- * @ingroup jobs
*/
-rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid, protocol_id_t protocol, u_int32_t spi);
-
-#endif /* REKEY_CHILD_SA_JOB_H_ */
+rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
+ protocol_id_t protocol,
+ u_int32_t spi);
+#endif /* REKEY_CHILD_SA_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/rekey_ike_sa_job.c b/src/charon/processing/jobs/rekey_ike_sa_job.c
index 020c3cce8..38aa41c27 100644
--- a/src/charon/processing/jobs/rekey_ike_sa_job.c
+++ b/src/charon/processing/jobs/rekey_ike_sa_job.c
@@ -1,10 +1,3 @@
-/**
- * @file rekey_ike_sa_job.c
- *
- * @brief Implementation of rekey_ike_sa_job_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,13 +11,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: rekey_ike_sa_job.c 3793 2008-04-11 08:14:48Z martin $
*/
-
+
#include "rekey_ike_sa_job.h"
#include <daemon.h>
-
typedef struct private_rekey_ike_sa_job_t private_rekey_ike_sa_job_t;
/**
@@ -74,7 +68,7 @@ static void execute(private_rekey_ike_sa_job_t *this)
{
if (this->reauth)
{
- status = ike_sa->reestablish(ike_sa);
+ status = ike_sa->reauth(ike_sa);
}
else
{
diff --git a/src/charon/processing/jobs/rekey_ike_sa_job.h b/src/charon/processing/jobs/rekey_ike_sa_job.h
index 4031b3813..c8d9abee3 100644
--- a/src/charon/processing/jobs/rekey_ike_sa_job.h
+++ b/src/charon/processing/jobs/rekey_ike_sa_job.h
@@ -1,10 +1,3 @@
-/**
- * @file rekey_ike_sa_job.h
- *
- * @brief Interface of rekey_ike_sa_job_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: rekey_ike_sa_job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup rekey_ike_sa_job rekey_ike_sa_job
+ * @{ @ingroup jobs
*/
#ifndef REKEY_IKE_SA_JOB_H_
@@ -30,14 +30,9 @@ typedef struct rekey_ike_sa_job_t rekey_ike_sa_job_t;
#include <processing/jobs/job.h>
/**
- * @brief Class representing an REKEY_IKE_SA Job.
+ * Class representing an REKEY_IKE_SA Job.
*
* This job initiates the rekeying of an IKE_SA.
- *
- * @b Constructors:
- * - rekey_ike_sa_job_create()
- *
- * @ingroup jobs
*/
struct rekey_ike_sa_job_t {
/**
@@ -47,14 +42,12 @@ struct rekey_ike_sa_job_t {
};
/**
- * @brief Creates a job of type REKEY_IKE_SA.
+ * Creates a job of type REKEY_IKE_SA.
*
* @param ike_sa_id ID of the IKE_SA to rekey
* @param reauth TRUE to reauthenticate peer, FALSE for rekeying only
* @return rekey_ike_sa_job_t object
- *
- * @ingroup jobs
*/
rekey_ike_sa_job_t *rekey_ike_sa_job_create(ike_sa_id_t *ike_sa_id, bool reauth);
-#endif /* REKEY_IKE_SA_JOB_H_ */
+#endif /* REKEY_IKE_SA_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/retransmit_job.c b/src/charon/processing/jobs/retransmit_job.c
index 8c15aa651..89858786e 100644
--- a/src/charon/processing/jobs/retransmit_job.c
+++ b/src/charon/processing/jobs/retransmit_job.c
@@ -1,10 +1,3 @@
-/**
- * @file retransmit_job.c
- *
- * @brief Implementation of retransmit_job_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: retransmit_job.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "retransmit_job.h"
diff --git a/src/charon/processing/jobs/retransmit_job.h b/src/charon/processing/jobs/retransmit_job.h
index 93bb548e7..60932b304 100644
--- a/src/charon/processing/jobs/retransmit_job.h
+++ b/src/charon/processing/jobs/retransmit_job.h
@@ -1,10 +1,3 @@
-/**
- * @file retransmit_job.h
- *
- * @brief Interface of retransmit_job_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: retransmit_job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup retransmit_job retransmit_job
+ * @{ @ingroup jobs
*/
#ifndef RETRANSMIT_JOB_H_
@@ -31,16 +31,11 @@ typedef struct retransmit_job_t retransmit_job_t;
#include <sa/ike_sa_id.h>
/**
- * @brief Class representing an retransmit Job.
+ * Class representing an retransmit Job.
*
* This job is scheduled every time a request is sent over the
* wire. If the response to the request is not received at schedule
* time, the retransmission will be initiated.
- *
- * @b Constructors:
- * - retransmit_job_create()
- *
- * @ingroup jobs
*/
struct retransmit_job_t {
/**
@@ -50,15 +45,13 @@ struct retransmit_job_t {
};
/**
- * @brief Creates a job of type retransmit.
+ * Creates a job of type retransmit.
*
* @param message_id message_id of the request to resend
* @param ike_sa_id identification of the ike_sa as ike_sa_id_t
* @return retransmit_job_t object
- *
- * @ingroup jobs
*/
retransmit_job_t *retransmit_job_create(u_int32_t message_id,
ike_sa_id_t *ike_sa_id);
-#endif /* RETRANSMIT_JOB_H_ */
+#endif /* RETRANSMIT_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/roam_job.c b/src/charon/processing/jobs/roam_job.c
index 842f57405..0b323ae8b 100644
--- a/src/charon/processing/jobs/roam_job.c
+++ b/src/charon/processing/jobs/roam_job.c
@@ -1,10 +1,3 @@
-/**
- * @file roam_job.c
- *
- * @brief Implementation of roam_job_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,9 +11,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: roam_job.c 3804 2008-04-14 11:37:46Z martin $
*/
-
#include <stdlib.h>
#include "roam_job.h"
@@ -62,18 +56,18 @@ static void execute(private_roam_job_t *this)
ike_sa_t *ike_sa;
linked_list_t *list;
ike_sa_id_t *id;
- iterator_t *iterator;
+ enumerator_t *enumerator;
- /* iterating over all IKE_SAs gives us no way to checkin_and_destroy
+ /* enumerator over all IKE_SAs gives us no way to checkin_and_destroy
* after a DESTROY_ME, so we check out each available IKE_SA by hand. */
list = linked_list_create();
- iterator = charon->ike_sa_manager->create_iterator(charon->ike_sa_manager);
- while (iterator->iterate(iterator, (void**)&ike_sa))
+ enumerator = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager);
+ while (enumerator->enumerate(enumerator, &ike_sa))
{
id = ike_sa->get_id(ike_sa);
list->insert_last(list, id->clone(id));
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
while (list->remove_last(list, (void**)&id) == SUCCESS)
{
diff --git a/src/charon/processing/jobs/roam_job.h b/src/charon/processing/jobs/roam_job.h
index 293b09f08..763416b4a 100644
--- a/src/charon/processing/jobs/roam_job.h
+++ b/src/charon/processing/jobs/roam_job.h
@@ -1,9 +1,3 @@
-/**
- * @file roam_job.h
- *
- * @brief Interface of roam_job_t.
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -17,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: roam_job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup roam_job roam_job
+ * @{ @ingroup jobs
*/
#ifndef ROAM_JOB_H_
@@ -29,15 +30,10 @@ typedef struct roam_job_t roam_job_t;
#include <processing/jobs/job.h>
/**
- * @brief A job to inform IKE_SAs about changed local address setup.
+ * A job to inform IKE_SAs about changed local address setup.
*
* If a local address appears or disappears, the kernel fires this job to
* update all IKE_SAs.
- *
- * @b Constructors:
- * - roam_job_create()
- *
- * @ingroup jobs
*/
struct roam_job_t {
@@ -48,14 +44,11 @@ struct roam_job_t {
};
/**
- * @brief Creates a job to inform IKE_SAs about an updated address list.
+ * Creates a job to inform IKE_SAs about an updated address list.
*
* @param address TRUE if address list changed, FALSE if routing changed
* @return initiate_ike_sa_job_t object
- *
- * @ingroup jobs
*/
roam_job_t *roam_job_create(bool address);
-#endif /*ROAM_JOB_H_*/
-
+#endif /*ROAM_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/send_dpd_job.c b/src/charon/processing/jobs/send_dpd_job.c
index d9c457ab6..a7d0cf3f3 100644
--- a/src/charon/processing/jobs/send_dpd_job.c
+++ b/src/charon/processing/jobs/send_dpd_job.c
@@ -1,10 +1,3 @@
-/**
- * @file send_dpd_job.c
- *
- * @brief Implementation of send_dpd_job_t.
- *
- */
-
/*
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
* Hochschule fuer Technik Rapperswil
@@ -18,9 +11,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: send_dpd_job.c 3589 2008-03-13 14:14:44Z martin $
*/
-
#include <stdlib.h>
#include "send_dpd_job.h"
diff --git a/src/charon/processing/jobs/send_dpd_job.h b/src/charon/processing/jobs/send_dpd_job.h
index 0e4059131..032823edd 100644
--- a/src/charon/processing/jobs/send_dpd_job.h
+++ b/src/charon/processing/jobs/send_dpd_job.h
@@ -1,9 +1,3 @@
-/**
- * @file send_dpd_job.h
- *
- * @brief Interface of send_dpd_job_t.
- */
-
/*
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
* Hochschule fuer Technik Rapperswil
@@ -17,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: send_dpd_job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup send_dpd_job send_dpd_job
+ * @{ @ingroup jobs
*/
#ifndef SEND_DPD_JOB_H_
@@ -29,16 +30,11 @@ typedef struct send_dpd_job_t send_dpd_job_t;
#include <sa/ike_sa_id.h>
/**
- * @brief Class representing a SEND_DPD Job.
+ * Class representing a SEND_DPD Job.
*
* Job to periodically send a Dead Peer Detection (DPD) request,
* ie. an IKE request with no payloads other than the encrypted payload
* required by the syntax.
- *
- * @b Constructors:
- * - send_dpd_job_create()
- *
- * @ingroup jobs
*/
struct send_dpd_job_t {
/**
@@ -48,13 +44,11 @@ struct send_dpd_job_t {
};
/**
- * @brief Creates a job of type SEND_DPD.
+ * Creates a job of type SEND_DPD.
*
* @param ike_sa_id identification of the ike_sa as ike_sa_id_t object (gets cloned)
* @return initiate_ike_sa_job_t object
- *
- * @ingroup jobs
*/
send_dpd_job_t *send_dpd_job_create(ike_sa_id_t *ike_sa_id);
-#endif /*SEND_DPD_JOB_H_*/
+#endif /*SEND_DPD_JOB_H_ @} */
diff --git a/src/charon/processing/jobs/send_keepalive_job.c b/src/charon/processing/jobs/send_keepalive_job.c
index 34198deb0..82f6a5f55 100644
--- a/src/charon/processing/jobs/send_keepalive_job.c
+++ b/src/charon/processing/jobs/send_keepalive_job.c
@@ -1,10 +1,3 @@
-/**
- * @file send_keepalive_job.c
- *
- * @brief Implementation of send_keepalive_job_t.
- *
- */
-
/*
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
* Hochschule fuer Technik Rapperswil
@@ -18,9 +11,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: send_keepalive_job.c 3589 2008-03-13 14:14:44Z martin $
*/
-
#include <stdlib.h>
#include "send_keepalive_job.h"
diff --git a/src/charon/processing/jobs/send_keepalive_job.h b/src/charon/processing/jobs/send_keepalive_job.h
index e8d214aed..44bab09b4 100644
--- a/src/charon/processing/jobs/send_keepalive_job.h
+++ b/src/charon/processing/jobs/send_keepalive_job.h
@@ -1,9 +1,3 @@
-/**
- * @file send_keepalive_job.h
- *
- * @brief Interface of send_keepalive_job_t.
- */
-
/*
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
* Hochschule fuer Technik Rapperswil
@@ -17,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: send_keepalive_job.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup send_keepalive_job send_keepalive_job
+ * @{ @ingroup jobs
*/
#ifndef SEND_KEEPALIVE_JOB_H_
@@ -29,15 +30,10 @@ typedef struct send_keepalive_job_t send_keepalive_job_t;
#include <sa/ike_sa_id.h>
/**
- * @brief Class representing a SEND_KEEPALIVE Job.
+ * Class representing a SEND_KEEPALIVE Job.
*
* This job will send a NAT keepalive packet if the IKE SA is still alive,
* and reinsert itself into the event queue.
- *
- * @b Constructors:
- * - send_keepalive_job_create()
- *
- * @ingroup jobs
*/
struct send_keepalive_job_t {
/**
@@ -47,13 +43,11 @@ struct send_keepalive_job_t {
};
/**
- * @brief Creates a job of type SEND_KEEPALIVE.
+ * Creates a job of type SEND_KEEPALIVE.
*
* @param ike_sa_id identification of the ike_sa as ike_sa_id_t object (gets cloned)
* @return initiate_ike_sa_job_t object
- *
- * @ingroup jobs
*/
send_keepalive_job_t *send_keepalive_job_create(ike_sa_id_t *ike_sa_id);
-#endif /*SEND_KEEPALIVE_JOB_H_*/
+#endif /*SEND_KEEPALIVE_JOB_H_ @} */
diff --git a/src/charon/processing/processor.c b/src/charon/processing/processor.c
index b3815eeb1..010f6624f 100644
--- a/src/charon/processing/processor.c
+++ b/src/charon/processing/processor.c
@@ -1,10 +1,3 @@
-/**
- * @file processor.c
- *
- * @brief Implementation of processor_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: processor.c 3742 2008-04-03 09:19:12Z tobias $
*/
#include <stdlib.h>
@@ -35,7 +30,7 @@
typedef struct private_processor_t private_processor_t;
/**
- * @brief Private data of processor_t class.
+ * Private data of processor_t class.
*/
struct private_processor_t {
/**
@@ -71,7 +66,12 @@ struct private_processor_t {
/**
* Condvar to wait for new jobs
*/
- pthread_cond_t condvar;
+ pthread_cond_t jobadded;
+
+ /**
+ * Condvar to wait for terminated threads
+ */
+ pthread_cond_t threadterminated;
};
static void process_jobs(private_processor_t *this);
@@ -85,7 +85,10 @@ static void restart(private_processor_t *this)
if (pthread_create(&thread, NULL, (void*)process_jobs, this) != 0)
{
+ pthread_mutex_lock(&this->mutex);
this->total_threads--;
+ pthread_cond_broadcast(&this->threadterminated);
+ pthread_mutex_unlock(&this->mutex);
}
}
@@ -108,7 +111,7 @@ static void process_jobs(private_processor_t *this)
if (this->list->get_count(this->list) == 0)
{
this->idle_threads++;
- pthread_cond_wait(&this->condvar, &this->mutex);
+ pthread_cond_wait(&this->jobadded, &this->mutex);
this->idle_threads--;
continue;
}
@@ -121,7 +124,7 @@ static void process_jobs(private_processor_t *this)
pthread_mutex_lock(&this->mutex);
}
this->total_threads--;
- pthread_cond_broadcast(&this->condvar);
+ pthread_cond_signal(&this->threadterminated);
pthread_mutex_unlock(&this->mutex);
}
@@ -130,7 +133,11 @@ static void process_jobs(private_processor_t *this)
*/
static u_int get_total_threads(private_processor_t *this)
{
- return this->total_threads;
+ u_int count;
+ pthread_mutex_lock(&this->mutex);
+ count = this->total_threads;
+ pthread_mutex_unlock(&this->mutex);
+ return count;
}
/**
@@ -138,7 +145,11 @@ static u_int get_total_threads(private_processor_t *this)
*/
static u_int get_idle_threads(private_processor_t *this)
{
- return this->idle_threads;
+ u_int count;
+ pthread_mutex_lock(&this->mutex);
+ count = this->idle_threads;
+ pthread_mutex_unlock(&this->mutex);
+ return count;
}
/**
@@ -160,8 +171,8 @@ static void queue_job(private_processor_t *this, job_t *job)
{
pthread_mutex_lock(&this->mutex);
this->list->insert_last(this->list, job);
+ pthread_cond_signal(&this->jobadded);
pthread_mutex_unlock(&this->mutex);
- pthread_cond_signal(&this->condvar);
}
/**
@@ -189,6 +200,7 @@ static void set_threads(private_processor_t *this, u_int count)
{ /* decrease thread count */
this->desired_threads = count;
}
+ pthread_cond_broadcast(&this->jobadded);
pthread_mutex_unlock(&this->mutex);
}
@@ -198,11 +210,13 @@ static void set_threads(private_processor_t *this, u_int count)
static void destroy(private_processor_t *this)
{
set_threads(this, 0);
+ pthread_mutex_lock(&this->mutex);
while (this->total_threads > 0)
{
- pthread_cond_broadcast(&this->condvar);
- pthread_cond_wait(&this->condvar, &this->mutex);
+ pthread_cond_broadcast(&this->jobadded);
+ pthread_cond_wait(&this->threadterminated, &this->mutex);
}
+ pthread_mutex_unlock(&this->mutex);
this->list->destroy_offset(this->list, offsetof(job_t, destroy));
free(this);
}
@@ -223,7 +237,8 @@ processor_t *processor_create(size_t pool_size)
this->list = linked_list_create();
pthread_mutex_init(&this->mutex, NULL);
- pthread_cond_init(&this->condvar, NULL);
+ pthread_cond_init(&this->jobadded, NULL);
+ pthread_cond_init(&this->threadterminated, NULL);
this->total_threads = 0;
this->desired_threads = 0;
this->idle_threads = 0;
diff --git a/src/charon/processing/processor.h b/src/charon/processing/processor.h
index f12c7f10e..530fbc24b 100644
--- a/src/charon/processing/processor.h
+++ b/src/charon/processing/processor.h
@@ -1,10 +1,3 @@
-/**
- * @file processor.h
- *
- * @brief Interface of processor_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: processor.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup processor processor
+ * @{ @ingroup processing
*/
#ifndef PROCESSOR_H_
@@ -32,80 +32,65 @@ typedef struct processor_t processor_t;
#include <processing/jobs/job.h>
/**
- * @brief The processor uses threads to process queued jobs.
- *
- * @b Constructors:
- * - processor_create()
- *
- * @ingroup processing
+ * The processor uses threads to process queued jobs.
*/
struct processor_t {
/**
- * @brief Get the total number of threads used by the processor.
- *
- * @param this calling object
+ * Get the total number of threads used by the processor.
+ *
* @return size of thread pool
*/
u_int (*get_total_threads) (processor_t *this);
/**
- * @brief Get the number of threads currently waiting.
- *
- * @param this calling object
+ * Get the number of threads currently waiting.
+ *
* @return number of idle threads
*/
u_int (*get_idle_threads) (processor_t *this);
/**
- * @brief Get the number of queued jobs.
+ * Get the number of queued jobs.
*
- * @param this calling object
* @returns number of items in queue
*/
u_int (*get_job_load) (processor_t *this);
/**
- * @brief Adds a job to the queue.
+ * Adds a job to the queue.
*
* This function is non blocking and adds a job_t to the queue.
*
- * @param this calling object
* @param job job to add to the queue
*/
void (*queue_job) (processor_t *this, job_t *job);
/**
- * @brief Set the number of threads to use in the processor.
+ * Set the number of threads to use in the processor.
*
* If the number of threads is smaller than number of currently running
* threads, thread count is decreased. Use 0 to disable the processor.
* This call blocks if it decreases thread count until threads have
* terminated, so make sure there are not too many blocking jobs.
*
- * @param this calling object
* @param count number of threads to allocate
*/
void (*set_threads)(processor_t *this, u_int count);
/**
- * @brief Destroy a processor object.
- *
- * @param processor calling object
+ * Destroy a processor object.
*/
void (*destroy) (processor_t *processor);
};
/**
- * @brief Create the thread pool without any threads.
+ * Create the thread pool without any threads.
*
* Use the set_threads method to start processing jobs.
*
* @return processor_t object
- *
- * @ingroup processing
*/
processor_t *processor_create();
-#endif /*PROCESSOR_H_*/
-
+#endif /*PROCESSOR_H_ @} */
diff --git a/src/charon/processing/scheduler.c b/src/charon/processing/scheduler.c
index ededb479a..42aa2579e 100644
--- a/src/charon/processing/scheduler.c
+++ b/src/charon/processing/scheduler.c
@@ -1,10 +1,3 @@
-/**
- * @file scheduler.c
- *
- * @brief Implementation of scheduler_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: scheduler.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdlib.h>
diff --git a/src/charon/processing/scheduler.h b/src/charon/processing/scheduler.h
index 7bde6e638..edc17a02b 100644
--- a/src/charon/processing/scheduler.h
+++ b/src/charon/processing/scheduler.h
@@ -1,10 +1,3 @@
-/**
- * @file scheduler.h
- *
- * @brief Interface of scheduler_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: scheduler.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup scheduler scheduler
+ * @{ @ingroup processing
*/
#ifndef SCHEDULER_H_
@@ -30,52 +30,40 @@ typedef struct scheduler_t scheduler_t;
#include <processing/jobs/job.h>
/**
- * @brief The scheduler queues and executes timed events.
+ * The scheduler queues and executes timed events.
*
* The scheduler stores timed events and passes them to the processor.
- *
- * @b Constructors:
- * - scheduler_create()
- *
- * @ingroup processing
*/
struct scheduler_t {
/**
- * @brief Adds a event to the queue, using a relative time offset.
+ * Adds a event to the queue, using a relative time offset.
*
* Schedules a job for execution using a relative time offset.
*
- * @param this calling object
* @param job job to schedule
* @param time relative to to schedule job (in ms)
*/
void (*schedule_job) (scheduler_t *this, job_t *job, u_int32_t time);
/**
- * @brief Returns number of jobs scheduled.
+ * Returns number of jobs scheduled.
*
- * @param this calling object
* @return number of scheduled jobs
*/
u_int (*get_job_load) (scheduler_t *this);
/**
- * @brief Destroys a scheduler object.
- *
- * @param this calling object
+ * Destroys a scheduler object.
*/
void (*destroy) (scheduler_t *this);
};
/**
- * @brief Create a scheduler.
+ * Create a scheduler.
*
* @return scheduler_t object
- *
- * @ingroup processing
*/
scheduler_t *scheduler_create(void);
-#endif /*SCHEDULER_H_*/
-
+#endif /*SCHEDULER_H_ @} */
diff --git a/src/charon/sa/authenticators/authenticator.c b/src/charon/sa/authenticators/authenticator.c
index 707aae9ad..c301e4933 100644
--- a/src/charon/sa/authenticators/authenticator.c
+++ b/src/charon/sa/authenticators/authenticator.c
@@ -1,11 +1,5 @@
-/**
- * @file authenticator.c
- *
- * @brief Generic constructor for authenticators.
- *
- */
-
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -18,13 +12,15 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: authenticator.c 4051 2008-06-10 09:08:27Z tobias $
*/
#include <string.h>
#include "authenticator.h"
-#include <sa/authenticators/rsa_authenticator.h>
+#include <sa/authenticators/pubkey_authenticator.h>
#include <sa/authenticators/psk_authenticator.h>
#include <sa/authenticators/eap_authenticator.h>
@@ -33,23 +29,46 @@ ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS,
"RSA signature",
"pre-shared key",
"DSS signature");
-ENUM_NEXT(auth_method_names, AUTH_EAP, AUTH_EAP, AUTH_DSS,
+ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_ECDSA_521, AUTH_DSS,
+ "ECDSA-256 signature",
+ "ECDSA-384 signature",
+ "ECDSA-521 signature");
+ENUM_NEXT(auth_method_names, AUTH_EAP, AUTH_EAP, AUTH_ECDSA_521,
"EAP");
ENUM_END(auth_method_names, AUTH_EAP);
-/*
+/**
* Described in header.
*/
-authenticator_t *authenticator_create(ike_sa_t *ike_sa, auth_method_t auth_method)
+authenticator_t *authenticator_create(ike_sa_t *ike_sa, config_auth_method_t auth_method)
{
switch (auth_method)
{
+ case CONF_AUTH_PUBKEY:
+ return (authenticator_t*)pubkey_authenticator_create(ike_sa);
+ case CONF_AUTH_PSK:
+ return (authenticator_t*)psk_authenticator_create(ike_sa);
+ case CONF_AUTH_EAP:
+ return (authenticator_t*)eap_authenticator_create(ike_sa);
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Described in header.
+ */
+authenticator_t *authenticator_create_from_auth_payload(ike_sa_t *ike_sa, auth_payload_t *auth_payload)
+{
+ switch (auth_payload->get_auth_method(auth_payload))
+ {
case AUTH_RSA:
- return (authenticator_t*)rsa_authenticator_create(ike_sa);
+ case AUTH_ECDSA_256:
+ case AUTH_ECDSA_384:
+ case AUTH_ECDSA_521:
+ return (authenticator_t*)pubkey_authenticator_create(ike_sa);
case AUTH_PSK:
return (authenticator_t*)psk_authenticator_create(ike_sa);
- case AUTH_EAP:
- return (authenticator_t*)eap_authenticator_create(ike_sa);
default:
return NULL;
}
diff --git a/src/charon/sa/authenticators/authenticator.h b/src/charon/sa/authenticators/authenticator.h
index c7b0fc81a..3c961d23e 100644
--- a/src/charon/sa/authenticators/authenticator.h
+++ b/src/charon/sa/authenticators/authenticator.h
@@ -1,11 +1,5 @@
-/**
- * @file authenticator.h
- *
- * @brief Interface of authenticator_t.
- *
- */
-
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -19,6 +13,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: authenticator.h 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+/**
+ * @defgroup authenticator authenticator
+ * @{ @ingroup authenticators
*/
#ifndef AUTHENTICATOR_H_
@@ -29,12 +30,11 @@ typedef struct authenticator_t authenticator_t;
#include <library.h>
#include <sa/ike_sa.h>
+#include <config/peer_cfg.h>
#include <encoding/payloads/auth_payload.h>
/**
* Method to use for authentication.
- *
- * @ingroup authenticators
*/
enum auth_method_t {
/**
@@ -57,6 +57,21 @@ enum auth_method_t {
AUTH_DSS = 3,
/**
+ * ECDSA with SHA-256 on the P-256 curve as specified in RFC 4754
+ */
+ AUTH_ECDSA_256 = 9,
+
+ /**
+ * ECDSA with SHA-384 on the P-384 curve as specified in RFC 4754
+ */
+ AUTH_ECDSA_384 = 10,
+
+ /**
+ * ECDSA with SHA-512 on the P-521 curve as specified in RFC 4754
+ */
+ AUTH_ECDSA_521 = 11,
+
+ /**
* EAP authentication. This value is never negotiated and therefore
* a value from private use.
*/
@@ -65,29 +80,22 @@ enum auth_method_t {
/**
* enum names for auth_method_t.
- *
- * @ingroup authenticators
*/
extern enum_name_t *auth_method_names;
/**
- * @brief Authenticator interface implemented by the various authenticators.
+ * Authenticator interface implemented by the various authenticators.
*
* Currently the following two AUTH methods are supported:
- * - shared key message integrity code (AUTH_PSK)
- * - RSA digital signature (AUTH_RSA)
- *
- * @b Constructors:
- * - authenticator_create()
- *
- * @ingroup authenticators
+ * - shared key message integrity code
+ * - RSA digital signature
+ * - ECDSA is supported using OpenSSL
*/
struct authenticator_t {
/**
- * @brief Verify a received authentication payload.
+ * Verify a received authentication payload.
*
- * @param this calling object
* @param ike_sa_init binary representation of received ike_sa_init
* @param my_nonce the sent nonce
* @param auth_payload authentication payload to verify
@@ -102,9 +110,8 @@ struct authenticator_t {
chunk_t my_nonce, auth_payload_t *auth_payload);
/**
- * @brief Build an authentication payload to send to the other peer.
+ * Build an authentication payload to send to the other peer.
*
- * @param this calling object
* @param ike_sa_init binary representation of sent ike_sa_init
* @param other_nonce the received nonce
* @param[out] auth_payload the resulting authentication payload
@@ -117,23 +124,29 @@ struct authenticator_t {
chunk_t other_nonce, auth_payload_t **auth_payload);
/**
- * @brief Destroys a authenticator_t object.
- *
- * @param this calling object
+ * Destroys a authenticator_t object.
*/
void (*destroy) (authenticator_t *this);
};
/**
- * @brief Creates an authenticator for the specified auth method.
+ * Creates an authenticator for the specified auth method (as configured).
*
* @param ike_sa associated ike_sa
* @param auth_method authentication method to use for build()/verify()
*
* @return authenticator_t object
- *
- * @ingroup authenticators
*/
-authenticator_t *authenticator_create(ike_sa_t *ike_sa, auth_method_t auth_method);
+authenticator_t *authenticator_create(ike_sa_t *ike_sa, config_auth_method_t auth_method);
+
+/**
+ * Creates an authenticator from the given auth payload.
+ *
+ * @param ike_sa associated ike_sa
+ * @param auth_payload auth payload
+ *
+ * @return authenticator_t object
+ */
+authenticator_t *authenticator_create_from_auth_payload(ike_sa_t *ike_sa, auth_payload_t *auth_payload);
-#endif /* AUTHENTICATOR_H_ */
+#endif /* AUTHENTICATOR_H_ @} */
diff --git a/src/charon/sa/authenticators/eap/eap_manager.c b/src/charon/sa/authenticators/eap/eap_manager.c
new file mode 100644
index 000000000..44d84156c
--- /dev/null
+++ b/src/charon/sa/authenticators/eap/eap_manager.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: eap_manager.c 3589 2008-03-13 14:14:44Z martin $
+ */
+
+#include "eap_manager.h"
+
+#include <pthread.h>
+
+#include <utils/linked_list.h>
+
+typedef struct private_eap_manager_t private_eap_manager_t;
+typedef struct eap_entry_t eap_entry_t;
+
+/**
+ * EAP constructor entry
+ */
+struct eap_entry_t {
+
+ /**
+ * EAP method type, vendor specific if vendor is set
+ */
+ eap_type_t type;
+
+ /**
+ * vendor ID, 0 for default EAP methods
+ */
+ u_int32_t vendor;
+
+ /**
+ * Role of the method returned by the constructor, EAP_SERVER or EAP_PEER
+ */
+ eap_role_t role;
+
+ /**
+ * constructor function to create instance
+ */
+ eap_constructor_t constructor;
+};
+
+/**
+ * private data of eap_manager
+ */
+struct private_eap_manager_t {
+
+ /**
+ * public functions
+ */
+ eap_manager_t public;
+
+ /**
+ * list of eap_entry_t's
+ */
+ linked_list_t *methods;
+
+ /**
+ * mutex to lock methods
+ */
+ pthread_mutex_t mutex;
+};
+
+/**
+ * Implementation of eap_manager_t.add_method.
+ */
+static void add_method(private_eap_manager_t *this, eap_type_t type,
+ u_int32_t vendor, eap_role_t role,
+ eap_constructor_t constructor)
+{
+ eap_entry_t *entry = malloc_thing(eap_entry_t);
+
+ entry->type = type;
+ entry->vendor = vendor;
+ entry->role = role;
+ entry->constructor = constructor;
+
+ pthread_mutex_lock(&this->mutex);
+ this->methods->insert_last(this->methods, entry);
+ pthread_mutex_unlock(&this->mutex);
+}
+
+/**
+ * Implementation of eap_manager_t.remove_method.
+ */
+static void remove_method(private_eap_manager_t *this, eap_constructor_t constructor)
+{
+ enumerator_t *enumerator;
+ eap_entry_t *entry;
+
+ pthread_mutex_lock(&this->mutex);
+ enumerator = this->methods->create_enumerator(this->methods);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (constructor == entry->constructor)
+ {
+ this->methods->remove_at(this->methods, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ pthread_mutex_unlock(&this->mutex);
+}
+
+/**
+ * Implementation of eap_manager_t.create_instance.
+ */
+static eap_method_t* create_instance(private_eap_manager_t *this,
+ eap_type_t type, u_int32_t vendor,
+ eap_role_t role, identification_t *server,
+ identification_t *peer)
+{
+ enumerator_t *enumerator;
+ eap_entry_t *entry;
+ eap_method_t *method = NULL;
+
+ pthread_mutex_lock(&this->mutex);
+ enumerator = this->methods->create_enumerator(this->methods);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (type == entry->type && vendor == entry->vendor &&
+ role == entry->role)
+ {
+ method = entry->constructor(server, peer);
+ if (method)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ pthread_mutex_unlock(&this->mutex);
+ return method;
+}
+
+/**
+ * Implementation of 2008_t.destroy
+ */
+static void destroy(private_eap_manager_t *this)
+{
+ this->methods->destroy_function(this->methods, free);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+eap_manager_t *eap_manager_create()
+{
+ private_eap_manager_t *this = malloc_thing(private_eap_manager_t);
+
+ this->public.add_method = (void(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, eap_constructor_t constructor))add_method;
+ this->public.remove_method = (void(*)(eap_manager_t*, eap_constructor_t constructor))remove_method;
+ this->public.create_instance = (eap_method_t*(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, identification_t*,identification_t*))create_instance;
+ this->public.destroy = (void(*)(eap_manager_t*))destroy;
+
+ this->methods = linked_list_create();
+ pthread_mutex_init(&this->mutex, NULL);
+
+ return &this->public;
+}
+
diff --git a/src/charon/sa/authenticators/eap/eap_manager.h b/src/charon/sa/authenticators/eap/eap_manager.h
new file mode 100644
index 000000000..74bfa1f51
--- /dev/null
+++ b/src/charon/sa/authenticators/eap/eap_manager.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: eap_manager.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup eap_manager eap_manager
+ * @{ @ingroup eap
+ */
+
+#ifndef EAP_MANAGER_H_
+#define EAP_MANAGER_H_
+
+#include <sa/authenticators/eap/eap_method.h>
+
+typedef struct eap_manager_t eap_manager_t;
+
+/**
+ * The EAP manager manages all EAP implementations and creates instances.
+ *
+ * A plugin registers it's implemented EAP method at the manager by
+ * providing type and a contructor function. The manager then instanciates
+ * eap_method_t instances through the provided constructor to handle
+ * EAP authentication.
+ */
+struct eap_manager_t {
+
+ /**
+ * Register a EAP method implementation.
+ *
+ * @param method vendor specific method, if vendor != 0
+ * @param vendor vendor ID, 0 for non-vendor (default) EAP methods
+ * @param role EAP role of the registered method
+ * @param constructor constructor function, returns an eap_method_t
+ */
+ void (*add_method)(eap_manager_t *this, eap_type_t type, u_int32_t vendor,
+ eap_role_t role, eap_constructor_t constructor);
+
+ /**
+ * Unregister a EAP method implementation using it's constructor.
+ *
+ * @param constructor constructor function to remove, as added in add_method
+ */
+ void (*remove_method)(eap_manager_t *this, eap_constructor_t constructor);
+
+ /**
+ * Create a new EAP method instance.
+ *
+ * @param type type of the EAP method
+ * @param vendor vendor ID, 0 for non-vendor (default) EAP methods
+ * @param role role of EAP method, either EAP_SERVER or EAP_PEER
+ * @param server identity of the server
+ * @param peer identity of the peer (client)
+ * @return EAP method instance, NULL if no constructor found
+ */
+ eap_method_t* (*create_instance)(eap_manager_t *this, eap_type_t type,
+ u_int32_t vendor, eap_role_t role,
+ identification_t *server,
+ identification_t *peer);
+
+ /**
+ * Destroy a eap_manager instance.
+ */
+ void (*destroy)(eap_manager_t *this);
+};
+
+/**
+ * Create a eap_manager instance.
+ */
+eap_manager_t *eap_manager_create();
+
+#endif /* EAP_MANAGER_H_ @}*/
diff --git a/src/charon/sa/authenticators/eap/eap_method.c b/src/charon/sa/authenticators/eap/eap_method.c
index 7434ca2a1..5e2db5489 100644
--- a/src/charon/sa/authenticators/eap/eap_method.c
+++ b/src/charon/sa/authenticators/eap/eap_method.c
@@ -1,10 +1,3 @@
-/**
- * @file eap_method.c
- *
- * @brief Generic constructor for eap_methods.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,22 +11,12 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_method.c 3589 2008-03-13 14:14:44Z martin $
*/
-#include <string.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <error.h>
-#include <dlfcn.h>
-
#include "eap_method.h"
-#include <daemon.h>
-#include <library.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-
ENUM_BEGIN(eap_type_names, EAP_IDENTITY, EAP_TOKEN_CARD,
"EAP_IDENTITY",
"EAP_NOTIFICATION",
@@ -62,171 +45,3 @@ ENUM(eap_role_names, EAP_SERVER, EAP_PEER,
"EAP_PEER",
);
-
-typedef struct module_entry_t module_entry_t;
-
-/**
- * Representation of a loaded module: EAP type, library handle, constructor
- */
-struct module_entry_t {
- eap_type_t type;
- u_int32_t vendor;
- void *handle;
- eap_constructor_t constructor;
-};
-
-/** List of module_entry_t's */
-static linked_list_t *modules = NULL;
-
-/**
- * unload modules at daemon shutdown
- */
-void eap_method_unload()
-{
- if (modules)
- {
- module_entry_t *entry;
-
- while (modules->remove_last(modules, (void**)&entry) == SUCCESS)
- {
- DBG2(DBG_CFG, "unloaded module EAP module %d-%d",
- entry->type, entry->vendor);
- dlclose(entry->handle);
- free(entry);
- }
- modules->destroy(modules);
- modules = NULL;
- }
-}
-
-/**
- * Load EAP modules at daemon startup
- */
-void eap_method_load(char *directory)
-{
- struct dirent* entry;
- DIR* dir;
-
- eap_method_unload();
- modules = linked_list_create();
-
- dir = opendir(directory);
- if (dir == NULL)
- {
- DBG1(DBG_CFG, "error opening EAP modules directory %s", directory);
- return;
- }
-
- DBG1(DBG_CFG, "loading EAP modules from '%s'", directory);
-
- while ((entry = readdir(dir)) != NULL)
- {
- char file[256];
- module_entry_t module, *loaded_module;
- eap_method_t *method;
- identification_t *id;
- char *ending;
-
- snprintf(file, sizeof(file), "%s/%s", directory, entry->d_name);
-
- ending = entry->d_name + strlen(entry->d_name) - 3;
- if (ending <= entry->d_name || !streq(ending, ".so"))
- {
- /* skip anything which does not look like a library */
- DBG2(DBG_CFG, " skipping %s, doesn't look like a library",
- entry->d_name);
- continue;
- }
-
- /* try to load the library */
- module.handle = dlopen(file, RTLD_LAZY);
- if (module.handle == NULL)
- {
- DBG1(DBG_CFG, " opening EAP module %s failed: %s", entry->d_name,
- dlerror());
- continue;
- }
- module.constructor = dlsym(module.handle, "eap_create");
- if (module.constructor == NULL)
- {
- DBG1(DBG_CFG, " EAP module %s has no eap_create() function, skipped",
- entry->d_name);
- dlclose(module.handle);
- continue;
- }
-
- /* get the type implemented in the method, create an instance for it */
- id = identification_create_from_string("john@doe.xyz");
- method = module.constructor(EAP_SERVER, id, id);
- if (method == NULL)
- {
- method = module.constructor(EAP_PEER, id, id);
- }
- id->destroy(id);
- if (method == NULL)
- {
- DBG1(DBG_CFG, " unable to create instance of EAP method %s, skipped",
- entry->d_name);
- dlclose(module.handle);
- continue;
- }
- module.type = method->get_type(method, &module.vendor);
- method->destroy(method);
-
- if (module.vendor)
- {
- DBG1(DBG_CFG, " loaded EAP method %d, vendor %d successfully from %s",
- module.type, module.vendor, entry->d_name);
- }
- else
- {
- DBG1(DBG_CFG, " loaded EAP method %N successfully from %s",
- eap_type_names, module.type, entry->d_name);
- }
-
- loaded_module = malloc_thing(module_entry_t);
- memcpy(loaded_module, &module, sizeof(module));
- modules->insert_last(modules, loaded_module);
- }
- closedir(dir);
-}
-
-/*
- * Described in header.
- */
-eap_method_t *eap_method_create(eap_type_t type, u_int32_t vendor, eap_role_t role,
- identification_t *server, identification_t *peer)
-{
- eap_method_t *method = NULL;
- iterator_t *iterator;
- module_entry_t *entry;
-
- iterator = modules->create_iterator(modules, TRUE);
- while (iterator->iterate(iterator, (void**)&entry))
- {
- if (entry->type == type && entry->vendor == vendor)
- {
- method = entry->constructor(role, server, peer);
- if (method)
- {
- break;
- }
- }
- }
- iterator->destroy(iterator);
-
- if (method == NULL)
- {
- if (vendor)
- {
- DBG1(DBG_CFG, "no vendor %d specific EAP module found for method "
- "%d %N", vendor, type, eap_role_names, role);
- }
- else
- {
- DBG1(DBG_CFG, "no EAP module found for %N %N",
- eap_type_names, type, eap_role_names, role);
- }
- }
- return method;
-}
diff --git a/src/charon/sa/authenticators/eap/eap_method.h b/src/charon/sa/authenticators/eap/eap_method.h
index 8675fd8ec..eda6f545e 100644
--- a/src/charon/sa/authenticators/eap/eap_method.h
+++ b/src/charon/sa/authenticators/eap/eap_method.h
@@ -1,10 +1,3 @@
-/**
- * @file eap_method.h
- *
- * @brief Interface eap_method_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_method.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup eap_method eap_method
+ * @{ @ingroup eap
*/
#ifndef EAP_METHOD_H_
@@ -34,8 +34,6 @@ typedef enum eap_code_t eap_code_t;
/**
* Role of an eap_method, SERVER or PEER (client)
- *
- * @ingroup eap
*/
enum eap_role_t {
EAP_SERVER,
@@ -43,15 +41,11 @@ enum eap_role_t {
};
/**
* enum names for eap_role_t.
- *
- * @ingroup eap
*/
extern enum_name_t *eap_role_names;
/**
* EAP types, defines the EAP method implementation
- *
- * @ingroup eap
*/
enum eap_type_t {
EAP_IDENTITY = 1,
@@ -68,15 +62,11 @@ enum eap_type_t {
/**
* enum names for eap_type_t.
- *
- * @ingroup eap
*/
extern enum_name_t *eap_type_names;
/**
* EAP code, type of an EAP message
- *
- * @ingroup eap
*/
enum eap_code_t {
EAP_REQUEST = 1,
@@ -87,14 +77,12 @@ enum eap_code_t {
/**
* enum names for eap_code_t.
- *
- * @ingroup eap
*/
extern enum_name_t *eap_code_names;
/**
- * @brief Interface of an EAP method for server and client side.
+ * Interface of an EAP method for server and client side.
*
* An EAP method initiates an EAP exchange and processes requests and
* responses. An EAP method may need multiple exchanges before succeeding, and
@@ -107,22 +95,16 @@ extern enum_name_t *eap_code_names;
* authentication. Even if a mutual EAP method is used, the traditional
* AUTH payloads are required. Only these include the nonces and messages from
* ike_sa_init and therefore prevent man in the middle attacks.
- *
- * @b Constructors:
- * - eap_method_create()
- *
- * @ingroup eap
*/
struct eap_method_t {
/**
- * @brief Initiate the EAP exchange.
+ * Initiate the EAP exchange.
*
* initiate() is only useable for server implementations, as clients only
* reply to server requests.
* A eap_payload is created in "out" if result is NEED_MORE.
*
- * @param this calling object
* @param out eap_payload to send to the client
* @return
* - NEED_MORE, if an other exchange is required
@@ -131,11 +113,10 @@ struct eap_method_t {
status_t (*initiate) (eap_method_t *this, eap_payload_t **out);
/**
- * @brief Process a received EAP message.
+ * Process a received EAP message.
*
* A eap_payload is created in "out" if result is NEED_MORE.
*
- * @param this calling object
* @param in eap_payload response received
* @param out created eap_payload to send
* @return
@@ -147,31 +128,28 @@ struct eap_method_t {
eap_payload_t **out);
/**
- * @brief Get the EAP type implemented in this method.
+ * Get the EAP type implemented in this method.
*
- * @param this calling object
* @param vendor pointer receiving vendor identifier for type, 0 for none
* @return type of the EAP method
*/
eap_type_t (*get_type) (eap_method_t *this, u_int32_t *vendor);
/**
- * @brief Check if this EAP method authenticates the server.
+ * Check if this EAP method authenticates the server.
*
* Some EAP methods provide mutual authentication and
* allow authentication using only EAP, if the peer supports it.
*
- * @param this calling object
* @return TRUE if methods provides mutual authentication
*/
bool (*is_mutual) (eap_method_t *this);
/**
- * @brief Get the MSK established by this EAP method.
+ * Get the MSK established by this EAP method.
*
* Not all EAP methods establish a shared secret.
*
- * @param this calling object
* @param msk chunk receiving internal stored MSK
* @return
* - SUCCESS, or
@@ -180,68 +158,25 @@ struct eap_method_t {
status_t (*get_msk) (eap_method_t *this, chunk_t *msk);
/**
- * @brief Destroys a eap_method_t object.
- *
- * @param this calling object
+ * Destroys a eap_method_t object.
*/
void (*destroy) (eap_method_t *this);
};
/**
- * @brief Creates an EAP method for a specific type and role.
- *
- * @param eap_type EAP type to use
- * @param eap_vendor vendor identifier if a vendor specifc EAP type is used
- * @param role role of the eap_method, server or peer
- * @param server ID of acting server
- * @param peer ID of involved peer (client)
- * @return eap_method_t object
- *
- * @ingroup eap
- */
-eap_method_t *eap_method_create(eap_type_t eap_type, u_int32_t eap_vendor,
- eap_role_t role, identification_t *server,
- identification_t *peer);
-
-/**
- * @brief (Re-)Load all EAP modules in the EAP modules directory.
- *
- * For security reasons, the directory and all it's modules must be owned
- * by root and must not be writeable by someone else.
- *
- * @param dir directory of the EAP modules
- *
- * @ingroup eap
- */
-void eap_method_load(char *directory);
-
-/**
- * @brief Unload all loaded EAP modules
- *
- * @ingroup eap
- */
-void eap_method_unload();
-
-/**
- * @brief Constructor definition for a pluggable EAP module.
+ * Constructor definition for a pluggable EAP method.
*
* Each EAP module must define a constructor function which will return
- * an initialized object with the methods defined in eap_method_t. The
- * constructor must be named eap_create() and it's signature must be equal
- * to that of eap_constructor_t.
- * A module may implement only a single role. If it does not support the role
- * requested, NULL should be returned. Multiple modules are allowed of the
- * same EAP type to support seperate implementations of peer/server.
+ * an initialized object with the methods defined in eap_method_t.
+ * Constructors for server and peers are identical, to support both roles
+ * of a EAP method, a plugin needs register two constructors in the
+ * eap_manager_t.
*
- * @param role role the module will play, peer or server
* @param server ID of the server to use for credential lookup
* @param peer ID of the peer to use for credential lookup
* @return implementation of the eap_method_t interface
- *
- * @ingroup eap
*/
-typedef eap_method_t *(*eap_constructor_t)(eap_role_t role,
- identification_t *server,
+typedef eap_method_t *(*eap_constructor_t)(identification_t *server,
identification_t *peer);
-#endif /* EAP_METHOD_H_ */
+#endif /* EAP_METHOD_H_ @} */
diff --git a/src/charon/sa/authenticators/eap_authenticator.c b/src/charon/sa/authenticators/eap_authenticator.c
index edd75da43..95bb5e57f 100644
--- a/src/charon/sa/authenticators/eap_authenticator.c
+++ b/src/charon/sa/authenticators/eap_authenticator.c
@@ -1,10 +1,3 @@
-/**
- * @file eap_authenticator.c
- *
- * @brief Implementation of eap_authenticator_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_authenticator.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <string.h>
@@ -160,9 +155,9 @@ static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
{
DBG1(DBG_IKE, "requesting %N authentication", eap_type_names, type);
}
- this->method = eap_method_create(type, vendor, this->role,
- this->ike_sa->get_my_id(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa));
+ this->method = charon->eap->create_instance(charon->eap, type, vendor,
+ this->role, this->ike_sa->get_my_id(this->ike_sa),
+ this->ike_sa->get_other_id(this->ike_sa));
if (this->method == NULL)
{
@@ -195,9 +190,11 @@ static status_t process_peer(private_eap_authenticator_t *this,
if (!vendor && type == EAP_IDENTITY)
{
- eap_method_t *method = eap_method_create(type, 0, EAP_PEER,
- this->ike_sa->get_other_id(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa));
+ eap_method_t *method;
+
+ method = charon->eap->create_instance(charon->eap, type, 0, EAP_PEER,
+ this->ike_sa->get_other_id(this->ike_sa),
+ this->ike_sa->get_my_id(this->ike_sa));
if (method == NULL || method->process(method, in, out) != SUCCESS)
{
@@ -227,9 +224,10 @@ static status_t process_peer(private_eap_authenticator_t *this,
DBG1(DBG_IKE, "EAP server requested %N authentication",
eap_type_names, type);
}
- this->method = eap_method_create(type, vendor, EAP_PEER,
- this->ike_sa->get_other_id(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa));
+ this->method = charon->eap->create_instance(charon->eap,
+ type, vendor, EAP_PEER,
+ this->ike_sa->get_other_id(this->ike_sa),
+ this->ike_sa->get_my_id(this->ike_sa));
if (this->method == NULL)
{
DBG1(DBG_IKE, "EAP server requested unsupported "
diff --git a/src/charon/sa/authenticators/eap_authenticator.h b/src/charon/sa/authenticators/eap_authenticator.h
index cf2180ee3..2dad59fbb 100644
--- a/src/charon/sa/authenticators/eap_authenticator.h
+++ b/src/charon/sa/authenticators/eap_authenticator.h
@@ -1,10 +1,3 @@
-/**
- * @file eap_authenticator.h
- *
- * @brief Interface of eap_authenticator_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: eap_authenticator.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup eap_authenticator eap_authenticator
+ * @{ @ingroup authenticators
*/
#ifndef EAP_AUTHENTICATOR_H_
@@ -29,7 +29,7 @@ typedef struct eap_authenticator_t eap_authenticator_t;
#include <encoding/payloads/eap_payload.h>
/**
- * @brief Implementation of the authenticator_t interface using AUTH_EAP.
+ * Implementation of the authenticator_t interface using AUTH_EAP.
*
* Authentication using EAP involves the most complex authenticator. It stays
* alive over multiple ike_auth transactions and handles multiple EAP
@@ -68,11 +68,6 @@ typedef struct eap_authenticator_t eap_authenticator_t;
+--------+ +--------+
@endverbatim
- * @b Constructors:
- * - eap_authenticator_create()
- * - authenticator_create() using auth_method AUTH_EAP
- *
- * @ingroup authenticators
*/
struct eap_authenticator_t {
@@ -82,7 +77,7 @@ struct eap_authenticator_t {
authenticator_t authenticator_interface;
/**
- * @brief Check if the EAP method was/is mutual and secure.
+ * Check if the EAP method was/is mutual and secure.
*
* RFC4306 proposes to authenticate the EAP responder (server) by standard
* IKEv2 methods (RSA, psk). Not all, but some EAP methods
@@ -93,19 +88,17 @@ struct eap_authenticator_t {
* AUTH payload, the client must verify that the server initiated mutual
* EAP authentication before it can trust the server.
*
- * @param this calling object
* @return TRUE, if no AUTH payload required, FALSE otherwise
*/
bool (*is_mutual) (eap_authenticator_t* this);
/**
- * @brief Initiate the EAP exchange.
+ * Initiate the EAP exchange.
*
* The server initiates EAP exchanges, so the client never calls
* this method. If initiate() returns NEED_MORE, the EAP authentication
* process started. In any case, a payload is created in "out".
*
- * @param this calling object
* @param type EAP method to use to authenticate client
* @param vendor EAP vendor identifier, if type is vendor specific, or 0
* @param out created initiaal EAP message to send
@@ -117,7 +110,7 @@ struct eap_authenticator_t {
u_int32_t vendor, eap_payload_t **out);
/**
- * @brief Process an EAP message.
+ * Process an EAP message.
*
* After receiving an EAP message "in", the peer/server processes
* the payload and creates a reply/subsequent request.
@@ -132,7 +125,6 @@ struct eap_authenticator_t {
* If a SUCCESS is returned (on any side), the EAP authentication was
* successful and the AUTH payload can be exchanged.
*
- * @param this calling object
* @param in received EAP message
* @param out created EAP message to send
* @return
@@ -145,13 +137,11 @@ struct eap_authenticator_t {
};
/**
- * @brief Creates an authenticator for AUTH_EAP.
+ * Creates an authenticator for AUTH_EAP.
*
* @param ike_sa associated ike_sa
* @return eap_authenticator_t object
- *
- * @ingroup authenticators
*/
eap_authenticator_t *eap_authenticator_create(ike_sa_t *ike_sa);
-#endif /* EAP_AUTHENTICATOR_H_ */
+#endif /* EAP_AUTHENTICATOR_H_ @} */
diff --git a/src/charon/sa/authenticators/psk_authenticator.c b/src/charon/sa/authenticators/psk_authenticator.c
index 6b76088bb..d003dc2c9 100644
--- a/src/charon/sa/authenticators/psk_authenticator.c
+++ b/src/charon/sa/authenticators/psk_authenticator.c
@@ -1,10 +1,3 @@
-/**
- * @file psk_authenticator.c
- *
- * @brief Implementation of psk_authenticator_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: psk_authenticator.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <string.h>
@@ -26,6 +21,7 @@
#include "psk_authenticator.h"
#include <daemon.h>
+#include <credentials/auth_info.h>
/**
* Key pad for the AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
@@ -105,39 +101,49 @@ chunk_t build_shared_key_signature(chunk_t ike_sa_init, chunk_t nonce,
* Implementation of authenticator_t.verify.
*/
static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
- chunk_t my_nonce, auth_payload_t *auth_payload)
+ chunk_t my_nonce, auth_payload_t *auth_payload)
{
- status_t status;
- chunk_t auth_data, recv_auth_data, shared_key;
+ chunk_t auth_data, recv_auth_data;
identification_t *my_id, *other_id;
+ shared_key_t *shared_key;
+ enumerator_t *enumerator;
+ bool authenticated = FALSE;
+ int keys_found = 0;
my_id = this->ike_sa->get_my_id(this->ike_sa);
other_id = this->ike_sa->get_other_id(this->ike_sa);
- status = charon->credentials->get_shared_key(charon->credentials, my_id,
- other_id, &shared_key);
- if (status != SUCCESS)
+ enumerator = charon->credentials->create_shared_enumerator(
+ charon->credentials, SHARED_IKE, my_id, other_id);
+ while (!authenticated && enumerator->enumerate(enumerator, &shared_key, NULL, NULL))
{
- DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
- return status;
+ keys_found++;
+ auth_data = build_shared_key_signature(ike_sa_init, my_nonce,
+ shared_key->get_key(shared_key), other_id,
+ this->ike_sa->get_skp_verify(this->ike_sa),
+ this->ike_sa->get_prf(this->ike_sa));
+ recv_auth_data = auth_payload->get_data(auth_payload);
+ if (auth_data.len == recv_auth_data.len &&
+ memeq(auth_data.ptr, recv_auth_data.ptr, auth_data.len))
+ {
+ DBG1(DBG_IKE, "authentication of '%D' with %N successful",
+ other_id, auth_method_names, AUTH_PSK);
+ authenticated = TRUE;
+ }
+ chunk_free(&auth_data);
}
+ enumerator->destroy(enumerator);
- auth_data = build_shared_key_signature(ike_sa_init, my_nonce, shared_key,
- other_id, this->ike_sa->get_skp_verify(this->ike_sa),
- this->ike_sa->get_prf(this->ike_sa));
- chunk_free_randomized(&shared_key);
-
- recv_auth_data = auth_payload->get_data(auth_payload);
- if (auth_data.len != recv_auth_data.len ||
- !memeq(auth_data.ptr, recv_auth_data.ptr, auth_data.len))
+ if (!authenticated)
{
- DBG1(DBG_IKE, "PSK MAC verification failed");
- chunk_free(&auth_data);
+ if (keys_found == 0)
+ {
+ DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
+ return NOT_FOUND;
+ }
+ DBG1(DBG_IKE, "tried %d shared key%s for '%D' - '%D', but MAC mismatched",
+ keys_found, keys_found == 1 ? "" : "s", my_id, other_id);
return FAILED;
}
- chunk_free(&auth_data);
-
- DBG1(DBG_IKE, "authentication of '%D' with %N successful",
- other_id, auth_method_names, AUTH_PSK);
return SUCCESS;
}
@@ -147,28 +153,27 @@ static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
static status_t build(private_psk_authenticator_t *this, chunk_t ike_sa_init,
chunk_t other_nonce, auth_payload_t **auth_payload)
{
- chunk_t shared_key;
+ shared_key_t *shared_key;
chunk_t auth_data;
- status_t status;
identification_t *my_id, *other_id;
my_id = this->ike_sa->get_my_id(this->ike_sa);
other_id = this->ike_sa->get_other_id(this->ike_sa);
DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
my_id, auth_method_names, AUTH_PSK);
- status = charon->credentials->get_shared_key(charon->credentials, my_id,
- other_id, &shared_key);
- if (status != SUCCESS)
+ shared_key = charon->credentials->get_shared(charon->credentials, SHARED_IKE,
+ my_id, other_id);
+ if (shared_key == NULL)
{
DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
- return status;
+ return NOT_FOUND;
}
-
- auth_data = build_shared_key_signature(ike_sa_init, other_nonce, shared_key,
- my_id, this->ike_sa->get_skp_build(this->ike_sa),
- this->ike_sa->get_prf(this->ike_sa));
+ auth_data = build_shared_key_signature(ike_sa_init, other_nonce,
+ shared_key->get_key(shared_key), my_id,
+ this->ike_sa->get_skp_build(this->ike_sa),
+ this->ike_sa->get_prf(this->ike_sa));
+ shared_key->destroy(shared_key);
DBG2(DBG_IKE, "successfully created shared key MAC");
- chunk_free_randomized(&shared_key);
*auth_payload = auth_payload_create();
(*auth_payload)->set_auth_method(*auth_payload, AUTH_PSK);
(*auth_payload)->set_data(*auth_payload, auth_data);
diff --git a/src/charon/sa/authenticators/psk_authenticator.h b/src/charon/sa/authenticators/psk_authenticator.h
index c1c5bcaac..c7cb5a23c 100644
--- a/src/charon/sa/authenticators/psk_authenticator.h
+++ b/src/charon/sa/authenticators/psk_authenticator.h
@@ -1,10 +1,3 @@
-/**
- * @file psk_authenticator.h
- *
- * @brief Interface of psk_authenticator_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: psk_authenticator.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup psk_authenticator psk_authenticator
+ * @{ @ingroup authenticators
*/
#ifndef PSK_AUTHENTICATOR_H_
@@ -28,13 +28,7 @@ typedef struct psk_authenticator_t psk_authenticator_t;
#include <sa/authenticators/authenticator.h>
/**
- * @brief Implementation of the authenticator_t interface using AUTH_PSK.
- *
- * @b Constructors:
- * - psk_authenticator_create()
- * - authenticator_create() using auth_method AUTH_PSK
- *
- * @ingroup authenticators
+ * Implementation of the authenticator_t interface using AUTH_PSK.
*/
struct psk_authenticator_t {
@@ -45,13 +39,11 @@ struct psk_authenticator_t {
};
/**
- * @brief Creates an authenticator for AUTH_PSK.
+ * Creates an authenticator for AUTH_PSK.
*
* @param ike_sa associated ike_sa
* @return psk_authenticator_t object
- *
- * @ingroup authenticators
*/
psk_authenticator_t *psk_authenticator_create(ike_sa_t *ike_sa);
-#endif /* PSK_AUTHENTICATOR_H_ */
+#endif /* PSK_AUTHENTICATOR_H_ @} */
diff --git a/src/charon/sa/authenticators/pubkey_authenticator.c b/src/charon/sa/authenticators/pubkey_authenticator.c
new file mode 100644
index 000000000..2c02ca84c
--- /dev/null
+++ b/src/charon/sa/authenticators/pubkey_authenticator.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: pubkey_authenticator.c 4054 2008-06-10 20:31:53Z andreas $
+ */
+
+#include <string.h>
+
+#include "pubkey_authenticator.h"
+
+#include <daemon.h>
+#include <credentials/auth_info.h>
+
+
+typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t;
+
+/**
+ * Private data of an pubkey_authenticator_t object.
+ */
+struct private_pubkey_authenticator_t {
+
+ /**
+ * Public authenticator_t interface.
+ */
+ pubkey_authenticator_t public;
+
+ /**
+ * Assigned IKE_SA
+ */
+ ike_sa_t *ike_sa;
+};
+
+/**
+ * Function implemented in psk_authenticator.c
+ */
+extern chunk_t build_tbs_octets(chunk_t ike_sa_init, chunk_t nonce,
+ identification_t *id, prf_t *prf);
+
+/**
+ * Implementation of authenticator_t.verify.
+ */
+static status_t verify(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
+ chunk_t my_nonce, auth_payload_t *auth_payload)
+{
+ public_key_t *public;
+ auth_method_t auth_method;
+ chunk_t auth_data, octets;
+ identification_t *other_id;
+ prf_t *prf;
+ auth_info_t *auth, *current_auth;
+ enumerator_t *enumerator;
+ key_type_t key_type = KEY_ECDSA;
+ signature_scheme_t scheme;
+ status_t status = FAILED;
+
+ other_id = this->ike_sa->get_other_id(this->ike_sa);
+ auth_method = auth_payload->get_auth_method(auth_payload);
+ switch (auth_method)
+ {
+ case AUTH_RSA:
+ /* We are currently fixed to SHA1 hashes.
+ * TODO: allow other hash algorithms and note it in "auth" */
+ key_type = KEY_RSA;
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ break;
+ case AUTH_ECDSA_256:
+ scheme = SIGN_ECDSA_256;
+ break;
+ case AUTH_ECDSA_384:
+ scheme = SIGN_ECDSA_384;
+ break;
+ case AUTH_ECDSA_521:
+ scheme = SIGN_ECDSA_521;
+ break;
+ default:
+ return INVALID_ARG;
+ }
+ auth_data = auth_payload->get_data(auth_payload);
+ prf = this->ike_sa->get_prf(this->ike_sa);
+ prf->set_key(prf, this->ike_sa->get_skp_verify(this->ike_sa));
+ octets = build_tbs_octets(ike_sa_init, my_nonce, other_id, prf);
+
+ auth = this->ike_sa->get_other_auth(this->ike_sa);
+ enumerator = charon->credentials->create_public_enumerator(
+ charon->credentials, key_type, other_id, auth);
+ while (enumerator->enumerate(enumerator, &public, &current_auth))
+ {
+ if (public->verify(public, scheme, octets, auth_data))
+ {
+ DBG1(DBG_IKE, "authentication of '%D' with %N successful",
+ other_id, auth_method_names, auth_method);
+ status = SUCCESS;
+ auth->merge(auth, current_auth);
+ break;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "signature validation failed, looking for another key");
+ }
+ }
+ enumerator->destroy(enumerator);
+ chunk_free(&octets);
+ return status;
+}
+
+/**
+ * Implementation of authenticator_t.build.
+ */
+static status_t build(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
+ chunk_t other_nonce, auth_payload_t **auth_payload)
+{
+ chunk_t octets, auth_data;
+ status_t status = FAILED;
+ private_key_t *private;
+ identification_t *my_id;
+ prf_t *prf;
+ auth_info_t *auth;
+ auth_method_t auth_method;
+ signature_scheme_t scheme;
+
+ my_id = this->ike_sa->get_my_id(this->ike_sa);
+ auth = this->ike_sa->get_my_auth(this->ike_sa);
+ private = charon->credentials->get_private(charon->credentials, KEY_ANY,
+ my_id, auth);
+ if (private == NULL)
+ {
+ DBG1(DBG_IKE, "no private key found for '%D'", my_id);
+ return NOT_FOUND;
+ }
+
+ switch (private->get_type(private))
+ {
+ case KEY_RSA:
+ /* we currently use always SHA1 for signatures,
+ * TODO: support other hashes depending on configuration/auth */
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ auth_method = AUTH_RSA;
+ break;
+ case KEY_ECDSA:
+ /* we try to deduct the signature scheme from the keysize */
+ switch (private->get_keysize(private))
+ {
+ case 32:
+ scheme = SIGN_ECDSA_256;
+ auth_method = AUTH_ECDSA_256;
+ break;
+ case 48:
+ scheme = SIGN_ECDSA_384;
+ auth_method = AUTH_ECDSA_384;
+ break;
+ case 66:
+ scheme = SIGN_ECDSA_521;
+ auth_method = AUTH_ECDSA_521;
+ break;
+ default:
+ DBG1(DBG_IKE, "%d bit ECDSA private key size not supported",
+ private->get_keysize(private));
+ return status;
+ }
+ break;
+ default:
+ DBG1(DBG_IKE, "private key of type %N not supported",
+ key_type_names, private->get_type(private));
+ return status;
+ }
+ prf = this->ike_sa->get_prf(this->ike_sa);
+ prf->set_key(prf, this->ike_sa->get_skp_build(this->ike_sa));
+ octets = build_tbs_octets(ike_sa_init, other_nonce, my_id, prf);
+
+ if (private->sign(private, scheme, octets, &auth_data))
+ {
+ auth_payload_t *payload = auth_payload_create();
+ payload->set_auth_method(payload, auth_method);
+ payload->set_data(payload, auth_data);
+ *auth_payload = payload;
+ chunk_free(&auth_data);
+ status = SUCCESS;
+ }
+ DBG1(DBG_IKE, "authentication of '%D' (myself) with %N %s", my_id,
+ auth_method_names, auth_method,
+ (status == SUCCESS)? "successful":"failed");
+ chunk_free(&octets);
+ private->destroy(private);
+
+ return status;
+}
+
+/**
+ * Implementation of authenticator_t.destroy.
+ */
+static void destroy(private_pubkey_authenticator_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+pubkey_authenticator_t *pubkey_authenticator_create(ike_sa_t *ike_sa)
+{
+ private_pubkey_authenticator_t *this = malloc_thing(private_pubkey_authenticator_t);
+
+ /* public functions */
+ this->public.authenticator_interface.verify = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t*))verify;
+ this->public.authenticator_interface.build = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t**))build;
+ this->public.authenticator_interface.destroy = (void(*)(authenticator_t*))destroy;
+
+ /* private data */
+ this->ike_sa = ike_sa;
+
+ return &this->public;
+}
diff --git a/src/charon/sa/authenticators/rsa_authenticator.h b/src/charon/sa/authenticators/pubkey_authenticator.h
index cc5cc0150..038d8b1d2 100644
--- a/src/charon/sa/authenticators/rsa_authenticator.h
+++ b/src/charon/sa/authenticators/pubkey_authenticator.h
@@ -1,11 +1,5 @@
-/**
- * @file rsa_authenticator.h
- *
- * @brief Interface of rsa_authenticator_t.
- *
- */
-
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -18,25 +12,26 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: pubkey_authenticator.h 4051 2008-06-10 09:08:27Z tobias $
*/
-#ifndef RSA_AUTHENTICATOR_H_
-#define RSA_AUTHENTICATOR_H_
+/**
+ * @defgroup pubkey_authenticator pubkey_authenticator
+ * @{ @ingroup authenticators
+ */
+
+#ifndef PUBKEY_AUTHENTICATOR_H_
+#define PUBKEY_AUTHENTICATOR_H_
-typedef struct rsa_authenticator_t rsa_authenticator_t;
+typedef struct pubkey_authenticator_t pubkey_authenticator_t;
#include <sa/authenticators/authenticator.h>
/**
- * @brief Implementation of the authenticator_t interface using AUTH_RSA.
- *
- * @b Constructors:
- * - rsa_authenticator_create()
- * - authenticator_create() using auth_method AUTH_RSA
- *
- * @ingroup authenticators
+ * Implementation of the authenticator_t interface using AUTH_PUBKEY.
*/
-struct rsa_authenticator_t {
+struct pubkey_authenticator_t {
/**
* Implemented authenticator_t interface.
@@ -45,13 +40,11 @@ struct rsa_authenticator_t {
};
/**
- * @brief Creates an authenticator for AUTH_RSA.
+ * Creates an authenticator for AUTH_PUBKEY.
*
* @param ike_sa associated ike_sa
- * @return rsa_authenticator_t object
- *
- * @ingroup authenticators
+ * @return pubkey_authenticator_t object
*/
-rsa_authenticator_t *rsa_authenticator_create(ike_sa_t *ike_sa);
+pubkey_authenticator_t *pubkey_authenticator_create(ike_sa_t *ike_sa);
-#endif /* RSA_AUTHENTICATOR_H_ */
+#endif /* PUBKEY_AUTHENTICATOR_H_ @} */
diff --git a/src/charon/sa/authenticators/rsa_authenticator.c b/src/charon/sa/authenticators/rsa_authenticator.c
deleted file mode 100644
index ba0fad1e3..000000000
--- a/src/charon/sa/authenticators/rsa_authenticator.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * @file rsa_authenticator.c
- *
- * @brief Implementation of rsa_authenticator_t.
- *
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <string.h>
-
-#include "rsa_authenticator.h"
-
-#include <daemon.h>
-
-
-typedef struct private_rsa_authenticator_t private_rsa_authenticator_t;
-
-/**
- * Private data of an rsa_authenticator_t object.
- */
-struct private_rsa_authenticator_t {
-
- /**
- * Public authenticator_t interface.
- */
- rsa_authenticator_t public;
-
- /**
- * Assigned IKE_SA
- */
- ike_sa_t *ike_sa;
-};
-
-/**
- * Function implemented in psk_authenticator.c
- */
-extern chunk_t build_tbs_octets(chunk_t ike_sa_init, chunk_t nonce,
- identification_t *id, prf_t *prf);
-
-/**
- * Implementation of authenticator_t.verify.
- */
-static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
- chunk_t my_nonce, auth_payload_t *auth_payload)
-{
- status_t status;
- chunk_t auth_data, octets;
- identification_t *other_id;
- ca_info_t *issuer;
- prf_t *prf;
-
- other_id = this->ike_sa->get_other_id(this->ike_sa);
-
- if (auth_payload->get_auth_method(auth_payload) != AUTH_RSA)
- {
- return INVALID_ARG;
- }
- auth_data = auth_payload->get_data(auth_payload);
- prf = this->ike_sa->get_prf(this->ike_sa);
- prf->set_key(prf, this->ike_sa->get_skp_verify(this->ike_sa));
- octets = build_tbs_octets(ike_sa_init, my_nonce, other_id, prf);
- status = charon->credentials->verify_signature(charon->credentials,
- octets, auth_data, other_id, &issuer);
- chunk_free(&octets);
-
- if (status == SUCCESS)
- {
- this->ike_sa->set_other_ca(this->ike_sa, issuer);
- DBG1(DBG_IKE, "authentication of '%D' with %N successful",
- other_id, auth_method_names, AUTH_RSA);
- }
- return status;
-}
-
-/**
- * Implementation of authenticator_t.build.
- */
-static status_t build(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
- chunk_t other_nonce, auth_payload_t **auth_payload)
-{
- chunk_t octets, auth_data;
- status_t status;
- rsa_public_key_t *my_pubkey;
- identification_t *my_id;
- prf_t *prf;
-
- my_id = this->ike_sa->get_my_id(this->ike_sa);
- DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
- my_id, auth_method_names, AUTH_RSA);
- DBG2(DBG_IKE, "looking for RSA public key belonging to '%D'...", my_id);
-
- my_pubkey = charon->credentials->get_rsa_public_key(charon->credentials, my_id);
- if (my_pubkey == NULL)
- {
- DBG1(DBG_IKE, "no RSA public key found for '%D'", my_id);
- return NOT_FOUND;
- }
- DBG2(DBG_IKE, " matching RSA public key found");
-
- prf = this->ike_sa->get_prf(this->ike_sa);
- prf->set_key(prf, this->ike_sa->get_skp_build(this->ike_sa));
- octets = build_tbs_octets(ike_sa_init, other_nonce, my_id, prf);
- status = charon->credentials->rsa_signature(charon->credentials,
- my_pubkey, HASH_SHA1, octets, &auth_data);
- chunk_free(&octets);
-
- if (status != SUCCESS)
- {
- DBG1(DBG_IKE, "building RSA signature with SHA-1 hash failed");
- return status;
- }
- DBG2(DBG_IKE, "successfully signed with RSA private key");
-
- *auth_payload = auth_payload_create();
- (*auth_payload)->set_auth_method(*auth_payload, AUTH_RSA);
- (*auth_payload)->set_data(*auth_payload, auth_data);
- chunk_free(&auth_data);
- return SUCCESS;
-}
-
-/**
- * Implementation of authenticator_t.destroy.
- */
-static void destroy(private_rsa_authenticator_t *this)
-{
- free(this);
-}
-
-/*
- * Described in header.
- */
-rsa_authenticator_t *rsa_authenticator_create(ike_sa_t *ike_sa)
-{
- private_rsa_authenticator_t *this = malloc_thing(private_rsa_authenticator_t);
-
- /* public functions */
- this->public.authenticator_interface.verify = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t*))verify;
- this->public.authenticator_interface.build = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t**))build;
- this->public.authenticator_interface.destroy = (void(*)(authenticator_t*))destroy;
-
- /* private data */
- this->ike_sa = ike_sa;
-
- return &this->public;
-}
diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c
index b6c71a8b5..2a6b6f67c 100644
--- a/src/charon/sa/child_sa.c
+++ b/src/charon/sa/child_sa.c
@@ -1,13 +1,7 @@
-/**
- * @file child_sa.c
- *
- * @brief Implementation of child_sa_t.
- *
- */
-
/*
+ * Copyright (C) 2006-2008 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -20,6 +14,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: child_sa.c 3920 2008-05-08 16:19:11Z tobias $
*/
#define _GNU_SOURCE
@@ -75,6 +71,8 @@ struct private_child_sa_t {
identification_t *id;
/** actual used SPI, 0 if unused */
u_int32_t spi;
+ /** Compression Parameter Index (CPI) used, 0 if unused */
+ u_int16_t cpi;
} me, other;
/**
@@ -115,12 +113,22 @@ struct private_child_sa_t {
/**
* encryption algorithm used for this SA
*/
- algorithm_t encryption;
+ u_int16_t enc_alg;
+
+ /**
+ * key size of enc_alg
+ */
+ u_int16_t enc_size;
/**
* integrity protection algorithm used for this SA
*/
- algorithm_t integrity;
+ u_int16_t int_alg;
+
+ /**
+ * key size of int_alg
+ */
+ u_int16_t int_size;
/**
* time, on which SA was installed
@@ -143,6 +151,16 @@ struct private_child_sa_t {
bool encap;
/**
+ * Specifies the IPComp transform used (IPCOMP_NONE if disabled)
+ */
+ ipcomp_transform_t ipcomp;
+
+ /**
+ * TRUE if we allocated (or tried to allocate) a CPI
+ */
+ bool cpi_allocated;
+
+ /**
* mode this SA uses, tunnel/transport
*/
mode_t mode;
@@ -251,10 +269,10 @@ static void get_stats(private_child_sa_t *this, mode_t *mode,
iterator->destroy(iterator);
*mode = this->mode;
- *encr_algo = this->encryption.algorithm;
- *encr_len = this->encryption.key_size;
- *int_algo = this->integrity.algorithm;
- *int_len = this->integrity.key_size;
+ *encr_algo = this->enc_alg;
+ *encr_len = this->enc_size;
+ *int_algo = this->int_alg;
+ *int_len = this->int_size;
*rekey = this->rekey_time;
*use_in = in;
*use_out = out;
@@ -498,10 +516,7 @@ static status_t alloc(private_child_sa_t *this, linked_list_t *proposals)
static status_t install(private_child_sa_t *this, proposal_t *proposal,
mode_t mode, prf_plus_t *prf_plus, bool mine)
{
- u_int32_t spi, soft, hard;;
- algorithm_t *enc_algo, *int_algo;
- algorithm_t enc_algo_none = {ENCR_UNDEFINED, 0};
- algorithm_t int_algo_none = {AUTH_UNDEFINED, 0};
+ u_int32_t spi, soft, hard;
host_t *src;
host_t *dst;
status_t status;
@@ -549,43 +564,43 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal,
protocol_id_names, this->protocol);
/* select encryption algo */
- if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &enc_algo))
+ if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
+ &this->enc_alg, &this->enc_size))
{
- DBG2(DBG_CHD, " using %N for encryption",
- encryption_algorithm_names, enc_algo->algorithm);
- }
- else
- {
- enc_algo = &enc_algo_none;
+ DBG2(DBG_CHD, " using %N for encryption",
+ encryption_algorithm_names, this->enc_alg);
}
/* select integrity algo */
- if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &int_algo))
+ if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
+ &this->int_alg, &this->int_size))
{
DBG2(DBG_CHD, " using %N for integrity",
- integrity_algorithm_names, int_algo->algorithm);
- }
- else
- {
- int_algo = &int_algo_none;
+ integrity_algorithm_names, this->int_alg);
}
-
soft = this->config->get_lifetime(this->config, TRUE);
hard = this->config->get_lifetime(this->config, FALSE);
/* send SA down to the kernel */
DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
- status = charon->kernel_interface->add_sa(charon->kernel_interface,
- src, dst, spi, this->protocol,
- this->reqid, mine ? soft : 0,
- hard, enc_algo, int_algo,
- prf_plus, mode, this->encap, mine);
- this->encryption = *enc_algo;
- this->integrity = *int_algo;
+ if (this->ipcomp != IPCOMP_NONE)
+ {
+ /* we install an additional IPComp SA */
+ u_int32_t cpi = htonl(ntohs(mine ? this->me.cpi : this->other.cpi));
+ status = charon->kernel_interface->add_sa(charon->kernel_interface,
+ src, dst, cpi, IPPROTO_COMP, this->reqid, 0, 0,
+ ENCR_UNDEFINED, 0, AUTH_UNDEFINED, 0, NULL, mode,
+ this->ipcomp, FALSE, mine);
+ }
+
+ status = charon->kernel_interface->add_sa(charon->kernel_interface,
+ src, dst, spi, this->protocol, this->reqid, mine ? soft : 0, hard,
+ this->enc_alg, this->enc_size, this->int_alg, this->int_size,
+ prf_plus, mode, IPCOMP_NONE, this->encap, mine);
+
this->install_time = time(NULL);
this->rekey_time = this->install_time + soft;
-
return status;
}
@@ -686,15 +701,15 @@ static status_t add_policies(private_child_sa_t *this,
/* install 3 policies: out, in and forward */
status = charon->kernel_interface->add_policy(charon->kernel_interface,
this->me.addr, this->other.addr, my_ts, other_ts, POLICY_OUT,
- this->protocol, this->reqid, high_prio, mode);
+ this->protocol, this->reqid, high_prio, mode, this->ipcomp);
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
this->other.addr, this->me.addr, other_ts, my_ts, POLICY_IN,
- this->protocol, this->reqid, high_prio, mode);
+ this->protocol, this->reqid, high_prio, mode, this->ipcomp);
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
this->other.addr, this->me.addr, other_ts, my_ts, POLICY_FWD,
- this->protocol, this->reqid, high_prio, mode);
+ this->protocol, this->reqid, high_prio, mode, this->ipcomp);
if (status != SUCCESS)
{
@@ -795,10 +810,20 @@ static status_t update_hosts(private_child_sa_t *this,
this->encap = encap;
- /* update our (initator) SAs */
+ if (this->ipcomp != IPCOMP_NONE)
+ {
+ /* update our (initator) IPComp SA */
+ charon->kernel_interface->update_sa(charon->kernel_interface, htonl(ntohs(this->me.cpi)),
+ IPPROTO_COMP, this->other.addr, this->me.addr, other, me, FALSE);
+ /* update his (responder) IPComp SA */
+ charon->kernel_interface->update_sa(charon->kernel_interface, htonl(ntohs(this->other.cpi)),
+ IPPROTO_COMP, this->me.addr, this->other.addr, me, other, FALSE);
+ }
+
+ /* update our (initator) SA */
charon->kernel_interface->update_sa(charon->kernel_interface, this->me.spi,
this->protocol, this->other.addr, this->me.addr, other, me, encap);
- /* update his (responder) SAs */
+ /* update his (responder) SA */
charon->kernel_interface->update_sa(charon->kernel_interface, this->other.spi,
this->protocol, this->me.addr, this->other.addr, me, other, encap);
@@ -846,13 +871,13 @@ static status_t update_hosts(private_child_sa_t *this,
/* reinstall updated policies */
charon->kernel_interface->add_policy(charon->kernel_interface,
me, other, policy->my_ts, policy->other_ts, POLICY_OUT,
- this->protocol, this->reqid, TRUE, this->mode);
+ this->protocol, this->reqid, TRUE, this->mode, this->ipcomp);
charon->kernel_interface->add_policy(charon->kernel_interface,
other, me, policy->other_ts, policy->my_ts, POLICY_IN,
- this->protocol, this->reqid, TRUE, this->mode);
+ this->protocol, this->reqid, TRUE, this->mode, this->ipcomp);
charon->kernel_interface->add_policy(charon->kernel_interface,
other, me, policy->other_ts, policy->my_ts, POLICY_FWD,
- this->protocol, this->reqid, TRUE, this->mode);
+ this->protocol, this->reqid, TRUE, this->mode, this->ipcomp);
}
iterator->destroy(iterator);
}
@@ -884,6 +909,30 @@ static void set_virtual_ip(private_child_sa_t *this, host_t *ip)
}
/**
+ * Implementation of child_sa_t.activate_ipcomp.
+ */
+static void activate_ipcomp(private_child_sa_t *this, ipcomp_transform_t ipcomp,
+ u_int16_t other_cpi)
+{
+ this->ipcomp = ipcomp;
+ this->other.cpi = other_cpi;
+}
+
+/**
+ * Implementation of child_sa_t.get_my_cpi.
+ */
+static u_int16_t get_my_cpi(private_child_sa_t *this)
+{
+ if (!this->cpi_allocated)
+ {
+ charon->kernel_interface->get_cpi(charon->kernel_interface,
+ this->other.addr, this->me.addr, this->reqid, &this->me.cpi);
+ this->cpi_allocated = TRUE;
+ }
+ return this->me.cpi;
+}
+
+/**
* Implementation of child_sa_t.destroy.
*/
static void destroy(private_child_sa_t *this)
@@ -916,6 +965,16 @@ static void destroy(private_child_sa_t *this)
charon->kernel_interface->del_sa(charon->kernel_interface,
this->other.addr, this->other.spi, this->protocol);
}
+ if (this->me.cpi)
+ {
+ charon->kernel_interface->del_sa(charon->kernel_interface,
+ this->other.addr, htonl(ntohs(this->me.cpi)), IPPROTO_COMP);
+ }
+ if (this->other.cpi)
+ {
+ charon->kernel_interface->del_sa(charon->kernel_interface,
+ this->other.addr, htonl(ntohs(this->other.cpi)), IPPROTO_COMP);
+ }
/* delete all policies in the kernel */
while (this->policies->remove_last(this->policies, (void**)&policy) == SUCCESS)
@@ -976,6 +1035,8 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state;
this->public.get_state = (child_sa_state_t(*)(child_sa_t*))get_state;
this->public.get_config = (child_cfg_t*(*)(child_sa_t*))get_config;
+ this->public.activate_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t,u_int16_t))activate_ipcomp;
+ this->public.get_my_cpi = (u_int16_t(*)(child_sa_t*))get_my_cpi;
this->public.set_virtual_ip = (void(*)(child_sa_t*,host_t*))set_virtual_ip;
this->public.destroy = (void(*)(child_sa_t*))destroy;
@@ -985,17 +1046,21 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->me.id = my_id->clone(my_id);
this->other.id = other_id->clone(other_id);
this->me.spi = 0;
+ this->me.cpi = 0;
this->other.spi = 0;
+ this->other.cpi = 0;
this->alloc_ah_spi = 0;
this->alloc_esp_spi = 0;
this->encap = encap;
+ this->cpi_allocated = FALSE;
+ this->ipcomp = IPCOMP_NONE;
this->state = CHILD_CREATED;
/* reuse old reqid if we are rekeying an existing CHILD_SA */
this->reqid = rekey ? rekey : ++reqid;
- this->encryption.algorithm = ENCR_UNDEFINED;
- this->encryption.key_size = 0;
- this->integrity.algorithm = AUTH_UNDEFINED;
- this->encryption.key_size = 0;
+ this->enc_alg = ENCR_UNDEFINED;
+ this->enc_size = 0;
+ this->int_alg = AUTH_UNDEFINED;
+ this->int_size = 0;
this->policies = linked_list_create();
this->my_ts = linked_list_create();
this->other_ts = linked_list_create();
diff --git a/src/charon/sa/child_sa.h b/src/charon/sa/child_sa.h
index b801dd012..5bd66acad 100644
--- a/src/charon/sa/child_sa.h
+++ b/src/charon/sa/child_sa.h
@@ -1,13 +1,7 @@
-/**
- * @file child_sa.h
- *
- * @brief Interface of child_sa_t.
- *
- */
-
/*
+ * Copyright (C) 2006-2008 Tobias Brunner
* Copyright (C) 2006-2007 Martin Willi
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006 Daniel Roethlisberger
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -19,8 +13,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: child_sa.h 3920 2008-05-08 16:19:11Z tobias $
*/
+/**
+ * @defgroup child_sa child_sa
+ * @{ @ingroup sa
+ */
#ifndef CHILD_SA_H_
#define CHILD_SA_H_
@@ -35,7 +35,7 @@ typedef struct child_sa_t child_sa_t;
#include <config/child_cfg.h>
/**
- * @brief States of a CHILD_SA
+ * States of a CHILD_SA
*/
enum child_sa_state_t {
@@ -71,7 +71,7 @@ enum child_sa_state_t {
extern enum_name_t *child_sa_state_names;
/**
- * @brief Represents an IPsec SAs between two hosts.
+ * Represents an IPsec SAs between two hosts.
*
* A child_sa_t contains two SAs. SAs for both
* directions are managed in one child_sa_t object. Both
@@ -86,57 +86,47 @@ extern enum_name_t *child_sa_state_names;
* - A calls child_sa_t.update to update the already allocated SPIs with the chosen proposal
*
* Once SAs are set up, policies can be added using add_policies.
- *
- *
- * @b Constructors:
- * - child_sa_create()
- *
- * @ingroup sa
*/
struct child_sa_t {
/**
- * @brief Get the name of the config this CHILD_SA uses.
+ * Get the name of the config this CHILD_SA uses.
*
- * @param this calling object
- * @return name
+ * @return name
*/
char* (*get_name) (child_sa_t *this);
/**
- * @brief Get the reqid of the CHILD SA.
+ * Get the reqid of the CHILD SA.
*
* Every CHILD_SA has a reqid. The kernel uses this ID to
* identify it.
*
- * @param this calling object
* @return reqid of the CHILD SA
*/
u_int32_t (*get_reqid)(child_sa_t *this);
/**
- * @brief Get the SPI of this CHILD_SA.
+ * Get the SPI of this CHILD_SA.
*
* Set the boolean parameter inbound to TRUE to
* get the SPI for which we receive packets, use
* FALSE to get those we use for sending packets.
*
- * @param this calling object
* @param inbound TRUE to get inbound SPI, FALSE for outbound.
* @return spi of the CHILD SA
*/
u_int32_t (*get_spi) (child_sa_t *this, bool inbound);
/**
- * @brief Get the protocol which this CHILD_SA uses to protect traffic.
+ * Get the protocol which this CHILD_SA uses to protect traffic.
*
- * @param this calling object
* @return AH | ESP
*/
protocol_id_t (*get_protocol) (child_sa_t *this);
/**
- * @brief Get info and statistics about this CHILD_SA.
+ * Get info and statistics about this CHILD_SA.
*
* @param mode mode this IKE_SA uses
* @param encr_algo encryption algorithm used by this CHILD_SA.
@@ -155,7 +145,7 @@ struct child_sa_t {
u_int32_t *use_fwd);
/**
- * @brief Allocate SPIs for given proposals.
+ * Allocate SPIs for given proposals.
*
* Since the kernel manages SPIs for us, we need
* to allocate them. If a proposal contains more
@@ -163,15 +153,13 @@ struct child_sa_t {
* allocated. SPIs are stored internally and written
* back to the proposal.
*
- * @param this calling object
* @param proposals list of proposals for which SPIs are allocated
*/
status_t (*alloc)(child_sa_t *this, linked_list_t* proposals);
/**
- * @brief Install the kernel SAs for a proposal, without previous SPI allocation.
+ * Install the kernel SAs for a proposal, without previous SPI allocation.
*
- * @param this calling object
* @param proposal proposal for which SPIs are allocated
* @param mode mode for the CHILD_SA
* @param prf_plus key material to use for key derivation
@@ -181,11 +169,10 @@ struct child_sa_t {
prf_plus_t *prf_plus);
/**
- * @brief Install the kernel SAs for a proposal, after SPIs have been allocated.
+ * Install the kernel SAs for a proposal, after SPIs have been allocated.
*
* Updates an SA, for which SPIs are already allocated via alloc().
*
- * @param this calling object
* @param proposal proposal for which SPIs are allocated
* @param mode mode for the CHILD_SA
* @param prf_plus key material to use for key derivation
@@ -195,11 +182,10 @@ struct child_sa_t {
prf_plus_t *prf_plus);
/**
- * @brief Update the hosts in the kernel SAs and policies.
+ * Update the hosts in the kernel SAs and policies.
*
* The CHILD must be INSTALLED to do this update.
*
- * @param this calling object
* @param me the new local host
* @param other the new remote host
* @param TRUE to use UDP encapsulation for NAT traversal
@@ -209,12 +195,11 @@ struct child_sa_t {
bool encap);
/**
- * @brief Install the policies using some traffic selectors.
+ * Install the policies using some traffic selectors.
*
* Supplied lists of traffic_selector_t's specify the policies
* to use for this child sa.
*
- * @param this calling object
* @param my_ts traffic selectors for local site
* @param other_ts traffic selectors for remote site
* @param mode mode for the SA: tunnel/transport
@@ -224,18 +209,16 @@ struct child_sa_t {
linked_list_t *other_ts_list, mode_t mode);
/**
- * @brief Get the traffic selectors of added policies of local host.
+ * Get the traffic selectors of added policies of local host.
*
- * @param this calling object
* @param local TRUE for own traffic selectors, FALSE for remote
* @return list of traffic selectors
*/
linked_list_t* (*get_traffic_selectors) (child_sa_t *this, bool local);
/**
- * @brief Get the time of this child_sa_t's last use (i.e. last use of any of its policies)
+ * Get the time of this child_sa_t's last use (i.e. last use of any of its policies)
*
- * @param this calling object
* @param inbound query for in- or outbound usage
* @param use_time the time
* @return SUCCESS or FAILED
@@ -243,48 +226,58 @@ struct child_sa_t {
status_t (*get_use_time) (child_sa_t *this, bool inbound, time_t *use_time);
/**
- * @brief Get the state of the CHILD_SA.
- *
- * @param this calling object
+ * Get the state of the CHILD_SA.
*/
child_sa_state_t (*get_state) (child_sa_t *this);
/**
- * @brief Set the state of the CHILD_SA.
+ * Set the state of the CHILD_SA.
*
- * @param this calling object
+ * @param state state to set on CHILD_SA
*/
void (*set_state) (child_sa_t *this, child_sa_state_t state);
/**
- * @brief Get the config used to set up this child sa.
+ * Get the config used to set up this child sa.
*
- * @param this calling object
* @return child_cfg
*/
child_cfg_t* (*get_config) (child_sa_t *this);
/**
- * @brief Set the virtual IP used received from IRAS.
+ * Set the virtual IP used received from IRAS.
*
* To allow proper setup of firewall rules, the virtual IP is required
* for filtering.
*
- * @param this calling object
* @param ip own virtual IP
*/
void (*set_virtual_ip) (child_sa_t *this, host_t *ip);
/**
- * @brief Destroys a child_sa.
- *
- * @param this calling object
+ * Activate IPComp by setting the transform ID and CPI values.
+ *
+ * @param ipcomp the IPComp transform to use
+ * @param other_cpi other Compression Parameter Index
+ */
+ void (*activate_ipcomp) (child_sa_t *this, ipcomp_transform_t ipcomp,
+ u_int16_t other_cpi);
+
+ /**
+ * Returns the Compression Parameter Index (CPI) allocated from the kernel.
+ *
+ * @return allocated CPI
+ */
+ u_int16_t (*get_my_cpi) (child_sa_t *this);
+
+ /**
+ * Destroys a child_sa.
*/
void (*destroy) (child_sa_t *this);
};
/**
- * @brief Constructor to create a new child_sa_t.
+ * Constructor to create a new child_sa_t.
*
* @param me own address
* @param other remote address
@@ -294,11 +287,9 @@ struct child_sa_t {
* @param reqid reqid of old CHILD_SA when rekeying, 0 otherwise
* @param encap TRUE to enable UDP encapsulation (NAT traversal)
* @return child_sa_t object
- *
- * @ingroup sa
*/
child_sa_t * child_sa_create(host_t *me, host_t *other,
identification_t *my_id, identification_t* other_id,
child_cfg_t *config, u_int32_t reqid, bool encap);
-#endif /*CHILD_SA_H_*/
+#endif /*CHILD_SA_H_ @} */
diff --git a/src/charon/sa/connect_manager.c b/src/charon/sa/connect_manager.c
index 06755fa9c..19ceea666 100644
--- a/src/charon/sa/connect_manager.c
+++ b/src/charon/sa/connect_manager.c
@@ -1,12 +1,5 @@
-/**
- * @file connect_manager.c
- *
- * @brief Implementation of connect_manager_t.
- *
- */
-
/*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: connect_manager.c 3792 2008-04-10 12:51:04Z tobias $
*/
#include "connect_manager.h"
@@ -34,13 +29,20 @@
#include <encoding/payloads/endpoint_notify.h>
/* base timeout
- * the sending interval is P2P_INTERVAL * active checklists (N)
- * retransmission timeout is P2P_INTERVAL * N * checks in waiting state (NW) */
-#define P2P_INTERVAL 20 /* ms */
-/* min retransmission timeout (RTO is P2P_INTERVAL * N * checks in waiting state) */
-#define P2P_RTO_MIN 100 /* ms */
-/* max number of retransmissions (+ the initial check) */
-#define P2P_MAX_RETRANS 2
+ * the check interval is ME_INTERVAL */
+#define ME_INTERVAL 25 /* ms */
+/* retransmission timeout is first ME_INTERVAL for ME_BOOST retransmissions
+ * then gets reduced to ME_INTERVAL * ME_RETRANS_BASE ^ (sent retransmissions - ME_BOOST). */
+/* number of initial retransmissions sent in short interval */
+#define ME_BOOST 2
+/* base for retransmissions */
+#define ME_RETRANS_BASE 1.8
+/* max number of retransmissions */
+#define ME_MAX_RETRANS 13
+
+/* time to wait before the initiator finishes the connectivity checks after
+ * the first check has succeeded */
+#define ME_WAIT_TO_FINISH 1000 /* ms */
typedef struct private_connect_manager_t private_connect_manager_t;
@@ -70,7 +72,7 @@ struct private_connect_manager_t {
linked_list_t *initiated;
/**
- * Linked list with checklists (hash table with session ID as key would be better).
+ * Linked list with checklists (hash table with connect ID as key would be better).
*/
linked_list_t *checklists;
};
@@ -180,8 +182,8 @@ struct check_list_t {
linked_list_t *endpoints;
} responder;
- /** session id */
- chunk_t session_id;
+ /** connect id */
+ chunk_t connect_id;
/** list of endpoint pairs */
linked_list_t *pairs;
@@ -195,6 +197,12 @@ struct check_list_t {
/** TRUE if this is the initiator */
bool is_initiator;
+ /** TRUE if the initiator is finishing the checks */
+ bool is_finishing;
+
+ /** the current sender job */
+ job_t *sender;
+
};
/**
@@ -205,7 +213,7 @@ static void check_list_destroy(check_list_t *this)
DESTROY_IF(this->initiator.id);
DESTROY_IF(this->responder.id);
- chunk_free(&this->session_id);
+ chunk_free(&this->connect_id);
chunk_free(&this->initiator.key);
chunk_free(&this->responder.key);
@@ -223,12 +231,12 @@ static void check_list_destroy(check_list_t *this)
* Creates a new checklist
*/
static check_list_t *check_list_create(identification_t *initiator, identification_t *responder,
- chunk_t session_id, chunk_t initiator_key, linked_list_t *initiator_endpoints,
+ chunk_t connect_id, chunk_t initiator_key, linked_list_t *initiator_endpoints,
bool is_initiator)
{
check_list_t *this = malloc_thing(check_list_t);
- this->session_id = chunk_clone(session_id);
+ this->connect_id = chunk_clone(connect_id);
this->initiator.id = initiator->clone(initiator);
this->initiator.key = chunk_clone(initiator_key);
@@ -242,43 +250,7 @@ static check_list_t *check_list_create(identification_t *initiator, identificati
this->triggered = linked_list_create();
this->state = CHECK_NONE;
this->is_initiator = is_initiator;
-
- return this;
-}
-
-
-typedef struct waiting_sa_t waiting_sa_t;
-
-/**
- * For an initiator, the data stored about a waiting mediated sa
- */
-struct waiting_sa_t {
- /** ike sa id */
- ike_sa_id_t *ike_sa_id;
-
- /** list of child_cfg_t */
- linked_list_t *childs;
-};
-
-/**
- * Destroys a queued mediated sa
- */
-static void waiting_sa_destroy(waiting_sa_t *this)
-{
- DESTROY_IF(this->ike_sa_id);
- this->childs->destroy_offset(this->childs, offsetof(child_cfg_t, destroy));
- free(this);
-}
-
-/**
- * Creates a new mediated sa object
- */
-static waiting_sa_t *waiting_sa_create(ike_sa_id_t *ike_sa_id)
-{
- waiting_sa_t *this = malloc_thing(waiting_sa_t);
-
- this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
- this->childs = linked_list_create();
+ this->is_finishing = FALSE;
return this;
}
@@ -306,7 +278,7 @@ static void initiated_destroy(initiated_t *this)
{
DESTROY_IF(this->id);
DESTROY_IF(this->peer_id);
- this->mediated->destroy_function(this->mediated, (void*)waiting_sa_destroy);
+ this->mediated->destroy_offset(this->mediated, offsetof(ike_sa_id_t, destroy));
free(this);
}
@@ -340,8 +312,8 @@ struct check_t {
/** destination of the connectivity check */
host_t *dst;
- /** session id */
- chunk_t session_id;
+ /** connect id */
+ chunk_t connect_id;
/** endpoint */
endpoint_notify_t *endpoint;
@@ -349,8 +321,8 @@ struct check_t {
/** raw endpoint payload (to verify the signature) */
chunk_t endpoint_raw;
- /** cookie */
- chunk_t cookie;
+ /** connect auth */
+ chunk_t auth;
};
/**
@@ -358,9 +330,11 @@ struct check_t {
*/
static void check_destroy(check_t *this)
{
- chunk_free(&this->session_id);
+ chunk_free(&this->connect_id);
chunk_free(&this->endpoint_raw);
- chunk_free(&this->cookie);
+ chunk_free(&this->auth);
+ DESTROY_IF(this->src);
+ DESTROY_IF(this->dst);
DESTROY_IF(this->endpoint);
free(this);
}
@@ -372,9 +346,11 @@ static check_t *check_create()
{
check_t *this = malloc_thing(check_t);
- this->session_id = chunk_empty;
- this->cookie = chunk_empty;
+ this->connect_id = chunk_empty;
+ this->auth = chunk_empty;
this->endpoint_raw = chunk_empty;
+ this->src = NULL;
+ this->dst = NULL;
this->endpoint = NULL;
this->mid = 0;
@@ -382,76 +358,52 @@ static check_t *check_create()
return this;
}
-typedef struct sender_data_t sender_data_t;
+typedef struct callback_data_t callback_data_t;
/**
- * Data required by the sender
+ * Data required by several callback jobs used in this file
*/
-struct sender_data_t {
+struct callback_data_t {
/** connect manager */
private_connect_manager_t *connect_manager;
- /** session id */
- chunk_t session_id;
+ /** connect id */
+ chunk_t connect_id;
+
+ /** message (pair) id */
+ u_int32_t mid;
};
/**
- * Destroys a sender data object
+ * Destroys a callback data object
*/
-static void sender_data_destroy(sender_data_t *this)
+static void callback_data_destroy(callback_data_t *this)
{
- chunk_free(&this->session_id);
+ chunk_free(&this->connect_id);
free(this);
}
/**
- * Creates a new sender data object
+ * Creates a new callback data object
*/
-static sender_data_t *sender_data_create(private_connect_manager_t *connect_manager, chunk_t session_id)
+static callback_data_t *callback_data_create(private_connect_manager_t *connect_manager,
+ chunk_t connect_id)
{
- sender_data_t *this = malloc_thing(sender_data_t);
+ callback_data_t *this = malloc_thing(callback_data_t);
this->connect_manager = connect_manager;
- this->session_id = session_id;
+ this->connect_id = chunk_clone(connect_id);
+ this->mid = 0;
return this;
}
-typedef struct retransmit_data_t retransmit_data_t;
-
-/**
- * Data required by the retransmission job
- */
-struct retransmit_data_t {
- /** connect manager */
- private_connect_manager_t *connect_manager;
-
- /** session id */
- chunk_t session_id;
-
- /** message (pair) id */
- u_int32_t mid;
-};
-
-/**
- * Destroys a retransmission data object
- */
-static void retransmit_data_destroy(retransmit_data_t *this)
-{
- chunk_free(&this->session_id);
- free(this);
-}
-
/**
* Creates a new retransmission data object
*/
-static retransmit_data_t *retransmit_data_create(private_connect_manager_t *connect_manager,
- chunk_t session_id, u_int32_t mid)
+static callback_data_t *retransmit_data_create(private_connect_manager_t *connect_manager,
+ chunk_t connect_id, u_int32_t mid)
{
- retransmit_data_t *this = malloc_thing(retransmit_data_t);
-
- this->connect_manager = connect_manager;
- this->session_id = session_id;
+ callback_data_t *this = callback_data_create(connect_manager, connect_id);
this->mid = mid;
-
return this;
}
@@ -529,34 +481,19 @@ static void remove_initiated(private_connect_manager_t *this, initiated_t *initi
}
/**
- * Finds a waiting sa
+ * Find the checklist with a specific connect ID
*/
-static bool match_waiting_sa(waiting_sa_t *current, ike_sa_id_t *ike_sa_id)
+static bool match_checklist_by_id(check_list_t *current, chunk_t *connect_id)
{
- return ike_sa_id->equals(ike_sa_id, current->ike_sa_id);
-}
-
-static status_t get_waiting_sa(initiated_t *initiated, ike_sa_id_t *ike_sa_id, waiting_sa_t **waiting_sa)
-{
- return initiated->mediated->find_first(initiated->mediated,
- (linked_list_match_t)match_waiting_sa,
- (void**)waiting_sa, ike_sa_id);
-}
-
-/**
- * Find the checklist with a specific session ID
- */
-static bool match_checklist_by_id(check_list_t *current, chunk_t *session_id)
-{
- return chunk_equals(*session_id, current->session_id);
+ return chunk_equals(*connect_id, current->connect_id);
}
static status_t get_checklist_by_id(private_connect_manager_t *this,
- chunk_t session_id, check_list_t **check_list)
+ chunk_t connect_id, check_list_t **check_list)
{
return this->checklists->find_first(this->checklists,
(linked_list_match_t)match_checklist_by_id,
- (void**)check_list, &session_id);
+ (void**)check_list, &connect_id);
}
/**
@@ -595,51 +532,6 @@ static status_t endpoints_contain(linked_list_t *endpoints, host_t *host, endpoi
}
/**
- * Updates the state of the whole checklist
- */
-static void update_checklist_state(check_list_t *checklist)
-{
- iterator_t *iterator;
- endpoint_pair_t *current;
- bool in_progress = FALSE, succeeded = FALSE;
-
- iterator = checklist->pairs->create_iterator(checklist->pairs, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
- {
- switch(current->state)
- {
- case CHECK_WAITING:
- /* at least one is still waiting -> checklist remains
- * in waiting state */
- iterator->destroy(iterator);
- return;
- case CHECK_IN_PROGRESS:
- in_progress = TRUE;
- break;
- case CHECK_SUCCEEDED:
- succeeded = TRUE;
- break;
- default:
- break;
- }
- }
- iterator->destroy(iterator);
-
- if (in_progress)
- {
- checklist->state = CHECK_IN_PROGRESS;
- }
- else if (succeeded)
- {
- checklist->state = CHECK_SUCCEEDED;
- }
- else
- {
- checklist->state = CHECK_FAILED;
- }
-}
-
-/**
* Inserts an endpoint pair into the list of pairs ordered by priority (high to low)
*/
static void insert_pair_by_priority(linked_list_t *pairs, endpoint_pair_t *pair)
@@ -681,14 +573,14 @@ static status_t get_pair_by_hosts(linked_list_t *pairs, host_t *local, host_t *r
(void**)pair, local, remote);
}
-/**
- * Searches for a pair with a specific id
- */
static bool match_pair_by_id(endpoint_pair_t *current, u_int32_t *id)
{
return current->id == *id;
}
+/**
+ * Searches for a pair with a specific id
+ */
static status_t get_pair_by_id(check_list_t *checklist, u_int32_t id, endpoint_pair_t **pair)
{
return checklist->pairs->find_first(checklist->pairs,
@@ -696,14 +588,14 @@ static status_t get_pair_by_id(check_list_t *checklist, u_int32_t id, endpoint_p
(void**)pair, &id);
}
-/**
- * Returns the best pair of state CHECK_SUCCEEDED from a checklist.
- */
static bool match_succeeded_pair(endpoint_pair_t *current)
{
return current->state == CHECK_SUCCEEDED;
}
+/**
+ * Returns the best pair of state CHECK_SUCCEEDED from a checklist.
+ */
static status_t get_best_valid_pair(check_list_t *checklist, endpoint_pair_t **pair)
{
return checklist->pairs->find_first(checklist->pairs,
@@ -711,14 +603,14 @@ static status_t get_best_valid_pair(check_list_t *checklist, endpoint_pair_t **p
(void**)pair);
}
-/**
- * Returns and *removes* the first triggered pair in state CHECK_WAITING.
- */
static bool match_waiting_pair(endpoint_pair_t *current)
{
return current->state == CHECK_WAITING;
}
+/**
+ * Returns and *removes* the first triggered pair in state CHECK_WAITING.
+ */
static status_t get_triggered_pair(check_list_t *checklist, endpoint_pair_t **pair)
{
iterator_t *iterator;
@@ -746,6 +638,24 @@ static status_t get_triggered_pair(check_list_t *checklist, endpoint_pair_t **pa
}
/**
+ * Prints all the pairs on a checklist
+ */
+static void print_checklist(check_list_t *checklist)
+{
+ iterator_t *iterator;
+ endpoint_pair_t *current;
+
+ DBG1(DBG_IKE, "pairs on checklist %#B:", &checklist->connect_id);
+ iterator = checklist->pairs->create_iterator(checklist->pairs, TRUE);
+ while (iterator->iterate(iterator, (void**)&current))
+ {
+ DBG1(DBG_IKE, " * %#H - %#H (%d)", current->local, current->remote,
+ current->priority);
+ }
+ iterator->destroy(iterator);
+}
+
+/**
* Prunes identical pairs with lower priority from the list
* Note: this function also numbers the remaining pairs serially
*/
@@ -775,7 +685,7 @@ static void prune_pairs(linked_list_t *pairs)
* order, and we iterate the list from the beginning, we are
* sure that the priority of 'other' is lower than that of
* 'current', remove it */
- DBG1(DBG_IKE, "pruning endpoint pair %H - %H with priority %d",
+ DBG1(DBG_IKE, "pruning endpoint pair %#H - %#H with priority %d",
other->local, other->remote, other->priority);
search->remove(search);
endpoint_pair_destroy(other);
@@ -792,6 +702,7 @@ static void prune_pairs(linked_list_t *pairs)
*/
static void build_pairs(check_list_t *checklist)
{
+ /* FIXME: limit endpoints and pairs */
iterator_t *iterator_i, *iterator_r;
endpoint_notify_t *initiator, *responder;
@@ -812,6 +723,8 @@ static void build_pairs(check_list_t *checklist)
iterator_r->destroy(iterator_r);
}
iterator_i->destroy(iterator_i);
+
+ print_checklist(checklist);
prune_pairs(checklist->pairs);
}
@@ -838,45 +751,45 @@ static status_t process_payloads(message_t *message, check_t *check)
switch (notify->get_notify_type(notify))
{
- case P2P_ENDPOINT:
+ case ME_ENDPOINT:
{
if (check->endpoint)
{
- DBG1(DBG_IKE, "connectivity check contains multiple P2P_ENDPOINT notifies");
+ DBG1(DBG_IKE, "connectivity check contains multiple ME_ENDPOINT notifies");
break;
}
endpoint_notify_t *endpoint = endpoint_notify_create_from_payload(notify);
if (!endpoint)
{
- DBG1(DBG_IKE, "received invalid P2P_ENDPOINT notify");
+ DBG1(DBG_IKE, "received invalid ME_ENDPOINT notify");
break;
}
check->endpoint = endpoint;
check->endpoint_raw = chunk_clone(notify->get_notification_data(notify));
- DBG2(DBG_IKE, "received P2P_ENDPOINT notify");
+ DBG2(DBG_IKE, "received ME_ENDPOINT notify");
break;
}
- case P2P_SESSIONID:
+ case ME_CONNECTID:
{
- if (check->session_id.ptr)
+ if (check->connect_id.ptr)
{
- DBG1(DBG_IKE, "connectivity check contains multiple P2P_SESSIONID notifies");
+ DBG1(DBG_IKE, "connectivity check contains multiple ME_CONNECTID notifies");
break;
}
- check->session_id = chunk_clone(notify->get_notification_data(notify));
- DBG3(DBG_IKE, "received p2p_sessionid %B", &check->session_id);
+ check->connect_id = chunk_clone(notify->get_notification_data(notify));
+ DBG2(DBG_IKE, "received ME_CONNECTID %#B", &check->connect_id);
break;
}
- case COOKIE:
+ case ME_CONNECTAUTH:
{
- if (check->cookie.ptr)
+ if (check->auth.ptr)
{
- DBG1(DBG_IKE, "connectivity check contains multiple COOKIE notifies");
+ DBG1(DBG_IKE, "connectivity check contains multiple ME_CONNECTAUTH notifies");
break;
}
- check->cookie = chunk_clone(notify->get_notification_data(notify));
- DBG3(DBG_IKE, "received cookie %B", &check->cookie);
+ check->auth = chunk_clone(notify->get_notification_data(notify));
+ DBG2(DBG_IKE, "received ME_CONNECTAUTH %#B", &check->auth);
break;
}
default:
@@ -885,7 +798,7 @@ static status_t process_payloads(message_t *message, check_t *check)
}
iterator->destroy(iterator);
- if (!check->session_id.ptr || !check->endpoint || !check->cookie.ptr)
+ if (!check->connect_id.ptr || !check->endpoint || !check->auth.ptr)
{
DBG1(DBG_IKE, "at least one payload was missing from the connectivity check");
return FAILED;
@@ -900,42 +813,129 @@ static status_t process_payloads(message_t *message, check_t *check)
static chunk_t build_signature(private_connect_manager_t *this,
check_list_t *checklist, check_t *check, bool outbound)
{
+ u_int32_t mid;
chunk_t mid_chunk, key_chunk, sig_chunk;
chunk_t sig_hash;
- mid_chunk = chunk_from_thing(check->mid);
+ mid = htonl(check->mid);
+ mid_chunk = chunk_from_thing(mid);
key_chunk = (checklist->is_initiator && outbound) || (!checklist->is_initiator && !outbound)
? checklist->initiator.key : checklist->responder.key;
- /* signature = SHA1( MID | P2P_SESSIONID | P2P_ENDPOINT | P2P_SESSIONKEY ) */
- sig_chunk = chunk_cat("cccc", mid_chunk, check->session_id, check->endpoint_raw, key_chunk);
+ /* signature = SHA1( MID | ME_CONNECTID | ME_ENDPOINT | ME_CONNECTKEY ) */
+ sig_chunk = chunk_cat("cccc", mid_chunk, check->connect_id, check->endpoint_raw, key_chunk);
this->hasher->allocate_hash(this->hasher, sig_chunk, &sig_hash);
- DBG3(DBG_IKE, "sig_chunk %B", &sig_chunk);
- DBG3(DBG_IKE, "sig_hash %B", &sig_hash);
+ DBG3(DBG_IKE, "sig_chunk %#B", &sig_chunk);
+ DBG3(DBG_IKE, "sig_hash %#B", &sig_hash);
chunk_free(&sig_chunk);
return sig_hash;
}
-static void queue_retransmission(private_connect_manager_t *this, chunk_t session_id, u_int32_t mid);
+static void queue_retransmission(private_connect_manager_t *this, check_list_t *checklist, endpoint_pair_t *pair);
static void schedule_checks(private_connect_manager_t *this, check_list_t *checklist, u_int32_t time);
static void finish_checks(private_connect_manager_t *this, check_list_t *checklist);
/**
+ * After one of the initiator's pairs has succeeded we finish the checks without
+ * waiting for all the timeouts
+ */
+static job_requeue_t initiator_finish(callback_data_t *data)
+{
+ private_connect_manager_t *this = data->connect_manager;
+
+ pthread_mutex_lock(&(this->mutex));
+
+ check_list_t *checklist;
+ if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS)
+ {
+ DBG1(DBG_IKE, "checklist with id '%#B' not found, can't finish connectivity checks",
+ &data->connect_id);
+ pthread_mutex_unlock(&(this->mutex));
+ return JOB_REQUEUE_NONE;
+ }
+
+ finish_checks(this, checklist);
+
+ pthread_mutex_unlock(&(this->mutex));
+
+ return JOB_REQUEUE_NONE;
+}
+
+/**
+ * Updates the state of the whole checklist
+ */
+static void update_checklist_state(private_connect_manager_t *this, check_list_t *checklist)
+{
+ iterator_t *iterator;
+ endpoint_pair_t *current;
+ bool in_progress = FALSE, succeeded = FALSE;
+
+ iterator = checklist->pairs->create_iterator(checklist->pairs, TRUE);
+ while (iterator->iterate(iterator, (void**)&current))
+ {
+ switch(current->state)
+ {
+ case CHECK_WAITING:
+ /* at least one is still waiting -> checklist remains
+ * in waiting state */
+ iterator->destroy(iterator);
+ return;
+ case CHECK_IN_PROGRESS:
+ in_progress = TRUE;
+ break;
+ case CHECK_SUCCEEDED:
+ succeeded = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+
+ if (checklist->is_initiator && succeeded && !checklist->is_finishing)
+ {
+ /* instead of waiting until all checks have finished (i.e. all
+ * retransmissions have failed) the initiator finishes the checks
+ * right after the first check has succeeded. to allow a probably
+ * better pair to succeed, we still wait a certain time */
+ DBG2(DBG_IKE, "fast finishing checks for checklist '%#B'", &checklist->connect_id);
+
+ callback_data_t *data = callback_data_create(this, checklist->connect_id);
+ job_t *job = (job_t*)callback_job_create((callback_job_cb_t)initiator_finish, data, (callback_job_cleanup_t)callback_data_destroy, NULL);
+ charon->scheduler->schedule_job(charon->scheduler, job, ME_WAIT_TO_FINISH);
+ checklist->is_finishing = TRUE;
+ }
+
+ if (in_progress)
+ {
+ checklist->state = CHECK_IN_PROGRESS;
+ }
+ else if (succeeded)
+ {
+ checklist->state = CHECK_SUCCEEDED;
+ }
+ else
+ {
+ checklist->state = CHECK_FAILED;
+ }
+}
+
+/**
* This function is triggered for each sent check after a specific timeout
*/
-static job_requeue_t retransmit(retransmit_data_t *data)
+static job_requeue_t retransmit(callback_data_t *data)
{
private_connect_manager_t *this = data->connect_manager;
pthread_mutex_lock(&(this->mutex));
check_list_t *checklist;
- if (get_checklist_by_id(this, data->session_id, &checklist) != SUCCESS)
+ if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS)
{
- DBG1(DBG_IKE, "checklist with id '%B' not found, can't retransmit connectivity check",
- &data->session_id);
+ DBG1(DBG_IKE, "checklist with id '%#B' not found, can't retransmit connectivity check",
+ &data->connect_id);
pthread_mutex_unlock(&(this->mutex));
return JOB_REQUEUE_NONE;
}
@@ -955,20 +955,20 @@ static job_requeue_t retransmit(retransmit_data_t *data)
goto retransmit_end;
}
- if (++pair->retransmitted >= P2P_MAX_RETRANS)
+ if (++pair->retransmitted > ME_MAX_RETRANS)
{
- DBG2(DBG_IKE, "pair with id '%d' failed after %d tries",
- data->mid, pair->retransmitted);
+ DBG2(DBG_IKE, "pair with id '%d' failed after %d retransmissions",
+ data->mid, ME_MAX_RETRANS);
pair->state = CHECK_FAILED;
goto retransmit_end;
}
charon->sender->send(charon->sender, pair->packet->clone(pair->packet));
- queue_retransmission(this, checklist->session_id, pair->id);
+ queue_retransmission(this, checklist, pair);
retransmit_end:
- update_checklist_state(checklist);
+ update_checklist_state(this, checklist);
switch(checklist->state)
{
@@ -989,11 +989,20 @@ retransmit_end:
/**
* Queues a retransmission job
*/
-static void queue_retransmission(private_connect_manager_t *this, chunk_t session_id, u_int32_t mid)
+static void queue_retransmission(private_connect_manager_t *this, check_list_t *checklist, endpoint_pair_t *pair)
{
- retransmit_data_t *data = retransmit_data_create(this, chunk_clone(session_id), mid);
- job_t *job = (job_t*)callback_job_create((callback_job_cb_t)retransmit, data, (callback_job_cleanup_t)retransmit_data_destroy, NULL);
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, P2P_RTO_MIN);
+ callback_data_t *data = retransmit_data_create(this, checklist->connect_id, pair->id);
+ job_t *job = (job_t*)callback_job_create((callback_job_cb_t)retransmit, data, (callback_job_cleanup_t)callback_data_destroy, NULL);
+
+ u_int32_t retransmission = pair->retransmitted + 1;
+ u_int32_t rto = ME_INTERVAL;
+ if (retransmission > ME_BOOST)
+ {
+ rto = (u_int32_t)(ME_INTERVAL * pow(ME_RETRANS_BASE, retransmission - ME_BOOST));
+ }
+ DBG2(DBG_IKE, "scheduling retransmission %d of pair '%d' in %dms", retransmission, pair->id, rto);
+
+ charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, rto);
}
/**
@@ -1009,16 +1018,21 @@ static void send_check(private_connect_manager_t *this, check_list_t *checklist,
message->set_destination(message, check->dst->clone(check->dst));
message->set_source(message, check->src->clone(check->src));
- message->set_ike_sa_id(message, ike_sa_id_create(0, 0, request));
+ ike_sa_id_t *ike_sa_id = ike_sa_id_create(0, 0, request);
+ message->set_ike_sa_id(message, ike_sa_id);
+ ike_sa_id->destroy(ike_sa_id);
- message->add_notify(message, FALSE, P2P_SESSIONID, check->session_id);
+ message->add_notify(message, FALSE, ME_CONNECTID, check->connect_id);
+ DBG2(DBG_IKE, "send ME_CONNECTID %#B", &check->connect_id);
notify_payload_t *endpoint = check->endpoint->build_notify(check->endpoint);
check->endpoint_raw = chunk_clone(endpoint->get_notification_data(endpoint));
message->add_payload(message, (payload_t*)endpoint);
+ DBG2(DBG_IKE, "send ME_ENDPOINT notify");
- check->cookie = build_signature(this, checklist, check, TRUE);
- message->add_notify(message, FALSE, COOKIE, check->cookie);
+ check->auth = build_signature(this, checklist, check, TRUE);
+ message->add_notify(message, FALSE, ME_CONNECTAUTH, check->auth);
+ DBG2(DBG_IKE, "send ME_CONNECTAUTH %#B", &check->auth);
packet_t *packet;
if (message->generate(message, NULL, NULL, &packet) == SUCCESS)
@@ -1029,42 +1043,55 @@ static void send_check(private_connect_manager_t *this, check_list_t *checklist,
{
DESTROY_IF(pair->packet);
pair->packet = packet;
- queue_retransmission(this, checklist->session_id, pair->id);
+ pair->retransmitted = 0;
+ queue_retransmission(this, checklist, pair);
}
else
{
packet->destroy(packet);
}
}
+ message->destroy(message);
}
/**
* Queues a triggered check
*/
-static void queue_triggered_check(check_list_t *checklist, endpoint_pair_t *pair)
+static void queue_triggered_check(private_connect_manager_t *this,
+ check_list_t *checklist, endpoint_pair_t *pair)
{
+ DBG2(DBG_IKE, "queueing triggered check for pair '%d'", pair->id);
pair->state = CHECK_WAITING;
checklist->triggered->insert_last(checklist->triggered, pair);
+
+ if (!checklist->sender)
+ {
+ /* if the sender is not running we restart it */
+ schedule_checks(this, checklist, ME_INTERVAL);
+ }
}
/**
* This function is triggered for each checklist at a specific interval
*/
-static job_requeue_t sender(sender_data_t *data)
+static job_requeue_t sender(callback_data_t *data)
{
private_connect_manager_t *this = data->connect_manager;
pthread_mutex_lock(&(this->mutex));
-
+
check_list_t *checklist;
- if (get_checklist_by_id(this, data->session_id, &checklist) != SUCCESS)
+ if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS)
{
- DBG1(DBG_IKE, "checklist with id '%B' not found, can't send connectivity check",
- &data->session_id);
+ DBG1(DBG_IKE, "checklist with id '%#B' not found, can't send connectivity check",
+ &data->connect_id);
pthread_mutex_unlock(&(this->mutex));
return JOB_REQUEUE_NONE;
}
+ /* reset the sender */
+ checklist->sender = NULL;
+
endpoint_pair_t *pair;
if (get_triggered_pair(checklist, &pair) != SUCCESS)
{
@@ -1087,7 +1114,7 @@ static job_requeue_t sender(sender_data_t *data)
check->mid = pair->id;
check->src = pair->local->clone(pair->local);
check->dst = pair->remote->clone(pair->remote);
- check->session_id = chunk_clone(checklist->session_id);
+ check->connect_id = chunk_clone(checklist->connect_id);
check->endpoint = endpoint_notify_create();
pair->state = CHECK_IN_PROGRESS;
@@ -1097,8 +1124,7 @@ static job_requeue_t sender(sender_data_t *data)
check_destroy(check);
/* schedule this job again */
- u_int32_t N = this->checklists->get_count(this->checklists);
- schedule_checks(this, checklist, P2P_INTERVAL * N);
+ schedule_checks(this, checklist, ME_INTERVAL);
pthread_mutex_unlock(&(this->mutex));
@@ -1111,10 +1137,9 @@ static job_requeue_t sender(sender_data_t *data)
*/
static void schedule_checks(private_connect_manager_t *this, check_list_t *checklist, u_int32_t time)
{
- chunk_t session_id = chunk_clone(checklist->session_id);
- sender_data_t *data = sender_data_create(this, session_id);
- job_t *job = (job_t*)callback_job_create((callback_job_cb_t)sender, data, (callback_job_cleanup_t)sender_data_destroy, NULL);
- charon->scheduler->schedule_job(charon->scheduler, job, time);
+ callback_data_t *data = callback_data_create(this, checklist->connect_id);
+ checklist->sender = (job_t*)callback_job_create((callback_job_cb_t)sender, data, (callback_job_cleanup_t)callback_data_destroy, NULL);
+ charon->scheduler->schedule_job(charon->scheduler, checklist->sender, time);
}
/**
@@ -1128,12 +1153,12 @@ static job_requeue_t initiate_mediated(initiate_data_t *data)
endpoint_pair_t *pair;
if (get_best_valid_pair(checklist, &pair) == SUCCESS)
{
- waiting_sa_t *waiting_sa;
+ ike_sa_id_t *waiting_sa;
iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE);
while (iterator->iterate(iterator, (void**)&waiting_sa))
{
- ike_sa_t *sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, waiting_sa->ike_sa_id);
- if (sa->initiate_mediated(sa, pair->local, pair->remote, waiting_sa->childs) != SUCCESS)
+ ike_sa_t *sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, waiting_sa);
+ if (sa->initiate_mediated(sa, pair->local, pair->remote, checklist->connect_id) != SUCCESS)
{
SIG(IKE_UP_FAILED, "establishing the mediated connection failed");
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
@@ -1175,11 +1200,6 @@ static void finish_checks(private_connect_manager_t *this, check_list_t *checkli
"and '%D'", checklist->initiator.id, checklist->responder.id);
}
}
-
- /* remove_checklist(this, checklist);
- * check_list_destroy(checklist);
- * FIXME: we should do this ^^^ after a specific timeout on the
- * responder side */
}
/**
@@ -1212,7 +1232,7 @@ static void process_response(private_connect_manager_t *this, check_t *check,
local_endpoints->insert_last(local_endpoints, local_endpoint);
}
- update_checklist_state(checklist);
+ update_checklist_state(this, checklist);
switch(checklist->state)
{
@@ -1253,12 +1273,12 @@ static void process_request(private_connect_manager_t *this, check_t *check,
{
case CHECK_IN_PROGRESS:
/* prevent retransmissions */
- pair->retransmitted = P2P_MAX_RETRANS;
+ pair->retransmitted = ME_MAX_RETRANS;
/* FIXME: we should wait to the next rto to send the triggered check
* fall-through */
case CHECK_WAITING:
case CHECK_FAILED:
- queue_triggered_check(checklist, pair);
+ queue_triggered_check(this, checklist, pair);
break;
case CHECK_SUCCEEDED:
default:
@@ -1277,7 +1297,7 @@ static void process_request(private_connect_manager_t *this, check_t *check,
insert_pair_by_priority(checklist->pairs, pair);
- queue_triggered_check(checklist, pair);
+ queue_triggered_check(this, checklist, pair);
local_endpoint->destroy(local_endpoint);
}
@@ -1288,7 +1308,7 @@ static void process_request(private_connect_manager_t *this, check_t *check,
response->mid = check->mid;
response->src = check->dst->clone(check->dst);
response->dst = check->src->clone(check->src);
- response->session_id = chunk_clone(check->session_id);
+ response->connect_id = chunk_clone(check->connect_id);
response->endpoint = peer_reflexive;
send_check(this, checklist, response, pair, FALSE);
@@ -1313,7 +1333,9 @@ static void process_check(private_connect_manager_t *this, message_t *message)
check_t *check = check_create();
check->mid = message->get_message_id(message);
check->src = message->get_source(message);
+ check->src = check->src->clone(check->src);
check->dst = message->get_destination(message);
+ check->dst = check->dst->clone(check->dst);
if (process_payloads(message, check) != SUCCESS)
{
@@ -1326,17 +1348,17 @@ static void process_check(private_connect_manager_t *this, message_t *message)
pthread_mutex_lock(&(this->mutex));
check_list_t *checklist;
- if (get_checklist_by_id(this, check->session_id, &checklist) != SUCCESS)
+ if (get_checklist_by_id(this, check->connect_id, &checklist) != SUCCESS)
{
- DBG1(DBG_IKE, "checklist with id '%B' not found",
- &check->session_id);
+ DBG1(DBG_IKE, "checklist with id '%#B' not found",
+ &check->connect_id);
check_destroy(check);
pthread_mutex_unlock(&(this->mutex));
return;
}
chunk_t sig = build_signature(this, checklist, check, FALSE);
- if (!chunk_equals(sig, check->cookie))
+ if (!chunk_equals(sig, check->auth))
{
DBG1(DBG_IKE, "connectivity check verification failed");
check_destroy(check);
@@ -1365,7 +1387,7 @@ static void process_check(private_connect_manager_t *this, message_t *message)
*/
static bool check_and_register(private_connect_manager_t *this,
identification_t *id, identification_t *peer_id,
- ike_sa_id_t *mediated_sa, child_cfg_t *child)
+ ike_sa_id_t *mediated_sa)
{
initiated_t *initiated;
bool already_there = TRUE;
@@ -1380,16 +1402,12 @@ static bool check_and_register(private_connect_manager_t *this,
already_there = FALSE;
}
- waiting_sa_t *waiting_sa;
- if (get_waiting_sa(initiated, mediated_sa, &waiting_sa) != SUCCESS)
+ if (initiated->mediated->find_first(initiated->mediated,
+ (linked_list_match_t)mediated_sa->equals, NULL, mediated_sa) != SUCCESS)
{
- waiting_sa = waiting_sa_create(mediated_sa);
- initiated->mediated->insert_last(initiated->mediated, waiting_sa);
+ initiated->mediated->insert_last(initiated->mediated, mediated_sa->clone(mediated_sa));
}
- child->get_ref(child);
- waiting_sa->childs->insert_last(waiting_sa->childs, child);
-
pthread_mutex_unlock(&(this->mutex));
return already_there;
@@ -1412,14 +1430,14 @@ static void check_and_initiate(private_connect_manager_t *this, ike_sa_id_t *med
return;
}
- waiting_sa_t *waiting_sa;
+ ike_sa_id_t *waiting_sa;
iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE);
while (iterator->iterate(iterator, (void**)&waiting_sa))
{
- job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa,
- waiting_sa->ike_sa_id);
+ job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa, waiting_sa);
charon->processor->queue_job(charon->processor, job);
}
+ iterator->destroy(iterator);
pthread_mutex_unlock(&(this->mutex));
}
@@ -1429,21 +1447,21 @@ static void check_and_initiate(private_connect_manager_t *this, ike_sa_id_t *med
*/
static status_t set_initiator_data(private_connect_manager_t *this,
identification_t *initiator, identification_t *responder,
- chunk_t session_id, chunk_t key, linked_list_t *endpoints, bool is_initiator)
+ chunk_t connect_id, chunk_t key, linked_list_t *endpoints, bool is_initiator)
{
check_list_t *checklist;
pthread_mutex_lock(&(this->mutex));
- if (get_checklist_by_id(this, session_id, NULL) == SUCCESS)
+ if (get_checklist_by_id(this, connect_id, NULL) == SUCCESS)
{
- DBG1(DBG_IKE, "checklist with id '%B' already exists, aborting",
- &session_id);
+ DBG1(DBG_IKE, "checklist with id '%#B' already exists, aborting",
+ &connect_id);
pthread_mutex_unlock(&(this->mutex));
return FAILED;
}
- checklist = check_list_create(initiator, responder, session_id, key, endpoints, is_initiator);
+ checklist = check_list_create(initiator, responder, connect_id, key, endpoints, is_initiator);
this->checklists->insert_last(this->checklists, checklist);
pthread_mutex_unlock(&(this->mutex));
@@ -1455,16 +1473,16 @@ static status_t set_initiator_data(private_connect_manager_t *this,
* Implementation of connect_manager_t.set_responder_data.
*/
static status_t set_responder_data(private_connect_manager_t *this,
- chunk_t session_id, chunk_t key, linked_list_t *endpoints)
+ chunk_t connect_id, chunk_t key, linked_list_t *endpoints)
{
check_list_t *checklist;
pthread_mutex_lock(&(this->mutex));
- if (get_checklist_by_id(this, session_id, &checklist) != SUCCESS)
+ if (get_checklist_by_id(this, connect_id, &checklist) != SUCCESS)
{
- DBG1(DBG_IKE, "checklist with id '%B' not found",
- &session_id);
+ DBG1(DBG_IKE, "checklist with id '%#B' not found",
+ &connect_id);
pthread_mutex_unlock(&(this->mutex));
return NOT_FOUND;
}
@@ -1484,6 +1502,33 @@ static status_t set_responder_data(private_connect_manager_t *this,
}
/**
+ * Implementation of connect_manager_t.stop_checks.
+ */
+static status_t stop_checks(private_connect_manager_t *this, chunk_t connect_id)
+{
+ check_list_t *checklist;
+
+ pthread_mutex_lock(&(this->mutex));
+
+ if (get_checklist_by_id(this, connect_id, &checklist) != SUCCESS)
+ {
+ DBG1(DBG_IKE, "checklist with id '%#B' not found",
+ &connect_id);
+ pthread_mutex_unlock(&(this->mutex));
+ return NOT_FOUND;
+ }
+
+ DBG1(DBG_IKE, "removing checklist with id '%#B'", &connect_id);
+
+ remove_checklist(this, checklist);
+ check_list_destroy(checklist);
+
+ pthread_mutex_unlock(&(this->mutex));
+
+ return SUCCESS;
+}
+
+/**
* Implementation of connect_manager_t.destroy.
*/
static void destroy(private_connect_manager_t *this)
@@ -1507,13 +1552,21 @@ connect_manager_t *connect_manager_create()
private_connect_manager_t *this = malloc_thing(private_connect_manager_t);
this->public.destroy = (void(*)(connect_manager_t*))destroy;
- this->public.check_and_register = (bool(*)(connect_manager_t*,identification_t*,identification_t*,ike_sa_id_t*,child_cfg_t*))check_and_register;
+ this->public.check_and_register = (bool(*)(connect_manager_t*,identification_t*,identification_t*,ike_sa_id_t*))check_and_register;
this->public.check_and_initiate = (void(*)(connect_manager_t*,ike_sa_id_t*,identification_t*,identification_t*))check_and_initiate;
this->public.set_initiator_data = (status_t(*)(connect_manager_t*,identification_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool))set_initiator_data;
this->public.set_responder_data = (status_t(*)(connect_manager_t*,chunk_t,chunk_t,linked_list_t*))set_responder_data;
this->public.process_check = (void(*)(connect_manager_t*,message_t*))process_check;
+ this->public.stop_checks = (status_t(*)(connect_manager_t*,chunk_t))stop_checks;
+
+ this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (this->hasher == NULL)
+ {
+ DBG1(DBG_IKE, "unable to create connect manager, SHA1 not supported");
+ free(this);
+ return NULL;
+ }
- this->hasher = hasher_create(HASH_SHA1);
this->checklists = linked_list_create();
this->initiated = linked_list_create();
diff --git a/src/charon/sa/connect_manager.h b/src/charon/sa/connect_manager.h
index 2f3e9109b..38d8e7a49 100644
--- a/src/charon/sa/connect_manager.h
+++ b/src/charon/sa/connect_manager.h
@@ -1,12 +1,5 @@
-/**
- * @file connect_manager.h
- *
- * @brief Interface of connect_manager_t.
- *
- */
-
/*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: connect_manager.h 3792 2008-04-10 12:51:04Z tobias $
+ */
+
+/**
+ * @defgroup connect_manager connect_manager
+ * @{ @ingroup sa
*/
#ifndef CONNECT_MANAGER_H_
@@ -26,43 +26,33 @@
typedef struct connect_manager_t connect_manager_t;
#include <encoding/message.h>
-#include <config/child_cfg.h>
#include <sa/ike_sa_id.h>
#include <utils/identification.h>
/**
- * @brief The connection manager is responsible for establishing a direct
+ * The connection manager is responsible for establishing a direct
* connection with another peer.
- *
- * @b Constructors:
- * - connect_manager_create()
- *
- * @ingroup sa
*/
struct connect_manager_t {
/**
- * @brief Checks if a there is already a mediated connection registered
+ * Checks if a there is already a mediated connection registered
* between two peers.
*
- * @param this the manager object
* @param id my id
* @param peer_id the other peer's id
* @param mediated_sa the IKE_SA ID of the mediated connection
- * @param child the CHILD_SA config of the mediated connection
* @returns
* - TRUE, if there was already a mediated connection registered
* - FALSE, otherwise
*/
bool (*check_and_register) (connect_manager_t *this,
- identification_t *id, identification_t *peer_id,
- ike_sa_id_t *mediated_sa, child_cfg_t *child);
+ identification_t *id, identification_t *peer_id, ike_sa_id_t *mediated_sa);
/**
- * @brief Checks if there are waiting connections with a specific peer.
+ * Checks if there are waiting connections with a specific peer.
* If so, reinitiate them.
*
- * @param this the manager object
* @param id my id
* @param peer_id the other peer's id
*/
@@ -70,29 +60,26 @@ struct connect_manager_t {
identification_t *id, identification_t *peer_id);
/**
- * @brief Creates a checklist and sets the initiator's data.
+ * Creates a checklist and sets the initiator's data.
*
- * @param this the manager object
* @param initiator ID of the initiator
* @param responder ID of the responder
- * @param session_id the session ID provided by the initiator
+ * @param connect_id the connect ID provided by the initiator
* @param key the initiator's key
* @param endpoints the initiator's endpoints
* @param is_initiator TRUE, if the caller of this method is the initiator
* FALSE, otherwise
- * @returns
- * SUCCESS
+ * @returns SUCCESS
*/
status_t (*set_initiator_data) (connect_manager_t *this,
identification_t *initiator, identification_t *responder,
- chunk_t session_id, chunk_t key, linked_list_t *endpoints, bool is_initiator);
+ chunk_t connect_id, chunk_t key, linked_list_t *endpoints, bool is_initiator);
/**
- * @brief Updates a checklist and sets the responder's data. The checklist's
+ * Updates a checklist and sets the responder's data. The checklist's
* state is advanced to WAITING which means that checks will be sent.
*
- * @param this the manager object
- * @param session_id the session ID
+ * @param connect_id the connect ID
* @param chunk_t the responder's key
* @param endpoints the responder's endpoints
* @returns
@@ -100,32 +87,37 @@ struct connect_manager_t {
* - SUCCESS, otherwise
*/
status_t (*set_responder_data) (connect_manager_t *this,
- chunk_t session_id, chunk_t key, linked_list_t *endpoints);
+ chunk_t connect_id, chunk_t key, linked_list_t *endpoints);
+ /**
+ * Stops checks for a checklist. Used after the responder received an IKE_SA_INIT
+ * request which contains a ME_CONNECTID payload.
+ *
+ * @param connect_id the connect ID
+ * @returns
+ * - NOT_FOUND, if the checklist has not been found
+ * - SUCCESS, otherwise
+ */
+ status_t (*stop_checks) (connect_manager_t *this, chunk_t connect_id);
/**
- * @brief Processes a connectivity check
+ * Processes a connectivity check
*
- * @param this the manager object
* @param message the received message
*/
void (*process_check) (connect_manager_t *this, message_t *message);
/**
- * @brief Destroys the manager with all data.
- *
- * @param this the manager object
+ * Destroys the manager with all data.
*/
void (*destroy) (connect_manager_t *this);
};
/**
- * @brief Create a manager.
+ * Create a manager.
*
* @returns connect_manager_t object
- *
- * @ingroup sa
*/
connect_manager_t *connect_manager_create(void);
-#endif /*CONNECT_MANAGER_H_*/
+#endif /*CONNECT_MANAGER_H_ @} */
diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c
index 93aa08965..384226380 100644
--- a/src/charon/sa/ike_sa.c
+++ b/src/charon/sa/ike_sa.c
@@ -1,12 +1,5 @@
-/**
- * @file ike_sa.c
- *
- * @brief Implementation of ike_sa_t.
- *
- */
-
/*
- * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2006-2008 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -21,6 +14,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_sa.c 4106 2008-06-25 11:40:50Z martin $
*/
#include <sys/time.h>
@@ -53,7 +48,8 @@
#include <sa/tasks/ike_auth.h>
#include <sa/tasks/ike_auth_lifetime.h>
#include <sa/tasks/ike_config.h>
-#include <sa/tasks/ike_cert.h>
+#include <sa/tasks/ike_cert_pre.h>
+#include <sa/tasks/ike_cert_post.h>
#include <sa/tasks/ike_rekey.h>
#include <sa/tasks/ike_reauth.h>
#include <sa/tasks/ike_delete.h>
@@ -67,8 +63,8 @@
#include <processing/jobs/send_keepalive_job.h>
#include <processing/jobs/rekey_ike_sa_job.h>
-#ifdef P2P
-#include <sa/tasks/ike_p2p.h>
+#ifdef ME
+#include <sa/tasks/ike_me.h>
#include <processing/jobs/initiate_mediation_job.h>
#endif
@@ -122,6 +118,16 @@ struct private_ike_sa_t {
peer_cfg_t *peer_cfg;
/**
+ * associated authentication/authorization info for local peer
+ */
+ auth_info_t *my_auth;
+
+ /**
+ * associated authentication/authorization info for remote peer
+ */
+ auth_info_t *other_auth;
+
+ /**
* Juggles tasks to process messages
*/
task_manager_t *task_manager;
@@ -136,12 +142,22 @@ struct private_ike_sa_t {
*/
host_t *other_host;
-#ifdef P2P
+#ifdef ME
+ /**
+ * Are we mediation server
+ */
+ bool is_mediation_server;
+
/**
* Server reflexive host
*/
host_t *server_reflexive_host;
-#endif /* P2P */
+
+ /**
+ * Connect ID
+ */
+ chunk_t connect_id;
+#endif /* ME */
/**
* Identification used for us
@@ -154,11 +170,6 @@ struct private_ike_sa_t {
identification_t *other_id;
/**
- * CA that issued the certificate of other
- */
- ca_info_t *other_ca;
-
- /**
* set of extensions the peer supports
*/
ike_extension_t extensions;
@@ -174,6 +185,11 @@ struct private_ike_sa_t {
linked_list_t *child_sas;
/**
+ * String describing the selected IKE proposal
+ */
+ char *selected_proposal;
+
+ /**
* crypter for inbound traffic
*/
crypter_t *crypter_in;
@@ -390,6 +406,7 @@ static peer_cfg_t* get_peer_cfg(private_ike_sa_t *this)
*/
static void set_peer_cfg(private_ike_sa_t *this, peer_cfg_t *peer_cfg)
{
+ DESTROY_IF(this->peer_cfg);
peer_cfg->get_ref(peer_cfg);
this->peer_cfg = peer_cfg;
@@ -398,18 +415,6 @@ static void set_peer_cfg(private_ike_sa_t *this, peer_cfg_t *peer_cfg)
this->ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
this->ike_cfg->get_ref(this->ike_cfg);
}
-
- /* apply values, so we are ready to initate/acquire */
- if (this->my_host->is_anyaddr(this->my_host))
- {
- host_t *me = this->ike_cfg->get_my_host(this->ike_cfg);
- set_my_host(this, me->clone(me));
- }
- if (this->other_host->is_anyaddr(this->other_host))
- {
- host_t *other = this->ike_cfg->get_other_host(this->ike_cfg);
- set_other_host(this, other->clone(other));
- }
/* apply IDs if they are not already set */
if (this->my_id->contains_wildcards(this->my_id))
{
@@ -426,6 +431,22 @@ static void set_peer_cfg(private_ike_sa_t *this, peer_cfg_t *peer_cfg)
}
/**
+ * Implementation of ike_sa_t.get_my_auth.
+ */
+static auth_info_t* get_my_auth(private_ike_sa_t *this)
+{
+ return this->my_auth;
+}
+
+/**
+ * Implementation of ike_sa_t.get_other_auth.
+ */
+static auth_info_t* get_other_auth(private_ike_sa_t *this)
+{
+ return this->other_auth;
+}
+
+/**
* Implementation of ike_sa_t.send_keepalive
*/
static void send_keepalive(private_ike_sa_t *this)
@@ -480,6 +501,15 @@ static void set_ike_cfg(private_ike_sa_t *this, ike_cfg_t *ike_cfg)
ike_cfg->get_ref(ike_cfg);
this->ike_cfg = ike_cfg;
}
+
+/**
+ * Implementation of ike_sa_t.is_ike_initiator
+ */
+static bool is_ike_initiator(private_ike_sa_t *this)
+{
+ return this->ike_initiator;
+}
+
/**
* Implementation of ike_sa_t.enable_extension.
*/
@@ -562,7 +592,7 @@ static status_t send_dpd(private_ike_sa_t *this)
send_dpd_job_t *job;
time_t diff, delay;
- delay = this->peer_cfg->get_dpd_delay(this->peer_cfg);
+ delay = this->peer_cfg->get_dpd(this->peer_cfg);
if (delay == 0)
{
@@ -907,7 +937,17 @@ static void send_notify_response(private_ike_sa_t *this, message_t *request,
response->destroy(response);
}
-#ifdef P2P
+#ifdef ME
+/**
+ * Implementation of ike_sa_t.act_as_mediation_server.
+ */
+static void act_as_mediation_server(private_ike_sa_t *this)
+{
+ charon->mediation_manager->update_sa_id(charon->mediation_manager,
+ this->other_id, this->ike_sa_id);
+ this->is_mediation_server = TRUE;
+}
+
/**
* Implementation of ike_sa_t.get_server_reflexive_host.
*/
@@ -926,13 +966,21 @@ static void set_server_reflexive_host(private_ike_sa_t *this, host_t *host)
}
/**
+ * Implementation of ike_sa_t.get_connect_id.
+ */
+static chunk_t get_connect_id(private_ike_sa_t *this)
+{
+ return this->connect_id;
+}
+
+/**
* Implementation of ike_sa_t.respond
*/
static status_t respond(private_ike_sa_t *this, identification_t *peer_id,
- chunk_t session_id)
+ chunk_t connect_id)
{
- ike_p2p_t *task = ike_p2p_create(&this->public, TRUE);
- task->respond(task, peer_id, session_id);
+ ike_me_t *task = ike_me_create(&this->public, TRUE);
+ task->respond(task, peer_id, connect_id);
this->task_manager->queue_task(this->task_manager, (task_t*)task);
return this->task_manager->initiate(this->task_manager);
}
@@ -942,7 +990,7 @@ static status_t respond(private_ike_sa_t *this, identification_t *peer_id,
*/
static status_t callback(private_ike_sa_t *this, identification_t *peer_id)
{
- ike_p2p_t *task = ike_p2p_create(&this->public, TRUE);
+ ike_me_t *task = ike_me_create(&this->public, TRUE);
task->callback(task, peer_id);
this->task_manager->queue_task(this->task_manager, (task_t*)task);
return this->task_manager->initiate(this->task_manager);
@@ -952,10 +1000,10 @@ static status_t callback(private_ike_sa_t *this, identification_t *peer_id)
* Implementation of ike_sa_t.relay
*/
static status_t relay(private_ike_sa_t *this, identification_t *requester,
- chunk_t session_id, chunk_t session_key, linked_list_t *endpoints, bool response)
+ chunk_t connect_id, chunk_t connect_key, linked_list_t *endpoints, bool response)
{
- ike_p2p_t *task = ike_p2p_create(&this->public, TRUE);
- task->relay(task, requester, session_id, session_key, endpoints, response);
+ ike_me_t *task = ike_me_create(&this->public, TRUE);
+ task->relay(task, requester, connect_id, connect_key, endpoints, response);
this->task_manager->queue_task(this->task_manager, (task_t*)task);
return this->task_manager->initiate(this->task_manager);
}
@@ -965,7 +1013,7 @@ static status_t relay(private_ike_sa_t *this, identification_t *requester,
*/
static status_t initiate_mediation(private_ike_sa_t *this, peer_cfg_t *mediated_cfg)
{
- ike_p2p_t *task = ike_p2p_create(&this->public, TRUE);
+ ike_me_t *task = ike_me_create(&this->public, TRUE);
task->connect(task, mediated_cfg->get_peer_id(mediated_cfg));
this->task_manager->queue_task(this->task_manager, (task_t*)task);
return this->task_manager->initiate(this->task_manager);
@@ -975,37 +1023,54 @@ static status_t initiate_mediation(private_ike_sa_t *this, peer_cfg_t *mediated_
* Implementation of ike_sa_t.initiate_mediated
*/
static status_t initiate_mediated(private_ike_sa_t *this, host_t *me, host_t *other,
- linked_list_t *childs)
+ chunk_t connect_id)
{
- this->my_host = me->clone(me);
- this->other_host = other->clone(other);
+ set_my_host(this, me->clone(me));
+ set_other_host(this, other->clone(other));
+ chunk_free(&this->connect_id);
+ this->connect_id = chunk_clone(connect_id);
- task_t *task;
- child_cfg_t *child_cfg;
- iterator_t *iterator = childs->create_iterator(childs, TRUE);
- while (iterator->iterate(iterator, (void**)&child_cfg))
+ return this->task_manager->initiate(this->task_manager);
+}
+#endif /* ME */
+
+/**
+ * Resolve DNS host in configuration
+ */
+static void resolve_hosts(private_ike_sa_t *this)
+{
+ host_t *host;
+
+ host = host_create_from_dns(this->ike_cfg->get_my_addr(this->ike_cfg), 0,
+ IKEV2_UDP_PORT);
+ if (host)
{
- task = (task_t*)child_create_create(&this->public, child_cfg);
- this->task_manager->queue_task(this->task_manager, task);
+ set_my_host(this, host);
+ }
+ host = host_create_from_dns(this->ike_cfg->get_other_addr(this->ike_cfg),
+ this->my_host->get_family(this->my_host),
+ IKEV2_UDP_PORT);
+ if (host)
+ {
+ set_other_host(this, host);
}
- iterator->destroy(iterator);
- return this->task_manager->initiate(this->task_manager);
}
-#endif /* P2P */
/**
- * Implementation of ike_sa_t.initiate.
+ * Initiates a CHILD_SA using the appropriate reqid
*/
-static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
+static status_t initiate_with_reqid(private_ike_sa_t *this, child_cfg_t *child_cfg, u_int32_t reqid)
{
task_t *task;
if (this->state == IKE_CREATED)
{
+ resolve_hosts(this);
+
if (this->other_host->is_anyaddr(this->other_host)
-#ifdef P2P
+#ifdef ME
&& !this->peer_cfg->get_mediated_by(this->peer_cfg)
-#endif /* P2P */
+#endif /* ME */
)
{
child_cfg->destroy(child_cfg);
@@ -1020,10 +1085,12 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_natd_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
- task = (task_t*)ike_cert_create(&this->public, TRUE);
+ task = (task_t*)ike_cert_pre_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_auth_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
+ task = (task_t*)ike_cert_post_create(&this->public, TRUE);
+ this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_config_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
@@ -1033,50 +1100,65 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
task = (task_t*)ike_mobike_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
}
-#ifdef P2P
- task = (task_t*)ike_p2p_create(&this->public, TRUE);
+#ifdef ME
+ task = (task_t*)ike_me_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
-#endif /* P2P */
+#endif /* ME */
}
-#ifdef P2P
- if (this->peer_cfg->get_mediated_by(this->peer_cfg))
- {
- /* mediated connection, initiate mediation process */
- job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id, child_cfg);
- child_cfg->destroy(child_cfg);
- charon->processor->queue_job(charon->processor, job);
- return SUCCESS;
- }
- else if (this->peer_cfg->is_mediation(this->peer_cfg))
+#ifdef ME
+ if (this->peer_cfg->is_mediation(this->peer_cfg))
{
+ /* mediation connection */
if (this->state == IKE_ESTABLISHED)
{ /* FIXME: we should try to find a better solution to this */
SIG(CHILD_UP_SUCCESS, "mediation connection is already up and running");
}
+ DESTROY_IF(child_cfg);
}
else
-#endif /* P2P */
+#endif /* ME */
{
/* normal IKE_SA with CHILD_SA */
task = (task_t*)child_create_create(&this->public, child_cfg);
child_cfg->destroy(child_cfg);
+ if (reqid)
+ {
+ child_create_t *child_create = (child_create_t*)task;
+ child_create->use_reqid(child_create, reqid);
+ }
this->task_manager->queue_task(this->task_manager, task);
+
+#ifdef ME
+ if (this->peer_cfg->get_mediated_by(this->peer_cfg))
+ {
+ /* mediated connection, initiate mediation process */
+ job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id);
+ charon->processor->queue_job(charon->processor, job);
+ return SUCCESS;
+ }
+#endif /* ME */
}
return this->task_manager->initiate(this->task_manager);
}
/**
+ * Implementation of ike_sa_t.initiate.
+ */
+static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
+{
+ return initiate_with_reqid(this, child_cfg, 0);
+}
+
+/**
* Implementation of ike_sa_t.acquire.
*/
static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
-{ /* FIXME: P2P-NAT-T */
+{
child_cfg_t *child_cfg;
iterator_t *iterator;
child_sa_t *current, *child_sa = NULL;
- task_t *task;
- child_create_t *child_create;
if (this->state == IKE_DELETING)
{
@@ -1105,34 +1187,10 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
return FAILED;
}
-
- if (this->state == IKE_CREATED)
- {
- task = (task_t*)ike_init_create(&this->public, TRUE, NULL);
- this->task_manager->queue_task(this->task_manager, task);
- task = (task_t*)ike_natd_create(&this->public, TRUE);
- this->task_manager->queue_task(this->task_manager, task);
- task = (task_t*)ike_cert_create(&this->public, TRUE);
- this->task_manager->queue_task(this->task_manager, task);
- task = (task_t*)ike_auth_create(&this->public, TRUE);
- this->task_manager->queue_task(this->task_manager, task);
- task = (task_t*)ike_config_create(&this->public, TRUE);
- this->task_manager->queue_task(this->task_manager, task);
- task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
- this->task_manager->queue_task(this->task_manager, task);
- if (this->peer_cfg->use_mobike(this->peer_cfg))
- {
- task = (task_t*)ike_mobike_create(&this->public, TRUE);
- this->task_manager->queue_task(this->task_manager, task);
- }
- }
-
child_cfg = child_sa->get_config(child_sa);
- child_create = child_create_create(&this->public, child_cfg);
- child_create->use_reqid(child_create, reqid);
- this->task_manager->queue_task(this->task_manager, (task_t*)child_create);
+ child_cfg->get_ref(child_cfg);
- return this->task_manager->initiate(this->task_manager);
+ return initiate_with_reqid(this, child_cfg, reqid);
}
/**
@@ -1175,10 +1233,12 @@ static status_t route(private_ike_sa_t *this, child_cfg_t *child_cfg)
default:
break;
}
+
+ resolve_hosts(this);
/* install kernel policies */
child_sa = child_sa_create(this->my_host, this->other_host, this->my_id,
- this->other_id, child_cfg, FALSE, 0);
+ this->other_id, child_cfg, 0, FALSE);
me = this->my_host;
if (this->my_virtual_ip)
{
@@ -1394,145 +1454,6 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
}
/**
- * Implementation of ike_sa_t.retransmit.
- */
-static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id)
-{ /* FIXME: P2P-NAT-T */
- this->time.outbound = time(NULL);
- if (this->task_manager->retransmit(this->task_manager, message_id) != SUCCESS)
- {
- child_cfg_t *child_cfg;
- child_sa_t* child_sa;
- linked_list_t *to_route, *to_restart;
- iterator_t *iterator;
-
- /* send a proper signal to brief interested bus listeners */
- switch (this->state)
- {
- case IKE_CONNECTING:
- {
- /* retry IKE_SA_INIT if we have multiple keyingtries */
- u_int32_t tries = this->peer_cfg->get_keyingtries(this->peer_cfg);
- this->keyingtry++;
- if (tries == 0 || tries > this->keyingtry)
- {
- SIG(IKE_UP_FAILED, "peer not responding, trying again "
- "(%d/%d) in background ", this->keyingtry + 1, tries);
- reset(this);
- return this->task_manager->initiate(this->task_manager);
- }
- SIG(IKE_UP_FAILED, "establishing IKE_SA failed, peer not responding");
- break;
- }
- case IKE_REKEYING:
- SIG(IKE_REKEY_FAILED, "rekeying IKE_SA failed, peer not responding");
- break;
- case IKE_DELETING:
- SIG(IKE_DOWN_FAILED, "proper IKE_SA delete failed, peer not responding");
- break;
- default:
- break;
- }
-
- /* summarize how we have to handle each child */
- to_route = linked_list_create();
- to_restart = linked_list_create();
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&child_sa))
- {
- child_cfg = child_sa->get_config(child_sa);
-
- if (child_sa->get_state(child_sa) == CHILD_ROUTED)
- {
- /* reroute routed CHILD_SAs */
- to_route->insert_last(to_route, child_cfg);
- }
- else
- {
- /* use DPD action for established CHILD_SAs */
- switch (this->peer_cfg->get_dpd_action(this->peer_cfg))
- {
- case DPD_ROUTE:
- to_route->insert_last(to_route, child_cfg);
- break;
- case DPD_RESTART:
- to_restart->insert_last(to_restart, child_cfg);
- break;
- default:
- break;
- }
- }
- }
- iterator->destroy(iterator);
-
- /* create a new IKE_SA if we have to route or to restart */
- if (to_route->get_count(to_route) || to_restart->get_count(to_restart))
- {
- private_ike_sa_t *new;
- task_t *task;
-
- new = (private_ike_sa_t*)charon->ike_sa_manager->checkout_new(
- charon->ike_sa_manager, TRUE);
-
- set_peer_cfg(new, this->peer_cfg);
- /* use actual used host, not the wildcarded one in config */
- new->other_host->destroy(new->other_host);
- new->other_host = this->other_host->clone(this->other_host);
- /* reset port to 500, but only if peer is not NATed */
- if (!has_condition(this, COND_NAT_THERE))
- {
- new->other_host->set_port(new->other_host, IKEV2_UDP_PORT);
- }
- /* take over virtual ip, as we need it for a proper route */
- if (this->my_virtual_ip)
- {
- set_virtual_ip(new, TRUE, this->my_virtual_ip);
- }
-
- /* install routes */
- while (to_route->remove_last(to_route, (void**)&child_cfg) == SUCCESS)
- {
- route(new, child_cfg);
- }
-
- /* restart children */
- if (to_restart->get_count(to_restart))
- {
- task = (task_t*)ike_init_create(&new->public, TRUE, NULL);
- new->task_manager->queue_task(new->task_manager, task);
- task = (task_t*)ike_natd_create(&new->public, TRUE);
- new->task_manager->queue_task(new->task_manager, task);
- task = (task_t*)ike_cert_create(&new->public, TRUE);
- new->task_manager->queue_task(new->task_manager, task);
- task = (task_t*)ike_config_create(&new->public, TRUE);
- new->task_manager->queue_task(new->task_manager, task);
- task = (task_t*)ike_auth_create(&new->public, TRUE);
- new->task_manager->queue_task(new->task_manager, task);
-
- while (to_restart->remove_last(to_restart, (void**)&child_cfg) == SUCCESS)
- {
- task = (task_t*)child_create_create(&new->public, child_cfg);
- new->task_manager->queue_task(new->task_manager, task);
- }
- task = (task_t*)ike_auth_lifetime_create(&new->public, TRUE);
- new->task_manager->queue_task(new->task_manager, task);
- if (this->peer_cfg->use_mobike(this->peer_cfg))
- {
- task = (task_t*)ike_mobike_create(&new->public, TRUE);
- new->task_manager->queue_task(new->task_manager, task);
- }
- new->task_manager->initiate(new->task_manager);
- }
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, &new->public);
- }
- to_route->destroy(to_route);
- to_restart->destroy(to_restart);
- return DESTROY_ME;
- }
- return SUCCESS;
-}
-
-/**
* Implementation of ike_sa_t.get_prf.
*/
static prf_t *get_prf(private_ike_sa_t *this)
@@ -1607,22 +1528,6 @@ static void set_other_id(private_ike_sa_t *this, identification_t *other)
}
/**
- * Implementation of ike_sa_t.get_other_ca.
- */
-static ca_info_t* get_other_ca(private_ike_sa_t *this)
-{
- return this->other_ca;
-}
-
-/**
- * Implementation of ike_sa_t.set_other_ca.
- */
-static void set_other_ca(private_ike_sa_t *this, ca_info_t *other_ca)
-{
- this->other_ca = other_ca;
-}
-
-/**
* Implementation of ike_sa_t.derive_keys.
*/
static status_t derive_keys(private_ike_sa_t *this,
@@ -1631,9 +1536,8 @@ static status_t derive_keys(private_ike_sa_t *this,
bool initiator, prf_t *child_prf, prf_t *old_prf)
{
prf_plus_t *prf_plus;
- chunk_t skeyseed, key, nonces, prf_plus_seed;
- algorithm_t *algo;
- size_t key_size;
+ chunk_t skeyseed, key, full_nonce, fixed_nonce, prf_plus_seed;
+ u_int16_t alg, key_size;
crypter_t *crypter_i, *crypter_r;
signer_t *signer_i, *signer_r;
u_int8_t spi_i_buf[sizeof(u_int64_t)], spi_r_buf[sizeof(u_int64_t)];
@@ -1641,24 +1545,42 @@ static status_t derive_keys(private_ike_sa_t *this,
chunk_t spi_r = chunk_from_buf(spi_r_buf);
/* Create SAs general purpose PRF first, we may use it here */
- if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo))
+ if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL))
{
- DBG1(DBG_IKE, "key derivation failed: no PSEUDO_RANDOM_FUNCTION");;
+ DBG1(DBG_IKE, "no %N selected",
+ transform_type_names, PSEUDO_RANDOM_FUNCTION);
return FAILED;
}
- this->prf = prf_create(algo->algorithm);
+ this->prf = lib->crypto->create_prf(lib->crypto, alg);
if (this->prf == NULL)
{
- DBG1(DBG_IKE, "key derivation failed: PSEUDO_RANDOM_FUNCTION "
- "%N not supported!", pseudo_random_function_names, algo->algorithm);
+ DBG1(DBG_IKE, "%N %N not supported!",
+ transform_type_names, PSEUDO_RANDOM_FUNCTION,
+ pseudo_random_function_names, alg);
return FAILED;
}
-
DBG4(DBG_IKE, "shared Diffie Hellman secret %B", &secret);
- nonces = chunk_cat("cc", nonce_i, nonce_r);
+ /* full nonce is used as seed for PRF+ ... */
+ full_nonce = chunk_cat("cc", nonce_i, nonce_r);
+ /* but the PRF may need a fixed key which only uses the first bytes of
+ * the nonces. */
+ switch (alg)
+ {
+ case PRF_AES128_XCBC:
+ /* while rfc4434 defines variable keys for AES-XCBC, rfc3664 does
+ * not and therefore fixed key semantics apply to XCBC for key
+ * derivation. */
+ nonce_i.len = min(nonce_i.len, this->prf->get_key_size(this->prf)/2);
+ nonce_r.len = min(nonce_r.len, this->prf->get_key_size(this->prf)/2);
+ break;
+ default:
+ /* all other algorithms use variable key length, full nonce */
+ break;
+ }
+ fixed_nonce = chunk_cat("cc", nonce_i, nonce_r);
*((u_int64_t*)spi_i.ptr) = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
*((u_int64_t*)spi_r.ptr) = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
- prf_plus_seed = chunk_cat("ccc", nonces, spi_i, spi_r);
+ prf_plus_seed = chunk_cat("ccc", full_nonce, spi_i, spi_r);
/* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
*
@@ -1667,7 +1589,7 @@ static status_t derive_keys(private_ike_sa_t *this,
if (child_prf == NULL) /* not rekeying */
{
/* SKEYSEED = prf(Ni | Nr, g^ir) */
- this->prf->set_key(this->prf, nonces);
+ this->prf->set_key(this->prf, fixed_nonce);
this->prf->allocate_bytes(this->prf, secret, &skeyseed);
DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed);
this->prf->set_key(this->prf, skeyseed);
@@ -1679,7 +1601,7 @@ static status_t derive_keys(private_ike_sa_t *this,
{
/* SKEYSEED = prf(SK_d (old), [g^ir (new)] | Ni | Nr)
* use OLD SAs PRF functions for both prf_plus and prf */
- secret = chunk_cat("mc", secret, nonces);
+ secret = chunk_cat("mc", secret, full_nonce);
child_prf->allocate_bytes(child_prf, secret, &skeyseed);
DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed);
old_prf->set_key(old_prf, skeyseed);
@@ -1687,14 +1609,15 @@ static status_t derive_keys(private_ike_sa_t *this,
chunk_free(&secret);
prf_plus = prf_plus_create(old_prf, prf_plus_seed);
}
- chunk_free(&nonces);
+ chunk_free(&full_nonce);
+ chunk_free(&fixed_nonce);
chunk_free(&prf_plus_seed);
/* KEYMAT = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr */
/* SK_d is used for generating CHILD_SA key mat => child_prf */
- proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo);
- this->child_prf = prf_create(algo->algorithm);
+ proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL);
+ this->child_prf = lib->crypto->create_prf(lib->crypto, alg);
key_size = this->child_prf->get_key_size(this->child_prf);
prf_plus->allocate_bytes(prf_plus, key_size, &key);
DBG4(DBG_IKE, "Sk_d secret %B", &key);
@@ -1702,17 +1625,20 @@ static status_t derive_keys(private_ike_sa_t *this,
chunk_free(&key);
/* SK_ai/SK_ar used for integrity protection => signer_in/signer_out */
- if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &algo))
+ if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL))
{
- DBG1(DBG_IKE, "key derivation failed: no INTEGRITY_ALGORITHM");
+ DBG1(DBG_IKE, "no %N selected",
+ transform_type_names, INTEGRITY_ALGORITHM);
return FAILED;
}
- signer_i = signer_create(algo->algorithm);
- signer_r = signer_create(algo->algorithm);
+ signer_i = lib->crypto->create_signer(lib->crypto, alg);
+ signer_r = lib->crypto->create_signer(lib->crypto, alg);
if (signer_i == NULL || signer_r == NULL)
{
- DBG1(DBG_IKE, "key derivation failed: INTEGRITY_ALGORITHM "
- "%N not supported!", integrity_algorithm_names ,algo->algorithm);
+ DBG1(DBG_IKE, "%N %N not supported!",
+ transform_type_names, INTEGRITY_ALGORITHM,
+ integrity_algorithm_names ,alg);
+ prf_plus->destroy(prf_plus);
return FAILED;
}
key_size = signer_i->get_key_size(signer_i);
@@ -1739,18 +1665,21 @@ static status_t derive_keys(private_ike_sa_t *this,
}
/* SK_ei/SK_er used for encryption => crypter_in/crypter_out */
- if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &algo))
+ if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &key_size))
{
- DBG1(DBG_IKE, "key derivation failed: no ENCRYPTION_ALGORITHM");
+ DBG1(DBG_IKE, "no %N selected",
+ transform_type_names, ENCRYPTION_ALGORITHM);
+ prf_plus->destroy(prf_plus);
return FAILED;
}
- crypter_i = crypter_create(algo->algorithm, algo->key_size / 8);
- crypter_r = crypter_create(algo->algorithm, algo->key_size / 8);
+ crypter_i = lib->crypto->create_crypter(lib->crypto, alg, key_size / 8);
+ crypter_r = lib->crypto->create_crypter(lib->crypto, alg, key_size / 8);
if (crypter_i == NULL || crypter_r == NULL)
{
- DBG1(DBG_IKE, "key derivation failed: ENCRYPTION_ALGORITHM "
- "%N (key size %d) not supported!",
- encryption_algorithm_names, algo->algorithm, algo->key_size);
+ DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
+ transform_type_names, ENCRYPTION_ALGORITHM,
+ encryption_algorithm_names, alg, key_size);
+ prf_plus->destroy(prf_plus);
return FAILED;
}
key_size = crypter_i->get_key_size(crypter_i);
@@ -1806,6 +1735,23 @@ static status_t derive_keys(private_ike_sa_t *this,
}
/**
+ * Implementation of ike_sa_t.get_proposal.
+ */
+static char* get_proposal(private_ike_sa_t *this)
+{
+ return this->selected_proposal;
+}
+
+/**
+ * Implementation of ike_sa_t.set_proposal.
+ */
+static void set_proposal(private_ike_sa_t *this, char *proposal)
+{
+ free(this->selected_proposal);
+ this->selected_proposal = strdup(proposal);
+}
+
+/**
* Implementation of ike_sa_t.add_child_sa.
*/
static void add_child_sa(private_ike_sa_t *this, child_sa_t *child_sa)
@@ -1944,9 +1890,9 @@ static status_t rekey(private_ike_sa_t *this)
}
/**
- * Implementation of ike_sa_t.reestablish
+ * Implementation of ike_sa_t.reauth
*/
-static status_t reestablish(private_ike_sa_t *this)
+static status_t reauth(private_ike_sa_t *this)
{
task_t *task;
@@ -1957,7 +1903,12 @@ static status_t reestablish(private_ike_sa_t *this)
{
DBG1(DBG_IKE, "initiator did not reauthenticate as requested");
if (this->other_virtual_ip != NULL ||
- has_condition(this, COND_EAP_AUTHENTICATED))
+ has_condition(this, COND_EAP_AUTHENTICATED)
+#ifdef ME
+ /* if we are mediation server we too cannot reauth the IKE_SA */
+ || this->is_mediation_server
+#endif /* ME */
+ )
{
time_t now = time(NULL);
@@ -1976,6 +1927,176 @@ static status_t reestablish(private_ike_sa_t *this)
}
/**
+ * Implementation of ike_sa_t.reestablish
+ */
+static status_t reestablish(private_ike_sa_t *this)
+{
+ ike_sa_t *new;
+ host_t *host;
+ action_t action;
+ iterator_t *iterator;
+ child_sa_t *child_sa;
+ child_cfg_t *child_cfg;
+ bool required = FALSE;
+ status_t status = FAILED;
+
+ /* check if we have children to keep up at all*/
+ iterator = create_child_sa_iterator(this);
+ while (iterator->iterate(iterator, (void**)&child_sa))
+ {
+ child_cfg = child_sa->get_config(child_sa);
+ if (this->state == IKE_DELETING)
+ {
+ action = child_cfg->get_close_action(child_cfg);
+ }
+ else
+ {
+ action = child_cfg->get_dpd_action(child_cfg);
+ }
+ switch (action)
+ {
+ case ACTION_RESTART:
+ case ACTION_ROUTE:
+ required = TRUE;
+ default:
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+#ifdef ME
+ /* we initiate the new IKE_SA of the mediation connection without CHILD_SA */
+ if (this->peer_cfg->is_mediation(this->peer_cfg))
+ {
+ required = TRUE;
+ }
+#endif /* ME */
+ if (!required)
+ {
+ return FAILED;
+ }
+
+ /* check if we are able to reestablish this IKE_SA */
+ if (!this->ike_initiator &&
+ (this->other_virtual_ip != NULL ||
+ has_condition(this, COND_EAP_AUTHENTICATED)
+#ifdef ME
+ || this->is_mediation_server
+#endif /* ME */
+ ))
+ {
+ DBG1(DBG_IKE, "unable to reestablish IKE_SA due asymetric setup");
+ return FAILED;
+ }
+
+ new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, TRUE);
+ new->set_peer_cfg(new, this->peer_cfg);
+ host = this->other_host;
+ new->set_other_host(new, host->clone(host));
+ host = this->my_host;
+ new->set_my_host(new, host->clone(host));
+ /* if we already have a virtual IP, we reuse it */
+ host = this->my_virtual_ip;
+ if (host)
+ {
+ new->set_virtual_ip(new, TRUE, host);
+ }
+
+#ifdef ME
+ if (this->peer_cfg->is_mediation(this->peer_cfg))
+ {
+ status = new->initiate(new, NULL);
+ }
+ else
+#endif /* ME */
+ {
+ iterator = create_child_sa_iterator(this);
+ while (iterator->iterate(iterator, (void**)&child_sa))
+ {
+ child_cfg = child_sa->get_config(child_sa);
+ if (this->state == IKE_DELETING)
+ {
+ action = child_cfg->get_close_action(child_cfg);
+ }
+ else
+ {
+ action = child_cfg->get_dpd_action(child_cfg);
+ }
+ switch (action)
+ {
+ case ACTION_RESTART:
+ DBG1(DBG_IKE, "restarting CHILD_SA %s",
+ child_cfg->get_name(child_cfg));
+ child_cfg->get_ref(child_cfg);
+ status = new->initiate(new, child_cfg);
+ break;
+ case ACTION_ROUTE:
+ status = new->route(new, child_cfg);
+ break;
+ default:
+ continue;
+ }
+ if (status == DESTROY_ME)
+ {
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+ }
+
+ if (status == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
+ return FAILED;
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
+ return SUCCESS;
+ }
+}
+
+/**
+ * Implementation of ike_sa_t.retransmit.
+ */
+static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id)
+{
+ this->time.outbound = time(NULL);
+ if (this->task_manager->retransmit(this->task_manager, message_id) != SUCCESS)
+ {
+ /* send a proper signal to brief interested bus listeners */
+ switch (this->state)
+ {
+ case IKE_CONNECTING:
+ {
+ /* retry IKE_SA_INIT if we have multiple keyingtries */
+ u_int32_t tries = this->peer_cfg->get_keyingtries(this->peer_cfg);
+ this->keyingtry++;
+ if (tries == 0 || tries > this->keyingtry)
+ {
+ SIG(IKE_UP_FAILED, "peer not responding, trying again "
+ "(%d/%d) in background ", this->keyingtry + 1, tries);
+ reset(this);
+ return this->task_manager->initiate(this->task_manager);
+ }
+ SIG(IKE_UP_FAILED, "establishing IKE_SA failed, peer not responding");
+ break;
+ }
+ case IKE_DELETING:
+ SIG(IKE_DOWN_FAILED, "proper IKE_SA delete failed, peer not responding");
+ break;
+ case IKE_REKEYING:
+ SIG(IKE_REKEY_FAILED, "rekeying IKE_SA failed, peer not responding");
+ /* FALL */
+ default:
+ reestablish(this);
+ break;
+ }
+ return DESTROY_ME;
+ }
+ return SUCCESS;
+}
+
+/**
* Implementation of ike_sa_t.set_auth_lifetime.
*/
static void set_auth_lifetime(private_ike_sa_t *this, u_int32_t lifetime)
@@ -2009,6 +2130,14 @@ static status_t roam(private_ike_sa_t *this, bool address)
host_t *me, *other;
ike_mobike_t *mobike;
+ switch (this->state)
+ {
+ case IKE_CREATED:
+ case IKE_DELETING:
+ return SUCCESS;
+ default:
+ break;
+ }
/* responder just updates the peer about changed address config */
if (!this->ike_sa_id->is_initiator(this->ike_sa_id))
{
@@ -2048,9 +2177,9 @@ static status_t roam(private_ike_sa_t *this, bool address)
this->task_manager->queue_task(this->task_manager, (task_t*)mobike);
return this->task_manager->initiate(this->task_manager);
}
- DBG1(DBG_IKE, "reestablishing IKE_SA due address change");
- /* ... reestablish if not */
- return reestablish(this);
+ DBG1(DBG_IKE, "reauthenticating IKE_SA due address change");
+ /* ... reauth if not */
+ return reauth(this);
}
/**
@@ -2097,6 +2226,18 @@ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other)
{
send_keepalive(this);
}
+
+#ifdef ME
+ if (other->is_mediation_server)
+ {
+ act_as_mediation_server(this);
+ }
+ else if (other->server_reflexive_host)
+ {
+ this->server_reflexive_host = other->server_reflexive_host->clone(
+ other->server_reflexive_host);
+ }
+#endif /* ME */
/* adopt all children */
while (other->child_sas->remove_last(other->child_sas,
@@ -2270,6 +2411,8 @@ static void destroy(private_ike_sa_t *this)
{
this->child_sas->destroy_offset(this->child_sas, offsetof(child_sa_t, destroy));
+ this->task_manager->destroy(this->task_manager);
+
DESTROY_IF(this->crypter_in);
DESTROY_IF(this->crypter_out);
DESTROY_IF(this->signer_in);
@@ -2278,6 +2421,7 @@ static void destroy(private_ike_sa_t *this)
DESTROY_IF(this->child_prf);
chunk_free(&this->skp_verify);
chunk_free(&this->skp_build);
+ free(this->selected_proposal);
if (this->my_virtual_ip)
{
@@ -2285,22 +2429,30 @@ static void destroy(private_ike_sa_t *this)
this->my_virtual_ip);
this->my_virtual_ip->destroy(this->my_virtual_ip);
}
- DESTROY_IF(this->other_virtual_ip);
+ if (this->other_virtual_ip)
+ {
+ if (this->peer_cfg && this->peer_cfg->get_pool(this->peer_cfg))
+ {
+ charon->attributes->release_address(charon->attributes,
+ this->peer_cfg->get_pool(this->peer_cfg),
+ this->other_virtual_ip);
+ }
+ this->other_virtual_ip->destroy(this->other_virtual_ip);
+ }
remove_dns_servers(this);
this->dns_servers->destroy_offset(this->dns_servers,
offsetof(host_t, destroy));
this->additional_addresses->destroy_offset(this->additional_addresses,
offsetof(host_t, destroy));
-#ifdef P2P
- if (this->peer_cfg && this->peer_cfg->is_mediation(this->peer_cfg) &&
- !this->ike_sa_id->is_initiator(this->ike_sa_id))
+#ifdef ME
+ if (this->is_mediation_server)
{
- /* mediation server */
charon->mediation_manager->remove(charon->mediation_manager, this->ike_sa_id);
}
DESTROY_IF(this->server_reflexive_host);
-#endif /* P2P */
+ chunk_free(&this->connect_id);
+#endif /* ME */
DESTROY_IF(this->my_host);
DESTROY_IF(this->other_host);
@@ -2309,9 +2461,10 @@ static void destroy(private_ike_sa_t *this)
DESTROY_IF(this->ike_cfg);
DESTROY_IF(this->peer_cfg);
+ DESTROY_IF(this->my_auth);
+ DESTROY_IF(this->other_auth);
this->ike_sa_id->destroy(this->ike_sa_id);
- this->task_manager->destroy(this->task_manager);
free(this);
}
@@ -2337,6 +2490,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.set_ike_cfg = (void (*)(ike_sa_t*,ike_cfg_t*))set_ike_cfg;
this->public.get_peer_cfg = (peer_cfg_t* (*)(ike_sa_t*))get_peer_cfg;
this->public.set_peer_cfg = (void (*)(ike_sa_t*,peer_cfg_t*))set_peer_cfg;
+ this->public.get_my_auth = (auth_info_t*(*)(ike_sa_t*))get_my_auth;
+ this->public.get_other_auth = (auth_info_t*(*)(ike_sa_t*))get_other_auth;
this->public.get_id = (ike_sa_id_t* (*)(ike_sa_t*)) get_id;
this->public.get_my_host = (host_t* (*)(ike_sa_t*)) get_my_host;
this->public.set_my_host = (void (*)(ike_sa_t*,host_t*)) set_my_host;
@@ -2347,14 +2502,13 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.set_my_id = (void (*)(ike_sa_t*,identification_t*)) set_my_id;
this->public.get_other_id = (identification_t* (*)(ike_sa_t*)) get_other_id;
this->public.set_other_id = (void (*)(ike_sa_t*,identification_t*)) set_other_id;
- this->public.get_other_ca = (ca_info_t* (*)(ike_sa_t*)) get_other_ca;
- this->public.set_other_ca = (void (*)(ike_sa_t*,ca_info_t*)) set_other_ca;
this->public.enable_extension = (void(*)(ike_sa_t*, ike_extension_t extension))enable_extension;
this->public.supports_extension = (bool(*)(ike_sa_t*, ike_extension_t extension))supports_extension;
this->public.set_condition = (void (*)(ike_sa_t*, ike_condition_t,bool)) set_condition;
this->public.has_condition = (bool (*)(ike_sa_t*,ike_condition_t)) has_condition;
this->public.set_pending_updates = (void(*)(ike_sa_t*, u_int32_t updates))set_pending_updates;
this->public.get_pending_updates = (u_int32_t(*)(ike_sa_t*))get_pending_updates;
+ this->public.is_ike_initiator = (bool (*)(ike_sa_t*))is_ike_initiator;
this->public.create_additional_address_iterator = (iterator_t*(*)(ike_sa_t*))create_additional_address_iterator;
this->public.add_additional_address = (void(*)(ike_sa_t*, host_t *host))add_additional_address;
this->public.retransmit = (status_t (*)(ike_sa_t *, u_int32_t)) retransmit;
@@ -2367,6 +2521,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.get_skp_verify = (chunk_t (*)(ike_sa_t *)) get_skp_verify;
this->public.get_skp_build = (chunk_t (*)(ike_sa_t *)) get_skp_build;
this->public.derive_keys = (status_t (*)(ike_sa_t *,proposal_t*,chunk_t,chunk_t,chunk_t,bool,prf_t*,prf_t*)) derive_keys;
+ this->public.get_proposal = (char* (*)(ike_sa_t*)) get_proposal;
+ this->public.set_proposal = (void (*)(ike_sa_t*,char*)) set_proposal;
this->public.add_child_sa = (void (*)(ike_sa_t*,child_sa_t*)) add_child_sa;
this->public.get_child_sa = (child_sa_t* (*)(ike_sa_t*,protocol_id_t,u_int32_t,bool)) get_child_sa;
this->public.create_child_sa_iterator = (iterator_t* (*)(ike_sa_t*)) create_child_sa_iterator;
@@ -2374,6 +2530,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.delete_child_sa = (status_t (*)(ike_sa_t*,protocol_id_t,u_int32_t)) delete_child_sa;
this->public.destroy_child_sa = (status_t (*)(ike_sa_t*,protocol_id_t,u_int32_t))destroy_child_sa;
this->public.rekey = (status_t (*)(ike_sa_t*))rekey;
+ this->public.reauth = (status_t (*)(ike_sa_t*))reauth;
this->public.reestablish = (status_t (*)(ike_sa_t*))reestablish;
this->public.set_auth_lifetime = (void(*)(ike_sa_t*, u_int32_t lifetime))set_auth_lifetime;
this->public.roam = (status_t(*)(ike_sa_t*,bool))roam;
@@ -2384,26 +2541,28 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.set_virtual_ip = (void (*)(ike_sa_t*,bool,host_t*))set_virtual_ip;
this->public.get_virtual_ip = (host_t* (*)(ike_sa_t*,bool))get_virtual_ip;
this->public.add_dns_server = (void (*)(ike_sa_t*,host_t*))add_dns_server;
-#ifdef P2P
+#ifdef ME
+ this->public.act_as_mediation_server = (void (*)(ike_sa_t*)) act_as_mediation_server;
this->public.get_server_reflexive_host = (host_t* (*)(ike_sa_t*)) get_server_reflexive_host;
this->public.set_server_reflexive_host = (void (*)(ike_sa_t*,host_t*)) set_server_reflexive_host;
+ this->public.get_connect_id = (chunk_t (*)(ike_sa_t*)) get_connect_id;
this->public.initiate_mediation = (status_t (*)(ike_sa_t*,peer_cfg_t*)) initiate_mediation;
- this->public.initiate_mediated = (status_t (*)(ike_sa_t*,host_t*,host_t*,linked_list_t*)) initiate_mediated;
+ this->public.initiate_mediated = (status_t (*)(ike_sa_t*,host_t*,host_t*,chunk_t)) initiate_mediated;
this->public.relay = (status_t (*)(ike_sa_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool)) relay;
this->public.callback = (status_t (*)(ike_sa_t*,identification_t*)) callback;
this->public.respond = (status_t (*)(ike_sa_t*,identification_t*,chunk_t)) respond;
-#endif /* P2P */
+#endif /* ME */
/* initialize private fields */
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
this->child_sas = linked_list_create();
- this->my_host = host_create_any(AF_INET);
- this->other_host = host_create_any(AF_INET);
+ this->my_host = host_create_from_string("0.0.0.0", IKEV2_UDP_PORT);
+ this->other_host = host_create_from_string("0.0.0.0", IKEV2_UDP_PORT);
this->my_id = identification_create_from_encoding(ID_ANY, chunk_empty);
this->other_id = identification_create_from_encoding(ID_ANY, chunk_empty);
- this->other_ca = NULL;
this->extensions = 0;
this->conditions = 0;
+ this->selected_proposal = NULL;
this->crypter_in = NULL;
this->crypter_out = NULL;
this->signer_in = NULL;
@@ -2420,6 +2579,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->time.delete = 0;
this->ike_cfg = NULL;
this->peer_cfg = NULL;
+ this->my_auth = auth_info_create();
+ this->other_auth = auth_info_create();
this->task_manager = task_manager_create(&this->public);
this->unique_id = ++unique_id;
this->my_virtual_ip = NULL;
@@ -2429,9 +2590,11 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->pending_updates = 0;
this->keyingtry = 0;
this->ike_initiator = FALSE;
-#ifdef P2P
+#ifdef ME
+ this->is_mediation_server = FALSE;
this->server_reflexive_host = NULL;
-#endif /* P2P */
+ this->connect_id = chunk_empty;
+#endif /* ME */
return &this->public;
}
diff --git a/src/charon/sa/ike_sa.h b/src/charon/sa/ike_sa.h
index 975447d9c..0935f5d6b 100644
--- a/src/charon/sa/ike_sa.h
+++ b/src/charon/sa/ike_sa.h
@@ -1,12 +1,5 @@
-/**
- * @file ike_sa.h
- *
- * @brief Interface of ike_sa_t.
- *
- */
-
/*
- * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2006-2008 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -21,6 +14,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_sa.h 4086 2008-06-22 11:24:33Z andreas $
+ */
+
+/**
+ * @defgroup ike_sa ike_sa
+ * @{ @ingroup sa
*/
#ifndef IKE_SA_H_
@@ -38,44 +38,35 @@ typedef struct ike_sa_t ike_sa_t;
#include <sa/ike_sa_id.h>
#include <sa/child_sa.h>
#include <sa/tasks/task.h>
-#include <utils/randomizer.h>
#include <crypto/prfs/prf.h>
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
-#include <crypto/ca.h>
#include <config/peer_cfg.h>
#include <config/ike_cfg.h>
+#include <credentials/auth_info.h>
/**
* Timeout in milliseconds after that a half open IKE_SA gets deleted.
- *
- * @ingroup sa
*/
#define HALF_OPEN_IKE_SA_TIMEOUT 30000
/**
* Interval to send keepalives when NATed, in seconds.
- *
- * @ingroup sa
*/
#define KEEPALIVE_INTERVAL 20
/**
* After which time rekeying should be retried if it failed, in seconds.
- *
- * @ingroup sa
*/
#define RETRY_INTERVAL 30
/**
* Jitter to subtract from RETRY_INTERVAL to randomize rekey retry.
- *
- * @ingroup sa
*/
#define RETRY_JITTER 20
/**
- * @brief Extensions (or optional features) the peer supports
+ * Extensions (or optional features) the peer supports
*/
enum ike_extension_t {
@@ -88,10 +79,15 @@ enum ike_extension_t {
* peer supports MOBIKE (RFC4555)
*/
EXT_MOBIKE = (1<<1),
+
+ /**
+ * peer supports HTTP cert lookups as specified in RFC4306
+ */
+ EXT_HASH_AND_URL = (1<<2),
};
/**
- * @brief Conditions of an IKE_SA, change during its lifetime
+ * Conditions of an IKE_SA, change during its lifetime
*/
enum ike_condition_t {
@@ -119,6 +115,11 @@ enum ike_condition_t {
* peer has ben authenticated using EAP
*/
COND_EAP_AUTHENTICATED = (1<<4),
+
+ /**
+ * received a certificate request from the peer
+ */
+ COND_CERTREQ_SEEN = (1<<5),
};
/**
@@ -138,7 +139,7 @@ enum statistic_t {
};
/**
- * @brief State of an IKE_SA.
+ * State of an IKE_SA.
*
* An IKE_SA passes various states in its lifetime. A newly created
* SA is in the state CREATED.
@@ -173,8 +174,6 @@ enum statistic_t {
X
/ \
@endverbatim
- *
- * @ingroup sa
*/
enum ike_sa_state_t {
@@ -210,365 +209,342 @@ enum ike_sa_state_t {
extern enum_name_t *ike_sa_state_names;
/**
- * @brief Class ike_sa_t representing an IKE_SA.
+ * Class ike_sa_t representing an IKE_SA.
*
* An IKE_SA contains crypto information related to a connection
* with a peer. It contains multiple IPsec CHILD_SA, for which
* it is responsible. All traffic is handled by an IKE_SA, using
* the task manager and its tasks.
- *
- * @b Constructors:
- * - ike_sa_create()
- *
- * @ingroup sa
*/
struct ike_sa_t {
/**
- * @brief Get the id of the SA.
+ * Get the id of the SA.
*
* Returned ike_sa_id_t object is not getting cloned!
*
- * @param this calling object
* @return ike_sa's ike_sa_id_t
*/
ike_sa_id_t* (*get_id) (ike_sa_t *this);
/**
- * @brief Get the numerical ID uniquely defining this IKE_SA.
+ * Get the numerical ID uniquely defining this IKE_SA.
*
- * @param this calling object
* @return unique ID
*/
u_int32_t (*get_unique_id) (ike_sa_t *this);
/**
- * @brief Get the state of the IKE_SA.
+ * Get the state of the IKE_SA.
*
- * @param this calling object
* @return state of the IKE_SA
*/
ike_sa_state_t (*get_state) (ike_sa_t *this);
/**
- * @brief Set the state of the IKE_SA.
+ * Set the state of the IKE_SA.
*
- * @param this calling object
* @param state state to set for the IKE_SA
*/
void (*set_state) (ike_sa_t *this, ike_sa_state_t ike_sa);
/**
- * @brief Get the name of the connection this IKE_SA uses.
+ * Get the name of the connection this IKE_SA uses.
*
- * @param this calling object
* @return name
*/
char* (*get_name) (ike_sa_t *this);
/**
- * @brief Get statistic values from the IKE_SA.
+ * Get statistic values from the IKE_SA.
*
- * @param this calling object
* @param kind kind of requested value
* @return value as integer
*/
u_int32_t (*get_statistic)(ike_sa_t *this, statistic_t kind);
/**
- * @brief Get the own host address.
+ * Get the own host address.
*
- * @param this calling object
* @return host address
*/
host_t* (*get_my_host) (ike_sa_t *this);
/**
- * @brief Set the own host address.
+ * Set the own host address.
*
- * @param this calling object
* @param me host address
*/
void (*set_my_host) (ike_sa_t *this, host_t *me);
/**
- * @brief Get the other peers host address.
+ * Get the other peers host address.
*
- * @param this calling object
* @return host address
*/
host_t* (*get_other_host) (ike_sa_t *this);
/**
- * @brief Set the others host address.
+ * Set the others host address.
*
- * @param this calling object
* @param other host address
*/
void (*set_other_host) (ike_sa_t *this, host_t *other);
/**
- * @brief Update the IKE_SAs host.
+ * Update the IKE_SAs host.
*
* Hosts may be NULL to use current host.
*
- * @param this calling object
* @param me new local host address, or NULL
* @param other new remote host address, or NULL
*/
void (*update_hosts)(ike_sa_t *this, host_t *me, host_t *other);
/**
- * @brief Get the own identification.
+ * Get the own identification.
*
- * @param this calling object
* @return identification
*/
identification_t* (*get_my_id) (ike_sa_t *this);
/**
- * @brief Set the own identification.
+ * Set the own identification.
*
- * @param this calling object
* @param me identification
*/
void (*set_my_id) (ike_sa_t *this, identification_t *me);
/**
- * @brief Get the other peer's identification.
+ * Get the other peer's identification.
*
- * @param this calling object
* @return identification
*/
identification_t* (*get_other_id) (ike_sa_t *this);
/**
- * @brief Set the other peer's identification.
+ * Set the other peer's identification.
*
- * @param this calling object
* @param other identification
*/
void (*set_other_id) (ike_sa_t *this, identification_t *other);
/**
- * @brief Get the other peer's certification authority
+ * Get the config used to setup this IKE_SA.
*
- * @param this calling object
- * @return ca_info_t record of other ca
- */
- ca_info_t* (*get_other_ca) (ike_sa_t *this);
-
- /**
- * @brief Set the other peer's certification authority
- *
- * @param this calling object
- * @param other_ca ca_info_t record of other ca
- */
- void (*set_other_ca) (ike_sa_t *this, ca_info_t *other_ca);
-
- /**
- * @brief Get the config used to setup this IKE_SA.
- *
- * @param this calling object
* @return ike_config
*/
ike_cfg_t* (*get_ike_cfg) (ike_sa_t *this);
/**
- * @brief Set the config to setup this IKE_SA.
+ * Set the config to setup this IKE_SA.
*
- * @param this calling object
* @param config ike_config to use
*/
void (*set_ike_cfg) (ike_sa_t *this, ike_cfg_t* config);
/**
- * @brief Get the peer config used by this IKE_SA.
+ * Get the peer config used by this IKE_SA.
*
- * @param this calling object
* @return peer_config
*/
peer_cfg_t* (*get_peer_cfg) (ike_sa_t *this);
/**
- * @brief Set the peer config to use with this IKE_SA.
+ * Set the peer config to use with this IKE_SA.
*
- * @param this calling object
* @param config peer_config to use
*/
void (*set_peer_cfg) (ike_sa_t *this, peer_cfg_t *config);
/**
- * @brief Add an additional address for the peer.
+ * Get authentication/authorization info for local peer.
+ *
+ * @return auth_info for me
+ */
+ auth_info_t* (*get_my_auth)(ike_sa_t *this);
+
+ /**
+ * Get authentication/authorization info for remote peer.
+ *
+ * @return auth_info for me
+ */
+ auth_info_t* (*get_other_auth)(ike_sa_t *this);
+
+ /**
+ * Add an additional address for the peer.
*
* In MOBIKE, a peer may transmit additional addresses where it is
* reachable. These are stored in the IKE_SA.
* The own list of addresses is not stored, they are queried from
* the kernel when required.
*
- * @param this calling object
* @param host host to add to list
*/
void (*add_additional_address)(ike_sa_t *this, host_t *host);
/**
- * @brief Create an iterator over all additional addresses of the peer.
+ * Create an iterator over all additional addresses of the peer.
*
- * @param this calling object
* @return iterator over addresses
*/
iterator_t* (*create_additional_address_iterator)(ike_sa_t *this);
/**
- * @brief Enable an extension the peer supports.
+ * Enable an extension the peer supports.
*
* If support for an IKE extension is detected, this method is called
* to enable that extension and behave accordingly.
*
- * @param this calling object
* @param extension extension to enable
*/
void (*enable_extension)(ike_sa_t *this, ike_extension_t extension);
/**
- * @brief Check if the peer supports an extension.
+ * Check if the peer supports an extension.
*
- * @param this calling object
* @param extension extension to check for support
* @return TRUE if peer supports it, FALSE otherwise
*/
bool (*supports_extension)(ike_sa_t *this, ike_extension_t extension);
/**
- * @brief Enable/disable a condition flag for this IKE_SA.
+ * Enable/disable a condition flag for this IKE_SA.
*
- * @param this calling object
* @param condition condition to enable/disable
* @param enable TRUE to enable condition, FALSE to disable
*/
void (*set_condition) (ike_sa_t *this, ike_condition_t condition, bool enable);
/**
- * @brief Check if a condition flag is set.
+ * Check if a condition flag is set.
*
- * @param this calling object
* @param condition condition to check
* @return TRUE if condition flag set, FALSE otherwise
*/
bool (*has_condition) (ike_sa_t *this, ike_condition_t condition);
/**
- * @brief Get the number of queued MOBIKE address updates.
+ * Get the number of queued MOBIKE address updates.
*
- * @param this calling object
* @return number of pending updates
*/
u_int32_t (*get_pending_updates)(ike_sa_t *this);
/**
- * @brief Set the number of queued MOBIKE address updates.
+ * Set the number of queued MOBIKE address updates.
*
- * @param this calling object
* @param updates number of pending updates
*/
void (*set_pending_updates)(ike_sa_t *this, u_int32_t updates);
+
+ /**
+ * Check if we are the original initiator of this IKE_SA (rekeying does not
+ * change this flag).
+ */
+ bool (*is_ike_initiator)(ike_sa_t *this);
+
-#ifdef P2P
+#ifdef ME
/**
- * @brief Get the server reflexive host.
+ * Activate mediation server functionality for this IKE_SA.
+ */
+ void (*act_as_mediation_server) (ike_sa_t *this);
+
+ /**
+ * Get the server reflexive host.
*
- * @param this calling object
* @return server reflexive host
*/
host_t* (*get_server_reflexive_host) (ike_sa_t *this);
/**
- * @brief Set the server reflexive host.
+ * Set the server reflexive host.
*
- * @param this calling object
* @param host server reflexive host
*/
void (*set_server_reflexive_host) (ike_sa_t *this, host_t *host);
/**
- * @brief Initiate the mediation of a mediated connection (i.e. initiate a
- * P2P_CONNECT exchange).
+ * Get the connect ID.
+ *
+ * @return connect ID
+ */
+ chunk_t (*get_connect_id) (ike_sa_t *this);
+
+ /**
+ * Initiate the mediation of a mediated connection (i.e. initiate a
+ * ME_CONNECT exchange).
*
- * @param this calling object
* @param mediated_cfg peer_cfg of the mediated connection
* @return
- * - SUCCESS if initialization started
- * - DESTROY_ME if initialization failed
+ * - SUCCESS if initialization started
+ * - DESTROY_ME if initialization failed
*/
status_t (*initiate_mediation) (ike_sa_t *this, peer_cfg_t *mediated_cfg);
/**
- * @brief Initiate the mediated connection
+ * Initiate the mediated connection
*
- * @param this calling object
* @param me local endpoint (gets cloned)
* @param other remote endpoint (gets cloned)
- * @param childs linked list of child_cfg_t of CHILD_SAs (gets cloned)
+ * @param connect_id connect ID (gets cloned)
* @return
- * - SUCCESS if initialization started
- * - DESTROY_ME if initialization failed
+ * - SUCCESS if initialization started
+ * - DESTROY_ME if initialization failed
*/
status_t (*initiate_mediated) (ike_sa_t *this, host_t *me, host_t *other,
- linked_list_t *childs);
+ chunk_t connect_id);
/**
- * @brief Relay data from one peer to another (i.e. initiate a
- * P2P_CONNECT exchange).
+ * Relay data from one peer to another (i.e. initiate a
+ * ME_CONNECT exchange).
*
* Data is cloned.
*
- * @param this calling object
* @param requester ID of the requesting peer
- * @param session_id data of the P2P_SESSIONID payload
- * @param session_key data of the P2P_SESSIONKEY payload
+ * @param connect_id data of the ME_CONNECTID payload
+ * @param connect_key data of the ME_CONNECTKEY payload
* @param endpoints endpoints
* @param response TRUE if this is a response
* @return
- * - SUCCESS if relay started
- * - DESTROY_ME if relay failed
+ * - SUCCESS if relay started
+ * - DESTROY_ME if relay failed
*/
- status_t (*relay) (ike_sa_t *this, identification_t *requester, chunk_t session_id,
- chunk_t session_key, linked_list_t *endpoints, bool response);
+ status_t (*relay) (ike_sa_t *this, identification_t *requester, chunk_t connect_id,
+ chunk_t connect_key, linked_list_t *endpoints, bool response);
/**
- * @brief Send a callback to a peer.
+ * Send a callback to a peer.
*
* Data is cloned.
*
- * @param this calling object
* @param peer_id ID of the other peer
* @return
- * - SUCCESS if response started
- * - DESTROY_ME if response failed
+ * - SUCCESS if response started
+ * - DESTROY_ME if response failed
*/
status_t (*callback) (ike_sa_t *this, identification_t *peer_id);
/**
- * @brief Respond to a P2P_CONNECT request.
+ * Respond to a ME_CONNECT request.
*
* Data is cloned.
*
- * @param this calling object
* @param peer_id ID of the other peer
- * @param session_id the session ID supplied by the initiator
+ * @param connect_id the connect ID supplied by the initiator
* @return
- * - SUCCESS if response started
- * - DESTROY_ME if response failed
+ * - SUCCESS if response started
+ * - DESTROY_ME if response failed
*/
- status_t (*respond) (ike_sa_t *this, identification_t *peer_id, chunk_t session_id);
-#endif /* P2P */
+ status_t (*respond) (ike_sa_t *this, identification_t *peer_id, chunk_t connect_id);
+#endif /* ME */
/**
- * @brief Initiate a new connection.
+ * Initiate a new connection.
*
* The configs are owned by the IKE_SA after the call.
*
- * @param this calling object
* @param child_cfg child config to create CHILD from
* @return
* - SUCCESS if initialization started
@@ -577,12 +553,11 @@ struct ike_sa_t {
status_t (*initiate) (ike_sa_t *this, child_cfg_t *child_cfg);
/**
- * @brief Route a policy in the kernel.
+ * Route a policy in the kernel.
*
* Installs the policies in the kernel. If traffic matches,
* the kernel requests connection setup from the IKE_SA via acquire().
*
- * @param this calling object
* @param child_cfg child config to route
* @return
* - SUCCESS if routed successfully
@@ -591,9 +566,8 @@ struct ike_sa_t {
status_t (*route) (ike_sa_t *this, child_cfg_t *child_cfg);
/**
- * @brief Unroute a policy in the kernel previously routed.
+ * Unroute a policy in the kernel previously routed.
*
- * @param this calling object
* @param reqid reqid of CHILD_SA to unroute
* @return
* - SUCCESS if route removed
@@ -603,12 +577,11 @@ struct ike_sa_t {
status_t (*unroute) (ike_sa_t *this, u_int32_t reqid);
/**
- * @brief Acquire connection setup for an installed kernel policy.
+ * Acquire connection setup for an installed kernel policy.
*
* If an installed policy raises an acquire, the kernel calls
* this function to establish the CHILD_SA (and maybe the IKE_SA).
*
- * @param this calling object
* @param reqid reqid of the CHILD_SA the policy belongs to.
* @return
* - SUCCESS if initialization started
@@ -617,13 +590,12 @@ struct ike_sa_t {
status_t (*acquire) (ike_sa_t *this, u_int32_t reqid);
/**
- * @brief Initiates the deletion of an IKE_SA.
+ * Initiates the deletion of an IKE_SA.
*
* Sends a delete message to the remote peer and waits for
* its response. If the response comes in, or a timeout occurs,
* the IKE SA gets deleted.
*
- * @param this calling object
* @return
* - SUCCESS if deletion is initialized
* - INVALID_STATE, if the IKE_SA is not in
@@ -633,7 +605,7 @@ struct ike_sa_t {
status_t (*delete) (ike_sa_t *this);
/**
- * @brief Update IKE_SAs after network interfaces have changed.
+ * Update IKE_SAs after network interfaces have changed.
*
* Whenever the network interface configuration changes, the kernel
* interface calls roam() on each IKE_SA. The IKE_SA then checks if
@@ -641,21 +613,19 @@ struct ike_sa_t {
* If MOBIKE is supported, addresses are updated; If not, the tunnel is
* restarted.
*
- * @param this calling object
* @param address TRUE if address list changed, FALSE otherwise
* @return SUCCESS, FAILED, DESTROY_ME
*/
status_t (*roam)(ike_sa_t *this, bool address);
/**
- * @brief Processes a incoming IKEv2-Message.
+ * Processes a incoming IKEv2-Message.
*
* Message processing may fail. If a critical failure occurs,
* process_message() return DESTROY_ME. Then the caller must
* destroy the IKE_SA immediatly, as it is unusable.
*
- * @param this calling object
- * @param message message to process
+ * @param message message to process
* @return
* - SUCCESS
* - FAILED
@@ -664,12 +634,11 @@ struct ike_sa_t {
status_t (*process_message) (ike_sa_t *this, message_t *message);
/**
- * @brief Generate a IKE message to send it to the peer.
+ * Generate a IKE message to send it to the peer.
*
* This method generates all payloads in the message and encrypts/signs
* the packet.
*
- * @param this calling object
* @param message message to generate
* @param packet generated output packet
* @return
@@ -681,9 +650,8 @@ struct ike_sa_t {
packet_t **packet);
/**
- * @brief Retransmits a request.
+ * Retransmits a request.
*
- * @param this calling object
* @param message_id ID of the request to retransmit
* @return
* - SUCCESS
@@ -692,13 +660,12 @@ struct ike_sa_t {
status_t (*retransmit) (ike_sa_t *this, u_int32_t message_id);
/**
- * @brief Sends a DPD request to the peer.
+ * Sends a DPD request to the peer.
*
* To check if a peer is still alive, periodic
* empty INFORMATIONAL messages are sent if no
* other traffic was received.
*
- * @param this calling object
* @return
* - SUCCESS
* - DESTROY_ME, if peer did not respond
@@ -706,19 +673,17 @@ struct ike_sa_t {
status_t (*send_dpd) (ike_sa_t *this);
/**
- * @brief Sends a keep alive packet.
+ * Sends a keep alive packet.
*
* To refresh NAT tables in a NAT router
* between the peers, periodic empty
* UDP packets are sent if no other traffic
* was sent.
- *
- * @param this calling object
*/
void (*send_keepalive) (ike_sa_t *this);
/**
- * @brief Derive all keys and create the transforms for IKE communication.
+ * Derive all keys and create the transforms for IKE communication.
*
* Keys are derived using the diffie hellman secret, nonces and internal
* stored SPIs.
@@ -726,7 +691,6 @@ struct ike_sa_t {
* existing IKE_SA (rekeying). The SK_d key from the old IKE_SA
* is included in the derivation process.
*
- * @param this calling object
* @param proposal proposal which contains algorithms to use
* @param secret secret derived from DH exchange, gets freed
* @param nonce_i initiators nonce
@@ -740,49 +704,58 @@ struct ike_sa_t {
bool initiator, prf_t *child_prf, prf_t *old_prf);
/**
- * @brief Get a multi purpose prf for the negotiated PRF function.
+ * Get the selected IKE proposal string
+ *
+ * @return string describing the selected IKE proposal
+ */
+ char* (*get_proposal)(ike_sa_t *this);
+
+ /**
+ * Set the selected IKE proposal string for status information purposes
+ * (the "%P" printf format handler is used)
+ *
+ * @param proposal string describing the selected IKE proposal
+ */
+ void (*set_proposal)(ike_sa_t *this, char *proposal);
+
+ /**
+ * Get a multi purpose prf for the negotiated PRF function.
*
- * @param this calling object
* @return pointer to prf_t object
*/
prf_t *(*get_prf) (ike_sa_t *this);
/**
- * @brief Get the prf-object, which is used to derive keys for child SAs.
+ * Get the prf-object, which is used to derive keys for child SAs.
*
- * @param this calling object
* @return pointer to prf_t object
*/
prf_t *(*get_child_prf) (ike_sa_t *this);
/**
- * @brief Get the key to build outgoing authentication data.
+ * Get the key to build outgoing authentication data.
*
- * @param this calling object
* @return pointer to prf_t object
*/
chunk_t (*get_skp_build) (ike_sa_t *this);
/**
- * @brief Get the key to verify incoming authentication data.
+ * Get the key to verify incoming authentication data.
*
- * @param this calling object
* @return pointer to prf_t object
*/
chunk_t (*get_skp_verify) (ike_sa_t *this);
/**
- * @brief Associates a child SA to this IKE SA
+ * Associates a child SA to this IKE SA
*
- * @param this calling object
* @param child_sa child_sa to add
*/
void (*add_child_sa) (ike_sa_t *this, child_sa_t *child_sa);
/**
- * @brief Get a CHILD_SA identified by protocol and SPI.
+ * Get a CHILD_SA identified by protocol and SPI.
*
- * @param this calling object
* @param protocol protocol of the SA
* @param spi SPI of the CHILD_SA
* @param inbound TRUE if SPI is inbound, FALSE if outbound
@@ -792,19 +765,17 @@ struct ike_sa_t {
u_int32_t spi, bool inbound);
/**
- * @brief Create an iterator over all CHILD_SAs.
+ * Create an iterator over all CHILD_SAs.
*
- * @param this calling object
* @return iterator
*/
iterator_t* (*create_child_sa_iterator) (ike_sa_t *this);
/**
- * @brief Rekey the CHILD SA with the specified reqid.
+ * Rekey the CHILD SA with the specified reqid.
*
* Looks for a CHILD SA owned by this IKE_SA, and start the rekeing.
*
- * @param this calling object
* @param protocol protocol of the SA
* @param spi inbound SPI of the CHILD_SA
* @return
@@ -814,13 +785,12 @@ struct ike_sa_t {
status_t (*rekey_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
/**
- * @brief Close the CHILD SA with the specified protocol/SPI.
+ * Close the CHILD SA with the specified protocol/SPI.
*
* Looks for a CHILD SA owned by this IKE_SA, deletes it and
* notify's the remote peer about the delete. The associated
* states and policies in the kernel get deleted, if they exist.
*
- * @param this calling object
* @param protocol protocol of the SA
* @param spi inbound SPI of the CHILD_SA
* @return
@@ -830,11 +800,10 @@ struct ike_sa_t {
status_t (*delete_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
/**
- * @brief Destroy a CHILD SA with the specified protocol/SPI.
+ * Destroy a CHILD SA with the specified protocol/SPI.
*
* Looks for a CHILD SA owned by this IKE_SA and destroys it.
*
- * @param this calling object
* @param protocol protocol of the SA
* @param spi inbound SPI of the CHILD_SA
* @return
@@ -844,99 +813,98 @@ struct ike_sa_t {
status_t (*destroy_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
/**
- * @brief Rekey the IKE_SA.
+ * Rekey the IKE_SA.
*
* Sets up a new IKE_SA, moves all CHILDs to it and deletes this IKE_SA.
*
- * @param this calling object
* @return - SUCCESS, if IKE_SA rekeying initiated
*/
status_t (*rekey) (ike_sa_t *this);
/**
- * @brief Restablish the IKE_SA.
+ * Reauthenticate the IKE_SA.
*
* Create a completely new IKE_SA with authentication, recreates all children
* within the IKE_SA, closes this IKE_SA.
*
- * @param this calling object
+ * @return DESTROY_ME to destroy the IKE_SA
+ */
+ status_t (*reauth) (ike_sa_t *this);
+
+ /**
+ * Restablish the IKE_SA.
+ *
+ * Reestablish an IKE_SA after it has been closed.
+ *
* @return DESTROY_ME to destroy the IKE_SA
*/
status_t (*reestablish) (ike_sa_t *this);
/**
- * @brief Set the lifetime limit received from a AUTH_LIFETIME notify.
+ * Set the lifetime limit received from a AUTH_LIFETIME notify.
*
- * @param this calling object
* @param lifetime lifetime in seconds
*/
void (*set_auth_lifetime)(ike_sa_t *this, u_int32_t lifetime);
/**
- * @brief Set the virtual IP to use for this IKE_SA and its children.
+ * Set the virtual IP to use for this IKE_SA and its children.
*
* The virtual IP is assigned per IKE_SA, not per CHILD_SA. It has the same
* lifetime as the IKE_SA.
*
- * @param this calling object
+ * @param local TRUE to set local address, FALSE for remote
+ * @param ip IP to set as virtual IP
*/
void (*set_virtual_ip) (ike_sa_t *this, bool local, host_t *ip);
/**
- * @brief Get the virtual IP configured.
+ * Get the virtual IP configured.
*
- * @param this calling object
* @param local TRUE to get local virtual IP, FALSE for remote
+ * @return host_t *virtual IP
*/
host_t* (*get_virtual_ip) (ike_sa_t *this, bool local);
/**
- * @brief Add a DNS server to the system.
+ * Add a DNS server to the system.
*
* An IRAS may send a DNS server. To use it, it is installed on the
* system. The DNS entry has a lifetime until the IKE_SA gets closed.
*
- * @param this calling object
* @param dns DNS server to install on the system
*/
void (*add_dns_server) (ike_sa_t *this, host_t *dns);
/**
- * @brief Inherit all attributes of other to this after rekeying.
+ * Inherit all attributes of other to this after rekeying.
*
* When rekeying is completed, all CHILD_SAs, the virtual IP and all
* outstanding tasks are moved from other to this.
* As this call may initiate inherited tasks, a status is returned.
*
- * @param this calling object
* @param other other task to inherit from
* @return DESTROY_ME if initiation of inherited task failed
*/
status_t (*inherit) (ike_sa_t *this, ike_sa_t *other);
/**
- * @brief Reset the IKE_SA, useable when initiating fails
- *
- * @param this calling object
+ * Reset the IKE_SA, useable when initiating fails
*/
void (*reset) (ike_sa_t *this);
/**
- * @brief Destroys a ike_sa_t object.
- *
- * @param this calling object
+ * Destroys a ike_sa_t object.
*/
void (*destroy) (ike_sa_t *this);
};
/**
- * @brief Creates an ike_sa_t object with a specific ID.
+ * Creates an ike_sa_t object with a specific ID.
*
* @param ike_sa_id ike_sa_id_t object to associate with new IKE_SA
* @return ike_sa_t object
- *
- * @ingroup sa
*/
ike_sa_t *ike_sa_create(ike_sa_id_t *ike_sa_id);
-#endif /* IKE_SA_H_ */
+#endif /* IKE_SA_H_ @} */
diff --git a/src/charon/sa/ike_sa_id.c b/src/charon/sa/ike_sa_id.c
index a838c0b8a..e012d5944 100644
--- a/src/charon/sa/ike_sa_id.c
+++ b/src/charon/sa/ike_sa_id.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_sa_id.c
- *
- * @brief Implementation of ike_sa_id_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,9 +12,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_sa_id.c 3589 2008-03-13 14:14:44Z martin $
*/
-
#include "ike_sa_id.h"
#include <stdio.h>
diff --git a/src/charon/sa/ike_sa_id.h b/src/charon/sa/ike_sa_id.h
index 0606b7222..652c968b6 100644
--- a/src/charon/sa/ike_sa_id.h
+++ b/src/charon/sa/ike_sa_id.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_sa_id.h
- *
- * @brief Interface of ike_sa_id_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,8 +12,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_sa_id.h 3589 2008-03-13 14:14:44Z martin $
*/
+/**
+ * @defgroup ike_sa_id ike_sa_id
+ * @{ @ingroup sa
+ */
#ifndef IKE_SA_ID_H_
#define IKE_SA_ID_H_
@@ -29,119 +28,101 @@ typedef struct ike_sa_id_t ike_sa_id_t;
#include <library.h>
-
/**
- * @brief An object of type ike_sa_id_t is used to identify an IKE_SA.
+ * An object of type ike_sa_id_t is used to identify an IKE_SA.
*
* An IKE_SA is identified by its initiator and responder spi's.
* Additionaly it contains the role of the actual running IKEv2-Daemon
* for the specific IKE_SA (original initiator or responder).
- *
- * @b Constructors:
- * - ike_sa_id_create()
- *
- * @ingroup sa
*/
struct ike_sa_id_t {
/**
- * @brief Set the SPI of the responder.
+ * Set the SPI of the responder.
*
* This function is called when a request or reply of a IKE_SA_INIT is received.
*
- * @param this calling object
* @param responder_spi SPI of responder to set
*/
void (*set_responder_spi) (ike_sa_id_t *this, u_int64_t responder_spi);
/**
- * @brief Set the SPI of the initiator.
+ * Set the SPI of the initiator.
*
- * @param this calling object
* @param initiator_spi SPI to set
*/
void (*set_initiator_spi) (ike_sa_id_t *this, u_int64_t initiator_spi);
/**
- * @brief Get the initiator SPI.
+ * Get the initiator SPI.
*
- * @param this calling object
* @return SPI of the initiator
*/
u_int64_t (*get_initiator_spi) (ike_sa_id_t *this);
/**
- * @brief Get the responder SPI.
+ * Get the responder SPI.
*
- * @param this calling object
* @return SPI of the responder
*/
u_int64_t (*get_responder_spi) (ike_sa_id_t *this);
/**
- * @brief Check if two ike_sa_id_t objects are equal.
+ * Check if two ike_sa_id_t objects are equal.
*
* Two ike_sa_id_t objects are equal if both SPI values and the role matches.
*
- * @param this calling object
* @param other ike_sa_id_t object to check if equal
* @return TRUE if given ike_sa_id_t are equal, FALSE otherwise
*/
bool (*equals) (ike_sa_id_t *this, ike_sa_id_t *other);
/**
- * @brief Replace all values of a given ike_sa_id_t object with values.
+ * Replace all values of a given ike_sa_id_t object with values.
* from another ike_sa_id_t object.
*
* After calling this function, both objects are equal.
*
- * @param this calling object
* @param other ike_sa_id_t object from which values will be taken
*/
void (*replace_values) (ike_sa_id_t *this, ike_sa_id_t *other);
/**
- * @brief Get the initiator flag.
+ * Get the initiator flag.
*
- * @param this calling object
* @return TRUE if we are the original initator
*/
bool (*is_initiator) (ike_sa_id_t *this);
/**
- * @brief Switche the original initiator flag.
+ * Switche the original initiator flag.
*
- * @param this calling object
* @return TRUE if we are the original initator after switch, FALSE otherwise
*/
bool (*switch_initiator) (ike_sa_id_t *this);
/**
- * @brief Clones a given ike_sa_id_t object.
+ * Clones a given ike_sa_id_t object.
*
- * @param this calling object
* @return cloned ike_sa_id_t object
*/
ike_sa_id_t *(*clone) (ike_sa_id_t *this);
/**
- * @brief Destroys an ike_sa_id_t object.
- *
- * @param this calling object
+ * Destroys an ike_sa_id_t object.
*/
void (*destroy) (ike_sa_id_t *this);
};
/**
- * @brief Creates an ike_sa_id_t object with specific SPI's and defined role.
+ * Creates an ike_sa_id_t object with specific SPI's and defined role.
*
* @param initiator_spi initiators SPI
* @param responder_spi responders SPI
* @param is_initiaor TRUE if we are the original initiator
* @return ike_sa_id_t object
- *
- * @ingroup sa
*/
-ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, bool is_initiaor);
+ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi,
+ bool is_initiaor);
-#endif /*IKE_SA_ID_H_*/
+#endif /*IKE_SA_ID_H_ @} */
diff --git a/src/charon/sa/ike_sa_manager.c b/src/charon/sa/ike_sa_manager.c
index 5e7f78af0..9c1b2d413 100644
--- a/src/charon/sa/ike_sa_manager.c
+++ b/src/charon/sa/ike_sa_manager.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_sa_manager.c
- *
- * @brief Implementation of ike_sa_mananger_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_sa_manager.c 4044 2008-06-06 15:05:54Z martin $
*/
#include <pthread.h>
@@ -30,6 +25,7 @@
#include <sa/ike_sa_id.h>
#include <bus/bus.h>
#include <utils/linked_list.h>
+#include <crypto/hashers/hasher.h>
typedef struct entry_t entry_t;
@@ -79,6 +75,11 @@ struct entry_t {
chunk_t init_hash;
/**
+ * remote host address, required for DoS detection
+ */
+ host_t *other;
+
+ /**
* message ID currently processing, if any
*/
u_int32_t message_id;
@@ -93,6 +94,7 @@ static status_t entry_destroy(entry_t *this)
this->ike_sa->destroy(this->ike_sa);
this->ike_sa_id->destroy(this->ike_sa_id);
chunk_free(&this->init_hash);
+ DESTROY_IF(this->other);
free(this);
return SUCCESS;
}
@@ -113,6 +115,7 @@ static entry_t *entry_create(ike_sa_id_t *ike_sa_id)
this->driveout_waiting_threads = FALSE;
this->message_id = -1;
this->init_hash = chunk_empty;
+ this->other = NULL;
/* ike_sa_id is always cloned */
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
@@ -146,9 +149,9 @@ struct private_ike_sa_manager_t {
linked_list_t *ike_sa_list;
/**
- * A randomizer, to get random SPIs for our side
+ * RNG to get random SPIs for our side
*/
- randomizer_t *randomizer;
+ rng_t *rng;
/**
* SHA1 hasher for IKE_SA_INIT retransmit detection
@@ -159,20 +162,20 @@ struct private_ike_sa_manager_t {
/**
* Implementation of private_ike_sa_manager_t.get_entry_by_id.
*/
-static status_t get_entry_by_id(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, entry_t **entry)
+static status_t get_entry_by_id(private_ike_sa_manager_t *this,
+ ike_sa_id_t *ike_sa_id, entry_t **entry)
{
- linked_list_t *list = this->ike_sa_list;
- iterator_t *iterator;
+ enumerator_t *enumerator;
entry_t *current;
status_t status;
- /* create iterator over list of ike_sa's */
- iterator = list->create_iterator(list, TRUE);
+ /* create enumerator over list of ike_sa's */
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
/* default status */
status = NOT_FOUND;
- while (iterator->iterate(iterator, (void**)&current))
+ while (enumerator->enumerate(enumerator, &current))
{
if (current->ike_sa_id->equals(current->ike_sa_id, ike_sa_id))
{
@@ -198,26 +201,26 @@ static status_t get_entry_by_id(private_ike_sa_manager_t *this, ike_sa_id_t *ike
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return status;
}
/**
* Implementation of private_ike_sa_manager_t.get_entry_by_sa.
*/
-static status_t get_entry_by_sa(private_ike_sa_manager_t *this, ike_sa_t *ike_sa, entry_t **entry)
+static status_t get_entry_by_sa(private_ike_sa_manager_t *this,
+ ike_sa_t *ike_sa, entry_t **entry)
{
- linked_list_t *list = this->ike_sa_list;
- iterator_t *iterator;
+ enumerator_t *enumerator;
entry_t *current;
status_t status;
- iterator = list->create_iterator(list, TRUE);
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
/* default status */
status = NOT_FOUND;
- while (iterator->iterate(iterator, (void**)&current))
+ while (enumerator->enumerate(enumerator, &current))
{
/* only pointers are compared */
if (current->ike_sa == ike_sa)
@@ -228,7 +231,7 @@ static status_t get_entry_by_sa(private_ike_sa_manager_t *this, ike_sa_t *ike_sa
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return status;
}
@@ -238,16 +241,15 @@ static status_t get_entry_by_sa(private_ike_sa_manager_t *this, ike_sa_t *ike_sa
*/
static status_t delete_entry(private_ike_sa_manager_t *this, entry_t *entry)
{
- linked_list_t *list = this->ike_sa_list;
- iterator_t *iterator;
+ enumerator_t *enumerator;
entry_t *current;
status_t status;
- iterator = list->create_iterator(list, TRUE);
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
status = NOT_FOUND;
- while (iterator->iterate(iterator, (void**)&current))
+ while (enumerator->enumerate(enumerator, &current))
{
if (current == entry)
{
@@ -263,13 +265,13 @@ static status_t delete_entry(private_ike_sa_manager_t *this, entry_t *entry)
}
DBG2(DBG_MGR, "found entry by pointer, deleting it");
- iterator->remove(iterator);
+ this->ike_sa_list->remove_at(this->ike_sa_list, enumerator);
entry_destroy(entry);
status = SUCCESS;
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return status;
}
@@ -309,8 +311,7 @@ static u_int64_t get_next_spi(private_ike_sa_manager_t *this)
{
u_int64_t spi;
- this->randomizer->get_pseudo_random_bytes(this->randomizer, sizeof(spi),
- (u_int8_t*)&spi);
+ this->rng->get_bytes(this->rng, sizeof(spi), (u_int8_t*)&spi);
return spi;
}
@@ -386,7 +387,7 @@ static ike_sa_t* checkout_by_message(private_ike_sa_manager_t* this,
message->get_exchange_type(message) == IKE_SA_INIT)
{
/* IKE_SA_INIT request. Check for an IKE_SA with such a message hash. */
- iterator_t *iterator;
+ enumerator_t *enumerator;
chunk_t data, hash;
data = message->get_packet_data(message);
@@ -394,14 +395,14 @@ static ike_sa_t* checkout_by_message(private_ike_sa_manager_t* this,
chunk_free(&data);
pthread_mutex_lock(&this->mutex);
- iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE);
- while (iterator->iterate(iterator, (void**)&entry))
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
+ while (enumerator->enumerate(enumerator, &entry))
{
if (chunk_equals(hash, entry->init_hash))
{
if (entry->message_id == 0)
{
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
pthread_mutex_unlock(&this->mutex);
chunk_free(&hash);
id->destroy(id);
@@ -418,7 +419,7 @@ static ike_sa_t* checkout_by_message(private_ike_sa_manager_t* this,
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
pthread_mutex_unlock(&this->mutex);
if (ike_sa == NULL)
@@ -488,7 +489,7 @@ static ike_sa_t* checkout_by_message(private_ike_sa_manager_t* this,
static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
peer_cfg_t *peer_cfg)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
entry_t *entry;
ike_sa_t *ike_sa = NULL;
identification_t *my_id, *other_id;
@@ -496,65 +497,70 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
ike_cfg_t *ike_cfg;
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
- my_host = ike_cfg->get_my_host(ike_cfg);
- other_host = ike_cfg->get_other_host(ike_cfg);
my_id = peer_cfg->get_my_id(peer_cfg);
other_id = peer_cfg->get_other_id(peer_cfg);
+ my_host = host_create_from_dns(ike_cfg->get_my_addr(ike_cfg), 0, 0);
+ other_host = host_create_from_dns(ike_cfg->get_other_addr(ike_cfg), 0, 0);
pthread_mutex_lock(&(this->mutex));
- iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE);
- while (iterator->iterate(iterator, (void**)&entry))
+ if (my_host && other_host)
{
- identification_t *found_my_id, *found_other_id;
- host_t *found_my_host, *found_other_host;
- int wc;
-
- if (!wait_for_entry(this, entry))
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
+ while (enumerator->enumerate(enumerator, &entry))
{
- continue;
- }
+ identification_t *found_my_id, *found_other_id;
+ host_t *found_my_host, *found_other_host;
- if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
- {
- /* skip IKE_SA which are not useable */
- continue;
- }
+ if (!wait_for_entry(this, entry))
+ {
+ continue;
+ }
- found_my_id = entry->ike_sa->get_my_id(entry->ike_sa);
- found_other_id = entry->ike_sa->get_other_id(entry->ike_sa);
- found_my_host = entry->ike_sa->get_my_host(entry->ike_sa);
- found_other_host = entry->ike_sa->get_other_host(entry->ike_sa);
+ if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
+ {
+ /* skip IKE_SA which are not useable */
+ continue;
+ }
- if (found_my_id->get_type(found_my_id) == ID_ANY &&
- found_other_id->get_type(found_other_id) == ID_ANY)
- {
- /* IKE_SA has no IDs yet, so we can't use it */
- continue;
- }
- DBG2(DBG_MGR, "candidate IKE_SA for \n\t%H[%D]...%H[%D]\n\t%H[%D]...%H[%D]",
- my_host, my_id, other_host, other_id,
- found_my_host, found_my_id, found_other_host, found_other_id);
- /* compare ID and hosts. Supplied ID may contain wildcards, and IP
- * may be %any. */
- if ((my_host->is_anyaddr(my_host) ||
- my_host->ip_equals(my_host, found_my_host)) &&
- (other_host->is_anyaddr(other_host) ||
- other_host->ip_equals(other_host, found_other_host)) &&
- found_my_id->matches(found_my_id, my_id, &wc) &&
- found_other_id->matches(found_other_id, other_id, &wc) &&
- streq(peer_cfg->get_name(peer_cfg),
- entry->ike_sa->get_name(entry->ike_sa)))
- {
- /* looks good, we take this one */
- DBG2(DBG_MGR, "found an existing IKE_SA for %H[%D]...%H[%D]",
- my_host, my_id, other_host, other_id);
- entry->checked_out = TRUE;
- ike_sa = entry->ike_sa;
- break;
+ found_my_id = entry->ike_sa->get_my_id(entry->ike_sa);
+ found_other_id = entry->ike_sa->get_other_id(entry->ike_sa);
+ found_my_host = entry->ike_sa->get_my_host(entry->ike_sa);
+ found_other_host = entry->ike_sa->get_other_host(entry->ike_sa);
+
+ if (found_my_id->get_type(found_my_id) == ID_ANY &&
+ found_other_id->get_type(found_other_id) == ID_ANY)
+ {
+ /* IKE_SA has no IDs yet, so we can't use it */
+ continue;
+ }
+ DBG2(DBG_MGR, "candidate IKE_SA for \n\t"
+ "%H[%D]...%H[%D]\n\t%H[%D]...%H[%D]",
+ my_host, my_id, other_host, other_id,
+ found_my_host, found_my_id, found_other_host, found_other_id);
+ /* compare ID and hosts. Supplied ID may contain wildcards, and IP
+ * may be %any. */
+ if ((my_host->is_anyaddr(my_host) ||
+ my_host->ip_equals(my_host, found_my_host)) &&
+ (other_host->is_anyaddr(other_host) ||
+ other_host->ip_equals(other_host, found_other_host)) &&
+ found_my_id->matches(found_my_id, my_id) &&
+ found_other_id->matches(found_other_id, other_id) &&
+ streq(peer_cfg->get_name(peer_cfg),
+ entry->ike_sa->get_name(entry->ike_sa)))
+ {
+ /* looks good, we take this one */
+ DBG2(DBG_MGR, "found an existing IKE_SA for %H[%D]...%H[%D]",
+ my_host, my_id, other_host, other_id);
+ entry->checked_out = TRUE;
+ ike_sa = entry->ike_sa;
+ break;
+ }
}
+ enumerator->destroy(enumerator);
}
- iterator->destroy(iterator);
+ DESTROY_IF(my_host);
+ DESTROY_IF(other_host);
if (!ike_sa)
{
@@ -589,15 +595,16 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
static ike_sa_t* checkout_by_id(private_ike_sa_manager_t *this, u_int32_t id,
bool child)
{
- iterator_t *iterator, *children;
+ enumerator_t *enumerator;
+ iterator_t *children;
entry_t *entry;
ike_sa_t *ike_sa = NULL;
child_sa_t *child_sa;
pthread_mutex_lock(&(this->mutex));
- iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE);
- while (iterator->iterate(iterator, (void**)&entry))
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
+ while (enumerator->enumerate(enumerator, &entry))
{
if (wait_for_entry(this, entry))
{
@@ -630,7 +637,7 @@ static ike_sa_t* checkout_by_id(private_ike_sa_manager_t *this, u_int32_t id,
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
pthread_mutex_unlock(&(this->mutex));
charon->bus->set_sa(charon->bus, ike_sa);
@@ -643,15 +650,16 @@ static ike_sa_t* checkout_by_id(private_ike_sa_manager_t *this, u_int32_t id,
static ike_sa_t* checkout_by_name(private_ike_sa_manager_t *this, char *name,
bool child)
{
- iterator_t *iterator, *children;
+ enumerator_t *enumerator;
+ iterator_t *children;
entry_t *entry;
ike_sa_t *ike_sa = NULL;
child_sa_t *child_sa;
pthread_mutex_lock(&(this->mutex));
- iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE);
- while (iterator->iterate(iterator, (void**)&entry))
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
+ while (enumerator->enumerate(enumerator, &entry))
{
if (wait_for_entry(this, entry))
{
@@ -684,39 +692,82 @@ static ike_sa_t* checkout_by_name(private_ike_sa_manager_t *this, char *name,
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
pthread_mutex_unlock(&(this->mutex));
charon->bus->set_sa(charon->bus, ike_sa);
return ike_sa;
}
+
+/**
+ * Implementation of ike_sa_manager_t.checkout_duplicate.
+ */
+static ike_sa_t* checkout_duplicate(private_ike_sa_manager_t *this,
+ ike_sa_t *ike_sa)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ ike_sa_t *duplicate = NULL;
+ identification_t *me, *other;
+
+ me = ike_sa->get_my_id(ike_sa);
+ other = ike_sa->get_other_id(ike_sa);
+
+ pthread_mutex_lock(&this->mutex);
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->ike_sa == ike_sa)
+ { /* self is not a duplicate */
+ continue;
+ }
+ if (wait_for_entry(this, entry))
+ {
+ if (me->equals(me, entry->ike_sa->get_my_id(entry->ike_sa)) &&
+ other->equals(other, entry->ike_sa->get_other_id(entry->ike_sa)))
+ {
+ duplicate = entry->ike_sa;
+ entry->checked_out = TRUE;
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ pthread_mutex_unlock(&this->mutex);
+ return duplicate;
+}
+
+/**
+ * enumerator cleanup function
+ */
+static void enumerator_unlock(private_ike_sa_manager_t *this)
+{
+ pthread_mutex_unlock(&this->mutex);
+}
/**
- * Iterator hook for iterate, gets ike_sas instead of entries
+ * enumerator filter function
*/
-static hook_result_t iterator_hook(private_ike_sa_manager_t* this, entry_t *in,
- ike_sa_t **out)
+static bool enumerator_filter(private_ike_sa_manager_t *this,
+ entry_t **in, ike_sa_t **out)
{
- /* check out entry */
- if (wait_for_entry(this, in))
+ if (wait_for_entry(this, *in))
{
- *out = in->ike_sa;
- return HOOK_NEXT;
+ *out = (*in)->ike_sa;
+ return TRUE;
}
- return HOOK_SKIP;
+ return FALSE;
}
/**
* Implementation of ike_sa_manager_t.create_iterator.
*/
-static iterator_t *create_iterator(private_ike_sa_manager_t* this)
+static enumerator_t *create_enumerator(private_ike_sa_manager_t* this)
{
- iterator_t *iterator = this->ike_sa_list->create_iterator_locked(
- this->ike_sa_list, &this->mutex);
-
- /* register hook to iterator over ike_sas, not entries */
- iterator->set_iterator_hook(iterator, (iterator_hook_t*)iterator_hook, this);
- return iterator;
+ pthread_mutex_lock(&this->mutex);
+ return enumerator_create_filter(
+ this->ike_sa_list->create_enumerator(this->ike_sa_list),
+ (void*)enumerator_filter, this, (void*)enumerator_unlock);
}
/**
@@ -732,6 +783,7 @@ static status_t checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
status_t retval;
entry_t *entry;
ike_sa_id_t *ike_sa_id;
+ host_t *other;
ike_sa_id = ike_sa->get_id(ike_sa);
@@ -747,6 +799,13 @@ static status_t checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
/* signal waiting threads */
entry->checked_out = FALSE;
entry->message_id = -1;
+ /* apply remote address for DoS detection */
+ other = ike_sa->get_other_host(ike_sa);
+ if (!entry->other || !other->equals(other, entry->other))
+ {
+ DESTROY_IF(entry->other);
+ entry->other = other->clone(other);
+ }
DBG2(DBG_MGR, "check-in of IKE_SA successful.");
pthread_cond_signal(&(entry->condvar));
retval = SUCCESS;
@@ -783,6 +842,7 @@ static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ik
ike_sa_id = ike_sa->get_id(ike_sa);
DBG2(DBG_MGR, "checkin and destroy IKE_SA");
+ charon->bus->set_sa(charon->bus, NULL);
pthread_mutex_lock(&(this->mutex));
@@ -803,7 +863,6 @@ static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ik
}
pthread_mutex_unlock(&(this->mutex));
- charon->bus->set_sa(charon->bus, ike_sa);
return retval;
}
@@ -812,23 +871,22 @@ static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ik
*/
static int get_half_open_count(private_ike_sa_manager_t *this, host_t *ip)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
entry_t *entry;
int count = 0;
pthread_mutex_lock(&(this->mutex));
- iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE);
- while (iterator->iterate(iterator, (void**)&entry))
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
+ while (enumerator->enumerate(enumerator, &entry))
{
/* we check if we have a responder CONNECTING IKE_SA without checkout */
if (!entry->ike_sa_id->is_initiator(entry->ike_sa_id) &&
entry->ike_sa->get_state(entry->ike_sa) == IKE_CONNECTING)
{
- /* if we have a host, we have wait until no other uses the IKE_SA */
+ /* if we have a host, count only matching IKE_SAs */
if (ip)
{
- if (wait_for_entry(this, entry) && ip->ip_equals(ip,
- entry->ike_sa->get_other_host(entry->ike_sa)))
+ if (entry->other && ip->ip_equals(ip, entry->other))
{
count++;
}
@@ -839,37 +897,37 @@ static int get_half_open_count(private_ike_sa_manager_t *this, host_t *ip)
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
pthread_mutex_unlock(&(this->mutex));
return count;
}
/**
- * Implementation of ike_sa_manager_t.destroy.
+ * Implementation of ike_sa_manager_t.flush.
*/
-static void destroy(private_ike_sa_manager_t *this)
+static void flush(private_ike_sa_manager_t *this)
{
/* destroy all list entries */
- linked_list_t *list = this->ike_sa_list;
- iterator_t *iterator;
+ enumerator_t *enumerator;
entry_t *entry;
pthread_mutex_lock(&(this->mutex));
DBG2(DBG_MGR, "going to destroy IKE_SA manager and all managed IKE_SA's");
/* Step 1: drive out all waiting threads */
DBG2(DBG_MGR, "set driveout flags for all stored IKE_SA's");
- iterator = list->create_iterator(list, TRUE);
- while (iterator->iterate(iterator, (void**)&entry))
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
+ while (enumerator->enumerate(enumerator, &entry))
{
/* do not accept new threads, drive out waiting threads */
entry->driveout_new_threads = TRUE;
entry->driveout_waiting_threads = TRUE;
}
+ enumerator->destroy(enumerator);
DBG2(DBG_MGR, "wait for all threads to leave IKE_SA's");
/* Step 2: wait until all are gone */
- iterator->reset(iterator);
- while (iterator->iterate(iterator, (void**)&entry))
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
+ while (enumerator->enumerate(enumerator, &entry))
{
while (entry->waiting_threads)
{
@@ -879,21 +937,33 @@ static void destroy(private_ike_sa_manager_t *this)
pthread_cond_wait(&(entry->condvar), &(this->mutex));
}
}
+ enumerator->destroy(enumerator);
DBG2(DBG_MGR, "delete all IKE_SA's");
/* Step 3: initiate deletion of all IKE_SAs */
- iterator->reset(iterator);
- while (iterator->iterate(iterator, (void**)&entry))
+ enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
+ while (enumerator->enumerate(enumerator, &entry))
{
entry->ike_sa->delete(entry->ike_sa);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
DBG2(DBG_MGR, "destroy all entries");
/* Step 4: destroy all entries */
- list->destroy_function(list, (void*)entry_destroy);
+ while (this->ike_sa_list->remove_last(this->ike_sa_list,
+ (void**)&entry) == SUCCESS)
+ {
+ entry_destroy(entry);
+ }
pthread_mutex_unlock(&(this->mutex));
-
- this->randomizer->destroy(this->randomizer);
+}
+
+/**
+ * Implementation of ike_sa_manager_t.destroy.
+ */
+static void destroy(private_ike_sa_manager_t *this)
+{
+ this->ike_sa_list->destroy(this->ike_sa_list);
+ this->rng->destroy(this->rng);
this->hasher->destroy(this->hasher);
free(this);
@@ -907,6 +977,7 @@ ike_sa_manager_t *ike_sa_manager_create()
private_ike_sa_manager_t *this = malloc_thing(private_ike_sa_manager_t);
/* assign public functions */
+ this->public.flush = (void(*)(ike_sa_manager_t*))flush;
this->public.destroy = (void(*)(ike_sa_manager_t*))destroy;
this->public.checkout = (ike_sa_t*(*)(ike_sa_manager_t*, ike_sa_id_t*))checkout;
this->public.checkout_new = (ike_sa_t*(*)(ike_sa_manager_t*,bool))checkout_new;
@@ -914,16 +985,30 @@ ike_sa_manager_t *ike_sa_manager_create()
this->public.checkout_by_config = (ike_sa_t*(*)(ike_sa_manager_t*,peer_cfg_t*))checkout_by_config;
this->public.checkout_by_id = (ike_sa_t*(*)(ike_sa_manager_t*,u_int32_t,bool))checkout_by_id;
this->public.checkout_by_name = (ike_sa_t*(*)(ike_sa_manager_t*,char*,bool))checkout_by_name;
- this->public.create_iterator = (iterator_t*(*)(ike_sa_manager_t*))create_iterator;
+ this->public.checkout_duplicate = (ike_sa_t*(*)(ike_sa_manager_t*, ike_sa_t *ike_sa))checkout_duplicate;
+ this->public.create_enumerator = (enumerator_t*(*)(ike_sa_manager_t*))create_enumerator;
this->public.checkin = (status_t(*)(ike_sa_manager_t*,ike_sa_t*))checkin;
this->public.checkin_and_destroy = (status_t(*)(ike_sa_manager_t*,ike_sa_t*))checkin_and_destroy;
this->public.get_half_open_count = (int(*)(ike_sa_manager_t*,host_t*))get_half_open_count;
/* initialize private variables */
+ this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_PREFERRED);
+ if (this->hasher == NULL)
+ {
+ DBG1(DBG_MGR, "manager initialization failed, no hasher supported");
+ free(this);
+ return NULL;
+ }
+ this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (this->rng == NULL)
+ {
+ DBG1(DBG_MGR, "manager initialization failed, no RNG supported");
+ this->hasher->destroy(this->hasher);
+ free(this);
+ return NULL;
+ }
this->ike_sa_list = linked_list_create();
pthread_mutex_init(&this->mutex, NULL);
- this->randomizer = randomizer_create();
- this->hasher = hasher_create(HASH_SHA1);
-
return &this->public;
}
+
diff --git a/src/charon/sa/ike_sa_manager.h b/src/charon/sa/ike_sa_manager.h
index a73a106ba..04b6d96c2 100644
--- a/src/charon/sa/ike_sa_manager.h
+++ b/src/charon/sa/ike_sa_manager.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_sa_manager.h
- *
- * @brief Interface of ike_sa_manager_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_sa_manager.h 3819 2008-04-17 10:46:25Z martin $
+ */
+
+/**
+ * @defgroup ike_sa_manager ike_sa_manager
+ * @{ @ingroup sa
*/
#ifndef IKE_SA_MANAGER_H_
@@ -32,7 +32,7 @@ typedef struct ike_sa_manager_t ike_sa_manager_t;
#include <config/peer_cfg.h>
/**
- * @brief The IKE_SA-Manager is responsible for managing all initiated and responded IKE_SA's.
+ * The IKE_SA-Manager is responsible for managing all initiated and responded IKE_SA's.
*
* To avoid access from multiple threads, IKE_SAs must be checked out from
* the manager, and checked in after usage.
@@ -42,18 +42,12 @@ typedef struct ike_sa_manager_t ike_sa_manager_t;
* This could be done by comparing thread-ids via pthread_self()...
*
* @todo Managing of ike_sa_t objects in a hash table instead of linked list.
- *
- * @b Constructors:
- * - ike_sa_manager_create()
- *
- * @ingroup sa
*/
struct ike_sa_manager_t {
/**
- * @brief Checkout an existing IKE_SA.
+ * Checkout an existing IKE_SA.
*
- * @param this the manager object
* @param ike_sa_id the SA identifier, will be updated
* @returns
* - checked out IKE_SA if found
@@ -62,16 +56,15 @@ struct ike_sa_manager_t {
ike_sa_t* (*checkout) (ike_sa_manager_t* this, ike_sa_id_t *sa_id);
/**
- * @brief Create and check out a new IKE_SA.
+ * Create and check out a new IKE_SA.
*
- * @param this the manager object
* @param initiator TRUE for initiator, FALSE otherwise
* @returns created andchecked out IKE_SA
*/
ike_sa_t* (*checkout_new) (ike_sa_manager_t* this, bool initiator);
/**
- * @brief Checkout an IKE_SA by a message.
+ * Checkout an IKE_SA by a message.
*
* In some situations, it is necessary that the manager knows the
* message to use for the checkout. This has the folloing reasons:
@@ -86,7 +79,6 @@ struct ike_sa_manager_t {
* If processing the message does not make sense (for the reasons above),
* NULL is returned.
*
- * @param this the manager object
* @param ike_sa_id the SA identifier, will be updated
* @returns
* - checked out/created IKE_SA
@@ -95,7 +87,7 @@ struct ike_sa_manager_t {
ike_sa_t* (*checkout_by_message) (ike_sa_manager_t* this, message_t *message);
/**
- * @brief Checkout an IKE_SA for initiation by a peer_config.
+ * Checkout an IKE_SA for initiation by a peer_config.
*
* To initiate, a CHILD_SA may be established within an existing IKE_SA.
* This call checks for an existing IKE_SA by comparing the configuration.
@@ -104,7 +96,6 @@ struct ike_sa_manager_t {
* If no IKE_SA is found, a new one is created. This is also the case when
* the found IKE_SA is in the DELETING state.
*
- * @param this the manager object
* @param peer_cfg configuration used to find an existing IKE_SA
* @return checked out/created IKE_SA
*/
@@ -112,14 +103,21 @@ struct ike_sa_manager_t {
peer_cfg_t *peer_cfg);
/**
- * @brief Check out an IKE_SA a unique ID.
+ * Check out a duplicate if ike_sa to do uniqueness tests.
+ *
+ * @param ike_sa ike_sa to get a duplicate from
+ * @return checked out duplicate
+ */
+ ike_sa_t* (*checkout_duplicate)(ike_sa_manager_t *this, ike_sa_t *ike_sa);
+
+ /**
+ * Check out an IKE_SA a unique ID.
*
* Every IKE_SA and every CHILD_SA is uniquely identified by an ID.
* These checkout function uses, depending
* on the child parameter, the unique ID of the IKE_SA or the reqid
* of one of a IKE_SAs CHILD_SA.
*
- * @param this the manager object
* @param id unique ID of the object
* @param child TRUE to use CHILD, FALSE to use IKE_SA
* @return
@@ -130,12 +128,11 @@ struct ike_sa_manager_t {
bool child);
/**
- * @brief Check out an IKE_SA by the policy/connection name.
+ * Check out an IKE_SA by the policy/connection name.
*
* Check out the IKE_SA by the connections name or by a CHILD_SAs policy
* name.
*
- * @param this the manager object
* @param name name of the connection/policy
* @param child TRUE to use policy name, FALSE to use conn name
* @return
@@ -146,24 +143,21 @@ struct ike_sa_manager_t {
bool child);
/**
- * @brief Create an iterator over all stored IKE_SAs.
+ * Create an enumerator over all stored IKE_SAs.
*
- * The avoid synchronization issues, the iterator locks access
+ * The avoid synchronization issues, the enumerator locks access
* to the manager exclusively, until it gets destroyed.
- * This iterator is for reading only! Writing will corrupt the manager.
*
- * @param this the manager object
- * @return iterator over all IKE_SAs.
+ * @return enumerator over all IKE_SAs.
*/
- iterator_t *(*create_iterator) (ike_sa_manager_t* this);
+ enumerator_t *(*create_enumerator) (ike_sa_manager_t* this);
/**
- * @brief Checkin the SA after usage.
+ * Checkin the SA after usage.
*
* @warning the SA pointer MUST NOT be used after checkin!
* The SA must be checked out again!
*
- * @param this the manager object
* @param ike_sa_id the SA identifier, will be updated
* @param ike_sa checked out SA
* @returns
@@ -173,7 +167,7 @@ struct ike_sa_manager_t {
status_t (*checkin) (ike_sa_manager_t* this, ike_sa_t *ike_sa);
/**
- * @brief Destroy a checked out SA.
+ * Destroy a checked out SA.
*
* The IKE SA is destroyed without notification of the remote peer.
* Use this only if the other peer doesn't respond or behaves not
@@ -182,7 +176,6 @@ struct ike_sa_manager_t {
* so this can be called if the SA is in a "unclean" state, without the
* risk that another thread can get the SA.
*
- * @param this the manager object
* @param ike_sa SA to delete
* @returns
* - SUCCESS if found
@@ -191,7 +184,7 @@ struct ike_sa_manager_t {
status_t (*checkin_and_destroy) (ike_sa_manager_t* this, ike_sa_t *ike_sa);
/**
- * @brief Get the number of IKE_SAs which are in the connecting state.
+ * Get the number of IKE_SAs which are in the connecting state.
*
* To prevent the server from resource exhaustion, cookies and other
* mechanisms are used. The number of half open IKE_SAs is a good
@@ -200,29 +193,31 @@ struct ike_sa_manager_t {
* from this IP are counted.
* Only SAs for which we are the responder are counted.
*
- * @param this the manager object
* @param ip NULL for all, IP for half open IKE_SAs with IP
* @return number of half open IKE_SAs
*/
int (*get_half_open_count) (ike_sa_manager_t *this, host_t *ip);
/**
- * @brief Destroys the manager with all associated SAs.
+ * Delete all existing IKE_SAs and destroy them immediately.
*
* Threads will be driven out, so all SAs can be deleted cleanly.
- *
- * @param this the manager object
+ */
+ void (*flush)(ike_sa_manager_t *this);
+
+ /**
+ * Destroys the manager with all associated SAs.
+ *
+ * A call to flush() is required before calling destroy.
*/
void (*destroy) (ike_sa_manager_t *this);
};
/**
- * @brief Create a manager.
- *
- * @returns ike_sa_manager_t object
+ * Create a manager.
*
- * @ingroup sa
+ * @returns ike_sa_manager_t object, NULL if initialization fails
*/
ike_sa_manager_t *ike_sa_manager_create(void);
-#endif /*IKE_SA_MANAGER_H_*/
+#endif /*IKE_SA_MANAGER_H_ @} */
diff --git a/src/charon/sa/mediation_manager.c b/src/charon/sa/mediation_manager.c
index f6137304d..d15f4c100 100644
--- a/src/charon/sa/mediation_manager.c
+++ b/src/charon/sa/mediation_manager.c
@@ -1,10 +1,3 @@
-/**
- * @file mediation_manager.c
- *
- * @brief Implementation of mediation_manager_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: mediation_manager.c 3773 2008-04-07 09:36:52Z tobias $
*/
#include "mediation_manager.h"
@@ -246,6 +241,7 @@ static void update_sa_id(private_mediation_manager_t *this, identification_t *pe
{
job_t *job = (job_t*)mediation_callback_job_create(requester, peer_id);
charon->processor->queue_job(charon->processor, job);
+ requester->destroy(requester);
}
pthread_mutex_unlock(&(this->mutex));
diff --git a/src/charon/sa/mediation_manager.h b/src/charon/sa/mediation_manager.h
index 74acc4d41..d21c93244 100644
--- a/src/charon/sa/mediation_manager.h
+++ b/src/charon/sa/mediation_manager.h
@@ -1,10 +1,3 @@
-/**
- * @file mediation_manager.h
- *
- * @brief Interface of mediation_manager_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: mediation_manager.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup mediation_manager mediation_manager
+ * @{ @ingroup sa
*/
#ifndef MEDIATION_MANAGER_H_
@@ -29,29 +29,22 @@ typedef struct mediation_manager_t mediation_manager_t;
#include <utils/identification.h>
/**
- * @brief The mediation manager is responsible for managing currently online
+ * The mediation manager is responsible for managing currently online
* peers and registered requests for offline peers on the mediation server.
- *
- * @b Constructors:
- * - mediation_manager_create()
- *
- * @ingroup sa
*/
struct mediation_manager_t {
/**
- * @brief Remove the IKE_SA of a peer.
+ * Remove the IKE_SA of a peer.
*
- * @param this the manager object
* @param ike_sa_id the IKE_SA ID of the peer's SA
*/
void (*remove) (mediation_manager_t* this, ike_sa_id_t *ike_sa_id);
/**
- * @brief Update the ike_sa_id that is assigned to a peer's ID. If the peer
+ * Update the ike_sa_id that is assigned to a peer's ID. If the peer
* is new, it gets a new record assigned.
*
- * @param this the manager object
* @param peer_id the peer's ID
* @param ike_sa_id the IKE_SA ID of the peer's SA
*/
@@ -59,9 +52,8 @@ struct mediation_manager_t {
ike_sa_id_t *ike_sa_id);
/**
- * @brief Checks if a specific peer is online.
+ * Checks if a specific peer is online.
*
- * @param this the manager object
* @param peer_id the peer's ID
* @returns
* - IKE_SA ID of the peer's SA.
@@ -71,10 +63,9 @@ struct mediation_manager_t {
identification_t *peer_id);
/**
- * @brief Checks if a specific peer is online and registers the requesting
+ * Checks if a specific peer is online and registers the requesting
* peer if it is not.
*
- * @param this the manager object
* @param peer_id the peer's ID
* @param requester the requesters ID
* @returns
@@ -85,20 +76,16 @@ struct mediation_manager_t {
identification_t *peer_id, identification_t *requester);
/**
- * @brief Destroys the manager with all data.
- *
- * @param this the manager object
+ * Destroys the manager with all data.
*/
void (*destroy) (mediation_manager_t *this);
};
/**
- * @brief Create a manager.
+ * Create a manager.
*
* @returns mediation_manager_t object
- *
- * @ingroup sa
*/
mediation_manager_t *mediation_manager_create(void);
-#endif /*MEDIATION_MANAGER_H_*/
+#endif /*MEDIATION_MANAGER_H_ @} */
diff --git a/src/charon/sa/task_manager.c b/src/charon/sa/task_manager.c
index 89f527aba..e453fff00 100644
--- a/src/charon/sa/task_manager.c
+++ b/src/charon/sa/task_manager.c
@@ -1,10 +1,3 @@
-/**
- * @file task_manager.c
- *
- * @brief Implementation of task_manager_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2007 Martin Willi
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: task_manager.c 3666 2008-03-26 18:40:19Z tobias $
*/
#include "task_manager.h"
@@ -31,7 +26,8 @@
#include <sa/tasks/ike_mobike.h>
#include <sa/tasks/ike_auth.h>
#include <sa/tasks/ike_auth_lifetime.h>
-#include <sa/tasks/ike_cert.h>
+#include <sa/tasks/ike_cert_pre.h>
+#include <sa/tasks/ike_cert_post.h>
#include <sa/tasks/ike_rekey.h>
#include <sa/tasks/ike_delete.h>
#include <sa/tasks/ike_config.h>
@@ -42,8 +38,8 @@
#include <encoding/payloads/delete_payload.h>
#include <processing/jobs/retransmit_job.h>
-#ifdef P2P
-#include <sa/tasks/ike_p2p.h>
+#ifdef ME
+#include <sa/tasks/ike_me.h>
#endif
typedef struct exchange_t exchange_t;
@@ -328,15 +324,16 @@ static status_t build_request(private_task_manager_t *this)
this->initiating.mid = 0;
exchange = IKE_SA_INIT;
activate_task(this, IKE_NATD);
- activate_task(this, IKE_CERT);
-#ifdef P2P
+ activate_task(this, IKE_CERT_PRE);
+#ifdef ME
/* this task has to be activated before the IKE_AUTHENTICATE
* task, because that task pregenerates the packet after
* which no payloads can be added to the message anymore.
*/
- activate_task(this, IKE_P2P);
-#endif /* P2P */
+ activate_task(this, IKE_ME);
+#endif /* ME */
activate_task(this, IKE_AUTHENTICATE);
+ activate_task(this, IKE_CERT_POST);
activate_task(this, IKE_CONFIG);
activate_task(this, CHILD_CREATE);
activate_task(this, IKE_AUTH_LIFETIME);
@@ -384,13 +381,13 @@ static status_t build_request(private_task_manager_t *this)
exchange = INFORMATIONAL;
break;
}
-#ifdef P2P
- if (activate_task(this, IKE_P2P))
+#ifdef ME
+ if (activate_task(this, IKE_ME))
{
- exchange = P2P_CONNECT;
+ exchange = ME_CONNECT;
break;
}
-#endif /* P2P */
+#endif /* ME */
case IKE_REKEYING:
if (activate_task(this, IKE_DELETE))
{
@@ -687,14 +684,16 @@ static status_t process_request(private_task_manager_t *this,
this->passive_tasks->insert_last(this->passive_tasks, task);
task = (task_t*)ike_natd_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
- task = (task_t*)ike_cert_create(this->ike_sa, FALSE);
+ task = (task_t*)ike_cert_pre_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
-#ifdef P2P
- task = (task_t*)ike_p2p_create(this->ike_sa, FALSE);
+#ifdef ME
+ task = (task_t*)ike_me_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
-#endif /* P2P */
+#endif /* ME */
task = (task_t*)ike_auth_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
+ task = (task_t*)ike_cert_post_create(this->ike_sa, FALSE);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
task = (task_t*)ike_config_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
task = (task_t*)child_create_create(this->ike_sa, NULL);
@@ -818,13 +817,13 @@ static status_t process_request(private_task_manager_t *this,
this->passive_tasks->insert_last(this->passive_tasks, task);
break;
}
-#ifdef P2P
- case P2P_CONNECT:
+#ifdef ME
+ case ME_CONNECT:
{
- task = (task_t*)ike_p2p_create(this->ike_sa, FALSE);
+ task = (task_t*)ike_me_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
}
-#endif /* P2P */
+#endif /* ME */
default:
break;
}
diff --git a/src/charon/sa/task_manager.h b/src/charon/sa/task_manager.h
index 38c63c1a9..6243ac888 100644
--- a/src/charon/sa/task_manager.h
+++ b/src/charon/sa/task_manager.h
@@ -1,10 +1,3 @@
-/**
- * @file task_manager.h
- *
- * @brief Interface of task_manager_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: task_manager.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup task_manager task_manager
+ * @{ @ingroup sa
*/
#ifndef TASK_MANAGER_H_
@@ -32,42 +32,32 @@ typedef struct task_manager_t task_manager_t;
/**
* First retransmit timeout in milliseconds.
- *
- * @ingroup sa
*/
#define RETRANSMIT_TIMEOUT 4000
/**
* Base which is raised to the power of the retransmission try.
- *
- * @ingroup sa
*/
#define RETRANSMIT_BASE 1.8
/**
* Number of retransmits done before giving up.
- *
- * @ingroup sa
*/
#define RETRANSMIT_TRIES 5
/**
* Interval for mobike routability checks in ms.
- *
- * @ingroup sa
*/
#define ROUTEABILITY_CHECK_INTERVAL 2500
/**
* Number of routability checks before giving up
- *
- * @ingroup sa
*/
#define ROUTEABILITY_CHECK_TRIES 10
/**
- * @brief The task manager, juggles task and handles message exchanges.
+ * The task manager, juggles task and handles message exchanges.
*
* On incoming requests, the task manager creates new tasks on demand and
* juggles the request through all available tasks. Each task inspects the
@@ -97,18 +87,12 @@ typedef struct task_manager_t task_manager_t;
@endberbatim
* The peer is considered dead after 2min 45s when no reply comes in.
- *
- * @b Constructors:
- * - task_manager_create()
- *
- * @ingroup sa
*/
struct task_manager_t {
/**
- * @brief Process an incoming message.
+ * Process an incoming message.
*
- * @param this calling object
* @param message message to add payloads to
* @return
* - DESTROY_ME if IKE_SA must be closed
@@ -117,28 +101,24 @@ struct task_manager_t {
status_t (*process_message) (task_manager_t *this, message_t *message);
/**
- * @brief Initiate an exchange with the currently queued tasks.
- *
- * @param this calling object
+ * Initiate an exchange with the currently queued tasks.
*/
status_t (*initiate) (task_manager_t *this);
/**
- * @brief Queue a task in the manager.
+ * Queue a task in the manager.
*
- * @param this calling object
* @param task task to queue
*/
void (*queue_task) (task_manager_t *this, task_t *task);
/**
- * @brief Retransmit a request if it hasn't been acknowledged yet.
+ * Retransmit a request if it hasn't been acknowledged yet.
*
* A return value of INVALID_STATE means that the message was already
* acknowledged and has not to be retransmitted. A return value of SUCCESS
* means retransmission was required and the message has been resent.
*
- * @param this calling object
* @param message_id ID of the message to retransmit
* @return
* - INVALID_STATE if retransmission not required
@@ -147,52 +127,45 @@ struct task_manager_t {
status_t (*retransmit) (task_manager_t *this, u_int32_t message_id);
/**
- * @brief Migrate all tasks from other to this.
+ * Migrate all tasks from other to this.
*
* To rekey or reestablish an IKE_SA completely, all queued or active
* tasks should get migrated to the new IKE_SA.
*
- * @param this manager which gets all tasks
* @param other manager which gives away its tasks
*/
void (*adopt_tasks) (task_manager_t *this, task_manager_t *other);
/**
- * @brief Reset message ID counters of the task manager.
+ * Reset message ID counters of the task manager.
*
* The IKEv2 protocol requires to restart exchanges with message IDs
* reset to zero (INVALID_KE_PAYLOAD, COOKIES, ...). The reset() method
* resets the message IDs and resets all active tasks using the migrate()
* method.
*
- * @param this calling object
* @param other manager which gives away its tasks
*/
void (*reset) (task_manager_t *this);
/**
- * @brief Check if we are currently waiting for a reply.
+ * Check if we are currently waiting for a reply.
*
- * @param this calling object
* @return TRUE if we are waiting, FALSE otherwise
*/
bool (*busy) (task_manager_t *this);
/**
- * @brief Destroy the task_manager_t.
- *
- * @param this calling object
+ * Destroy the task_manager_t.
*/
void (*destroy) (task_manager_t *this);
};
/**
- * @brief Create an instance of the task manager.
+ * Create an instance of the task manager.
*
* @param ike_sa IKE_SA to manage.
- *
- * @ingroup sa
*/
task_manager_t *task_manager_create(ike_sa_t *ike_sa);
-#endif /* TASK_MANAGER_H_ */
+#endif /* TASK_MANAGER_H_ @} */
diff --git a/src/charon/sa/tasks/child_create.c b/src/charon/sa/tasks/child_create.c
index 3947a84d1..4638da03e 100644
--- a/src/charon/sa/tasks/child_create.c
+++ b/src/charon/sa/tasks/child_create.c
@@ -1,11 +1,5 @@
-/**
- * @file child_create.c
- *
- * @brief Implementation of the child_create task.
- *
- */
-
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -19,6 +13,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: child_create.c 3920 2008-05-08 16:19:11Z tobias $
*/
#include "child_create.h"
@@ -105,6 +101,21 @@ struct private_child_create_t {
mode_t mode;
/**
+ * IPComp transform to use
+ */
+ ipcomp_transform_t ipcomp;
+
+ /**
+ * IPComp transform proposed or accepted by the other peer
+ */
+ ipcomp_transform_t ipcomp_received;
+
+ /**
+ * Other Compression Parameter Index (CPI)
+ */
+ u_int16_t other_cpi;
+
+ /**
* reqid to use if we are rekeying
*/
u_int32_t reqid;
@@ -141,17 +152,16 @@ static status_t get_nonce(message_t *message, chunk_t *nonce)
*/
static status_t generate_nonce(chunk_t *nonce)
{
- status_t status;
- randomizer_t *randomizer = randomizer_create();
+ rng_t *rng;
- status = randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_SIZE,
- nonce);
- randomizer->destroy(randomizer);
- if (status != SUCCESS)
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (!rng)
{
- DBG1(DBG_IKE, "error generating random nonce value");
+ DBG1(DBG_IKE, "error generating nonce value, no RNG found");
return FAILED;
}
+ rng->allocate_bytes(rng, NONCE_SIZE, nonce);
+ rng->destroy(rng);
return SUCCESS;
}
@@ -227,11 +237,11 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
if (!this->proposal->has_dh_group(this->proposal, this->dh_group))
{
- algorithm_t *algo;
+ u_int16_t group;
+
if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP,
- &algo))
+ &group, NULL))
{
- u_int16_t group = algo->algorithm;
SIG(CHILD_UP_FAILED, "DH group %N inacceptable, requesting %N",
diffie_hellman_group_names, this->dh_group,
diffie_hellman_group_names, group);
@@ -332,6 +342,12 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
}
prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
+ if (this->ipcomp != IPCOMP_NONE)
+ {
+ this->child_sa->activate_ipcomp(this->child_sa, this->ipcomp,
+ this->other_cpi);
+ }
+
if (this->initiator)
{
status = this->child_sa->update(this->child_sa, this->proposal,
@@ -422,6 +438,36 @@ static void build_payloads(private_child_create_t *this, message_t *message)
}
/**
+ * Adds an IPCOMP_SUPPORTED notify to the message, if possible
+ */
+static void build_ipcomp_supported_notify(private_child_create_t *this, message_t *message)
+{
+ if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
+ {
+ DBG1(DBG_IKE, "IPComp is not supported if either peer is natted, IPComp is disabled");
+ this->ipcomp = IPCOMP_NONE;
+ return;
+ }
+
+ u_int16_t cpi = this->child_sa->get_my_cpi(this->child_sa);
+ if (cpi)
+ {
+ chunk_t cpi_chunk, tid_chunk, data;
+ u_int8_t tid = this->ipcomp;
+ cpi_chunk = chunk_from_thing(cpi);
+ tid_chunk = chunk_from_thing(tid);
+ data = chunk_cat("cc", cpi_chunk, tid_chunk);
+ message->add_notify(message, FALSE, IPCOMP_SUPPORTED, data);
+ chunk_free(&data);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "unable to allocate a CPI from kernel, IPComp is disabled");
+ this->ipcomp = IPCOMP_NONE;
+ }
+}
+
+/**
* Read payloads from message
*/
static void process_payloads(private_child_create_t *this, message_t *message)
@@ -450,7 +496,7 @@ static void process_payloads(private_child_create_t *this, message_t *message)
if (!this->initiator)
{
this->dh_group = ke_payload->get_dh_group_number(ke_payload);
- this->dh = diffie_hellman_create(this->dh_group);
+ this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
}
if (this->dh)
{
@@ -476,6 +522,25 @@ static void process_payloads(private_child_create_t *this, message_t *message)
case USE_BEET_MODE:
this->mode = MODE_BEET;
break;
+ case IPCOMP_SUPPORTED:
+ {
+ chunk_t data = notify_payload->get_notification_data(notify_payload);
+ u_int16_t cpi = *(u_int16_t*)data.ptr;
+ ipcomp_transform_t ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
+ switch(ipcomp)
+ {
+ case IPCOMP_DEFLATE:
+ this->other_cpi = cpi;
+ this->ipcomp_received = ipcomp;
+ break;
+ case IPCOMP_LZS:
+ case IPCOMP_LZJH:
+ default:
+ DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a transform"
+ " ID we don't support %N", ipcomp_transform_names, ipcomp);
+ break;
+ }
+ }
default:
break;
}
@@ -540,11 +605,10 @@ static status_t build_i(private_child_create_t *this, message_t *message)
if (!this->reqid)
{
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
- vip = peer_cfg->get_my_virtual_ip(peer_cfg);
+ vip = peer_cfg->get_virtual_ip(peer_cfg);
if (vip)
{
propose_all = TRUE;
- vip->destroy(vip);
}
}
@@ -580,7 +644,13 @@ static status_t build_i(private_child_create_t *this, message_t *message)
if (this->dh_group != MODP_NONE)
{
- this->dh = diffie_hellman_create(this->dh_group);
+ this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
+ }
+
+ if (this->config->use_ipcomp(this->config)) {
+ /* IPCOMP_DEFLATE is the only transform we support at the moment */
+ this->ipcomp = IPCOMP_DEFLATE;
+ build_ipcomp_supported_notify(this, message);
}
build_payloads(this, message);
@@ -700,6 +770,16 @@ static status_t build_r(private_child_create_t *this, message_t *message)
this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid,
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
+ if (this->config->use_ipcomp(this->config) && this->ipcomp_received != IPCOMP_NONE)
+ {
+ this->ipcomp = this->ipcomp_received;
+ build_ipcomp_supported_notify(this, message);
+ }
+ else if (this->ipcomp_received != IPCOMP_NONE)
+ {
+ DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify but IPComp is disabled, ignoring");
+ }
+
switch (select_and_install(this, no_dh))
{
case SUCCESS:
@@ -806,6 +886,25 @@ static status_t process_i(private_child_create_t *this, message_t *message)
process_payloads(this, message);
+ if (this->ipcomp == IPCOMP_NONE && this->ipcomp_received != IPCOMP_NONE)
+ {
+ SIG(CHILD_UP_FAILED, "received an IPCOMP_SUPPORTED notify but we did not "
+ "send one previously, no CHILD_SA built");
+ return SUCCESS;
+ }
+ else if (this->ipcomp != IPCOMP_NONE && this->ipcomp_received == IPCOMP_NONE)
+ {
+ DBG1(DBG_IKE, "peer didn't accept our proposed IPComp transforms, "
+ "IPComp is disabled");
+ this->ipcomp = IPCOMP_NONE;
+ }
+ else if (this->ipcomp != IPCOMP_NONE && this->ipcomp != this->ipcomp_received)
+ {
+ SIG(CHILD_UP_FAILED, "received an IPCOMP_SUPPORTED notify for a transform "
+ "we did not propose, no CHILD_SA built");
+ return SUCCESS;
+ }
+
if (select_and_install(this, no_dh) == SUCCESS)
{
SIG(CHILD_UP_SUCCESS, "CHILD_SA '%s' established successfully",
@@ -884,6 +983,9 @@ static void migrate(private_child_create_t *this, ike_sa_t *ike_sa)
this->dh = NULL;
this->child_sa = NULL;
this->mode = MODE_TUNNEL;
+ this->ipcomp = IPCOMP_NONE;
+ this->ipcomp_received = IPCOMP_NONE;
+ this->other_cpi = 0;
this->reqid = 0;
this->established = FALSE;
}
@@ -957,6 +1059,9 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config)
this->dh_group = MODP_NONE;
this->child_sa = NULL;
this->mode = MODE_TUNNEL;
+ this->ipcomp = IPCOMP_NONE;
+ this->ipcomp_received = IPCOMP_NONE;
+ this->other_cpi = 0;
this->reqid = 0;
this->established = FALSE;
diff --git a/src/charon/sa/tasks/child_create.h b/src/charon/sa/tasks/child_create.h
index 9f4815215..cee37121e 100644
--- a/src/charon/sa/tasks/child_create.h
+++ b/src/charon/sa/tasks/child_create.h
@@ -1,10 +1,3 @@
-/**
- * @file child_create.h
- *
- * @brief Interface child_create_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: child_create.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup child_create child_create
+ * @{ @ingroup tasks
*/
#ifndef CHILD_CREATE_H_
@@ -31,15 +31,10 @@ typedef struct child_create_t child_create_t;
#include <config/child_cfg.h>
/**
- * @brief Task of type CHILD_CREATE, established a new CHILD_SA.
+ * Task of type CHILD_CREATE, established a new CHILD_SA.
*
* This task may be included in the IKE_AUTH message or in a separate
* CREATE_CHILD_SA exchange.
- *
- * @b Constructors:
- * - child_create_create()
- *
- * @ingroup tasks
*/
struct child_create_t {
@@ -49,35 +44,32 @@ struct child_create_t {
task_t task;
/**
- * @brief Use a specific reqid for the CHILD_SA.
+ * Use a specific reqid for the CHILD_SA.
*
* When this task is used for rekeying, the same reqid is used
* for the new CHILD_SA.
*
- * @param this calling object
* @param reqid reqid to use
*/
void (*use_reqid) (child_create_t *this, u_int32_t reqid);
/**
- * @brief Get the lower of the two nonces, used for rekey collisions.
+ * Get the lower of the two nonces, used for rekey collisions.
*
- * @param this calling object
* @return lower nonce
*/
chunk_t (*get_lower_nonce) (child_create_t *this);
/**
- * @brief Get the CHILD_SA established/establishing by this task.
+ * Get the CHILD_SA established/establishing by this task.
*
- * @param this calling object
* @return child_sa
*/
child_sa_t* (*get_child) (child_create_t *this);
};
/**
- * @brief Create a new child_create task.
+ * Create a new child_create task.
*
* @param ike_sa IKE_SA this task works for
* @param config child_cfg if task initiator, NULL if responder
@@ -85,4 +77,4 @@ struct child_create_t {
*/
child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config);
-#endif /* CHILD_CREATE_H_ */
+#endif /* CHILD_CREATE_H_ @} */
diff --git a/src/charon/sa/tasks/child_delete.c b/src/charon/sa/tasks/child_delete.c
index d0b34a276..4156f9704 100644
--- a/src/charon/sa/tasks/child_delete.c
+++ b/src/charon/sa/tasks/child_delete.c
@@ -1,10 +1,3 @@
-/**
- * @file child_delete.c
- *
- * @brief Implementation of the child_delete task.
- *
- */
-
/*
* Copyright (C) 2006-2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: child_delete.c 3802 2008-04-14 08:17:18Z martin $
*/
#include "child_delete.h"
@@ -157,23 +152,48 @@ static void process_payloads(private_child_delete_t *this, message_t *message)
}
/**
- * destroy the children listed in this->child_sas
+ * destroy the children listed in this->child_sas, reestablish by policy
*/
-static void destroy_children(private_child_delete_t *this)
+static status_t destroy_and_reestablish(private_child_delete_t *this)
{
iterator_t *iterator;
child_sa_t *child_sa;
+ child_cfg_t *child_cfg;
protocol_id_t protocol;
u_int32_t spi;
+ status_t status = SUCCESS;
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
while (iterator->iterate(iterator, (void**)&child_sa))
{
spi = child_sa->get_spi(child_sa, TRUE);
protocol = child_sa->get_protocol(child_sa);
+ child_cfg = child_sa->get_config(child_sa);
+ child_cfg->get_ref(child_cfg);
this->ike_sa->destroy_child_sa(this->ike_sa, protocol, spi);
+ if (!this->initiator)
+ { /* enforce child_cfg policy if deleted passively */
+ switch (child_cfg->get_close_action(child_cfg))
+ {
+ case ACTION_RESTART:
+ child_cfg->get_ref(child_cfg);
+ status = this->ike_sa->initiate(this->ike_sa, child_cfg);
+ break;
+ case ACTION_ROUTE:
+ status = this->ike_sa->route(this->ike_sa, child_cfg);
+ break;
+ default:
+ break;
+ }
+ }
+ child_cfg->destroy(child_cfg);
+ if (status != SUCCESS)
+ {
+ break;
+ }
}
iterator->destroy(iterator);
+ return status;
}
/**
@@ -214,9 +234,8 @@ static status_t process_i(private_child_delete_t *this, message_t *message)
this->child_sas = linked_list_create();
process_payloads(this, message);
- destroy_children(this);
SIG(CHILD_DOWN_SUCCESS, "CHILD_SA closed");
- return SUCCESS;
+ return destroy_and_reestablish(this);
}
/**
@@ -239,9 +258,8 @@ static status_t build_r(private_child_delete_t *this, message_t *message)
{
build_payloads(this, message);
}
- destroy_children(this);
SIG(CHILD_DOWN_SUCCESS, "CHILD_SA closed");
- return SUCCESS;
+ return destroy_and_reestablish(this);
}
/**
diff --git a/src/charon/sa/tasks/child_delete.h b/src/charon/sa/tasks/child_delete.h
index a7e676a50..c304ea9d8 100644
--- a/src/charon/sa/tasks/child_delete.h
+++ b/src/charon/sa/tasks/child_delete.h
@@ -1,10 +1,3 @@
-/**
- * @file child_delete.h
- *
- * @brief Interface child_delete_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: child_delete.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup child_delete child_delete
+ * @{ @ingroup tasks
*/
#ifndef CHILD_DELETE_H_
@@ -31,12 +31,7 @@ typedef struct child_delete_t child_delete_t;
#include <sa/child_sa.h>
/**
- * @brief Task of type child_delete, delete a CHILD_SA.
- *
- * @b Constructors:
- * - child_delete_create()
- *
- * @ingroup tasks
+ * Task of type child_delete, delete a CHILD_SA.
*/
struct child_delete_t {
@@ -46,16 +41,15 @@ struct child_delete_t {
task_t task;
/**
- * @brief Get the CHILD_SA to delete by this task.
+ * Get the CHILD_SA to delete by this task.
*
- * @param this calling object
* @return child_sa
*/
child_sa_t* (*get_child) (child_delete_t *this);
};
/**
- * @brief Create a new child_delete task.
+ * Create a new child_delete task.
*
* @param ike_sa IKE_SA this task works for
* @param child_sa CHILD_SA to delete, or NULL as responder
@@ -63,4 +57,4 @@ struct child_delete_t {
*/
child_delete_t *child_delete_create(ike_sa_t *ike_sa, child_sa_t *child_sa);
-#endif /* CHILD_DELETE_H_ */
+#endif /* CHILD_DELETE_H_ @} */
diff --git a/src/charon/sa/tasks/child_rekey.c b/src/charon/sa/tasks/child_rekey.c
index 3667d8fad..3953951a3 100644
--- a/src/charon/sa/tasks/child_rekey.c
+++ b/src/charon/sa/tasks/child_rekey.c
@@ -1,10 +1,3 @@
-/**
- * @file child_rekey.c
- *
- * @brief Implementation of the child_rekey task.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: child_rekey.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "child_rekey.h"
diff --git a/src/charon/sa/tasks/child_rekey.h b/src/charon/sa/tasks/child_rekey.h
index 3515f0c3f..b386ef3c6 100644
--- a/src/charon/sa/tasks/child_rekey.h
+++ b/src/charon/sa/tasks/child_rekey.h
@@ -1,10 +1,3 @@
-/**
- * @file child_rekey.h
- *
- * @brief Interface child_rekey_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: child_rekey.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup child_rekey child_rekey
+ * @{ @ingroup tasks
*/
#ifndef CHILD_REKEY_H_
@@ -31,12 +31,7 @@ typedef struct child_rekey_t child_rekey_t;
#include <sa/tasks/task.h>
/**
- * @brief Task of type CHILD_REKEY, rekey an established CHILD_SA.
- *
- * @b Constructors:
- * - child_rekey_create()
- *
- * @ingroup tasks
+ * Task of type CHILD_REKEY, rekey an established CHILD_SA.
*/
struct child_rekey_t {
@@ -46,20 +41,19 @@ struct child_rekey_t {
task_t task;
/**
- * @brief Register a rekeying task which collides with this one
+ * Register a rekeying task which collides with this one
*
* If two peers initiate rekeying at the same time, the collision must
* be handled gracefully. The task manager is aware of what exchanges
* are going on and notifies the outgoing task by passing the incoming.
*
- * @param this task initated by us
* @param other incoming task
*/
void (*collide)(child_rekey_t* this, task_t *other);
};
/**
- * @brief Create a new CHILD_REKEY task.
+ * Create a new CHILD_REKEY task.
*
* @param ike_sa IKE_SA this task works for
* @param child_sa child_sa to rekey, NULL if responder
@@ -67,4 +61,4 @@ struct child_rekey_t {
*/
child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, child_sa_t *child_sa);
-#endif /* CHILD_REKEY_H_ */
+#endif /* CHILD_REKEY_H_ @} */
diff --git a/src/charon/sa/tasks/ike_auth.c b/src/charon/sa/tasks/ike_auth.c
index de88a0abe..fd5012ee6 100644
--- a/src/charon/sa/tasks/ike_auth.c
+++ b/src/charon/sa/tasks/ike_auth.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_auth.c
- *
- * @brief Implementation of the ike_auth task.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -18,7 +11,9 @@
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * for more details
+ *
+ * $Id: ike_auth.c 4051 2008-06-10 09:08:27Z tobias $
*/
#include "ike_auth.h"
@@ -94,6 +89,68 @@ struct private_ike_auth_t {
};
/**
+ * check uniqueness and delete duplicates
+ */
+static bool check_uniqueness(private_ike_auth_t *this)
+{
+ ike_sa_t *duplicate;
+ unique_policy_t policy;
+ status_t status = SUCCESS;
+ peer_cfg_t *peer_cfg;
+ bool cancel = FALSE;
+
+ peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
+ policy = peer_cfg->get_unique_policy(peer_cfg);
+ if (policy == UNIQUE_NO)
+ {
+ return FALSE;
+ }
+ duplicate = charon->ike_sa_manager->checkout_duplicate(
+ charon->ike_sa_manager, this->ike_sa);
+ if (duplicate)
+ {
+ peer_cfg = duplicate->get_peer_cfg(duplicate);
+ if (peer_cfg &&
+ peer_cfg->equals(peer_cfg, this->ike_sa->get_peer_cfg(this->ike_sa)))
+ {
+ switch (duplicate->get_state(duplicate))
+ {
+ case IKE_ESTABLISHED:
+ case IKE_REKEYING:
+ switch (policy)
+ {
+ case UNIQUE_REPLACE:
+ DBG1(DBG_IKE, "deleting duplicate IKE_SA due "
+ "uniqueness policy");
+ status = duplicate->delete(duplicate);
+ break;
+ case UNIQUE_KEEP:
+ DBG1(DBG_IKE, "cancelling IKE_SA setup due "
+ "uniqueness policy");
+ cancel = TRUE;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (status == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+ duplicate);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, duplicate);
+ }
+ }
+ return cancel;
+}
+
+/**
* build the AUTH payload
*/
static status_t build_auth(private_ike_auth_t *this, message_t *message)
@@ -101,7 +158,7 @@ static status_t build_auth(private_ike_auth_t *this, message_t *message)
authenticator_t *auth;
auth_payload_t *auth_payload;
peer_cfg_t *config;
- auth_method_t method;
+ config_auth_method_t method;
status_t status;
/* create own authenticator and add auth payload */
@@ -117,7 +174,7 @@ static status_t build_auth(private_ike_auth_t *this, message_t *message)
if (auth == NULL)
{
SIG(IKE_UP_FAILED, "configured authentication method %N not supported",
- auth_method_names, method);
+ config_auth_method_names, method);
return FAILED;
}
@@ -186,13 +243,13 @@ static status_t process_auth(private_ike_auth_t *this, message_t *message)
/* AUTH payload is missing, client wants to use EAP authentication */
return NOT_FOUND;
}
-
+
auth_method = auth_payload->get_auth_method(auth_payload);
- auth = authenticator_create(this->ike_sa, auth_method);
+ auth = authenticator_create_from_auth_payload(this->ike_sa, auth_payload);
if (auth == NULL)
{
- SIG(IKE_UP_FAILED, "authentication method %N used by %D not "
+ SIG(IKE_UP_FAILED, "authentication method %N used by '%D' not "
"supported", auth_method_names, auth_method,
this->ike_sa->get_other_id(this->ike_sa));
return NOT_SUPPORTED;
@@ -231,9 +288,9 @@ static status_t process_id(private_ike_auth_t *this, message_t *message)
{
id = idr->get_identification(idr);
req = this->ike_sa->get_other_id(this->ike_sa);
- if (!id->matches(id, req, NULL))
+ if (!id->matches(id, req))
{
- SIG(IKE_UP_FAILED, "peer ID %D unacceptable, %D required", id, req);
+ SIG(IKE_UP_FAILED, "peer ID '%D' unacceptable, '%D' required", id, req);
id->destroy(id);
return FAILED;
}
@@ -321,12 +378,12 @@ static status_t build_auth_eap(private_ike_auth_t *this, message_t *message)
if (!this->initiator)
{
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %D[%H]...[%H]%D",
+ SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %H[%D]...[%D]%H",
this->ike_sa->get_name(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa));
+ this->ike_sa->get_my_id(this->ike_sa),
+ this->ike_sa->get_other_id(this->ike_sa),
+ this->ike_sa->get_other_host(this->ike_sa));
return SUCCESS;
}
return NEED_MORE;
@@ -367,12 +424,12 @@ static status_t process_auth_eap(private_ike_auth_t *this, message_t *message)
if (this->initiator)
{
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %D[%H]...[%H]%D",
+ SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %H[%D]...[%D]%H",
this->ike_sa->get_name(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa));
+ this->ike_sa->get_my_id(this->ike_sa),
+ this->ike_sa->get_other_id(this->ike_sa),
+ this->ike_sa->get_other_host(this->ike_sa));
return SUCCESS;
}
return NEED_MORE;
@@ -404,7 +461,7 @@ static status_t process_eap_i(private_ike_auth_t *this, message_t *message)
return NEED_MORE;
default:
this->eap_payload = NULL;
- SIG(IKE_UP_FAILED, "failed to authenticate against %D using EAP",
+ SIG(IKE_UP_FAILED, "failed to authenticate against '%D' using EAP",
this->ike_sa->get_other_id(this->ike_sa));
return FAILED;
}
@@ -482,7 +539,7 @@ static status_t build_i(private_ike_auth_t *this, message_t *message)
}
config = this->ike_sa->get_peer_cfg(this->ike_sa);
- if (config->get_auth_method(config) == AUTH_EAP)
+ if (config->get_auth_method(config) == CONF_AUTH_EAP)
{
this->eap_auth = eap_authenticator_create(this->ike_sa);
}
@@ -525,13 +582,13 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
this->eap_auth = eap_authenticator_create(this->ike_sa);
break;
default:
- break;
+ return NEED_MORE;
}
config = charon->backends->get_peer_cfg(charon->backends,
this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_other_id(this->ike_sa),
- this->ike_sa->get_other_ca(this->ike_sa));
+ this->ike_sa->get_other_auth(this->ike_sa));
if (config)
{
this->ike_sa->set_peer_cfg(this->ike_sa, config);
@@ -557,10 +614,17 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
return collect_my_init_data(this, message);
}
+ if (!this->peer_authenticated && this->eap_auth == NULL)
+ {
+ /* peer not authenticated, nor does it want to use EAP */
+ message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
+ return FAILED;
+ }
+
config = this->ike_sa->get_peer_cfg(this->ike_sa);
if (config == NULL)
{
- SIG(IKE_UP_FAILED, "no matching config found for %D...%D",
+ SIG(IKE_UP_FAILED, "no matching config found for '%D'...'%D'",
this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_other_id(this->ike_sa));
message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
@@ -574,26 +638,25 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
return FAILED;
}
+ if (check_uniqueness(this))
+ {
+ message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
+ return FAILED;
+ }
+
/* use "traditional" authentication if we could authenticate peer */
if (this->peer_authenticated)
{
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %D[%H]...[%H]%D",
+ SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %H[%D]...[%D]%H",
this->ike_sa->get_name(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa));
+ this->ike_sa->get_my_id(this->ike_sa),
+ this->ike_sa->get_other_id(this->ike_sa),
+ this->ike_sa->get_other_host(this->ike_sa));
return SUCCESS;
}
- if (this->eap_auth == NULL)
- {
- /* peer not authenticated, nor does it want to use EAP */
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
- return FAILED;
- }
-
/* initiate EAP authenitcation */
eap_type = config->get_eap_type(config, &eap_vendor);
status = this->eap_auth->initiate(this->eap_auth, eap_type,
@@ -618,6 +681,8 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
{
iterator_t *iterator;
payload_t *payload;
+ peer_cfg_t *config;
+ auth_info_t *auth;
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
@@ -652,8 +717,8 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
case AUTH_LIFETIME:
/* handled in ike_auth_lifetime task */
break;
- case P2P_ENDPOINT:
- /* handled in ike_p2p task */
+ case ME_ENDPOINT:
+ /* handled in ike_me task */
break;
default:
{
@@ -664,7 +729,7 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
iterator->destroy(iterator);
return FAILED;
}
- DBG1(DBG_IKE, "received %N notify",
+ DBG2(DBG_IKE, "received %N notify",
notify_type_names, type);
break;
}
@@ -687,13 +752,21 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
return process_eap_i(this, message);
}
+ config = this->ike_sa->get_peer_cfg(this->ike_sa);
+ auth = this->ike_sa->get_other_auth(this->ike_sa);
+ if (!auth->complies(auth, config->get_auth(config)))
+ {
+ SIG(IKE_UP_FAILED, "authorization of '%D' for config %s failed",
+ this->ike_sa->get_other_id(this->ike_sa), config->get_name(config));
+ return FAILED;
+ }
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %D[%H]...[%H]%D",
+ SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %H[%D]...[%D]%H",
this->ike_sa->get_name(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa));
+ this->ike_sa->get_my_id(this->ike_sa),
+ this->ike_sa->get_other_id(this->ike_sa),
+ this->ike_sa->get_other_host(this->ike_sa));
return SUCCESS;
}
diff --git a/src/charon/sa/tasks/ike_auth.h b/src/charon/sa/tasks/ike_auth.h
index d7326c988..15f98f312 100644
--- a/src/charon/sa/tasks/ike_auth.h
+++ b/src/charon/sa/tasks/ike_auth.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_auth.h
- *
- * @brief Interface ike_auth_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_auth.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ike_auth ike_auth
+ * @{ @ingroup tasks
*/
#ifndef IKE_AUTH_H_
@@ -30,7 +30,7 @@ typedef struct ike_auth_t ike_auth_t;
#include <sa/tasks/task.h>
/**
- * @brief Task of type ike_auth, authenticates an IKE_SA using authenticators.
+ * Task of type ike_auth, authenticates an IKE_SA using authenticators.
*
* The ike_auth task authenticates the IKE_SA using the IKE_AUTH
* exchange. It processes and build IDi and IDr payloads and also
@@ -38,11 +38,6 @@ typedef struct ike_auth_t ike_auth_t;
* which do the actual authentication process. If the ike_auth task is used
* with EAP authentication, it stays alive over multiple exchanges until
* EAP has completed.
- *
- * @b Constructors:
- * - ike_auth_create()
- *
- * @ingroup tasks
*/
struct ike_auth_t {
@@ -53,7 +48,7 @@ struct ike_auth_t {
};
/**
- * @brief Create a new task of type IKE_AUTHENTICATE.
+ * Create a new task of type IKE_AUTHENTICATE.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if thask is the initator of an exchange
@@ -61,4 +56,4 @@ struct ike_auth_t {
*/
ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator);
-#endif /* IKE_AUTH_H_ */
+#endif /* IKE_AUTH_H_ @} */
diff --git a/src/charon/sa/tasks/ike_auth_lifetime.c b/src/charon/sa/tasks/ike_auth_lifetime.c
index 9d37ec608..2d18c6a1e 100644
--- a/src/charon/sa/tasks/ike_auth_lifetime.c
+++ b/src/charon/sa/tasks/ike_auth_lifetime.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_auth_lifetime.c
- *
- * @brief Implementation of the ike_auth_lifetime task.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_auth_lifetime.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "ike_auth_lifetime.h"
diff --git a/src/charon/sa/tasks/ike_auth_lifetime.h b/src/charon/sa/tasks/ike_auth_lifetime.h
index 500b89d39..21a3bbfdc 100644
--- a/src/charon/sa/tasks/ike_auth_lifetime.h
+++ b/src/charon/sa/tasks/ike_auth_lifetime.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_auth_lifetime.h
- *
- * @brief Interface ike_auth_lifetime_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_auth_lifetime.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ike_auth_lifetime ike_auth_lifetime
+ * @{ @ingroup tasks
*/
#ifndef IKE_AUTH_LIFETIME_H_
@@ -30,15 +30,10 @@ typedef struct ike_auth_lifetime_t ike_auth_lifetime_t;
#include <sa/tasks/task.h>
/**
- * @brief Task of type IKE_AUTH_LIFETIME, implements RFC4478.
+ * Task of type IKE_AUTH_LIFETIME, implements RFC4478.
*
* This task exchanges lifetimes for IKE_AUTH to force a client to
* reauthenticate before the responders lifetime reaches the limit.
- *
- * @b Constructors:
- * - ike_auth_lifetime_create()
- *
- * @ingroup tasks
*/
struct ike_auth_lifetime_t {
@@ -49,7 +44,7 @@ struct ike_auth_lifetime_t {
};
/**
- * @brief Create a new IKE_AUTH_LIFETIME task.
+ * Create a new IKE_AUTH_LIFETIME task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if taks is initiated by us
@@ -57,5 +52,4 @@ struct ike_auth_lifetime_t {
*/
ike_auth_lifetime_t *ike_auth_lifetime_create(ike_sa_t *ike_sa, bool initiator);
-#endif /* IKE_MOBIKE_H_ */
-
+#endif /* IKE_MOBIKE_H_ @} */
diff --git a/src/charon/sa/tasks/ike_cert.c b/src/charon/sa/tasks/ike_cert.c
deleted file mode 100644
index 880ed9c42..000000000
--- a/src/charon/sa/tasks/ike_cert.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/**
- * @file ike_cert.c
- *
- * @brief Implementation of the ike_cert task.
- *
- */
-
-/*
- * Copyright (C) 2006-2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "ike_cert.h"
-
-#include <daemon.h>
-#include <sa/ike_sa.h>
-#include <crypto/hashers/hasher.h>
-#include <encoding/payloads/cert_payload.h>
-#include <encoding/payloads/certreq_payload.h>
-
-
-typedef struct private_ike_cert_t private_ike_cert_t;
-
-/**
- * Private members of a ike_cert_t task.
- */
-struct private_ike_cert_t {
-
- /**
- * Public methods and task_t interface.
- */
- ike_cert_t public;
-
- /**
- * Assigned IKE_SA.
- */
- ike_sa_t *ike_sa;
-
- /**
- * Are we the initiator?
- */
- bool initiator;
-
- /**
- * list of CA cert hashes requested, items point to 20 byte chunk
- */
- linked_list_t *cas;
-
- /**
- * have we seen a certificate request?
- */
- bool certreq_seen;
-};
-
-/**
- * read certificate requests
- */
-static void process_certreqs(private_ike_cert_t *this, message_t *message)
-{
- iterator_t *iterator;
- payload_t *payload;
-
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
- {
- if (payload->get_type(payload) == CERTIFICATE_REQUEST)
- {
- certreq_payload_t *certreq = (certreq_payload_t*)payload;
- cert_encoding_t encoding;
- chunk_t keyids, keyid;
-
- this->certreq_seen = TRUE;
-
- encoding = certreq->get_cert_encoding(certreq);
- if (encoding != CERT_X509_SIGNATURE)
- {
- DBG1(DBG_IKE, "certreq payload %N not supported - ignored",
- cert_encoding_names, encoding);
- continue;
- }
-
- keyids = certreq->get_data(certreq);
-
- while (keyids.len >= HASH_SIZE_SHA1)
- {
- keyid = chunk_create(keyids.ptr, HASH_SIZE_SHA1);
- keyid = chunk_clone(keyid);
- this->cas->insert_last(this->cas, keyid.ptr);
- keyids = chunk_skip(keyids, HASH_SIZE_SHA1);
- }
- }
- }
- iterator->destroy(iterator);
-}
-
-/**
- * import certificates
- */
-static void process_certs(private_ike_cert_t *this, message_t *message)
-{
- iterator_t *iterator;
- payload_t *payload;
-
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
- {
- if (payload->get_type(payload) == CERTIFICATE)
- {
- cert_encoding_t encoding;
- x509_t *cert;
- chunk_t cert_data;
- bool found;
- cert_payload_t *cert_payload = (cert_payload_t*)payload;
-
- encoding = cert_payload->get_cert_encoding(cert_payload);
- if (encoding != CERT_X509_SIGNATURE)
- {
- DBG1(DBG_IKE, "certificate payload %N not supported - ignored",
- cert_encoding_names, encoding);
- continue;
- }
-
- cert_data = cert_payload->get_data_clone(cert_payload);
- cert = x509_create_from_chunk(cert_data, 0);
- if (cert)
- {
- if (charon->credentials->verify(charon->credentials, cert, &found))
- {
- DBG2(DBG_IKE, "received end entity certificate is trusted - "
- "added to store");
- if (found)
- {
- cert->destroy(cert);
- }
- else
- {
- charon->credentials->add_end_certificate(charon->credentials, cert);
- }
- }
- else
- {
- DBG1(DBG_IKE, "received end entity certificate is not trusted - "
- "discarded");
- cert->destroy(cert);
- }
- }
- else
- {
- DBG1(DBG_IKE, "parsing of received certificate failed - discarded");
- chunk_free(&cert_data);
- }
- }
- }
- iterator->destroy(iterator);
-}
-
-/**
- * build certificate requests
- */
-static void build_certreqs(private_ike_cert_t *this, message_t *message)
-{
- ike_cfg_t *ike_cfg;
- peer_cfg_t *peer_cfg;
- identification_t *ca;
- certreq_payload_t *certreq;
-
- ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
-
- if (ike_cfg->send_certreq(ike_cfg) != CERT_NEVER_SEND)
- {
- peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
-
- if (peer_cfg)
- {
- ca = peer_cfg->get_other_ca(peer_cfg);
-
- if (ca && ca->get_type(ca) != ID_ANY)
- {
- certreq = certreq_payload_create_from_cacert(ca);
- }
- else
- {
- certreq = certreq_payload_create_from_cacerts();
- }
- }
- else
- {
- certreq = certreq_payload_create_from_cacerts();
- }
-
- if (certreq)
- {
- message->add_payload(message, (payload_t*)certreq);
- }
- }
-}
-
-/**
- * add certificates to message
- */
-static void build_certs(private_ike_cert_t *this, message_t *message)
-{
- peer_cfg_t *peer_cfg;
- x509_t *cert;
- cert_payload_t *payload;
-
- peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
-
- if (peer_cfg && peer_cfg->get_auth_method(peer_cfg) == AUTH_RSA)
- {
- switch (peer_cfg->get_cert_policy(peer_cfg))
- {
- case CERT_NEVER_SEND:
- break;
- case CERT_SEND_IF_ASKED:
- if (!this->certreq_seen)
- {
- break;
- }
- /* FALL */
- case CERT_ALWAYS_SEND:
- {
- /* TODO: respect CA cert request */
- cert = charon->credentials->get_certificate(charon->credentials,
- peer_cfg->get_my_id(peer_cfg));
- if (cert)
- {
- payload = cert_payload_create_from_x509(cert);
- message->add_payload(message, (payload_t*)payload);
- }
- }
- }
- }
-}
-
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t build_i(private_ike_cert_t *this, message_t *message)
-{
- if (message->get_exchange_type(message) == IKE_SA_INIT)
- {
- return NEED_MORE;
- }
-
- build_certreqs(this, message);
- build_certs(this, message);
-
- return NEED_MORE;
-}
-
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_cert_t *this, message_t *message)
-{
- if (message->get_exchange_type(message) == IKE_SA_INIT)
- {
- return NEED_MORE;
- }
-
- process_certreqs(this, message);
- process_certs(this, message);
-
- return NEED_MORE;
-}
-
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_cert_t *this, message_t *message)
-{
- if (message->get_exchange_type(message) == IKE_SA_INIT)
- {
- build_certreqs(this, message);
- return NEED_MORE;
- }
-
- build_certs(this, message);
-
- return SUCCESS;
-}
-
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_cert_t *this, message_t *message)
-{
- if (message->get_exchange_type(message) == IKE_SA_INIT)
- {
- process_certreqs(this, message);
- return NEED_MORE;
- }
-
- process_certs(this, message);
- return SUCCESS;
-}
-
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_cert_t *this)
-{
- return IKE_CERT;
-}
-
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_cert_t *this, ike_sa_t *ike_sa)
-{
- this->ike_sa = ike_sa;
-
- this->cas->destroy_function(this->cas, free);
- this->cas = linked_list_create();
- this->certreq_seen = FALSE;
-}
-
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_cert_t *this)
-{
- this->cas->destroy_function(this->cas, free);
- free(this);
-}
-
-/*
- * Described in header.
- */
-ike_cert_t *ike_cert_create(ike_sa_t *ike_sa, bool initiator)
-{
- private_ike_cert_t *this = malloc_thing(private_ike_cert_t);
-
- this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
- this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
- this->public.task.destroy = (void(*)(task_t*))destroy;
-
- if (initiator)
- {
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
- }
- else
- {
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
- }
-
- this->ike_sa = ike_sa;
- this->initiator = initiator;
- this->cas = linked_list_create();
- this->certreq_seen = FALSE;
-
- return &this->public;
-}
diff --git a/src/charon/sa/tasks/ike_cert_post.c b/src/charon/sa/tasks/ike_cert_post.c
new file mode 100644
index 000000000..184868b28
--- /dev/null
+++ b/src/charon/sa/tasks/ike_cert_post.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2006-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: ike_cert_post.c 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+#include "ike_cert_post.h"
+
+#include <daemon.h>
+#include <sa/ike_sa.h>
+#include <encoding/payloads/cert_payload.h>
+#include <encoding/payloads/certreq_payload.h>
+#include <credentials/certificates/x509.h>
+
+
+typedef struct private_ike_cert_post_t private_ike_cert_post_t;
+
+/**
+ * Private members of a ike_cert_post_t task.
+ */
+struct private_ike_cert_post_t {
+
+ /**
+ * Public methods and task_t interface.
+ */
+ ike_cert_post_t public;
+
+ /**
+ * Assigned IKE_SA.
+ */
+ ike_sa_t *ike_sa;
+
+ /**
+ * Are we the initiator?
+ */
+ bool initiator;
+};
+
+/**
+ * Generates the cert payload, if possible with "Hash and URL"
+ */
+static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this, certificate_t *cert)
+{
+ cert_payload_t *payload = NULL;
+
+ if (this->ike_sa->supports_extension(this->ike_sa, EXT_HASH_AND_URL))
+ {
+ /* ok, our peer sent us a HTTP_CERT_LOOKUP_SUPPORTED Notify */
+ hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher != NULL)
+ {
+ chunk_t hash, encoded = cert->get_encoding(cert);
+ enumerator_t *enumerator;
+ char *url;
+
+ hasher->allocate_hash(hasher, encoded, &hash);
+ identification_t *id = identification_create_from_encoding(ID_CERT_DER_SHA1, hash);
+
+ enumerator = charon->credentials->create_cdp_enumerator(charon->credentials, CERT_X509, id);
+ if (enumerator->enumerate(enumerator, &url))
+ {
+ /* if we have an URL available we send that to our peer */
+ payload = cert_payload_create_from_hash_and_url(hash, url);
+ }
+ enumerator->destroy(enumerator);
+
+ id->destroy(id);
+ chunk_free(&hash);
+ chunk_free(&encoded);
+ hasher->destroy(hasher);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "unable to use hash-and-url: sha1 not supported");
+ }
+ }
+
+ if (!payload)
+ {
+ /* our peer does not support "Hash and URL" or we do not have an URL
+ * to send to our peer, just create a normal cert payload */
+ payload = cert_payload_create_from_cert(cert);
+ }
+
+ return payload;
+}
+
+/**
+ * add certificates to message
+ */
+static void build_certs(private_ike_cert_post_t *this, message_t *message)
+{
+ peer_cfg_t *peer_cfg;
+
+ peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
+ if (peer_cfg && peer_cfg->get_auth_method(peer_cfg) == CONF_AUTH_PUBKEY)
+ {
+ switch (peer_cfg->get_cert_policy(peer_cfg))
+ {
+ case CERT_NEVER_SEND:
+ break;
+ case CERT_SEND_IF_ASKED:
+ if (!this->ike_sa->has_condition(this->ike_sa, COND_CERTREQ_SEEN))
+ {
+ break;
+ }
+ /* FALL */
+ case CERT_ALWAYS_SEND:
+ {
+ cert_payload_t *payload;
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ auth_info_t *auth;
+ auth_item_t item;
+
+ auth = this->ike_sa->get_my_auth(this->ike_sa);
+ /* get subject cert first, then issuing certificates */
+ if (!auth->get_item(auth, AUTHZ_SUBJECT_CERT, (void**)&cert))
+ {
+ break;
+ }
+ payload = build_cert_payload(this, cert);
+ if (!payload)
+ {
+ break;
+ }
+ DBG1(DBG_IKE, "sending end entity cert \"%D\"",
+ cert->get_subject(cert));
+ message->add_payload(message, (payload_t*)payload);
+
+ enumerator = auth->create_item_enumerator(auth);
+ while (enumerator->enumerate(enumerator, &item, &cert))
+ {
+ if (item == AUTHZ_IM_CERT)
+ {
+ payload = cert_payload_create_from_cert(cert);
+ if (payload)
+ {
+ DBG1(DBG_IKE, "sending issuer cert \"%D\"",
+ cert->get_subject(cert));
+ message->add_payload(message, (payload_t*)payload);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ }
+ }
+}
+
+/**
+ * Implementation of task_t.process for initiator
+ */
+static status_t build_i(private_ike_cert_post_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == IKE_SA_INIT)
+ {
+ return NEED_MORE;
+ }
+ build_certs(this, message);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of task_t.process for responder
+ */
+static status_t process_r(private_ike_cert_post_t *this, message_t *message)
+{
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.build for responder
+ */
+static status_t build_r(private_ike_cert_post_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == IKE_SA_INIT)
+ {
+ return NEED_MORE;
+ }
+ build_certs(this, message);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of task_t.process for initiator
+ */
+static status_t process_i(private_ike_cert_post_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == IKE_SA_INIT)
+ {
+ return NEED_MORE;
+ }
+ return SUCCESS;
+}
+
+/**
+ * Implementation of task_t.get_type
+ */
+static task_type_t get_type(private_ike_cert_post_t *this)
+{
+ return IKE_CERT_POST;
+}
+
+/**
+ * Implementation of task_t.migrate
+ */
+static void migrate(private_ike_cert_post_t *this, ike_sa_t *ike_sa)
+{
+ this->ike_sa = ike_sa;
+}
+
+/**
+ * Implementation of task_t.destroy
+ */
+static void destroy(private_ike_cert_post_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+ike_cert_post_t *ike_cert_post_create(ike_sa_t *ike_sa, bool initiator)
+{
+ private_ike_cert_post_t *this = malloc_thing(private_ike_cert_post_t);
+
+ this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
+ this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
+ this->public.task.destroy = (void(*)(task_t*))destroy;
+
+ if (initiator)
+ {
+ this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
+ this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
+ }
+ else
+ {
+ this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
+ this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
+ }
+
+ this->ike_sa = ike_sa;
+ this->initiator = initiator;
+
+ return &this->public;
+}
+
diff --git a/src/charon/sa/tasks/ike_cert_post.h b/src/charon/sa/tasks/ike_cert_post.h
new file mode 100644
index 000000000..78b32d67a
--- /dev/null
+++ b/src/charon/sa/tasks/ike_cert_post.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: ike_cert_post.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ike_cert_post ike_cert_post
+ * @{ @ingroup tasks
+ */
+
+#ifndef IKE_CERT_POST_H_
+#define IKE_CERT_POST_H_
+
+typedef struct ike_cert_post_t ike_cert_post_t;
+
+#include <library.h>
+#include <sa/ike_sa.h>
+#include <sa/tasks/task.h>
+
+/**
+ * Task of type ike_cert_post, certificate processing after authentication.
+ */
+struct ike_cert_post_t {
+
+ /**
+ * Implements the task_t interface
+ */
+ task_t task;
+};
+
+/**
+ * Create a new ike_cert_post task.
+ *
+ * The initiator parameter means the original initiator, not the initiator
+ * of the certificate request.
+ *
+ * @param ike_sa IKE_SA this task works for
+ * @param initiator TRUE if thask is the original initator
+ * @return ike_cert_post task to handle by the task_manager
+ */
+ike_cert_post_t *ike_cert_post_create(ike_sa_t *ike_sa, bool initiator);
+
+#endif /* IKE_CERT_POST_H_ @} */
diff --git a/src/charon/sa/tasks/ike_cert_pre.c b/src/charon/sa/tasks/ike_cert_pre.c
new file mode 100644
index 000000000..3568a214e
--- /dev/null
+++ b/src/charon/sa/tasks/ike_cert_pre.c
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2006-2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: ike_cert_pre.c 3852 2008-04-18 21:27:08Z andreas $
+ */
+
+#include "ike_cert_pre.h"
+
+#include <daemon.h>
+#include <sa/ike_sa.h>
+#include <encoding/payloads/cert_payload.h>
+#include <encoding/payloads/certreq_payload.h>
+#include <credentials/certificates/x509.h>
+
+
+typedef struct private_ike_cert_pre_t private_ike_cert_pre_t;
+
+/**
+ * Private members of a ike_cert_pre_t task.
+ */
+struct private_ike_cert_pre_t {
+
+ /**
+ * Public methods and task_t interface.
+ */
+ ike_cert_pre_t public;
+
+ /**
+ * Assigned IKE_SA.
+ */
+ ike_sa_t *ike_sa;
+
+ /**
+ * Are we the initiator?
+ */
+ bool initiator;
+
+ /**
+ * Did we send a HTTP_CERT_LOOKUP_SUPPORTED Notify?
+ */
+ bool http_cert_lookup_supported_sent;
+};
+
+/**
+ * read certificate requests
+ */
+static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
+{
+ iterator_t *iterator;
+ payload_t *payload;
+ auth_info_t *auth;
+ bool ca_found = FALSE;
+
+ auth = this->ike_sa->get_my_auth(this->ike_sa);
+
+ iterator = message->get_payload_iterator(message);
+ while (iterator->iterate(iterator, (void**)&payload))
+ {
+ switch(payload->get_type(payload))
+ {
+ case CERTIFICATE_REQUEST:
+ {
+ certreq_payload_t *certreq = (certreq_payload_t*)payload;
+ chunk_t keyid;
+ enumerator_t *enumerator;
+
+ this->ike_sa->set_condition(this->ike_sa, COND_CERTREQ_SEEN, TRUE);
+
+ if (certreq->get_cert_type(certreq) != CERT_X509)
+ {
+ DBG1(DBG_IKE, "cert payload %N not supported - ignored",
+ certificate_type_names, certreq->get_cert_type(certreq));
+ break;
+ }
+ enumerator = certreq->create_keyid_enumerator(certreq);
+ while (enumerator->enumerate(enumerator, &keyid))
+ {
+ identification_t *id;
+ certificate_t *cert;
+
+ id = identification_create_from_encoding(
+ ID_PUBKEY_INFO_SHA1, keyid);
+ cert = charon->credentials->get_cert(charon->credentials,
+ CERT_X509, KEY_ANY, id, TRUE);
+ if (cert)
+ {
+ DBG1(DBG_IKE, "received cert request for \"%D\"",
+ cert->get_subject(cert));
+ auth->add_item(auth, AUTHN_CA_CERT, cert);
+ cert->destroy(cert);
+ ca_found = TRUE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received cert request for unknown ca "
+ "with keyid %D", id);
+ auth->add_item(auth, AUTHN_CA_CERT_KEYID, id);
+ }
+ id->destroy(id);
+ }
+ enumerator->destroy(enumerator);
+ break;
+ }
+ case NOTIFY:
+ {
+ notify_payload_t *notify = (notify_payload_t*)payload;
+
+ /* we only handle one type of notify here */
+ if (notify->get_notify_type(notify) == HTTP_CERT_LOOKUP_SUPPORTED)
+ {
+ this->ike_sa->enable_extension(this->ike_sa, EXT_HASH_AND_URL);
+ }
+ break;
+ }
+ default:
+ /* ignore other payloads here, these are handled elsewhere */
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+}
+
+/**
+ * tries to extract a certificate from the cert payload or the credential
+ * manager (based on the hash of a "Hash and URL" encoded cert).
+ * Note: the returned certificate (if any) has to be destroyed
+ */
+static certificate_t *try_get_cert(cert_payload_t *cert_payload)
+{
+ certificate_t *cert = NULL;
+ switch (cert_payload->get_cert_encoding(cert_payload))
+ {
+ case ENC_X509_SIGNATURE:
+ {
+ cert = cert_payload->get_cert(cert_payload);
+ break;
+ }
+ case ENC_X509_HASH_AND_URL:
+ {
+ identification_t *id;
+ chunk_t hash = cert_payload->get_hash(cert_payload);
+ if (!hash.ptr)
+ {
+ /* invalid "Hash and URL" data (logged elsewhere) */
+ break;
+ }
+ id = identification_create_from_encoding(ID_CERT_DER_SHA1, hash);
+ cert = charon->credentials->get_cert(charon->credentials,
+ CERT_X509, KEY_ANY, id, FALSE);
+ id->destroy(id);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ return cert;
+}
+
+/**
+ * import certificates
+ */
+static void process_certs(private_ike_cert_pre_t *this, message_t *message)
+{
+ iterator_t *iterator;
+ payload_t *payload;
+ auth_info_t *auth;
+ bool first = TRUE;
+
+ auth = this->ike_sa->get_other_auth(this->ike_sa);
+
+ iterator = message->get_payload_iterator(message);
+ while (iterator->iterate(iterator, (void**)&payload))
+ {
+ if (payload->get_type(payload) == CERTIFICATE)
+ {
+ cert_payload_t *cert_payload = (cert_payload_t*)payload;
+ cert_encoding_t type = cert_payload->get_cert_encoding(cert_payload);
+ switch (type)
+ {
+ case ENC_X509_SIGNATURE:
+ case ENC_X509_HASH_AND_URL:
+ {
+ if (type == ENC_X509_HASH_AND_URL &&
+ !this->http_cert_lookup_supported_sent)
+ {
+ DBG1(DBG_IKE, "received hash-and-url encoded cert, but"
+ " we don't accept them, ignore");
+ break;
+ }
+
+ certificate_t *cert = try_get_cert(cert_payload);
+
+ if (cert)
+ {
+ /* we've got a certificate from the payload or the cache */
+ if (first)
+ { /* the first certificate MUST be an end entity one */
+ DBG1(DBG_IKE, "received end entity cert \"%D\"",
+ cert->get_subject(cert));
+ auth->add_item(auth, AUTHN_SUBJECT_CERT, cert);
+ first = FALSE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received issuer cert \"%D\"",
+ cert->get_subject(cert));
+ auth->add_item(auth, AUTHN_IM_CERT, cert);
+ }
+ cert->destroy(cert);
+ }
+ else if (type == ENC_X509_HASH_AND_URL)
+ {
+ /* we received a "Hash and URL" encoded certificate that
+ * we haven't fetched yet, we store the URL and fetch
+ * it later */
+ char *url = cert_payload->get_url(cert_payload);
+ if (!url)
+ {
+ DBG1(DBG_IKE, "received invalid hash-and-url encoded"
+ " cert, ignore");
+ break;
+ }
+
+ if (first)
+ { /* the first certificate MUST be an end entity one */
+ DBG1(DBG_IKE, "received hash-and-url for end"
+ " entity cert \"%s\"", url);
+ auth->add_item(auth, AUTHN_SUBJECT_HASH_URL, url);
+ first = FALSE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received hash-and-url for issuer"
+ " cert \"%s\"", url);
+ auth->add_item(auth, AUTHN_IM_HASH_URL, url);
+ }
+ }
+ break;
+ }
+ case ENC_PKCS7_WRAPPED_X509:
+ case ENC_PGP:
+ case ENC_DNS_SIGNED_KEY:
+ case ENC_KERBEROS_TOKEN:
+ case ENC_CRL:
+ case ENC_ARL:
+ case ENC_SPKI:
+ case ENC_X509_ATTRIBUTE:
+ case ENC_RAW_RSA_KEY:
+ case ENC_X509_HASH_AND_URL_BUNDLE:
+ case ENC_OCSP_CONTENT:
+ default:
+ DBG1(DBG_ENC, "certificate encoding %N not supported",
+ cert_encoding_names, cert_payload->get_cert_encoding(cert_payload));
+ }
+ }
+ }
+ iterator->destroy(iterator);
+}
+
+/**
+ * add a certificate request to the message, building request payload if required.
+ */
+static void add_certreq_payload(message_t *message, certreq_payload_t **reqp,
+ certificate_t *cert)
+{
+ public_key_t *public;
+ certreq_payload_t *req;
+
+ public = cert->get_public_key(cert);
+ if (!public)
+ {
+ return;
+ }
+ switch (cert->get_type(cert))
+ {
+ case CERT_X509:
+ {
+ identification_t *keyid;
+ x509_t *x509 = (x509_t*)cert;
+
+ if (!(x509->get_flags(x509) & X509_CA))
+ { /* no CA cert, skip */
+ break;
+ }
+ if (*reqp == NULL)
+ {
+ *reqp = certreq_payload_create_type(CERT_X509);
+ message->add_payload(message, (payload_t*)*reqp);
+ }
+ req = *reqp;
+ keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+ req->add_keyid(req, keyid->get_encoding(keyid));
+ DBG1(DBG_IKE, "sending cert request for \"%D\"",
+ cert->get_subject(cert));
+ break;
+ }
+ default:
+ break;
+ }
+ public->destroy(public);
+}
+
+/**
+ * build certificate requests
+ */
+static void build_certreqs(private_ike_cert_pre_t *this, message_t *message)
+{
+ ike_cfg_t *ike_cfg;
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ auth_info_t *auth;
+ bool restricted = FALSE;
+ auth_item_t item;
+ certreq_payload_t *x509_req = NULL;
+
+ ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
+ if (!ike_cfg->send_certreq(ike_cfg))
+ {
+ return;
+ }
+ auth = this->ike_sa->get_other_auth(this->ike_sa);
+
+ /* check if we require a specific CA for that peer */
+ enumerator = auth->create_item_enumerator(auth);
+ while (enumerator->enumerate(enumerator, &item, &cert))
+ {
+ if (item == AUTHN_CA_CERT)
+ {
+ restricted = TRUE;
+ add_certreq_payload(message, &x509_req, cert);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!restricted)
+ {
+ /* otherwise include all trusted CA certificates */
+ enumerator = charon->credentials->create_cert_enumerator(
+ charon->credentials, CERT_ANY, KEY_ANY, NULL, TRUE);
+ while (enumerator->enumerate(enumerator, &cert, TRUE))
+ {
+ add_certreq_payload(message, &x509_req, cert);
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ /* if we've added at least one certreq, we notify our peer that we support
+ * "Hash and URL" for the requested certificates */
+ if (lib->settings->get_bool(lib->settings, "charon.hash_and_url", FALSE) &&
+ message->get_payload(message, CERTIFICATE_REQUEST))
+ {
+ message->add_notify(message, FALSE, HTTP_CERT_LOOKUP_SUPPORTED, chunk_empty);
+ this->http_cert_lookup_supported_sent = TRUE;
+ }
+}
+
+/**
+ * Implementation of task_t.process for initiator
+ */
+static status_t build_i(private_ike_cert_pre_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == IKE_SA_INIT)
+ {
+ return NEED_MORE;
+ }
+ build_certreqs(this, message);
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.process for responder
+ */
+static status_t process_r(private_ike_cert_pre_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == IKE_SA_INIT)
+ {
+ return NEED_MORE;
+ }
+ process_certreqs(this, message);
+ process_certs(this, message);
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.build for responder
+ */
+static status_t build_r(private_ike_cert_pre_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == IKE_SA_INIT)
+ {
+ build_certreqs(this, message);
+ return NEED_MORE;
+ }
+ return SUCCESS;
+}
+
+/**
+ * Implementation of task_t.process for initiator
+ */
+static status_t process_i(private_ike_cert_pre_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == IKE_SA_INIT)
+ {
+ process_certreqs(this, message);
+ return NEED_MORE;
+ }
+ process_certs(this, message);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of task_t.get_type
+ */
+static task_type_t get_type(private_ike_cert_pre_t *this)
+{
+ return IKE_CERT_PRE;
+}
+
+/**
+ * Implementation of task_t.migrate
+ */
+static void migrate(private_ike_cert_pre_t *this, ike_sa_t *ike_sa)
+{
+ this->ike_sa = ike_sa;
+}
+
+/**
+ * Implementation of task_t.destroy
+ */
+static void destroy(private_ike_cert_pre_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator)
+{
+ private_ike_cert_pre_t *this = malloc_thing(private_ike_cert_pre_t);
+
+ this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
+ this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
+ this->public.task.destroy = (void(*)(task_t*))destroy;
+
+ if (initiator)
+ {
+ this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
+ this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
+ }
+ else
+ {
+ this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
+ this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
+ }
+
+ this->ike_sa = ike_sa;
+ this->initiator = initiator;
+ this->http_cert_lookup_supported_sent = FALSE;
+
+ return &this->public;
+}
diff --git a/src/charon/sa/tasks/ike_cert.h b/src/charon/sa/tasks/ike_cert_pre.h
index ba0283953..d8793a8e2 100644
--- a/src/charon/sa/tasks/ike_cert.h
+++ b/src/charon/sa/tasks/ike_cert_pre.h
@@ -1,12 +1,5 @@
-/**
- * @file ike_cert.h
- *
- * @brief Interface ike_cert_t.
- *
- */
-
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2007-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,27 +11,28 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_cert_pre.h 3589 2008-03-13 14:14:44Z martin $
*/
-#ifndef IKE_CERT_H_
-#define IKE_CERT_H_
+/**
+ * @defgroup ike_cert_pre ike_cert_pre
+ * @{ @ingroup tasks
+ */
-typedef struct ike_cert_t ike_cert_t;
+#ifndef IKE_CERT_PRE_H_
+#define IKE_CERT_PRE_H_
+
+typedef struct ike_cert_pre_t ike_cert_pre_t;
#include <library.h>
#include <sa/ike_sa.h>
#include <sa/tasks/task.h>
/**
- * @brief Task of type ike_cert, exchanges certificates and
- * certificate requests.
- *
- * @b Constructors:
- * - ike_cert_create()
- *
- * @ingroup tasks
+ * Task of type ike_cert_post, certificate processing before authentication.
*/
-struct ike_cert_t {
+struct ike_cert_pre_t {
/**
* Implements the task_t interface
@@ -47,15 +41,15 @@ struct ike_cert_t {
};
/**
- * @brief Create a new ike_cert task.
+ * Create a new ike_cert_pre task.
*
* The initiator parameter means the original initiator, not the initiator
* of the certificate request.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if thask is the original initator
- * @return ike_cert task to handle by the task_manager
+ * @return ike_cert_pre task to handle by the task_manager
*/
-ike_cert_t *ike_cert_create(ike_sa_t *ike_sa, bool initiator);
+ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator);
-#endif /* IKE_CERT_H_ */
+#endif /* IKE_CERT_PRE_H_ @} */
diff --git a/src/charon/sa/tasks/ike_config.c b/src/charon/sa/tasks/ike_config.c
index 3c73395a5..c31e62750 100644
--- a/src/charon/sa/tasks/ike_config.c
+++ b/src/charon/sa/tasks/ike_config.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_config.c
- *
- * @brief Implementation of the ike_config task.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_config.c 3800 2008-04-14 07:18:16Z martin $
*/
#include "ike_config.h"
@@ -266,14 +261,14 @@ static status_t build_i(private_ike_config_t *this, message_t *message)
/* reuse virtual IP if we already have one */
vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
- if (vip)
+ if (!vip)
{
- this->virtual_ip = vip->clone(vip);
+ config = this->ike_sa->get_peer_cfg(this->ike_sa);
+ vip = config->get_virtual_ip(config);
}
- else
+ if (vip)
{
- config = this->ike_sa->get_peer_cfg(this->ike_sa);
- this->virtual_ip = config->get_my_virtual_ip(config);
+ this->virtual_ip = vip->clone(vip);
}
build_payloads(this, message, CFG_REQUEST);
@@ -307,14 +302,20 @@ static status_t build_r(private_ike_config_t *this, message_t *message)
if (config && this->virtual_ip)
{
- host_t *ip;
+ host_t *ip = NULL;
DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
- ip = config->get_other_virtual_ip(config, this->virtual_ip);
- if (ip == NULL || ip->is_anyaddr(ip))
+ if (config->get_pool(config))
+ {
+ ip = charon->attributes->acquire_address(charon->attributes,
+ config->get_pool(config),
+ this->ike_sa->get_other_id(this->ike_sa),
+ this->ike_sa->get_other_auth(this->ike_sa),
+ this->virtual_ip);
+ }
+ if (ip == NULL)
{
DBG1(DBG_IKE, "not assigning a virtual IP to peer");
- DESTROY_IF(ip);
return SUCCESS;
}
DBG1(DBG_IKE, "assigning virtual IP %H to peer", ip);
@@ -323,16 +324,6 @@ static status_t build_r(private_ike_config_t *this, message_t *message)
this->virtual_ip->destroy(this->virtual_ip);
this->virtual_ip = ip;
- /* DNS testing values
- if (this->dns->remove_last(this->dns, (void**)&ip) == SUCCESS)
- {
- ip->destroy(ip);
- ip = host_create_from_string("10.3.0.1", 0);
- this->dns->insert_last(this->dns, ip);
- ip = host_create_from_string("10.3.0.2", 0);
- this->dns->insert_last(this->dns, ip);
- } */
-
build_payloads(this, message, CFG_REPLY);
}
return SUCCESS;
@@ -359,7 +350,11 @@ static status_t process_i(private_ike_config_t *this, message_t *message)
if (this->virtual_ip == NULL)
{ /* force a configured virtual IP, even server didn't return one */
config = this->ike_sa->get_peer_cfg(this->ike_sa);
- this->virtual_ip = config->get_my_virtual_ip(config);
+ this->virtual_ip = config->get_virtual_ip(config);
+ if (this->virtual_ip)
+ {
+ this->virtual_ip = this->virtual_ip->clone(this->virtual_ip);
+ }
}
if (this->virtual_ip && !this->virtual_ip->is_anyaddr(this->virtual_ip))
diff --git a/src/charon/sa/tasks/ike_config.h b/src/charon/sa/tasks/ike_config.h
index a7cfddff0..23410a196 100644
--- a/src/charon/sa/tasks/ike_config.h
+++ b/src/charon/sa/tasks/ike_config.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_config.h
- *
- * @brief Interface ike_config_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_config.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ike_config ike_config
+ * @{ @ingroup tasks
*/
#ifndef IKE_CONFIG_H_
@@ -30,13 +30,8 @@ typedef struct ike_config_t ike_config_t;
#include <sa/tasks/task.h>
/**
- * @brief Task of type IKE_CONFIG, sets up a virtual IP and other
+ * Task of type IKE_CONFIG, sets up a virtual IP and other
* configurations for an IKE_SA.
- *
- * @b Constructors:
- * - ike_config_create()
- *
- * @ingroup tasks
*/
struct ike_config_t {
@@ -47,7 +42,7 @@ struct ike_config_t {
};
/**
- * @brief Create a new ike_config task.
+ * Create a new ike_config task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE for initiator
@@ -55,4 +50,4 @@ struct ike_config_t {
*/
ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator);
-#endif /* IKE_CONFIG_H_ */
+#endif /* IKE_CONFIG_H_ @} */
diff --git a/src/charon/sa/tasks/ike_delete.c b/src/charon/sa/tasks/ike_delete.c
index 1a3656ca6..aa7950ef7 100644
--- a/src/charon/sa/tasks/ike_delete.c
+++ b/src/charon/sa/tasks/ike_delete.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_delete.c
- *
- * @brief Implementation of the ike_delete task.
- *
- */
-
/*
* Copyright (C) 2006-2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_delete.c 3802 2008-04-14 08:17:18Z martin $
*/
#include "ike_delete.h"
@@ -87,18 +82,18 @@ static status_t process_r(private_ike_delete_t *this, message_t *message)
* come so far without being correct */
switch (this->ike_sa->get_state(this->ike_sa))
{
- case IKE_DELETING:
- this->simultaneous = TRUE;
- break;
case IKE_ESTABLISHED:
DBG1(DBG_IKE, "deleting IKE_SA on request");
+ this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
+ this->ike_sa->reestablish(this->ike_sa);
break;
- case IKE_REKEYING:
- break;
+ case IKE_DELETING:
+ this->simultaneous = TRUE;
+ /* FALL */
default:
+ this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
break;
}
- this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
return NEED_MORE;
}
diff --git a/src/charon/sa/tasks/ike_delete.h b/src/charon/sa/tasks/ike_delete.h
index e8ec5ebbe..6d08d345d 100644
--- a/src/charon/sa/tasks/ike_delete.h
+++ b/src/charon/sa/tasks/ike_delete.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_delete.h
- *
- * @brief Interface ike_delete_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_delete.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ike_delete ike_delete
+ * @{ @ingroup tasks
*/
#ifndef IKE_DELETE_H_
@@ -30,12 +30,7 @@ typedef struct ike_delete_t ike_delete_t;
#include <sa/tasks/task.h>
/**
- * @brief Task of type ike_delete, delete an IKE_SA.
- *
- * @b Constructors:
- * - ike_delete_create()
- *
- * @ingroup tasks
+ * Task of type ike_delete, delete an IKE_SA.
*/
struct ike_delete_t {
@@ -46,7 +41,7 @@ struct ike_delete_t {
};
/**
- * @brief Create a new ike_delete task.
+ * Create a new ike_delete task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if we initiate the delete
@@ -54,4 +49,4 @@ struct ike_delete_t {
*/
ike_delete_t *ike_delete_create(ike_sa_t *ike_sa, bool initiator);
-#endif /* IKE_DELETE_H_ */
+#endif /* IKE_DELETE_H_ @} */
diff --git a/src/charon/sa/tasks/ike_dpd.c b/src/charon/sa/tasks/ike_dpd.c
index be751766e..9f1d43cbf 100644
--- a/src/charon/sa/tasks/ike_dpd.c
+++ b/src/charon/sa/tasks/ike_dpd.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_dpd.c
- *
- * @brief Implementation of the ike_dpd task.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_dpd.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "ike_dpd.h"
diff --git a/src/charon/sa/tasks/ike_dpd.h b/src/charon/sa/tasks/ike_dpd.h
index 531b0502d..62b8a6a10 100644
--- a/src/charon/sa/tasks/ike_dpd.h
+++ b/src/charon/sa/tasks/ike_dpd.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_dpd.h
- *
- * @brief Interface ike_dpd_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_dpd.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ike_dpd ike_dpd
+ * @{ @ingroup tasks
*/
#ifndef IKE_DPD_H_
@@ -30,14 +30,9 @@ typedef struct ike_dpd_t ike_dpd_t;
#include <sa/tasks/task.h>
/**
- * @brief Task of type ike_dpd, detects dead peers.
+ * Task of type ike_dpd, detects dead peers.
*
* The DPD task actually does nothing, as a DPD has no associated payloads.
- *
- * @b Constructors:
- * - ike_dpd_create()
- *
- * @ingroup tasks
*/
struct ike_dpd_t {
@@ -48,11 +43,11 @@ struct ike_dpd_t {
};
/**
- * @brief Create a new ike_dpd task.
+ * Create a new ike_dpd task.
*
* @param initiator TRUE if thask is the original initator
* @return ike_dpd task to handle by the task_manager
*/
ike_dpd_t *ike_dpd_create(bool initiator);
-#endif /* IKE_DPD_H_ */
+#endif /* IKE_DPD_H_ @} */
diff --git a/src/charon/sa/tasks/ike_init.c b/src/charon/sa/tasks/ike_init.c
index 42b47a82f..7def3a556 100644
--- a/src/charon/sa/tasks/ike_init.c
+++ b/src/charon/sa/tasks/ike_init.c
@@ -1,11 +1,5 @@
-/**
- * @file ike_init.c
- *
- * @brief Implementation of the ike_init task.
- *
- */
-
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -19,6 +13,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_init.c 4086 2008-06-22 11:24:33Z andreas $
*/
#include "ike_init.h"
@@ -195,7 +191,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
this->dh_group = ke_payload->get_dh_group_number(ke_payload);
if (!this->initiator)
{
- this->dh = diffie_hellman_create(this->dh_group);
+ this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
}
if (this->dh)
{
@@ -222,13 +218,12 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
*/
static status_t build_i(private_ike_init_t *this, message_t *message)
{
- randomizer_t *randomizer;
- status_t status;
+ rng_t *rng;
this->config = this->ike_sa->get_ike_cfg(this->ike_sa);
SIG(IKE_UP_START, "initiating IKE_SA '%s' to %H",
this->ike_sa->get_name(this->ike_sa),
- this->config->get_other_host(this->config));
+ this->ike_sa->get_other_host(this->ike_sa));
this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
if (this->retry++ >= MAX_RETRIES)
@@ -241,7 +236,7 @@ static status_t build_i(private_ike_init_t *this, message_t *message)
if (!this->dh)
{
this->dh_group = this->config->get_dh_group(this->config);
- this->dh = diffie_hellman_create(this->dh_group);
+ this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
if (this->dh == NULL)
{
SIG(IKE_UP_FAILED, "configured DH group %N not supported",
@@ -253,15 +248,14 @@ static status_t build_i(private_ike_init_t *this, message_t *message)
/* generate nonce only when we are trying the first time */
if (this->my_nonce.ptr == NULL)
{
- randomizer = randomizer_create();
- status = randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_SIZE,
- &this->my_nonce);
- randomizer->destroy(randomizer);
- if (status != SUCCESS)
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (!rng)
{
- SIG(IKE_UP_FAILED, "error generating random nonce value");
+ SIG(IKE_UP_FAILED, "error generating nonce");
return FAILED;
}
+ rng->allocate_bytes(rng, NONCE_SIZE, &this->my_nonce);
+ rng->destroy(rng);
}
if (this->cookie.ptr)
@@ -270,30 +264,90 @@ static status_t build_i(private_ike_init_t *this, message_t *message)
}
build_payloads(this, message);
-
+
+#ifdef ME
+ {
+ chunk_t connect_id = this->ike_sa->get_connect_id(this->ike_sa);
+ if (connect_id.ptr)
+ {
+ message->add_notify(message, FALSE, ME_CONNECTID, connect_id);
+ }
+ }
+#endif /* ME */
return NEED_MORE;
}
/**
- * Implementation of task_t.process for initiator
+ * Implementation of task_t.process for responder
*/
static status_t process_r(private_ike_init_t *this, message_t *message)
{
- randomizer_t *randomizer;
+ rng_t *rng;
this->config = this->ike_sa->get_ike_cfg(this->ike_sa);
- SIG(IKE_UP_FAILED, "%H is initiating an IKE_SA",
+ SIG(IKE_UP_START, "%H is initiating an IKE_SA",
message->get_source(message));
this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
- randomizer = randomizer_create();
- if (randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_SIZE,
- &this->my_nonce) != SUCCESS)
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (!rng)
+ {
+ DBG1(DBG_IKE, "error generating nonce");
+ return FAILED;
+ }
+ rng->allocate_bytes(rng, NONCE_SIZE, &this->my_nonce);
+ rng->destroy(rng);
+
+#ifdef ME
{
- DBG1(DBG_IKE, "error generating random nonce value");
+ chunk_t connect_id = chunk_empty;
+ iterator_t *iterator;
+ payload_t *payload;
+
+ /* check for a ME_CONNECTID notify */
+ iterator = message->get_payload_iterator(message);
+ while (iterator->iterate(iterator, (void**)&payload))
+ {
+ if (payload->get_type(payload) == NOTIFY)
+ {
+ notify_payload_t *notify = (notify_payload_t*)payload;
+ notify_type_t type = notify->get_notify_type(notify);
+
+ switch (type)
+ {
+ case ME_CONNECTID:
+ {
+ chunk_free(&connect_id);
+ connect_id = chunk_clone(notify->get_notification_data(notify));
+ DBG2(DBG_IKE, "received ME_CONNECTID %#B", &connect_id);
+ break;
+ }
+ default:
+ {
+ if (type < 16383)
+ {
+ DBG1(DBG_IKE, "received %N notify error",
+ notify_type_names, type);
+ break;
+ }
+ DBG2(DBG_IKE, "received %N notify",
+ notify_type_names, type);
+ break;
+ }
+ }
+ }
+ }
+ iterator->destroy(iterator);
+
+ if (connect_id.ptr)
+ {
+ charon->connect_manager->stop_checks(charon->connect_manager,
+ connect_id);
+ chunk_free(&connect_id);
+ }
}
- randomizer->destroy(randomizer);
+#endif /* ME */
process_payloads(this, message);
@@ -321,11 +375,11 @@ static status_t build_r(private_ike_init_t *this, message_t *message)
!this->proposal->has_dh_group(this->proposal, this->dh_group) ||
this->dh->get_shared_secret(this->dh, &secret) != SUCCESS)
{
- algorithm_t *algo;
+ u_int16_t group;
+
if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP,
- &algo))
+ &group, NULL))
{
- u_int16_t group = algo->algorithm;
SIG(CHILD_UP_FAILED, "DH group %N inacceptable, requesting %N",
diffie_hellman_group_names, this->dh_group,
diffie_hellman_group_names, group);
@@ -370,9 +424,16 @@ static status_t build_r(private_ike_init_t *this, message_t *message)
message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
return FAILED;
}
-
- build_payloads(this, message);
+ /* Keep the selected IKE proposal for status information purposes */
+ {
+ char buf[BUF_LEN];
+
+ snprintf(buf, BUF_LEN, "%P", this->proposal);
+ this->ike_sa->set_proposal(this->ike_sa, buf+4);
+ }
+
+ build_payloads(this, message);
return SUCCESS;
}
@@ -427,7 +488,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
this->cookie = chunk_clone(notify->get_notification_data(notify));
this->ike_sa->reset(this->ike_sa);
iterator->destroy(iterator);
- DBG1(DBG_IKE, "received %N notify", notify_type_names, type);
+ DBG2(DBG_IKE, "received %N notify", notify_type_names, type);
return NEED_MORE;
}
default:
@@ -439,7 +500,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
iterator->destroy(iterator);
return FAILED;
}
- DBG1(DBG_IKE, "received %N notify",
+ DBG2(DBG_IKE, "received %N notify",
notify_type_names, type);
break;
}
@@ -454,7 +515,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
if (this->proposal == NULL ||
this->other_nonce.len == 0 || this->my_nonce.len == 0)
{
- SIG(IKE_UP_FAILED, "peers proposal selection invalid");
+ SIG(IKE_UP_FAILED, "peer's proposal selection invalid");
return FAILED;
}
@@ -462,7 +523,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
!this->proposal->has_dh_group(this->proposal, this->dh_group) ||
this->dh->get_shared_secret(this->dh, &secret) != SUCCESS)
{
- SIG(IKE_UP_FAILED, "peers DH group selection invalid");
+ SIG(IKE_UP_FAILED, "peer's DH group selection invalid");
return FAILED;
}
@@ -494,6 +555,15 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
SIG(IKE_UP_FAILED, "key derivation failed");
return FAILED;
}
+
+ /* Keep the selected IKE proposal for status information purposes */
+ {
+ char buf[BUF_LEN];
+
+ snprintf(buf, BUF_LEN, "%P", this->proposal);
+ this->ike_sa->set_proposal(this->ike_sa, buf+4);
+ }
+
return SUCCESS;
}
@@ -532,7 +602,7 @@ static void migrate(private_ike_init_t *this, ike_sa_t *ike_sa)
this->ike_sa = ike_sa;
this->proposal = NULL;
- this->dh = diffie_hellman_create(this->dh_group);
+ this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
}
/**
diff --git a/src/charon/sa/tasks/ike_init.h b/src/charon/sa/tasks/ike_init.h
index f60c096e8..0e5a913fd 100644
--- a/src/charon/sa/tasks/ike_init.h
+++ b/src/charon/sa/tasks/ike_init.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_init.h
- *
- * @brief Interface ike_init_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_init.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ike_init ike_init
+ * @{ @ingroup tasks
*/
#ifndef IKE_INIT_H_
@@ -30,14 +30,9 @@ typedef struct ike_init_t ike_init_t;
#include <sa/tasks/task.h>
/**
- * @brief Task of type IKE_INIT, creates an IKE_SA without authentication.
+ * Task of type IKE_INIT, creates an IKE_SA without authentication.
*
* The authentication of is handle in the ike_auth task.
- *
- * @b Constructors:
- * - ike_init_create()
- *
- * @ingroup tasks
*/
struct ike_init_t {
@@ -47,16 +42,15 @@ struct ike_init_t {
task_t task;
/**
- * @brief Get the lower of the two nonces, used for rekey collisions.
+ * Get the lower of the two nonces, used for rekey collisions.
*
- * @param this calling object
* @return lower nonce
*/
chunk_t (*get_lower_nonce) (ike_init_t *this);
};
/**
- * @brief Create a new IKE_INIT task.
+ * Create a new IKE_INIT task.
*
* @param ike_sa IKE_SA this task works for (new one when rekeying)
* @param initiator TRUE if thask is the original initator
@@ -65,4 +59,4 @@ struct ike_init_t {
*/
ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa);
-#endif /* IKE_INIT_H_ */
+#endif /* IKE_INIT_H_ @} */
diff --git a/src/charon/sa/tasks/ike_p2p.c b/src/charon/sa/tasks/ike_me.c
index 84b88e16b..2d7c64d70 100644
--- a/src/charon/sa/tasks/ike_p2p.c
+++ b/src/charon/sa/tasks/ike_me.c
@@ -1,12 +1,5 @@
-/**
- * @file ike_p2p.c
- *
- * @brief Implementation of the ike_p2p task.
- *
- */
-
/*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,9 +11,11 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_me.c 3806 2008-04-15 05:56:35Z martin $
*/
-
-#include "ike_p2p.h"
+
+#include "ike_me.h"
#include <string.h>
@@ -31,27 +26,20 @@
#include <encoding/payloads/endpoint_notify.h>
#include <processing/jobs/mediation_job.h>
-#define P2P_SESSIONID_LEN 8
-#define P2P_SESSIONKEY_LEN 16
+#define ME_CONNECTID_LEN 4
+#define ME_CONNECTKEY_LEN 16
-/* FIXME: proposed values */
-#define P2P_SESSIONID_MIN_LEN 4
-#define P2P_SESSIONID_MAX_LEN 16
-#define P2P_SESSIONKEY_MIN_LEN 8
-#define P2P_SESSIONKEY_MAX_LEN 64
-
-
-typedef struct private_ike_p2p_t private_ike_p2p_t;
+typedef struct private_ike_me_t private_ike_me_t;
/**
- * Private members of a ike_p2p_t task.
+ * Private members of a ike_me_t task.
*/
-struct private_ike_p2p_t {
+struct private_ike_me_t {
/**
* Public methods and task_t interface.
*/
- ike_p2p_t public;
+ ike_me_t public;
/**
* Assigned IKE_SA.
@@ -105,12 +93,12 @@ struct private_ike_p2p_t {
/**
* Received ID used for connectivity checks
*/
- chunk_t session_id;
+ chunk_t connect_id;
/**
* Received key used for connectivity checks
*/
- chunk_t session_key;
+ chunk_t connect_key;
/**
* Peer config of the mediated connection
@@ -138,7 +126,7 @@ static void add_endpoints_to_message(message_t *message, linked_list_t *endpoint
/**
* Gathers endpoints and adds them to the current message
*/
-static void gather_and_add_endpoints(private_ike_p2p_t *this, message_t *message)
+static void gather_and_add_endpoints(private_ike_me_t *this, message_t *message)
{
iterator_t *iterator;
host_t *addr, *host;
@@ -176,7 +164,7 @@ static void gather_and_add_endpoints(private_ike_p2p_t *this, message_t *message
/**
* read notifys from message and evaluate them
*/
-static void process_payloads(private_ike_p2p_t *this, message_t *message)
+static void process_payloads(private_ike_me_t *this, message_t *message)
{
iterator_t *iterator;
payload_t *payload;
@@ -193,55 +181,55 @@ static void process_payloads(private_ike_p2p_t *this, message_t *message)
switch (notify->get_notify_type(notify))
{
- case P2P_CONNECT_FAILED:
+ case ME_CONNECT_FAILED:
{
- DBG2(DBG_IKE, "received P2P_CONNECT_FAILED notify");
+ DBG2(DBG_IKE, "received ME_CONNECT_FAILED notify");
this->failed = TRUE;
break;
}
- case P2P_MEDIATION:
+ case ME_MEDIATION:
{
- DBG2(DBG_IKE, "received P2P_MEDIATION notify");
+ DBG2(DBG_IKE, "received ME_MEDIATION notify");
this->mediation = TRUE;
break;
}
- case P2P_ENDPOINT:
+ case ME_ENDPOINT:
{
endpoint_notify_t *endpoint = endpoint_notify_create_from_payload(notify);
if (!endpoint)
{
- DBG1(DBG_IKE, "received invalid P2P_ENDPOINT notify");
+ DBG1(DBG_IKE, "received invalid ME_ENDPOINT notify");
break;
}
- DBG1(DBG_IKE, "received %N P2P_ENDPOINT %#H", p2p_endpoint_type_names,
+ DBG1(DBG_IKE, "received %N ME_ENDPOINT %#H", me_endpoint_type_names,
endpoint->get_type(endpoint), endpoint->get_host(endpoint));
this->remote_endpoints->insert_last(this->remote_endpoints, endpoint);
break;
}
- case P2P_CALLBACK:
+ case ME_CALLBACK:
{
- DBG2(DBG_IKE, "received P2P_CALLBACK notify");
+ DBG2(DBG_IKE, "received ME_CALLBACK notify");
this->callback = TRUE;
break;
}
- case P2P_SESSIONID:
+ case ME_CONNECTID:
{
- chunk_free(&this->session_id);
- this->session_id = chunk_clone(notify->get_notification_data(notify));
- DBG3(DBG_IKE, "received p2p_sessionid %B", &this->session_id);
+ chunk_free(&this->connect_id);
+ this->connect_id = chunk_clone(notify->get_notification_data(notify));
+ DBG2(DBG_IKE, "received ME_CONNECTID %#B", &this->connect_id);
break;
}
- case P2P_SESSIONKEY:
+ case ME_CONNECTKEY:
{
- chunk_free(&this->session_key);
- this->session_key = chunk_clone(notify->get_notification_data(notify));
- DBG4(DBG_IKE, "received p2p_sessionkey %B", &this->session_key);
+ chunk_free(&this->connect_key);
+ this->connect_key = chunk_clone(notify->get_notification_data(notify));
+ DBG4(DBG_IKE, "received ME_CONNECTKEY %#B", &this->connect_key);
break;
}
- case P2P_RESPONSE:
+ case ME_RESPONSE:
{
- DBG2(DBG_IKE, "received P2P_RESPONSE notify");
+ DBG2(DBG_IKE, "received ME_RESPONSE notify");
this->response = TRUE;
break;
}
@@ -253,9 +241,9 @@ static void process_payloads(private_ike_p2p_t *this, message_t *message)
}
/**
- * Implementation of task_t.process for initiator
+ * Implementation of task_t.build for initiator
*/
-static status_t build_i(private_ike_p2p_t *this, message_t *message)
+static status_t build_i(private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
@@ -264,8 +252,8 @@ static status_t build_i(private_ike_p2p_t *this, message_t *message)
peer_cfg_t *peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
if (peer_cfg->is_mediation(peer_cfg))
{
- DBG2(DBG_IKE, "adding P2P_MEDIATION");
- message->add_notify(message, FALSE, P2P_MEDIATION, chunk_empty);
+ DBG2(DBG_IKE, "adding ME_MEDIATION");
+ message->add_notify(message, FALSE, ME_MEDIATION, chunk_empty);
}
else
{
@@ -283,48 +271,40 @@ static status_t build_i(private_ike_p2p_t *this, message_t *message)
}
break;
}
- case P2P_CONNECT:
+ case ME_CONNECT:
{
id_payload_t *id_payload;
- randomizer_t *rand = randomizer_create();
+ rng_t *rng;
id_payload = id_payload_create_from_identification(ID_PEER, this->peer_id);
message->add_payload(message, (payload_t*)id_payload);
- if (!this->response)
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ if (!rng)
{
- /* only the initiator creates a session ID. the responder returns
- * the session ID that it received from the initiator */
- if (rand->allocate_pseudo_random_bytes(rand,
- P2P_SESSIONID_LEN, &this->session_id) != SUCCESS)
- {
- DBG1(DBG_IKE, "unable to generate session ID for P2P_CONNECT");
- rand->destroy(rand);
- return FAILED;
- }
+ DBG1(DBG_IKE, "unable to generate connect ID for ME_CONNECT");
+ return FAILED;
}
-
- if (rand->allocate_pseudo_random_bytes(rand,
- P2P_SESSIONKEY_LEN, &this->session_key) != SUCCESS)
+ if (!this->response)
{
- DBG1(DBG_IKE, "unable to generate session key for P2P_CONNECT");
- rand->destroy(rand);
- return FAILED;
+ /* only the initiator creates a connect ID. the responder returns
+ * the connect ID that it received from the initiator */
+ rng->allocate_bytes(rng, ME_CONNECTID_LEN, &this->connect_id);
}
+ rng->allocate_bytes(rng, ME_CONNECTKEY_LEN, &this->connect_key);
+ rng->destroy(rng);
- rand->destroy(rand);
-
- message->add_notify(message, FALSE, P2P_SESSIONID, this->session_id);
- message->add_notify(message, FALSE, P2P_SESSIONKEY, this->session_key);
+ message->add_notify(message, FALSE, ME_CONNECTID, this->connect_id);
+ message->add_notify(message, FALSE, ME_CONNECTKEY, this->connect_key);
if (this->response)
{
- message->add_notify(message, FALSE, P2P_RESPONSE, chunk_empty);
+ message->add_notify(message, FALSE, ME_RESPONSE, chunk_empty);
}
else
{
- /* FIXME: should we make that configurable */
- message->add_notify(message, FALSE, P2P_CALLBACK, chunk_empty);
+ /* FIXME: should we make that configurable? */
+ message->add_notify(message, FALSE, ME_CALLBACK, chunk_empty);
}
gather_and_add_endpoints(this, message);
@@ -340,17 +320,17 @@ static status_t build_i(private_ike_p2p_t *this, message_t *message)
/**
* Implementation of task_t.process for responder
*/
-static status_t process_r(private_ike_p2p_t *this, message_t *message)
+static status_t process_r(private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
- case P2P_CONNECT:
+ case ME_CONNECT:
{
id_payload_t *id_payload;
id_payload = (id_payload_t*)message->get_payload(message, ID_PEER);
if (!id_payload)
{
- DBG1(DBG_IKE, "received P2P_CONNECT without ID_PEER payload, aborting");
+ DBG1(DBG_IKE, "received ME_CONNECT without ID_PEER payload, aborting");
break;
}
this->peer_id = id_payload->get_identification(id_payload);
@@ -359,32 +339,32 @@ static status_t process_r(private_ike_p2p_t *this, message_t *message)
if (this->callback)
{
- DBG1(DBG_IKE, "received P2P_CALLBACK for '%D'", this->peer_id);
+ DBG1(DBG_IKE, "received ME_CALLBACK for '%D'", this->peer_id);
break;
}
- if (!this->session_id.ptr)
+ if (!this->connect_id.ptr)
{
- DBG1(DBG_IKE, "received P2P_CONNECT without P2P_SESSIONID notify, aborting");
+ DBG1(DBG_IKE, "received ME_CONNECT without ME_CONNECTID notify, aborting");
this->invalid_syntax = TRUE;
break;
}
- if (!this->session_key.ptr)
+ if (!this->connect_key.ptr)
{
- DBG1(DBG_IKE, "received P2P_CONNECT without P2P_SESSIONKEY notify, aborting");
+ DBG1(DBG_IKE, "received ME_CONNECT without ME_CONNECTKEY notify, aborting");
this->invalid_syntax = TRUE;
break;
}
if (!this->remote_endpoints->get_count(this->remote_endpoints))
{
- DBG1(DBG_IKE, "received P2P_CONNECT without any P2P_ENDPOINT payloads, aborting");
+ DBG1(DBG_IKE, "received ME_CONNECT without any ME_ENDPOINT payloads, aborting");
this->invalid_syntax = TRUE;
break;
}
- DBG1(DBG_IKE, "received P2P_CONNECT");
+ DBG1(DBG_IKE, "received ME_CONNECT");
break;
}
default:
@@ -396,11 +376,11 @@ static status_t process_r(private_ike_p2p_t *this, message_t *message)
/**
* Implementation of task_t.build for responder
*/
-static status_t build_r(private_ike_p2p_t *this, message_t *message)
+static status_t build_r(private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
- case P2P_CONNECT:
+ case ME_CONNECT:
{
if (this->invalid_syntax)
{
@@ -422,7 +402,7 @@ static status_t build_r(private_ike_p2p_t *this, message_t *message)
* as initiator, upon receiving a response from another peer,
* update the checklist and start sending checks */
charon->connect_manager->set_responder_data(charon->connect_manager,
- this->session_id, this->session_key, this->remote_endpoints);
+ this->connect_id, this->connect_key, this->remote_endpoints);
}
else
{
@@ -430,10 +410,10 @@ static status_t build_r(private_ike_p2p_t *this, message_t *message)
* as responder, create a checklist with the initiator's data */
charon->connect_manager->set_initiator_data(charon->connect_manager,
this->peer_id, this->ike_sa->get_my_id(this->ike_sa),
- this->session_id, this->session_key, this->remote_endpoints,
+ this->connect_id, this->connect_key, this->remote_endpoints,
FALSE);
if (this->ike_sa->respond(this->ike_sa, this->peer_id,
- this->session_id) != SUCCESS)
+ this->connect_id) != SUCCESS)
{
return FAILED;
}
@@ -449,7 +429,7 @@ static status_t build_r(private_ike_p2p_t *this, message_t *message)
/**
* Implementation of task_t.process for initiator
*/
-static status_t process_i(private_ike_p2p_t *this, message_t *message)
+static status_t process_i(private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
@@ -459,7 +439,7 @@ static status_t process_i(private_ike_p2p_t *this, message_t *message)
if (!this->mediation)
{
- DBG1(DBG_IKE, "server did not return a P2P_MEDIATION, aborting");
+ DBG1(DBG_IKE, "server did not return a ME_MEDIATION, aborting");
return FAILED;
}
@@ -485,16 +465,14 @@ static status_t process_i(private_ike_p2p_t *this, message_t *message)
break;
}
- case P2P_CONNECT:
+ case ME_CONNECT:
{
process_payloads(this, message);
if (this->failed)
{
DBG1(DBG_IKE, "peer '%D' is not online", this->peer_id);
- /* FIXME: notify the mediated connection (job?)
- * FIXME: probably delete the created checklist, at least as
- * responder */
+ /* FIXME: notify the mediated connection (job?) */
}
else
{
@@ -503,7 +481,7 @@ static status_t process_i(private_ike_p2p_t *this, message_t *message)
/* FIXME: handle result of set_responder_data.
* as responder, we update the checklist and start sending checks */
charon->connect_manager->set_responder_data(charon->connect_manager,
- this->session_id, this->session_key, this->local_endpoints);
+ this->connect_id, this->connect_key, this->local_endpoints);
}
else
{
@@ -511,8 +489,10 @@ static status_t process_i(private_ike_p2p_t *this, message_t *message)
* as initiator, we create a checklist and set the initiator's data */
charon->connect_manager->set_initiator_data(charon->connect_manager,
this->ike_sa->get_my_id(this->ike_sa), this->peer_id,
- this->session_id, this->session_key, this->local_endpoints,
+ this->connect_id, this->connect_key, this->local_endpoints,
TRUE);
+ /* FIXME: also start a timer for the whole transaction (maybe
+ * within the connect_manager?) */
}
}
break;
@@ -524,29 +504,29 @@ static status_t process_i(private_ike_p2p_t *this, message_t *message)
}
/**
- * Implementation of task_t.process for initiator (mediation server)
+ * Implementation of task_t.build for initiator (mediation server)
*/
-static status_t build_i_ms(private_ike_p2p_t *this, message_t *message)
+static status_t build_i_ms(private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
- case P2P_CONNECT:
+ case ME_CONNECT:
{
id_payload_t *id_payload = id_payload_create_from_identification(ID_PEER, this->peer_id);
message->add_payload(message, (payload_t*)id_payload);
if (this->callback)
{
- message->add_notify(message, FALSE, P2P_CALLBACK, chunk_empty);
+ message->add_notify(message, FALSE, ME_CALLBACK, chunk_empty);
}
else
{
if (this->response)
{
- message->add_notify(message, FALSE, P2P_RESPONSE, chunk_empty);
+ message->add_notify(message, FALSE, ME_RESPONSE, chunk_empty);
}
- message->add_notify(message, FALSE, P2P_SESSIONID, this->session_id);
- message->add_notify(message, FALSE, P2P_SESSIONKEY, this->session_key);
+ message->add_notify(message, FALSE, ME_CONNECTID, this->connect_id);
+ message->add_notify(message, FALSE, ME_CONNECTKEY, this->connect_key);
add_endpoints_to_message(message, this->remote_endpoints);
}
@@ -562,27 +542,37 @@ static status_t build_i_ms(private_ike_p2p_t *this, message_t *message)
/**
* Implementation of task_t.process for responder (mediation server)
*/
-static status_t process_r_ms(private_ike_p2p_t *this, message_t *message)
+static status_t process_r_ms(private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
case IKE_SA_INIT:
{
+ /* FIXME: we should check for SA* and TS* payloads
+ * if any are there send NO_ADDITIONAL_SAS back and delete this SA */
process_payloads(this, message);
return this->mediation ? NEED_MORE : SUCCESS;
}
case IKE_AUTH:
{
+ /* FIXME: we should check whether the current peer_config is configured
+ * as mediation connection */
process_payloads(this, message);
break;
}
- case P2P_CONNECT:
+ case CREATE_CHILD_SA:
+ {
+ /* FIXME: if this is not to rekey the IKE SA we have to return a
+ * NO_ADDITIONAL_SAS and then delete the SA */
+ break;
+ }
+ case ME_CONNECT:
{
id_payload_t *id_payload;
id_payload = (id_payload_t*)message->get_payload(message, ID_PEER);
if (!id_payload)
{
- DBG1(DBG_IKE, "received P2P_CONNECT without ID_PEER payload, aborting");
+ DBG1(DBG_IKE, "received ME_CONNECT without ID_PEER payload, aborting");
this->invalid_syntax = TRUE;
break;
}
@@ -591,23 +581,23 @@ static status_t process_r_ms(private_ike_p2p_t *this, message_t *message)
process_payloads(this, message);
- if (!this->session_id.ptr)
+ if (!this->connect_id.ptr)
{
- DBG1(DBG_IKE, "received P2P_CONNECT without P2P_SESSIONID notify, aborting");
+ DBG1(DBG_IKE, "received ME_CONNECT without ME_CONNECTID notify, aborting");
this->invalid_syntax = TRUE;
break;
}
- if (!this->session_key.ptr)
+ if (!this->connect_key.ptr)
{
- DBG1(DBG_IKE, "received P2P_CONNECT without P2P_SESSIONKEY notify, aborting");
+ DBG1(DBG_IKE, "received ME_CONNECT without ME_CONNECTKEY notify, aborting");
this->invalid_syntax = TRUE;
break;
}
if (!this->remote_endpoints->get_count(this->remote_endpoints))
{
- DBG1(DBG_IKE, "received P2P_CONNECT without any P2P_ENDPOINT payloads, aborting");
+ DBG1(DBG_IKE, "received ME_CONNECT without any ME_ENDPOINT payloads, aborting");
this->invalid_syntax = TRUE;
break;
}
@@ -623,13 +613,13 @@ static status_t process_r_ms(private_ike_p2p_t *this, message_t *message)
/**
* Implementation of task_t.build for responder (mediation server)
*/
-static status_t build_r_ms(private_ike_p2p_t *this, message_t *message)
+static status_t build_r_ms(private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
case IKE_SA_INIT:
{
- message->add_notify(message, FALSE, P2P_MEDIATION, chunk_empty);
+ message->add_notify(message, FALSE, ME_MEDIATION, chunk_empty);
return NEED_MORE;
}
case IKE_AUTH:
@@ -645,17 +635,17 @@ static status_t build_r_ms(private_ike_p2p_t *this, message_t *message)
endpoint = endpoint_notify_create_from_host(SERVER_REFLEXIVE, host, NULL);
message->add_payload(message, (payload_t*)endpoint->build_notify(endpoint));
+ endpoint->destroy(endpoint);
}
- charon->mediation_manager->update_sa_id(charon->mediation_manager,
- this->ike_sa->get_other_id(this->ike_sa),
- this->ike_sa->get_id(this->ike_sa));
+ /* FIXME: we actually must delete any existing IKE_SAs with the same remote id */
+ this->ike_sa->act_as_mediation_server(this->ike_sa);
SIG(CHILD_UP_SUCCESS, "established mediation connection without CHILD_SA successfully");
break;
}
- case P2P_CONNECT:
+ case ME_CONNECT:
{
if (this->invalid_syntax)
{
@@ -678,13 +668,13 @@ static status_t build_r_ms(private_ike_p2p_t *this, message_t *message)
if (!peer_sa)
{
/* the peer is not online */
- message->add_notify(message, TRUE, P2P_CONNECT_FAILED, chunk_empty);
+ message->add_notify(message, TRUE, ME_CONNECT_FAILED, chunk_empty);
break;
}
job_t *job = (job_t*)mediation_job_create(this->peer_id,
- this->ike_sa->get_other_id(this->ike_sa), this->session_id,
- this->session_key, this->remote_endpoints, this->response);
+ this->ike_sa->get_other_id(this->ike_sa), this->connect_id,
+ this->connect_key, this->remote_endpoints, this->response);
charon->processor->queue_job(charon->processor, job);
break;
@@ -698,64 +688,71 @@ static status_t build_r_ms(private_ike_p2p_t *this, message_t *message)
/**
* Implementation of task_t.process for initiator (mediation server)
*/
-static status_t process_i_ms(private_ike_p2p_t *this, message_t *message)
+static status_t process_i_ms(private_ike_me_t *this, message_t *message)
{
+ /* FIXME: theoretically we should be prepared to receive a ME_CONNECT_FAILED
+ * here if the responding peer is not able to proceed. in this case we shall
+ * notify the initiating peer with a ME_CONNECT request containing only a
+ * ME_CONNECT_FAILED */
return SUCCESS;
}
/**
- * Implementation of ike_p2p.connect
+ * Implementation of ike_me.connect
*/
-static void p2p_connect(private_ike_p2p_t *this, identification_t *peer_id)
+static void me_connect(private_ike_me_t *this, identification_t *peer_id)
{
this->peer_id = peer_id->clone(peer_id);
}
/**
- * Implementation of ike_p2p.respond
+ * Implementation of ike_me.respond
*/
-static void p2p_respond(private_ike_p2p_t *this, identification_t *peer_id,
- chunk_t session_id)
+static void me_respond(private_ike_me_t *this, identification_t *peer_id,
+ chunk_t connect_id)
{
this->peer_id = peer_id->clone(peer_id);
- this->session_id = chunk_clone(session_id);
+ this->connect_id = chunk_clone(connect_id);
this->response = TRUE;
}
/**
- * Implementation of ike_p2p.callback
+ * Implementation of ike_me.callback
*/
-static void p2p_callback(private_ike_p2p_t *this, identification_t *peer_id)
+static void me_callback(private_ike_me_t *this, identification_t *peer_id)
{
this->peer_id = peer_id->clone(peer_id);
this->callback = TRUE;
}
/**
- * Implementation of ike_p2p.relay
+ * Implementation of ike_me.relay
*/
-static void relay(private_ike_p2p_t *this, identification_t *requester, chunk_t session_id,
- chunk_t session_key, linked_list_t *endpoints, bool response)
+static void relay(private_ike_me_t *this, identification_t *requester, chunk_t connect_id,
+ chunk_t connect_key, linked_list_t *endpoints, bool response)
{
this->peer_id = requester->clone(requester);
- this->session_id = chunk_clone(session_id);
- this->session_key = chunk_clone(session_key);
+ this->connect_id = chunk_clone(connect_id);
+ this->connect_key = chunk_clone(connect_key);
+
+ this->remote_endpoints->destroy_offset(this->remote_endpoints, offsetof(endpoint_notify_t, destroy));
this->remote_endpoints = endpoints->clone_offset(endpoints, offsetof(endpoint_notify_t, clone));
+
this->response = response;
}
/**
* Implementation of task_t.get_type
*/
-static task_type_t get_type(private_ike_p2p_t *this)
+static task_type_t get_type(private_ike_me_t *this)
{
- return IKE_P2P;
+ return IKE_ME;
}
/**
* Implementation of task_t.migrate
*/
-static void migrate(private_ike_p2p_t *this, ike_sa_t *ike_sa)
+static void migrate(private_ike_me_t *this, ike_sa_t *ike_sa)
{
this->ike_sa = ike_sa;
}
@@ -763,12 +760,12 @@ static void migrate(private_ike_p2p_t *this, ike_sa_t *ike_sa)
/**
* Implementation of task_t.destroy
*/
-static void destroy(private_ike_p2p_t *this)
+static void destroy(private_ike_me_t *this)
{
DESTROY_IF(this->peer_id);
- chunk_free(&this->session_id);
- chunk_free(&this->session_key);
+ chunk_free(&this->connect_id);
+ chunk_free(&this->connect_key);
this->local_endpoints->destroy_offset(this->local_endpoints, offsetof(endpoint_notify_t, destroy));
this->remote_endpoints->destroy_offset(this->remote_endpoints, offsetof(endpoint_notify_t, destroy));
@@ -780,16 +777,15 @@ static void destroy(private_ike_p2p_t *this)
/*
* Described in header.
*/
-ike_p2p_t *ike_p2p_create(ike_sa_t *ike_sa, bool initiator)
+ike_me_t *ike_me_create(ike_sa_t *ike_sa, bool initiator)
{
- private_ike_p2p_t *this = malloc_thing(private_ike_p2p_t);
+ private_ike_me_t *this = malloc_thing(private_ike_me_t);
this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
this->public.task.destroy = (void(*)(task_t*))destroy;
- ike_sa_id_t *id = ike_sa->get_id(ike_sa);
- if (id->is_initiator(id))
+ if (ike_sa->is_ike_initiator(ike_sa))
{
if (initiator)
{
@@ -817,17 +813,17 @@ ike_p2p_t *ike_p2p_create(ike_sa_t *ike_sa, bool initiator)
}
}
- this->public.connect = (void(*)(ike_p2p_t*,identification_t*))p2p_connect;
- this->public.respond = (void(*)(ike_p2p_t*,identification_t*,chunk_t))p2p_respond;
- this->public.callback = (void(*)(ike_p2p_t*,identification_t*))p2p_callback;
- this->public.relay = (void(*)(ike_p2p_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool))relay;
+ this->public.connect = (void(*)(ike_me_t*,identification_t*))me_connect;
+ this->public.respond = (void(*)(ike_me_t*,identification_t*,chunk_t))me_respond;
+ this->public.callback = (void(*)(ike_me_t*,identification_t*))me_callback;
+ this->public.relay = (void(*)(ike_me_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool))relay;
this->ike_sa = ike_sa;
this->initiator = initiator;
this->peer_id = NULL;
- this->session_id = chunk_empty;
- this->session_key = chunk_empty;
+ this->connect_id = chunk_empty;
+ this->connect_key = chunk_empty;
this->local_endpoints = linked_list_create();
this->remote_endpoints = linked_list_create();
this->mediation = FALSE;
diff --git a/src/charon/sa/tasks/ike_p2p.h b/src/charon/sa/tasks/ike_me.h
index 327ac49d8..c9a515c8f 100644
--- a/src/charon/sa/tasks/ike_p2p.h
+++ b/src/charon/sa/tasks/ike_me.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_p2p.h
- *
- * @brief Interface ike_p2p_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,35 +11,37 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_me.h 3666 2008-03-26 18:40:19Z tobias $
*/
-#ifndef IKE_P2P_H_
-#define IKE_P2P_H_
+/**
+ * @defgroup ike_me ike_me
+ * @{ @ingroup tasks
+ */
+
+#ifndef IKE_ME_H_
+#define IKE_ME_H_
-typedef struct ike_p2p_t ike_p2p_t;
+typedef struct ike_me_t ike_me_t;
#include <library.h>
#include <sa/ike_sa.h>
#include <sa/tasks/task.h>
/**
- * @brief Task of type IKE_P2P, detects and handles P2P-NAT-T extensions.
+ * Task of type IKE_ME, detects and handles IKE-ME extensions.
*
- * This tasks handles the P2P_MEDIATION notify exchange to setup a mediation
- * connection, allows to initiate mediated connections using P2P_CONNECT
+ * This tasks handles the ME_MEDIATION Notify exchange to setup a mediation
+ * connection, allows to initiate mediated connections using ME_CONNECT
* exchanges and to request reflexive addresses from the mediation server using
- * P2P_ENDPOINT notifies.
+ * ME_ENDPOINT notifies.
*
* @note This task has to be activated before the IKE_AUTH task, because that
* task generates the IKE_SA_INIT message so that no more payloads can be added
* to it afterwards.
- *
- * @b Constructors:
- * - ike_p2p_create()
- *
- * @ingroup tasks
*/
-struct ike_p2p_t {
+struct ike_me_t {
/**
* Implements the task_t interface
@@ -54,57 +49,52 @@ struct ike_p2p_t {
task_t task;
/**
- * @brief Initiates a connection with another peer (i.e. sends a P2P_CONNECT
+ * Initiates a connection with another peer (i.e. sends a ME_CONNECT
* to the mediation server)
*
- * @param this object
* @param peer_id ID of the other peer (gets cloned)
*/
- void (*connect)(ike_p2p_t *this, identification_t *peer_id);
+ void (*connect)(ike_me_t *this, identification_t *peer_id);
/**
- * @brief Responds to a P2P_CONNECT from another peer (i.e. sends a P2P_CONNECT
+ * Responds to a ME_CONNECT from another peer (i.e. sends a ME_CONNECT
* to the mediation server)
*
- * @param this object
* @param peer_id ID of the other peer (gets cloned)
- * @param session_id the session ID as provided by the initiator (gets cloned)
+ * @param connect_id the connect ID as provided by the initiator (gets cloned)
*/
- void (*respond)(ike_p2p_t *this, identification_t *peer_id, chunk_t session_id);
+ void (*respond)(ike_me_t *this, identification_t *peer_id, chunk_t connect_id);
/**
- * @brief Sends a P2P_CALLBACK to a peer that previously requested another peer.
+ * Sends a ME_CALLBACK to a peer that previously requested another peer.
*
- * @param this object
* @param peer_id ID of the other peer (gets cloned)
*/
- void (*callback)(ike_p2p_t *this, identification_t *peer_id);
+ void (*callback)(ike_me_t *this, identification_t *peer_id);
/**
- * @brief Relays data to another peer (i.e. sends a P2P_CONNECT to the peer)
+ * Relays data to another peer (i.e. sends a ME_CONNECT to the peer)
*
* Data gets cloned.
*
- * @param this object
* @param requester ID of the requesting peer
- * @param session_id content of the P2P_SESSIONID notify
- * @param session_key content of the P2P_SESSIONKEY notify
+ * @param connect_id content of the ME_CONNECTID notify
+ * @param connect_key content of the ME_CONNECTKEY notify
* @param endpoints endpoints
* @param response TRUE if this is a response
*/
- void (*relay)(ike_p2p_t *this, identification_t *requester, chunk_t session_id,
- chunk_t session_key, linked_list_t *endpoints, bool response);
+ void (*relay)(ike_me_t *this, identification_t *requester, chunk_t connect_id,
+ chunk_t connect_key, linked_list_t *endpoints, bool response);
};
/**
- * @brief Create a new ike_p2p task.
+ * Create a new ike_me task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if taks is initiated by us
- * @return ike_p2p task to handle by the task_manager
+ * @return ike_me task to handle by the task_manager
*/
-ike_p2p_t *ike_p2p_create(ike_sa_t *ike_sa, bool initiator);
-
+ike_me_t *ike_me_create(ike_sa_t *ike_sa, bool initiator);
-#endif /*IKE_P2P_H_*/
+#endif /*IKE_ME_H_ @} */
diff --git a/src/charon/sa/tasks/ike_mobike.c b/src/charon/sa/tasks/ike_mobike.c
index a53c243f0..23c68b9e9 100644
--- a/src/charon/sa/tasks/ike_mobike.c
+++ b/src/charon/sa/tasks/ike_mobike.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_mobike.c
- *
- * @brief Implementation of the ike_mobike task.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_mobike.c 4006 2008-05-23 15:43:42Z martin $
*/
#include "ike_mobike.h"
@@ -28,6 +23,7 @@
#include <sa/tasks/ike_natd.h>
#include <encoding/payloads/notify_payload.h>
+#define COOKIE2_SIZE 16
typedef struct private_ike_mobike_t private_ike_mobike_t;
@@ -125,6 +121,12 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
this->ike_sa->enable_extension(this->ike_sa, EXT_MOBIKE);
break;
}
+ case COOKIE2:
+ {
+ chunk_free(&this->cookie2);
+ this->cookie2 = chunk_clone(notify->get_notification_data(notify));
+ break;
+ }
case ADDITIONAL_IP6_ADDRESS:
{
family = AF_INET6;
@@ -211,6 +213,23 @@ static void build_address_list(private_ike_mobike_t *this, message_t *message)
}
/**
+ * build a cookie and add it to the message
+ */
+static void build_cookie(private_ike_mobike_t *this, message_t *message)
+{
+ rng_t *rng;
+
+ chunk_free(&this->cookie2);
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ if (rng)
+ {
+ rng->allocate_bytes(rng, COOKIE2_SIZE, &this->cookie2);
+ rng->destroy(rng);
+ message->add_notify(message, FALSE, COOKIE2, this->cookie2);
+ }
+}
+
+/**
* update addresses of associated CHILD_SAs
*/
static void update_children(private_ike_mobike_t *this)
@@ -262,6 +281,11 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
charon->kernel_interface, other);
if (me)
{
+ if (me->get_family(me) != other->get_family(other))
+ {
+ me->destroy(me);
+ continue;
+ }
/* reuse port for an active address, 4500 otherwise */
me->set_port(me, me->ip_equals(me, me_old) ?
me_old->get_port(me_old) : IKEV2_NATT_PORT);
@@ -297,6 +321,7 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
if (this->update)
{
message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, chunk_empty);
+ build_cookie(this, message);
update_children(this);
}
if (this->address)
@@ -363,6 +388,11 @@ static status_t build_r(private_ike_mobike_t *this, message_t *message)
{
this->natd->task.build(&this->natd->task, message);
}
+ if (this->cookie2.ptr)
+ {
+ message->add_notify(message, FALSE, COOKIE2, this->cookie2);
+ chunk_free(&this->cookie2);
+ }
if (this->update)
{
update_children(this);
@@ -392,7 +422,25 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message)
/* newer update queued, ignore this one */
return SUCCESS;
}
- process_payloads(this, message);
+ if (this->cookie2.ptr)
+ { /* check cookie if we included none */
+ chunk_t cookie2;
+
+ cookie2 = this->cookie2;
+ this->cookie2 = chunk_empty;
+ process_payloads(this, message);
+ if (!chunk_equals(cookie2, this->cookie2))
+ {
+ chunk_free(&cookie2);
+ DBG1(DBG_IKE, "COOKIE2 mismatch, closing IKE_SA");
+ return FAILED;
+ }
+ chunk_free(&cookie2);
+ }
+ else
+ {
+ process_payloads(this, message);
+ }
if (this->natd)
{
this->natd->task.process(&this->natd->task, message);
diff --git a/src/charon/sa/tasks/ike_mobike.h b/src/charon/sa/tasks/ike_mobike.h
index bb5150723..9dd29970e 100644
--- a/src/charon/sa/tasks/ike_mobike.h
+++ b/src/charon/sa/tasks/ike_mobike.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_mobike.h
- *
- * @brief Interface ike_mobike_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_mobike.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ike_mobike ike_mobike
+ * @{ @ingroup tasks
*/
#ifndef IKE_MOBIKE_H_
@@ -31,7 +31,7 @@ typedef struct ike_mobike_t ike_mobike_t;
#include <network/packet.h>
/**
- * @brief Task of type ike_mobike, detects and handles MOBIKE extension.
+ * Task of type ike_mobike, detects and handles MOBIKE extension.
*
* The MOBIKE extension is defined in RFC4555. It allows to update IKE
* and IPsec tunnel addresses.
@@ -39,11 +39,6 @@ typedef struct ike_mobike_t ike_mobike_t;
* support, allows the exchange of ADDITIONAL_*_ADDRESS to exchange additional
* endpoints and handles the UPDATE_SA_ADDRESS notify to finally update
* endpoints.
- *
- * @b Constructors:
- * - ike_mobike_create()
- *
- * @ingroup tasks
*/
struct ike_mobike_t {
@@ -53,36 +48,33 @@ struct ike_mobike_t {
task_t task;
/**
- * @brief Use the task to roam to other addresses.
+ * Use the task to roam to other addresses.
*
- * @param this calling object
* @param address TRUE to include address list update
*/
void (*roam)(ike_mobike_t *this, bool address);
/**
- * @brief Transmision hook, called by task manager.
+ * Transmision hook, called by task manager.
*
* The task manager calls this hook whenever it transmits a packet. It
* allows the mobike task to send the packet on multiple paths to do path
* probing.
*
- * @param this calling object
* @param packet the packet to transmit
*/
void (*transmit)(ike_mobike_t *this, packet_t *packet);
/**
- * @brief Check if this task is probing for routability.
+ * Check if this task is probing for routability.
*
- * @param this calling object
* @return TRUE if task is probing
*/
bool (*is_probing)(ike_mobike_t *this);
};
/**
- * @brief Create a new ike_mobike task.
+ * Create a new ike_mobike task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if taks is initiated by us
@@ -90,5 +82,4 @@ struct ike_mobike_t {
*/
ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator);
-#endif /* IKE_MOBIKE_H_ */
-
+#endif /* IKE_MOBIKE_H_ @} */
diff --git a/src/charon/sa/tasks/ike_natd.c b/src/charon/sa/tasks/ike_natd.c
index 4c64ff8ba..69e5bac26 100644
--- a/src/charon/sa/tasks/ike_natd.c
+++ b/src/charon/sa/tasks/ike_natd.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_natd.c
- *
- * @brief Implementation of the ike_natd task.
- *
- */
-
/*
* Copyright (C) 2006-2007 Martin Willi
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_natd.c 3806 2008-04-15 05:56:35Z martin $
*/
#include "ike_natd.h"
@@ -118,17 +113,17 @@ static chunk_t generate_natd_hash(private_ike_natd_t *this,
*/
static chunk_t generate_natd_hash_faked(private_ike_natd_t *this)
{
- randomizer_t *randomizer;
+ rng_t *rng;
chunk_t chunk;
- randomizer = randomizer_create();
- if (randomizer->allocate_pseudo_random_bytes(randomizer, HASH_SIZE_SHA1,
- &chunk) != SUCCESS)
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (!rng)
{
DBG1(DBG_IKE, "unable to get random bytes for NATD fake");
- chunk = chunk_empty;
+ return chunk_empty;
}
- randomizer->destroy(randomizer);
+ rng->allocate_bytes(rng, HASH_SIZE_SHA1, &chunk);
+ rng->destroy(rng);
return chunk;
}
@@ -259,7 +254,7 @@ static status_t process_i(private_ike_natd_t *this, message_t *message)
{
peer_cfg_t *peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
-#ifdef P2P
+#ifdef ME
/* if we are on a mediated connection we have already switched to
* port 4500 and the correct destination port is already configured,
* therefore we must not switch again */
@@ -267,14 +262,14 @@ static status_t process_i(private_ike_natd_t *this, message_t *message)
{
return SUCCESS;
}
-#endif /* P2P */
+#endif /* ME */
if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY) ||
-#ifdef P2P
+#ifdef ME
/* if we are on a mediation connection we swith to port 4500 even
* if no NAT is detected. */
peer_cfg->is_mediation(peer_cfg) ||
-#endif /* P2P */
+#endif /* ME */
/* if peer supports NAT-T, we switch to port 4500 even
* if no NAT is detected. MOBIKE requires this. */
(peer_cfg->use_mobike(peer_cfg) &&
@@ -308,6 +303,12 @@ static status_t build_i(private_ike_natd_t *this, message_t *message)
iterator_t *iterator;
host_t *host;
+ if (this->hasher == NULL)
+ {
+ DBG1(DBG_IKE, "unable to build NATD payloads, SHA1 not supported");
+ return NEED_MORE;
+ }
+
/* destination is always set */
host = message->get_destination(message);
notify = build_natd_payload(this, NAT_DETECTION_DESTINATION_IP, host);
@@ -368,6 +369,12 @@ static status_t build_r(private_ike_natd_t *this, message_t *message)
if (this->src_seen && this->dst_seen)
{
+ if (this->hasher == NULL)
+ {
+ DBG1(DBG_IKE, "unable to build NATD payloads, SHA1 not supported");
+ return SUCCESS;
+ }
+
/* initiator seems to support NAT detection, add response */
me = message->get_source(message);
notify = build_natd_payload(this, NAT_DETECTION_SOURCE_IP, me);
@@ -415,7 +422,7 @@ static void migrate(private_ike_natd_t *this, ike_sa_t *ike_sa)
*/
static void destroy(private_ike_natd_t *this)
{
- this->hasher->destroy(this->hasher);
+ DESTROY_IF(this->hasher);
free(this);
}
@@ -443,7 +450,7 @@ ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator)
this->ike_sa = ike_sa;
this->initiator = initiator;
- this->hasher = hasher_create(HASH_SHA1);
+ this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
this->src_seen = FALSE;
this->dst_seen = FALSE;
this->src_matched = FALSE;
diff --git a/src/charon/sa/tasks/ike_natd.h b/src/charon/sa/tasks/ike_natd.h
index 8d0cb58b4..d78c931d9 100644
--- a/src/charon/sa/tasks/ike_natd.h
+++ b/src/charon/sa/tasks/ike_natd.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_natd.h
- *
- * @brief Interface ike_natd_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_natd.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ike_natd ike_natd
+ * @{ @ingroup tasks
*/
#ifndef IKE_NATD_H_
@@ -30,12 +30,7 @@ typedef struct ike_natd_t ike_natd_t;
#include <sa/tasks/task.h>
/**
- * @brief Task of type ike_natd, detects NAT situation in IKE_SA_INIT exchange.
- *
- * @b Constructors:
- * - ike_natd_create()
- *
- * @ingroup tasks
+ * Task of type ike_natd, detects NAT situation in IKE_SA_INIT exchange.
*/
struct ike_natd_t {
@@ -46,7 +41,7 @@ struct ike_natd_t {
};
/**
- * @brief Create a new ike_natd task.
+ * Create a new ike_natd task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if thask is the original initator
@@ -54,4 +49,4 @@ struct ike_natd_t {
*/
ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator);
-#endif /* IKE_NATD_H_ */
+#endif /* IKE_NATD_H_ @} */
diff --git a/src/charon/sa/tasks/ike_reauth.c b/src/charon/sa/tasks/ike_reauth.c
index 0e98382a8..854e9359d 100644
--- a/src/charon/sa/tasks/ike_reauth.c
+++ b/src/charon/sa/tasks/ike_reauth.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_reauth.c
- *
- * @brief Implementation of the ike_reauth task.
- *
- */
-
/*
* Copyright (C) 2006-2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_reauth.c 3793 2008-04-11 08:14:48Z martin $
*/
#include "ike_reauth.h"
@@ -66,22 +61,30 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message)
host_t *host;
iterator_t *iterator;
child_sa_t *child_sa;
+ peer_cfg_t *peer_cfg;
/* process delete response first */
this->ike_delete->task.process(&this->ike_delete->task, message);
- /* reestablish only if we have children */
+ peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
+
+ /* reauthenticate only if we have children */
iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa);
- if (iterator->get_count(iterator) == 0)
+ if (iterator->get_count(iterator) == 0
+#ifdef ME
+ /* we allow a peer to reauth a mediation connection (without CHILD_SA) */
+ && !peer_cfg->is_mediation(peer_cfg)
+#endif /* ME */
+ )
{
- DBG1(DBG_IKE, "unable to reestablish IKE_SA, no CHILD_SA to recreate");
+ DBG1(DBG_IKE, "unable to reauthenticate IKE_SA, no CHILD_SA to recreate");
iterator->destroy(iterator);
return FAILED;
}
new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, TRUE);
- new->set_peer_cfg(new, this->ike_sa->get_peer_cfg(this->ike_sa));
+ new->set_peer_cfg(new, peer_cfg);
host = this->ike_sa->get_other_host(this->ike_sa);
new->set_other_host(new, host->clone(host));
host = this->ike_sa->get_my_host(this->ike_sa);
@@ -93,6 +96,20 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message)
new->set_virtual_ip(new, TRUE, host);
}
+#ifdef ME
+ /* we initiate the new IKE_SA of the mediation connection without CHILD_SA */
+ if (peer_cfg->is_mediation(peer_cfg))
+ {
+ if (new->initiate(new, NULL) == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, new);
+ DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
+ return FAILED;
+ }
+ }
+#endif /* ME */
+
while (iterator->iterate(iterator, (void**)&child_sa))
{
switch (child_sa->get_state(child_sa))
@@ -114,7 +131,7 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message)
iterator->destroy(iterator);
charon->ike_sa_manager->checkin_and_destroy(
charon->ike_sa_manager, new);
- DBG1(DBG_IKE, "reestablishing IKE_SA failed");
+ DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
return FAILED;
}
break;
diff --git a/src/charon/sa/tasks/ike_reauth.h b/src/charon/sa/tasks/ike_reauth.h
index 3c872e1e1..1076cc7cc 100644
--- a/src/charon/sa/tasks/ike_reauth.h
+++ b/src/charon/sa/tasks/ike_reauth.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_reauth.h
- *
- * @brief Interface ike_reauth_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_reauth.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ike_reauth ike_reauth
+ * @{ @ingroup tasks
*/
#ifndef IKE_REAUTH_H_
@@ -30,12 +30,7 @@ typedef struct ike_reauth_t ike_reauth_t;
#include <sa/tasks/task.h>
/**
- * @brief Task of type ike_reauth, reestablishes an IKE_SA.
- *
- * @b Constructors:
- * - ike_reauth_create()
- *
- * @ingroup tasks
+ * Task of type ike_reauth, reestablishes an IKE_SA.
*/
struct ike_reauth_t {
@@ -46,7 +41,7 @@ struct ike_reauth_t {
};
/**
- * @brief Create a new ike_reauth task.
+ * Create a new ike_reauth task.
*
* This task is initiator only.
*
@@ -55,5 +50,4 @@ struct ike_reauth_t {
*/
ike_reauth_t *ike_reauth_create(ike_sa_t *ike_sa);
-#endif /* IKE_REAUTH_H_ */
-
+#endif /* IKE_REAUTH_H_ @} */
diff --git a/src/charon/sa/tasks/ike_rekey.c b/src/charon/sa/tasks/ike_rekey.c
index 827f95156..9c0d1805c 100644
--- a/src/charon/sa/tasks/ike_rekey.c
+++ b/src/charon/sa/tasks/ike_rekey.c
@@ -1,10 +1,3 @@
-/**
- * @file ike_rekey.c
- *
- * @brief Implementation of the ike_rekey task.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_rekey.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "ike_rekey.h"
diff --git a/src/charon/sa/tasks/ike_rekey.h b/src/charon/sa/tasks/ike_rekey.h
index 125422efd..1bfde8a54 100644
--- a/src/charon/sa/tasks/ike_rekey.h
+++ b/src/charon/sa/tasks/ike_rekey.h
@@ -1,10 +1,3 @@
-/**
- * @file ike_rekey.h
- *
- * @brief Interface ike_rekey_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: ike_rekey.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ike_rekey ike_rekey
+ * @{ @ingroup tasks
*/
#ifndef IKE_REKEY_H_
@@ -30,12 +30,7 @@ typedef struct ike_rekey_t ike_rekey_t;
#include <sa/tasks/task.h>
/**
- * @brief Task of type IKE_REKEY, rekey an established IKE_SA.
- *
- * @b Constructors:
- * - ike_rekey_create()
- *
- * @ingroup tasks
+ * Task of type IKE_REKEY, rekey an established IKE_SA.
*/
struct ike_rekey_t {
@@ -45,20 +40,19 @@ struct ike_rekey_t {
task_t task;
/**
- * @brief Register a rekeying task which collides with this one.
+ * Register a rekeying task which collides with this one.
*
* If two peers initiate rekeying at the same time, the collision must
* be handled gracefully. The task manager is aware of what exchanges
* are going on and notifies the outgoing task by passing the incoming.
*
- * @param this task initated by us
* @param other incoming task
*/
void (*collide)(ike_rekey_t* this, task_t *other);
};
/**
- * @brief Create a new IKE_REKEY task.
+ * Create a new IKE_REKEY task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE for initiator, FALSE for responder
@@ -66,4 +60,4 @@ struct ike_rekey_t {
*/
ike_rekey_t *ike_rekey_create(ike_sa_t *ike_sa, bool initiator);
-#endif /* IKE_REKEY_H_ */
+#endif /* IKE_REKEY_H_ @} */
diff --git a/src/charon/sa/tasks/task.c b/src/charon/sa/tasks/task.c
index cc20a8861..3192b688a 100644
--- a/src/charon/sa/tasks/task.c
+++ b/src/charon/sa/tasks/task.c
@@ -1,10 +1,3 @@
-/**
- * @file task.c
- *
- * @brief Enum values for task types
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2007 Martin Willi
@@ -19,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: task.c 3666 2008-03-26 18:40:19Z tobias $
*/
#include "task.h"
@@ -29,15 +24,16 @@ ENUM(task_type_names, IKE_INIT, CHILD_REKEY,
"IKE_MOBIKE",
"IKE_AUTHENTICATE",
"IKE_AUTH_LIFETIME",
- "IKE_CERT",
+ "IKE_CERT_PRE",
+ "IKE_CERT_POST",
"IKE_CONFIG",
"IKE_REKEY",
"IKE_REAUTH",
"IKE_DELETE",
"IKE_DPD",
-#ifdef P2P
- "IKE_P2P",
-#endif /* P2P */
+#ifdef ME
+ "IKE_ME",
+#endif /* ME */
"CHILD_CREATE",
"CHILD_DELETE",
"CHILD_REKEY",
diff --git a/src/charon/sa/tasks/task.h b/src/charon/sa/tasks/task.h
index a59207711..26b4f214e 100644
--- a/src/charon/sa/tasks/task.h
+++ b/src/charon/sa/tasks/task.h
@@ -1,10 +1,3 @@
-/**
- * @file task.h
- *
- * @brief Interface task_t.
- *
- */
-
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2006 Martin Willi
@@ -19,6 +12,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: task.h 3666 2008-03-26 18:40:19Z tobias $
+ */
+
+/**
+ * @defgroup task task
+ * @{ @ingroup tasks
*/
#ifndef TASK_H_
@@ -32,9 +32,7 @@ typedef struct task_t task_t;
#include <encoding/message.h>
/**
- * @brief Different kinds of tasks.
- *
- * @ingroup tasks
+ * Different kinds of tasks.
*/
enum task_type_t {
/** establish an unauthenticated IKE_SA */
@@ -47,8 +45,10 @@ enum task_type_t {
IKE_AUTHENTICATE,
/** AUTH_LIFETIME negotiation, RFC4478 */
IKE_AUTH_LIFETIME,
- /** exchange certificates and requests */
- IKE_CERT,
+ /** certificate processing before authentication (certreqs, cert parsing) */
+ IKE_CERT_PRE,
+ /** certificate processing after authentication (certs payload generation) */
+ IKE_CERT_POST,
/** Configuration payloads, virtual IP and such */
IKE_CONFIG,
/** rekey an IKE_SA */
@@ -59,10 +59,10 @@ enum task_type_t {
IKE_DELETE,
/** liveness check */
IKE_DPD,
-#ifdef P2P
- /** handle P2P-NAT-T stuff */
- IKE_P2P,
-#endif /* P2P */
+#ifdef ME
+ /** handle ME stuff */
+ IKE_ME,
+#endif /* ME */
/** establish a CHILD_SA within an IKE_SA */
CHILD_CREATE,
/** delete an established CHILD_SA */
@@ -77,7 +77,7 @@ enum task_type_t {
extern enum_name_t *task_type_names;
/**
- * @brief Interface for a task, an operation handled within exchanges.
+ * Interface for a task, an operation handled within exchanges.
*
* A task is an elemantary operation. It may be handled by a single or by
* multiple exchanges. An exchange may even complete multiple tasks.
@@ -94,18 +94,12 @@ extern enum_name_t *task_type_names;
* the task needs further build()/process() calls to complete, the manager
* leaves the taks in the queue. A returned FAILED indicates a critical failure.
* The manager closes the IKE_SA whenever a task returns FAILED.
- *
- * @b Constructors:
- * - None, use implementations specific constructors
- *
- * @ingroup tasks
*/
struct task_t {
/**
- * @brief Build a request or response message for this task.
+ * Build a request or response message for this task.
*
- * @param this calling object
* @param message message to add payloads to
* @return
* - FAILED if a critical error occured
@@ -115,9 +109,8 @@ struct task_t {
status_t (*build) (task_t *this, message_t *message);
/**
- * @brief Process a request or response message for this task.
+ * Process a request or response message for this task.
*
- * @param this calling object
* @param message message to read payloads from
* @return
* - FAILED if a critical error occured
@@ -127,14 +120,12 @@ struct task_t {
status_t (*process) (task_t *this, message_t *message);
/**
- * @brief Get the type of the task implementation.
- *
- * @param this calling object
+ * Get the type of the task implementation.
*/
task_type_t (*get_type) (task_t *this);
/**
- * @brief Migrate a task to a new IKE_SA.
+ * Migrate a task to a new IKE_SA.
*
* After migrating a task, it goes back to a state where it can be
* used again to initate an exchange. This is useful when a task
@@ -144,17 +135,14 @@ struct task_t {
* try.
* The ike_sa is the new IKE_SA this task belongs to and operates on.
*
- * @param this calling object
* @param ike_sa new IKE_SA this task works for
*/
void (*migrate) (task_t *this, ike_sa_t *ike_sa);
/**
- * @brief Destroys a task_t object.
- *
- * @param this calling object
+ * Destroys a task_t object.
*/
void (*destroy) (task_t *this);
};
-#endif /* TASK_H_ */
+#endif /* TASK_H_ @} */