summaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/Makefile.am31
-rw-r--r--src/Makefile.in67
-rw-r--r--src/_copyright/Makefile.in37
-rw-r--r--src/_updown/Makefile.in20
-rw-r--r--src/_updown_espmark/Makefile.in20
-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
-rw-r--r--src/dumm/Makefile.am14
-rw-r--r--src/dumm/Makefile.in78
-rw-r--r--src/dumm/bridge.c31
-rw-r--r--src/dumm/bridge.h18
-rw-r--r--src/dumm/dumm.c207
-rw-r--r--src/dumm/dumm.h32
-rw-r--r--src/dumm/guest.c162
-rw-r--r--src/dumm/guest.h61
-rw-r--r--src/dumm/iface.c46
-rw-r--r--src/dumm/iface.h6
-rw-r--r--src/dumm/main.c953
-rw-r--r--src/dumm/mconsole.c102
-rw-r--r--src/dumm/mconsole.h11
-rw-r--r--src/dumm/testing.c171
-rw-r--r--src/include/Makefile.am3
-rw-r--r--src/include/Makefile.in23
-rw-r--r--src/include/linux/pfkeyv2.h5
-rw-r--r--src/include/linux/types.h172
-rw-r--r--src/include/linux/xfrm.h140
-rw-r--r--src/include/sys/queue.h557
-rw-r--r--src/ipsec/Makefile.in20
-rw-r--r--src/libcrypto/Makefile.in33
-rw-r--r--src/libcrypto/libaes/aes_cbc.c4
-rw-r--r--src/libcrypto/libaes/aes_cbc.h4
-rw-r--r--src/libfast/Makefile.am8
-rw-r--r--src/libfast/Makefile.in497
-rw-r--r--src/libfast/context.h (renamed from src/manager/lib/context.h)25
-rw-r--r--src/libfast/controller.h (renamed from src/manager/lib/controller.h)43
-rw-r--r--src/libfast/dispatcher.c (renamed from src/manager/lib/dispatcher.c)280
-rw-r--r--src/libfast/dispatcher.h139
-rw-r--r--src/libfast/filter.h65
-rw-r--r--src/libfast/request.c (renamed from src/manager/lib/request.c)208
-rw-r--r--src/libfast/request.h (renamed from src/manager/lib/request.h)101
-rw-r--r--src/libfast/session.c (renamed from src/manager/lib/session.c)104
-rw-r--r--src/libfast/session.h (renamed from src/manager/lib/session.h)39
-rw-r--r--src/libfreeswan/Makefile.in33
-rw-r--r--src/libfreeswan/ipsec_policy.h64
-rw-r--r--src/libfreeswan/pfkeyv2.h82
-rw-r--r--src/libfreeswan/ttoaddr.c4
-rw-r--r--src/libstrongswan/Makefile.am161
-rw-r--r--src/libstrongswan/Makefile.in891
-rw-r--r--src/libstrongswan/asn1/asn1.c366
-rw-r--r--src/libstrongswan/asn1/asn1.h223
-rw-r--r--src/libstrongswan/asn1/asn1_parser.c302
-rw-r--r--src/libstrongswan/asn1/asn1_parser.h119
-rw-r--r--src/libstrongswan/asn1/oid.c276
-rw-r--r--src/libstrongswan/asn1/oid.h124
-rw-r--r--src/libstrongswan/asn1/oid.txt70
-rwxr-xr-xsrc/libstrongswan/asn1/pem.c108
-rwxr-xr-xsrc/libstrongswan/asn1/pem.h14
-rw-r--r--src/libstrongswan/asn1/ttodata.c433
-rw-r--r--src/libstrongswan/asn1/ttodata.h28
-rw-r--r--src/libstrongswan/chunk.c322
-rw-r--r--src/libstrongswan/chunk.h85
-rwxr-xr-xsrc/libstrongswan/credential_store.h330
-rw-r--r--src/libstrongswan/credentials/builder.c38
-rw-r--r--src/libstrongswan/credentials/builder.h115
-rw-r--r--src/libstrongswan/credentials/certificates/ac.h86
-rw-r--r--src/libstrongswan/credentials/certificates/certificate.c41
-rw-r--r--src/libstrongswan/credentials/certificates/certificate.h192
-rw-r--r--src/libstrongswan/credentials/certificates/crl.c31
-rw-r--r--src/libstrongswan/credentials/certificates/crl.h88
-rw-r--r--src/libstrongswan/credentials/certificates/ocsp_request.h41
-rw-r--r--src/libstrongswan/credentials/certificates/ocsp_response.c29
-rw-r--r--src/libstrongswan/credentials/certificates/ocsp_response.h84
-rw-r--r--src/libstrongswan/credentials/certificates/x509.c26
-rw-r--r--src/libstrongswan/credentials/certificates/x509.h107
-rw-r--r--src/libstrongswan/credentials/credential_factory.c312
-rw-r--r--src/libstrongswan/credentials/credential_factory.h105
-rw-r--r--src/libstrongswan/credentials/keys/private_key.c19
-rw-r--r--src/libstrongswan/credentials/keys/private_key.h114
-rw-r--r--src/libstrongswan/credentials/keys/public_key.c37
-rw-r--r--src/libstrongswan/credentials/keys/public_key.h155
-rw-r--r--src/libstrongswan/credentials/keys/shared_key.c111
-rw-r--r--src/libstrongswan/credentials/keys/shared_key.h95
-rw-r--r--src/libstrongswan/crypto/ac.c636
-rw-r--r--src/libstrongswan/crypto/ac.h110
-rw-r--r--src/libstrongswan/crypto/ca.c813
-rw-r--r--src/libstrongswan/crypto/ca.h243
-rw-r--r--src/libstrongswan/crypto/certinfo.c257
-rw-r--r--src/libstrongswan/crypto/certinfo.h203
-rwxr-xr-xsrc/libstrongswan/crypto/crl.c536
-rwxr-xr-xsrc/libstrongswan/crypto/crl.h158
-rw-r--r--src/libstrongswan/crypto/crypters/crypter.c47
-rw-r--r--src/libstrongswan/crypto/crypters/crypter.h121
-rw-r--r--src/libstrongswan/crypto/crypto_factory.c571
-rw-r--r--src/libstrongswan/crypto/crypto_factory.h235
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.c573
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.h85
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.c64
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.h140
-rw-r--r--src/libstrongswan/crypto/ocsp.c934
-rw-r--r--src/libstrongswan/crypto/ocsp.h89
-rw-r--r--src/libstrongswan/crypto/pkcs7.c1077
-rw-r--r--src/libstrongswan/crypto/pkcs7.h209
-rw-r--r--src/libstrongswan/crypto/pkcs9.c82
-rw-r--r--src/libstrongswan/crypto/pkcs9.h63
-rw-r--r--src/libstrongswan/crypto/prf_plus.c9
-rw-r--r--src/libstrongswan/crypto/prf_plus.h46
-rw-r--r--src/libstrongswan/crypto/prfs/prf.c47
-rw-r--r--src/libstrongswan/crypto/prfs/prf.h82
-rw-r--r--src/libstrongswan/crypto/rngs/rng.c24
-rw-r--r--src/libstrongswan/crypto/rngs/rng.h75
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_private_key.c722
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_private_key.h163
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_public_key.c516
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_public_key.h173
-rw-r--r--src/libstrongswan/crypto/signers/signer.c34
-rw-r--r--src/libstrongswan/crypto/signers/signer.h84
-rwxr-xr-xsrc/libstrongswan/crypto/x509.c1562
-rwxr-xr-xsrc/libstrongswan/crypto/x509.h406
-rw-r--r--src/libstrongswan/database/database.h103
-rw-r--r--src/libstrongswan/database/database_factory.c119
-rw-r--r--src/libstrongswan/database/database_factory.h73
-rw-r--r--src/libstrongswan/debug.c22
-rw-r--r--src/libstrongswan/debug.h16
-rw-r--r--src/libstrongswan/enum.c33
-rw-r--r--src/libstrongswan/enum.h55
-rw-r--r--src/libstrongswan/fetcher/fetcher.h105
-rw-r--r--src/libstrongswan/fetcher/fetcher_manager.c208
-rw-r--r--src/libstrongswan/fetcher/fetcher_manager.h74
-rw-r--r--src/libstrongswan/fips/fips.c15
-rw-r--r--src/libstrongswan/fips/fips.h33
-rw-r--r--src/libstrongswan/fips/fips_canister_end.c9
-rw-r--r--src/libstrongswan/fips/fips_canister_start.c9
-rw-r--r--src/libstrongswan/fips/fips_signer.c17
-rw-r--r--src/libstrongswan/library.c222
-rw-r--r--src/libstrongswan/library.h324
-rw-r--r--src/libstrongswan/plugins/aes/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/aes/Makefile.in494
-rw-r--r--src/libstrongswan/plugins/aes/aes_crypter.c (renamed from src/libstrongswan/crypto/crypters/aes_cbc_crypter.c)164
-rw-r--r--src/libstrongswan/plugins/aes/aes_crypter.h (renamed from src/libstrongswan/crypto/crypters/aes_cbc_crypter.h)45
-rw-r--r--src/libstrongswan/plugins/aes/aes_plugin.c60
-rw-r--r--src/libstrongswan/plugins/aes/aes_plugin.h47
-rw-r--r--src/libstrongswan/plugins/curl/Makefile.am11
-rw-r--r--src/libstrongswan/plugins/curl/Makefile.in495
-rw-r--r--src/libstrongswan/plugins/curl/curl_fetcher.c176
-rw-r--r--src/libstrongswan/plugins/curl/curl_fetcher.h47
-rw-r--r--src/libstrongswan/plugins/curl/curl_plugin.c79
-rw-r--r--src/libstrongswan/plugins/curl/curl_plugin.h47
-rw-r--r--src/libstrongswan/plugins/des/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/des/Makefile.in494
-rw-r--r--src/libstrongswan/plugins/des/des_crypter.c (renamed from src/libstrongswan/crypto/crypters/des_crypter.c)107
-rw-r--r--src/libstrongswan/plugins/des/des_crypter.h (renamed from src/libstrongswan/crypto/crypters/des_crypter.h)29
-rw-r--r--src/libstrongswan/plugins/des/des_plugin.c62
-rw-r--r--src/libstrongswan/plugins/des/des_plugin.h47
-rw-r--r--src/libstrongswan/plugins/fips_prf/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/fips_prf/Makefile.in496
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf.c (renamed from src/libstrongswan/crypto/prfs/fips_prf.c)82
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf.h (renamed from src/libstrongswan/crypto/prfs/fips_prf.h)47
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c59
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf_plugin.h47
-rw-r--r--src/libstrongswan/plugins/gmp/Makefile.am15
-rw-r--r--src/libstrongswan/plugins/gmp/Makefile.in502
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c567
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h49
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_plugin.c85
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_plugin.h47
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c842
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h48
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c587
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h50
-rw-r--r--src/libstrongswan/plugins/hmac/Makefile.am11
-rw-r--r--src/libstrongswan/plugins/hmac/Makefile.in499
-rw-r--r--src/libstrongswan/plugins/hmac/hmac.c (renamed from src/libstrongswan/crypto/hmac.c)21
-rw-r--r--src/libstrongswan/plugins/hmac/hmac.h (renamed from src/libstrongswan/crypto/hmac.h)68
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_plugin.c84
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_plugin.h47
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_prf.c (renamed from src/libstrongswan/crypto/prfs/hmac_prf.c)53
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_prf.h (renamed from src/libstrongswan/crypto/prfs/hmac_prf.h)38
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_signer.c (renamed from src/libstrongswan/crypto/signers/hmac_signer.c)120
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_signer.h (renamed from src/libstrongswan/crypto/signers/hmac_signer.h)39
-rw-r--r--src/libstrongswan/plugins/ldap/Makefile.am11
-rw-r--r--src/libstrongswan/plugins/ldap/Makefile.in495
-rw-r--r--src/libstrongswan/plugins/ldap/ldap_fetcher.c213
-rw-r--r--src/libstrongswan/plugins/ldap/ldap_fetcher.h42
-rw-r--r--src/libstrongswan/plugins/ldap/ldap_plugin.c62
-rw-r--r--src/libstrongswan/plugins/ldap/ldap_plugin.h47
-rw-r--r--src/libstrongswan/plugins/md5/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/md5/Makefile.in494
-rw-r--r--src/libstrongswan/plugins/md5/md5_hasher.c (renamed from src/libstrongswan/crypto/hashers/md5_hasher.c)35
-rw-r--r--src/libstrongswan/plugins/md5/md5_hasher.h (renamed from src/libstrongswan/crypto/hashers/md5_hasher.h)36
-rw-r--r--src/libstrongswan/plugins/md5/md5_plugin.c60
-rw-r--r--src/libstrongswan/plugins/md5/md5_plugin.h47
-rw-r--r--src/libstrongswan/plugins/mysql/Makefile.am12
-rw-r--r--src/libstrongswan/plugins/mysql/Makefile.in497
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_database.c695
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_database.h58
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_plugin.c69
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_plugin.h47
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.am21
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.in518
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.c258
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.h51
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c242
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h50
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c342
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h50
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.c445
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.h49
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.c447
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.h49
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.c185
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.h (renamed from src/libstrongswan/crypto/hashers/sha1_hasher.h)50
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c164
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.h49
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c422
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h49
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c433
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h49
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_util.c120
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_util.h70
-rw-r--r--src/libstrongswan/plugins/padlock/Makefile.am12
-rw-r--r--src/libstrongswan/plugins/padlock/Makefile.in500
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_aes_crypter.c201
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_aes_crypter.h50
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_plugin.c64
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_plugin.h47
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c177
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h48
-rw-r--r--src/libstrongswan/plugins/plugin.h49
-rw-r--r--src/libstrongswan/plugins/plugin_loader.c193
-rw-r--r--src/libstrongswan/plugins/plugin_loader.h67
-rw-r--r--src/libstrongswan/plugins/pubkey/Makefile.am13
-rw-r--r--src/libstrongswan/plugins/pubkey/Makefile.in500
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_cert.c284
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_cert.h51
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_plugin.c65
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_plugin.h47
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_public_key.c185
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_public_key.h36
-rw-r--r--src/libstrongswan/plugins/random/Makefile.am11
-rw-r--r--src/libstrongswan/plugins/random/Makefile.in497
-rw-r--r--src/libstrongswan/plugins/random/random_plugin.c62
-rw-r--r--src/libstrongswan/plugins/random/random_plugin.h47
-rw-r--r--src/libstrongswan/plugins/random/random_rng.c134
-rw-r--r--src/libstrongswan/plugins/random/random_rng.h49
-rw-r--r--src/libstrongswan/plugins/sha1/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/sha1/Makefile.in494
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_hasher.c (renamed from src/libstrongswan/crypto/hashers/sha1_hasher.c)182
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_hasher.h69
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_plugin.c64
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_plugin.h47
-rw-r--r--src/libstrongswan/plugins/sha2/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/sha2/Makefile.in494
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_hasher.c (renamed from src/libstrongswan/crypto/hashers/sha2_hasher.c)44
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_hasher.h (renamed from src/libstrongswan/crypto/hashers/sha2_hasher.h)32
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_plugin.c64
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_plugin.h47
-rw-r--r--src/libstrongswan/plugins/sqlite/Makefile.am12
-rw-r--r--src/libstrongswan/plugins/sqlite/Makefile.in499
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_database.c321
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_database.h46
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_plugin.c60
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_plugin.h47
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.am16
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.in508
-rw-r--r--src/libstrongswan/plugins/x509/ietf_attr_list.c (renamed from src/libstrongswan/crypto/ietf_attr_list.c)37
-rw-r--r--src/libstrongswan/plugins/x509/ietf_attr_list.h (renamed from src/libstrongswan/crypto/ietf_attr_list.h)28
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.c1140
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.h59
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c1295
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.h49
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.c742
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.h48
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_request.c612
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_request.h54
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_response.c990
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_response.h47
-rw-r--r--src/libstrongswan/plugins/x509/x509_plugin.c80
-rw-r--r--src/libstrongswan/plugins/x509/x509_plugin.h47
-rw-r--r--src/libstrongswan/plugins/xcbc/Makefile.am11
-rw-r--r--src/libstrongswan/plugins/xcbc/Makefile.in499
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc.c299
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc.h78
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_plugin.c65
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_plugin.h47
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_prf.c131
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_prf.h50
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_signer.c177
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_signer.h47
-rw-r--r--src/libstrongswan/printf_hook.c132
-rw-r--r--src/libstrongswan/printf_hook.h89
-rw-r--r--src/libstrongswan/settings.c411
-rw-r--r--src/libstrongswan/settings.h96
-rw-r--r--src/libstrongswan/utils.c342
-rw-r--r--src/libstrongswan/utils.h275
-rw-r--r--src/libstrongswan/utils/enumerator.c364
-rw-r--r--src/libstrongswan/utils/enumerator.h118
-rw-r--r--src/libstrongswan/utils/fetcher.c424
-rw-r--r--src/libstrongswan/utils/fetcher.h95
-rw-r--r--src/libstrongswan/utils/host.c156
-rw-r--r--src/libstrongswan/utils/host.h150
-rw-r--r--src/libstrongswan/utils/identification.c376
-rw-r--r--src/libstrongswan/utils/identification.h142
-rw-r--r--src/libstrongswan/utils/iterator.h95
-rw-r--r--src/libstrongswan/utils/leak_detective.c418
-rw-r--r--src/libstrongswan/utils/leak_detective.h42
-rw-r--r--src/libstrongswan/utils/lexparser.c19
-rw-r--r--src/libstrongswan/utils/lexparser.h39
-rw-r--r--src/libstrongswan/utils/linked_list.c253
-rw-r--r--src/libstrongswan/utils/linked_list.h201
-rw-r--r--src/libstrongswan/utils/mutex.c267
-rw-r--r--src/libstrongswan/utils/mutex.h123
-rw-r--r--src/libstrongswan/utils/optionsfrom.c10
-rw-r--r--src/libstrongswan/utils/optionsfrom.h38
-rw-r--r--src/libstrongswan/utils/randomizer.c165
-rw-r--r--src/libstrongswan/utils/randomizer.h114
-rw-r--r--src/manager/Makefile.am60
-rw-r--r--src/manager/Makefile.in488
-rw-r--r--src/manager/controller/auth_controller.c9
-rw-r--r--src/manager/controller/auth_controller.h20
-rw-r--r--src/manager/controller/config_controller.c9
-rw-r--r--src/manager/controller/config_controller.h20
-rw-r--r--src/manager/controller/control_controller.c9
-rw-r--r--src/manager/controller/control_controller.h18
-rw-r--r--src/manager/controller/gateway_controller.c9
-rw-r--r--src/manager/controller/gateway_controller.h20
-rw-r--r--src/manager/controller/ikesa_controller.c9
-rw-r--r--src/manager/controller/ikesa_controller.h20
-rw-r--r--src/manager/database.c183
-rw-r--r--src/manager/gateway.c11
-rw-r--r--src/manager/gateway.h34
-rw-r--r--src/manager/lib/dispatcher.h95
-rw-r--r--src/manager/main.c55
-rw-r--r--src/manager/manager.c23
-rw-r--r--src/manager/manager.dbbin12288 -> 0 bytes
-rw-r--r--src/manager/manager.h39
-rw-r--r--src/manager/storage.c129
-rw-r--r--src/manager/storage.h (renamed from src/manager/database.h)44
-rw-r--r--src/manager/templates/header.cs6
-rw-r--r--src/manager/xml.c (renamed from src/manager/lib/xml.c)9
-rw-r--r--src/manager/xml.h (renamed from src/manager/lib/xml.h)24
-rw-r--r--src/medsrv/Makefile.am42
-rw-r--r--src/medsrv/Makefile.in667
-rwxr-xr-xsrc/medsrv/controller/peer_controller.c377
-rwxr-xr-xsrc/medsrv/controller/peer_controller.h50
-rwxr-xr-xsrc/medsrv/controller/user_controller.c363
-rwxr-xr-xsrc/medsrv/controller/user_controller.h50
-rwxr-xr-xsrc/medsrv/filter/auth_filter.c100
-rwxr-xr-xsrc/medsrv/filter/auth_filter.h50
-rw-r--r--src/medsrv/main.c78
-rwxr-xr-xsrc/medsrv/templates/footer.cs4
-rwxr-xr-xsrc/medsrv/templates/header.cs31
-rwxr-xr-xsrc/medsrv/templates/peer/add.cs24
-rwxr-xr-xsrc/medsrv/templates/peer/edit.cs25
-rwxr-xr-xsrc/medsrv/templates/peer/list.cs28
-rwxr-xr-xsrc/medsrv/templates/static/favicon.icobin0 -> 894 bytes
-rw-r--r--src/medsrv/templates/static/mootools.js341
-rw-r--r--src/medsrv/templates/static/script.js13
-rwxr-xr-xsrc/medsrv/templates/static/strongswan.pngbin0 -> 19837 bytes
-rwxr-xr-xsrc/medsrv/templates/static/style.css132
-rwxr-xr-xsrc/medsrv/templates/user/add.cs28
-rwxr-xr-xsrc/medsrv/templates/user/edit.cs35
-rw-r--r--src/medsrv/templates/user/help.cs34
-rwxr-xr-xsrc/medsrv/templates/user/login.cs23
-rw-r--r--src/medsrv/user.c77
-rw-r--r--src/medsrv/user.h52
-rw-r--r--src/openac/Makefile.am8
-rw-r--r--src/openac/Makefile.in49
-rw-r--r--src/openac/build.c193
-rw-r--r--src/openac/build.h45
-rwxr-xr-xsrc/openac/openac.c163
-rw-r--r--src/pluto/Makefile.am11
-rw-r--r--src/pluto/Makefile.in51
-rw-r--r--src/pluto/ac.c12
-rw-r--r--src/pluto/alg/ike_alg_aes.c2
-rw-r--r--src/pluto/alg_info.c12
-rw-r--r--src/pluto/connections.c6
-rw-r--r--src/pluto/connections.h4
-rw-r--r--src/pluto/constants.c22
-rw-r--r--src/pluto/constants.h5
-rw-r--r--src/pluto/crl.c4
-rw-r--r--src/pluto/demux.c4
-rw-r--r--src/pluto/fetch.c4
-rw-r--r--src/pluto/ike_alg.c5
-rw-r--r--src/pluto/ipsec_doi.c13
-rw-r--r--src/pluto/kernel.c22
-rw-r--r--src/pluto/kernel_netlink.c31
-rw-r--r--src/pluto/keys.c10
-rw-r--r--src/pluto/log.c32
-rw-r--r--src/pluto/modecfg.c13
-rw-r--r--src/pluto/plutomain.c40
-rw-r--r--src/pluto/smartcard.c10
-rw-r--r--src/pluto/spdb.c16
-rw-r--r--src/pluto/vendor.c9
-rw-r--r--src/pluto/vendor.h26
-rw-r--r--src/pluto/xauth.c4
-rw-r--r--src/pluto/xauth.h13
-rw-r--r--src/scepclient/Makefile.am12
-rw-r--r--src/scepclient/Makefile.in50
-rw-r--r--src/scepclient/scep.c2
-rw-r--r--src/starter/Makefile.am16
-rw-r--r--src/starter/Makefile.in52
-rw-r--r--src/starter/args.c27
-rw-r--r--src/starter/cmp.c8
-rw-r--r--src/starter/confread.c156
-rw-r--r--src/starter/confread.h21
-rw-r--r--src/starter/invokecharon.c58
-rw-r--r--src/starter/invokepluto.c58
-rw-r--r--src/starter/ipsec.conf.587
-rw-r--r--src/starter/keywords.c270
-rw-r--r--src/starter/keywords.h17
-rw-r--r--src/starter/keywords.txt13
-rw-r--r--src/starter/lex.yy.c94
-rw-r--r--src/starter/starter.c67
-rw-r--r--src/starter/starterstroke.c109
-rw-r--r--src/starter/starterstroke.h5
-rw-r--r--src/starter/starterwhack.c54
-rw-r--r--src/stroke/Makefile.am3
-rw-r--r--src/stroke/Makefile.in40
-rw-r--r--src/stroke/stroke.c54
-rw-r--r--src/stroke/stroke_keywords.c5
-rw-r--r--src/stroke/stroke_msg.h (renamed from src/stroke/stroke.h)40
-rw-r--r--src/strongswan.conf25
-rw-r--r--src/whack/Makefile.in37
733 files changed, 74138 insertions, 31811 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index e01ad84b4..913099c23 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = include
+SUBDIRS = . include
if USE_FILE_CONFIG
SUBDIRS += libfreeswan starter ipsec _copyright
@@ -11,6 +11,7 @@ endif
if USE_PLUTO
SUBDIRS += libcrypto pluto whack
endif
+
if USE_CHARON
SUBDIRS += charon
endif
@@ -19,32 +20,32 @@ if USE_STROKE
SUBDIRS += stroke
endif
-if USE_PLUTO_OR_CHARON
+if USE_UPDOWN
SUBDIRS += _updown _updown_espmark
endif
if USE_TOOLS
- SUBDIRS += openac scepclient
+ SUBDIRS += libcrypto openac scepclient
endif
-if USE_UML
+if USE_DUMM
SUBDIRS += dumm
endif
+if USE_FAST
+ SUBDIRS += libfast
+endif
+
if USE_MANAGER
SUBDIRS += manager
endif
-if USE_FILE_CONFIG
-install-exec-local :
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/cacerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/ocspcerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/certs
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/acerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/aacerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/crls
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/reqs
- mkdir -p -m 700 $(DESTDIR)$(confdir)/ipsec.d/private
+if USE_MEDSRV
+ SUBDIRS += medsrv
endif
+EXTRA_DIST = strongswan.conf
+
+install-exec-local :
+ test -e "$(DESTDIR)${sysconfdir}" || $(INSTALL) -d "$(DESTDIR)$(sysconfdir)"
+ test -e "$(DESTDIR)$(sysconfdir)/strongswan.conf" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -m 640 strongswan.conf $(DESTDIR)$(sysconfdir)/strongswan.conf || true
diff --git a/src/Makefile.in b/src/Makefile.in
index 17fc6f746..5b970f87a 100644
--- a/src/Makefile.in
+++ b/src/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.
@@ -36,10 +36,12 @@ host_triplet = @host@
@USE_PLUTO_TRUE@am__append_3 = libcrypto pluto whack
@USE_CHARON_TRUE@am__append_4 = charon
@USE_STROKE_TRUE@am__append_5 = stroke
-@USE_PLUTO_OR_CHARON_TRUE@am__append_6 = _updown _updown_espmark
-@USE_TOOLS_TRUE@am__append_7 = openac scepclient
-@USE_UML_TRUE@am__append_8 = dumm
-@USE_MANAGER_TRUE@am__append_9 = manager
+@USE_UPDOWN_TRUE@am__append_6 = _updown _updown_espmark
+@USE_TOOLS_TRUE@am__append_7 = libcrypto openac scepclient
+@USE_DUMM_TRUE@am__append_8 = dumm
+@USE_FAST_TRUE@am__append_9 = libfast
+@USE_MANAGER_TRUE@am__append_10 = manager
+@USE_MEDSRV_TRUE@am__append_11 = medsrv
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -61,9 +63,9 @@ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = include libfreeswan starter ipsec _copyright \
+DIST_SUBDIRS = . include libfreeswan starter ipsec _copyright \
libstrongswan libcrypto pluto whack charon stroke _updown \
- _updown_espmark openac scepclient dumm manager
+ _updown_espmark openac scepclient dumm libfast manager medsrv
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -84,6 +86,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -113,6 +116,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -143,7 +147,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@
@@ -154,12 +157,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@
@@ -169,12 +171,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@
@@ -187,19 +189,23 @@ 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@
-SUBDIRS = include $(am__append_1) $(am__append_2) $(am__append_3) \
+SUBDIRS = . include $(am__append_1) $(am__append_2) $(am__append_3) \
$(am__append_4) $(am__append_5) $(am__append_6) \
- $(am__append_7) $(am__append_8) $(am__append_9)
+ $(am__append_7) $(am__append_8) $(am__append_9) \
+ $(am__append_10) $(am__append_11)
+EXTRA_DIST = strongswan.conf
all: all-recursive
.SUFFIXES:
@@ -314,8 +320,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -340,8 +346,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -351,13 +357,12 @@ ctags: CTAGS
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
@@ -442,7 +447,6 @@ 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."
-@USE_FILE_CONFIG_FALSE@install-exec-local:
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
@@ -515,16 +519,9 @@ uninstall-am:
ps ps-am tags tags-recursive uninstall uninstall-am
-@USE_FILE_CONFIG_TRUE@install-exec-local :
-@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d
-@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/cacerts
-@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/ocspcerts
-@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/certs
-@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/acerts
-@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/aacerts
-@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/crls
-@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/reqs
-@USE_FILE_CONFIG_TRUE@ mkdir -p -m 700 $(DESTDIR)$(confdir)/ipsec.d/private
+install-exec-local :
+ test -e "$(DESTDIR)${sysconfdir}" || $(INSTALL) -d "$(DESTDIR)$(sysconfdir)"
+ test -e "$(DESTDIR)$(sysconfdir)/strongswan.conf" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -m 640 strongswan.conf $(DESTDIR)$(sysconfdir)/strongswan.conf || true
# 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/_copyright/Makefile.in b/src/_copyright/Makefile.in
index 84ac628e6..342dc48ed 100644
--- a/src/_copyright/Makefile.in
+++ b/src/_copyright/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.
@@ -87,6 +87,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -116,6 +117,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -146,7 +148,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@
@@ -157,12 +158,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@
@@ -172,12 +172,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@
@@ -190,10 +190,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@
@@ -246,8 +248,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
@@ -354,8 +356,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -367,8 +369,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -378,13 +380,12 @@ ctags: CTAGS
CTAGS: $(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
diff --git a/src/_updown/Makefile.in b/src/_updown/Makefile.in
index 4579ace58..8173de597 100644
--- a/src/_updown/Makefile.in
+++ b/src/_updown/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.
@@ -69,6 +69,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -98,6 +99,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -128,7 +130,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@
@@ -139,12 +140,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@
@@ -154,12 +154,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@
@@ -172,10 +172,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@
diff --git a/src/_updown_espmark/Makefile.in b/src/_updown_espmark/Makefile.in
index c205632dd..00555c6b3 100644
--- a/src/_updown_espmark/Makefile.in
+++ b/src/_updown_espmark/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.
@@ -69,6 +69,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -98,6 +99,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -128,7 +130,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@
@@ -139,12 +140,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@
@@ -154,12 +154,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@
@@ -172,10 +172,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@
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_ @} */
diff --git a/src/dumm/Makefile.am b/src/dumm/Makefile.am
index 3356e7a57..1e47e8907 100644
--- a/src/dumm/Makefile.am
+++ b/src/dumm/Makefile.am
@@ -1,12 +1,14 @@
lib_LTLIBRARIES = libdumm.la
-ipsec_PROGRAMS = dumm
+ipsec_PROGRAMS = dumm testing
-libdumm_la_SOURCES = dumm.c dumm.h guest.c guest.h iface.c iface.h bridge.c bridge.h mconsole.c mconsole.h cowfs.h cowfs.c
+libdumm_la_SOURCES = dumm.c dumm.h guest.c guest.h iface.c iface.h \
+ bridge.c bridge.h mconsole.c mconsole.h cowfs.h cowfs.c
dumm_SOURCES = main.c
+testing_SOURCES = testing.c
-libdumm_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lbridge -lfuse -lutil ${xml_LIBS}
-dumm_LDADD = -ldumm -lreadline
-
-INCLUDES = -I$(top_srcdir)/src/libstrongswan ${xml_CFLAGS}
+libdumm_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lbridge -lfuse -lutil
+dumm_LDADD = -ldumm ${gtk_LIBS}
+testing_LDADD = -ldumm
+INCLUDES = -I$(top_srcdir)/src/libstrongswan ${gtk_CFLAGS}
AM_CFLAGS = -D_FILE_OFFSET_BITS=64
diff --git a/src/dumm/Makefile.in b/src/dumm/Makefile.in
index 3431641d5..7dc53b8c0 100644
--- a/src/dumm/Makefile.in
+++ b/src/dumm/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.
@@ -33,7 +33,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-ipsec_PROGRAMS = dumm$(EXEEXT)
+ipsec_PROGRAMS = dumm$(EXEEXT) testing$(EXEEXT)
subdir = src/dumm
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -51,10 +51,8 @@ am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(ipsecdir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
-am__DEPENDENCIES_1 =
libdumm_la_DEPENDENCIES = \
- $(top_builddir)/src/libstrongswan/libstrongswan.la \
- $(am__DEPENDENCIES_1)
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
am_libdumm_la_OBJECTS = dumm.lo guest.lo iface.lo bridge.lo \
mconsole.lo cowfs.lo
libdumm_la_OBJECTS = $(am_libdumm_la_OBJECTS)
@@ -62,7 +60,11 @@ ipsecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(ipsec_PROGRAMS)
am_dumm_OBJECTS = main.$(OBJEXT)
dumm_OBJECTS = $(am_dumm_OBJECTS)
-dumm_DEPENDENCIES =
+am__DEPENDENCIES_1 =
+dumm_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_testing_OBJECTS = testing.$(OBJEXT)
+testing_OBJECTS = $(am_testing_OBJECTS)
+testing_DEPENDENCIES =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -75,8 +77,9 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libdumm_la_SOURCES) $(dumm_SOURCES)
-DIST_SOURCES = $(libdumm_la_SOURCES) $(dumm_SOURCES)
+SOURCES = $(libdumm_la_SOURCES) $(dumm_SOURCES) $(testing_SOURCES)
+DIST_SOURCES = $(libdumm_la_SOURCES) $(dumm_SOURCES) \
+ $(testing_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -99,6 +102,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -128,6 +132,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -158,7 +163,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@
@@ -169,12 +173,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@
@@ -184,12 +187,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@
@@ -202,10 +205,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@
@@ -213,11 +218,15 @@ top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
lib_LTLIBRARIES = libdumm.la
-libdumm_la_SOURCES = dumm.c dumm.h guest.c guest.h iface.c iface.h bridge.c bridge.h mconsole.c mconsole.h cowfs.h cowfs.c
+libdumm_la_SOURCES = dumm.c dumm.h guest.c guest.h iface.c iface.h \
+ bridge.c bridge.h mconsole.c mconsole.h cowfs.h cowfs.c
+
dumm_SOURCES = main.c
-libdumm_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lbridge -lfuse -lutil ${xml_LIBS}
-dumm_LDADD = -ldumm -lreadline
-INCLUDES = -I$(top_srcdir)/src/libstrongswan ${xml_CFLAGS}
+testing_SOURCES = testing.c
+libdumm_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lbridge -lfuse -lutil
+dumm_LDADD = -ldumm ${gtk_LIBS}
+testing_LDADD = -ldumm
+INCLUDES = -I$(top_srcdir)/src/libstrongswan ${gtk_CFLAGS}
AM_CFLAGS = -D_FILE_OFFSET_BITS=64
all: all-am
@@ -258,8 +267,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
@@ -267,8 +276,8 @@ uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
- $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
clean-libLTLIBRARIES:
@@ -290,8 +299,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
@@ -312,6 +321,9 @@ clean-ipsecPROGRAMS:
dumm$(EXEEXT): $(dumm_OBJECTS) $(dumm_DEPENDENCIES)
@rm -f dumm$(EXEEXT)
$(LINK) $(dumm_OBJECTS) $(dumm_LDADD) $(LIBS)
+testing$(EXEEXT): $(testing_OBJECTS) $(testing_DEPENDENCIES)
+ @rm -f testing$(EXEEXT)
+ $(LINK) $(testing_OBJECTS) $(testing_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -326,6 +338,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mconsole.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testing.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -359,8 +372,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -372,8 +385,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -383,13 +396,12 @@ ctags: CTAGS
CTAGS: $(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
diff --git a/src/dumm/bridge.c b/src/dumm/bridge.c
index c6068e60c..cb8017c78 100644
--- a/src/dumm/bridge.c
+++ b/src/dumm/bridge.c
@@ -31,6 +31,11 @@ struct private_bridge_t {
/** list of attached interfaces */
linked_list_t *ifaces;
};
+
+/**
+ * defined in iface.c
+ */
+bool iface_control(char *name, bool up);
/**
* Implementation of bridge_t.get_name.
@@ -41,11 +46,11 @@ static char* get_name(private_bridge_t *this)
}
/**
- * Implementation of bridge_t.create_iface_iterator.
+ * Implementation of bridge_t.create_iface_enumerator.
*/
-static iterator_t* create_iface_iterator(private_bridge_t *this)
+static enumerator_t* create_iface_enumerator(private_bridge_t *this)
{
- return this->ifaces->create_iterator(this->ifaces, TRUE);
+ return this->ifaces->create_enumerator(this->ifaces);
}
/**
@@ -53,12 +58,12 @@ static iterator_t* create_iface_iterator(private_bridge_t *this)
*/
static bool disconnect_iface(private_bridge_t *this, iface_t *iface)
{
- iterator_t *iterator;
- iface_t *current;
+ enumerator_t *enumerator;
+ iface_t *current = NULL;
bool good = FALSE;
- iterator = this->ifaces->create_iterator(this->ifaces, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = this->ifaces->create_enumerator(this->ifaces);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
if (current == iface)
{
@@ -70,6 +75,7 @@ static bool disconnect_iface(private_bridge_t *this, iface_t *iface)
else
{
iface->set_bridge(iface, NULL);
+ this->ifaces->remove_at(this->ifaces, enumerator);
good = TRUE;
}
break;
@@ -80,7 +86,7 @@ static bool disconnect_iface(private_bridge_t *this, iface_t *iface)
DBG1("iface '%s' not found on bridge '%s'", iface->get_hostif(iface),
this->name);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return good;
}
@@ -118,8 +124,9 @@ static void unregister(iface_t *iface)
*/
static void destroy(private_bridge_t *this)
{
- this->ifaces->invoke_function(this->ifaces, (void(*)(void*))unregister);
+ this->ifaces->invoke_function(this->ifaces, (linked_list_invoke_t)unregister);
this->ifaces->destroy(this->ifaces);
+ iface_control(this->name, FALSE);
if (br_del_bridge(this->name) != 0)
{
DBG1("deleting bridge '%s' from kernel failed: %m", this->name);
@@ -150,7 +157,7 @@ bridge_t *bridge_create(char *name)
this = malloc_thing(private_bridge_t);
this->public.get_name = (char*(*)(bridge_t*))get_name;
- this->public.create_iface_iterator = (iterator_t*(*)(bridge_t*))create_iface_iterator;
+ this->public.create_iface_enumerator = (enumerator_t*(*)(bridge_t*))create_iface_enumerator;
this->public.disconnect_iface = (bool(*)(bridge_t*, iface_t *iface))disconnect_iface;
this->public.connect_iface = (bool(*)(bridge_t*, iface_t *iface))connect_iface;
this->public.destroy = (void*)destroy;
@@ -161,6 +168,10 @@ bridge_t *bridge_create(char *name)
free(this);
return NULL;
}
+ if (!iface_control(name, TRUE))
+ {
+ DBG1("bringing bridge '%s' up failed: %m", name);
+ }
this->name = strdup(name);
this->ifaces = linked_list_create();
diff --git a/src/dumm/bridge.h b/src/dumm/bridge.h
index 6d28ed376..79a0a3a72 100644
--- a/src/dumm/bridge.h
+++ b/src/dumm/bridge.h
@@ -17,7 +17,7 @@
#define BRIDGE_H
#include <library.h>
-#include <utils/iterator.h>
+#include <utils/enumerator.h>
typedef struct bridge_t bridge_t;
@@ -31,32 +31,32 @@ struct bridge_t {
/**
* @brief Get the name of the bridge.
*
- * @return name of the bridge
+ * @return name of the bridge
*/
char* (*get_name)(bridge_t *this);
/**
* @brief Add an interface to a bridge.
*
- * @param iface interface to add
- * @return TRUE if interface added
+ * @param iface interface to add
+ * @return TRUE if interface added
*/
bool (*connect_iface)(bridge_t *this, iface_t *iface);
/**
* @brief Remove an interface from a bridge.
*
- * @param iface interface to remove
- * @return TRUE if interface removed
+ * @param iface interface to remove
+ * @return TRUE if interface removed
*/
bool (*disconnect_iface)(bridge_t *this, iface_t *iface);
/**
- * @brief Create an iterator over all interfaces.
+ * @brief Create an enumerator over all interfaces.
*
- * @return iterator over iface_t's
+ * @return enumerator over iface_t's
*/
- iterator_t* (*create_iface_iterator)(bridge_t *this);
+ enumerator_t* (*create_iface_enumerator)(bridge_t *this);
/**
* @brief Destroy a bridge
diff --git a/src/dumm/dumm.c b/src/dumm/dumm.c
index b9a2814e6..5db8eaee0 100644
--- a/src/dumm/dumm.c
+++ b/src/dumm/dumm.c
@@ -23,6 +23,7 @@
#include <errno.h>
#include <debug.h>
+#include <utils/linked_list.h>
#include "dumm.h"
@@ -31,11 +32,6 @@
#define TEMPLATE_DIR "templates"
#define TEMPLATE_DIR_DIR "diff"
-/**
- * instances of dumm, used to deliver signals
- */
-static linked_list_t *instances = NULL;
-
typedef struct private_dumm_t private_dumm_t;
struct private_dumm_t {
@@ -74,11 +70,31 @@ static guest_t* create_guest(private_dumm_t *this, char *name, char *kernel,
}
/**
- * Implementation of dumm_t.create_guest_iterator.
+ * Implementation of dumm_t.create_guest_enumerator.
+ */
+static enumerator_t* create_guest_enumerator(private_dumm_t *this)
+{
+ return this->guests->create_enumerator(this->guests);
+}
+
+/**
+ * Implementation of dumm_t.delete_guest.
*/
-static iterator_t* create_guest_iterator(private_dumm_t *this)
+static void delete_guest(private_dumm_t *this, guest_t *guest)
{
- return this->guests->create_iterator(this->guests, TRUE);
+ if (this->guests->remove(this->guests, guest, NULL))
+ {
+ char buf[512];
+ int len;
+
+ len = snprintf(buf, sizeof(buf), "rm -Rf %s/%s",
+ this->guest_dir, guest->get_name(guest));
+ guest->destroy(guest);
+ if (len > 8 && len < 512)
+ {
+ system(buf);
+ }
+ }
}
/**
@@ -97,11 +113,22 @@ static bridge_t* create_bridge(private_dumm_t *this, char *name)
}
/**
- * Implementation of dumm_t.create_bridge_iterator.
+ * Implementation of dumm_t.create_bridge_enumerator.
+ */
+static enumerator_t* create_bridge_enumerator(private_dumm_t *this)
+{
+ return this->bridges->create_enumerator(this->bridges);
+}
+
+/**
+ * Implementation of dumm_t.delete_bridge.
*/
-static iterator_t* create_bridge_iterator(private_dumm_t *this)
+static void delete_bridge(private_dumm_t *this, bridge_t *bridge)
{
- return this->bridges->create_iterator(this->bridges, TRUE);
+ if (this->bridges->remove(this->bridges, bridge, NULL))
+ {
+ bridge->destroy(bridge);
+ }
}
/**
@@ -109,26 +136,18 @@ static iterator_t* create_bridge_iterator(private_dumm_t *this)
*/
static void clear_template(private_dumm_t *this)
{
- iterator_t *iterator, *ifaces;
+ enumerator_t *enumerator;
guest_t *guest;
- iface_t *iface;
free(this->template);
this->template = NULL;
- iterator = this->guests->create_iterator(this->guests, TRUE);
- while (iterator->iterate(iterator, (void**)&guest))
+ enumerator = this->guests->create_enumerator(this->guests);
+ while (enumerator->enumerate(enumerator, (void**)&guest))
{
guest->load_template(guest, NULL);
- ifaces = guest->create_iface_iterator(guest);
- while (ifaces->iterate(ifaces, (void**)&iface))
- {
- ifaces->remove(ifaces);
- iface->destroy(iface);
- }
- ifaces->destroy(ifaces);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -136,7 +155,7 @@ static void clear_template(private_dumm_t *this)
*/
static bool load_template(private_dumm_t *this, char *name)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
guest_t *guest;
char dir[PATH_MAX];
size_t len;
@@ -169,131 +188,36 @@ static bool load_template(private_dumm_t *this, char *name)
return FALSE;
}
}
- iterator = this->guests->create_iterator(this->guests, TRUE);
- while (iterator->iterate(iterator, (void**)&guest))
+ enumerator = this->guests->create_enumerator(this->guests);
+ while (enumerator->enumerate(enumerator, (void**)&guest))
{
if (!guest->load_template(guest, dir))
{
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
clear_template(this);
return FALSE;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return TRUE;
}
/**
- * signal handler
- */
-void signal_handler(int sig, siginfo_t *info, void *ucontext)
-{
- if (sig == SIGCHLD)
- {
- switch (info->si_code)
- {
- case CLD_EXITED:
- case CLD_KILLED:
- case CLD_DUMPED:
- {
- private_dumm_t *this;
- guest_t *guest;
- iterator_t *iterator, *guests;
-
- iterator = instances->create_iterator(instances, TRUE);
- while (iterator->iterate(iterator, (void**)&this))
- {
- if (this->destroying)
- {
- continue;
- }
- guests = this->guests->create_iterator(this->guests, TRUE);
- while (guests->iterate(guests, (void**)&guest))
- {
- if (guest->get_pid(guest) == info->si_pid)
- {
- guest->sigchild(guest);
- break;
- }
- }
- guests->destroy(guests);
- }
- iterator->destroy(iterator);
- break;
- }
- default:
- break;
- }
-
- }
- /* SIGHUP is currently just ignored */
-}
-
-/**
- * add a dumm instance
- */
-static void add_instance(private_dumm_t *this)
-{
- if (instances == NULL)
- {
- struct sigaction action;
-
- instances = linked_list_create();
-
- memset(&action, 0, sizeof(action));
- action.sa_sigaction = signal_handler;
- action.sa_flags = SA_SIGINFO;
-
- if (sigaction(SIGCHLD, &action, NULL) != 0 ||
- sigaction(SIGHUP, &action, NULL) != 0)
- {
- DBG1("installing signal handler failed!");
- }
- }
- instances->insert_last(instances, this);
-}
-
-/**
- * remove a dumm instance
- */
-static void remove_instance(private_dumm_t *this)
-{
- iterator_t *iterator;
- private_dumm_t *current;
-
- iterator = instances->create_iterator(instances, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
- {
- if (current == this)
- {
- iterator->remove(iterator);
- break;
- }
- }
- iterator->destroy(iterator);
- if (instances->get_count(instances) == 0)
- {
- instances->destroy(instances);
- instances = NULL;
- }
-}
-
-/**
* Implementation of dumm_t.destroy
*/
static void destroy(private_dumm_t *this)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
guest_t *guest;
this->bridges->destroy_offset(this->bridges, offsetof(bridge_t, destroy));
- iterator = this->guests->create_iterator(this->guests, TRUE);
- while (iterator->iterate(iterator, (void**)&guest))
+ enumerator = this->guests->create_enumerator(this->guests);
+ while (enumerator->enumerate(enumerator, (void**)&guest))
{
- guest->stop(guest);
+ guest->stop(guest, NULL);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
this->destroying = TRUE;
this->guests->destroy_offset(this->guests, offsetof(guest_t, destroy));
@@ -301,7 +225,6 @@ static void destroy(private_dumm_t *this)
free(this->template_dir);
free(this->template);
free(this->dir);
- remove_instance(this);
free(this);
}
@@ -329,7 +252,6 @@ static void load_guests(private_dumm_t *this)
guest = guest_load(this->guest_dir, ent->d_name);
if (guest)
{
- DBG1("loaded guest '%s'", ent->d_name);
this->guests->insert_last(this->guests, guest);
}
else
@@ -349,20 +271,35 @@ dumm_t *dumm_create(char *dir)
private_dumm_t *this = malloc_thing(private_dumm_t);
this->public.create_guest = (guest_t*(*)(dumm_t*,char*,char*,char*,int))create_guest;
- this->public.create_guest_iterator = (iterator_t*(*)(dumm_t*))create_guest_iterator;
+ this->public.create_guest_enumerator = (enumerator_t*(*)(dumm_t*))create_guest_enumerator;
+ this->public.delete_guest = (void(*)(dumm_t*,guest_t*))delete_guest;
this->public.create_bridge = (bridge_t*(*)(dumm_t*, char *name))create_bridge;
- this->public.create_bridge_iterator = (iterator_t*(*)(dumm_t*))create_bridge_iterator;
+ this->public.create_bridge_enumerator = (enumerator_t*(*)(dumm_t*))create_bridge_enumerator;
+ this->public.delete_bridge = (void(*)(dumm_t*,bridge_t*))delete_bridge;
this->public.load_template = (bool(*)(dumm_t*, char *name))load_template;
this->public.destroy = (void(*)(dumm_t*))destroy;
this->destroying = FALSE;
- if (*dir == '/' || getcwd(cwd, sizeof(cwd)) == 0)
+
+ if (dir && *dir == '/')
{
this->dir = strdup(dir);
}
else
{
- asprintf(&this->dir, "%s/%s", cwd, dir);
+ if (getcwd(cwd, sizeof(cwd)) == NULL)
+ {
+ free(this);
+ return NULL;
+ }
+ if (dir)
+ {
+ asprintf(&this->dir, "%s/%s", cwd, dir);
+ }
+ else
+ {
+ this->dir = strdup(cwd);
+ }
}
this->template = NULL;
asprintf(&this->guest_dir, "%s/%s", this->dir, GUEST_DIR);
@@ -370,8 +307,6 @@ dumm_t *dumm_create(char *dir)
this->guests = linked_list_create();
this->bridges = linked_list_create();
- add_instance(this);
-
if (mkdir(this->guest_dir, PERME) < 0 && errno != EEXIST)
{
DBG1("creating guest directory '%s' failed: %m", this->guest_dir);
diff --git a/src/dumm/dumm.h b/src/dumm/dumm.h
index 5414f9993..6abf4fc92 100644
--- a/src/dumm/dumm.h
+++ b/src/dumm/dumm.h
@@ -19,7 +19,7 @@
#include <signal.h>
#include <library.h>
-#include <utils/linked_list.h>
+#include <utils/enumerator.h>
#include "guest.h"
#include "bridge.h"
@@ -30,8 +30,6 @@ typedef struct dumm_t dumm_t;
* @brief dumm - Dynamic Uml Mesh Modeler
*
* Controls a group of UML guests and their networks.
- * Dumm catches SIGCHD and SIGHUP to trace UML child processes and the FUSE
- * filesystem. Do not overwrite these signal handlers!
*/
struct dumm_t {
@@ -48,11 +46,18 @@ struct dumm_t {
char *master, int mem);
/**
- * @brief Create an iterator over all guests.
+ * @brief Create an enumerator over all guests.
*
- * @return iteraotor over guest_t's
+ * @return enumerator over guest_t's
*/
- iterator_t* (*create_guest_iterator) (dumm_t *this);
+ enumerator_t* (*create_guest_enumerator) (dumm_t *this);
+
+ /**
+ * @brief Delete a guest from disk.
+ *
+ * @param guest guest to destroy
+ */
+ void (*delete_guest) (dumm_t *this, guest_t *guest);
/**
* @brief Create a new bridge.
@@ -63,11 +68,18 @@ struct dumm_t {
bridge_t* (*create_bridge)(dumm_t *this, char *name);
/**
- * @brief Create an iterator over all bridges.
+ * @brief Create an enumerator over all bridges.
+ *
+ * @return enumerator over bridge_t's
+ */
+ enumerator_t* (*create_bridge_enumerator)(dumm_t *this);
+
+ /**
+ * @brief Delete a bridge.
*
- * @return iterator over bridge_t's
+ * @param bridge bridge to destroy
*/
- iterator_t* (*create_bridge_iterator)(dumm_t *this);
+ void (*delete_bridge) (dumm_t *this, bridge_t *bridge);
/**
* @brief Loads a template, create a new one if it does not exist.
@@ -86,7 +98,7 @@ struct dumm_t {
/**
* @brief Create a group of UML hosts and networks.
*
- * @param dir directory to create guests/load from
+ * @param dir directory to create guests/load from, NULL for cwd
* @return created UML group, or NULL if failed.
*/
dumm_t *dumm_create(char *dir);
diff --git a/src/dumm/guest.c b/src/dumm/guest.c
index bbb59f431..4b2652688 100644
--- a/src/dumm/guest.c
+++ b/src/dumm/guest.c
@@ -41,6 +41,7 @@
#define DIFF_DIR "diff"
#define UNION_DIR "union"
#define MEMORY_FILE "mem"
+#define PID_FILE "pid"
#define KERNEL_FILE "linux"
#define LOG_FILE "boot.log"
#define NOTIFY_FILE "notify"
@@ -63,8 +64,6 @@ struct private_guest_t {
int pid;
/** state of guest */
guest_state_t state;
- /** log file for console 0 */
- int bootlog;
/** FUSE cowfs instance */
cowfs_t *cowfs;
/** mconsole to control running UML */
@@ -94,7 +93,7 @@ static char* get_name(private_guest_t *this)
*/
static iface_t* create_iface(private_guest_t *this, char *name)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
iface_t *iface;
if (this->state != GUEST_RUNNING)
@@ -103,17 +102,17 @@ static iface_t* create_iface(private_guest_t *this, char *name)
return NULL;
}
- iterator = this->ifaces->create_iterator(this->ifaces, TRUE);
- while (iterator->iterate(iterator, (void**)&iface))
+ enumerator = this->ifaces->create_enumerator(this->ifaces);
+ while (enumerator->enumerate(enumerator, (void**)&iface))
{
if (streq(name, iface->get_guestif(iface)))
{
DBG1("guest '%s' already has an interface '%s'", this->name, name);
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return NULL;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
iface = iface_create(this->name, name, this->mconsole);
if (iface)
@@ -124,11 +123,32 @@ static iface_t* create_iface(private_guest_t *this, char *name)
}
/**
- * Implementation of guest_t.create_iface_iterator.
+ * Implementation of guest_t.destroy_iface.
*/
-static iterator_t* create_iface_iterator(private_guest_t *this)
+static void destroy_iface(private_guest_t *this, iface_t *iface)
{
- return this->ifaces->create_iterator(this->ifaces, TRUE);
+ enumerator_t *enumerator;
+ iface_t *current;
+
+ enumerator = this->ifaces->create_enumerator(this->ifaces);
+ while (enumerator->enumerate(enumerator, (void**)&current))
+ {
+ if (current == iface)
+ {
+ this->ifaces->remove_at(this->ifaces, enumerator);
+ current->destroy(current);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * Implementation of guest_t.create_iface_enumerator.
+ */
+static enumerator_t* create_iface_enumerator(private_guest_t *this)
+{
+ return this->ifaces->create_enumerator(this->ifaces);
}
/**
@@ -170,45 +190,62 @@ static char* write_arg(char **pos, size_t *left, char *format, ...)
}
/**
- * Implementation of get_t.close_console.
+ * Implementation of guest_t.stop.
*/
-static char* get_console(private_guest_t *this, int console)
+static void stop(private_guest_t *this, idle_function_t idle)
{
- if (this->state == GUEST_RUNNING)
+ if (this->state != GUEST_STOPPED)
{
- return this->mconsole->get_console_pts(this->mconsole, console);
+ this->state = GUEST_STOPPING;
+ this->ifaces->destroy_offset(this->ifaces, offsetof(iface_t, destroy));
+ this->ifaces = linked_list_create();
+ kill(this->pid, SIGINT);
+ while (this->state != GUEST_STOPPED)
+ {
+ if (idle)
+ {
+ idle();
+ }
+ else
+ {
+ usleep(50000);
+ }
+ }
+ unlinkat(this->dir, PID_FILE, 0);
}
- return NULL;
}
/**
- * Implementation of guest_t.stop.
+ * save pid in file
*/
-static void stop(private_guest_t *this)
+void savepid(private_guest_t *this)
{
- if (this->state != GUEST_STOPPED)
+ FILE *file;
+
+ file = fdopen(openat(this->dir, PID_FILE, O_RDWR | O_CREAT | O_TRUNC,
+ PERM), "w");
+ if (file)
{
- this->state = GUEST_STOPPING;
- this->ifaces->destroy_offset(this->ifaces, offsetof(iface_t, destroy));
- this->ifaces = linked_list_create();
- kill(this->pid, SIGINT);
- waitpid(this->pid, NULL, 0);
- this->state = GUEST_STOPPED;
+ fprintf(file, "%d", this->pid);
+ fclose(file);
}
}
/**
* Implementation of guest_t.start.
*/
-static bool start(private_guest_t *this)
+static bool start(private_guest_t *this, invoke_function_t invoke, void* data,
+ idle_function_t idle)
{
char buf[2048];
char *notify;
char *pos = buf;
- char *args[16];
+ char *args[32];
int i = 0;
size_t left = sizeof(buf);
+ memset(args, 0, sizeof(args));
+
if (this->state != GUEST_STOPPED)
{
DBG1("unable to start guest in state %N", guest_state_names, this->state);
@@ -226,32 +263,22 @@ static bool start(private_guest_t *this)
args[i++] = write_arg(&pos, &left, "umid=%s", this->name);
args[i++] = write_arg(&pos, &left, "mem=%dM", this->mem);
args[i++] = write_arg(&pos, &left, "mconsole=notify:%s", notify);
- args[i++] = write_arg(&pos, &left, "con=pts");
- args[i++] = write_arg(&pos, &left, "con0=none,fd:%d", this->bootlog);
- args[i++] = NULL;
+ args[i++] = write_arg(&pos, &left, "con=null");
- this->pid = fork();
- switch (this->pid)
- {
- case 0: /* child, */
- dup2(open("/dev/null", 0), 0);
- dup2(this->bootlog, 1);
- dup2(this->bootlog, 2);
- execvp(args[0], args);
- DBG1("starting UML kernel '%s' failed: %m", args[0]);
- exit(1);
- case -1:
- this->state = GUEST_STOPPED;
- return FALSE;
- default:
- break;
+ this->pid = invoke(data, &this->public, args, i);
+ if (!this->pid)
+ {
+ this->state = GUEST_STOPPED;
+ return FALSE;
}
+ savepid(this);
+
/* open mconsole */
- this->mconsole = mconsole_create(notify);
+ this->mconsole = mconsole_create(notify, idle);
if (this->mconsole == NULL)
{
DBG1("opening mconsole at '%s' failed, stopping guest", buf);
- stop(this);
+ stop(this, NULL);
return FALSE;
}
@@ -266,6 +293,7 @@ static bool load_template(private_guest_t *this, char *path)
{
char dir[PATH_MAX];
size_t len;
+ iface_t *iface;
if (path == NULL)
{
@@ -285,7 +313,15 @@ static bool load_template(private_guest_t *this, char *path)
return FALSE;
}
}
- return this->cowfs->set_overlay(this->cowfs, dir);
+ if (!this->cowfs->set_overlay(this->cowfs, dir))
+ {
+ return FALSE;
+ }
+ while (this->ifaces->remove_last(this->ifaces, (void**)&iface) == SUCCESS)
+ {
+ iface->destroy(iface);
+ }
+ return TRUE;
}
/**
@@ -293,10 +329,6 @@ static bool load_template(private_guest_t *this, char *path)
*/
static void sigchild(private_guest_t *this)
{
- if (this->state != GUEST_STOPPING)
- { /* collect zombie if uml crashed */
- waitpid(this->pid, NULL, WNOHANG);
- }
DESTROY_IF(this->mconsole);
this->mconsole = NULL;
this->state = GUEST_STOPPED;
@@ -341,22 +373,6 @@ static bool mount_unionfs(private_guest_t *this)
}
/**
- * open logfile for boot messages
- */
-static int open_bootlog(private_guest_t *this)
-{
- int fd;
-
- fd = openat(this->dir, LOG_FILE, O_WRONLY | O_CREAT, PERM);
- if (fd == -1)
- {
- DBG1("opening bootlog failed, using stdout");
- return 1;
- }
- return fd;
-}
-
-/**
* load memory configuration from file
*/
int loadmem(private_guest_t *this)
@@ -402,12 +418,8 @@ bool savemem(private_guest_t *this, int mem)
*/
static void destroy(private_guest_t *this)
{
- stop(this);
+ stop(this, NULL);
umount_unionfs(this);
- if (this->bootlog > 1)
- {
- close(this->bootlog);
- }
if (this->dir > 0)
{
close(this->dir);
@@ -430,10 +442,10 @@ static private_guest_t *guest_create_generic(char *parent, char *name,
this->public.get_pid = (pid_t(*)(guest_t*))get_pid;
this->public.get_state = (guest_state_t(*)(guest_t*))get_state;
this->public.create_iface = (iface_t*(*)(guest_t*,char*))create_iface;
- this->public.create_iface_iterator = (iterator_t*(*)(guest_t*))create_iface_iterator;
+ this->public.destroy_iface = (void(*)(guest_t*,iface_t*))destroy_iface;
+ this->public.create_iface_enumerator = (enumerator_t*(*)(guest_t*))create_iface_enumerator;
this->public.start = (void*)start;
this->public.stop = (void*)stop;
- this->public.get_console = (char*(*)(guest_t*,int))get_console;
this->public.load_template = (bool(*)(guest_t*, char *path))load_template;
this->public.sigchild = (void(*)(guest_t*))sigchild;
this->public.destroy = (void*)destroy;
@@ -458,13 +470,11 @@ static private_guest_t *guest_create_generic(char *parent, char *name,
free(this);
return NULL;
}
-
this->pid = 0;
this->state = GUEST_STOPPED;
this->mconsole = NULL;
this->ifaces = linked_list_create();
this->mem = 0;
- this->bootlog = open_bootlog(this);
this->name = strdup(name);
this->cowfs = NULL;
diff --git a/src/dumm/guest.h b/src/dumm/guest.h
index 10b37aaa7..79a47fa62 100644
--- a/src/dumm/guest.h
+++ b/src/dumm/guest.h
@@ -17,11 +17,12 @@
#define GUEST_H
#include <library.h>
-#include <utils/iterator.h>
+#include <utils/enumerator.h>
#include "iface.h"
typedef enum guest_state_t guest_state_t;
+typedef struct guest_t guest_t;
/**
* @brief State of a guest (started, stopped, ...)
@@ -44,7 +45,26 @@ enum guest_state_t {
*/
extern enum_name_t *guest_state_names;
-typedef struct guest_t guest_t;
+/**
+ * Invoke function which lauches the UML guest.
+ *
+ * Consoles are all set to NULL, you may change them by adding additional UML
+ * options to args before invocation.
+ *
+ * @param data callback data
+ * @param guest guest to start
+ * @param args args to use for guest invocation, args[0] is kernel
+ * @param argc number of elements in args
+ * @param idle
+ * @return PID of child, 0 if failed
+ */
+typedef pid_t (*invoke_function_t)(void *data, guest_t *guest,
+ char *args[], int argc);
+
+/**
+ * Idle function to pass to start().
+ */
+typedef void (*idle_function_t)(void);
/**
* @brief A guest is a UML instance running on the host.
@@ -75,27 +95,21 @@ struct guest_t {
/**
* @brief Start the guest.
*
- * @return TRUE if guest successfully started
+ * @param invoke UML guest invocation function
+ * @param data data to pass back to invoke function
+ * @param idle idle function to call while waiting on child
+ * @return TRUE if guest successfully started
*/
- bool (*start) (guest_t *this);
+ bool (*start) (guest_t *this, invoke_function_t invoke, void *data,
+ idle_function_t idle);
/**
* @brief Kill the guest.
*
- * @return TRUE if guest was running and killed
+ * @param idle idle function to call while waiting to termination
+ * @return TRUE if guest was running and killed
*/
- bool (*stop) (guest_t *this);
-
- /**
- * @brief Get a console pts device.
- *
- * Every guest has 5 consoles, numbered from 1 to 5. These are associated
- * to a unique pts device on the host.
- *
- * @param console console number to get (1-5)
- * @return pts device file name, NULL if failed
- */
- char* (*get_console) (guest_t *this, int console);
+ bool (*stop) (guest_t *this, idle_function_t idle);
/**
* @brief Create a new interface in the current scenario.
@@ -106,11 +120,18 @@ struct guest_t {
iface_t* (*create_iface)(guest_t *this, char *name);
/**
- * @brief Create an iterator over all guest interfaces.
+ * @brief Destroy an interface on guest.
+ *
+ * @param iface interface to destroy
+ */
+ void (*destroy_iface)(guest_t *this, iface_t *iface);
+
+ /**
+ * @brief Create an enumerator over all guest interfaces.
*
- * @return iterator over iface_t's
+ * @return enumerator over iface_t's
*/
- iterator_t* (*create_iface_iterator)(guest_t *this);
+ enumerator_t* (*create_iface_enumerator)(guest_t *this);
/**
* @brief Set the template COWFS overlay to use.
diff --git a/src/dumm/iface.c b/src/dumm/iface.c
index 3c1bfc470..b78c10bec 100644
--- a/src/dumm/iface.c
+++ b/src/dumm/iface.c
@@ -44,6 +44,42 @@ struct private_iface_t {
};
/**
+ * bring an interface up or down
+ */
+bool iface_control(char *name, bool up)
+{
+ int s;
+ bool good = FALSE;
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (!s)
+ {
+ return FALSE;
+ }
+ if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0)
+ {
+ if (up)
+ {
+ ifr.ifr_flags |= IFF_UP;
+ }
+ else
+ {
+ ifr.ifr_flags &= ~IFF_UP;
+ }
+ if (ioctl(s, SIOCSIFFLAGS, &ifr) == 0)
+ {
+ good = TRUE;
+ }
+ }
+ close(s);
+ return good;
+}
+
+/**
* Implementation of iface_t.get_guestif.
*/
static char* get_guestif(private_iface_t *this)
@@ -74,7 +110,11 @@ static bool destroy_tap(private_iface_t *this)
{
struct ifreq ifr;
int tap;
-
+
+ if (!iface_control(this->hostif, FALSE))
+ {
+ DBG1("bringing iface down failed: %m");
+ }
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
strncpy(ifr.ifr_name, this->hostif, sizeof(ifr.ifr_name) - 1);
@@ -165,6 +205,10 @@ iface_t *iface_create(char *guest, char *guestif, mconsole_t *mconsole)
free(this);
return NULL;
}
+ if (!iface_control(this->hostif, TRUE))
+ {
+ DBG1("bringing iface '%s' up failed: %m", this->hostif);
+ }
if (!this->mconsole->add_iface(this->mconsole, this->guestif, this->hostif))
{
DBG1("creating interface '%s' in guest failed", this->guestif);
diff --git a/src/dumm/iface.h b/src/dumm/iface.h
index 59de99f22..e04fe4ed1 100644
--- a/src/dumm/iface.h
+++ b/src/dumm/iface.h
@@ -17,7 +17,7 @@
#define IFACE_H
#include <library.h>
-#include <utils/iterator.h>
+#include <utils/enumerator.h>
#define TAP_DEVICE "/dev/net/tun"
@@ -53,10 +53,8 @@ struct iface_t {
void (*set_bridge)(iface_t *this, bridge_t *bridge);
/*
- bool (*up) (iface_t *this);
- bool (*down) (iface_t *this);
bool (*add_addr) (iface_t *this, host_t *addr);
- iterator_t* (*create_addr_iterator) (iface_t *this);
+ enumerator_t* (*create_addr_enumerator) (iface_t *this);
*/
/**
diff --git a/src/dumm/main.c b/src/dumm/main.c
index d6e142e24..d4f2c5176 100644
--- a/src/dumm/main.c
+++ b/src/dumm/main.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -13,539 +13,452 @@
* for more details.
*/
-#define _GNU_SOURCE
+#include "dumm.h"
+
+#include <utils/linked_list.h>
-#include <stdio.h>
+#include <sys/types.h>
#include <unistd.h>
-#include <getopt.h>
-#include <library.h>
-#include <readline/readline.h>
-#include <readline/history.h>
-#include <dlfcn.h>
-#include <dirent.h>
-#include "dumm.h"
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <vte/vte.h>
+#include <vte/reaper.h>
/**
- * global set of UMLs guests
+ * notebook page with vte and guest
*/
-dumm_t *dumm;
+typedef struct {
+ gint num;
+ GtkWidget *vte;
+ guest_t *guest;
+} page_t;
/**
- * show usage information (program arguments)
+ * Main window
*/
-static void usage()
-{
- printf("Usage:\n");
- printf(" --dir|-d <path> set working dir to <path>\n");
- printf(" --help|-h show this help\n");
-}
+GtkWidget *window;
/**
- * readline() wrapper
+ * notebook with guests, vtes
*/
-static char* get_line(char *format, ...)
-{
- char *line = NULL;
- char *prompt = "";
- va_list args;
-
- va_start(args, format);
- vasprintf(&prompt, format, args);
- va_end(args);
-
- while (TRUE)
- {
- line = readline(prompt);
- if (line == NULL)
- {
- printf("quit\n");
- dumm->destroy(dumm);
- clear_history();
- exit(0);
- }
- if (*line == '\0')
- {
- free(line);
- continue;
- }
- add_history(line);
- break;
- }
- free(prompt);
- return line;
-}
+GtkWidget *notebook;
+
+/**
+ * dumm context
+ */
+dumm_t *dumm;
+
+/**
+ * pages in notebook, page_t
+ */
+linked_list_t *pages;
/**
- * get a guest by name
+ * handle guest termination, SIGCHILD
*/
-static guest_t* get_guest(char *name)
+static void child_exited(VteReaper *vtereaper, gint pid, gint status)
{
- iterator_t *iterator;
- guest_t *guest = NULL;
+ enumerator_t *enumerator;
+ page_t *page;
- iterator = dumm->create_guest_iterator(dumm);
- while (iterator->iterate(iterator, (void**)&guest))
+ enumerator = pages->create_enumerator(pages);
+ while (enumerator->enumerate(enumerator, (void**)&page))
{
- if (streq(guest->get_name(guest), name))
+ if (page->guest->get_pid(page->guest) == pid)
{
+ page->guest->sigchild(page->guest);
+ vte_terminal_feed(VTE_TERMINAL(page->vte),
+ "\n\r--- guest terminated ---\n\r", -1);
break;
}
- guest = NULL;
}
- iterator->destroy(iterator);
- return guest;
+ enumerator->destroy(enumerator);
}
-/**
- * get a bridge by name
- */
-static bridge_t* get_bridge(char *name)
+static page_t* get_page(int num)
{
- iterator_t *iterator;
- bridge_t *bridge = NULL;
+ enumerator_t *enumerator;
+ page_t *page, *found = NULL;
- iterator = dumm->create_bridge_iterator(dumm);
- while (iterator->iterate(iterator, (void**)&bridge))
+ enumerator = pages->create_enumerator(pages);
+ while (enumerator->enumerate(enumerator, (void**)&page))
{
- if (streq(bridge->get_name(bridge), name))
+ if (page->num == num)
{
+ found = page;
break;
}
- bridge = NULL;
}
- iterator->destroy(iterator);
- return bridge;
+ enumerator->destroy(enumerator);
+ return found;
}
/**
- * get an interface by guest name
+ * Guest invocation callback
*/
-static iface_t* get_iface(char *name, char *ifname)
+static pid_t invoke(void *vte, guest_t *guest,
+ char *args[], int argc)
{
- iterator_t *guests, *ifaces;
- guest_t *guest;
- iface_t *iface;
-
- guests = dumm->create_guest_iterator(dumm);
- while (guests->iterate(guests, (void**)&guest))
- {
- if (streq(guest->get_name(guest), name))
- {
- iface = NULL;
- ifaces = guest->create_iface_iterator(guest);
- while (ifaces->iterate(ifaces, (void**)&iface))
- {
- if (streq(iface->get_guestif(iface), ifname))
- {
- break;
- }
- iface = NULL;
- }
- ifaces->destroy(ifaces);
- if (iface)
- {
- break;
- }
- }
- }
- guests->destroy(guests);
- return iface;
+ args[argc] = "con0=fd:0,fd:1";
+ return vte_terminal_fork_command(VTE_TERMINAL(vte), args[0], args, NULL,
+ NULL, FALSE, FALSE, FALSE);
}
-static void guest_addif_menu(guest_t *guest)
+void idle(void)
{
- char *name;
-
- name = get_line("interface name: ");
+ gtk_main_iteration_do(FALSE);
+ sched_yield();
+}
+
+static void start_guest()
+{
+ page_t *page;
- if (!guest->create_iface(guest, name))
+ page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+ if (page && page->guest->get_state(page->guest) == GUEST_STOPPED)
{
- printf("creating interface failed\n");
+ vte_terminal_feed(VTE_TERMINAL(page->vte),
+ "--- starting guest ---\n\r", -1);
+ page->guest->start(page->guest, invoke, VTE_TERMINAL(page->vte), idle);
}
- free(name);
}
-static void guest_delif_menu(guest_t *guest)
+static void start_all_guests()
{
- char *name;
- iface_t *iface;
- iterator_t *iterator;
- bool found = FALSE;
-
- name = get_line("interface name: ");
+ enumerator_t *enumerator;
+ page_t *page;
- iterator = guest->create_iface_iterator(guest);
- while (iterator->iterate(iterator, (void**)&iface))
+ enumerator = pages->create_enumerator(pages);
+ while (enumerator->enumerate(enumerator, (void**)&page))
{
- if (streq(iface->get_guestif(iface), name))
+ if (page->guest->get_state(page->guest) == GUEST_STOPPED)
{
- iterator->remove(iterator);
- iface->destroy(iface);
- found = TRUE;
- break;
+ vte_terminal_feed(VTE_TERMINAL(page->vte),
+ "--- starting all guests ---\n\r", -1);
+ page->guest->start(page->guest, invoke,
+ VTE_TERMINAL(page->vte), idle);
}
}
- iterator->destroy(iterator);
-
- if (!found)
- {
- printf("interface '%s' not found\n");
- }
- free(name);
+ enumerator->destroy(enumerator);
}
-static void guest_console(guest_t *guest)
+static void stop_guest()
{
- int con;
+ page_t *page;
- for (con = 1; con <= 6; con++)
+ page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+ if (page && page->guest->get_state(page->guest) == GUEST_RUNNING)
{
- char *pts = guest->get_console(guest, con);
- if (pts)
- {
- printf("%d: %s\n", con, pts);
- free(pts);
- }
+ page->guest->stop(page->guest, idle);
}
}
-static void guest_menu(guest_t *guest)
+/**
+ * quit signal handler
+ */
+static void quit()
{
- while (TRUE)
+ enumerator_t *enumerator;
+ page_t *page;
+
+ dumm->load_template(dumm, NULL);
+
+ enumerator = pages->create_enumerator(pages);
+ while (enumerator->enumerate(enumerator, &page))
{
- char *line = get_line("guest/%s# ", guest->get_name(guest));
-
- if (streq(line, "back"))
- {
- free(line);
- break;
+ if (page->guest->get_state(page->guest) != GUEST_STOPPED)
+ {
+ page->guest->stop(page->guest, idle);
}
- else if (streq(line, "start"))
- {
- if (guest->start(guest))
- {
- printf("guest '%s' is running\n", guest->get_name(guest));
- }
- else
- {
- printf("failed to start guest '%s'\n", guest->get_name(guest));
- }
- }
- else if (streq(line, "stop"))
- {
- printf("stopping guest '%s'...\n", guest->get_name(guest));
- guest->stop(guest);
- printf("guest '%s' is down\n", guest->get_name(guest));
- }
- else if (streq(line, "addif"))
- {
- guest_addif_menu(guest);
- }
- else if (streq(line, "delif"))
- {
- guest_delif_menu(guest);
- }
- else if (streq(line, "console"))
- {
- guest_console(guest);
- }
- else
- {
- printf("back|start|stop|addif|delif|console\n");
- }
- free(line);
}
+ enumerator->destroy(enumerator);
+ gtk_main_quit();
}
-static void guest_create_menu()
+static void error_dialog(char *msg)
{
- char *name, *kernel, *master, *mem;
- guest_t *guest;
-
- name = get_line("guest name: ");
- kernel = get_line("kernel image: ");
- master = get_line("master filesystem: ");
- mem = get_line("amount of memory in MB: ");
-
- guest = dumm->create_guest(dumm, name, kernel, master, atoi(mem));
- if (guest)
- {
- printf("guest '%s' created\n", guest->get_name(guest));
- guest_menu(guest);
- }
- else
- {
- printf("failed to create guest '%s'\n", name);
- }
- free(name);
- free(kernel);
- free(master);
- free(mem);
+ GtkWidget *error;
+
+ error = gtk_message_dialog_new(GTK_WINDOW(window),
+ GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE, msg);
+ gtk_dialog_run(GTK_DIALOG(error));
+ gtk_widget_destroy(error);
}
-static void guest_list_menu()
+static void create_switch()
{
+ GtkWidget *dialog, *table, *label, *name;
+ bridge_t *bridge;
+
+ dialog = gtk_dialog_new_with_buttons("Create new switch", GTK_WINDOW(window),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ GTK_STOCK_NEW, GTK_RESPONSE_ACCEPT, NULL);
+
+ table = gtk_table_new(1, 2, TRUE);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
+
+ label = gtk_label_new("Switch name");
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, 0, 0, 0, 0);
+ gtk_widget_show(label);
+
+ name = gtk_entry_new();
+ gtk_table_attach(GTK_TABLE(table), name, 1, 2, 0, 1,
+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
+ gtk_widget_show(name);
+
+ gtk_widget_show(table);
+
while (TRUE)
{
- iterator_t *iterator;
- guest_t *guest;
- char *line = get_line("guest# ");
-
- if (streq(line, "back"))
- {
- free(line);
- break;
- }
- else if (streq(line, "list"))
- {
- iterator = dumm->create_guest_iterator(dumm);
- while (iterator->iterate(iterator, (void**)&guest))
- {
- printf("%s\n", guest->get_name(guest));
- }
- iterator->destroy(iterator);
- }
- else if (streq(line, "create"))
- {
- guest_create_menu();
- }
- else
+ switch (gtk_dialog_run(GTK_DIALOG(dialog)))
{
- guest = get_guest(line);
- if (guest)
- {
- guest_menu(guest);
- }
- else
- {
- printf("back|list|create|<guest>\n");
+ case GTK_RESPONSE_ACCEPT:
+ {
+ if (streq(gtk_entry_get_text(GTK_ENTRY(name)), ""))
+ {
+ continue;
+ }
+ bridge = dumm->create_bridge(dumm,
+ (char*)gtk_entry_get_text(GTK_ENTRY(name)));
+ if (!bridge)
+ {
+ error_dialog("creating bridge failed!");
+ continue;
+ }
+ break;
}
+ default:
+ break;
}
- free(line);
+ break;
}
+ gtk_widget_destroy(dialog);
}
-static void bridge_addif_menu(bridge_t *bridge)
+static void delete_switch()
{
- char *name, *ifname;
- iface_t *iface;
-
- name = get_line("guest name: ");
- ifname = get_line("interface name: ");
-
- iface = get_iface(name, ifname);
- if (!iface)
- {
- printf("guest '%s' has no interface named '%s'\n", name, ifname);
- }
- else if (!bridge->connect_iface(bridge, iface))
- {
- printf("failed to add interface '%s' to bridge '%s'\n", ifname,
- bridge->get_name(bridge));
- }
- free(name);
- free(ifname);
+
}
-static void bridge_delif_menu(bridge_t *bridge)
+static void connect_guest()
{
- char *name, *ifname;
+ page_t *page;
+ GtkWidget *dialog, *table, *label, *name, *box;
+ bridge_t *bridge;
iface_t *iface;
+ enumerator_t *enumerator;
- name = get_line("guest name: ");
- ifname = get_line("interface name: ");
-
- iface = get_iface(name, ifname);
- if (!iface)
+ page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+ if (!page || page->guest->get_state(page->guest) != GUEST_RUNNING)
{
- printf("guest '%s' has no interface named '%s'\n", name, ifname);
+ return;
}
- else if (!bridge->disconnect_iface(bridge, iface))
+
+ dialog = gtk_dialog_new_with_buttons("Connect guest", GTK_WINDOW(window),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ GTK_STOCK_NEW, GTK_RESPONSE_ACCEPT, NULL);
+
+ table = gtk_table_new(2, 2, TRUE);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
+
+ label = gtk_label_new("Interface name");
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, 0, 0, 0, 0);
+ gtk_widget_show(label);
+
+ name = gtk_entry_new();
+ gtk_table_attach(GTK_TABLE(table), name, 1, 2, 0, 1,
+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
+ gtk_widget_show(name);
+
+ label = gtk_label_new("Connected switch");
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, 0, 0, 0, 0);
+ gtk_widget_show(label);
+
+ box = gtk_combo_box_new_text();
+ gtk_table_attach(GTK_TABLE(table), box, 1, 2, 1, 2,
+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
+ enumerator = dumm->create_bridge_enumerator(dumm);
+ while (enumerator->enumerate(enumerator, &bridge))
{
- printf("failed to remove interface '%s' from bridge '%s'\n", ifname,
- bridge->get_name(bridge));
+ gtk_combo_box_append_text(GTK_COMBO_BOX(box), bridge->get_name(bridge));
}
- free(name);
- free(ifname);
-}
-
-static void bridge_menu(bridge_t *bridge)
-{
+ enumerator->destroy(enumerator);
+ gtk_widget_show(box);
+
+ gtk_widget_show(table);
+
while (TRUE)
{
- char *line = get_line("bridge/%s# ", bridge->get_name(bridge));
-
- if (streq(line, "back"))
- {
- free(line);
- break;
- }
- else if (streq(line, "list"))
+ switch (gtk_dialog_run(GTK_DIALOG(dialog)))
{
- iterator_t *iterator;
- iface_t *iface;
-
- iterator = bridge->create_iface_iterator(bridge);
- while (iterator->iterate(iterator, (void**)&iface))
- {
- printf("%s (%s)\n", iface->get_guestif(iface), iface->get_hostif(iface));
+ case GTK_RESPONSE_ACCEPT:
+ {
+ if (streq(gtk_entry_get_text(GTK_ENTRY(name)), ""))
+ {
+ continue;
+ }
+
+ iface = page->guest->create_iface(page->guest,
+ (char*)gtk_entry_get_text(GTK_ENTRY(name)));
+ if (!iface)
+ {
+ error_dialog("creating interface failed!");
+ continue;
+ }
+ enumerator = dumm->create_bridge_enumerator(dumm);
+ while (enumerator->enumerate(enumerator, &bridge))
+ {
+ if (!bridge->connect_iface(bridge, iface))
+ {
+ error_dialog("connecting interface failed!");
+ }
+ break;
+ }
+ enumerator->destroy(enumerator);
+ break;
}
- iterator->destroy(iterator);
- }
- else if (streq(line, "addif"))
- {
- bridge_addif_menu(bridge);
- }
- else if (streq(line, "delif"))
- {
- bridge_delif_menu(bridge);
- }
- else
- {
- printf("back|list|addif|delif\n");
+ default:
+ break;
}
- free(line);
+ break;
}
+ gtk_widget_destroy(dialog);
}
-static void bridge_create_menu()
+static void disconnect_guest()
{
- char *name;
- bridge_t *bridge;
-
- name = get_line("bridge name: ");
-
- bridge = dumm->create_bridge(dumm, name);
- if (bridge)
- {
- printf("bridge '%s' created\n", bridge->get_name(bridge));
- bridge_menu(bridge);
- }
- else
- {
- printf("failed to create bridge '%s'\n", name);
- }
- free(name);
+
}
-static void bridge_list_menu()
+static void delete_guest()
{
- while (TRUE)
+ page_t *page;
+
+ page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
+ if (page)
{
- iterator_t *iterator;
- bridge_t *bridge;
- char *line = get_line("bridge# ");
-
- if (streq(line, "back"))
- {
- free(line);
- break;
- }
- else if (streq(line, "list"))
- {
- iterator = dumm->create_bridge_iterator(dumm);
- while (iterator->iterate(iterator, (void**)&bridge))
- {
- printf("%s\n", bridge->get_name(bridge));
- }
- iterator->destroy(iterator);
- }
- else if (streq(line, "create"))
- {
- bridge_create_menu();
- }
- else
- {
- bridge = get_bridge(line);
- if (bridge)
- {
- bridge_menu(bridge);
- }
- else
- {
- printf("back|list|create|<bridge>\n");
- }
- }
- free(line);
+ page->guest->stop(page->guest, idle);
+ dumm->delete_guest(dumm, page->guest);
+ gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page->num);
+ pages->remove(pages, page, NULL);
+ g_free(page);
}
}
-static void template_menu()
+/**
+ * create a new page for a guest
+ */
+static page_t* create_page(guest_t *guest)
{
- char *name;
-
- name = get_line("template name (or 'none'): ");
+ GtkWidget *label;
+ page_t *page;
- dumm->load_template(dumm, streq(name, "none") ? NULL : name);
-
- free(name);
+ page = g_new(page_t, 1);
+ page->guest = guest;
+ page->vte = vte_terminal_new();
+ label = gtk_label_new(guest->get_name(guest));
+ page->num = gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+ page->vte, label);
+ gtk_widget_show(page->vte);
+ pages->insert_last(pages, page);
+ return page;
}
-typedef bool (*uml_test_t)(dumm_t *dumm);
-
-static void test_menu()
+/**
+ * create a new guest
+ */
+static void create_guest()
{
- char *name;
- void *handle;
- struct dirent *ent;
- DIR *dir;
- uml_test_t test;
+ guest_t *guest;
+ GtkWidget *dialog, *table, *label, *name, *kernel, *master, *memory;
+
+ dialog = gtk_dialog_new_with_buttons("Create new guest", GTK_WINDOW(window),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ GTK_STOCK_NEW, GTK_RESPONSE_ACCEPT, NULL);
+
+ table = gtk_table_new(4, 2, TRUE);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
+
+ label = gtk_label_new("Guest name");
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, 0, 0, 0, 0);
+ gtk_widget_show(label);
+
+ label = gtk_label_new("UML kernel");
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, 0, 0, 0, 0);
+ gtk_widget_show(label);
+
+ label = gtk_label_new("Master filesystem");
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, 0, 0, 0, 0);
+ gtk_widget_show(label);
+
+ label = gtk_label_new("Memory (MB)");
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, 0, 0, 0, 0);
+ gtk_widget_show(label);
+
+ name = gtk_entry_new();
+ gtk_table_attach(GTK_TABLE(table), name, 1, 2, 0, 1,
+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
+ gtk_widget_show(name);
+
+ kernel = gtk_file_chooser_button_new("Select UML kernel image",
+ GTK_FILE_CHOOSER_ACTION_OPEN);
+ gtk_table_attach(GTK_TABLE(table), kernel, 1, 2, 1, 2,
+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
+ gtk_widget_show(kernel);
+
+ master = gtk_file_chooser_button_new("Select master filesystem",
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+ gtk_table_attach(GTK_TABLE(table), master, 1, 2, 2, 3,
+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
+ gtk_widget_show(master);
- name = get_line("test name: ");
+ memory = gtk_spin_button_new_with_range(1, 4096, 1);
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(memory), 0);
+ gtk_table_attach(GTK_TABLE(table), memory, 1, 2, 3, 4,
+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
+ gtk_widget_show(memory);
- dir = opendir("tests");
- if (dir)
+ gtk_widget_show(table);
+
+ while (TRUE)
{
- while ((ent = readdir(dir)))
+ switch (gtk_dialog_run(GTK_DIALOG(dialog)))
{
- char buf[PATH_MAX];
- size_t len;
-
- len = strlen(ent->d_name);
- if (strlen(ent->d_name) < 4 || !streq(ent->d_name + len - 3, ".so"))
+ case GTK_RESPONSE_ACCEPT:
{
- continue;
- }
+ char *sname, *skernel, *smaster;
+ page_t *page;
+
+ sname = (char*)gtk_entry_get_text(GTK_ENTRY(name));
+ skernel = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(kernel));
+ smaster = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(master));
- snprintf(buf, sizeof(buf), "%s/%s", "tests", ent->d_name);
- handle = dlopen(buf, RTLD_LAZY);
- if (!handle)
- {
- printf("failed to open test %s\n", ent->d_name);
- continue;
- }
- test = dlsym(handle, "test");
- if (test && dumm->load_template(dumm, ent->d_name))
- {
- printf("running test %s: ", ent->d_name);
- if (test(dumm))
+ if (!sname[0] || !skernel || !smaster)
{
- printf("success\n");
+ continue;
}
- else
+ guest = dumm->create_guest(dumm, sname, skernel, smaster,
+ gtk_spin_button_get_value(GTK_SPIN_BUTTON(memory)));
+ if (!guest)
{
- printf("failed\n");
+ error_dialog("creating guest failed!");
+ continue;
}
+ page = create_page(guest);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), page->num);
+ break;
}
- else
- {
- printf("failed to open test %s\n", ent->d_name);
- }
- dlclose(handle);
+ default:
+ break;
}
+ break;
}
- free(name);
-}
-
-/**
- * Signal handler
- */
-void signal_action(int sig, siginfo_t *info, void *ucontext)
-{
- dumm->destroy(dumm);
- clear_history();
- exit(0);
+ gtk_widget_destroy(dialog);
}
/**
@@ -553,80 +466,156 @@ void signal_action(int sig, siginfo_t *info, void *ucontext)
*/
int main(int argc, char *argv[])
{
- struct sigaction action;
- char *dir = ".";
+ GtkWidget *menubar, *menu, *menuitem, *vbox;
+ GtkWidget *dummMenu, *guestMenu, *switchMenu;
+ enumerator_t *enumerator;
+ guest_t *guest;
+
+ library_init(NULL);
+ gtk_init(&argc, &argv);
+
+ pages = linked_list_create();
+ dumm = dumm_create(NULL);
- while (TRUE)
- {
- struct option options[] = {
- {"dir", 1, 0, 0},
- {"help", 0, 0, 0},
- {0, 0, 0, 0}
- };
-
- switch (getopt_long(argc, argv, "d:h", options, NULL))
- {
- case -1:
- break;
- case 'd':
- dir = optarg;
- continue;
- case 'h':
- usage();
- return 0;
- default:
- usage();
- return 1;
- }
- break;
- }
+ /* setup window */
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(quit), NULL);
+ gtk_window_set_title(GTK_WINDOW (window), "Dumm");
+ gtk_window_set_default_size(GTK_WINDOW (window), 1000, 500);
+ g_signal_connect(G_OBJECT(vte_reaper_get()), "child-exited",
+ G_CALLBACK(child_exited), NULL);
- memset(&action, 0, sizeof(action));
- action.sa_sigaction = signal_action;
- action.sa_flags = SA_SIGINFO;
- if (sigaction(SIGINT, &action, NULL) != 0 ||
- sigaction(SIGQUIT, &action, NULL) != 0 ||
- sigaction(SIGTERM, &action, NULL) != 0)
- {
- printf("signal handler setup failed: %m.\n");
- return 1;
- }
+ /* add vbox with menubar, notebook */
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+ menubar = gtk_menu_bar_new();
+ gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
+ notebook = gtk_notebook_new();
+ g_object_set(G_OBJECT(notebook), "homogeneous", TRUE, NULL);
+ gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM);
+ gtk_container_add(GTK_CONTAINER(vbox), notebook);
+
+ /* Dumm menu */
+ menu = gtk_menu_new();
+ dummMenu = gtk_menu_item_new_with_mnemonic("_Dumm");
+ gtk_menu_bar_append(GTK_MENU_BAR(menubar), dummMenu);
+ gtk_widget_show(dummMenu);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(dummMenu), menu);
- dumm = dumm_create(dir);
- while (TRUE)
+ /* Dumm -> exit */
+ menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(quit), NULL);
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_show(menuitem);
+
+ /* Guest menu */
+ menu = gtk_menu_new();
+ guestMenu = gtk_menu_item_new_with_mnemonic("_Guest");
+ gtk_menu_bar_append(GTK_MENU_BAR(menubar), guestMenu);
+ gtk_widget_show(guestMenu);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(guestMenu), menu);
+
+ /* Guest -> new */
+ menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW, NULL);
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(create_guest), NULL);
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_show(menuitem);
+
+ /* Guest -> delete */
+ menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_DELETE, NULL);
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(delete_guest), NULL);
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_show(menuitem);
+
+ menuitem = gtk_separator_menu_item_new();
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_show(menuitem);
+
+ /* Guest -> start */
+ menuitem = gtk_menu_item_new_with_mnemonic("_Start");
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(start_guest), NULL);
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_show(menuitem);
+
+ /* Guest -> startall */
+ menuitem = gtk_menu_item_new_with_mnemonic("Start _all");
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(start_all_guests), NULL);
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_show(menuitem);
+
+ /* Guest -> stop */
+ menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_STOP, NULL);
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(stop_guest), NULL);
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_show(menuitem);
+
+ menuitem = gtk_separator_menu_item_new();
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_show(menuitem);
+
+ /* Guest -> connect */
+ menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_CONNECT, NULL);
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(connect_guest), NULL);
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_show(menuitem);
+
+ /* Guest -> disconnect */
+ menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_DISCONNECT, NULL);
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(disconnect_guest), NULL);
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_set_sensitive(menuitem, FALSE);
+ gtk_widget_show(menuitem);
+
+ /* Switch menu */
+ menu = gtk_menu_new();
+ switchMenu = gtk_menu_item_new_with_mnemonic("_Switch");
+ gtk_menu_bar_append(GTK_MENU_BAR(menubar), switchMenu);
+ gtk_widget_show(switchMenu);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(switchMenu), menu);
+
+ /* Switch -> new */
+ menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW, NULL);
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(create_switch), NULL);
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_show(menuitem);
+
+ /* Switch -> delete */
+ menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_DELETE, NULL);
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(delete_switch), NULL);
+ gtk_menu_append(GTK_MENU(menu), menuitem);
+ gtk_widget_set_sensitive(menuitem, FALSE);
+ gtk_widget_show(menuitem);
+
+ /* show widgets */
+ gtk_widget_show(menubar);
+ gtk_widget_show(notebook);
+ gtk_widget_show(vbox);
+ gtk_widget_show(window);
+
+ /* fill notebook with guests */
+ enumerator = dumm->create_guest_enumerator(dumm);
+ while (enumerator->enumerate(enumerator, (void**)&guest))
{
- char *line = get_line("# ");
-
- if (streq(line, "quit"))
- {
- free(line);
- break;
- }
- else if (streq(line, "guest"))
- {
- guest_list_menu();
- }
- else if (streq(line, "bridge"))
- {
- bridge_list_menu();
- }
- else if (streq(line, "template"))
- {
- template_menu();
- }
- else if (streq(line, "test"))
- {
- test_menu();
- }
- else
- {
- printf("quit|guest|bridge|template|test\n");
- }
- free(line);
+ create_page(guest);
}
- dumm->load_template(dumm, NULL);
+ enumerator->destroy(enumerator);
+
+ gtk_main();
+
dumm->destroy(dumm);
- clear_history();
+ pages->destroy_function(pages, g_free);
+
+ library_deinit();
return 0;
}
diff --git a/src/dumm/mconsole.c b/src/dumm/mconsole.c
index 25cb84621..d9864f676 100644
--- a/src/dumm/mconsole.c
+++ b/src/dumm/mconsole.c
@@ -44,6 +44,8 @@ struct private_mconsole_t {
int notify;
/** address of uml socket */
struct sockaddr_un uml;
+ /** idle function */
+ void (*idle)(void);
};
/**
@@ -91,7 +93,7 @@ static int request(private_mconsole_t *this, char *command,
{
mconsole_request request;
mconsole_reply reply;
- int len, total = 0;
+ int len, total = 0, flags = 0;
memset(&request, 0, sizeof(request));
request.magic = MCONSOLE_MAGIC;
@@ -101,19 +103,41 @@ static int request(private_mconsole_t *this, char *command,
*buf = '\0';
(*size)--;
- if (sendto(this->console, &request, sizeof(request), 0,
- (struct sockaddr*)&this->uml, sizeof(this->uml)) < 0)
+ if (this->idle)
+ {
+ flags = MSG_DONTWAIT;
+ }
+ do
+ {
+ if (this->idle)
+ {
+ this->idle();
+ }
+ len = sendto(this->console, &request, sizeof(request), flags,
+ (struct sockaddr*)&this->uml, sizeof(this->uml));
+ }
+ while (len < 0 && (errno == EINTR || errno == EAGAIN));
+
+ if (len < 0)
{
snprintf(buf, *size, "sending mconsole command to UML failed: %m");
return -1;
}
do
{
- len = recv(this->console, &reply, sizeof(reply), 0);
+ len = recv(this->console, &reply, sizeof(reply), flags);
+ if (len < 0 && (errno == EINTR || errno == EAGAIN))
+ {
+ if (this->idle)
+ {
+ this->idle();
+ }
+ continue;
+ }
if (len < 0)
{
snprintf(buf, *size, "receiving from mconsole failed: %m");
- return -1;
+ return -1;
}
if (len > 0)
{
@@ -169,58 +193,39 @@ static bool del_iface(private_mconsole_t *this, char *guest)
}
return TRUE;
}
-
-/**
- * Implementation of mconsole_t.get_console_pts.
- */
-static char* get_console_pts(private_mconsole_t *this, int con)
-{
- char buf[128];
- char *pos;
- int len;
-
- len = snprintf(buf, sizeof(buf), "config con%d", con);
- if (len < 0 || len >= sizeof(buf))
- {
- return NULL;
- }
- len = sizeof(buf);
- if (request(this, buf, buf, &len) != 0)
- {
- DBG1("getting console pts failed: %.*s", len, buf);
- return NULL;
- }
- pos = memchr(buf, ':', len);
- if (pos == NULL)
- {
- return NULL;
- }
- pos++;
- return strndup(pos, len - (pos - buf));
-}
/**
* Poll until guest is ready
*/
static bool wait_bootup(private_mconsole_t *this)
{
- char *cmd, buf[128];
+ char buf[128];
int len, res;
- cmd = "config con0";
while (TRUE)
{
len = sizeof(buf);
- res = request(this, cmd, buf, &len);
+ res = request(this, "config eth9=mcast", buf, &len);
if (res < 0)
{
return FALSE;
}
if (res == 0)
{
+ while (request(this, "remove eth9", buf, &len) != 0)
+ {
+ usleep(50000);
+ }
return TRUE;
}
- usleep(50000);
+ if (this->idle)
+ {
+ this->idle();
+ }
+ else
+ {
+ usleep(50000);
+ }
}
}
@@ -241,7 +246,7 @@ static bool wait_for_notify(private_mconsole_t *this, char *nsock)
{
struct sockaddr_un addr;
mconsole_notify notify;
- int len;
+ int len, flags = 0;
this->notify = socket(AF_UNIX, SOCK_DGRAM, 0);
if (this->notify < 0)
@@ -258,10 +263,20 @@ static bool wait_for_notify(private_mconsole_t *this, char *nsock)
close(this->notify);
return FALSE;
}
+ if (this->idle)
+ {
+ flags = MSG_DONTWAIT;
+ }
do
{
- len = recvfrom(this->notify, &notify, sizeof(notify), 0, NULL, 0);
- } while (len < 0 && errno == EINTR);
+ if (this->idle)
+ {
+ this->idle();
+ }
+ len = recvfrom(this->notify, &notify, sizeof(notify), flags, NULL, 0);
+ }
+ while (len < 0 && (errno == EINTR || errno == EAGAIN));
+
if (len < 0 || len >= sizeof(notify))
{
DBG1("reading from mconsole notify socket failed: %m");
@@ -314,15 +329,16 @@ static bool setup_console(private_mconsole_t *this)
/**
* create the mconsole instance
*/
-mconsole_t *mconsole_create(char *notify)
+mconsole_t *mconsole_create(char *notify, void(*idle)(void))
{
private_mconsole_t *this = malloc_thing(private_mconsole_t);
this->public.add_iface = (bool(*)(mconsole_t*, char *guest, char *host))add_iface;
this->public.del_iface = (bool(*)(mconsole_t*, char *guest))del_iface;
- this->public.get_console_pts = (char*(*)(mconsole_t*, int con))get_console_pts;
this->public.destroy = (void*)destroy;
+ this->idle = idle;
+
if (!wait_for_notify(this, notify))
{
free(this);
diff --git a/src/dumm/mconsole.h b/src/dumm/mconsole.h
index 53aaa1b8b..55ce15dda 100644
--- a/src/dumm/mconsole.h
+++ b/src/dumm/mconsole.h
@@ -43,14 +43,6 @@ struct mconsole_t {
bool (*del_iface)(mconsole_t *this, char *guest);
/**
- * @brief Get the pts device file assigned to a console.
- *
- * @param con console number in guest
- * @return allocated device string
- */
- char* (*get_console_pts)(mconsole_t *this, int con);
-
- /**
* @brief Destroy the mconsole instance
*/
void (*destroy) (mconsole_t *this);
@@ -63,9 +55,10 @@ struct mconsole_t {
* to connect to the mconsole socket supplied in the received notification.
*
* @param notify unix notify socket path
+ * @param idle idle function to call while waiting for responses
* @return mconsole instance, or NULL if failed
*/
-mconsole_t *mconsole_create(char *notify);
+mconsole_t *mconsole_create(char *notify, void(*idle)(void));
#endif /* MCONSOLE_H */
diff --git a/src/dumm/testing.c b/src/dumm/testing.c
new file mode 100644
index 000000000..c0d23296b
--- /dev/null
+++ b/src/dumm/testing.c
@@ -0,0 +1,171 @@
+/*
+ * 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 <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <library.h>
+#include <dumm.h>
+
+/**
+ * number of running guests
+ */
+static int running = 0;
+
+/**
+ * Guest invocation callback
+ */
+static pid_t invoke(void *vte, guest_t *guest,
+ char *args[], int argc)
+{
+ pid_t pid;
+
+ args[argc] = "con0=xterm";
+
+ pid = fork();
+ switch (pid)
+ {
+ case 0: /* child */
+ dup2(open("/dev/null", 0), 1);
+ dup2(open("/dev/null", 0), 2);
+ execvp(args[0], args);
+ exit(-1);
+ case -1:
+ fprintf(stderr, "starting guest '%s' failed\n", guest->get_name(guest));
+ return 0;
+ default:
+ printf("started guest '%s', pid: %d\n", guest->get_name(guest), pid);
+ running++;
+ return pid;
+ }
+}
+
+/**
+ * main routine, parses args and reads from console
+ */
+int main(int argc, char *argv[])
+{
+ dumm_t *dumm;
+ enumerator_t *enumerator;
+ guest_t *guest;
+ bridge_t *switch0, *switch1, *switch2;
+ iface_t *iface;
+ sigset_t set;
+ siginfo_t info;
+
+ library_init(NULL);
+
+ dumm = dumm_create(NULL);
+
+ switch0 = dumm->create_bridge(dumm, "switch0");
+ switch1 = dumm->create_bridge(dumm, "switch1");
+ switch2 = dumm->create_bridge(dumm, "switch2");
+
+ if (switch0 && switch1 && switch2)
+ {
+ enumerator = dumm->create_guest_enumerator(dumm);
+ while (enumerator->enumerate(enumerator, &guest))
+ {
+ if (!guest->start(guest, invoke, NULL, NULL))
+ {
+ continue;
+ }
+ if (streq(guest->get_name(guest), "alice"))
+ {
+ iface = guest->create_iface(guest, "eth0");
+ if (iface)
+ {
+ switch1->connect_iface(switch1, iface);
+ }
+ iface = guest->create_iface(guest, "eth1");
+ if (iface)
+ {
+ switch0->connect_iface(switch0, iface);
+ }
+ }
+ else if (streq(guest->get_name(guest), "moon") ||
+ streq(guest->get_name(guest), "sun"))
+ {
+ iface = guest->create_iface(guest, "eth0");
+ if (iface)
+ {
+ switch0->connect_iface(switch0, iface);
+ }
+ iface = guest->create_iface(guest, "eth1");
+ if (iface)
+ {
+ switch1->connect_iface(switch1, iface);
+ }
+ }
+ else if (streq(guest->get_name(guest), "bob"))
+ {
+ iface = guest->create_iface(guest, "eth0");
+ if (iface)
+ {
+ switch2->connect_iface(switch2, iface);
+ }
+ }
+ else if (streq(guest->get_name(guest), "venus"))
+ {
+ iface = guest->create_iface(guest, "eth0");
+ if (iface)
+ {
+ switch1->connect_iface(switch1, iface);
+ }
+ }
+ else if (streq(guest->get_name(guest), "carol") ||
+ streq(guest->get_name(guest), "winnetou") ||
+ streq(guest->get_name(guest), "dave"))
+ {
+ iface = guest->create_iface(guest, "eth0");
+ if (iface)
+ {
+ switch0->connect_iface(switch0, iface);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGINT);
+ sigaddset(&set, SIGHUP);
+ sigaddset(&set, SIGTERM);
+ sigaddset(&set, SIGCHLD);
+ sigprocmask(SIG_SETMASK, &set, NULL);
+ while (running)
+ {
+ if (sigwaitinfo(&set, &info) == SIGCHLD)
+ {
+ enumerator = dumm->create_guest_enumerator(dumm);
+ while (enumerator->enumerate(enumerator, &guest))
+ {
+ if (guest->get_pid(guest) == info.si_pid)
+ {
+ running--;
+ guest->sigchild(guest);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ }
+ }
+ dumm->destroy(dumm);
+
+ library_deinit();
+ return 0;
+}
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index c7e9ca9ff..6aeb84bae 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -1,2 +1,3 @@
EXTRA_DIST = linux/ipsec.h linux/netlink.h linux/rtnetlink.h \
- linux/pfkeyv2.h linux/udp.h linux/xfrm.h
+ linux/pfkeyv2.h linux/udp.h linux/xfrm.h linux/types.h \
+ sys/queue.h
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index 2659b44ba..126713f12 100644
--- a/src/include/Makefile.in
+++ b/src/include/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.
@@ -61,6 +61,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -90,6 +91,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -120,7 +122,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@
@@ -131,12 +132,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@
@@ -146,12 +146,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@
@@ -164,10 +164,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@
@@ -175,7 +177,8 @@ top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
EXTRA_DIST = linux/ipsec.h linux/netlink.h linux/rtnetlink.h \
- linux/pfkeyv2.h linux/udp.h linux/xfrm.h
+ linux/pfkeyv2.h linux/udp.h linux/xfrm.h linux/types.h \
+ sys/queue.h
all: all-am
diff --git a/src/include/linux/pfkeyv2.h b/src/include/linux/pfkeyv2.h
index bac0fb389..4de9d7761 100644
--- a/src/include/linux/pfkeyv2.h
+++ b/src/include/linux/pfkeyv2.h
@@ -251,7 +251,8 @@ struct sadb_x_sec_ctx {
#define SADB_X_SPDEXPIRE 21
#define SADB_X_SPDDELETE2 22
#define SADB_X_NAT_T_NEW_MAPPING 23
-#define SADB_MAX 23
+#define SADB_X_MIGRATE 24
+#define SADB_MAX 24
/* Security Association flags */
#define SADB_SAFLAGS_PFS 1
@@ -285,6 +286,7 @@ struct sadb_x_sec_ctx {
#define SADB_X_AALG_SHA2_384HMAC 6
#define SADB_X_AALG_SHA2_512HMAC 7
#define SADB_X_AALG_RIPEMD160HMAC 8
+#define SADB_X_AALG_AES_XCBC_MAC 9
#define SADB_X_AALG_NULL 251 /* kame */
#define SADB_AALG_MAX 251
@@ -296,6 +298,7 @@ struct sadb_x_sec_ctx {
#define SADB_X_EALG_BLOWFISHCBC 7
#define SADB_EALG_NULL 11
#define SADB_X_EALG_AESCBC 12
+#define SADB_X_EALG_CAMELLIACBC 22
#define SADB_EALG_MAX 253 /* last EALG */
/* private allocations should use 249-255 (RFC2407) */
#define SADB_X_EALG_SERPENTCBC 252 /* draft-ietf-ipsec-ciph-aes-cbc-00 */
diff --git a/src/include/linux/types.h b/src/include/linux/types.h
new file mode 100644
index 000000000..22cfdc05e
--- /dev/null
+++ b/src/include/linux/types.h
@@ -0,0 +1,172 @@
+#ifndef _LINUX_TYPES_H
+#define _LINUX_TYPES_H
+
+
+#include <linux/posix_types.h>
+#include <asm/types.h>
+
+#ifndef __KERNEL_STRICT_NAMES
+
+typedef __u32 __kernel_dev_t;
+
+typedef __kernel_fd_set fd_set;
+typedef __kernel_dev_t dev_t;
+typedef __kernel_ino_t ino_t;
+typedef __kernel_mode_t mode_t;
+typedef __kernel_nlink_t nlink_t;
+typedef __kernel_off_t off_t;
+typedef __kernel_pid_t pid_t;
+typedef __kernel_daddr_t daddr_t;
+typedef __kernel_key_t key_t;
+typedef __kernel_suseconds_t suseconds_t;
+typedef __kernel_timer_t timer_t;
+typedef __kernel_clockid_t clockid_t;
+typedef __kernel_mqd_t mqd_t;
+
+typedef __kernel_uid_t uid_t;
+typedef __kernel_gid_t gid_t;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __kernel_loff_t loff_t;
+#endif
+
+/*
+ * The following typedefs are also protected by individual ifdefs for
+ * historical reasons:
+ */
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef __kernel_size_t size_t;
+#endif
+
+#ifndef _SSIZE_T
+#define _SSIZE_T
+typedef __kernel_ssize_t ssize_t;
+#endif
+
+#ifndef _PTRDIFF_T
+#define _PTRDIFF_T
+typedef __kernel_ptrdiff_t ptrdiff_t;
+#endif
+
+#ifndef _TIME_T
+#define _TIME_T
+typedef __kernel_time_t time_t;
+#endif
+
+#ifndef _CLOCK_T
+#define _CLOCK_T
+typedef __kernel_clock_t clock_t;
+#endif
+
+#ifndef _CADDR_T
+#define _CADDR_T
+typedef __kernel_caddr_t caddr_t;
+#endif
+
+/* bsd */
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+
+/* sysv */
+typedef unsigned char unchar;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+#ifndef __BIT_TYPES_DEFINED__
+#define __BIT_TYPES_DEFINED__
+
+typedef __u8 u_int8_t;
+typedef __s8 int8_t;
+typedef __u16 u_int16_t;
+typedef __s16 int16_t;
+typedef __u32 u_int32_t;
+typedef __s32 int32_t;
+
+#endif /* !(__BIT_TYPES_DEFINED__) */
+
+typedef __u8 uint8_t;
+typedef __u16 uint16_t;
+typedef __u32 uint32_t;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __u64 uint64_t;
+typedef __u64 u_int64_t;
+typedef __s64 int64_t;
+#endif
+
+/* this is a special 64bit data type that is 8-byte aligned */
+#define aligned_u64 unsigned long long __attribute__((aligned(8)))
+#define aligned_be64 __be64 __attribute__((aligned(8)))
+#define aligned_le64 __le64 __attribute__((aligned(8)))
+
+/**
+ * The type used for indexing onto a disc or disc partition.
+ *
+ * Linux always considers sectors to be 512 bytes long independently
+ * of the devices real block size.
+ */
+#ifdef CONFIG_LBD
+typedef u64 sector_t;
+#else
+typedef unsigned long sector_t;
+#endif
+
+/*
+ * The type of the inode's block count.
+ */
+#ifdef CONFIG_LSF
+typedef u64 blkcnt_t;
+#else
+typedef unsigned long blkcnt_t;
+#endif
+
+/*
+ * The type of an index into the pagecache. Use a #define so asm/types.h
+ * can override it.
+ */
+#ifndef pgoff_t
+#define pgoff_t unsigned long
+#endif
+
+#endif /* __KERNEL_STRICT_NAMES */
+
+/*
+ * Below are truly Linux-specific types that should never collide with
+ * any application/library that wants linux/types.h.
+ */
+
+#ifdef __CHECKER__
+#define __bitwise__ __attribute__((bitwise))
+#else
+#define __bitwise__
+#endif
+#ifdef __CHECK_ENDIAN__
+#define __bitwise __bitwise__
+#else
+#define __bitwise
+#endif
+
+typedef __u16 __bitwise __le16;
+typedef __u16 __bitwise __be16;
+typedef __u32 __bitwise __le32;
+typedef __u32 __bitwise __be32;
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __u64 __bitwise __le64;
+typedef __u64 __bitwise __be64;
+#endif
+typedef __u16 __bitwise __sum16;
+typedef __u32 __bitwise __wsum;
+
+
+struct ustat {
+ __kernel_daddr_t f_tfree;
+ __kernel_ino_t f_tinode;
+ char f_fname[6];
+ char f_fpack[6];
+};
+
+#endif /* _LINUX_TYPES_H */
diff --git a/src/include/linux/xfrm.h b/src/include/linux/xfrm.h
index 6b42cc474..e31b8c84f 100644
--- a/src/include/linux/xfrm.h
+++ b/src/include/linux/xfrm.h
@@ -12,8 +12,8 @@
*/
typedef union
{
- __u32 a4;
- __u32 a6[4];
+ __be32 a4;
+ __be32 a6[4];
} xfrm_address_t;
/* Ident of a specific xfrm_state. It is used on input to lookup
@@ -23,7 +23,7 @@ typedef union
struct xfrm_id
{
xfrm_address_t daddr;
- __u32 spi;
+ __be32 spi;
__u8 proto;
};
@@ -49,10 +49,10 @@ struct xfrm_selector
{
xfrm_address_t daddr;
xfrm_address_t saddr;
- __u16 dport;
- __u16 dport_mask;
- __u16 sport;
- __u16 sport_mask;
+ __be16 dport;
+ __be16 dport_mask;
+ __be16 sport;
+ __be16 sport_mask;
__u16 family;
__u8 prefixlen_d;
__u8 prefixlen_s;
@@ -91,8 +91,15 @@ struct xfrm_replay_state
};
struct xfrm_algo {
+ char alg_name[64];
+ unsigned int alg_key_len; /* in bits */
+ char alg_key[0];
+};
+
+struct xfrm_algo_aead {
char alg_name[64];
- int alg_key_len; /* in bits */
+ int alg_key_len; /* in bits */
+ int alg_icv_len; /* in bits */
char alg_key[0];
};
@@ -104,9 +111,17 @@ struct xfrm_stats {
enum
{
+ XFRM_POLICY_TYPE_MAIN = 0,
+ XFRM_POLICY_TYPE_SUB = 1,
+ XFRM_POLICY_TYPE_MAX = 2
+};
+
+enum
+{
XFRM_POLICY_IN = 0,
XFRM_POLICY_OUT = 1,
XFRM_POLICY_FWD = 2,
+ XFRM_POLICY_MASK = 3,
XFRM_POLICY_MAX = 3
};
@@ -118,6 +133,13 @@ enum
XFRM_SHARE_UNIQUE /* Use once */
};
+#define XFRM_MODE_TRANSPORT 0
+#define XFRM_MODE_TUNNEL 1
+#define XFRM_MODE_ROUTEOPTIMIZATION 2
+#define XFRM_MODE_IN_TRIGGER 3
+#define XFRM_MODE_BEET 4
+#define XFRM_MODE_MAX 5
+
/* Netlink configuration messages. */
enum {
XFRM_MSG_BASE = 0x10,
@@ -160,6 +182,22 @@ enum {
#define XFRM_MSG_NEWAE XFRM_MSG_NEWAE
XFRM_MSG_GETAE,
#define XFRM_MSG_GETAE XFRM_MSG_GETAE
+
+ XFRM_MSG_REPORT,
+#define XFRM_MSG_REPORT XFRM_MSG_REPORT
+
+ XFRM_MSG_MIGRATE,
+#define XFRM_MSG_MIGRATE XFRM_MSG_MIGRATE
+
+ XFRM_MSG_NEWSADINFO,
+#define XFRM_MSG_NEWSADINFO XFRM_MSG_NEWSADINFO
+ XFRM_MSG_GETSADINFO,
+#define XFRM_MSG_GETSADINFO XFRM_MSG_GETSADINFO
+
+ XFRM_MSG_NEWSPDINFO,
+#define XFRM_MSG_NEWSPDINFO XFRM_MSG_NEWSPDINFO
+ XFRM_MSG_GETSPDINFO,
+#define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO
__XFRM_MSG_MAX
};
#define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
@@ -193,8 +231,8 @@ struct xfrm_user_tmpl {
struct xfrm_encap_tmpl {
__u16 encap_type;
- __u16 encap_sport;
- __u16 encap_dport;
+ __be16 encap_sport;
+ __be16 encap_dport;
xfrm_address_t encap_oa;
};
@@ -213,6 +251,12 @@ enum xfrm_ae_ftype_t {
#define XFRM_AE_MAX (__XFRM_AE_MAX - 1)
};
+struct xfrm_userpolicy_type {
+ __u8 type;
+ __u16 reserved1;
+ __u8 reserved2;
+};
+
/* Netlink message attributes. */
enum xfrm_attr_type_t {
XFRMA_UNSPEC,
@@ -228,11 +272,54 @@ enum xfrm_attr_type_t {
XFRMA_REPLAY_VAL,
XFRMA_REPLAY_THRESH,
XFRMA_ETIMER_THRESH,
+ XFRMA_SRCADDR, /* xfrm_address_t */
+ XFRMA_COADDR, /* xfrm_address_t */
+ XFRMA_LASTUSED,
+ XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */
+ XFRMA_MIGRATE,
+ XFRMA_ALG_AEAD, /* struct xfrm_algo_aead */
__XFRMA_MAX
#define XFRMA_MAX (__XFRMA_MAX - 1)
};
+enum xfrm_sadattr_type_t {
+ XFRMA_SAD_UNSPEC,
+ XFRMA_SAD_CNT,
+ XFRMA_SAD_HINFO,
+ __XFRMA_SAD_MAX
+
+#define XFRMA_SAD_MAX (__XFRMA_SAD_MAX - 1)
+};
+
+struct xfrmu_sadhinfo {
+ __u32 sadhcnt; /* current hash bkts */
+ __u32 sadhmcnt; /* max allowed hash bkts */
+};
+
+enum xfrm_spdattr_type_t {
+ XFRMA_SPD_UNSPEC,
+ XFRMA_SPD_INFO,
+ XFRMA_SPD_HINFO,
+ __XFRMA_SPD_MAX
+
+#define XFRMA_SPD_MAX (__XFRMA_SPD_MAX - 1)
+};
+
+struct xfrmu_spdinfo {
+ __u32 incnt;
+ __u32 outcnt;
+ __u32 fwdcnt;
+ __u32 inscnt;
+ __u32 outscnt;
+ __u32 fwdscnt;
+};
+
+struct xfrmu_spdhinfo {
+ __u32 spdhcnt;
+ __u32 spdhmcnt;
+};
+
struct xfrm_usersa_info {
struct xfrm_selector sel;
struct xfrm_id id;
@@ -243,24 +330,28 @@ struct xfrm_usersa_info {
__u32 seq;
__u32 reqid;
__u16 family;
- __u8 mode; /* 0=transport,1=tunnel */
+ __u8 mode; /* XFRM_MODE_xxx */
__u8 replay_window;
__u8 flags;
#define XFRM_STATE_NOECN 1
#define XFRM_STATE_DECAP_DSCP 2
#define XFRM_STATE_NOPMTUDISC 4
+#define XFRM_STATE_WILDRECV 8
+#define XFRM_STATE_ICMP 16
};
struct xfrm_usersa_id {
xfrm_address_t daddr;
- __u32 spi;
+ __be32 spi;
__u16 family;
__u8 proto;
};
struct xfrm_aevent_id {
struct xfrm_usersa_id sa_id;
+ xfrm_address_t saddr;
__u32 flags;
+ __u32 reqid;
};
struct xfrm_userspi_info {
@@ -281,6 +372,8 @@ struct xfrm_userpolicy_info {
#define XFRM_POLICY_BLOCK 1
__u8 flags;
#define XFRM_POLICY_LOCALOK 1 /* Allow user to override global policy */
+ /* Automatically expand selector to include matching ICMP payloads. */
+#define XFRM_POLICY_ICMP 2
__u8 share;
};
@@ -315,12 +408,31 @@ struct xfrm_usersa_flush {
__u8 proto;
};
+struct xfrm_user_report {
+ __u8 proto;
+ struct xfrm_selector sel;
+};
+
+struct xfrm_user_migrate {
+ xfrm_address_t old_daddr;
+ xfrm_address_t old_saddr;
+ xfrm_address_t new_daddr;
+ xfrm_address_t new_saddr;
+ __u8 proto;
+ __u8 mode;
+ __u16 reserved;
+ __u32 reqid;
+ __u16 old_family;
+ __u16 new_family;
+};
+
#ifndef __KERNEL__
/* backwards compatibility for userspace */
#define XFRMGRP_ACQUIRE 1
#define XFRMGRP_EXPIRE 2
#define XFRMGRP_SA 4
#define XFRMGRP_POLICY 8
+#define XFRMGRP_REPORT 0x20
#endif
enum xfrm_nlgroups {
@@ -336,6 +448,10 @@ enum xfrm_nlgroups {
#define XFRMNLGRP_POLICY XFRMNLGRP_POLICY
XFRMNLGRP_AEVENTS,
#define XFRMNLGRP_AEVENTS XFRMNLGRP_AEVENTS
+ XFRMNLGRP_REPORT,
+#define XFRMNLGRP_REPORT XFRMNLGRP_REPORT
+ XFRMNLGRP_MIGRATE,
+#define XFRMNLGRP_MIGRATE XFRMNLGRP_MIGRATE
__XFRMNLGRP_MAX
};
#define XFRMNLGRP_MAX (__XFRMNLGRP_MAX - 1)
diff --git a/src/include/sys/queue.h b/src/include/sys/queue.h
new file mode 100644
index 000000000..b0e6b38c1
--- /dev/null
+++ b/src/include/sys/queue.h
@@ -0,0 +1,557 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define _SYS_QUEUE_H_
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * lists, simple queues, tail queues, and circular queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The
+ * elements are singly linked for minimum space and pointer manipulation
+ * overhead at the expense of O(n) removal for arbitrary elements. New
+ * elements can be added to the list after an existing element or at the
+ * head of the list. Elements being removed from the head of the list
+ * should use the explicit macro for this purpose for optimum
+ * efficiency. A singly-linked list may only be traversed in the forward
+ * direction. Singly-linked lists are ideal for applications with large
+ * datasets and few or no removals or for implementing a LIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A simple queue is headed by a pair of pointers, one the head of the
+ * list and the other to the tail of the list. The elements are singly
+ * linked to save space, so elements can only be removed from the
+ * head of the list. New elements can be added to the list after
+ * an existing element, at the head of the list, or at the end of the
+ * list. A simple queue may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+/*
+ * List definitions.
+ */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List functions.
+ */
+#define LIST_INIT(head) do { \
+ (head)->lh_first = NULL; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ (elm)->field.le_next = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &(elm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_REMOVE(elm, field) do { \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_FOREACH(var, head, field) \
+ for ((var) = ((head)->lh_first); \
+ (var); \
+ (var) = ((var)->field.le_next))
+
+/*
+ * List access methods.
+ */
+#define LIST_EMPTY(head) ((head)->lh_first == NULL)
+#define LIST_FIRST(head) ((head)->lh_first)
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+
+/*
+ * Singly-linked List definitions.
+ */
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_INIT(head) do { \
+ (head)->slh_first = NULL; \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ (elm)->field.sle_next = (slistelm)->field.sle_next; \
+ (slistelm)->field.sle_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.sle_next = (head)->slh_first; \
+ (head)->slh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ (head)->slh_first = (head)->slh_first->field.sle_next; \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_REMOVE(head, elm, type, field) do { \
+ if ((head)->slh_first == (elm)) { \
+ SLIST_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = (head)->slh_first; \
+ while(curelm->field.sle_next != (elm)) \
+ curelm = curelm->field.sle_next; \
+ curelm->field.sle_next = \
+ curelm->field.sle_next->field.sle_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_FOREACH(var, head, field) \
+ for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
+
+/*
+ * Singly-linked List access methods.
+ */
+#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
+#define SLIST_FIRST(head) ((head)->slh_first)
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define STAILQ_HEAD(name, type) \
+struct name { \
+ struct type *stqh_first; /* first element */ \
+ struct type **stqh_last; /* addr of last next element */ \
+}
+
+#define STAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).stqh_first }
+
+#define STAILQ_ENTRY(type) \
+struct { \
+ struct type *stqe_next; /* next element */ \
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define STAILQ_INIT(head) do { \
+ (head)->stqh_first = NULL; \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (head)->stqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.stqe_next = NULL; \
+ *(head)->stqh_last = (elm); \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (listelm)->field.stqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_REMOVE_HEAD(head, field) do { \
+ if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_REMOVE(head, elm, type, field) do { \
+ if ((head)->stqh_first == (elm)) { \
+ STAILQ_REMOVE_HEAD((head), field); \
+ } else { \
+ struct type *curelm = (head)->stqh_first; \
+ while (curelm->field.stqe_next != (elm)) \
+ curelm = curelm->field.stqe_next; \
+ if ((curelm->field.stqe_next = \
+ curelm->field.stqe_next->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(curelm)->field.stqe_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->stqh_first); \
+ (var); \
+ (var) = ((var)->field.stqe_next))
+
+/*
+ * Singly-linked Tail queue access methods.
+ */
+#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
+#define STAILQ_FIRST(head) ((head)->stqh_first)
+#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
+
+
+/*
+ * Simple queue definitions.
+ */
+#define SIMPLEQ_HEAD(name, type) \
+struct name { \
+ struct type *sqh_first; /* first element */ \
+ struct type **sqh_last; /* addr of last next element */ \
+}
+
+#define SIMPLEQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).sqh_first }
+
+#define SIMPLEQ_ENTRY(type) \
+struct { \
+ struct type *sqe_next; /* next element */ \
+}
+
+/*
+ * Simple queue functions.
+ */
+#define SIMPLEQ_INIT(head) do { \
+ (head)->sqh_first = NULL; \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (head)->sqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.sqe_next = NULL; \
+ *(head)->sqh_last = (elm); \
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
+ (head)->sqh_last = &(elm)->field.sqe_next; \
+ (listelm)->field.sqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
+ if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
+ (head)->sqh_last = &(head)->sqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
+ if ((head)->sqh_first == (elm)) { \
+ SIMPLEQ_REMOVE_HEAD((head), field); \
+ } else { \
+ struct type *curelm = (head)->sqh_first; \
+ while (curelm->field.sqe_next != (elm)) \
+ curelm = curelm->field.sqe_next; \
+ if ((curelm->field.sqe_next = \
+ curelm->field.sqe_next->field.sqe_next) == NULL) \
+ (head)->sqh_last = &(curelm)->field.sqe_next; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->sqh_first); \
+ (var); \
+ (var) = ((var)->field.sqe_next))
+
+/*
+ * Simple queue access methods.
+ */
+#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
+#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
+#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
+
+
+/*
+ * Tail queue definitions.
+ */
+#define _TAILQ_HEAD(name, type, qual) \
+struct name { \
+ qual type *tqh_first; /* first element */ \
+ qual type *qual *tqh_last; /* addr of last next element */ \
+}
+#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first }
+
+#define _TAILQ_ENTRY(type, qual) \
+struct { \
+ qual type *tqe_next; /* next element */ \
+ qual type *qual *tqe_prev; /* address of previous next element */\
+}
+#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
+
+/*
+ * Tail queue functions.
+ */
+#define TAILQ_INIT(head) do { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->tqh_first); \
+ (var); \
+ (var) = ((var)->field.tqe_next))
+
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
+ (var); \
+ (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+
+/*
+ * Tail queue access methods.
+ */
+#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+
+/*
+ * Circular queue definitions.
+ */
+#define CIRCLEQ_HEAD(name, type) \
+struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+}
+
+#define CIRCLEQ_HEAD_INITIALIZER(head) \
+ { (void *)&head, (void *)&head }
+
+#define CIRCLEQ_ENTRY(type) \
+struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+}
+
+/*
+ * Circular queue functions.
+ */
+#define CIRCLEQ_INIT(head) do { \
+ (head)->cqh_first = (void *)(head); \
+ (head)->cqh_last = (void *)(head); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm)->field.cqe_next; \
+ (elm)->field.cqe_prev = (listelm); \
+ if ((listelm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (listelm)->field.cqe_next->field.cqe_prev = (elm); \
+ (listelm)->field.cqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm); \
+ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
+ if ((listelm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (listelm)->field.cqe_prev->field.cqe_next = (elm); \
+ (listelm)->field.cqe_prev = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.cqe_next = (head)->cqh_first; \
+ (elm)->field.cqe_prev = (void *)(head); \
+ if ((head)->cqh_last == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (head)->cqh_first->field.cqe_prev = (elm); \
+ (head)->cqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.cqe_next = (void *)(head); \
+ (elm)->field.cqe_prev = (head)->cqh_last; \
+ if ((head)->cqh_first == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (head)->cqh_last->field.cqe_next = (elm); \
+ (head)->cqh_last = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_REMOVE(head, elm, field) do { \
+ if ((elm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm)->field.cqe_prev; \
+ else \
+ (elm)->field.cqe_next->field.cqe_prev = \
+ (elm)->field.cqe_prev; \
+ if ((elm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm)->field.cqe_next; \
+ else \
+ (elm)->field.cqe_prev->field.cqe_next = \
+ (elm)->field.cqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->cqh_first); \
+ (var) != (const void *)(head); \
+ (var) = ((var)->field.cqe_next))
+
+#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
+ for ((var) = ((head)->cqh_last); \
+ (var) != (const void *)(head); \
+ (var) = ((var)->field.cqe_prev))
+
+/*
+ * Circular queue access methods.
+ */
+#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
+#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
+#define CIRCLEQ_LAST(head) ((head)->cqh_last)
+#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
+#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
+
+#define CIRCLEQ_LOOP_NEXT(head, elm, field) \
+ (((elm)->field.cqe_next == (void *)(head)) \
+ ? ((head)->cqh_first) \
+ : (elm->field.cqe_next))
+#define CIRCLEQ_LOOP_PREV(head, elm, field) \
+ (((elm)->field.cqe_prev == (void *)(head)) \
+ ? ((head)->cqh_last) \
+ : (elm->field.cqe_prev))
+
+#endif /* sys/queue.h */
diff --git a/src/ipsec/Makefile.in b/src/ipsec/Makefile.in
index b11c73060..d50ae90f4 100644
--- a/src/ipsec/Makefile.in
+++ b/src/ipsec/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.
@@ -69,6 +69,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -98,6 +99,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -128,7 +130,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@
@@ -139,12 +140,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@
@@ -154,12 +154,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@
@@ -172,10 +172,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@
diff --git a/src/libcrypto/Makefile.in b/src/libcrypto/Makefile.in
index ecfca64c4..274f7986f 100644
--- a/src/libcrypto/Makefile.in
+++ b/src/libcrypto/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.
@@ -88,6 +88,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -117,6 +118,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -147,7 +149,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@
@@ -158,12 +159,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@
@@ -173,12 +173,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@
@@ -191,10 +191,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@
@@ -562,8 +564,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -575,8 +577,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -586,13 +588,12 @@ ctags: CTAGS
CTAGS: $(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
diff --git a/src/libcrypto/libaes/aes_cbc.c b/src/libcrypto/libaes/aes_cbc.c
index 962dd1a35..c406b1622 100644
--- a/src/libcrypto/libaes/aes_cbc.c
+++ b/src/libcrypto/libaes/aes_cbc.c
@@ -6,8 +6,8 @@
#include "aes_cbc.h"
#include "cbc_generic.h"
/* returns bool success */
-int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
+int SS_AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
aes_set_key(aes_ctx, key, keysize, 0);
return 1;
}
-CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
+CBC_IMPL_BLK16(SS_AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
diff --git a/src/libcrypto/libaes/aes_cbc.h b/src/libcrypto/libaes/aes_cbc.h
index 92f5d77f5..65015da6e 100644
--- a/src/libcrypto/libaes/aes_cbc.h
+++ b/src/libcrypto/libaes/aes_cbc.h
@@ -1,4 +1,4 @@
/* Glue header */
#include "aes.h"
-int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize);
-int AES_cbc_encrypt(aes_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt);
+int SS_AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize);
+int SS_AES_cbc_encrypt(aes_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt);
diff --git a/src/libfast/Makefile.am b/src/libfast/Makefile.am
new file mode 100644
index 000000000..6104f335d
--- /dev/null
+++ b/src/libfast/Makefile.am
@@ -0,0 +1,8 @@
+lib_LTLIBRARIES = libfast.la
+
+libfast_la_SOURCES = context.h dispatcher.c request.h session.h \
+ controller.h dispatcher.h request.c session.c filter.h
+libfast_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ -lfcgi -lpthread -lneo_cgi -lneo_cs -lneo_utl -lz
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I/usr/include/ClearSilver
+AM_CFLAGS = -rdynamic
diff --git a/src/libfast/Makefile.in b/src/libfast/Makefile.in
new file mode 100644
index 000000000..5a1ab491e
--- /dev/null
+++ b/src/libfast/Makefile.in
@@ -0,0 +1,497 @@
+# 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/libfast
+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)$(libdir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libfast_la_DEPENDENCIES = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+am_libfast_la_OBJECTS = dispatcher.lo request.lo session.lo
+libfast_la_OBJECTS = $(am_libfast_la_OBJECTS)
+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 = $(libfast_la_SOURCES)
+DIST_SOURCES = $(libfast_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@
+lib_LTLIBRARIES = libfast.la
+libfast_la_SOURCES = context.h dispatcher.c request.h session.h \
+ controller.h dispatcher.h request.c session.c filter.h
+
+libfast_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ -lfcgi -lpthread -lneo_cgi -lneo_cs -lneo_utl -lz
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I/usr/include/ClearSilver
+AM_CFLAGS = -rdynamic
+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/libfast/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libfast/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-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libfast.la: $(libfast_la_OBJECTS) $(libfast_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libfast_la_OBJECTS) $(libfast_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dispatcher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/request.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.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)$(libdir)"; 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-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-libLTLIBRARIES
+
+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-libLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-libLTLIBRARIES
+
+# 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/manager/lib/context.h b/src/libfast/context.h
index 23c979b8e..dc1450bd1 100644
--- a/src/manager/lib/context.h
+++ b/src/libfast/context.h
@@ -1,10 +1,3 @@
-/**
- * @file context.h
- *
- * @brief Interface of context_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: context.h 3489 2008-02-22 09:40:58Z martin $
+ */
+
+/**
+ * @defgroup context context
+ * @{ @ingroup libfast
*/
#ifndef CONTEXT_H_
@@ -26,22 +26,19 @@
typedef struct context_t context_t;
/**
- * @brief Constructor function for a context
+ * Constructor function for a user specific context.
*/
typedef context_t *(*context_constructor_t)(void *param);
/**
- * @brief Custom session context
- *
+ * User specific session context, to extend.
*/
struct context_t {
/**
- * @brief Destroy the context_t.
- *
- * @param this calling object
+ * Destroy the context_t.
*/
void (*destroy) (context_t *this);
};
-#endif /* CONTEXT_H_ */
+#endif /* CONTEXT_H_ @}*/
diff --git a/src/manager/lib/controller.h b/src/libfast/controller.h
index 5b39f559c..162e114e3 100644
--- a/src/manager/lib/controller.h
+++ b/src/libfast/controller.h
@@ -1,10 +1,3 @@
-/**
- * @file controller.h
- *
- * @brief Interface controller_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: controller.h 3489 2008-02-22 09:40:58Z martin $
+ */
+
+/**
+ * @defgroup controller_i controller
+ * @{ @ingroup libfast
*/
#ifndef CONTROLLER_H_
@@ -29,36 +29,31 @@
typedef struct controller_t controller_t;
/**
- * @brief Controller action handle function
- *
- * @param request http request
- * @param response http response
- */
-typedef void *(*controller_handler_t)(controller_t *this, request_t *request);
-
-/**
- * @brief Constructor function for a controller
+ * Constructor function for a controller.
*
- * @param context session specific context
- * @param param user supplied param
+ * @param context session specific context, implements context_t
+ * @param param user supplied param, as registered to the dispatcher
*/
typedef controller_t *(*controller_constructor_t)(context_t* context, void *param);
/**
- * @brief Controller interface, to be implemented by users controllers.
+ * Controller interface, to be implemented by users controllers.
*
+ * Controller instances get created per session, so each session has an
+ * associated set of private controller instances.
+ * The controller handle function is called for each incoming request.
*/
struct controller_t {
/**
- * @brief Get the name of the controller.
+ * Get the name of the controller.
*
* @return name of the controller
*/
char* (*get_name)(controller_t *this);
/**
- * @brief Handle a HTTP request for that controller.
+ * Handle a HTTP request for that controller.
*
* Request URLs are parsed in the form
* controller_name/p1/p2/p3/p4/p5 with a maximum of 5 parameters. Each
@@ -73,12 +68,12 @@ struct controller_t {
* @return
*/
void (*handle)(controller_t *this, request_t *request,
- char *a1, char *a2, char *a3, char *a4, char *a5);
+ char *p1, char *p2, char *p3, char *p4, char *p5);
/**
- * @brief Destroy the controller instance.
+ * Destroy the controller instance.
*/
void (*destroy) (controller_t *this);
};
-#endif /* CONTROLLER_H_ */
+#endif /* CONTROLLER_H_ @} */
diff --git a/src/manager/lib/dispatcher.c b/src/libfast/dispatcher.c
index ce53d39ea..e87fd246f 100644
--- a/src/manager/lib/dispatcher.c
+++ b/src/libfast/dispatcher.c
@@ -1,10 +1,3 @@
-/**
- * @file dispatcher.c
- *
- * @brief Implementation of dispatcher_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: dispatcher.c 3672 2008-03-27 10:24:37Z martin $
*/
#include "dispatcher.h"
@@ -76,39 +71,29 @@ struct private_dispatcher_t {
time_t timeout;
/**
- * List of controllers controller_constructor_t
+ * running in debug mode?
*/
- linked_list_t *controllers;
-
- /**
- * constructor function to create session context (in constructor_entry_t)
- */
- context_constructor_t context_constructor;
+ bool debug;
/**
- * user param to context constructor
- */
- void *param;
-
- /**
- * thread specific initialization handler
+ * List of controllers controller_constructor_t
*/
- void (*init)(void *param);
+ linked_list_t *controllers;
/**
- * argument to pass to thread intiializer
+ * List of filters filter_constructor_t
*/
- void *init_param;
+ linked_list_t *filters;
- /**
- * thread specific deinitialization handler
+ /**
+ * constructor function to create session context (in controller_entry_t)
*/
- void (*deinit)(void *param);
+ context_constructor_t context_constructor;
/**
- * param tho thread specific deinitialization handler
+ * user param to context constructor
*/
- void *deinit_param;
+ void *param;
};
typedef struct {
@@ -116,17 +101,28 @@ typedef struct {
controller_constructor_t constructor;
/** parameter to constructor */
void *param;
-} constructor_entry_t;
+} controller_entry_t;
+
+typedef struct {
+ /** constructor function */
+ filter_constructor_t constructor;
+ /** parameter to constructor */
+ void *param;
+} filter_entry_t;
typedef struct {
/** session instance */
session_t *session;
/** condvar to wait for session */
pthread_cond_t cond;
+ /** client host address, to prevent session hijacking */
+ char *host;
/** TRUE if session is in use */
bool in_use;
/** last use of the session */
time_t used;
+ /** has the session been closed by the handler? */
+ bool closed;
} session_entry_t;
/**
@@ -135,10 +131,12 @@ typedef struct {
static session_t* load_session(private_dispatcher_t *this)
{
iterator_t *iterator;
- constructor_entry_t *entry;
+ controller_entry_t *centry;
+ filter_entry_t *fentry;
session_t *session;
context_t *context = NULL;
controller_t *controller;
+ filter_t *filter;
if (this->context_constructor)
{
@@ -147,28 +145,39 @@ static session_t* load_session(private_dispatcher_t *this)
session = session_create(context);
iterator = this->controllers->create_iterator(this->controllers, TRUE);
- while (iterator->iterate(iterator, (void**)&entry))
+ while (iterator->iterate(iterator, (void**)&centry))
{
- controller = entry->constructor(context, entry->param);
+ controller = centry->constructor(context, centry->param);
session->add_controller(session, controller);
}
iterator->destroy(iterator);
+ iterator = this->filters->create_iterator(this->filters, TRUE);
+ while (iterator->iterate(iterator, (void**)&fentry))
+ {
+ filter = fentry->constructor(context, fentry->param);
+ session->add_filter(session, filter);
+ }
+ iterator->destroy(iterator);
+
return session;
}
/**
* create a new session entry
*/
-static session_entry_t *session_entry_create(private_dispatcher_t *this)
+static session_entry_t *session_entry_create(private_dispatcher_t *this,
+ char *host)
{
session_entry_t *entry;
entry = malloc_thing(session_entry_t);
entry->in_use = FALSE;
+ entry->closed = FALSE;
pthread_cond_init(&entry->cond, NULL);
entry->session = load_session(this);
entry->used = time(NULL);
+ entry->host = strdup(host);
return entry;
}
@@ -176,6 +185,7 @@ static session_entry_t *session_entry_create(private_dispatcher_t *this)
static void session_entry_destroy(session_entry_t *entry)
{
entry->session->destroy(entry->session);
+ free(entry->host);
free(entry);
}
@@ -185,7 +195,7 @@ static void session_entry_destroy(session_entry_t *entry)
static void add_controller(private_dispatcher_t *this,
controller_constructor_t constructor, void *param)
{
- constructor_entry_t *entry = malloc_thing(constructor_entry_t);
+ controller_entry_t *entry = malloc_thing(controller_entry_t);
entry->constructor = constructor;
entry->param = param;
@@ -193,143 +203,111 @@ static void add_controller(private_dispatcher_t *this,
}
/**
+ * Implementation of dispatcher_t.add_filter.
+ */
+static void add_filter(private_dispatcher_t *this,
+ filter_constructor_t constructor, void *param)
+{
+ filter_entry_t *entry = malloc_thing(filter_entry_t);
+
+ entry->constructor = constructor;
+ entry->param = param;
+ this->filters->insert_last(this->filters, entry);
+}
+
+/**
* Actual dispatching code
*/
static void dispatch(private_dispatcher_t *this)
{
- FCGX_Request fcgi_req;
-
- if (FCGX_InitRequest(&fcgi_req, this->fd, 0) == 0)
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+ while (TRUE)
{
- while (TRUE)
+ request_t *request;
+ session_entry_t *current, *found = NULL;
+ iterator_t *iterator;
+ time_t now;
+ char *sid;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ request = request_create(this->fd, this->debug);
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+ if (request == NULL)
{
- request_t *request;
- session_entry_t *current, *found = NULL;
- iterator_t *iterator;
- time_t now;
- char *sid;
- int accepted;
-
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
- accepted = FCGX_Accept_r(&fcgi_req);
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
-
- if (accepted != 0)
- {
- break;
- }
-
- /* prepare */
- request = request_create(&fcgi_req, TRUE);
- if (request == NULL)
+ continue;
+ }
+ sid = request->get_cookie(request, "SID");
+ now = time(NULL);
+
+ /* find session */
+ pthread_mutex_lock(&this->mutex);
+ iterator = this->sessions->create_iterator(this->sessions, TRUE);
+ while (iterator->iterate(iterator, (void**)&current))
+ {
+ /* check all sessions for timeout or close flag
+ * TODO: use a seperate cleanup thread */
+ if (!current->in_use &&
+ (current->used < now - this->timeout || current->closed))
{
+ iterator->remove(iterator);
+ session_entry_destroy(current);
continue;
}
- sid = request->get_cookie(request, "SID");
- now = time(NULL);
-
- /* find session */
- pthread_mutex_lock(&this->mutex);
- iterator = this->sessions->create_iterator(this->sessions, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ /* find by session ID. Prevent session hijacking by host check */
+ if (!found && sid &&
+ streq(current->session->get_sid(current->session), sid) &&
+ streq(current->host, request->get_host(request)))
{
- /* check all sessions for timeout */
- if (!current->in_use &&
- current->used < now - this->timeout)
- {
- iterator->remove(iterator);
- session_entry_destroy(current);
- continue;
- }
- if (!found && sid &&
- streq(current->session->get_sid(current->session), sid))
- {
- found = current;
- }
+ found = current;
}
- iterator->destroy(iterator);
-
- if (found)
- { /* wait until session is unused */
- while (found->in_use)
- {
- pthread_cond_wait(&found->cond, &this->mutex);
- }
- }
- else
- { /* create a new session if not found */
- found = session_entry_create(this);
- this->sessions->insert_first(this->sessions, found);
- }
- found->in_use = TRUE;
- pthread_mutex_unlock(&this->mutex);
+ }
+ iterator->destroy(iterator);
- /* start processing */
- found->session->process(found->session, request);
- found->used = time(NULL);
-
- /* release session */
- pthread_mutex_lock(&this->mutex);
- found->in_use = FALSE;
- pthread_cond_signal(&found->cond);
- pthread_mutex_unlock(&this->mutex);
-
- /* cleanup */
- request->destroy(request);
-
- /*
- FCGX_FPrintF(fcgi_req.out, "<ul>");
- char **env = fcgi_req.envp;
- while (*env)
- {
- FCGX_FPrintF(fcgi_req.out, "<li>%s</li>", *env);
- env++;
- }
- FCGX_FPrintF(fcgi_req.out, "</ul>");
- */
+ if (found)
+ {
+ /* wait until session is unused */
+ while (found->in_use)
+ {
+ pthread_cond_wait(&found->cond, &this->mutex);
+ }
}
- }
-}
-
-/**
- * Setup thread and start dispatching
- */
-static void start_dispatching(private_dispatcher_t *this)
-{
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
- if (this->init)
- {
- this->init(this->init_param);
- }
- if (this->deinit)
- {
- pthread_cleanup_push(this->deinit, this->deinit_param);
- dispatch(this);
- pthread_cleanup_pop(1);
- }
- else
- {
- dispatch(this);
+ else
+ { /* create a new session if not found */
+ found = session_entry_create(this, request->get_host(request));
+ this->sessions->insert_first(this->sessions, found);
+ }
+ found->in_use = TRUE;
+ pthread_mutex_unlock(&this->mutex);
+
+ /* start processing */
+ found->session->process(found->session, request);
+ found->used = time(NULL);
+
+ /* release session */
+ pthread_mutex_lock(&this->mutex);
+ found->in_use = FALSE;
+ found->closed = request->session_closed(request);
+ pthread_cond_signal(&found->cond);
+ pthread_mutex_unlock(&this->mutex);
+
+ /* cleanup */
+ request->destroy(request);
}
}
/**
* Implementation of dispatcher_t.run.
*/
-static void run(private_dispatcher_t *this, int threads,
- void(*init)(void *param), void *init_param,
- void(*deinit)(void *param), void *deinit_param)
+static void run(private_dispatcher_t *this, int threads)
{
- this->init = init;
- this->init_param = init_param;
- this->deinit = deinit;
- this->deinit_param = deinit_param;
this->thread_count = threads;
this->threads = malloc(sizeof(pthread_t) * threads);
while (threads)
{
if (pthread_create(&this->threads[threads - 1],
- NULL, (void*)start_dispatching, this) == 0)
+ NULL, (void*)dispatch, this) == 0)
{
threads--;
}
@@ -365,29 +343,35 @@ static void destroy(private_dispatcher_t *this)
}
this->sessions->destroy_function(this->sessions, (void*)session_entry_destroy);
this->controllers->destroy_function(this->controllers, free);
+ this->filters->destroy_function(this->filters, free);
+ free(this->threads);
free(this);
}
/*
* see header file
*/
-dispatcher_t *dispatcher_create(char *socket, int timeout,
+dispatcher_t *dispatcher_create(char *socket, bool debug, int timeout,
context_constructor_t constructor, void *param)
{
private_dispatcher_t *this = malloc_thing(private_dispatcher_t);
this->public.add_controller = (void(*)(dispatcher_t*, controller_constructor_t, void*))add_controller;
- this->public.run = (void(*)(dispatcher_t*, int threads,void(*)(void *),void *,void(*)(void *),void *))run;
+ this->public.add_filter = (void(*)(dispatcher_t*,filter_constructor_t constructor, void *param))add_filter;
+ this->public.run = (void(*)(dispatcher_t*, int threads))run;
this->public.waitsignal = (void(*)(dispatcher_t*))waitsignal;
this->public.destroy = (void(*)(dispatcher_t*))destroy;
this->sessions = linked_list_create();
this->controllers = linked_list_create();
+ this->filters = linked_list_create();
this->context_constructor = constructor;
pthread_mutex_init(&this->mutex, NULL);
this->param = param;
this->fd = 0;
this->timeout = timeout;
+ this->debug = debug;
+ this->threads = NULL;
FCGX_Init();
diff --git a/src/libfast/dispatcher.h b/src/libfast/dispatcher.h
new file mode 100644
index 000000000..98a7b7e30
--- /dev/null
+++ b/src/libfast/dispatcher.h
@@ -0,0 +1,139 @@
+/*
+ * 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: dispatcher.h 3519 2008-03-02 12:14:34Z martin $
+ */
+
+/**
+ * @defgroup libfast libfast
+ * @{
+ * FastCGI Application Server w/ templates.
+ *
+ * Libfast is a framework to write web applications in an MVC fashion. It uses
+ * the ClearSilver template engine and communicates through FastCGI with
+ * the webserver. It is multithreaded and really fast.
+ *
+ * The application has a global context and a session context. The global
+ * context is accessed from all sessions simultaneously and therefore
+ * needs to be threadsave. Often a database wrapper is the global context.
+ * The session context is instanciated per session. Sessions are managed
+ * automatically through session cookies. The session context is kept alive
+ * until the session times out. It must implement the context_t interface and
+ * a #context_constructor_t is needed to create instances. To each session,
+ * a set of controllers gets instanciated. The controller instances are per
+ * session, so you can hold private data for each user.
+ * Controllers need to implement the controller_t interface and need a
+ * #controller_constructor_t function to create instances.
+ *
+ * A small example shows how to set up libfast:
+ * @code
+ dispatcher_t *dispatcher;
+ your_global_context_implementation_t *global;
+
+ global = initialize_your_global_context();
+
+ dispatcher = dispatcher_create(NULL, FALSE, 180,
+ (context_constructor_t)your_session_context_create, global);
+ dispatcher->add_controller(dispatcher, your_controller1_create, param1);
+ dispatcher->add_controller(dispatcher, your_controller2_create, param2);
+
+ dispatcher->run(dispatcher, 20);
+
+ dispatcher->waitsignal(dispatcher);
+
+ dispatcher->destroy(dispatcher);
+ global->destroy();
+ @endcode
+ * @}
+ *
+ * @defgroup dispatcher dispatcher
+ * @{ @ingroup libfast
+ */
+
+#ifndef DISPATCHER_H_
+#define DISPATCHER_H_
+
+#include "controller.h"
+#include "filter.h"
+
+typedef struct dispatcher_t dispatcher_t;
+
+/**
+ * Dispatcher, accepts connections using multiple threads.
+ *
+ * The dispatcher creates a session for each client (using SID cookies). In
+ * each session, a session context is created using the context constructor.
+ * Each controller is instanciated in the session using the controller
+ * constructor added with add_controller.
+ */
+struct dispatcher_t {
+
+ /**
+ * Register a controller to the dispatcher.
+ *
+ * The first controller added serves as default controller. Client's
+ * get redirected to it if no other controller matches.
+ *
+ * @param constructor constructor function to the conntroller
+ * @param param param to pass to constructor
+ */
+ void (*add_controller)(dispatcher_t *this,
+ controller_constructor_t constructor, void *param);
+
+ /**
+ * @brief Add a filter to the dispatcher.
+ *
+ * @param constructor constructor to create filter in session
+ * @param param param to pass to constructor
+ */
+ void (*add_filter)(dispatcher_t *this,
+ filter_constructor_t constructor, void *param);
+
+ /**
+ * Start with dispatching.
+ *
+ * Instanciate a constant thread pool and start dispatching requests.
+ *
+ * @param threads number of dispatching threads
+ */
+ void (*run)(dispatcher_t *this, int threads);
+
+ /**
+ * Wait for a relevant signal action.
+ *
+ */
+ void (*waitsignal)(dispatcher_t *this);
+
+ /**
+ * Destroy the dispatcher_t.
+ */
+ void (*destroy) (dispatcher_t *this);
+};
+
+/**
+ * Create a dispatcher.
+ *
+ * The context constructor is invoked to create a session context for
+ * each session.
+ *
+ * @param socket FastCGI socket path, NULL for dynamic
+ * @param debug no stripping, no compression, timing information
+ * @param timeout session timeout
+ * @param constructor construction function for session context
+ * @param param parameter to supply to context constructor
+ */
+dispatcher_t *dispatcher_create(char *socket, bool debug, int timeout,
+ context_constructor_t constructor, void *param);
+
+#endif /* DISPATCHER_H_ @} */
diff --git a/src/libfast/filter.h b/src/libfast/filter.h
new file mode 100644
index 000000000..614a2ef58
--- /dev/null
+++ b/src/libfast/filter.h
@@ -0,0 +1,65 @@
+/*
+ * 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 filter filter
+ * @{ @ingroup libfast
+ */
+
+#ifndef FILTER_H_
+#define FILTER_H_
+
+#include "request.h"
+#include "context.h"
+#include "controller.h"
+
+typedef struct filter_t filter_t;
+
+/**
+ * Constructor function for a filter
+ *
+ * @param context session specific context
+ * @param param user supplied param
+ */
+typedef filter_t *(*filter_constructor_t)(context_t* context, void *param);
+
+/**
+ * Filter interface, to be implemented by users filters.
+ */
+struct filter_t {
+
+ /**
+ * Called before the controller handles the request.
+ *
+ * @param request HTTP request
+ * @param p1 first parameter
+ * @param p2 second parameter
+ * @param p3 third parameter
+ * @param p4 forth parameter
+ * @param p5 fifth parameter
+ * @return TRUE to continue request handling
+ */
+ bool (*run)(filter_t *this, request_t *request,
+ char *p0, char *p1, char *p2, char *p3, char *p4, char *p5);
+
+ /**
+ * Destroy the filter instance.
+ */
+ void (*destroy) (filter_t *this);
+};
+
+#endif /* FILTER_H_ @} */
diff --git a/src/manager/lib/request.c b/src/libfast/request.c
index bbaec10cc..ec022d41e 100644
--- a/src/manager/lib/request.c
+++ b/src/libfast/request.c
@@ -1,10 +1,3 @@
-/**
- * @file request.c
- *
- * @brief Implementation of request_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: request.c 3531 2008-03-06 09:50:56Z martin $
*/
#define _GNU_SOURCE
@@ -25,6 +20,7 @@
#include "request.h"
#include <library.h>
+#include <debug.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
@@ -45,7 +41,12 @@ struct private_request_t {
/**
* FastCGI request object
*/
- FCGX_Request *req;
+ FCGX_Request req;
+
+ /**
+ * length of the req.envp array
+ */
+ int req_env_len;
/**
* ClearSilver CGI Kit context
@@ -56,19 +57,24 @@ struct private_request_t {
* ClearSilver HDF dataset for this request
*/
HDF *hdf;
+
+ /**
+ * close the session?
+ */
+ bool closed;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
};
/**
- * key to a thread specific FCGX_Request, used for ClearSilver cgiwrap callbacks.
+ * key to a the threads "this" request, used for ClearSilver cgiwrap callbacks.
* ClearSilver cgiwrap is not threadsave, so we use a private
* context for each thread.
*/
-static pthread_key_t req_key;
-
-/**
- * length of param list in req->envp
- */
-static pthread_key_t req_env_len_key;
+static pthread_key_t this_key;
/**
* control variable for pthread_once
@@ -80,8 +86,9 @@ pthread_once_t once = PTHREAD_ONCE_INIT;
*/
static int read_cb(void *null, char *buf, int size)
{
- FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
- return FCGX_GetStr(buf, size, req->in);
+ private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
+
+ return FCGX_GetStr(buf, size, this->req.in);
}
/**
@@ -89,8 +96,9 @@ static int read_cb(void *null, char *buf, int size)
*/
static int writef_cb(void *null, const char *format, va_list args)
{
- FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
- FCGX_VFPrintF(req->out, format, args);
+ private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
+
+ FCGX_VFPrintF(this->req.out, format, args);
return 0;
}
/**
@@ -98,8 +106,9 @@ static int writef_cb(void *null, const char *format, va_list args)
*/
static int write_cb(void *null, const char *buf, int size)
{
- FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
- return FCGX_PutStr(buf, size, req->out);
+ private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
+
+ return FCGX_PutStr(buf, size, this->req.out);
}
/**
@@ -108,8 +117,9 @@ static int write_cb(void *null, const char *buf, int size)
static char *getenv_cb(void *null, const char *key)
{
char *value;
- FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
- value = FCGX_GetParam(key, req->envp);
+ private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
+
+ value = FCGX_GetParam(key, this->req.envp);
return value ? strdup(value) : NULL;
}
@@ -129,16 +139,15 @@ static int iterenv_cb(void *null, int num, char **key, char **value)
{
*key = NULL;
*value = NULL;
- FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
- int req_env_len = (int)pthread_getspecific(req_env_len_key);
- if (num < req_env_len)
+ private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
+ if (num < this->req_env_len)
{
char *eq;
- eq = strchr(req->envp[num], '=');
+ eq = strchr(this->req.envp[num], '=');
if (eq)
{
- *key = strndup(req->envp[num], eq - req->envp[num]);
+ *key = strndup(this->req.envp[num], eq - this->req.envp[num]);
*value = strdup(eq + 1);
}
if (*key == NULL || *value == NULL)
@@ -164,11 +173,29 @@ static char* get_cookie(private_request_t *this, char *name)
*/
static char* get_path(private_request_t *this)
{
- char * path = FCGX_GetParam("PATH_INFO", this->req->envp);
+ char * path = FCGX_GetParam("PATH_INFO", this->req.envp);
return path ? path : "";
}
/**
+ * Implementation of request_t.get_host.
+ */
+static char* get_host(private_request_t *this)
+{
+ char *addr = FCGX_GetParam("REMOTE_ADDR", this->req.envp);
+ return addr ? addr : "";
+}
+
+/**
+ * Implementation of request_t.get_user_agent.
+ */
+static char* get_user_agent(private_request_t *this)
+{
+ char *agent = FCGX_GetParam("HTTP_USER_AGENT", this->req.envp);
+ return agent ? agent : "";
+}
+
+/**
* Implementation of request_t.get_post_data.
*/
static char* get_query_data(private_request_t *this, char *name)
@@ -181,8 +208,9 @@ static char* get_query_data(private_request_t *this, char *name)
*/
static void add_cookie(private_request_t *this, char *name, char *value)
{
+ pthread_setspecific(this_key, this);
cgi_cookie_set (this->cgi, name, value,
- FCGX_GetParam("SCRIPT_NAME", this->req->envp),
+ FCGX_GetParam("SCRIPT_NAME", this->req.envp),
NULL, NULL, 0, 0);
}
@@ -193,14 +221,24 @@ static void redirect(private_request_t *this, char *fmt, ...)
{
va_list args;
- FCGX_FPrintF(this->req->out, "Status: 303 See Other\n");
- FCGX_FPrintF(this->req->out, "Location: %s%s",
- FCGX_GetParam("SCRIPT_NAME", this->req->envp),
+ FCGX_FPrintF(this->req.out, "Status: 303 See Other\n");
+ FCGX_FPrintF(this->req.out, "Location: %s%s",
+ FCGX_GetParam("SCRIPT_NAME", this->req.envp),
*fmt == '/' ? "" : "/");
va_start(args, fmt);
- FCGX_VFPrintF(this->req->out, fmt, args);
+ FCGX_VFPrintF(this->req.out, fmt, args);
va_end(args);
- FCGX_FPrintF(this->req->out, "\n\n");
+ FCGX_FPrintF(this->req.out, "\n\n");
+}
+
+/**
+ * Implementation of request_t.to_referer.
+ */
+static void to_referer(private_request_t *this)
+{
+ FCGX_FPrintF(this->req.out, "Status: 303 See Other\n");
+ FCGX_FPrintF(this->req.out, "Location: %s\n\n",
+ FCGX_GetParam("HTTP_REFERER", this->req.envp));
}
/**
@@ -208,7 +246,23 @@ static void redirect(private_request_t *this, char *fmt, ...)
*/
static char* get_base(private_request_t *this)
{
- return FCGX_GetParam("SCRIPT_NAME", this->req->envp);
+ return FCGX_GetParam("SCRIPT_NAME", this->req.envp);
+}
+
+/**
+ * Implementation of request_t.session_closed.
+ */
+static bool session_closed(private_request_t *this)
+{
+ return this->closed;
+}
+
+/**
+ * Implementation of request_t.close_session.
+ */
+static void close_session(private_request_t *this)
+{
+ this->closed = TRUE;
}
/**
@@ -216,9 +270,9 @@ static char* get_base(private_request_t *this)
*/
static void serve(private_request_t *this, char *headers, chunk_t chunk)
{
- FCGX_FPrintF(this->req->out, "%s\n\n", headers);
+ FCGX_FPrintF(this->req.out, "%s\n\n", headers);
- FCGX_PutStr(chunk.ptr, chunk.len, this->req->out);
+ FCGX_PutStr(chunk.ptr, chunk.len, this->req.out);
}
/**
@@ -228,6 +282,7 @@ static void render(private_request_t *this, char *template)
{
NEOERR* err;
+ pthread_setspecific(this_key, this);
err = cgi_display(this->cgi, template);
if (err)
{
@@ -238,6 +293,25 @@ static void render(private_request_t *this, char *template)
}
/**
+ * Implementation of request_t.streamf.
+ */
+static int streamf(private_request_t *this, char *format, ...)
+{
+ va_list args;
+ int written;
+
+ va_start(args, format);
+ written = FCGX_VFPrintF(this->req.out, format, args);
+ va_end(args);
+ if (written >= 0 &&
+ FCGX_FFlush(this->req.out) == -1)
+ {
+ return -1;
+ }
+ return written;
+}
+
+/**
* Implementation of request_t.set.
*/
static void set(private_request_t *this, char *key, char *value)
@@ -255,6 +329,15 @@ static void setf(private_request_t *this, char *format, ...)
va_start(args, format);
hdf_set_valuevf(this->hdf, format, args);
va_end(args);
+}
+
+/**
+ * Implementation of request_t.get_ref.
+ */
+static request_t* get_ref(private_request_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
}
/**
@@ -262,8 +345,13 @@ static void setf(private_request_t *this, char *format, ...)
*/
static void destroy(private_request_t *this)
{
- cgi_destroy(&this->cgi);
- free(this);
+ if (ref_put(&this->ref))
+ {
+ pthread_setspecific(this_key, this);
+ cgi_destroy(&this->cgi);
+ FCGX_Finish_r(&this->req);
+ free(this);
+ }
}
/**
@@ -274,43 +362,60 @@ static void init(void)
{
cgiwrap_init_emu(NULL, read_cb, writef_cb, write_cb,
getenv_cb, putenv_cb, iterenv_cb);
- pthread_key_create(&req_key, NULL);
- pthread_key_create(&req_env_len_key, NULL);
+ pthread_key_create(&this_key, NULL);
}
/*
* see header file
*/
-request_t *request_create(FCGX_Request *request, bool debug)
+request_t *request_create(int fd, bool debug)
{
NEOERR* err;
private_request_t *this = malloc_thing(private_request_t);
+ bool failed = FALSE;
+
+ pthread_cleanup_push(free, this);
+ if (FCGX_InitRequest(&this->req, fd, 0) != 0 ||
+ FCGX_Accept_r(&this->req) != 0)
+ {
+ failed = TRUE;
+ }
+ pthread_cleanup_pop(failed);
+ if (failed)
+ {
+ return NULL;
+ }
this->public.get_path = (char*(*)(request_t*))get_path;
this->public.get_base = (char*(*)(request_t*))get_base;
+ this->public.get_host = (char*(*)(request_t*))get_host;
+ this->public.get_user_agent = (char*(*)(request_t*))get_user_agent;
this->public.add_cookie = (void(*)(request_t*, char *name, char *value))add_cookie;
this->public.get_cookie = (char*(*)(request_t*,char*))get_cookie;
this->public.get_query_data = (char*(*)(request_t*, char *name))get_query_data;
+ this->public.session_closed = (bool(*)(request_t*))session_closed;
+ this->public.close_session = (void(*)(request_t*))close_session;
this->public.redirect = (void(*)(request_t*, char *fmt,...))redirect;
+ this->public.to_referer = (void(*)(request_t*))to_referer;
this->public.render = (void(*)(request_t*,char*))render;
+ this->public.streamf = (int(*)(request_t*, char *format, ...))streamf;
this->public.serve = (void(*)(request_t*,char*,chunk_t))serve;
this->public.set = (void(*)(request_t*, char *, char*))set;
this->public.setf = (void(*)(request_t*, char *format, ...))setf;
+ this->public.get_ref = (request_t*(*)(request_t*))get_ref;
this->public.destroy = (void(*)(request_t*))destroy;
pthread_once(&once, init);
+ pthread_setspecific(this_key, this);
- this->req = request;
- pthread_setspecific(req_key, (void*)request);
-
- int req_env_len = 0;
- while (request->envp[req_env_len] != NULL)
+ this->ref = 1;
+ this->closed = FALSE;
+ this->req_env_len = 0;
+ while (this->req.envp[this->req_env_len] != NULL)
{
- req_env_len++;
+ this->req_env_len++;
}
- pthread_setspecific(req_env_len_key, (void*)req_env_len);
-
err = hdf_init(&this->hdf);
if (!err)
{
@@ -335,6 +440,7 @@ request_t *request_create(FCGX_Request *request, bool debug)
}
}
nerr_log_error(err);
+ FCGX_Finish_r(&this->req);
free(this);
return NULL;
}
diff --git a/src/manager/lib/request.h b/src/libfast/request.h
index f78741d37..b0d5bd89c 100644
--- a/src/manager/lib/request.h
+++ b/src/libfast/request.h
@@ -1,10 +1,3 @@
-/**
- * @file request.h
- *
- * @brief Interface of request_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: request.h 3531 2008-03-06 09:50:56Z martin $
+ */
+
+/**
+ * @defgroup request request
+ * @{ @ingroup libfast
*/
#ifndef REQUEST_H_
@@ -29,21 +29,22 @@
typedef struct request_t request_t;
/**
- * @brief A HTTP request, encapsulates FCGX_Request.
+ * A HTTP request, encapsulates FCGX_Request.
*
+ * The response is also handled through the request object.
*/
struct request_t {
/**
- * @brief Add a cookie to the reply (Set-Cookie header).
+ * Add a cookie to the reply (Set-Cookie header).
*
- * @param name name of the cookie to set
- * @param value value of the cookie
+ * @param name name of the cookie to set
+ * @param value value of the cookie
*/
void (*add_cookie)(request_t *this, char *name, char *value);
/**
- * @brief Get a cookie the client sent in the request.
+ * Get a cookie the client sent in the request.
*
* @param name name of the cookie
* @return cookie value, NULL if no such cookie found
@@ -51,21 +52,35 @@ struct request_t {
char* (*get_cookie)(request_t *this, char *name);
/**
- * @brief Get the request path relative to the application.
+ * Get the request path relative to the application.
*
* @return path
*/
char* (*get_path)(request_t *this);
/**
- * @brief Get the base path of the application.
+ * Get the base path of the application.
*
* @return base path
*/
char* (*get_base)(request_t *this);
/**
- * @brief Get a post/get variable included in the request.
+ * Get the remote host address of this request.
+ *
+ * @return host address as string
+ */
+ char* (*get_host)(request_t *this);
+
+ /**
+ * Get the user agent string.
+ *
+ * @return user agent string
+ */
+ char* (*get_user_agent)(request_t *this);
+
+ /**
+ * Get a post/get variable included in the request.
*
* @param name name of the POST/GET variable
* @return value, NULL if not found
@@ -73,7 +88,19 @@ struct request_t {
char* (*get_query_data)(request_t *this, char *name);
/**
- * @brief Redirect the client to another location.
+ * Close the session and it's context after handling.
+ */
+ void (*close_session)(request_t *this);
+
+ /**
+ * Has the session been closed by close_session()?
+ *
+ * @return TRUE if session has been closed
+ */
+ bool (*session_closed)(request_t *this);
+
+ /**
+ * Redirect the client to another location.
*
* @param fmt location format string
* @param ... variable argument for fmt
@@ -81,7 +108,12 @@ struct request_t {
void (*redirect)(request_t *this, char *fmt, ...);
/**
- * @brief Set a template value.
+ * Redirect the client to the referer.
+ */
+ void (*to_referer)(request_t *this);
+
+ /**
+ * Set a template value.
*
* @param key key to set
* @param value value to set key to
@@ -89,7 +121,7 @@ struct request_t {
void (*set)(request_t *this, char *key, char *value);
/**
- * @brief Set a template value using format strings.
+ * Set a template value using format strings.
*
* Format string is in the form "key=value", where printf like format
* substitution occurs over the whole string.
@@ -100,7 +132,7 @@ struct request_t {
void (*setf)(request_t *this, char *format, ...);
/**
- * @brief Render a template.
+ * Render a template.
*
* The render() function additionally sets a HDF variable "base"
* which points to the root of the web application and allows to point to
@@ -111,7 +143,19 @@ struct request_t {
void (*render)(request_t *this, char *template);
/**
- * @brief Serve a request with headers and a body.
+ * Stream a format string to the client.
+ *
+ * Stream is not closed and may be called multiple times to allow
+ * server-push functionality.
+ *
+ * @param format printf like format string
+ * @param ... argmuent list to format string
+ * @return number of streamed bytes, < 0 if stream closed
+ */
+ int (*streamf)(request_t *this, char *format, ...);
+
+ /**
+ * Serve a request with headers and a body.
*
* @param headers HTTP headers, \n separated
* @param chunk body to write to output
@@ -119,17 +163,24 @@ struct request_t {
void (*serve)(request_t *this, char *headers, chunk_t chunk);
/**
- * @brief Destroy the request_t.
+ * Increase the reference count to the stream.
+ *
+ * @return this with increased refcount
+ */
+ request_t* (*get_ref)(request_t *this);
+
+ /**
+ * Destroy the request_t.
*/
void (*destroy) (request_t *this);
};
/**
- * @brief Create a request from the fastcgi struct.
+ * Create a request from the fastcgi struct.
*
- * @param request the FCGI request
+ * @param fd file descripter opened with FCGX_OpenSocket
* @param debug no stripping, no compression, timing information
*/
-request_t *request_create(FCGX_Request *request, bool debug);
+request_t *request_create(int fd, bool debug);
-#endif /* REQUEST_H_ */
+#endif /* REQUEST_H_ @} */
diff --git a/src/manager/lib/session.c b/src/libfast/session.c
index fe260b887..cb2e736b8 100644
--- a/src/manager/lib/session.c
+++ b/src/libfast/session.c
@@ -1,10 +1,3 @@
-/**
- * @file session.c
- *
- * @brief Implementation of session_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: session.c 4060 2008-06-11 14:11:01Z martin $
*/
#define _GNU_SOURCE
@@ -29,7 +24,6 @@
#include <stdio.h>
#include <utils/linked_list.h>
-#include <utils/randomizer.h>
typedef struct private_session_t private_session_t;
@@ -54,13 +48,18 @@ struct private_session_t {
linked_list_t *controllers;
/**
+ * list of filter instances filter_t
+ */
+ linked_list_t *filters;
+
+ /**
* user defined session context
*/
context_t *context;
};
/**
- * Implementation of session_t.load_controller.
+ * Implementation of session_t.add_controller.
*/
static void add_controller(private_session_t *this, controller_t *controller)
{
@@ -68,18 +67,52 @@ static void add_controller(private_session_t *this, controller_t *controller)
}
/**
+ * Implementation of session_t.add_filter.
+ */
+static void add_filter(private_session_t *this, filter_t *filter)
+{
+ this->filters->insert_last(this->filters, filter);
+}
+
+/**
* Create a session ID and a cookie
*/
static void create_sid(private_session_t *this, request_t *request)
{
char buf[16];
chunk_t chunk = chunk_from_buf(buf);
- randomizer_t *randomizer = randomizer_create();
+ rng_t *rng;
- randomizer->get_pseudo_random_bytes(randomizer, sizeof(buf), buf);
- this->sid = chunk_to_hex(chunk, FALSE);
- request->add_cookie(request, "SID", this->sid);
- randomizer->destroy(randomizer);
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (rng)
+ {
+ rng->get_bytes(rng, sizeof(buf), buf);
+ this->sid = chunk_to_hex(chunk, NULL, FALSE).ptr;
+ request->add_cookie(request, "SID", this->sid);
+ rng->destroy(rng);
+ }
+}
+
+/**
+ * run all registered filters
+ */
+static bool run_filter(private_session_t *this, request_t *request, char *p0,
+ char *p1, char *p2, char *p3, char *p4, char *p5)
+{
+ enumerator_t *enumerator;
+ filter_t *filter;
+
+ enumerator = this->filters->create_enumerator(this->filters);
+ while (enumerator->enumerate(enumerator, &filter))
+ {
+ if (!filter->run(filter, request, p0, p1, p2, p3, p4, p5))
+ {
+ enumerator->destroy(enumerator);
+ return FALSE;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return TRUE;
}
/**
@@ -88,7 +121,7 @@ static void create_sid(private_session_t *this, request_t *request)
static void process(private_session_t *this, request_t *request)
{
char *pos, *start, *param[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
- iterator_t *iterator;
+ enumerator_t *enumerator;
bool handled = FALSE;
controller_t *current;
int i = 0;
@@ -101,28 +134,36 @@ static void process(private_session_t *this, request_t *request)
start = request->get_path(request);
if (start)
{
- if (*start == '/') start++;
+ if (*start == '/')
+ {
+ start++;
+ }
while ((pos = strchr(start, '/')) != NULL && i < 5)
{
- param[i++] = strndup(start, pos - start);
+ param[i++] = strndupa(start, pos - start);
start = pos + 1;
}
- param[i] = strdup(start);
- iterator = this->controllers->create_iterator(this->controllers, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ param[i] = strdupa(start);
+
+ if (run_filter(this, request, param[0], param[1], param[2], param[3],
+ param[4], param[5]))
{
- if (streq(current->get_name(current), param[0]))
- {
- current->handle(current, request, param[1], param[2], param[3],
- param[4], param[5]);
- handled = TRUE;
- break;
+ enumerator = this->controllers->create_enumerator(this->controllers);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (streq(current->get_name(current), param[0]))
+ {
+ current->handle(current, request, param[1], param[2],
+ param[3], param[4], param[5]);
+ handled = TRUE;
+ break;
+ }
}
+ enumerator->destroy(enumerator);
}
- iterator->destroy(iterator);
- for (i = 0; i < 6; i++)
+ else
{
- free(param[i]);
+ handled = TRUE;
}
}
if (!handled)
@@ -149,7 +190,8 @@ static char* get_sid(private_session_t *this)
static void destroy(private_session_t *this)
{
this->controllers->destroy_offset(this->controllers, offsetof(controller_t, destroy));
- if (this->context) this->context->destroy(this->context);
+ this->filters->destroy_offset(this->filters, offsetof(filter_t, destroy));
+ DESTROY_IF(this->context);
free(this->sid);
free(this);
}
@@ -162,12 +204,14 @@ session_t *session_create(context_t *context)
private_session_t *this = malloc_thing(private_session_t);
this->public.add_controller = (void(*)(session_t*, controller_t*))add_controller;
+ this->public.add_filter = (void(*)(session_t*, filter_t*))add_filter;
this->public.process = (void(*)(session_t*,request_t*))process;
this->public.get_sid = (char*(*)(session_t*))get_sid;
this->public.destroy = (void(*)(session_t*))destroy;
this->sid = NULL;
this->controllers = linked_list_create();
+ this->filters = linked_list_create();
this->context = context;
return &this->public;
diff --git a/src/manager/lib/session.h b/src/libfast/session.h
index d18545876..0df5d5482 100644
--- a/src/manager/lib/session.h
+++ b/src/libfast/session.h
@@ -1,10 +1,3 @@
-/**
- * @file session.h
- *
- * @brief Interface of session_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: session.h 3519 2008-03-02 12:14:34Z martin $
+ */
+
+/**
+ * @defgroup session session
+ * @{ @ingroup libfast
*/
#ifndef SESSION_H_
@@ -25,38 +25,45 @@
#include "request.h"
#include "controller.h"
+#include "filter.h"
typedef struct session_t session_t;
/**
- * @brief A session, identified by a session ID.
- *
+ * Session handling class, instanciated for each user session.
*/
struct session_t {
/**
- * @brief Get the session ID of the session.
+ * Get the session ID of the session.
*
* @return session ID
*/
char* (*get_sid)(session_t *this);
/**
- * @brief Add a controller instance to the session.
+ * Add a controller instance to the session.
*
* @param controller controller to add
*/
void (*add_controller)(session_t *this, controller_t *controller);
/**
- * @brief Process a request in this session.
+ * @brief Add a filter instance to the session.
+ *
+ * @param filter filter to add
+ */
+ void (*add_filter)(session_t *this, filter_t *filter);
+
+ /**
+ * Process a request in this session.
*
* @param request request to process
*/
void (*process)(session_t *this, request_t *request);
/**
- * @brief Destroy the session_t.
+ * Destroy the session_t.
*
* @param this calling object
*/
@@ -64,10 +71,10 @@ struct session_t {
};
/**
- * @brief Create a session.
+ * Create a session new session.
*
- * @param context user defined session context instance
+ * @param context user defined session context instance
*/
session_t *session_create(context_t *context);
-#endif /* SESSION_H_ */
+#endif /* SESSION_H_ @} */
diff --git a/src/libfreeswan/Makefile.in b/src/libfreeswan/Makefile.in
index dacd7e76b..bf605d1ff 100644
--- a/src/libfreeswan/Makefile.in
+++ b/src/libfreeswan/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.
@@ -101,6 +101,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -130,6 +131,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -160,7 +162,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@
@@ -171,12 +172,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@
@@ -186,12 +186,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@
@@ -204,10 +204,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@
@@ -400,8 +402,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -413,8 +415,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -424,13 +426,12 @@ ctags: CTAGS
CTAGS: $(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
diff --git a/src/libfreeswan/ipsec_policy.h b/src/libfreeswan/ipsec_policy.h
index 52b4d7590..bf074f18f 100644
--- a/src/libfreeswan/ipsec_policy.h
+++ b/src/libfreeswan/ipsec_policy.h
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
*
- * RCSID $Id: ipsec_policy.h 3265 2007-10-08 19:52:55Z andreas $
+ * RCSID $Id: ipsec_policy.h 3839 2008-04-18 11:25:37Z andreas $
*/
#define _IPSEC_POLICY_H /* seen it, no need to see it again */
@@ -75,14 +75,16 @@ enum ipsec_bandwidth_quality {
* and in http://www.iana.org/assignments/isakmp-registry
*/
enum ipsec_authentication_algo {
- AH_NONE = 0,
- AH_MD5 = 2,
- AH_SHA = 3,
- AH_DES = 4,
- AH_SHA2_256 = 5,
- AH_SHA2_384 = 6,
- AH_SHA2_512 = 7,
- AH_RIPEMD = 8
+ AH_NONE = 0,
+ AH_MD5 = 2,
+ AH_SHA = 3,
+ AH_DES = 4,
+ AH_SHA2_256 = 5,
+ AH_SHA2_384 = 6,
+ AH_SHA2_512 = 7,
+ AH_RIPEMD = 8,
+ AH_AES_XCBC_MAC = 9,
+ AH_RSA = 10
};
/* IPsec ESP transform values
@@ -91,25 +93,31 @@ enum ipsec_authentication_algo {
*/
enum ipsec_cipher_algo {
- ESP_NONE = 0,
- ESP_DES_IV64 = 1,
- ESP_DES = 2,
- ESP_3DES = 3,
- ESP_RC5 = 4,
- ESP_IDEA = 5,
- ESP_CAST = 6,
- ESP_BLOWFISH = 7,
- ESP_3IDEA = 8,
- ESP_DES_IV32 = 9,
- ESP_RC4 = 10,
- ESP_NULL = 11,
- ESP_AES = 12,
- ESP_AES_CTR = 13,
- ESP_AES_CCM_8 = 14,
- ESP_AES_CCM_12 = 15,
- ESP_AES_CCM_16 = 16,
- ESP_SERPENT = 252,
- ESP_TWOFISH = 253
+ ESP_NONE = 0,
+ ESP_DES_IV64 = 1,
+ ESP_DES = 2,
+ ESP_3DES = 3,
+ ESP_RC5 = 4,
+ ESP_IDEA = 5,
+ ESP_CAST = 6,
+ ESP_BLOWFISH = 7,
+ ESP_3IDEA = 8,
+ ESP_DES_IV32 = 9,
+ ESP_RC4 = 10,
+ ESP_NULL = 11,
+ ESP_AES = 12,
+ ESP_AES_CTR = 13,
+ ESP_AES_CCM_8 = 14,
+ ESP_AES_CCM_12 = 15,
+ ESP_AES_CCM_16 = 16,
+ ESP_UNASSIGNED_17 = 17,
+ ESP_AES_GCM_8 = 18,
+ ESP_AES_GCM_12 = 19,
+ ESP_AES_GCM_16 = 20,
+ ESP_SEED_CBC = 21,
+ ESP_CAMELLIA = 22,
+ ESP_SERPENT = 252,
+ ESP_TWOFISH = 253
};
/* IPCOMP transform values
diff --git a/src/libfreeswan/pfkeyv2.h b/src/libfreeswan/pfkeyv2.h
index d763d4024..1ea1265d3 100644
--- a/src/libfreeswan/pfkeyv2.h
+++ b/src/libfreeswan/pfkeyv2.h
@@ -1,5 +1,5 @@
/*
- * RCSID $Id: pfkeyv2.h 3265 2007-10-08 19:52:55Z andreas $
+ * RCSID $Id: pfkeyv2.h 3846 2008-04-18 17:01:45Z andreas $
*/
/*
@@ -312,49 +312,39 @@ struct sadb_protocol {
#define SADB_X_SAFLAGS_CLEARFLOW 4
#define SADB_X_SAFLAGS_INFLOW 8
-/* not obvious, but these are the same values as used in isakmp,
- * and in freeswan/ipsec_policy.h. If you need to add any, they
- * should be added as according to
- * http://www.iana.org/assignments/isakmp-registry
- *
- * and if not, then please try to use a private-use value, and
- * consider asking IANA to assign a value.
- */
-#define SADB_AALG_NONE 0
-#define SADB_AALG_MD5_HMAC 2
-#define SADB_AALG_SHA1_HMAC 3
-#define SADB_AALG_DES_MAC 4
-#define SADB_AALG_SHA2_256_HMAC 5
-#define SADB_AALG_SHA2_384_HMAC 6
-#define SADB_AALG_SHA2_512_HMAC 7
-#define SADB_AALG_RIPEMD_160_HMAC 8
-#define SADB_AALG_AES_XCBC_MAC 9
+/* Authentication algorithms */
+#define SADB_AALG_NONE 0
+#define SADB_AALG_MD5HMAC 2
+#define SADB_AALG_SHA1HMAC 3
+#define SADB_X_AALG_SHA2_256HMAC 5
+#define SADB_X_AALG_SHA2_384HMAC 6
+#define SADB_X_AALG_SHA2_512HMAC 7
+#define SADB_X_AALG_RIPEMD160HMAC 8
+#define SADB_X_AALG_AES_XCBC_MAC 9
#define SADB_X_AALG_NULL 251 /* kame */
#define SADB_AALG_MAX 251
+/* Encryption algorithms */
#define SADB_EALG_NONE 0
-#define SADB_EALG_DES_CBC 2
-#define SADB_EALG_3DES_CBC 3
-#define SADB_EALG_RC5_CBC 4
-#define SADB_EALG_IDEA_CBC 5
-#define SADB_EALG_CAST_CBC 6
-#define SADB_EALG_BLOWFISH_CBC 7
+#define SADB_EALG_DESCBC 2
+#define SADB_EALG_3DESCBC 3
+#define SADB_X_EALG_CASTCBC 6
+#define SADB_X_EALG_BLOWFISHCBC 7
#define SADB_EALG_NULL 11
-#define SADB_EALG_AES_CBC 12
-#define SADB_EALG_AES_CTR 13
-#define SADB_X_EALG_SERPENT_CBC 252
-#define SADB_X_EALG_TWOFISH_CBC 253
-#define SADB_EALG_MAX 253
-
-#define SADB_X_CALG_NONE 0
-#define SADB_X_CALG_OUI 1
-#define SADB_X_CALG_DEFLATE 2
-#define SADB_X_CALG_LZS 3
-#define SADB_X_CALG_V42BIS 4
-#ifdef KERNEL26_HAS_KAME_DUPLICATES
-#define SADB_X_CALG_LZJH 4
-#endif
-#define SADB_X_CALG_MAX 4
+#define SADB_X_EALG_AESCBC 12
+#define SADB_X_EALG_CAMELLIACBC 22
+#define SADB_EALG_MAX 253 /* last EALG */
+/* private allocations should use 249-255 (RFC2407) */
+#define SADB_X_EALG_SERPENTCBC 252 /* draft-ietf-ipsec-ciph-aes-cbc-00 */
+#define SADB_X_EALG_TWOFISHCBC 253 /* draft-ietf-ipsec-ciph-aes-cbc-00 */
+
+/* Compression algorithms */
+#define SADB_X_CALG_NONE 0
+#define SADB_X_CALG_OUI 1
+#define SADB_X_CALG_DEFLATE 2
+#define SADB_X_CALG_LZS 3
+#define SADB_X_CALG_LZJH 4
+#define SADB_X_CALG_MAX 4
#define SADB_X_TALG_NONE 0
#define SADB_X_TALG_IPv4_in_IPv4 1
@@ -363,13 +353,11 @@ struct sadb_protocol {
#define SADB_X_TALG_IPv6_in_IPv6 4
#define SADB_X_TALG_MAX 4
+/* Identity Extension values */
+#define SADB_IDENTTYPE_RESERVED 0
+#define SADB_IDENTTYPE_PREFIX 1
+#define SADB_IDENTTYPE_FQDN 2
+#define SADB_IDENTTYPE_USERFQDN 3
+#define SADB_IDENTTYPE_MAX 3
-#define SADB_IDENTTYPE_RESERVED 0
-#define SADB_IDENTTYPE_PREFIX 1
-#define SADB_IDENTTYPE_FQDN 2
-#define SADB_IDENTTYPE_USERFQDN 3
-#define SADB_X_IDENTTYPE_CONNECTION 4
-#define SADB_IDENTTYPE_MAX 4
-
-#define SADB_KEY_FLAGS_MAX 0
#endif /* __PFKEY_V2_H */
diff --git a/src/libfreeswan/ttoaddr.c b/src/libfreeswan/ttoaddr.c
index f1c6810ea..15e8dfe55 100644
--- a/src/libfreeswan/ttoaddr.c
+++ b/src/libfreeswan/ttoaddr.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
*
- * RCSID $Id: ttoaddr.c 3265 2007-10-08 19:52:55Z andreas $
+ * RCSID $Id: ttoaddr.c 3684 2008-03-28 11:46:30Z martin $
*/
#include "internal.h"
#include "freeswan.h"
@@ -320,7 +320,7 @@ size_t srclen; /* known to be >0 */
ip_address *dst;
{
const char *stop = src + srclen; /* just past end */
- unsigned piece;
+ unsigned piece = 0;
int gapat; /* where was empty piece seen */
err_t oops;
# define NPIECES 8
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am
index fc642c615..869f9677b 100644
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
@@ -9,73 +9,63 @@ else
endif
libstrongswan_la_SOURCES += \
-credential_store.h \
library.c library.h \
chunk.c chunk.h \
debug.c debug.h \
enum.c enum.h \
+settings.h settings.c \
printf_hook.c printf_hook.h \
asn1/asn1.c asn1/asn1.h \
+asn1/asn1_parser.c asn1/asn1_parser.h \
asn1/oid.c asn1/oid.h \
asn1/pem.c asn1/pem.h \
-asn1/ttodata.c asn1/ttodata.h \
-crypto/ac.c crypto/ac.h \
-crypto/ca.c crypto/ca.h \
-crypto/certinfo.c crypto/certinfo.h \
-crypto/crl.c crypto/crl.h \
crypto/crypters/crypter.c crypto/crypters/crypter.h \
-crypto/crypters/aes_cbc_crypter.c crypto/crypters/aes_cbc_crypter.h \
-crypto/crypters/des_crypter.c crypto/crypters/des_crypter.h \
-crypto/diffie_hellman.c crypto/diffie_hellman.h \
crypto/hashers/hasher.h crypto/hashers/hasher.c \
-crypto/hashers/sha1_hasher.c crypto/hashers/sha1_hasher.h \
-crypto/hashers/sha2_hasher.c crypto/hashers/sha2_hasher.h \
-crypto/hashers/md5_hasher.c crypto/hashers/md5_hasher.h \
-crypto/hmac.c crypto/hmac.h \
-crypto/ietf_attr_list.c crypto/ietf_attr_list.h \
-crypto/ocsp.c crypto/ocsp.h \
-crypto/pkcs7.c crypto/pkcs7.h \
crypto/pkcs9.c crypto/pkcs9.h \
-crypto/prfs/fips_prf.c crypto/prfs/fips_prf.h \
-crypto/prfs/hmac_prf.c crypto/prfs/hmac_prf.h \
crypto/prfs/prf.c crypto/prfs/prf.h \
+crypto/rngs/rng.c crypto/rngs/rng.h \
crypto/prf_plus.h crypto/prf_plus.c \
-crypto/rsa/rsa_private_key.c crypto/rsa/rsa_private_key.h \
-crypto/rsa/rsa_public_key.h crypto/rsa/rsa_public_key.c \
-crypto/signers/hmac_signer.c crypto/signers/hmac_signer.h \
crypto/signers/signer.c crypto/signers/signer.h \
-crypto/x509.c crypto/x509.h \
-utils/fetcher.c utils/fetcher.h \
+crypto/diffie_hellman.c crypto/diffie_hellman.h \
+crypto/crypto_factory.c crypto/crypto_factory.h \
+credentials/credential_factory.c credentials/credential_factory.h \
+credentials/builder.c credentials/builder.h \
+credentials/keys/private_key.c credentials/keys/private_key.h \
+credentials/keys/public_key.c credentials/keys/public_key.h \
+credentials/keys/shared_key.c credentials/keys/shared_key.h \
+credentials/certificates/certificate.c credentials/certificates/certificate.h \
+credentials/certificates/x509.h credentials/certificates/x509.c \
+credentials/certificates/ac.h \
+credentials/certificates/crl.h credentials/certificates/crl.c \
+credentials/certificates/ocsp_request.h \
+credentials/certificates/ocsp_response.h credentials/certificates/ocsp_response.c \
+fetcher/fetcher.h fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
+database/database.h database/database_factory.h database/database_factory.c \
+utils.h utils.c \
utils/host.c utils/host.h \
utils/identification.c utils/identification.h \
utils/iterator.h \
-utils/leak_detective.c utils/leak_detective.h \
utils/lexparser.c utils/lexparser.h \
utils/linked_list.c utils/linked_list.h \
utils/enumerator.c utils/enumerator.h \
utils/optionsfrom.c utils/optionsfrom.h \
-utils/randomizer.c utils/randomizer.h
-
-if USE_INTEGRITY_TEST
- libstrongswan_la_SOURCES += \
- fips/fips_canister_end.c
-endif
+utils/mutex.c utils/mutex.h \
+plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h
-libstrongswan_la_LIBADD = -lgmp -lpthread
+libstrongswan_la_LIBADD = -lpthread -ldl
INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\"
if USE_LEAK_DETECTIVE
- libstrongswan_la_LIBADD += -ldl
- AM_CFLAGS = -DLEAK_DETECTIVE
+ AM_CFLAGS += -DLEAK_DETECTIVE
+ libstrongswan_la_SOURCES += utils/leak_detective.c utils/leak_detective.h
endif
-if USE_LIBCURL
- libstrongswan_la_LIBADD += -lcurl
-endif
-
-if USE_LIBLDAP
- libstrongswan_la_LIBADD += -lldap -llber
+if USE_INTEGRITY_TEST
+ libstrongswan_la_SOURCES += \
+ fips/fips_canister_end.c
endif
EXTRA_DIST = asn1/oid.txt asn1/oid.pl
@@ -88,15 +78,92 @@ asn1/oid.c : asn1/oid.txt asn1/oid.pl
asn1/oid.h : asn1/oid.txt asn1/oid.pl
cd asn1 && $(PERL) oid.pl
+
+# build plugins with their own Makefile
+#######################################
+
+SUBDIRS = .
+
+if USE_AES
+ SUBDIRS += plugins/aes
+endif
+
+if USE_DES
+ SUBDIRS += plugins/des
+endif
+
+if USE_MD5
+ SUBDIRS += plugins/md5
+endif
+
+if USE_SHA1
+ SUBDIRS += plugins/sha1
+endif
+
+if USE_SHA2
+ SUBDIRS += plugins/sha2
+endif
+
+if USE_FIPS_PRF
+ SUBDIRS += plugins/fips_prf
+endif
+
+if USE_GMP
+ SUBDIRS += plugins/gmp
+endif
+
+if USE_RANDOM
+ SUBDIRS += plugins/random
+endif
+
+if USE_HMAC
+ SUBDIRS += plugins/hmac
+endif
+
+if USE_XCBC
+ SUBDIRS += plugins/xcbc
+endif
+
+if USE_X509
+ SUBDIRS += plugins/x509
+endif
+
+if USE_PUBKEY
+ SUBDIRS += plugins/pubkey
+endif
+
+if USE_CURL
+ SUBDIRS += plugins/curl
+endif
+
+if USE_LDAP
+ SUBDIRS += plugins/ldap
+endif
+
+if USE_MYSQL
+ SUBDIRS += plugins/mysql
+endif
+
+if USE_SQLITE
+ SUBDIRS += plugins/sqlite
+endif
+
+if USE_PADLOCK
+ SUBDIRS += plugins/padlock
+endif
+
+if USE_OPENSSL
+ SUBDIRS += plugins/openssl
+endif
+
if USE_INTEGRITY_TEST
-# build fips_signer which in turn builds fips_signature.h
-#########################################################
-noinst_PROGRAMS = fips_signer
-fips_signer_SOURCES = fips/fips_signer.c
-fips_signer_LDADD = libstrongswan.la
-
-BUILT_SOURCES += fips_signature.h
-CLEANFILES = fips_signature.h fips_signer
+ noinst_PROGRAMS = fips_signer
+ fips_signer_SOURCES = fips/fips_signer.c
+ fips_signer_LDADD = libstrongswan.la
+
+ BUILT_SOURCES += fips_signature.h
+ CLEANFILES = fips_signature.h fips_signer
+ AM_CFLAGS += -DSTRONGSWAN_CONF=\"${strongswan_conf}\"
fips_signature.h : fips_signer
./fips_signer
diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in
index c8a471e00..fc6e40229 100644
--- a/src/libstrongswan/Makefile.in
+++ b/src/libstrongswan/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.
@@ -33,11 +33,29 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-@USE_LEAK_DETECTIVE_TRUE@am__append_1 = -ldl
-@USE_LIBCURL_TRUE@am__append_2 = -lcurl
-@USE_LIBLDAP_TRUE@am__append_3 = -lldap -llber
+@USE_LEAK_DETECTIVE_TRUE@am__append_1 = -DLEAK_DETECTIVE
+@USE_LEAK_DETECTIVE_TRUE@am__append_2 = utils/leak_detective.c utils/leak_detective.h
+@USE_AES_TRUE@am__append_3 = plugins/aes
+@USE_DES_TRUE@am__append_4 = plugins/des
+@USE_MD5_TRUE@am__append_5 = plugins/md5
+@USE_SHA1_TRUE@am__append_6 = plugins/sha1
+@USE_SHA2_TRUE@am__append_7 = plugins/sha2
+@USE_FIPS_PRF_TRUE@am__append_8 = plugins/fips_prf
+@USE_GMP_TRUE@am__append_9 = plugins/gmp
+@USE_RANDOM_TRUE@am__append_10 = plugins/random
+@USE_HMAC_TRUE@am__append_11 = plugins/hmac
+@USE_XCBC_TRUE@am__append_12 = plugins/xcbc
+@USE_X509_TRUE@am__append_13 = plugins/x509
+@USE_PUBKEY_TRUE@am__append_14 = plugins/pubkey
+@USE_CURL_TRUE@am__append_15 = plugins/curl
+@USE_LDAP_TRUE@am__append_16 = plugins/ldap
+@USE_MYSQL_TRUE@am__append_17 = plugins/mysql
+@USE_SQLITE_TRUE@am__append_18 = plugins/sqlite
+@USE_PADLOCK_TRUE@am__append_19 = plugins/padlock
+@USE_OPENSSL_TRUE@am__append_20 = plugins/openssl
@USE_INTEGRITY_TEST_TRUE@noinst_PROGRAMS = fips_signer$(EXEEXT)
-@USE_INTEGRITY_TEST_TRUE@am__append_4 = fips_signature.h
+@USE_INTEGRITY_TEST_TRUE@am__append_21 = fips_signature.h
+@USE_INTEGRITY_TEST_TRUE@am__append_22 = -DSTRONGSWAN_CONF=\"${strongswan_conf}\"
subdir = src/libstrongswan
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -55,78 +73,82 @@ am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
-am__DEPENDENCIES_1 =
-libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
-am__libstrongswan_la_SOURCES_DIST = credential_store.h library.c \
- library.h chunk.c chunk.h debug.c debug.h enum.c enum.h \
- printf_hook.c printf_hook.h asn1/asn1.c asn1/asn1.h asn1/oid.c \
- asn1/oid.h asn1/pem.c asn1/pem.h asn1/ttodata.c asn1/ttodata.h \
- crypto/ac.c crypto/ac.h crypto/ca.c crypto/ca.h \
- crypto/certinfo.c crypto/certinfo.h crypto/crl.c crypto/crl.h \
- crypto/crypters/crypter.c crypto/crypters/crypter.h \
- crypto/crypters/aes_cbc_crypter.c \
- crypto/crypters/aes_cbc_crypter.h \
- crypto/crypters/des_crypter.c crypto/crypters/des_crypter.h \
+libstrongswan_la_DEPENDENCIES =
+am__libstrongswan_la_SOURCES_DIST = library.c library.h chunk.c \
+ chunk.h debug.c debug.h enum.c enum.h settings.h settings.c \
+ printf_hook.c printf_hook.h asn1/asn1.c asn1/asn1.h \
+ asn1/asn1_parser.c asn1/asn1_parser.h asn1/oid.c asn1/oid.h \
+ asn1/pem.c asn1/pem.h crypto/crypters/crypter.c \
+ crypto/crypters/crypter.h crypto/hashers/hasher.h \
+ crypto/hashers/hasher.c crypto/pkcs9.c crypto/pkcs9.h \
+ crypto/prfs/prf.c crypto/prfs/prf.h crypto/rngs/rng.c \
+ crypto/rngs/rng.h crypto/prf_plus.h crypto/prf_plus.c \
+ crypto/signers/signer.c crypto/signers/signer.h \
crypto/diffie_hellman.c crypto/diffie_hellman.h \
- crypto/hashers/hasher.h crypto/hashers/hasher.c \
- crypto/hashers/sha1_hasher.c crypto/hashers/sha1_hasher.h \
- crypto/hashers/sha2_hasher.c crypto/hashers/sha2_hasher.h \
- crypto/hashers/md5_hasher.c crypto/hashers/md5_hasher.h \
- crypto/hmac.c crypto/hmac.h crypto/ietf_attr_list.c \
- crypto/ietf_attr_list.h crypto/ocsp.c crypto/ocsp.h \
- crypto/pkcs7.c crypto/pkcs7.h crypto/pkcs9.c crypto/pkcs9.h \
- crypto/prfs/fips_prf.c crypto/prfs/fips_prf.h \
- crypto/prfs/hmac_prf.c crypto/prfs/hmac_prf.h \
- crypto/prfs/prf.c crypto/prfs/prf.h crypto/prf_plus.h \
- crypto/prf_plus.c crypto/rsa/rsa_private_key.c \
- crypto/rsa/rsa_private_key.h crypto/rsa/rsa_public_key.h \
- crypto/rsa/rsa_public_key.c crypto/signers/hmac_signer.c \
- crypto/signers/hmac_signer.h crypto/signers/signer.c \
- crypto/signers/signer.h crypto/x509.c crypto/x509.h \
- utils/fetcher.c utils/fetcher.h utils/host.c utils/host.h \
- utils/identification.c utils/identification.h utils/iterator.h \
+ crypto/crypto_factory.c crypto/crypto_factory.h \
+ credentials/credential_factory.c \
+ credentials/credential_factory.h credentials/builder.c \
+ credentials/builder.h credentials/keys/private_key.c \
+ credentials/keys/private_key.h credentials/keys/public_key.c \
+ credentials/keys/public_key.h credentials/keys/shared_key.c \
+ credentials/keys/shared_key.h \
+ credentials/certificates/certificate.c \
+ credentials/certificates/certificate.h \
+ credentials/certificates/x509.h \
+ credentials/certificates/x509.c credentials/certificates/ac.h \
+ credentials/certificates/crl.h credentials/certificates/crl.c \
+ credentials/certificates/ocsp_request.h \
+ credentials/certificates/ocsp_response.h \
+ credentials/certificates/ocsp_response.c fetcher/fetcher.h \
+ fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
+ database/database.h database/database_factory.h \
+ database/database_factory.c utils.h utils.c utils/host.c \
+ utils/host.h utils/identification.c utils/identification.h \
+ utils/iterator.h utils/lexparser.c utils/lexparser.h \
+ utils/linked_list.c utils/linked_list.h utils/enumerator.c \
+ utils/enumerator.h utils/optionsfrom.c utils/optionsfrom.h \
+ utils/mutex.c utils/mutex.h plugins/plugin_loader.c \
+ plugins/plugin_loader.h plugins/plugin.h \
utils/leak_detective.c utils/leak_detective.h \
- utils/lexparser.c utils/lexparser.h utils/linked_list.c \
- utils/linked_list.h utils/enumerator.c utils/enumerator.h \
- utils/optionsfrom.c utils/optionsfrom.h utils/randomizer.c \
- utils/randomizer.h fips/fips_canister_start.c fips/fips.c \
- fips/fips.h fips/fips_canister_end.c
+ fips/fips_canister_start.c fips/fips.c fips/fips.h \
+ fips/fips_canister_end.c
+@USE_LEAK_DETECTIVE_TRUE@am__objects_1 = leak_detective.lo
@USE_INTEGRITY_TEST_FALSE@am_libstrongswan_la_OBJECTS = library.lo \
@USE_INTEGRITY_TEST_FALSE@ chunk.lo debug.lo enum.lo \
-@USE_INTEGRITY_TEST_FALSE@ printf_hook.lo asn1.lo oid.lo pem.lo \
-@USE_INTEGRITY_TEST_FALSE@ ttodata.lo ac.lo ca.lo certinfo.lo \
-@USE_INTEGRITY_TEST_FALSE@ crl.lo crypter.lo aes_cbc_crypter.lo \
-@USE_INTEGRITY_TEST_FALSE@ des_crypter.lo diffie_hellman.lo \
-@USE_INTEGRITY_TEST_FALSE@ hasher.lo sha1_hasher.lo \
-@USE_INTEGRITY_TEST_FALSE@ sha2_hasher.lo md5_hasher.lo hmac.lo \
-@USE_INTEGRITY_TEST_FALSE@ ietf_attr_list.lo ocsp.lo pkcs7.lo \
-@USE_INTEGRITY_TEST_FALSE@ pkcs9.lo fips_prf.lo hmac_prf.lo \
-@USE_INTEGRITY_TEST_FALSE@ prf.lo prf_plus.lo \
-@USE_INTEGRITY_TEST_FALSE@ rsa_private_key.lo rsa_public_key.lo \
-@USE_INTEGRITY_TEST_FALSE@ hmac_signer.lo signer.lo x509.lo \
-@USE_INTEGRITY_TEST_FALSE@ fetcher.lo host.lo identification.lo \
-@USE_INTEGRITY_TEST_FALSE@ leak_detective.lo lexparser.lo \
+@USE_INTEGRITY_TEST_FALSE@ settings.lo printf_hook.lo asn1.lo \
+@USE_INTEGRITY_TEST_FALSE@ asn1_parser.lo oid.lo pem.lo \
+@USE_INTEGRITY_TEST_FALSE@ crypter.lo hasher.lo pkcs9.lo prf.lo \
+@USE_INTEGRITY_TEST_FALSE@ rng.lo prf_plus.lo signer.lo \
+@USE_INTEGRITY_TEST_FALSE@ diffie_hellman.lo crypto_factory.lo \
+@USE_INTEGRITY_TEST_FALSE@ credential_factory.lo builder.lo \
+@USE_INTEGRITY_TEST_FALSE@ private_key.lo public_key.lo \
+@USE_INTEGRITY_TEST_FALSE@ shared_key.lo certificate.lo x509.lo \
+@USE_INTEGRITY_TEST_FALSE@ crl.lo ocsp_response.lo \
+@USE_INTEGRITY_TEST_FALSE@ fetcher_manager.lo \
+@USE_INTEGRITY_TEST_FALSE@ database_factory.lo utils.lo host.lo \
+@USE_INTEGRITY_TEST_FALSE@ identification.lo lexparser.lo \
@USE_INTEGRITY_TEST_FALSE@ linked_list.lo enumerator.lo \
-@USE_INTEGRITY_TEST_FALSE@ optionsfrom.lo randomizer.lo
+@USE_INTEGRITY_TEST_FALSE@ optionsfrom.lo mutex.lo \
+@USE_INTEGRITY_TEST_FALSE@ plugin_loader.lo $(am__objects_1)
@USE_INTEGRITY_TEST_TRUE@am_libstrongswan_la_OBJECTS = \
@USE_INTEGRITY_TEST_TRUE@ fips_canister_start.lo fips.lo \
@USE_INTEGRITY_TEST_TRUE@ library.lo chunk.lo debug.lo enum.lo \
-@USE_INTEGRITY_TEST_TRUE@ printf_hook.lo asn1.lo oid.lo pem.lo \
-@USE_INTEGRITY_TEST_TRUE@ ttodata.lo ac.lo ca.lo certinfo.lo \
-@USE_INTEGRITY_TEST_TRUE@ crl.lo crypter.lo aes_cbc_crypter.lo \
-@USE_INTEGRITY_TEST_TRUE@ des_crypter.lo diffie_hellman.lo \
-@USE_INTEGRITY_TEST_TRUE@ hasher.lo sha1_hasher.lo \
-@USE_INTEGRITY_TEST_TRUE@ sha2_hasher.lo md5_hasher.lo hmac.lo \
-@USE_INTEGRITY_TEST_TRUE@ ietf_attr_list.lo ocsp.lo pkcs7.lo \
-@USE_INTEGRITY_TEST_TRUE@ pkcs9.lo fips_prf.lo hmac_prf.lo \
-@USE_INTEGRITY_TEST_TRUE@ prf.lo prf_plus.lo rsa_private_key.lo \
-@USE_INTEGRITY_TEST_TRUE@ rsa_public_key.lo hmac_signer.lo \
-@USE_INTEGRITY_TEST_TRUE@ signer.lo x509.lo fetcher.lo host.lo \
-@USE_INTEGRITY_TEST_TRUE@ identification.lo leak_detective.lo \
-@USE_INTEGRITY_TEST_TRUE@ lexparser.lo linked_list.lo \
-@USE_INTEGRITY_TEST_TRUE@ enumerator.lo optionsfrom.lo \
-@USE_INTEGRITY_TEST_TRUE@ randomizer.lo fips_canister_end.lo
+@USE_INTEGRITY_TEST_TRUE@ settings.lo printf_hook.lo asn1.lo \
+@USE_INTEGRITY_TEST_TRUE@ asn1_parser.lo oid.lo pem.lo \
+@USE_INTEGRITY_TEST_TRUE@ crypter.lo hasher.lo pkcs9.lo prf.lo \
+@USE_INTEGRITY_TEST_TRUE@ rng.lo prf_plus.lo signer.lo \
+@USE_INTEGRITY_TEST_TRUE@ diffie_hellman.lo crypto_factory.lo \
+@USE_INTEGRITY_TEST_TRUE@ credential_factory.lo builder.lo \
+@USE_INTEGRITY_TEST_TRUE@ private_key.lo public_key.lo \
+@USE_INTEGRITY_TEST_TRUE@ shared_key.lo certificate.lo x509.lo \
+@USE_INTEGRITY_TEST_TRUE@ crl.lo ocsp_response.lo \
+@USE_INTEGRITY_TEST_TRUE@ fetcher_manager.lo \
+@USE_INTEGRITY_TEST_TRUE@ database_factory.lo utils.lo host.lo \
+@USE_INTEGRITY_TEST_TRUE@ identification.lo lexparser.lo \
+@USE_INTEGRITY_TEST_TRUE@ linked_list.lo enumerator.lo \
+@USE_INTEGRITY_TEST_TRUE@ optionsfrom.lo mutex.lo \
+@USE_INTEGRITY_TEST_TRUE@ plugin_loader.lo $(am__objects_1) \
+@USE_INTEGRITY_TEST_TRUE@ fips_canister_end.lo
libstrongswan_la_OBJECTS = $(am_libstrongswan_la_OBJECTS)
PROGRAMS = $(noinst_PROGRAMS)
am__fips_signer_SOURCES_DIST = fips/fips_signer.c
@@ -149,8 +171,22 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
SOURCES = $(libstrongswan_la_SOURCES) $(fips_signer_SOURCES)
DIST_SOURCES = $(am__libstrongswan_la_SOURCES_DIST) \
$(am__fips_signer_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/aes plugins/des plugins/md5 plugins/sha1 \
+ plugins/sha2 plugins/fips_prf plugins/gmp plugins/random \
+ plugins/hmac plugins/xcbc plugins/x509 plugins/pubkey \
+ plugins/curl plugins/ldap plugins/mysql plugins/sqlite \
+ plugins/padlock plugins/openssl
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -171,6 +207,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -200,6 +237,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -230,7 +268,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@
@@ -241,12 +278,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@
@@ -256,12 +292,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@
@@ -274,10 +310,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@
@@ -285,145 +323,153 @@ top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
lib_LTLIBRARIES = libstrongswan.la
-@USE_INTEGRITY_TEST_FALSE@libstrongswan_la_SOURCES = \
-@USE_INTEGRITY_TEST_FALSE@ credential_store.h library.c \
+@USE_INTEGRITY_TEST_FALSE@libstrongswan_la_SOURCES = library.c \
@USE_INTEGRITY_TEST_FALSE@ library.h chunk.c chunk.h debug.c \
-@USE_INTEGRITY_TEST_FALSE@ debug.h enum.c enum.h printf_hook.c \
+@USE_INTEGRITY_TEST_FALSE@ debug.h enum.c enum.h settings.h \
+@USE_INTEGRITY_TEST_FALSE@ settings.c printf_hook.c \
@USE_INTEGRITY_TEST_FALSE@ printf_hook.h asn1/asn1.c \
-@USE_INTEGRITY_TEST_FALSE@ asn1/asn1.h asn1/oid.c asn1/oid.h \
-@USE_INTEGRITY_TEST_FALSE@ asn1/pem.c asn1/pem.h asn1/ttodata.c \
-@USE_INTEGRITY_TEST_FALSE@ asn1/ttodata.h crypto/ac.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/ac.h crypto/ca.c crypto/ca.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/certinfo.c crypto/certinfo.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/crl.c crypto/crl.h \
+@USE_INTEGRITY_TEST_FALSE@ asn1/asn1.h asn1/asn1_parser.c \
+@USE_INTEGRITY_TEST_FALSE@ asn1/asn1_parser.h asn1/oid.c \
+@USE_INTEGRITY_TEST_FALSE@ asn1/oid.h asn1/pem.c asn1/pem.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/crypters/crypter.c \
@USE_INTEGRITY_TEST_FALSE@ crypto/crypters/crypter.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/crypters/aes_cbc_crypter.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/crypters/aes_cbc_crypter.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/crypters/des_crypter.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/crypters/des_crypter.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/hasher.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/hasher.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/sha1_hasher.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/sha1_hasher.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/sha2_hasher.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/sha2_hasher.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/md5_hasher.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/md5_hasher.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/hmac.c crypto/hmac.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/ietf_attr_list.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/ietf_attr_list.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/ocsp.c crypto/ocsp.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/pkcs7.c crypto/pkcs7.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/pkcs9.c crypto/pkcs9.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/prfs/fips_prf.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/prfs/fips_prf.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/prfs/hmac_prf.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/prfs/hmac_prf.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/prfs/prf.c crypto/prfs/prf.h \
+@USE_INTEGRITY_TEST_FALSE@ crypto/rngs/rng.c crypto/rngs/rng.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/prf_plus.h crypto/prf_plus.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/rsa/rsa_private_key.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/rsa/rsa_private_key.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/rsa/rsa_public_key.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/rsa/rsa_public_key.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/signers/hmac_signer.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/signers/hmac_signer.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/signers/signer.c \
@USE_INTEGRITY_TEST_FALSE@ crypto/signers/signer.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/x509.c crypto/x509.h \
-@USE_INTEGRITY_TEST_FALSE@ utils/fetcher.c utils/fetcher.h \
-@USE_INTEGRITY_TEST_FALSE@ utils/host.c utils/host.h \
+@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.c \
+@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.h \
+@USE_INTEGRITY_TEST_FALSE@ crypto/crypto_factory.c \
+@USE_INTEGRITY_TEST_FALSE@ crypto/crypto_factory.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/credential_factory.c \
+@USE_INTEGRITY_TEST_FALSE@ credentials/credential_factory.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/builder.c \
+@USE_INTEGRITY_TEST_FALSE@ credentials/builder.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/keys/private_key.c \
+@USE_INTEGRITY_TEST_FALSE@ credentials/keys/private_key.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/keys/public_key.c \
+@USE_INTEGRITY_TEST_FALSE@ credentials/keys/public_key.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/keys/shared_key.c \
+@USE_INTEGRITY_TEST_FALSE@ credentials/keys/shared_key.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/certificate.c \
+@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/certificate.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/x509.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/x509.c \
+@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/ac.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/crl.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/crl.c \
+@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/ocsp_request.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/ocsp_response.h \
+@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/ocsp_response.c \
+@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher.h \
+@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher_manager.h \
+@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher_manager.c \
+@USE_INTEGRITY_TEST_FALSE@ database/database.h \
+@USE_INTEGRITY_TEST_FALSE@ database/database_factory.h \
+@USE_INTEGRITY_TEST_FALSE@ database/database_factory.c utils.h \
+@USE_INTEGRITY_TEST_FALSE@ utils.c utils/host.c utils/host.h \
@USE_INTEGRITY_TEST_FALSE@ utils/identification.c \
@USE_INTEGRITY_TEST_FALSE@ utils/identification.h \
-@USE_INTEGRITY_TEST_FALSE@ utils/iterator.h \
-@USE_INTEGRITY_TEST_FALSE@ utils/leak_detective.c \
-@USE_INTEGRITY_TEST_FALSE@ utils/leak_detective.h \
-@USE_INTEGRITY_TEST_FALSE@ utils/lexparser.c utils/lexparser.h \
+@USE_INTEGRITY_TEST_FALSE@ utils/iterator.h utils/lexparser.c \
+@USE_INTEGRITY_TEST_FALSE@ utils/lexparser.h \
@USE_INTEGRITY_TEST_FALSE@ utils/linked_list.c \
@USE_INTEGRITY_TEST_FALSE@ utils/linked_list.h \
@USE_INTEGRITY_TEST_FALSE@ utils/enumerator.c \
@USE_INTEGRITY_TEST_FALSE@ utils/enumerator.h \
@USE_INTEGRITY_TEST_FALSE@ utils/optionsfrom.c \
-@USE_INTEGRITY_TEST_FALSE@ utils/optionsfrom.h \
-@USE_INTEGRITY_TEST_FALSE@ utils/randomizer.c \
-@USE_INTEGRITY_TEST_FALSE@ utils/randomizer.h
+@USE_INTEGRITY_TEST_FALSE@ utils/optionsfrom.h utils/mutex.c \
+@USE_INTEGRITY_TEST_FALSE@ utils/mutex.h \
+@USE_INTEGRITY_TEST_FALSE@ plugins/plugin_loader.c \
+@USE_INTEGRITY_TEST_FALSE@ plugins/plugin_loader.h \
+@USE_INTEGRITY_TEST_FALSE@ plugins/plugin.h $(am__append_2)
@USE_INTEGRITY_TEST_TRUE@libstrongswan_la_SOURCES = \
@USE_INTEGRITY_TEST_TRUE@ fips/fips_canister_start.c \
-@USE_INTEGRITY_TEST_TRUE@ fips/fips.c fips/fips.h \
-@USE_INTEGRITY_TEST_TRUE@ credential_store.h library.c \
+@USE_INTEGRITY_TEST_TRUE@ fips/fips.c fips/fips.h library.c \
@USE_INTEGRITY_TEST_TRUE@ library.h chunk.c chunk.h debug.c \
-@USE_INTEGRITY_TEST_TRUE@ debug.h enum.c enum.h printf_hook.c \
+@USE_INTEGRITY_TEST_TRUE@ debug.h enum.c enum.h settings.h \
+@USE_INTEGRITY_TEST_TRUE@ settings.c printf_hook.c \
@USE_INTEGRITY_TEST_TRUE@ printf_hook.h asn1/asn1.c asn1/asn1.h \
+@USE_INTEGRITY_TEST_TRUE@ asn1/asn1_parser.c asn1/asn1_parser.h \
@USE_INTEGRITY_TEST_TRUE@ asn1/oid.c asn1/oid.h asn1/pem.c \
-@USE_INTEGRITY_TEST_TRUE@ asn1/pem.h asn1/ttodata.c \
-@USE_INTEGRITY_TEST_TRUE@ asn1/ttodata.h crypto/ac.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/ac.h crypto/ca.c crypto/ca.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/certinfo.c crypto/certinfo.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/crl.c crypto/crl.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/crypters/crypter.c \
+@USE_INTEGRITY_TEST_TRUE@ asn1/pem.h crypto/crypters/crypter.c \
@USE_INTEGRITY_TEST_TRUE@ crypto/crypters/crypter.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/crypters/aes_cbc_crypter.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/crypters/aes_cbc_crypter.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/crypters/des_crypter.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/crypters/des_crypter.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.h \
@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/hasher.h \
@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/hasher.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/sha1_hasher.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/sha1_hasher.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/sha2_hasher.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/sha2_hasher.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/md5_hasher.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/md5_hasher.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/hmac.c crypto/hmac.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/ietf_attr_list.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/ietf_attr_list.h crypto/ocsp.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/ocsp.h crypto/pkcs7.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/pkcs7.h crypto/pkcs9.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/pkcs9.h crypto/prfs/fips_prf.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/prfs/fips_prf.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/prfs/hmac_prf.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/prfs/hmac_prf.h \
+@USE_INTEGRITY_TEST_TRUE@ crypto/pkcs9.c crypto/pkcs9.h \
@USE_INTEGRITY_TEST_TRUE@ crypto/prfs/prf.c crypto/prfs/prf.h \
+@USE_INTEGRITY_TEST_TRUE@ crypto/rngs/rng.c crypto/rngs/rng.h \
@USE_INTEGRITY_TEST_TRUE@ crypto/prf_plus.h crypto/prf_plus.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/rsa/rsa_private_key.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/rsa/rsa_private_key.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/rsa/rsa_public_key.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/rsa/rsa_public_key.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/signers/hmac_signer.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/signers/hmac_signer.h \
@USE_INTEGRITY_TEST_TRUE@ crypto/signers/signer.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/signers/signer.h crypto/x509.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/x509.h utils/fetcher.c \
-@USE_INTEGRITY_TEST_TRUE@ utils/fetcher.h utils/host.c \
-@USE_INTEGRITY_TEST_TRUE@ utils/host.h utils/identification.c \
+@USE_INTEGRITY_TEST_TRUE@ crypto/signers/signer.h \
+@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.c \
+@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.h \
+@USE_INTEGRITY_TEST_TRUE@ crypto/crypto_factory.c \
+@USE_INTEGRITY_TEST_TRUE@ crypto/crypto_factory.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/credential_factory.c \
+@USE_INTEGRITY_TEST_TRUE@ credentials/credential_factory.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/builder.c \
+@USE_INTEGRITY_TEST_TRUE@ credentials/builder.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/keys/private_key.c \
+@USE_INTEGRITY_TEST_TRUE@ credentials/keys/private_key.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/keys/public_key.c \
+@USE_INTEGRITY_TEST_TRUE@ credentials/keys/public_key.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/keys/shared_key.c \
+@USE_INTEGRITY_TEST_TRUE@ credentials/keys/shared_key.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/certificate.c \
+@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/certificate.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/x509.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/x509.c \
+@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/ac.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/crl.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/crl.c \
+@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/ocsp_request.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/ocsp_response.h \
+@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/ocsp_response.c \
+@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher.h \
+@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher_manager.h \
+@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher_manager.c \
+@USE_INTEGRITY_TEST_TRUE@ database/database.h \
+@USE_INTEGRITY_TEST_TRUE@ database/database_factory.h \
+@USE_INTEGRITY_TEST_TRUE@ database/database_factory.c utils.h \
+@USE_INTEGRITY_TEST_TRUE@ utils.c utils/host.c utils/host.h \
+@USE_INTEGRITY_TEST_TRUE@ utils/identification.c \
@USE_INTEGRITY_TEST_TRUE@ utils/identification.h \
-@USE_INTEGRITY_TEST_TRUE@ utils/iterator.h \
-@USE_INTEGRITY_TEST_TRUE@ utils/leak_detective.c \
-@USE_INTEGRITY_TEST_TRUE@ utils/leak_detective.h \
-@USE_INTEGRITY_TEST_TRUE@ utils/lexparser.c utils/lexparser.h \
-@USE_INTEGRITY_TEST_TRUE@ utils/linked_list.c \
+@USE_INTEGRITY_TEST_TRUE@ utils/iterator.h utils/lexparser.c \
+@USE_INTEGRITY_TEST_TRUE@ utils/lexparser.h utils/linked_list.c \
@USE_INTEGRITY_TEST_TRUE@ utils/linked_list.h \
@USE_INTEGRITY_TEST_TRUE@ utils/enumerator.c utils/enumerator.h \
@USE_INTEGRITY_TEST_TRUE@ utils/optionsfrom.c \
-@USE_INTEGRITY_TEST_TRUE@ utils/optionsfrom.h \
-@USE_INTEGRITY_TEST_TRUE@ utils/randomizer.c utils/randomizer.h \
+@USE_INTEGRITY_TEST_TRUE@ utils/optionsfrom.h utils/mutex.c \
+@USE_INTEGRITY_TEST_TRUE@ utils/mutex.h plugins/plugin_loader.c \
+@USE_INTEGRITY_TEST_TRUE@ plugins/plugin_loader.h \
+@USE_INTEGRITY_TEST_TRUE@ plugins/plugin.h $(am__append_2) \
@USE_INTEGRITY_TEST_TRUE@ fips/fips_canister_end.c
-libstrongswan_la_LIBADD = -lgmp -lpthread $(am__append_1) \
- $(am__append_2) $(am__append_3)
+libstrongswan_la_LIBADD = -lpthread -ldl
INCLUDES = -I$(top_srcdir)/src/libstrongswan
-@USE_LEAK_DETECTIVE_TRUE@AM_CFLAGS = -DLEAK_DETECTIVE
+AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\" $(am__append_1) \
+ $(am__append_22)
EXTRA_DIST = asn1/oid.txt asn1/oid.pl
-BUILT_SOURCES = asn1/oid.c asn1/oid.h $(am__append_4)
+BUILT_SOURCES = asn1/oid.c asn1/oid.h $(am__append_21)
MAINTAINERCLEANFILES = asn1/oid.c asn1/oid.h
+
+# build plugins with their own Makefile
+#######################################
+SUBDIRS = . $(am__append_3) $(am__append_4) $(am__append_5) \
+ $(am__append_6) $(am__append_7) $(am__append_8) \
+ $(am__append_9) $(am__append_10) $(am__append_11) \
+ $(am__append_12) $(am__append_13) $(am__append_14) \
+ $(am__append_15) $(am__append_16) $(am__append_17) \
+ $(am__append_18) $(am__append_19) $(am__append_20)
@USE_INTEGRITY_TEST_TRUE@fips_signer_SOURCES = fips/fips_signer.c
@USE_INTEGRITY_TEST_TRUE@fips_signer_LDADD = libstrongswan.la
@USE_INTEGRITY_TEST_TRUE@CLEANFILES = fips_signature.h fips_signer
all: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) all-am
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
@@ -462,8 +508,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
@@ -471,8 +517,8 @@ uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
- $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
clean-libLTLIBRARIES:
@@ -502,53 +548,49 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_cbc_crypter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ca.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_parser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certificate.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chunk.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/credential_factory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_factory.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/database_factory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des_crypter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diffie_hellman.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enum.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enumerator.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetcher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetcher_manager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_canister_end.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_canister_start.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_prf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_signer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hasher.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac_prf.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac_signer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/host.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/identification.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ietf_attr_list.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/leak_detective.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lexparser.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/library.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linked_list.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_hasher.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mutex.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp_response.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oid.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optionsfrom.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs7.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs9.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_loader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf_plus.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf_hook.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/randomizer.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa_private_key.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa_public_key.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1_hasher.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/public_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rng.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settings.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shared_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signer.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttodata.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509.Plo@am__quote@
.c.o:
@@ -579,6 +621,13 @@ asn1.lo: asn1/asn1.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o asn1.lo `test -f 'asn1/asn1.c' || echo '$(srcdir)/'`asn1/asn1.c
+asn1_parser.lo: asn1/asn1_parser.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT asn1_parser.lo -MD -MP -MF $(DEPDIR)/asn1_parser.Tpo -c -o asn1_parser.lo `test -f 'asn1/asn1_parser.c' || echo '$(srcdir)/'`asn1/asn1_parser.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/asn1_parser.Tpo $(DEPDIR)/asn1_parser.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='asn1/asn1_parser.c' object='asn1_parser.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 asn1_parser.lo `test -f 'asn1/asn1_parser.c' || echo '$(srcdir)/'`asn1/asn1_parser.c
+
oid.lo: asn1/oid.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT oid.lo -MD -MP -MF $(DEPDIR)/oid.Tpo -c -o oid.lo `test -f 'asn1/oid.c' || echo '$(srcdir)/'`asn1/oid.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/oid.Tpo $(DEPDIR)/oid.Plo
@@ -593,41 +642,6 @@ pem.lo: asn1/pem.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pem.lo `test -f 'asn1/pem.c' || echo '$(srcdir)/'`asn1/pem.c
-ttodata.lo: asn1/ttodata.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ttodata.lo -MD -MP -MF $(DEPDIR)/ttodata.Tpo -c -o ttodata.lo `test -f 'asn1/ttodata.c' || echo '$(srcdir)/'`asn1/ttodata.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ttodata.Tpo $(DEPDIR)/ttodata.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='asn1/ttodata.c' object='ttodata.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 ttodata.lo `test -f 'asn1/ttodata.c' || echo '$(srcdir)/'`asn1/ttodata.c
-
-ac.lo: crypto/ac.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ac.lo -MD -MP -MF $(DEPDIR)/ac.Tpo -c -o ac.lo `test -f 'crypto/ac.c' || echo '$(srcdir)/'`crypto/ac.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ac.Tpo $(DEPDIR)/ac.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/ac.c' object='ac.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 ac.lo `test -f 'crypto/ac.c' || echo '$(srcdir)/'`crypto/ac.c
-
-ca.lo: crypto/ca.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ca.lo -MD -MP -MF $(DEPDIR)/ca.Tpo -c -o ca.lo `test -f 'crypto/ca.c' || echo '$(srcdir)/'`crypto/ca.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ca.Tpo $(DEPDIR)/ca.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/ca.c' object='ca.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 ca.lo `test -f 'crypto/ca.c' || echo '$(srcdir)/'`crypto/ca.c
-
-certinfo.lo: crypto/certinfo.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT certinfo.lo -MD -MP -MF $(DEPDIR)/certinfo.Tpo -c -o certinfo.lo `test -f 'crypto/certinfo.c' || echo '$(srcdir)/'`crypto/certinfo.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/certinfo.Tpo $(DEPDIR)/certinfo.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/certinfo.c' object='certinfo.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 certinfo.lo `test -f 'crypto/certinfo.c' || echo '$(srcdir)/'`crypto/certinfo.c
-
-crl.lo: crypto/crl.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crl.lo -MD -MP -MF $(DEPDIR)/crl.Tpo -c -o crl.lo `test -f 'crypto/crl.c' || echo '$(srcdir)/'`crypto/crl.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/crl.Tpo $(DEPDIR)/crl.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/crl.c' object='crl.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 crl.lo `test -f 'crypto/crl.c' || echo '$(srcdir)/'`crypto/crl.c
-
crypter.lo: crypto/crypters/crypter.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypter.lo -MD -MP -MF $(DEPDIR)/crypter.Tpo -c -o crypter.lo `test -f 'crypto/crypters/crypter.c' || echo '$(srcdir)/'`crypto/crypters/crypter.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/crypter.Tpo $(DEPDIR)/crypter.Plo
@@ -635,27 +649,6 @@ crypter.lo: crypto/crypters/crypter.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypter.lo `test -f 'crypto/crypters/crypter.c' || echo '$(srcdir)/'`crypto/crypters/crypter.c
-aes_cbc_crypter.lo: crypto/crypters/aes_cbc_crypter.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_cbc_crypter.lo -MD -MP -MF $(DEPDIR)/aes_cbc_crypter.Tpo -c -o aes_cbc_crypter.lo `test -f 'crypto/crypters/aes_cbc_crypter.c' || echo '$(srcdir)/'`crypto/crypters/aes_cbc_crypter.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/aes_cbc_crypter.Tpo $(DEPDIR)/aes_cbc_crypter.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/crypters/aes_cbc_crypter.c' object='aes_cbc_crypter.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes_cbc_crypter.lo `test -f 'crypto/crypters/aes_cbc_crypter.c' || echo '$(srcdir)/'`crypto/crypters/aes_cbc_crypter.c
-
-des_crypter.lo: crypto/crypters/des_crypter.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT des_crypter.lo -MD -MP -MF $(DEPDIR)/des_crypter.Tpo -c -o des_crypter.lo `test -f 'crypto/crypters/des_crypter.c' || echo '$(srcdir)/'`crypto/crypters/des_crypter.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/des_crypter.Tpo $(DEPDIR)/des_crypter.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/crypters/des_crypter.c' object='des_crypter.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 des_crypter.lo `test -f 'crypto/crypters/des_crypter.c' || echo '$(srcdir)/'`crypto/crypters/des_crypter.c
-
-diffie_hellman.lo: crypto/diffie_hellman.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT diffie_hellman.lo -MD -MP -MF $(DEPDIR)/diffie_hellman.Tpo -c -o diffie_hellman.lo `test -f 'crypto/diffie_hellman.c' || echo '$(srcdir)/'`crypto/diffie_hellman.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/diffie_hellman.Tpo $(DEPDIR)/diffie_hellman.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/diffie_hellman.c' object='diffie_hellman.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 diffie_hellman.lo `test -f 'crypto/diffie_hellman.c' || echo '$(srcdir)/'`crypto/diffie_hellman.c
-
hasher.lo: crypto/hashers/hasher.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hasher.lo -MD -MP -MF $(DEPDIR)/hasher.Tpo -c -o hasher.lo `test -f 'crypto/hashers/hasher.c' || echo '$(srcdir)/'`crypto/hashers/hasher.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/hasher.Tpo $(DEPDIR)/hasher.Plo
@@ -663,131 +656,131 @@ hasher.lo: crypto/hashers/hasher.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hasher.lo `test -f 'crypto/hashers/hasher.c' || echo '$(srcdir)/'`crypto/hashers/hasher.c
-sha1_hasher.lo: crypto/hashers/sha1_hasher.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha1_hasher.lo -MD -MP -MF $(DEPDIR)/sha1_hasher.Tpo -c -o sha1_hasher.lo `test -f 'crypto/hashers/sha1_hasher.c' || echo '$(srcdir)/'`crypto/hashers/sha1_hasher.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sha1_hasher.Tpo $(DEPDIR)/sha1_hasher.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/hashers/sha1_hasher.c' object='sha1_hasher.lo' libtool=yes @AMDEPBACKSLASH@
+pkcs9.lo: crypto/pkcs9.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pkcs9.lo -MD -MP -MF $(DEPDIR)/pkcs9.Tpo -c -o pkcs9.lo `test -f 'crypto/pkcs9.c' || echo '$(srcdir)/'`crypto/pkcs9.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pkcs9.Tpo $(DEPDIR)/pkcs9.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/pkcs9.c' object='pkcs9.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 sha1_hasher.lo `test -f 'crypto/hashers/sha1_hasher.c' || echo '$(srcdir)/'`crypto/hashers/sha1_hasher.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pkcs9.lo `test -f 'crypto/pkcs9.c' || echo '$(srcdir)/'`crypto/pkcs9.c
-sha2_hasher.lo: crypto/hashers/sha2_hasher.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha2_hasher.lo -MD -MP -MF $(DEPDIR)/sha2_hasher.Tpo -c -o sha2_hasher.lo `test -f 'crypto/hashers/sha2_hasher.c' || echo '$(srcdir)/'`crypto/hashers/sha2_hasher.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sha2_hasher.Tpo $(DEPDIR)/sha2_hasher.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/hashers/sha2_hasher.c' object='sha2_hasher.lo' libtool=yes @AMDEPBACKSLASH@
+prf.lo: crypto/prfs/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 prf.lo -MD -MP -MF $(DEPDIR)/prf.Tpo -c -o prf.lo `test -f 'crypto/prfs/prf.c' || echo '$(srcdir)/'`crypto/prfs/prf.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/prf.Tpo $(DEPDIR)/prf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prfs/prf.c' object='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 sha2_hasher.lo `test -f 'crypto/hashers/sha2_hasher.c' || echo '$(srcdir)/'`crypto/hashers/sha2_hasher.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o prf.lo `test -f 'crypto/prfs/prf.c' || echo '$(srcdir)/'`crypto/prfs/prf.c
-md5_hasher.lo: crypto/hashers/md5_hasher.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT md5_hasher.lo -MD -MP -MF $(DEPDIR)/md5_hasher.Tpo -c -o md5_hasher.lo `test -f 'crypto/hashers/md5_hasher.c' || echo '$(srcdir)/'`crypto/hashers/md5_hasher.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5_hasher.Tpo $(DEPDIR)/md5_hasher.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/hashers/md5_hasher.c' object='md5_hasher.lo' libtool=yes @AMDEPBACKSLASH@
+rng.lo: crypto/rngs/rng.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rng.lo -MD -MP -MF $(DEPDIR)/rng.Tpo -c -o rng.lo `test -f 'crypto/rngs/rng.c' || echo '$(srcdir)/'`crypto/rngs/rng.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rng.Tpo $(DEPDIR)/rng.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/rngs/rng.c' object='rng.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 md5_hasher.lo `test -f 'crypto/hashers/md5_hasher.c' || echo '$(srcdir)/'`crypto/hashers/md5_hasher.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rng.lo `test -f 'crypto/rngs/rng.c' || echo '$(srcdir)/'`crypto/rngs/rng.c
-hmac.lo: crypto/hmac.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hmac.lo -MD -MP -MF $(DEPDIR)/hmac.Tpo -c -o hmac.lo `test -f 'crypto/hmac.c' || echo '$(srcdir)/'`crypto/hmac.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/hmac.Tpo $(DEPDIR)/hmac.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/hmac.c' object='hmac.lo' libtool=yes @AMDEPBACKSLASH@
+prf_plus.lo: crypto/prf_plus.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT prf_plus.lo -MD -MP -MF $(DEPDIR)/prf_plus.Tpo -c -o prf_plus.lo `test -f 'crypto/prf_plus.c' || echo '$(srcdir)/'`crypto/prf_plus.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/prf_plus.Tpo $(DEPDIR)/prf_plus.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prf_plus.c' object='prf_plus.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 hmac.lo `test -f 'crypto/hmac.c' || echo '$(srcdir)/'`crypto/hmac.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o prf_plus.lo `test -f 'crypto/prf_plus.c' || echo '$(srcdir)/'`crypto/prf_plus.c
-ietf_attr_list.lo: crypto/ietf_attr_list.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ietf_attr_list.lo -MD -MP -MF $(DEPDIR)/ietf_attr_list.Tpo -c -o ietf_attr_list.lo `test -f 'crypto/ietf_attr_list.c' || echo '$(srcdir)/'`crypto/ietf_attr_list.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ietf_attr_list.Tpo $(DEPDIR)/ietf_attr_list.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/ietf_attr_list.c' object='ietf_attr_list.lo' libtool=yes @AMDEPBACKSLASH@
+signer.lo: crypto/signers/signer.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT signer.lo -MD -MP -MF $(DEPDIR)/signer.Tpo -c -o signer.lo `test -f 'crypto/signers/signer.c' || echo '$(srcdir)/'`crypto/signers/signer.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/signer.Tpo $(DEPDIR)/signer.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/signers/signer.c' object='signer.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ietf_attr_list.lo `test -f 'crypto/ietf_attr_list.c' || echo '$(srcdir)/'`crypto/ietf_attr_list.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o signer.lo `test -f 'crypto/signers/signer.c' || echo '$(srcdir)/'`crypto/signers/signer.c
-ocsp.lo: crypto/ocsp.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ocsp.lo -MD -MP -MF $(DEPDIR)/ocsp.Tpo -c -o ocsp.lo `test -f 'crypto/ocsp.c' || echo '$(srcdir)/'`crypto/ocsp.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ocsp.Tpo $(DEPDIR)/ocsp.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/ocsp.c' object='ocsp.lo' libtool=yes @AMDEPBACKSLASH@
+diffie_hellman.lo: crypto/diffie_hellman.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT diffie_hellman.lo -MD -MP -MF $(DEPDIR)/diffie_hellman.Tpo -c -o diffie_hellman.lo `test -f 'crypto/diffie_hellman.c' || echo '$(srcdir)/'`crypto/diffie_hellman.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/diffie_hellman.Tpo $(DEPDIR)/diffie_hellman.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/diffie_hellman.c' object='diffie_hellman.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 ocsp.lo `test -f 'crypto/ocsp.c' || echo '$(srcdir)/'`crypto/ocsp.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o diffie_hellman.lo `test -f 'crypto/diffie_hellman.c' || echo '$(srcdir)/'`crypto/diffie_hellman.c
-pkcs7.lo: crypto/pkcs7.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pkcs7.lo -MD -MP -MF $(DEPDIR)/pkcs7.Tpo -c -o pkcs7.lo `test -f 'crypto/pkcs7.c' || echo '$(srcdir)/'`crypto/pkcs7.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pkcs7.Tpo $(DEPDIR)/pkcs7.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/pkcs7.c' object='pkcs7.lo' libtool=yes @AMDEPBACKSLASH@
+crypto_factory.lo: crypto/crypto_factory.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_factory.lo -MD -MP -MF $(DEPDIR)/crypto_factory.Tpo -c -o crypto_factory.lo `test -f 'crypto/crypto_factory.c' || echo '$(srcdir)/'`crypto/crypto_factory.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/crypto_factory.Tpo $(DEPDIR)/crypto_factory.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/crypto_factory.c' object='crypto_factory.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 pkcs7.lo `test -f 'crypto/pkcs7.c' || echo '$(srcdir)/'`crypto/pkcs7.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_factory.lo `test -f 'crypto/crypto_factory.c' || echo '$(srcdir)/'`crypto/crypto_factory.c
-pkcs9.lo: crypto/pkcs9.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pkcs9.lo -MD -MP -MF $(DEPDIR)/pkcs9.Tpo -c -o pkcs9.lo `test -f 'crypto/pkcs9.c' || echo '$(srcdir)/'`crypto/pkcs9.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pkcs9.Tpo $(DEPDIR)/pkcs9.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/pkcs9.c' object='pkcs9.lo' libtool=yes @AMDEPBACKSLASH@
+credential_factory.lo: credentials/credential_factory.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT credential_factory.lo -MD -MP -MF $(DEPDIR)/credential_factory.Tpo -c -o credential_factory.lo `test -f 'credentials/credential_factory.c' || echo '$(srcdir)/'`credentials/credential_factory.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/credential_factory.Tpo $(DEPDIR)/credential_factory.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/credential_factory.c' object='credential_factory.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 pkcs9.lo `test -f 'crypto/pkcs9.c' || echo '$(srcdir)/'`crypto/pkcs9.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o credential_factory.lo `test -f 'credentials/credential_factory.c' || echo '$(srcdir)/'`credentials/credential_factory.c
-fips_prf.lo: crypto/prfs/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 fips_prf.lo -MD -MP -MF $(DEPDIR)/fips_prf.Tpo -c -o fips_prf.lo `test -f 'crypto/prfs/fips_prf.c' || echo '$(srcdir)/'`crypto/prfs/fips_prf.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fips_prf.Tpo $(DEPDIR)/fips_prf.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prfs/fips_prf.c' object='fips_prf.lo' libtool=yes @AMDEPBACKSLASH@
+builder.lo: credentials/builder.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT builder.lo -MD -MP -MF $(DEPDIR)/builder.Tpo -c -o builder.lo `test -f 'credentials/builder.c' || echo '$(srcdir)/'`credentials/builder.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/builder.Tpo $(DEPDIR)/builder.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/builder.c' object='builder.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 fips_prf.lo `test -f 'crypto/prfs/fips_prf.c' || echo '$(srcdir)/'`crypto/prfs/fips_prf.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o builder.lo `test -f 'credentials/builder.c' || echo '$(srcdir)/'`credentials/builder.c
-hmac_prf.lo: crypto/prfs/hmac_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 hmac_prf.lo -MD -MP -MF $(DEPDIR)/hmac_prf.Tpo -c -o hmac_prf.lo `test -f 'crypto/prfs/hmac_prf.c' || echo '$(srcdir)/'`crypto/prfs/hmac_prf.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/hmac_prf.Tpo $(DEPDIR)/hmac_prf.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prfs/hmac_prf.c' object='hmac_prf.lo' libtool=yes @AMDEPBACKSLASH@
+private_key.lo: credentials/keys/private_key.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT private_key.lo -MD -MP -MF $(DEPDIR)/private_key.Tpo -c -o private_key.lo `test -f 'credentials/keys/private_key.c' || echo '$(srcdir)/'`credentials/keys/private_key.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/private_key.Tpo $(DEPDIR)/private_key.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/keys/private_key.c' object='private_key.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 hmac_prf.lo `test -f 'crypto/prfs/hmac_prf.c' || echo '$(srcdir)/'`crypto/prfs/hmac_prf.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o private_key.lo `test -f 'credentials/keys/private_key.c' || echo '$(srcdir)/'`credentials/keys/private_key.c
-prf.lo: crypto/prfs/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 prf.lo -MD -MP -MF $(DEPDIR)/prf.Tpo -c -o prf.lo `test -f 'crypto/prfs/prf.c' || echo '$(srcdir)/'`crypto/prfs/prf.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/prf.Tpo $(DEPDIR)/prf.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prfs/prf.c' object='prf.lo' libtool=yes @AMDEPBACKSLASH@
+public_key.lo: credentials/keys/public_key.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT public_key.lo -MD -MP -MF $(DEPDIR)/public_key.Tpo -c -o public_key.lo `test -f 'credentials/keys/public_key.c' || echo '$(srcdir)/'`credentials/keys/public_key.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/public_key.Tpo $(DEPDIR)/public_key.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/keys/public_key.c' object='public_key.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 prf.lo `test -f 'crypto/prfs/prf.c' || echo '$(srcdir)/'`crypto/prfs/prf.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o public_key.lo `test -f 'credentials/keys/public_key.c' || echo '$(srcdir)/'`credentials/keys/public_key.c
-prf_plus.lo: crypto/prf_plus.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT prf_plus.lo -MD -MP -MF $(DEPDIR)/prf_plus.Tpo -c -o prf_plus.lo `test -f 'crypto/prf_plus.c' || echo '$(srcdir)/'`crypto/prf_plus.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/prf_plus.Tpo $(DEPDIR)/prf_plus.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prf_plus.c' object='prf_plus.lo' libtool=yes @AMDEPBACKSLASH@
+shared_key.lo: credentials/keys/shared_key.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared_key.lo -MD -MP -MF $(DEPDIR)/shared_key.Tpo -c -o shared_key.lo `test -f 'credentials/keys/shared_key.c' || echo '$(srcdir)/'`credentials/keys/shared_key.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/shared_key.Tpo $(DEPDIR)/shared_key.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/keys/shared_key.c' object='shared_key.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 prf_plus.lo `test -f 'crypto/prf_plus.c' || echo '$(srcdir)/'`crypto/prf_plus.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared_key.lo `test -f 'credentials/keys/shared_key.c' || echo '$(srcdir)/'`credentials/keys/shared_key.c
-rsa_private_key.lo: crypto/rsa/rsa_private_key.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsa_private_key.lo -MD -MP -MF $(DEPDIR)/rsa_private_key.Tpo -c -o rsa_private_key.lo `test -f 'crypto/rsa/rsa_private_key.c' || echo '$(srcdir)/'`crypto/rsa/rsa_private_key.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rsa_private_key.Tpo $(DEPDIR)/rsa_private_key.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/rsa/rsa_private_key.c' object='rsa_private_key.lo' libtool=yes @AMDEPBACKSLASH@
+certificate.lo: credentials/certificates/certificate.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT certificate.lo -MD -MP -MF $(DEPDIR)/certificate.Tpo -c -o certificate.lo `test -f 'credentials/certificates/certificate.c' || echo '$(srcdir)/'`credentials/certificates/certificate.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/certificate.Tpo $(DEPDIR)/certificate.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/certificates/certificate.c' object='certificate.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 rsa_private_key.lo `test -f 'crypto/rsa/rsa_private_key.c' || echo '$(srcdir)/'`crypto/rsa/rsa_private_key.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o certificate.lo `test -f 'credentials/certificates/certificate.c' || echo '$(srcdir)/'`credentials/certificates/certificate.c
-rsa_public_key.lo: crypto/rsa/rsa_public_key.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsa_public_key.lo -MD -MP -MF $(DEPDIR)/rsa_public_key.Tpo -c -o rsa_public_key.lo `test -f 'crypto/rsa/rsa_public_key.c' || echo '$(srcdir)/'`crypto/rsa/rsa_public_key.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rsa_public_key.Tpo $(DEPDIR)/rsa_public_key.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/rsa/rsa_public_key.c' object='rsa_public_key.lo' libtool=yes @AMDEPBACKSLASH@
+x509.lo: credentials/certificates/x509.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT x509.lo -MD -MP -MF $(DEPDIR)/x509.Tpo -c -o x509.lo `test -f 'credentials/certificates/x509.c' || echo '$(srcdir)/'`credentials/certificates/x509.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/x509.Tpo $(DEPDIR)/x509.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/certificates/x509.c' object='x509.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 rsa_public_key.lo `test -f 'crypto/rsa/rsa_public_key.c' || echo '$(srcdir)/'`crypto/rsa/rsa_public_key.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o x509.lo `test -f 'credentials/certificates/x509.c' || echo '$(srcdir)/'`credentials/certificates/x509.c
-hmac_signer.lo: crypto/signers/hmac_signer.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hmac_signer.lo -MD -MP -MF $(DEPDIR)/hmac_signer.Tpo -c -o hmac_signer.lo `test -f 'crypto/signers/hmac_signer.c' || echo '$(srcdir)/'`crypto/signers/hmac_signer.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/hmac_signer.Tpo $(DEPDIR)/hmac_signer.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/signers/hmac_signer.c' object='hmac_signer.lo' libtool=yes @AMDEPBACKSLASH@
+crl.lo: credentials/certificates/crl.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crl.lo -MD -MP -MF $(DEPDIR)/crl.Tpo -c -o crl.lo `test -f 'credentials/certificates/crl.c' || echo '$(srcdir)/'`credentials/certificates/crl.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/crl.Tpo $(DEPDIR)/crl.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/certificates/crl.c' object='crl.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 hmac_signer.lo `test -f 'crypto/signers/hmac_signer.c' || echo '$(srcdir)/'`crypto/signers/hmac_signer.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crl.lo `test -f 'credentials/certificates/crl.c' || echo '$(srcdir)/'`credentials/certificates/crl.c
-signer.lo: crypto/signers/signer.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT signer.lo -MD -MP -MF $(DEPDIR)/signer.Tpo -c -o signer.lo `test -f 'crypto/signers/signer.c' || echo '$(srcdir)/'`crypto/signers/signer.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/signer.Tpo $(DEPDIR)/signer.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/signers/signer.c' object='signer.lo' libtool=yes @AMDEPBACKSLASH@
+ocsp_response.lo: credentials/certificates/ocsp_response.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ocsp_response.lo -MD -MP -MF $(DEPDIR)/ocsp_response.Tpo -c -o ocsp_response.lo `test -f 'credentials/certificates/ocsp_response.c' || echo '$(srcdir)/'`credentials/certificates/ocsp_response.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ocsp_response.Tpo $(DEPDIR)/ocsp_response.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/certificates/ocsp_response.c' object='ocsp_response.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 signer.lo `test -f 'crypto/signers/signer.c' || echo '$(srcdir)/'`crypto/signers/signer.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ocsp_response.lo `test -f 'credentials/certificates/ocsp_response.c' || echo '$(srcdir)/'`credentials/certificates/ocsp_response.c
-x509.lo: crypto/x509.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT x509.lo -MD -MP -MF $(DEPDIR)/x509.Tpo -c -o x509.lo `test -f 'crypto/x509.c' || echo '$(srcdir)/'`crypto/x509.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/x509.Tpo $(DEPDIR)/x509.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/x509.c' object='x509.lo' libtool=yes @AMDEPBACKSLASH@
+fetcher_manager.lo: fetcher/fetcher_manager.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fetcher_manager.lo -MD -MP -MF $(DEPDIR)/fetcher_manager.Tpo -c -o fetcher_manager.lo `test -f 'fetcher/fetcher_manager.c' || echo '$(srcdir)/'`fetcher/fetcher_manager.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fetcher_manager.Tpo $(DEPDIR)/fetcher_manager.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fetcher/fetcher_manager.c' object='fetcher_manager.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o x509.lo `test -f 'crypto/x509.c' || echo '$(srcdir)/'`crypto/x509.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fetcher_manager.lo `test -f 'fetcher/fetcher_manager.c' || echo '$(srcdir)/'`fetcher/fetcher_manager.c
-fetcher.lo: utils/fetcher.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fetcher.lo -MD -MP -MF $(DEPDIR)/fetcher.Tpo -c -o fetcher.lo `test -f 'utils/fetcher.c' || echo '$(srcdir)/'`utils/fetcher.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fetcher.Tpo $(DEPDIR)/fetcher.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/fetcher.c' object='fetcher.lo' libtool=yes @AMDEPBACKSLASH@
+database_factory.lo: database/database_factory.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT database_factory.lo -MD -MP -MF $(DEPDIR)/database_factory.Tpo -c -o database_factory.lo `test -f 'database/database_factory.c' || echo '$(srcdir)/'`database/database_factory.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/database_factory.Tpo $(DEPDIR)/database_factory.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='database/database_factory.c' object='database_factory.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 fetcher.lo `test -f 'utils/fetcher.c' || echo '$(srcdir)/'`utils/fetcher.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o database_factory.lo `test -f 'database/database_factory.c' || echo '$(srcdir)/'`database/database_factory.c
host.lo: utils/host.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT host.lo -MD -MP -MF $(DEPDIR)/host.Tpo -c -o host.lo `test -f 'utils/host.c' || echo '$(srcdir)/'`utils/host.c
@@ -803,13 +796,6 @@ identification.lo: utils/identification.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o identification.lo `test -f 'utils/identification.c' || echo '$(srcdir)/'`utils/identification.c
-leak_detective.lo: utils/leak_detective.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT leak_detective.lo -MD -MP -MF $(DEPDIR)/leak_detective.Tpo -c -o leak_detective.lo `test -f 'utils/leak_detective.c' || echo '$(srcdir)/'`utils/leak_detective.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/leak_detective.Tpo $(DEPDIR)/leak_detective.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/leak_detective.c' object='leak_detective.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 leak_detective.lo `test -f 'utils/leak_detective.c' || echo '$(srcdir)/'`utils/leak_detective.c
-
lexparser.lo: utils/lexparser.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lexparser.lo -MD -MP -MF $(DEPDIR)/lexparser.Tpo -c -o lexparser.lo `test -f 'utils/lexparser.c' || echo '$(srcdir)/'`utils/lexparser.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lexparser.Tpo $(DEPDIR)/lexparser.Plo
@@ -838,12 +824,26 @@ optionsfrom.lo: utils/optionsfrom.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o optionsfrom.lo `test -f 'utils/optionsfrom.c' || echo '$(srcdir)/'`utils/optionsfrom.c
-randomizer.lo: utils/randomizer.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT randomizer.lo -MD -MP -MF $(DEPDIR)/randomizer.Tpo -c -o randomizer.lo `test -f 'utils/randomizer.c' || echo '$(srcdir)/'`utils/randomizer.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/randomizer.Tpo $(DEPDIR)/randomizer.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/randomizer.c' object='randomizer.lo' libtool=yes @AMDEPBACKSLASH@
+mutex.lo: utils/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 mutex.lo -MD -MP -MF $(DEPDIR)/mutex.Tpo -c -o mutex.lo `test -f 'utils/mutex.c' || echo '$(srcdir)/'`utils/mutex.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/mutex.Tpo $(DEPDIR)/mutex.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/mutex.c' object='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 randomizer.lo `test -f 'utils/randomizer.c' || echo '$(srcdir)/'`utils/randomizer.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mutex.lo `test -f 'utils/mutex.c' || echo '$(srcdir)/'`utils/mutex.c
+
+plugin_loader.lo: plugins/plugin_loader.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plugin_loader.lo -MD -MP -MF $(DEPDIR)/plugin_loader.Tpo -c -o plugin_loader.lo `test -f 'plugins/plugin_loader.c' || echo '$(srcdir)/'`plugins/plugin_loader.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/plugin_loader.Tpo $(DEPDIR)/plugin_loader.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugins/plugin_loader.c' object='plugin_loader.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o plugin_loader.lo `test -f 'plugins/plugin_loader.c' || echo '$(srcdir)/'`plugins/plugin_loader.c
+
+leak_detective.lo: utils/leak_detective.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT leak_detective.lo -MD -MP -MF $(DEPDIR)/leak_detective.Tpo -c -o leak_detective.lo `test -f 'utils/leak_detective.c' || echo '$(srcdir)/'`utils/leak_detective.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/leak_detective.Tpo $(DEPDIR)/leak_detective.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/leak_detective.c' object='leak_detective.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 leak_detective.lo `test -f 'utils/leak_detective.c' || echo '$(srcdir)/'`utils/leak_detective.c
fips_canister_start.lo: fips/fips_canister_start.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fips_canister_start.lo -MD -MP -MF $(DEPDIR)/fips_canister_start.Tpo -c -o fips_canister_start.lo `test -f 'fips/fips_canister_start.c' || echo '$(srcdir)/'`fips/fips_canister_start.c
@@ -886,42 +886,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
@@ -960,24 +1042,42 @@ 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: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) check-am
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
-installdirs:
+installdirs: installdirs-recursive
+installdirs-am:
for dir in "$(DESTDIR)$(libdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
+ $(MAKE) $(AM_MAKEFLAGS) 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 \
@@ -996,80 +1096,83 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-clean: clean-am
+clean: clean-recursive
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
clean-noinstPROGRAMS 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-dvi: install-dvi-am
+install-dvi: install-dvi-recursive
install-exec-am: install-libLTLIBRARIES
-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-libLTLIBRARIES
-.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-generic \
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS ctags \
- distclean distclean-compile distclean-generic \
+ ctags-recursive distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-libLTLIBRARIES install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags uninstall uninstall-am uninstall-libLTLIBRARIES
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-libLTLIBRARIES
asn1/oid.c : asn1/oid.txt asn1/oid.pl
diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c
index 3f0b829a9..524abfe5e 100644
--- a/src/libstrongswan/asn1/asn1.c
+++ b/src/libstrongswan/asn1/asn1.c
@@ -1,10 +1,3 @@
-/**
- * @file asn1.c
- *
- * @brief Simple ASN.1 parser
- *
- */
-
/*
* Copyright (C) 2006 Martin Will
* Copyright (C) 2000-2008 Andreas Steffen
@@ -21,19 +14,23 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: asn1.c 3451 2008-02-05 19:27:05Z andreas $
+ * $Id: asn1.c 4047 2008-06-10 07:36:44Z tobias $
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
-#include "asn1.h"
-
#include <library.h>
#include <debug.h>
-/* some common prefabricated ASN.1 constants */
+#include "oid.h"
+#include "asn1.h"
+#include "asn1_parser.h"
+
+/**
+ * some common prefabricated ASN.1 constants
+ */
static u_char ASN1_INTEGER_0_str[] = { 0x02, 0x00 };
static u_char ASN1_INTEGER_1_str[] = { 0x02, 0x01, 0x01 };
static u_char ASN1_INTEGER_2_str[] = { 0x02, 0x01, 0x02 };
@@ -42,7 +39,9 @@ const chunk_t ASN1_INTEGER_0 = chunk_from_buf(ASN1_INTEGER_0_str);
const chunk_t ASN1_INTEGER_1 = chunk_from_buf(ASN1_INTEGER_1_str);
const chunk_t ASN1_INTEGER_2 = chunk_from_buf(ASN1_INTEGER_2_str);
-/* some popular algorithmIdentifiers */
+/**
+ * some popular algorithmIdentifiers
+ */
static u_char ASN1_md2_id_str[] = {
0x30, 0x0c,
@@ -149,19 +148,8 @@ static const chunk_t ASN1_sha256WithRSA_id = chunk_from_buf(ASN1_sha256WithRSA_i
static const chunk_t ASN1_sha384WithRSA_id = chunk_from_buf(ASN1_sha384WithRSA_id_str);
static const chunk_t ASN1_sha512WithRSA_id = chunk_from_buf(ASN1_sha512WithRSA_id_str);
-/* ASN.1 definiton of an algorithmIdentifier */
-static const asn1Object_t algorithmIdentifierObjects[] = {
- { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */
- { 1, "parameters", ASN1_EOC, ASN1_RAW } /* 2 */
-};
-
-#define ALGORITHM_ID_ALG 1
-#define ALGORITHM_ID_PARAMETERS 2
-#define ALGORITHM_ID_ROOF 3
-
-/**
- * return the ASN.1 encoded algorithm identifier
+/*
+ * Defined in header.
*/
chunk_t asn1_algorithmIdentifier(int oid)
{
@@ -198,11 +186,10 @@ chunk_t asn1_algorithmIdentifier(int oid)
}
}
-/**
- * If the oid is listed in the oid_names table then the corresponding
- * position in the oid_names table is returned otherwise -1 is returned
+/*
+ * Defined in header.
*/
-int known_oid(chunk_t object)
+int asn1_known_oid(chunk_t object)
{
int oid = 0;
@@ -230,8 +217,8 @@ int known_oid(chunk_t object)
return -1;
}
-/**
- * Decodes the length in bytes of an ASN.1 object
+/*
+ * Defined in header.
*/
u_int asn1_length(chunk_t *blob)
{
@@ -278,26 +265,9 @@ u_int asn1_length(chunk_t *blob)
}
/**
- * determines if a character string is of type ASN.1 printableString
- */
-bool is_printablestring(chunk_t str)
-{
- const char printablestring_charset[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?";
- u_int i;
-
- for (i = 0; i < str.len; i++)
- {
- if (strchr(printablestring_charset, str.ptr[i]) == NULL)
- return FALSE;
- }
- return TRUE;
-}
-
-/**
* Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
*/
-time_t asn1totime(const chunk_t *utctime, asn1_t type)
+time_t asn1_to_time(const chunk_t *utctime, asn1_t type)
{
struct tm t;
time_t tz_offset;
@@ -372,7 +342,7 @@ time_t asn1totime(const chunk_t *utctime, asn1_t type)
/**
* Convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
*/
-chunk_t timetoasn1(const time_t *time, asn1_t type)
+chunk_t asn1_from_time(const time_t *time, asn1_t type)
{
int offset;
const char *format;
@@ -397,31 +367,17 @@ chunk_t timetoasn1(const time_t *time, asn1_t type)
return asn1_simple_object(type, formatted_time);
}
-
-/**
- * Initializes the internal context of the ASN.1 parser
- */
-void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0,
- bool implicit, bool private)
-{
- ctx->blobs[0] = blob;
- ctx->level0 = level0;
- ctx->implicit = implicit;
- ctx->private = private;
- memset(ctx->loopAddr, '\0', sizeof(ctx->loopAddr));
-}
-
-/**
- * print the value of an ASN.1 simple object
+/*
+ * Defined in header.
*/
-static void debug_asn1_simple_object(chunk_t object, asn1_t type, bool private)
+void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private)
{
int oid;
switch (type)
{
case ASN1_OID:
- oid = known_oid(object);
+ oid = asn1_known_oid(object);
if (oid != OID_UNKNOWN)
{
DBG2(" '%s'", oid_names[oid].name);
@@ -438,7 +394,7 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type, bool private)
case ASN1_UTCTIME:
case ASN1_GENERALIZEDTIME:
{
- time_t time = asn1totime(&object, type);
+ time_t time = asn1_to_time(&object, type);
DBG2(" '%T'", &time);
}
@@ -457,147 +413,9 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type, bool private)
}
/**
- * Parses and extracts the next ASN.1 object
- */
-bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx)
-{
- asn1Object_t obj = objects[*objectID];
- chunk_t *blob;
- chunk_t *blob1;
- u_char *start_ptr;
-
- *object = chunk_empty;
-
- if (obj.flags & ASN1_END) /* end of loop or option found */
- {
- if (ctx->loopAddr[obj.level] && ctx->blobs[obj.level+1].len > 0)
- {
- *objectID = ctx->loopAddr[obj.level]; /* another iteration */
- obj = objects[*objectID];
- }
- else
- {
- ctx->loopAddr[obj.level] = 0; /* exit loop or option*/
- return TRUE;
- }
- }
-
- *level = ctx->level0 + obj.level;
- blob = ctx->blobs + obj.level;
- blob1 = blob + 1;
- start_ptr = blob->ptr;
-
- /* handle ASN.1 defaults values */
- if ((obj.flags & ASN1_DEF) && (blob->len == 0 || *start_ptr != obj.type) )
- {
- /* field is missing */
- DBG2("L%d - %s:", *level, obj.name);
- if (obj.type & ASN1_CONSTRUCTED)
- {
- (*objectID)++ ; /* skip context-specific tag */
- }
- return TRUE;
- }
-
- /* handle ASN.1 options */
-
- if ((obj.flags & ASN1_OPT)
- && (blob->len == 0 || *start_ptr != obj.type))
- {
- /* advance to end of missing option field */
- do
- (*objectID)++;
- while (!((objects[*objectID].flags & ASN1_END)
- && (objects[*objectID].level == obj.level)));
- return TRUE;
- }
-
- /* an ASN.1 object must possess at least a tag and length field */
-
- if (blob->len < 2)
- {
- DBG1("L%d - %s: ASN.1 object smaller than 2 octets",
- *level, obj.name);
- return FALSE;
- }
-
- blob1->len = asn1_length(blob);
-
- if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len)
- {
- DBG1("L%d - %s: length of ASN.1 object invalid or too large",
- *level, obj.name);
- return FALSE;
- }
-
- blob1->ptr = blob->ptr;
- blob->ptr += blob1->len;
- blob->len -= blob1->len;
-
- /* return raw ASN.1 object without prior type checking */
-
- if (obj.flags & ASN1_RAW)
- {
- DBG2("L%d - %s:", *level, obj.name);
- object->ptr = start_ptr;
- object->len = (size_t)(blob->ptr - start_ptr);
- return TRUE;
- }
-
- if (*start_ptr != obj.type && !(ctx->implicit && *objectID == 0))
- {
- DBG1("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
- *level, obj.name, obj.type, *start_ptr);
- DBG3("%b", start_ptr, (u_int)(blob->ptr - start_ptr));
- return FALSE;
- }
-
- DBG2("L%d - %s:", ctx->level0+obj.level, obj.name);
-
- /* In case of "SEQUENCE OF" or "SET OF" start a loop */
- if (obj.flags & ASN1_LOOP)
- {
- if (blob1->len > 0)
- {
- /* at least one item, start the loop */
- ctx->loopAddr[obj.level] = *objectID + 1;
- }
- else
- {
- /* no items, advance directly to end of loop */
- do
- (*objectID)++;
- while (!((objects[*objectID].flags & ASN1_END)
- && (objects[*objectID].level == obj.level)));
- return TRUE;
- }
- }
-
- if (obj.flags & ASN1_OBJ)
- {
- object->ptr = start_ptr;
- object->len = (size_t)(blob->ptr - start_ptr);
- if (ctx->private)
- {
- DBG4("%B", object);
- }
- else
- {
- DBG3("%B", object);
- }
- }
- else if (obj.flags & ASN1_BODY)
- {
- *object = *blob1;
- debug_asn1_simple_object(*object, obj.type, ctx->private);
- }
- return TRUE;
-}
-
-/**
* parse an ASN.1 simple type
*/
-bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name)
+bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name)
{
size_t len;
@@ -625,44 +443,69 @@ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const c
}
DBG2("L%d - %s:", level, name);
- debug_asn1_simple_object(*object, type, FALSE);
+ asn1_debug_simple_object(*object, type, FALSE);
return TRUE;
}
/**
- * extracts an algorithmIdentifier
+ * ASN.1 definition of an algorithmIdentifier
+ */
+static const asn1Object_t algorithmIdentifierObjects[] = {
+ { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */
+ { 1, "parameters", ASN1_EOC, ASN1_RAW }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+/* parameters are optional in case of ecdsa-with-SHA1 as algorithm (RFC 3279) */
+static const asn1Object_t algorithmIdentifierObjectsOptional[] = {
+ { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */
+ { 1, "parameters", ASN1_EOC, ASN1_RAW|ASN1_OPT }, /* 2 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define ALGORITHM_ID_ALG 1
+#define ALGORITHM_ID_PARAMETERS 2
+
+/*
+ * Defined in header
*/
-int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
+int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
{
- asn1_ctx_t ctx;
+ asn1_parser_t *parser;
chunk_t object;
- u_int level;
+ int objectID;
int alg = OID_UNKNOWN;
- int objectID = 0;
+ const asn1Object_t *objects = algorithmIdentifierObjectsOptional;
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
+ if (parameters != NULL)
+ {
+ objects = algorithmIdentifierObjects;
+ }
+
+ parser = asn1_parser_create(objects, blob);
+ parser->set_top_level(parser, level0);
- while (objectID < ALGORITHM_ID_ROOF)
+ while (parser->iterate(parser, &objectID, &object))
{
- if (!extract_object(algorithmIdentifierObjects, &objectID, &object, &level, &ctx))
- return OID_UNKNOWN;
-
switch (objectID)
{
case ALGORITHM_ID_ALG:
- alg = known_oid(object);
+ alg = asn1_known_oid(object);
break;
case ALGORITHM_ID_PARAMETERS:
if (parameters != NULL)
+ {
*parameters = object;
+ }
break;
default:
break;
}
- objectID++;
}
+ parser->destroy(parser);
return alg;
- }
+}
/*
* tests if a blob contains a valid ASN.1 set or sequence
@@ -696,10 +539,27 @@ bool is_asn1(chunk_t blob)
return FALSE;
}
+/*
+ * Defined in header.
+ */
+bool asn1_is_printablestring(chunk_t str)
+{
+ const char printablestring_charset[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?";
+ u_int i;
+
+ for (i = 0; i < str.len; i++)
+ {
+ if (strchr(printablestring_charset, str.ptr[i]) == NULL)
+ return FALSE;
+ }
+ return TRUE;
+}
+
/**
* codes ASN.1 lengths up to a size of 16'777'215 bytes
*/
-void code_asn1_length(size_t length, chunk_t *code)
+static void asn1_code_length(size_t length, chunk_t *code)
{
if (length < 128)
{
@@ -732,14 +592,14 @@ void code_asn1_length(size_t length, chunk_t *code)
/**
* build an empty asn.1 object with tag and length fields already filled in
*/
-u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen)
+u_char* asn1_build_object(chunk_t *object, asn1_t type, size_t datalen)
{
u_char length_buf[4];
chunk_t length = { length_buf, 0 };
u_char *pos;
/* code the asn.1 length field */
- code_asn1_length(datalen, &length);
+ asn1_code_length(datalen, &length);
/* allocate memory for the asn.1 TLV object */
object->len = 1 + length.len + datalen;
@@ -759,13 +619,13 @@ u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen)
}
/**
- * build a simple ASN.1 object
+ * Build a simple ASN.1 object
*/
chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
{
chunk_t object;
- u_char *pos = build_asn1_object(&object, tag, content.len);
+ u_char *pos = asn1_build_object(&object, tag, content.len);
memcpy(pos, content.ptr, content.len);
pos += content.len;
@@ -778,7 +638,7 @@ chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
chunk_t asn1_bitstring(const char *mode, chunk_t content)
{
chunk_t object;
- u_char *pos = build_asn1_object(&object, ASN1_BIT_STRING, 1 + content.len);
+ u_char *pos = asn1_build_object(&object, ASN1_BIT_STRING, 1 + content.len);
*pos++ = 0x00;
memcpy(pos, content.ptr, content.len);
@@ -812,7 +672,7 @@ chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
va_end(chunks);
/* allocate needed memory for construct */
- pos = build_asn1_object(&construct, type, construct.len);
+ pos = asn1_build_object(&construct, type, construct.len);
/* copy or move the chunks */
va_start(chunks, mode);
@@ -834,55 +694,39 @@ chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
}
/**
- * convert a MP integer into a DER coded ASN.1 object
- */
-chunk_t asn1_integer_from_mpz(const mpz_t value)
-{
- size_t bits = mpz_sizeinbase(value, 2); /* size in bits */
- chunk_t n;
-
- n.len = 1 + bits / 8; /* size in bytes */
- n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
-
- return asn1_wrap(ASN1_INTEGER, "m", n);
-}
-
-/**
* ASN.1 definition of time
*/
static const asn1Object_t timeObjects[] = {
- { 0, "utcTime", ASN1_UTCTIME, ASN1_OPT|ASN1_BODY }, /* 0 */
- { 0, "end opt", ASN1_EOC, ASN1_END }, /* 1 */
- { 0, "generalizeTime",ASN1_GENERALIZEDTIME, ASN1_OPT|ASN1_BODY }, /* 2 */
- { 0, "end opt", ASN1_EOC, ASN1_END } /* 3 */
+ { 0, "utcTime", ASN1_UTCTIME, ASN1_OPT|ASN1_BODY }, /* 0 */
+ { 0, "end opt", ASN1_EOC, ASN1_END }, /* 1 */
+ { 0, "generalizeTime", ASN1_GENERALIZEDTIME, ASN1_OPT|ASN1_BODY }, /* 2 */
+ { 0, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
#define TIME_UTC 0
#define TIME_GENERALIZED 2
-#define TIME_ROOF 4
/**
* extracts and converts a UTCTIME or GENERALIZEDTIME object
*/
-time_t parse_time(chunk_t blob, int level0)
+time_t asn1_parse_time(chunk_t blob, int level0)
{
- asn1_ctx_t ctx;
+ asn1_parser_t *parser;
chunk_t object;
- u_int level;
- int objectID = 0;
+ int objectID;
+ time_t utc_time = 0;
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
+ parser= asn1_parser_create(timeObjects, blob);
+ parser->set_top_level(parser, level0);
- while (objectID < TIME_ROOF)
+ while (parser->iterate(parser, &objectID, &object))
{
- if (!extract_object(timeObjects, &objectID, &object, &level, &ctx))
- return 0;
-
if (objectID == TIME_UTC || objectID == TIME_GENERALIZED)
{
- return asn1totime(&object, (objectID == TIME_UTC)
- ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME);
+ utc_time = asn1_to_time(&object, (objectID == TIME_UTC)
+ ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME);
}
- objectID++;
}
- return 0;
+ parser->destroy(parser);
+ return utc_time;
}
diff --git a/src/libstrongswan/asn1/asn1.h b/src/libstrongswan/asn1/asn1.h
index d9d85ba44..0f2e6e5c0 100644
--- a/src/libstrongswan/asn1/asn1.h
+++ b/src/libstrongswan/asn1/asn1.h
@@ -1,10 +1,3 @@
-/**
- * @file asn1.h
- *
- * @brief Simple ASN.1 parser
- *
- */
-
/*
* Copyright (C) 2006 Martin Will
* Copyright (C) 2000-2008 Andreas Steffen
@@ -21,23 +14,23 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: asn1.h 3423 2008-01-22 10:32:37Z andreas $
+ * $Id: asn1.h 3876 2008-04-26 09:24:14Z andreas $
+ */
+
+/**
+ * @defgroup asn1i asn1
+ * @{ @ingroup asn1
*/
-#ifndef _ASN1_H
-#define _ASN1_H
+#ifndef ASN1_H_
+#define ASN1_H_
#include <stdarg.h>
-#include <gmp.h>
#include <library.h>
-#include <asn1/oid.h>
-
/**
- * @brief Definition of some primitive ASN1 types
- *
- * @ingroup asn1
+ * Definition of some primitive ASN1 types
*/
typedef enum {
ASN1_EOC = 0x00,
@@ -65,7 +58,6 @@ typedef enum {
ASN1_CONSTRUCTED = 0x20,
ASN1_SEQUENCE = 0x30,
-
ASN1_SET = 0x31,
ASN1_CONTEXT_S_0 = 0x80,
@@ -86,64 +78,155 @@ typedef enum {
ASN1_CONTEXT_C_5 = 0xA5
} asn1_t;
-/* Definition of ASN1 flags */
+#define ASN1_INVALID_LENGTH 0xffffffff
-#define ASN1_NONE 0x00
-#define ASN1_DEF 0x01
-#define ASN1_OPT 0x02
-#define ASN1_LOOP 0x04
-#define ASN1_END 0x08
-#define ASN1_OBJ 0x10
-#define ASN1_BODY 0x20
-#define ASN1_RAW 0x40
+/**
+ * Some common prefabricated ASN.1 constants
+ */
+extern const chunk_t ASN1_INTEGER_0;
+extern const chunk_t ASN1_INTEGER_1;
+extern const chunk_t ASN1_INTEGER_2;
-#define ASN1_INVALID_LENGTH 0xffffffff
-/* definition of an ASN.1 object */
+/** Some ASN.1 analysis functions */
-typedef struct {
- u_int level;
- const u_char *name;
- asn1_t type;
- u_char flags;
-} asn1Object_t;
+/**
+ * Returns some popular algorithmIdentifiers
+ *
+ * @param oid known OID index
+ * @return body of the corresponding OID
+ */
+chunk_t asn1_algorithmIdentifier(int oid);
-#define ASN1_MAX_LEVEL 10
+/**
+ * Converts an ASN.1 OID into a known OID index
+ *
+ * @param object body of an OID
+ * @return index into the oid_names[] table or OID_UNKNOWN
+ */
+int asn1_known_oid(chunk_t object);
-typedef struct {
- bool implicit;
- bool private;
- u_int level0;
- u_int loopAddr[ASN1_MAX_LEVEL+1];
- chunk_t blobs[ASN1_MAX_LEVEL+2];
-} asn1_ctx_t;
+/**
+ * Returns the length of an ASN.1 object
+ * The blob pointer is advanced past the tag length fields
+ *
+ * @param pointer to an ASN.1 coded blob
+ * @return length of ASN.1 object
+ */
+u_int asn1_length(chunk_t *blob);
-/* some common prefabricated ASN.1 constants */
-extern const chunk_t ASN1_INTEGER_0;
-extern const chunk_t ASN1_INTEGER_1;
-extern const chunk_t ASN1_INTEGER_2;
+/**
+ * Parses an ASN.1 algorithmIdentifier object
+ *
+ * @param blob ASN.1 coded blob
+ * @param level0 top-most level offset
+ * @param params returns optional [ASN.1 coded] parameters
+ * @return known OID index or OID_UNKNOWN
+ */
+int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *params);
+
+/**
+ * Parse the top-most level of an ASN.1 object
+ *
+ * @param object ASN.1 coded object
+ * @param type Expected ASN.1 type
+ * @param level0 top-most level offset
+ * @param name descriptive name of object
+ * @return TRUE if parsing successful
+ */
+bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level0,
+ const char* name);
+
+/**
+ * Print the value of an ASN.1 simple object
+ *
+ * @param object ASN.1 object to be printed
+ * @param type asn1_t type
+ * @param private ASN.1 data is confidential (use debug level 4)
+ */
+void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private);
+
+/**
+ * Converts an ASN.1 UTCTIME or GENERALIZEDTIME string to time_t
+ *
+ * @param utctime body of an ASN.1 coded time object
+ * @param type ASN1_UTCTIME or ASN1_GENERALIZEDTIME
+ * @return time_t in UTC
+ */
+time_t asn1_to_time(const chunk_t *utctime, asn1_t type);
+
+/**
+ * Converts time_t to an ASN.1 UTCTIME or GENERALIZEDTIME string
+ *
+ * @param time time_t in UTC
+ * @param type ASN1_UTCTIME or ASN1_GENERALIZEDTIME
+ * @return body of an ASN.1 code time object
+ */
+chunk_t asn1_from_time(const time_t *time, asn1_t type);
+
+/**
+ * Parse an ASN.1 UTCTIME or GENERALIZEDTIME object
+ *
+ * @param blob ASN.1 coded time object
+ * @param level top-most level offset
+ * @return time_t in UTC
+ */
+time_t asn1_parse_time(chunk_t blob, int level0);
+
+/**
+ * Determines if a binary blob is ASN.1 coded
+ *
+ * @param blob blob to be tested
+ * @return TRUE if blob is ASN.1 coded (SEQUENCE or SET)
+ */
+bool is_asn1(chunk_t blob);
+
+/**
+ * Determines if a character string can be coded as PRINTABLESTRING
+ *
+ * @param str character string to be tested
+ * @return TRUE if no special characters are contained
+ */
+bool asn1_is_printablestring(chunk_t str);
+
+
+/** some ASN.1 synthesis functions */
+
+/**
+ * Build an empty ASN.1 object with tag and length fields already filled in
+ *
+ * @param object returned object - memory is allocated by function
+ * @param type ASN.1 type to be created
+ * @param datalen size of the body to be created
+ * @return points to the first position in the body
+ */
+u_char* asn1_build_object(chunk_t *object, asn1_t type, size_t datalen);
+
+/**
+ * Build a simple ASN.1 object
+ *
+ * @param tag ASN.1 type to be created
+ * @param content content of the ASN.1 object
+ * @return chunk containing the ASN.1 coded object
+ */
+chunk_t asn1_simple_object(asn1_t tag, chunk_t content);
+
+/**
+ * Build an ASN.1 BITSTRING object
+ *
+ * @param mode 'c' for copy or 'm' for move
+ * @param content content of the BITSTRING
+ * @return chunk containing the ASN.1 coded BITSTRING
+ */
+chunk_t asn1_bitstring(const char *mode, chunk_t content);
+
+/**
+ * Build an ASN.1 object from a variable number of individual chunks
+ *
+ * @param typ ASN.1 type to be created
+ * @param mode for each list member: 'c' for copy or 'm' for move
+ * @return chunk containing the ASN.1 coded object
+ */
+chunk_t asn1_wrap(asn1_t type, const char *mode, ...);
-/* returns some popular algorithmIdentifiers */
-extern chunk_t asn1_algorithmIdentifier(int oid);
-
-extern int known_oid(chunk_t object);
-extern u_int asn1_length(chunk_t *blob);
-extern bool is_printablestring(chunk_t str);
-extern time_t asn1totime(const chunk_t *utctime, asn1_t type);
-extern chunk_t timetoasn1(const time_t *time, asn1_t type);
-extern void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit, bool private);
-extern bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx);
-extern bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name);
-extern int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters);
-extern time_t parse_time(chunk_t blob, int level0);
-
-extern bool is_asn1(chunk_t blob);
-
-extern void code_asn1_length(size_t length, chunk_t *code);
-extern u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen);
-extern chunk_t asn1_integer_from_mpz(const mpz_t value);
-extern chunk_t asn1_simple_object(asn1_t tag, chunk_t content);
-extern chunk_t asn1_bitstring(const char *mode, chunk_t content);
-extern chunk_t asn1_wrap(asn1_t type, const char *mode, ...);
-
-#endif /* _ASN1_H */
+#endif /* ASN1_H_ @}*/
diff --git a/src/libstrongswan/asn1/asn1_parser.c b/src/libstrongswan/asn1/asn1_parser.c
new file mode 100644
index 000000000..7a2028fc3
--- /dev/null
+++ b/src/libstrongswan/asn1/asn1_parser.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2006 Martin Will
+ * Copyright (C) 2000-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: asn1_parser.c 3894 2008-04-28 18:44:21Z andreas $
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include <library.h>
+#include <debug.h>
+
+#include "asn1.h"
+#include "asn1_parser.h"
+
+#define ASN1_MAX_LEVEL 10
+
+typedef struct private_asn1_parser_t private_asn1_parser_t;
+
+/**
+ * Private data of an asn1_cxt_t object.
+ */
+struct private_asn1_parser_t {
+ /**
+ * Public interface.
+ */
+ asn1_parser_t public;
+
+ /**
+ * Syntax definition of ASN.1 object
+ */
+ asn1Object_t const *objects;
+
+ /**
+ * Current syntax definition line
+ */
+ int line;
+
+ /**
+ * Current stat of the parsing operation
+ */
+ bool success;
+
+ /**
+ * Declare object data as private - use debug level 4 to log it
+ */
+ bool private;
+
+ /**
+ * Top-most type is implicit - ignore it
+ */
+ bool implicit;
+
+ /**
+ * Top-most parsing level - defaults to 0
+ */
+ u_int level0;
+
+ /**
+ * Jump back address for loops for each level
+ */
+ int loopAddr[ASN1_MAX_LEVEL + 1];
+
+ /**
+ * Current parsing pointer for each level
+ */
+ chunk_t blobs[ASN1_MAX_LEVEL + 2];
+};
+
+/**
+ * Implementation of asn1_parser_t.iterate
+ */
+static bool iterate(private_asn1_parser_t *this, int *objectID, chunk_t *object)
+{
+ chunk_t *blob, *blob1;
+ u_char *start_ptr;
+ u_int level;
+ asn1Object_t obj;
+
+ *object = chunk_empty;
+
+ /* Advance to the next object syntax definition line */
+ obj = this->objects[++(this->line)];
+
+ /* Terminate if the end of the object syntax definition has been reached */
+ if (obj.flags & ASN1_EXIT)
+ {
+ return FALSE;
+ }
+
+ if (obj.flags & ASN1_END) /* end of loop or option found */
+ {
+ if (this->loopAddr[obj.level] && this->blobs[obj.level+1].len > 0)
+ {
+ this->line = this->loopAddr[obj.level]; /* another iteration */
+ obj = this->objects[this->line];
+ }
+ else
+ {
+ this->loopAddr[obj.level] = 0; /* exit loop or option*/
+ goto end;
+ }
+ }
+
+ level = this->level0 + obj.level;
+ blob = this->blobs + obj.level;
+ blob1 = blob + 1;
+ start_ptr = blob->ptr;
+
+ /* handle ASN.1 defaults values */
+ if ((obj.flags & ASN1_DEF) && (blob->len == 0 || *start_ptr != obj.type) )
+ {
+ /* field is missing */
+ DBG2("L%d - %s:", level, obj.name);
+ if (obj.type & ASN1_CONSTRUCTED)
+ {
+ this->line++ ; /* skip context-specific tag */
+ }
+ goto end;
+ }
+
+ /* handle ASN.1 options */
+
+ if ((obj.flags & ASN1_OPT)
+ && (blob->len == 0 || *start_ptr != obj.type))
+ {
+ /* advance to end of missing option field */
+ do
+ {
+ this->line++;
+ }
+ while (!((this->objects[this->line].flags & ASN1_END) &&
+ (this->objects[this->line].level == obj.level)));
+ goto end;
+ }
+
+ /* an ASN.1 object must possess at least a tag and length field */
+
+ if (blob->len < 2)
+ {
+ DBG1("L%d - %s: ASN.1 object smaller than 2 octets",
+ level, obj.name);
+ this->success = FALSE;
+ goto end;
+ }
+
+ blob1->len = asn1_length(blob);
+
+ if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len)
+ {
+ DBG1("L%d - %s: length of ASN.1 object invalid or too large",
+ level, obj.name);
+ this->success = FALSE;
+ }
+
+ blob1->ptr = blob->ptr;
+ blob->ptr += blob1->len;
+ blob->len -= blob1->len;
+
+ /* return raw ASN.1 object without prior type checking */
+
+ if (obj.flags & ASN1_RAW)
+ {
+ DBG2("L%d - %s:", level, obj.name);
+ object->ptr = start_ptr;
+ object->len = (size_t)(blob->ptr - start_ptr);
+ goto end;
+ }
+
+ if (*start_ptr != obj.type && !(this->implicit && this->line == 0))
+ {
+ DBG1("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
+ level, obj.name, obj.type, *start_ptr);
+ DBG3("%b", start_ptr, (u_int)(blob->ptr - start_ptr));
+ this->success = FALSE;
+ goto end;
+ }
+
+ DBG2("L%d - %s:", level, obj.name);
+
+ /* In case of "SEQUENCE OF" or "SET OF" start a loop */
+ if (obj.flags & ASN1_LOOP)
+ {
+ if (blob1->len > 0)
+ {
+ /* at least one item, start the loop */
+ this->loopAddr[obj.level] = this->line + 1;
+ }
+ else
+ {
+ /* no items, advance directly to end of loop */
+ do
+ {
+ this->line++;
+ }
+ while (!((this->objects[this->line].flags & ASN1_END) &&
+ (this->objects[this->line].level == obj.level)));
+ goto end;
+ }
+ }
+
+ if (obj.flags & ASN1_OBJ)
+ {
+ object->ptr = start_ptr;
+ object->len = (size_t)(blob->ptr - start_ptr);
+ if (this->private)
+ {
+ DBG4("%B", object);
+ }
+ else
+ {
+ DBG3("%B", object);
+ }
+ }
+ else if (obj.flags & ASN1_BODY)
+ {
+ *object = *blob1;
+ asn1_debug_simple_object(*object, obj.type, this->private);
+ }
+
+end:
+ *objectID = this->line;
+ return this->success;
+}
+
+/**
+ * Implementation of asn1_parser_t.get_level
+ */
+static u_int get_level(private_asn1_parser_t *this)
+{
+ return this->level0 + this->objects[this->line].level;
+}
+
+/**
+ * Implementation of asn1_parser_t.set_top_level
+ */
+static void set_top_level(private_asn1_parser_t *this, u_int level0)
+{
+ this->level0 = level0;
+}
+
+/**
+ * Implementation of asn1_parser_t.set_flags
+ */
+static void set_flags(private_asn1_parser_t *this, bool implicit, bool private)
+{
+ this->implicit = implicit;
+ this->private = private;
+}
+
+/**
+ * Implementation of asn1_parser_t.success
+ */
+static bool success(private_asn1_parser_t *this)
+{
+ return this->success;
+}
+
+/**
+ * Implementation of asn1_parser_t.destroy
+ */
+static void destroy(private_asn1_parser_t *this)
+{
+ free(this);
+}
+
+/**
+ * Defined in header.
+ */
+asn1_parser_t* asn1_parser_create(asn1Object_t const *objects, chunk_t blob)
+{
+ private_asn1_parser_t *this = malloc_thing(private_asn1_parser_t);
+
+ memset(this, '\0', sizeof(private_asn1_parser_t));
+ this->objects = objects;
+ this->blobs[0] = blob;
+ this->line = -1;
+ this->success = TRUE;
+
+ this->public.iterate = (bool (*)(asn1_parser_t*, int*, chunk_t*))iterate;
+ this->public.get_level = (u_int (*)(asn1_parser_t*))get_level;
+ this->public.set_top_level = (void (*)(asn1_parser_t*, u_int))set_top_level;
+ this->public.set_flags = (void (*)(asn1_parser_t*, bool, bool))set_flags;
+ this->public.success = (bool (*)(asn1_parser_t*))success;
+ this->public.destroy = (void (*)(asn1_parser_t*))destroy;
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/asn1/asn1_parser.h b/src/libstrongswan/asn1/asn1_parser.h
new file mode 100644
index 000000000..d84a5336f
--- /dev/null
+++ b/src/libstrongswan/asn1/asn1_parser.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2006 Martin Will
+ * Copyright (C) 2000-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: asn1_parser.h 3894 2008-04-28 18:44:21Z andreas $
+ */
+
+/**
+ * @defgroup asn1_parser asn1_parser
+ * @{ @ingroup asn1
+ */
+
+#ifndef ASN1_PARSER_H_
+#define ASN1_PARSER_H_
+
+#include <stdarg.h>
+
+#include <library.h>
+
+/**
+ * Definition of ASN.1 flags
+ */
+#define ASN1_NONE 0x00
+#define ASN1_DEF 0x01
+#define ASN1_OPT 0x02
+#define ASN1_LOOP 0x04
+#define ASN1_END 0x08
+#define ASN1_OBJ 0x10
+#define ASN1_BODY 0x20
+#define ASN1_RAW 0x40
+#define ASN1_EXIT 0x80
+
+typedef struct asn1Object_t asn1Object_t;
+
+/**
+ * Syntax definition of an ASN.1 object
+ */
+struct asn1Object_t{
+ u_int level;
+ const u_char *name;
+ asn1_t type;
+ u_char flags;
+};
+
+typedef struct asn1_parser_t asn1_parser_t;
+
+/**
+ * Public interface of an ASN.1 parser
+ */
+struct asn1_parser_t {
+
+ /**
+ * Parse the next ASN.1 object in the hierarchy and return it
+ *
+ * @param objectID current line in the object syntax definition
+ * @param object current object
+ * @return - FALSE if end of object syntax definition was reached
+ * or a parsing error occurred
+ * - TRUE otherwise
+ */
+ bool (*iterate)(asn1_parser_t *this, int *objectID, chunk_t *object);
+
+ /**
+ * Get the current parsing level
+ *
+ * @return current level
+ */
+ u_int (*get_level)(asn1_parser_t *this);
+
+ /**
+ * Set the top-most level
+ *
+ * @param level top-most level
+ */
+ void (*set_top_level)(asn1_parser_t *this, u_int level0);
+
+ /**
+ * Set implicit and private flags
+ *
+ * @param implicit top-most type of object is implicit
+ * @param private object data is private (use debug level 4)
+ */
+ void (*set_flags)(asn1_parser_t *this, bool implicit, bool private);
+
+ /**
+ * Show final parsing status
+ *
+ * @return TRUE if parsing was successful, FALSE otherwise
+ */
+ bool (*success)(asn1_parser_t *this);
+
+ /**
+ * Destroy the ASN.1 parser
+ */
+ void (*destroy)(asn1_parser_t *this);
+};
+
+/**
+ * Create an ASN.1 parser
+ *
+ * @param objects syntax definition of the ASN.1 object to be parsed
+ * @param blob ASN.1 coded binary blob
+ * @return ASN.1 context
+ */
+asn1_parser_t* asn1_parser_create(asn1Object_t const *objects, chunk_t blob);
+
+#endif /* ASN1_PARSER_H_ @}*/
diff --git a/src/libstrongswan/asn1/oid.c b/src/libstrongswan/asn1/oid.c
index 63896be6b..f9eb26d1d 100644
--- a/src/libstrongswan/asn1/oid.c
+++ b/src/libstrongswan/asn1/oid.c
@@ -62,10 +62,10 @@ const oid_t oid_names[] = {
{ 0x25, 50, 0, "extendedKeyUsage" }, /* 49 */
{ 0x37, 51, 0, "targetInformation" }, /* 50 */
{ 0x38, 0, 0, "noRevAvail" }, /* 51 */
- {0x2A, 95, 1, "" }, /* 52 */
+ {0x2A, 131, 1, "" }, /* 52 */
{ 0x86, 0, 1, "" }, /* 53 */
{ 0x48, 0, 1, "" }, /* 54 */
- { 0x86, 0, 1, "" }, /* 55 */
+ { 0x86, 95, 1, "" }, /* 55 */
{ 0xF6, 61, 1, "" }, /* 56 */
{ 0x7D, 0, 1, "NortelNetworks" }, /* 57 */
{ 0x07, 0, 1, "Entrust" }, /* 58 */
@@ -105,105 +105,175 @@ const oid_t oid_names[] = {
{ 0x05, 0, 0, "md5" }, /* 92 */
{ 0x03, 0, 1, "encryptionAlgorithm" }, /* 93 */
{ 0x07, 0, 0, "3des-ede-cbc" }, /* 94 */
- {0x2B, 161, 1, "" }, /* 95 */
- { 0x06, 148, 1, "dod" }, /* 96 */
- { 0x01, 0, 1, "internet" }, /* 97 */
- { 0x04, 116, 1, "private" }, /* 98 */
- { 0x01, 0, 1, "enterprise" }, /* 99 */
- { 0x82, 109, 1, "" }, /* 100 */
- { 0x37, 0, 1, "Microsoft" }, /* 101 */
- { 0x0A, 106, 1, "" }, /* 102 */
- { 0x03, 0, 1, "" }, /* 103 */
- { 0x03, 105, 0, "msSGC" }, /* 104 */
- { 0x04, 0, 0, "msEncryptingFileSystem" }, /* 105 */
- { 0x14, 0, 1, "msEnrollmentInfrastructure"}, /* 106 */
- { 0x02, 0, 1, "msCertificateTypeExtension"}, /* 107 */
- { 0x02, 0, 0, "msSmartcardLogon" }, /* 108 */
- { 0x89, 0, 1, "" }, /* 109 */
- { 0x31, 0, 1, "" }, /* 110 */
- { 0x01, 0, 1, "" }, /* 111 */
- { 0x01, 0, 1, "" }, /* 112 */
- { 0x02, 0, 1, "" }, /* 113 */
- { 0x02, 115, 0, "" }, /* 114 */
- { 0x4B, 0, 0, "TCGID" }, /* 115 */
- { 0x05, 0, 1, "security" }, /* 116 */
- { 0x05, 0, 1, "mechanisms" }, /* 117 */
- { 0x07, 0, 1, "id-pkix" }, /* 118 */
- { 0x01, 121, 1, "id-pe" }, /* 119 */
- { 0x01, 0, 0, "authorityInfoAccess" }, /* 120 */
- { 0x03, 131, 1, "id-kp" }, /* 121 */
- { 0x01, 123, 0, "serverAuth" }, /* 122 */
- { 0x02, 124, 0, "clientAuth" }, /* 123 */
- { 0x03, 125, 0, "codeSigning" }, /* 124 */
- { 0x04, 126, 0, "emailProtection" }, /* 125 */
- { 0x05, 127, 0, "ipsecEndSystem" }, /* 126 */
- { 0x06, 128, 0, "ipsecTunnel" }, /* 127 */
- { 0x07, 129, 0, "ipsecUser" }, /* 128 */
- { 0x08, 130, 0, "timeStamping" }, /* 129 */
- { 0x09, 0, 0, "ocspSigning" }, /* 130 */
- { 0x08, 133, 1, "id-otherNames" }, /* 131 */
- { 0x05, 0, 0, "xmppAddr" }, /* 132 */
- { 0x0A, 138, 1, "id-aca" }, /* 133 */
- { 0x01, 135, 0, "authenticationInfo" }, /* 134 */
- { 0x02, 136, 0, "accessIdentity" }, /* 135 */
- { 0x03, 137, 0, "chargingIdentity" }, /* 136 */
- { 0x04, 0, 0, "group" }, /* 137 */
- { 0x30, 0, 1, "id-ad" }, /* 138 */
- { 0x01, 147, 1, "ocsp" }, /* 139 */
- { 0x01, 141, 0, "basic" }, /* 140 */
- { 0x02, 142, 0, "nonce" }, /* 141 */
- { 0x03, 143, 0, "crl" }, /* 142 */
- { 0x04, 144, 0, "response" }, /* 143 */
- { 0x05, 145, 0, "noCheck" }, /* 144 */
- { 0x06, 146, 0, "archiveCutoff" }, /* 145 */
- { 0x07, 0, 0, "serviceLocator" }, /* 146 */
- { 0x02, 0, 0, "caIssuers" }, /* 147 */
- { 0x0E, 154, 1, "oiw" }, /* 148 */
- { 0x03, 0, 1, "secsig" }, /* 149 */
- { 0x02, 0, 1, "algorithms" }, /* 150 */
- { 0x07, 152, 0, "des-cbc" }, /* 151 */
- { 0x1A, 153, 0, "sha-1" }, /* 152 */
- { 0x1D, 0, 0, "sha-1WithRSASignature" }, /* 153 */
- { 0x24, 0, 1, "TeleTrusT" }, /* 154 */
- { 0x03, 0, 1, "algorithm" }, /* 155 */
- { 0x03, 0, 1, "signatureAlgorithm" }, /* 156 */
- { 0x01, 0, 1, "rsaSignature" }, /* 157 */
- { 0x02, 159, 0, "rsaSigWithripemd160" }, /* 158 */
- { 0x03, 160, 0, "rsaSigWithripemd128" }, /* 159 */
- { 0x04, 0, 0, "rsaSigWithripemd256" }, /* 160 */
- {0x60, 0, 1, "" }, /* 161 */
- { 0x86, 0, 1, "" }, /* 162 */
- { 0x48, 0, 1, "" }, /* 163 */
- { 0x01, 0, 1, "organization" }, /* 164 */
- { 0x65, 172, 1, "gov" }, /* 165 */
- { 0x03, 0, 1, "csor" }, /* 166 */
- { 0x04, 0, 1, "nistalgorithm" }, /* 167 */
- { 0x02, 0, 1, "hashalgs" }, /* 168 */
- { 0x01, 170, 0, "id-SHA-256" }, /* 169 */
- { 0x02, 171, 0, "id-SHA-384" }, /* 170 */
- { 0x03, 0, 0, "id-SHA-512" }, /* 171 */
- { 0x86, 0, 1, "" }, /* 172 */
- { 0xf8, 0, 1, "" }, /* 173 */
- { 0x42, 186, 1, "netscape" }, /* 174 */
- { 0x01, 181, 1, "" }, /* 175 */
- { 0x01, 177, 0, "nsCertType" }, /* 176 */
- { 0x03, 178, 0, "nsRevocationUrl" }, /* 177 */
- { 0x04, 179, 0, "nsCaRevocationUrl" }, /* 178 */
- { 0x08, 180, 0, "nsCaPolicyUrl" }, /* 179 */
- { 0x0d, 0, 0, "nsComment" }, /* 180 */
- { 0x03, 184, 1, "directory" }, /* 181 */
- { 0x01, 0, 1, "" }, /* 182 */
- { 0x03, 0, 0, "employeeNumber" }, /* 183 */
- { 0x04, 0, 1, "policy" }, /* 184 */
- { 0x01, 0, 0, "nsSGC" }, /* 185 */
- { 0x45, 0, 1, "verisign" }, /* 186 */
- { 0x01, 0, 1, "pki" }, /* 187 */
- { 0x09, 0, 1, "attributes" }, /* 188 */
- { 0x02, 190, 0, "messageType" }, /* 189 */
- { 0x03, 191, 0, "pkiStatus" }, /* 190 */
- { 0x04, 192, 0, "failInfo" }, /* 191 */
- { 0x05, 193, 0, "senderNonce" }, /* 192 */
- { 0x06, 194, 0, "recipientNonce" }, /* 193 */
- { 0x07, 195, 0, "transID" }, /* 194 */
- { 0x08, 0, 0, "extensionReq" } /* 195 */
+ { 0xCE, 0, 1, "" }, /* 95 */
+ { 0x3D, 0, 1, "ansi-X9-62" }, /* 96 */
+ { 0x02, 99, 1, "id-publicKeyType" }, /* 97 */
+ { 0x01, 0, 0, "id-ecPublicKey" }, /* 98 */
+ { 0x03, 129, 1, "ellipticCurve" }, /* 99 */
+ { 0x00, 121, 1, "c-TwoCurve" }, /* 100 */
+ { 0x01, 102, 0, "c2pnb163v1" }, /* 101 */
+ { 0x02, 103, 0, "c2pnb163v2" }, /* 102 */
+ { 0x03, 104, 0, "c2pnb163v3" }, /* 103 */
+ { 0x04, 105, 0, "c2pnb176w1" }, /* 104 */
+ { 0x05, 106, 0, "c2tnb191v1" }, /* 105 */
+ { 0x06, 107, 0, "c2tnb191v2" }, /* 106 */
+ { 0x07, 108, 0, "c2tnb191v3" }, /* 107 */
+ { 0x08, 109, 0, "c2onb191v4" }, /* 108 */
+ { 0x09, 110, 0, "c2onb191v5" }, /* 109 */
+ { 0x0A, 111, 0, "c2pnb208w1" }, /* 110 */
+ { 0x0B, 112, 0, "c2tnb239v1" }, /* 111 */
+ { 0x0C, 113, 0, "c2tnb239v2" }, /* 112 */
+ { 0x0D, 114, 0, "c2tnb239v3" }, /* 113 */
+ { 0x0E, 115, 0, "c2onb239v4" }, /* 114 */
+ { 0x0F, 116, 0, "c2onb239v5" }, /* 115 */
+ { 0x10, 117, 0, "c2pnb272w1" }, /* 116 */
+ { 0x11, 118, 0, "c2pnb304w1" }, /* 117 */
+ { 0x12, 119, 0, "c2tnb359v1" }, /* 118 */
+ { 0x13, 120, 0, "c2pnb368w1" }, /* 119 */
+ { 0x14, 0, 0, "c2tnb431r1" }, /* 120 */
+ { 0x01, 0, 1, "primeCurve" }, /* 121 */
+ { 0x01, 123, 0, "prime192v1" }, /* 122 */
+ { 0x02, 124, 0, "prime192v2" }, /* 123 */
+ { 0x03, 125, 0, "prime192v3" }, /* 124 */
+ { 0x04, 126, 0, "prime239v1" }, /* 125 */
+ { 0x05, 127, 0, "prime239v2" }, /* 126 */
+ { 0x06, 128, 0, "prime239v3" }, /* 127 */
+ { 0x07, 0, 0, "prime256v1" }, /* 128 */
+ { 0x04, 0, 1, "id-ecSigType" }, /* 129 */
+ { 0x01, 0, 0, "ecdsa-with-SHA1" }, /* 130 */
+ {0x2B, 231, 1, "" }, /* 131 */
+ { 0x06, 184, 1, "dod" }, /* 132 */
+ { 0x01, 0, 1, "internet" }, /* 133 */
+ { 0x04, 152, 1, "private" }, /* 134 */
+ { 0x01, 0, 1, "enterprise" }, /* 135 */
+ { 0x82, 145, 1, "" }, /* 136 */
+ { 0x37, 0, 1, "Microsoft" }, /* 137 */
+ { 0x0A, 142, 1, "" }, /* 138 */
+ { 0x03, 0, 1, "" }, /* 139 */
+ { 0x03, 141, 0, "msSGC" }, /* 140 */
+ { 0x04, 0, 0, "msEncryptingFileSystem" }, /* 141 */
+ { 0x14, 0, 1, "msEnrollmentInfrastructure"}, /* 142 */
+ { 0x02, 0, 1, "msCertificateTypeExtension"}, /* 143 */
+ { 0x02, 0, 0, "msSmartcardLogon" }, /* 144 */
+ { 0x89, 0, 1, "" }, /* 145 */
+ { 0x31, 0, 1, "" }, /* 146 */
+ { 0x01, 0, 1, "" }, /* 147 */
+ { 0x01, 0, 1, "" }, /* 148 */
+ { 0x02, 0, 1, "" }, /* 149 */
+ { 0x02, 151, 0, "" }, /* 150 */
+ { 0x4B, 0, 0, "TCGID" }, /* 151 */
+ { 0x05, 0, 1, "security" }, /* 152 */
+ { 0x05, 0, 1, "mechanisms" }, /* 153 */
+ { 0x07, 0, 1, "id-pkix" }, /* 154 */
+ { 0x01, 157, 1, "id-pe" }, /* 155 */
+ { 0x01, 0, 0, "authorityInfoAccess" }, /* 156 */
+ { 0x03, 167, 1, "id-kp" }, /* 157 */
+ { 0x01, 159, 0, "serverAuth" }, /* 158 */
+ { 0x02, 160, 0, "clientAuth" }, /* 159 */
+ { 0x03, 161, 0, "codeSigning" }, /* 160 */
+ { 0x04, 162, 0, "emailProtection" }, /* 161 */
+ { 0x05, 163, 0, "ipsecEndSystem" }, /* 162 */
+ { 0x06, 164, 0, "ipsecTunnel" }, /* 163 */
+ { 0x07, 165, 0, "ipsecUser" }, /* 164 */
+ { 0x08, 166, 0, "timeStamping" }, /* 165 */
+ { 0x09, 0, 0, "ocspSigning" }, /* 166 */
+ { 0x08, 169, 1, "id-otherNames" }, /* 167 */
+ { 0x05, 0, 0, "xmppAddr" }, /* 168 */
+ { 0x0A, 174, 1, "id-aca" }, /* 169 */
+ { 0x01, 171, 0, "authenticationInfo" }, /* 170 */
+ { 0x02, 172, 0, "accessIdentity" }, /* 171 */
+ { 0x03, 173, 0, "chargingIdentity" }, /* 172 */
+ { 0x04, 0, 0, "group" }, /* 173 */
+ { 0x30, 0, 1, "id-ad" }, /* 174 */
+ { 0x01, 183, 1, "ocsp" }, /* 175 */
+ { 0x01, 177, 0, "basic" }, /* 176 */
+ { 0x02, 178, 0, "nonce" }, /* 177 */
+ { 0x03, 179, 0, "crl" }, /* 178 */
+ { 0x04, 180, 0, "response" }, /* 179 */
+ { 0x05, 181, 0, "noCheck" }, /* 180 */
+ { 0x06, 182, 0, "archiveCutoff" }, /* 181 */
+ { 0x07, 0, 0, "serviceLocator" }, /* 182 */
+ { 0x02, 0, 0, "caIssuers" }, /* 183 */
+ { 0x0E, 190, 1, "oiw" }, /* 184 */
+ { 0x03, 0, 1, "secsig" }, /* 185 */
+ { 0x02, 0, 1, "algorithms" }, /* 186 */
+ { 0x07, 188, 0, "des-cbc" }, /* 187 */
+ { 0x1A, 189, 0, "sha-1" }, /* 188 */
+ { 0x1D, 0, 0, "sha-1WithRSASignature" }, /* 189 */
+ { 0x24, 197, 1, "TeleTrusT" }, /* 190 */
+ { 0x03, 0, 1, "algorithm" }, /* 191 */
+ { 0x03, 0, 1, "signatureAlgorithm" }, /* 192 */
+ { 0x01, 0, 1, "rsaSignature" }, /* 193 */
+ { 0x02, 195, 0, "rsaSigWithripemd160" }, /* 194 */
+ { 0x03, 196, 0, "rsaSigWithripemd128" }, /* 195 */
+ { 0x04, 0, 0, "rsaSigWithripemd256" }, /* 196 */
+ { 0x81, 0, 1, "" }, /* 197 */
+ { 0x04, 0, 1, "Certicom" }, /* 198 */
+ { 0x00, 0, 1, "curve" }, /* 199 */
+ { 0x01, 201, 0, "sect163k1" }, /* 200 */
+ { 0x02, 202, 0, "sect163r1" }, /* 201 */
+ { 0x03, 203, 0, "sect239k1" }, /* 202 */
+ { 0x04, 204, 0, "sect113r1" }, /* 203 */
+ { 0x05, 205, 0, "sect113r2" }, /* 204 */
+ { 0x06, 206, 0, "secp112r1" }, /* 205 */
+ { 0x07, 207, 0, "secp112r2" }, /* 206 */
+ { 0x08, 208, 0, "secp160r1" }, /* 207 */
+ { 0x09, 209, 0, "secp160k1" }, /* 208 */
+ { 0x0A, 210, 0, "secp256k1" }, /* 209 */
+ { 0x0F, 211, 0, "sect163r2" }, /* 210 */
+ { 0x10, 212, 0, "sect283k1" }, /* 211 */
+ { 0x11, 213, 0, "sect283r1" }, /* 212 */
+ { 0x16, 214, 0, "sect131r1" }, /* 213 */
+ { 0x17, 215, 0, "sect131r2" }, /* 214 */
+ { 0x18, 216, 0, "sect193r1" }, /* 215 */
+ { 0x19, 217, 0, "sect193r2" }, /* 216 */
+ { 0x1A, 218, 0, "sect233k1" }, /* 217 */
+ { 0x1B, 219, 0, "sect233r1" }, /* 218 */
+ { 0x1C, 220, 0, "secp128r1" }, /* 219 */
+ { 0x1D, 221, 0, "secp128r2" }, /* 220 */
+ { 0x1E, 222, 0, "secp160r2" }, /* 221 */
+ { 0x1F, 223, 0, "secp192k1" }, /* 222 */
+ { 0x20, 224, 0, "secp224k1" }, /* 223 */
+ { 0x21, 225, 0, "secp224r1" }, /* 224 */
+ { 0x22, 226, 0, "secp384r1" }, /* 225 */
+ { 0x23, 227, 0, "secp521r1" }, /* 226 */
+ { 0x24, 228, 0, "sect409k1" }, /* 227 */
+ { 0x25, 229, 0, "sect409r1" }, /* 228 */
+ { 0x26, 230, 0, "sect571k1" }, /* 229 */
+ { 0x27, 0, 0, "sect571r1" }, /* 230 */
+ {0x60, 0, 1, "" }, /* 231 */
+ { 0x86, 0, 1, "" }, /* 232 */
+ { 0x48, 0, 1, "" }, /* 233 */
+ { 0x01, 0, 1, "organization" }, /* 234 */
+ { 0x65, 242, 1, "gov" }, /* 235 */
+ { 0x03, 0, 1, "csor" }, /* 236 */
+ { 0x04, 0, 1, "nistalgorithm" }, /* 237 */
+ { 0x02, 0, 1, "hashalgs" }, /* 238 */
+ { 0x01, 240, 0, "id-SHA-256" }, /* 239 */
+ { 0x02, 241, 0, "id-SHA-384" }, /* 240 */
+ { 0x03, 0, 0, "id-SHA-512" }, /* 241 */
+ { 0x86, 0, 1, "" }, /* 242 */
+ { 0xf8, 0, 1, "" }, /* 243 */
+ { 0x42, 256, 1, "netscape" }, /* 244 */
+ { 0x01, 251, 1, "" }, /* 245 */
+ { 0x01, 247, 0, "nsCertType" }, /* 246 */
+ { 0x03, 248, 0, "nsRevocationUrl" }, /* 247 */
+ { 0x04, 249, 0, "nsCaRevocationUrl" }, /* 248 */
+ { 0x08, 250, 0, "nsCaPolicyUrl" }, /* 249 */
+ { 0x0d, 0, 0, "nsComment" }, /* 250 */
+ { 0x03, 254, 1, "directory" }, /* 251 */
+ { 0x01, 0, 1, "" }, /* 252 */
+ { 0x03, 0, 0, "employeeNumber" }, /* 253 */
+ { 0x04, 0, 1, "policy" }, /* 254 */
+ { 0x01, 0, 0, "nsSGC" }, /* 255 */
+ { 0x45, 0, 1, "verisign" }, /* 256 */
+ { 0x01, 0, 1, "pki" }, /* 257 */
+ { 0x09, 0, 1, "attributes" }, /* 258 */
+ { 0x02, 260, 0, "messageType" }, /* 259 */
+ { 0x03, 261, 0, "pkiStatus" }, /* 260 */
+ { 0x04, 262, 0, "failInfo" }, /* 261 */
+ { 0x05, 263, 0, "senderNonce" }, /* 262 */
+ { 0x06, 264, 0, "recipientNonce" }, /* 263 */
+ { 0x07, 265, 0, "transID" }, /* 264 */
+ { 0x08, 0, 0, "extensionReq" } /* 265 */
};
diff --git a/src/libstrongswan/asn1/oid.h b/src/libstrongswan/asn1/oid.h
index 9980221ab..a0fb95f18 100644
--- a/src/libstrongswan/asn1/oid.h
+++ b/src/libstrongswan/asn1/oid.h
@@ -49,37 +49,97 @@ extern const oid_t oid_names[];
#define OID_MD2 91
#define OID_MD5 92
#define OID_3DES_EDE_CBC 94
-#define OID_AUTHORITY_INFO_ACCESS 120
-#define OID_OCSP_SIGNING 130
-#define OID_XMPP_ADDR 132
-#define OID_AUTHENTICATION_INFO 134
-#define OID_ACCESS_IDENTITY 135
-#define OID_CHARGING_IDENTITY 136
-#define OID_GROUP 137
-#define OID_OCSP 139
-#define OID_BASIC 140
-#define OID_NONCE 141
-#define OID_CRL 142
-#define OID_RESPONSE 143
-#define OID_NO_CHECK 144
-#define OID_ARCHIVE_CUTOFF 145
-#define OID_SERVICE_LOCATOR 146
-#define OID_CA_ISSUERS 147
-#define OID_DES_CBC 151
-#define OID_SHA1 152
-#define OID_SHA1_WITH_RSA_OIW 153
-#define OID_SHA256 169
-#define OID_SHA384 170
-#define OID_SHA512 171
-#define OID_NS_REVOCATION_URL 177
-#define OID_NS_CA_REVOCATION_URL 178
-#define OID_NS_CA_POLICY_URL 179
-#define OID_NS_COMMENT 180
-#define OID_PKI_MESSAGE_TYPE 189
-#define OID_PKI_STATUS 190
-#define OID_PKI_FAIL_INFO 191
-#define OID_PKI_SENDER_NONCE 192
-#define OID_PKI_RECIPIENT_NONCE 193
-#define OID_PKI_TRANS_ID 194
+#define OID_EC_PUBLICKEY 98
+#define OID_C2PNB163V1 101
+#define OID_C2PNB163V2 102
+#define OID_C2PNB163V3 103
+#define OID_C2PNB176W1 104
+#define OID_C2PNB191V1 105
+#define OID_C2PNB191V2 106
+#define OID_C2PNB191V3 107
+#define OID_C2PNB191V4 108
+#define OID_C2PNB191V5 109
+#define OID_C2PNB208W1 110
+#define OID_C2PNB239V1 111
+#define OID_C2PNB239V2 112
+#define OID_C2PNB239V3 113
+#define OID_C2PNB239V4 114
+#define OID_C2PNB239V5 115
+#define OID_C2PNB272W1 116
+#define OID_C2PNB304W1 117
+#define OID_C2PNB359V1 118
+#define OID_C2PNB368W1 119
+#define OID_C2PNB431R1 120
+#define OID_PRIME192V1 122
+#define OID_PRIME192V2 123
+#define OID_PRIME192V3 124
+#define OID_PRIME239V1 125
+#define OID_PRIME239V2 126
+#define OID_PRIME239V3 127
+#define OID_PRIME256V1 128
+#define OID_ECDSA_WITH_SHA1 130
+#define OID_AUTHORITY_INFO_ACCESS 156
+#define OID_OCSP_SIGNING 166
+#define OID_XMPP_ADDR 168
+#define OID_AUTHENTICATION_INFO 170
+#define OID_ACCESS_IDENTITY 171
+#define OID_CHARGING_IDENTITY 172
+#define OID_GROUP 173
+#define OID_OCSP 175
+#define OID_BASIC 176
+#define OID_NONCE 177
+#define OID_CRL 178
+#define OID_RESPONSE 179
+#define OID_NO_CHECK 180
+#define OID_ARCHIVE_CUTOFF 181
+#define OID_SERVICE_LOCATOR 182
+#define OID_CA_ISSUERS 183
+#define OID_DES_CBC 187
+#define OID_SHA1 188
+#define OID_SHA1_WITH_RSA_OIW 189
+#define OID_SECT163K1 200
+#define OID_SECT163R1 201
+#define OID_SECT239K1 202
+#define OID_SECT113R1 203
+#define OID_SECT113R2 204
+#define OID_SECT112R1 205
+#define OID_SECT112R2 206
+#define OID_SECT160R1 207
+#define OID_SECT160K1 208
+#define OID_SECT256K1 209
+#define OID_SECT163R2 210
+#define OID_SECT283K1 211
+#define OID_SECT283R1 212
+#define OID_SECT131R1 213
+#define OID_SECT131R2 214
+#define OID_SECT193R1 215
+#define OID_SECT193R2 216
+#define OID_SECT233K1 217
+#define OID_SECT233R1 218
+#define OID_SECT128R1 219
+#define OID_SECT128R2 220
+#define OID_SECT160R2 221
+#define OID_SECT192K1 222
+#define OID_SECT224K1 223
+#define OID_SECT224R1 224
+#define OID_SECT384R1 225
+#define OID_SECT521R1 226
+#define OID_SECT409K1 227
+#define OID_SECT409R1 228
+#define OID_SECT571K1 229
+#define OID_SECT571R1 230
+#define OID_SHA256 239
+#define OID_SHA384 240
+#define OID_SHA512 241
+#define OID_NS_REVOCATION_URL 247
+#define OID_NS_CA_REVOCATION_URL 248
+#define OID_NS_CA_POLICY_URL 249
+#define OID_NS_COMMENT 250
+#define OID_PKI_MESSAGE_TYPE 259
+#define OID_PKI_STATUS 260
+#define OID_PKI_FAIL_INFO 261
+#define OID_PKI_SENDER_NONCE 262
+#define OID_PKI_RECIPIENT_NONCE 263
+#define OID_PKI_TRANS_ID 264
#endif /* OID_H_ */
diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt
index e6dede287..6bb765787 100644
--- a/src/libstrongswan/asn1/oid.txt
+++ b/src/libstrongswan/asn1/oid.txt
@@ -93,6 +93,42 @@
0x05 "md5" OID_MD5
0x03 "encryptionAlgorithm"
0x07 "3des-ede-cbc" OID_3DES_EDE_CBC
+ 0xCE ""
+ 0x3D "ansi-X9-62"
+ 0x02 "id-publicKeyType"
+ 0x01 "id-ecPublicKey" OID_EC_PUBLICKEY
+ 0x03 "ellipticCurve"
+ 0x00 "c-TwoCurve"
+ 0x01 "c2pnb163v1" OID_C2PNB163V1
+ 0x02 "c2pnb163v2" OID_C2PNB163V2
+ 0x03 "c2pnb163v3" OID_C2PNB163V3
+ 0x04 "c2pnb176w1" OID_C2PNB176W1
+ 0x05 "c2tnb191v1" OID_C2PNB191V1
+ 0x06 "c2tnb191v2" OID_C2PNB191V2
+ 0x07 "c2tnb191v3" OID_C2PNB191V3
+ 0x08 "c2onb191v4" OID_C2PNB191V4
+ 0x09 "c2onb191v5" OID_C2PNB191V5
+ 0x0A "c2pnb208w1" OID_C2PNB208W1
+ 0x0B "c2tnb239v1" OID_C2PNB239V1
+ 0x0C "c2tnb239v2" OID_C2PNB239V2
+ 0x0D "c2tnb239v3" OID_C2PNB239V3
+ 0x0E "c2onb239v4" OID_C2PNB239V4
+ 0x0F "c2onb239v5" OID_C2PNB239V5
+ 0x10 "c2pnb272w1" OID_C2PNB272W1
+ 0x11 "c2pnb304w1" OID_C2PNB304W1
+ 0x12 "c2tnb359v1" OID_C2PNB359V1
+ 0x13 "c2pnb368w1" OID_C2PNB368W1
+ 0x14 "c2tnb431r1" OID_C2PNB431R1
+ 0x01 "primeCurve"
+ 0x01 "prime192v1" OID_PRIME192V1
+ 0x02 "prime192v2" OID_PRIME192V2
+ 0x03 "prime192v3" OID_PRIME192V3
+ 0x04 "prime239v1" OID_PRIME239V1
+ 0x05 "prime239v2" OID_PRIME239V2
+ 0x06 "prime239v3" OID_PRIME239V3
+ 0x07 "prime256v1" OID_PRIME256V1
+ 0x04 "id-ecSigType"
+ 0x01 "ecdsa-with-SHA1" OID_ECDSA_WITH_SHA1
0x2B ""
0x06 "dod"
0x01 "internet"
@@ -159,6 +195,40 @@
0x02 "rsaSigWithripemd160"
0x03 "rsaSigWithripemd128"
0x04 "rsaSigWithripemd256"
+ 0x81 ""
+ 0x04 "Certicom"
+ 0x00 "curve"
+ 0x01 "sect163k1" OID_SECT163K1
+ 0x02 "sect163r1" OID_SECT163R1
+ 0x03 "sect239k1" OID_SECT239K1
+ 0x04 "sect113r1" OID_SECT113R1
+ 0x05 "sect113r2" OID_SECT113R2
+ 0x06 "secp112r1" OID_SECT112R1
+ 0x07 "secp112r2" OID_SECT112R2
+ 0x08 "secp160r1" OID_SECT160R1
+ 0x09 "secp160k1" OID_SECT160K1
+ 0x0A "secp256k1" OID_SECT256K1
+ 0x0F "sect163r2" OID_SECT163R2
+ 0x10 "sect283k1" OID_SECT283K1
+ 0x11 "sect283r1" OID_SECT283R1
+ 0x16 "sect131r1" OID_SECT131R1
+ 0x17 "sect131r2" OID_SECT131R2
+ 0x18 "sect193r1" OID_SECT193R1
+ 0x19 "sect193r2" OID_SECT193R2
+ 0x1A "sect233k1" OID_SECT233K1
+ 0x1B "sect233r1" OID_SECT233R1
+ 0x1C "secp128r1" OID_SECT128R1
+ 0x1D "secp128r2" OID_SECT128R2
+ 0x1E "secp160r2" OID_SECT160R2
+ 0x1F "secp192k1" OID_SECT192K1
+ 0x20 "secp224k1" OID_SECT224K1
+ 0x21 "secp224r1" OID_SECT224R1
+ 0x22 "secp384r1" OID_SECT384R1
+ 0x23 "secp521r1" OID_SECT521R1
+ 0x24 "sect409k1" OID_SECT409K1
+ 0x25 "sect409r1" OID_SECT409R1
+ 0x26 "sect571k1" OID_SECT571K1
+ 0x27 "sect571r1" OID_SECT571R1
0x60 ""
0x86 ""
0x48 ""
diff --git a/src/libstrongswan/asn1/pem.c b/src/libstrongswan/asn1/pem.c
index b752a97ab..d3176b6bc 100755
--- a/src/libstrongswan/asn1/pem.c
+++ b/src/libstrongswan/asn1/pem.c
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2001-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -11,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: pem.c 3256 2007-10-07 13:42:43Z andreas $
+ * $Id: pem.c 4029 2008-06-03 12:14:02Z martin $
*/
#include <stdio.h>
@@ -27,7 +29,6 @@
#include <library.h>
#include <debug.h>
#include <asn1/asn1.h>
-#include <asn1/ttodata.h>
#include <utils/lexparser.h>
#include <crypto/hashers/hasher.h>
@@ -83,7 +84,7 @@ static bool find_boundary(const char* tag, chunk_t *line)
/*
* decrypts a passphrase protected encrypted data block
*/
-static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_size,
+static bool pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_size,
chunk_t *iv, chunk_t *passphrase)
{
hasher_t *hasher;
@@ -95,10 +96,18 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s
u_int8_t padding, *last_padding_pos, *first_padding_pos;
if (passphrase == NULL || passphrase->len == 0)
- return "missing passphrase";
+ {
+ DBG1(" missing passphrase");
+ return FALSE;
+ }
/* build key from passphrase and IV */
- hasher = hasher_create(HASH_MD5);
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
+ if (hasher == NULL)
+ {
+ DBG1(" MD5 hash algorithm not available");
+ return FALSE;
+ }
hash.len = hasher->get_hash_size(hasher);
hash.ptr = alloca(hash.len);
hasher->get_hash(hasher, *passphrase, NULL);
@@ -115,13 +124,23 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s
hasher->destroy(hasher);
/* decrypt blob */
- crypter = crypter_create(alg, key_size);
+ crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size);
+ if (crypter == NULL)
+ {
+ DBG1(" %N encryption algorithm not available",
+ encryption_algorithm_names, alg);
+ return FALSE;
+ }
crypter->set_key(crypter, key);
- if (crypter->decrypt(crypter, *blob, *iv, &decrypted) != SUCCESS)
+
+ if (iv->len != crypter->get_block_size(crypter) ||
+ blob->len % iv->len)
{
crypter->destroy(crypter);
- return "data size is not multiple of block size";
+ DBG1(" data size is not multiple of block size");
+ return FALSE;
}
+ crypter->decrypt(crypter, *blob, *iv, &decrypted);
crypter->destroy(crypter);
memcpy(blob->ptr, decrypted.ptr, blob->len);
chunk_free(&decrypted);
@@ -135,11 +154,14 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s
while (--last_padding_pos > first_padding_pos)
{
if (*last_padding_pos != padding)
- return "invalid passphrase";
+ {
+ DBG1(" invalid passphrase");
+ return FALSE;
+ }
}
/* remove padding */
blob->len -= padding;
- return NULL;
+ return TRUE;
}
/* Converts a PEM encoded file into its binary form
@@ -147,7 +169,7 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s
* RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
* RFC 934 Message Encapsulation, January 1985
*/
-err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
+bool pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
{
typedef enum {
PEM_PRE = 0,
@@ -223,7 +245,6 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
encrypted = TRUE;
else if (match("DEK-Info", &name))
{
- size_t len = 0;
chunk_t dek;
if (!extract_token(&dek, ',', &value))
@@ -251,21 +272,16 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
}
else
{
- return "encryption algorithm not supported";
+ DBG1(" encryption algorithm '%.s' not supported",
+ dek.len, dek.ptr);
+ return FALSE;
}
-
eat_whitespace(&value);
- ugh = ttodata(value.ptr, value.len, 16, iv.ptr, 16, &len);
- if (ugh)
- return "error in IV";
-
- iv.len = len;
+ iv = chunk_from_hex(value, iv.ptr);
}
}
else /* state is PEM_BODY */
{
- const char *ugh = NULL;
- size_t len = 0;
chunk_t data;
/* remove any trailing whitespace */
@@ -280,21 +296,18 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
*pgp = TRUE;
data.ptr++;
data.len--;
- DBG2(" Armor checksum: %.*s", (int)data.len, data.ptr);
+ DBG2(" armor checksum: %.*s", (int)data.len, data.ptr);
continue;
}
-
- ugh = ttodata(data.ptr, data.len, 64, dst.ptr, blob->len - dst.len, &len);
- if (ugh)
+
+ if (blob->len - dst.len < data.len / 4 * 3)
{
state = PEM_ABORT;
- break;
- }
- else
- {
- dst.ptr += len;
- dst.len += len;
}
+ data = chunk_from_base64(data, dst.ptr);
+
+ dst.ptr += data.len;
+ dst.len += data.len;
}
}
}
@@ -302,19 +315,24 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
blob->len = dst.len;
if (state != PEM_POST)
- return "file coded in unknown format, discarded";
-
- return (encrypted)? pem_decrypt(blob, alg, key_size, &iv, passphrase) : NULL;
+ {
+ DBG1(" file coded in unknown format, discarded");
+ return FALSE;
+ }
+ if (!encrypted)
+ {
+ return TRUE;
+ }
+ return pem_decrypt(blob, alg, key_size, &iv, passphrase);
+
}
/* load a coded key or certificate file with autodetection
* of binary DER or base64 PEM ASN.1 formats and armored PGP format
*/
-bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
- const char *type, chunk_t *blob, bool *pgp)
+bool pem_asn1_load_file(char *filename, chunk_t *passphrase,
+ chunk_t *blob, bool *pgp)
{
- err_t ugh = NULL;
-
FILE *fd = fopen(filename, "r");
if (fd)
@@ -326,7 +344,7 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
blob->ptr = malloc(blob->len);
bytes = fread(blob->ptr, 1, blob->len, fd);
fclose(fd);
- DBG1(" loading %s file '%s' (%d bytes)", type, filename, bytes);
+ DBG2(" loading '%s' (%d bytes)", filename, bytes);
*pgp = FALSE;
@@ -341,9 +359,7 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
DBG4(" passphrase:", passphrase->ptr, passphrase->len);
/* try PEM format */
- ugh = pem_to_bin(blob, passphrase, pgp);
-
- if (ugh == NULL)
+ if (pem_to_bin(blob, passphrase, pgp))
{
if (*pgp)
{
@@ -355,16 +371,16 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
DBG2(" file coded in PEM format");
return TRUE;
}
- ugh = "file coded in unknown format, discarded";
+ DBG1(" file coded in unknown format, discarded");
}
/* a conversion error has occured */
- DBG1(" %s", ugh);
chunk_free(blob);
}
else
{
- DBG1(" could not open %s file '%s'", type, filename);
+ DBG1(" reading file '%s' failed", filename);
}
return FALSE;
}
+
diff --git a/src/libstrongswan/asn1/pem.h b/src/libstrongswan/asn1/pem.h
index 0f4b7202c..4b76fbe80 100755
--- a/src/libstrongswan/asn1/pem.h
+++ b/src/libstrongswan/asn1/pem.h
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2001-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -10,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: pem.h 4011 2008-05-23 19:18:08Z andreas $
*/
#ifndef PEM_H_
@@ -19,9 +23,9 @@
#include <library.h>
-err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp);
+bool pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp);
-bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
- const char *type, chunk_t *blob, bool *pgp);
+bool pem_asn1_load_file(char *filename, chunk_t *passphrase,
+ chunk_t *blob, bool *pgp);
-#endif /*PEM_H_*/
+#endif /*PEM_H_ @} */
diff --git a/src/libstrongswan/asn1/ttodata.c b/src/libstrongswan/asn1/ttodata.c
deleted file mode 100644
index 125313c2a..000000000
--- a/src/libstrongswan/asn1/ttodata.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * convert from text form of arbitrary data (e.g., keys) to binary
- * Copyright (C) 2000 Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- * License for more details.
- */
-
-#include "ttodata.h"
-
-#include <string.h>
-#include <ctype.h>
-
-/* converters and misc */
-static int unhex(const char *, char *, size_t);
-static int unb64(const char *, char *, size_t);
-static int untext(const char *, char *, size_t);
-static const char *badch(const char *, int, char *, size_t);
-
-/* internal error codes for converters */
-#define SHORT (-2) /* internal buffer too short */
-#define BADPAD (-3) /* bad base64 padding */
-#define BADCH0 (-4) /* invalid character 0 */
-#define BADCH1 (-5) /* invalid character 1 */
-#define BADCH2 (-6) /* invalid character 2 */
-#define BADCH3 (-7) /* invalid character 3 */
-#define BADOFF(code) (BADCH0-(code))
-
-/**
- * @brief convert text to data, with verbose error reports
- *
- * If some of this looks slightly odd, it's because it has changed
- * repeatedly (from the original atodata()) without a major rewrite.
- *
- * @param src
- * @param srclen 0 means apply strlen()
- * @param base 0 means figure it out
- * @param dst need not be valid if dstlen is 0
- * @param dstlen
- * @param lenp where to record length (NULL is nowhere)
- * @param errp error buffer
- * @param flags
- * @return NULL on success, else literal or errp
- */
-const char *ttodatav(const char *src, size_t srclen, int base, char *dst, size_t dstlen, size_t *lenp, char *errp, size_t errlen, unsigned int flags)
-{
- size_t ingroup; /* number of input bytes converted at once */
- char buf[4]; /* output from conversion */
- int nbytes; /* size of output */
- int (*decode)(const char *, char *, size_t);
- char *stop;
- int ndone;
- int i;
- int underscoreok;
- int skipSpace = 0;
-
- if (srclen == 0)
- {
- srclen = strlen(src);
- }
- if (dstlen == 0)
- {
- dst = buf; /* point it somewhere valid */
- }
- stop = dst + dstlen;
-
- if (base == 0)
- {
- if (srclen < 2)
- {
- return "input too short to be valid";
- }
- if (*src++ != '0')
- {
- return "input does not begin with format prefix";
- }
- switch (*src++)
- {
- case 'x':
- case 'X':
- base = 16;
- break;
- case 's':
- case 'S':
- base = 64;
- break;
- case 't':
- case 'T':
- base = 256;
- break;
- default:
- return "unknown format prefix";
- }
- srclen -= 2;
- }
- switch (base)
- {
- case 16:
- decode = unhex;
- underscoreok = 1;
- ingroup = 2;
- break;
- case 64:
- decode = unb64;
- underscoreok = 0;
- ingroup = 4;
- if(flags & TTODATAV_IGNORESPACE)
- {
- skipSpace = 1;
- }
- break;
- case 256:
- decode = untext;
- ingroup = 1;
- underscoreok = 0;
- break;
- default:
- return "unknown base";
- }
-
- /* proceed */
- ndone = 0;
- while (srclen > 0)
- {
- char stage[4]; /* staging area for group */
- size_t sl = 0;
-
- /* Grab ingroup characters into stage,
- * squeezing out blanks if we are supposed to ignore them.
- */
- for (sl = 0; sl < ingroup; src++, srclen--)
- {
- if (srclen == 0)
- {
- return "input ends in mid-byte, perhaps truncated";
- }
- else if (!(skipSpace && (*src == ' ' || *src == '\t')))
- {
- stage[sl++] = *src;
- }
- }
-
- nbytes = (*decode)(stage, buf, sizeof(buf));
- switch (nbytes)
- {
- case BADCH0:
- case BADCH1:
- case BADCH2:
- case BADCH3:
- return badch(stage, nbytes, errp, errlen);
- case SHORT:
- return "internal buffer too short (\"can't happen\")";
- case BADPAD:
- return "bad (non-zero) padding at end of base64 input";
- }
- if (nbytes <= 0)
- {
- return "unknown internal error";
- }
- for (i = 0; i < nbytes; i++)
- {
- if (dst < stop)
- {
- *dst++ = buf[i];
- }
- ndone++;
- }
- while (srclen >= 1 && skipSpace && (*src == ' ' || *src == '\t'))
- {
- src++;
- srclen--;
- }
- if (underscoreok && srclen > 1 && (*src == '_' || *src == ':'))
- {
- /* srclen > 1 means not last character */
- src++;
- srclen--;
- }
- }
-
- if (ndone == 0)
- {
- return "no data bytes specified by input";
- }
- if (lenp != NULL)
- {
- *lenp = ndone;
- }
- return NULL;
-}
-
-/**
- * @brief ttodata - convert text to data
- *
- * @param src
- * @param srclen 0 means apply strlen()
- * @param base 0 means figure it out
- * @param dst need not be valid if dstlen is 0
- * @param dstlen
- * @param lenp where to record length (NULL is nowhere)
- * @return NULL on success, else literal
- */
-const char *ttodata(const char *src, size_t srclen, int base, char *dst, size_t dstlen, size_t *lenp)
-{
- return ttodatav(src, srclen, base, dst, dstlen, lenp, (char *)NULL,
- (size_t)0, TTODATAV_SPACECOUNTS);
-}
-
-/**
- * @brief atodata - convert ASCII to data
- *
- * backward-compatibility interface
- *
- * @param src
- * @param srclen
- * @param dst
- * @param dstlen
- * @return 0 for failure, true length for success
- */
-size_t atodata(const char *src, size_t srclen, char *dst, size_t dstlen)
-{
- size_t len;
- const char *err;
-
- err = ttodata(src, srclen, 0, dst, dstlen, &len);
- return (err)? 0:len;
-}
-
-/**
- * @brief atobytes - convert ASCII to data bytes
- *
- * another backward-compatibility interface
- */
-const char *atobytes(const char *src, size_t srclen, char *dst, size_t dstlen, size_t *lenp)
-{
- return ttodata(src, srclen, 0, dst, dstlen, lenp);
-}
-
-/**
- * @brief unhex - convert two ASCII hex digits to byte
- *
- * @param src known to be full length
- * @param dstnumber of result bytes, or error code
- * @param dstlen not large enough is a failure
- * @return
- */
-static int unhex(const char *src, char *dst, size_t dstlen)
-{
- char *p;
- unsigned byte;
- static char hex[] = "0123456789abcdef";
-
- if (dstlen < 1)
- {
- return SHORT;
- }
-
- p = strchr(hex, *src);
- if (p == NULL)
- {
- p = strchr(hex, tolower(*src));
- }
- if (p == NULL)
- {
- return BADCH0;
- }
- byte = (p - hex) << 4;
- src++;
-
- p = strchr(hex, *src);
- if (p == NULL)
- {
- p = strchr(hex, tolower(*src));
- }
- if (p == NULL)
- {
- return BADCH1;
- }
- byte |= (p - hex);
-
- *dst = byte;
- return 1;
-}
-
-/**
- * @brief unb64 - convert four ASCII base64 digits to three bytes
- *
- * Note that a base64 digit group is padded out with '=' if it represents
- * less than three bytes: one byte is dd==, two is ddd=, three is dddd.
- *
- * @param src known to be full length
- * @param dst
- * @param dstlen
- * @return number of result bytes, or error code
- */
-static int unb64(const char *src, char *dst, size_t dstlen)
-{
- char *p;
- unsigned byte1;
- unsigned byte2;
- static char base64[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- if (dstlen < 3)
- {
- return SHORT;
- }
- p = strchr(base64, *src++);
-
- if (p == NULL)
- {
- return BADCH0;
- }
- byte1 = (p - base64) << 2; /* first six bits */
-
- p = strchr(base64, *src++);
- if (p == NULL)
- {
- return BADCH1;
- }
-
- byte2 = p - base64; /* next six: two plus four */
- *dst++ = byte1 | (byte2 >> 4);
- byte1 = (byte2 & 0xf) << 4;
-
- p = strchr(base64, *src++);
- if (p == NULL)
- {
- if (*(src-1) == '=' && *src == '=')
- {
- if (byte1 != 0) /* bad padding */
- {
- return BADPAD;
- }
- return 1;
- }
- return BADCH2;
- }
-
- byte2 = p - base64; /* next six: four plus two */
- *dst++ = byte1 | (byte2 >> 2);
- byte1 = (byte2 & 0x3) << 6;
-
- p = strchr(base64, *src++);
- if (p == NULL)
- {
- if (*(src-1) == '=')
- {
- if (byte1 != 0) /* bad padding */
- {
- return BADPAD;
- }
- return 2;
- }
- return BADCH3;
- }
- byte2 = p - base64; /* last six */
- *dst++ = byte1 | byte2;
-
- return 3;
-}
-
-/**
- * @brief untext - convert one ASCII character to byte
- *
- * @param src known to be full length
- * @param dst
- * @param dstlen not large enough is a failure
- * @return number of result bytes, or error code
- */
-static int untext(const char *src, char *dst, size_t dstlen)
-{
- if (dstlen < 1)
- {
- return SHORT;
- }
- *dst = *src;
- return 1;
-}
-
-/**
- * @brief badch - produce a nice complaint about an unknown character
- *
- * If the compiler complains that the array bigenough[] has a negative
- * size, that means the TTODATAV_BUF constant has been set too small.
- *
- * @param src
- * @param errcode
- * @param errp might be NULL
- * @param errlen
- * @return literal or errp
- */
-static const char *badch(const char *src, int errcode, char *errp, size_t errlen)
-{
- static const char pre[] = "unknown character (`";
- static const char suf[] = "') in input";
- char buf[5];
-# define REQD (sizeof(pre) - 1 + sizeof(buf) - 1 + sizeof(suf))
- struct sizecheck {
- char bigenough[TTODATAV_BUF - REQD]; /* see above */
- };
- char ch;
-
- if (errp == NULL || errlen < REQD)
- {
- return "unknown character in input";
- }
- strcpy(errp, pre);
- ch = *(src + BADOFF(errcode));
- if (isprint(ch))
- {
- buf[0] = ch;
- buf[1] = '\0';
- }
- else
- {
- buf[0] = '\\';
- buf[1] = ((ch & 0700) >> 6) + '0';
- buf[2] = ((ch & 0070) >> 3) + '0';
- buf[3] = ((ch & 0007) >> 0) + '0';
- buf[4] = '\0';
- }
- strcat(errp, buf);
- strcat(errp, suf);
- return (const char *)errp;
-}
diff --git a/src/libstrongswan/asn1/ttodata.h b/src/libstrongswan/asn1/ttodata.h
deleted file mode 100644
index 6125c6b82..000000000
--- a/src/libstrongswan/asn1/ttodata.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * convert from text form of arbitrary data (e.g., keys) to binary
- * Copyright (C) 2000 Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- * License for more details.
- */
-
-#ifndef TTODATA_H_
-#define TTODATA_H_
-
-#include <library.h>
-
-#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */
-#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/
-#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */
-
-err_t ttodata(const char *src, size_t srclen, int base, char *buf, size_t buflen, size_t *needed);
-
-
-#endif /* TTODATA_H_ */
diff --git a/src/libstrongswan/chunk.c b/src/libstrongswan/chunk.c
index 0d7841641..7e7a7c69d 100644
--- a/src/libstrongswan/chunk.c
+++ b/src/libstrongswan/chunk.c
@@ -1,10 +1,3 @@
-/**
- * @file chunk.c
- *
- * @brief Pointer/lenght abstraction and its functions.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,16 +12,19 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: chunk.c 3868 2008-04-24 13:26:22Z martin $
*/
#include <stdio.h>
#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
#include "chunk.h"
#include <debug.h>
#include <printf_hook.h>
-#include <utils/randomizer.h>
/**
* Empty chunk.
@@ -211,43 +207,41 @@ void chunk_split(chunk_t chunk, const char *mode, ...)
/**
* Described in header.
*/
-bool chunk_write(chunk_t chunk, const char *path, const char *label, mode_t mask, bool force)
+bool chunk_write(chunk_t chunk, char *path, mode_t mask, bool force)
{
mode_t oldmask;
FILE *fd;
+ bool good = FALSE;
- if (!force)
+ if (!force && access(path, F_OK) == 0)
{
- fd = fopen(path, "r");
- if (fd)
- {
- fclose(fd);
- DBG1(" %s file '%s' already exists", label, path);
- return FALSE;
- }
+ DBG1(" file '%s' already exists", path);
+ return FALSE;
}
-
- /* set umask */
oldmask = umask(mask);
-
fd = fopen(path, "w");
-
if (fd)
{
- fwrite(chunk.ptr, sizeof(u_char), chunk.len, fd);
+ if (fwrite(chunk.ptr, sizeof(u_char), chunk.len, fd) == chunk.len)
+ {
+ good = TRUE;
+ }
+ else
+ {
+ DBG1(" writing to file '%s' failed: %s", path, strerror(errno));
+ }
fclose(fd);
- DBG1(" written %s file '%s' (%u bytes)", label, path, chunk.len);
- umask(oldmask);
return TRUE;
}
else
{
- DBG1(" could not open %s file '%s' for writing", label, path);
- umask(oldmask);
- return FALSE;
+ DBG1(" could not open file '%s': %s", path, strerror(errno));
}
+ umask(oldmask);
+ return good;
}
+
/** hex conversion digits */
static char hexdig_upper[] = "0123456789ABCDEF";
static char hexdig_lower[] = "0123456789abcdef";
@@ -255,10 +249,9 @@ static char hexdig_lower[] = "0123456789abcdef";
/**
* Described in header.
*/
-char *chunk_to_hex(chunk_t chunk, bool uppercase)
+chunk_t chunk_to_hex(chunk_t chunk, char *buf, bool uppercase)
{
- int i;
- char *str;
+ int i, len;;
char *hexdig = hexdig_lower;
if (uppercase)
@@ -266,51 +259,182 @@ char *chunk_to_hex(chunk_t chunk, bool uppercase)
hexdig = hexdig_upper;
}
- str = malloc(chunk.len * 2 + 1);
- str[chunk.len * 2] = '\0';
+ len = chunk.len * 2;
+ if (!buf)
+ {
+ buf = malloc(len + 1);
+ }
+ buf[len] = '\0';
- for (i = 0; i < chunk.len; i ++)
+ for (i = 0; i < chunk.len; i++)
{
- str[i*2] = hexdig[(chunk.ptr[i] >> 4) & 0xF];
- str[i*2+1] = hexdig[(chunk.ptr[i] ) & 0xF];
+ buf[i*2] = hexdig[(chunk.ptr[i] >> 4) & 0xF];
+ buf[i*2+1] = hexdig[(chunk.ptr[i] ) & 0xF];
+ }
+ return chunk_create(buf, len);
+}
+
+/**
+ * convert a signle hex character to its binary value
+ */
+static char hex2bin(char hex)
+{
+ switch (hex)
+ {
+ case '0' ... '9':
+ return hex - '0';
+ case 'A' ... 'F':
+ return hex - 'A' + 10;
+ case 'a' ... 'f':
+ return hex - 'a' + 10;
+ default:
+ return 0;
}
- return str;
}
/**
* Described in header.
*/
-void chunk_free(chunk_t *chunk)
+chunk_t chunk_from_hex(chunk_t hex, char *buf)
{
- free(chunk->ptr);
- chunk->ptr = NULL;
- chunk->len = 0;
+ int i, len;
+
+ len = hex.len / 2;
+ if (!buf)
+ {
+ buf = malloc(len);
+ }
+ for (i = 0; i < len; i++)
+ {
+ buf[i] = hex2bin(*hex.ptr++) << 4;
+ buf[i] |= hex2bin(*hex.ptr++);
+ }
+ return chunk_create(buf, len);
}
+/** base 64 conversion digits */
+static char b64digits[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
/**
* Described in header.
*/
-void chunk_free_randomized(chunk_t *chunk)
+chunk_t chunk_to_base64(chunk_t chunk, char *buf)
{
- if (chunk->ptr)
+ int i, len;
+ char *pos;
+
+ len = chunk.len + ((3 - chunk.len % 3) % 3);
+ if (!buf)
{
- if (chunk->len > 0)
+ buf = malloc(len * 4 / 3 + 1);
+ }
+ pos = buf;
+ for (i = 0; i < len; i+=3)
+ {
+ *pos++ = b64digits[chunk.ptr[i] >> 2];
+ if (i+1 >= chunk.len)
+ {
+ *pos++ = b64digits[(chunk.ptr[i] & 0x03) << 4];
+ *pos++ = '=';
+ *pos++ = '=';
+ break;
+ }
+ *pos++ = b64digits[((chunk.ptr[i] & 0x03) << 4) | (chunk.ptr[i+1] >> 4)];
+ if (i+2 >= chunk.len)
{
- randomizer_t *randomizer = randomizer_create();
+ *pos++ = b64digits[(chunk.ptr[i+1] & 0x0F) << 2];
+ *pos++ = '=';
+ break;
+ }
+ *pos++ = b64digits[((chunk.ptr[i+1] & 0x0F) << 2) | (chunk.ptr[i+2] >> 6)];
+ *pos++ = b64digits[chunk.ptr[i+2] & 0x3F];
+ }
+ *pos = '\0';
+ return chunk_create(buf, len * 4 / 3);
+}
+
+/**
+ * convert a base 64 digit to its binary form (inversion of b64digits array)
+ */
+static int b642bin(char b64)
+{
+ switch (b64)
+ {
+ case 'A' ... 'Z':
+ return b64 - 'A';
+ case 'a' ... 'z':
+ return ('Z' - 'A' + 1) + b64 - 'a';
+ case '0' ... '9':
+ return ('Z' - 'A' + 1) + ('z' - 'a' + 1) + b64 - '0';
+ case '+':
+ case '-':
+ return 62;
+ case '/':
+ case '_':
+ return 63;
+ case '=':
+ return 0;
+ default:
+ return -1;
+ }
+}
- randomizer->get_pseudo_random_bytes(randomizer,
- chunk->len, chunk->ptr);
- randomizer->destroy(randomizer);
- };
- free(chunk->ptr);
- chunk->ptr = NULL;
+/**
+ * Described in header.
+ */
+chunk_t chunk_from_base64(chunk_t base64, char *buf)
+{
+ u_char *pos, byte[4];
+ int i, j, len, outlen;
+
+ len = base64.len / 4 * 3;
+ if (!buf)
+ {
+ buf = malloc(len);
+ }
+ pos = base64.ptr;
+ outlen = 0;
+ for (i = 0; i < len; i+=3)
+ {
+ outlen += 3;
+ for (j = 0; j < 4; j++)
+ {
+ if (*pos == '=')
+ {
+ outlen--;
+ }
+ byte[j] = b642bin(*pos++);
+ }
+ buf[i] = (byte[0] << 2) | (byte[1] >> 4);
+ buf[i+1] = (byte[1] << 4) | (byte[2] >> 2);
+ buf[i+2] = (byte[2] << 6) | (byte[3]);
}
+ return chunk_create(buf, outlen);
+}
+
+/**
+ * Described in header.
+ */
+void chunk_free(chunk_t *chunk)
+{
+ free(chunk->ptr);
+ chunk->ptr = NULL;
chunk->len = 0;
}
/**
* Described in header.
*/
+void chunk_clear(chunk_t *chunk)
+{
+ memset(chunk->ptr, 0, chunk->len);
+ chunk_free(chunk);
+}
+
+/**
+ * Described in header.
+ */
chunk_t chunk_skip(chunk_t chunk, size_t bytes)
{
if (chunk.len > bytes)
@@ -347,91 +471,21 @@ bool chunk_equals(chunk_t a, chunk_t b)
}
/**
- * Described in header.
- */
-bool chunk_equals_or_null(chunk_t a, chunk_t b)
-{
- if (a.ptr == NULL || b.ptr == NULL)
- return TRUE;
- return a.len == b.len && memeq(a.ptr, b.ptr, a.len);
-}
-
-/**
- * Number of bytes per line to dump raw data
- */
-#define BYTES_PER_LINE 16
-
-/**
- * output handler in printf() for byte ranges
- */
-static int print_bytes(FILE *stream, const struct printf_info *info,
- const void *const *args)
-{
- char *bytes = *((void**)(args[0]));
- int len = *((size_t*)(args[1]));
-
- char buffer[BYTES_PER_LINE * 3];
- char ascii_buffer[BYTES_PER_LINE + 1];
- char *buffer_pos = buffer;
- char *bytes_pos = bytes;
- char *bytes_roof = bytes + len;
- int line_start = 0;
- int i = 0;
- int written = 0;
-
- written += fprintf(stream, "=> %d bytes @ %p", len, bytes);
-
- while (bytes_pos < bytes_roof)
- {
- *buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF];
- *buffer_pos++ = hexdig_upper[ *bytes_pos & 0xF];
-
- ascii_buffer[i++] =
- (*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.';
-
- if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE)
- {
- int padding = 3 * (BYTES_PER_LINE - i);
- int written;
-
- while (padding--)
- {
- *buffer_pos++ = ' ';
- }
- *buffer_pos++ = '\0';
- ascii_buffer[i] = '\0';
-
- written += fprintf(stream, "\n%4d: %s %s",
- line_start, buffer, ascii_buffer);
-
-
- buffer_pos = buffer;
- line_start += BYTES_PER_LINE;
- i = 0;
- }
- else
- {
- *buffer_pos++ = ' ';
- }
- }
- return written;
-}
-
-/**
* output handler in printf() for chunks
*/
-static int print_chunk(FILE *stream, const struct printf_info *info,
+static int chunk_print(FILE *stream, const struct printf_info *info,
const void *const *args)
{
chunk_t *chunk = *((chunk_t**)(args[0]));
bool first = TRUE;
chunk_t copy = *chunk;
int written = 0;
+ printf_hook_functions_t mem = mem_get_printf_hooks();
if (!info->alt)
{
const void *new_args[] = {&chunk->ptr, &chunk->len};
- return print_bytes(stream, info, new_args);
+ return mem.print(stream, info, new_args);
}
while (copy.len > 0)
@@ -451,10 +505,24 @@ static int print_chunk(FILE *stream, const struct printf_info *info,
}
/**
- * register printf() handlers
+ * arginfo handler for printf() mem ranges
*/
-static void __attribute__ ((constructor))print_register()
+static int chunk_arginfo(const struct printf_info *info, size_t n, int *argtypes)
{
- register_printf_function(PRINTF_CHUNK, print_chunk, arginfo_ptr);
- register_printf_function(PRINTF_BYTES, print_bytes, arginfo_ptr_int);
+ if (n > 0)
+ {
+ argtypes[0] = PA_POINTER;
+ }
+ return 1;
}
+
+/**
+ * return printf hook functions for a chunk
+ */
+printf_hook_functions_t chunk_get_printf_hooks()
+{
+ printf_hook_functions_t hooks = {chunk_print, chunk_arginfo};
+
+ return hooks;
+}
+
diff --git a/src/libstrongswan/chunk.h b/src/libstrongswan/chunk.h
index 9c0aabba1..146b175d6 100644
--- a/src/libstrongswan/chunk.h
+++ b/src/libstrongswan/chunk.h
@@ -1,12 +1,5 @@
-/**
- * @file chunk.h
- *
- * @brief Pointer/length abstraction and its functions.
- *
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -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: chunk.h 3868 2008-04-24 13:26:22Z martin $
+ */
+
+/**
+ * @defgroup chunk chunk
+ * @{ @ingroup libstrongswan
*/
#ifndef CHUNK_H_
@@ -26,8 +26,7 @@
#include <string.h>
#include <stdarg.h>
-
-#include <library.h>
+#include <sys/types.h>
typedef struct chunk_t chunk_t;
@@ -41,6 +40,8 @@ struct chunk_t {
size_t len;
};
+#include <library.h>
+
/**
* A { NULL, 0 }-chunk handy for initialization.
*/
@@ -64,7 +65,7 @@ size_t chunk_length(const char *mode, ...);
/**
* Concatenate chunks into a chunk pointing to "ptr",
* "mode" is a string of "c" (copy) and "m" (move), which says
- * how to handle to chunks in "..."
+ * how to handle the chunks in "..."
*/
chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...);
@@ -81,12 +82,54 @@ void chunk_split(chunk_t chunk, const char *mode, ...);
/**
* Write the binary contents of a chunk_t to a file
*/
-bool chunk_write(chunk_t chunk, const char *path, const char *label, mode_t mask, bool force);
+bool chunk_write(chunk_t chunk, char *path, mode_t mask, bool force);
+
+/**
+ * Convert a chunk of data to hex encoding.
+ *
+ * The resulting string is '\0' terminated, but the chunk does not include
+ * the '\0'. If buf is supplied, it must hold at least (chunk.len * 2 + 1).
+ *
+ * @param chunk data to convert
+ * @param buff buffer to write to, NULL to malloc
+ * @param uppercase TRUE to use uppercase letters
+ * @return chunk of encoded data
+ */
+chunk_t chunk_to_hex(chunk_t chunk, char *buf, bool uppercase);
+
+/**
+ * Convert a hex encoded in a binary chunk.
+ *
+ * If buf is supplied, it must hold at least (hex.len / 2).
+ *
+ * @param hex hex encoded input data
+ * @param buf buffer to write decoded data, NULL to malloc
+ * @return converted data
+ */
+chunk_t chunk_from_hex(chunk_t hex, char *buf);
+
+/**
+ * Convert a chunk of data to its base64 encoding.
+ *
+ * The resulting string is '\0' terminated, but the chunk does not include
+ * the '\0'. If buf is supplied, it must hold at least (chunk.len * 4 / 3 + 1).
+ *
+ * @param chunk data to convert
+ * @param buff buffer to write to, NULL to malloc
+ * @return chunk of encoded data
+ */
+chunk_t chunk_to_base64(chunk_t chunk, char *buf);
/**
- * convert a chunk to an allocated hex string
+ * Convert a base64 in a binary chunk.
+ *
+ * If buf is supplied, it must hold at least (base64.len / 4 * 3).
+ *
+ * @param base64 base64 encoded input data
+ * @param buf buffer to write decoded data, NULL to malloc
+ * @return converted data
*/
-char *chunk_to_hex(chunk_t chunk, bool uppercase);
+chunk_t chunk_from_base64(chunk_t base64, char *buf);
/**
* Free contents of a chunk
@@ -94,9 +137,9 @@ char *chunk_to_hex(chunk_t chunk, bool uppercase);
void chunk_free(chunk_t *chunk);
/**
- * Overwrite the contents of a chunk with pseudo-random bytes and free them
+ * Overwrite the contents of a chunk and free it
*/
-void chunk_free_randomized(chunk_t *chunk);
+void chunk_clear(chunk_t *chunk);
/**
* Initialize a chunk to point to buffer inspectable by sizeof()
@@ -156,9 +199,11 @@ int chunk_compare(chunk_t a, chunk_t b);
bool chunk_equals(chunk_t a, chunk_t b);
/**
- * Compare two chunks for equality,
- * NULL chunks are always equal.
+ * Get printf hooks for a chunk.
+ *
+ * Arguments are:
+ * chunk_t *chunk
*/
-bool chunk_equals_or_null(chunk_t a, chunk_t b);
+printf_hook_functions_t chunk_get_printf_hooks();
-#endif /* CHUNK_H_ */
+#endif /* CHUNK_H_ @}*/
diff --git a/src/libstrongswan/credential_store.h b/src/libstrongswan/credential_store.h
deleted file mode 100755
index 62b6ad2d5..000000000
--- a/src/libstrongswan/credential_store.h
+++ /dev/null
@@ -1,330 +0,0 @@
-/**
- * @file credential_store.h
- *
- * @brief Interface credential_store_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.
- */
-
-#ifndef CREDENTIAL_STORE_H_
-#define CREDENTIAL_STORE_H_
-
-typedef struct credential_store_t credential_store_t;
-
-#include <library.h>
-#include <crypto/x509.h>
-#include <crypto/ca.h>
-#include <crypto/rsa/rsa_private_key.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <utils/identification.h>
-
-
-/**
- * @brief The interface for a credential_store backend.
- *
- * @b Constructors:
- * - stroke_create()
- *
- * @ingroup config
- */
-struct credential_store_t {
-
- /**
- * @brief Returns the secret shared by two specific IDs.
- *
- * The returned chunk must be destroyed by the caller after usage.
- *
- * @param this calling object
- * @param my_id my ID identifiying the secret.
- * @param other_id peer ID identifying the secret.
- * @param[out] secret the pre-shared secret will be written there.
- * @return
- * - NOT_FOUND if no preshared secrets for specific ID could be found
- * - SUCCESS
- *
- */
- status_t (*get_shared_key) (credential_store_t *this, identification_t *my_id,
- identification_t *other_id, chunk_t *shared_key);
-
- /**
- * @brief Returns the EAP secret for two specified IDs.
- *
- * The returned chunk must be destroyed by the caller after usage.
- *
- * @param this calling object
- * @param my_id my ID identifiying the secret.
- * @param other_id peer ID identifying the secret.
- * @param[out] eap_key the EAP secret will be written here
- * @return
- * - NOT_FOUND if no preshared secrets for specific ID could be found
- * - SUCCESS
- *
- */
- status_t (*get_eap_key) (credential_store_t *this, identification_t *my_id,
- identification_t *other_id, chunk_t *eap_key);
-
- /**
- * @brief Returns the RSA public key of a specific ID.
- *
- * @param this calling object
- * @param id identification_t object identifiying the key.
- * @return public key, or NULL if not found
- */
- rsa_public_key_t* (*get_rsa_public_key) (credential_store_t *this, identification_t *id);
-
- /**
- * @brief Is there a matching RSA private key belonging to an RSA public key?
- *
- * @param this calling object
- * @param pubkey public key
- * @return TRUE if matching private key was found
- */
- bool (*has_rsa_private_key) (credential_store_t *this, rsa_public_key_t *pubkey);
-
- /**
- * @brief Returns the certificate of a specific ID.
- *
- * @param this calling object
- * @param id identification_t object identifiying the cert.
- * @return certificate, or NULL if not found
- */
- x509_t* (*get_certificate) (credential_store_t *this, identification_t *id);
-
- /**
- * @brief Returns the auth certificate of a specific subject distinguished name.
- *
- * @param this calling object
- * @param auth_flags set of allowed authority types
- * @param id identification_t object identifiying the cacert.
- * @return certificate, or NULL if not found
- */
- x509_t* (*get_auth_certificate) (credential_store_t *this, u_int auth_flags, identification_t *id);
-
- /**
- * @brief Returns the ca certificate of a specific keyID.
- *
- * @param this calling object
- * @param keyid identification_t object identifiying the cacert.
- * @return certificate, or NULL if not found
- */
- x509_t* (*get_ca_certificate_by_keyid) (credential_store_t *this, chunk_t keyid);
-
- /**
- * @brief Returns the issuing ca of a given certificate.
- *
- * @param this calling object
- * @param cert certificate for which issuer ca info is required
- * @return ca info, or NULL if not found
- */
- ca_info_t* (*get_issuer) (credential_store_t *this, x509_t* cert);
-
- /**
- * @brief RSA private key belonging to an RSA public key
- *
- *
- * @param this calling object
- * @param pubkey public key used to find the matching private key
- * @param hash_algorithm hash algorithm to be used for signature
- * @param data data block to be signed
- * @param signature signature to be returned
- * @return status of the signature process - SUCCESS if successful
- */
- status_t (*rsa_signature) (credential_store_t *this, rsa_public_key_t *pubkey, hash_algorithm_t hash_algorithm,
- chunk_t data, chunk_t *signature);
-
- /**
- * @brief Verify an RSA signature given the ID of the signer
- *
- * @param this calling object
- * @param hash hash value to be verified.
- * @param sig signature to be verified.
- * @param id identification_t object identifiying the signer.
- * @param issuer_p issuer of the signer's certificate (if not self-signed).
- * @return status of the verification - SUCCESS if successful
- */
- status_t (*verify_signature) (credential_store_t *this, chunk_t hash, chunk_t sig, identification_t *id,
- ca_info_t **issuer_p);
-
- /**
- * @brief Verify an X.509 certificate up to trust anchor without any status checks
- *
- * @param this calling object
- * @param label label characterizing the certificate to be verified
- * @param cert certificate to be verified
- * @return TRUE if trusted
- */
- bool (*is_trusted) (credential_store_t *this, const char *label, x509_t *cert);
-
- /**
- * @brief Verify an X.509 certificate up to trust anchor including status checks
- *
- * @param this calling object
- * @param cert certificate to be verified
- * @param found found a certificate copy in the credential store
- * @return TRUE if valid, trusted, and current status is good
- */
- bool (*verify) (credential_store_t *this, x509_t *cert, bool *found);
-
- /**
- * @brief If an end certificate does not already exists in the credential store then add it.
- *
- * @param this calling object
- * @param cert certificate to be added
- * @return pointer to the added or already existing certificate
- */
- x509_t* (*add_end_certificate) (credential_store_t *this, x509_t *cert);
-
- /**
- * @brief If an authority certificate does not already exists in the credential store then add it.
- *
- * @param this calling object
- * @param cert authority certificate to be added
- * @param auth_flag authority flags to add to the certificate
- * @return pointer to the added or already existing certificate
- */
- x509_t* (*add_auth_certificate) (credential_store_t *this, x509_t *cert, u_int auth_flag);
-
- /**
- * @brief If a ca info record does not already exists in the credential store then add it.
- *
- * @param this calling object
- * @param ca_info ca info record to be added
- * @return pointer to the added or already existing ca_info_t record
- */
- ca_info_t* (*add_ca_info) (credential_store_t *this, ca_info_t *ca_info);
-
- /**
- * @brief Release a ca info record with a given name.
- *
- * @param this calling object
- * @param name name of the ca info record to be released
- * @return
- * - SUCCESS, or
- * - NOT_FOUND
- */
- status_t (*release_ca_info) (credential_store_t *this, const char *name);
-
- /**
- * @brief Create an iterator over all end certificates.
- *
- * @param this calling object
- * @return iterator
- */
- iterator_t* (*create_cert_iterator) (credential_store_t *this);
-
- /**
- * @brief Create an iterator over all authority certificates.
- *
- * @param this calling object
- * @return iterator
- */
- iterator_t* (*create_auth_cert_iterator) (credential_store_t *this);
-
- /**
- * @brief Create an iterator over all CA info records
- *
- * @param this calling object
- * @return iterator
- */
- iterator_t* (*create_cainfo_iterator) (credential_store_t *this);
-
- /**
- * @brief Create an iterator over all attribute certificates.
- *
- * @param this calling object
- * @return iterator
- */
- iterator_t* (*create_acert_iterator) (credential_store_t *this);
-
- /**
- * @brief Loads ca certificates from a default directory.
- *
- * Certificates in both DER and PEM format are accepted
- *
- * @param this calling object
- */
- void (*load_ca_certificates) (credential_store_t *this);
-
- /**
- * @brief Loads authorization authority certificates from a default directory.
- *
- * Certificates in both DER and PEM format are accepted
- *
- * @param this calling object
- */
- void (*load_aa_certificates) (credential_store_t *this);
-
- /**
- * @brief Loads attribute certificates from a default directory.
- *
- * Certificates in both DER and PEM format are accepted
- *
- * @param this calling object
- */
- void (*load_attr_certificates) (credential_store_t *this);
-
- /**
- * @brief Loads ocsp certificates from a default directory.
- *
- * Certificates in both DER and PEM format are accepted
- *
- * @param this calling object
- */
- void (*load_ocsp_certificates) (credential_store_t *this);
-
- /**
- * @brief Loads CRLs from a default directory.
- *
- * Certificates in both DER and PEM format are accepted
- *
- * @param this calling object
- * @param path directory to load crls from
- */
- void (*load_crls) (credential_store_t *this);
-
- /**
- * @brief Loads secrets in ipsec.secrets
- *
- * RSA private key files can be either in DER or PEM format
- * Optional encryption with a passphrase supported
- *
- * @param this calling object
- * @param reload are the secrets to be reloaded
- */
- void (*load_secrets) (credential_store_t *this, bool reload);
-
- /**
- * @brief Destroys a credential_store_t object.
- *
- * @param this calling object
- */
- void (*destroy) (credential_store_t *this);
-};
-
-/**
- * @brief Creates a credential_store_t instance.
- *
- * @param strict enforce a strict crl policy
- * @return credential store instance.
- *
- * @ingroup config
- */
-credential_store_t *credential_store_create(bool strict);
-
-
-#endif /*CREDENTIAL_STORE_H_*/
diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c
new file mode 100644
index 000000000..c13a8a860
--- /dev/null
+++ b/src/libstrongswan/credentials/builder.c
@@ -0,0 +1,38 @@
+/*
+ * 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 "builder.h"
+
+ENUM(builder_part_names, BUILD_BLOB_ASN1_DER, BUILD_END,
+ "BUILD_FROM_FILE",
+ "BUILD_BLOB_ASN1_DER",
+ "BUILD_BLOB_ASN1_PEM",
+ "BUILD_KEY_SIZE",
+ "BUILD_SIGNING_KEY",
+ "BUILD_SIGNING_CERT",
+ "BUILD_PUBLIC_KEY",
+ "BUILD_SUBJECT",
+ "BUILD_SUBJECT_ALTNAME",
+ "BUILD_ISSUER",
+ "BUILD_ISSUER_ALTNAME",
+ "BUILD_NOT_BEFORE_TIME",
+ "BUILD_NOT_AFTER_TIME",
+ "BUILD_SERIAL",
+ "BUILD_IETF_GROUP_ATTR",
+ "BUILD_CA_CERT",
+ "BUILD_CERT",
+ "BUILD_X509_FLAG",
+ "BUILD_END",
+);
diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h
new file mode 100644
index 000000000..22c106b7a
--- /dev/null
+++ b/src/libstrongswan/credentials/builder.h
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup builder builder
+ * @{ @ingroup credentials
+ */
+
+#ifndef BUILDER_H_
+#define BUILDER_H_
+
+typedef struct builder_t builder_t;
+typedef enum builder_part_t builder_part_t;
+
+/**
+ * Constructor function which creates a new builder instance.
+ *
+ * @param subtype constructor specific subtype, e.g. certificate_type_t
+ * @return builder to construct a instance of type
+ */
+typedef builder_t* (*builder_constructor_t)(int subtype);
+
+#include <library.h>
+
+/**
+ * Parts to build credentials from.
+ */
+enum builder_part_t {
+ /** path to a file containing an ASN1 blob, char* */
+ BUILD_FROM_FILE,
+ /** DER encoded ASN1 blob, chunk_t */
+ BUILD_BLOB_ASN1_DER,
+ /** PEM encoded ASN1 blob, null terminated char* */
+ BUILD_BLOB_ASN1_PEM,
+ /** key size in bits, as used for key generation, u_int */
+ BUILD_KEY_SIZE,
+ /** private key to use for signing, private_key_t* */
+ BUILD_SIGNING_KEY,
+ /** certificate used for signing, certificate_t* */
+ BUILD_SIGNING_CERT,
+ /** public key to include, public_key_t* */
+ BUILD_PUBLIC_KEY,
+ /** subject for e.g. certificates, identification_t* */
+ BUILD_SUBJECT,
+ /** additional subject name, identification_t* */
+ BUILD_SUBJECT_ALTNAME,
+ /** issuer for e.g. certificates, identification_t* */
+ BUILD_ISSUER,
+ /** additional issuer name, identification_t* */
+ BUILD_ISSUER_ALTNAME,
+ /** notBefore, time_t* */
+ BUILD_NOT_BEFORE_TIME,
+ /** notAfter, time_t* */
+ BUILD_NOT_AFTER_TIME,
+ /** a serial number in binary form, chunk_t */
+ BUILD_SERIAL,
+ /** a comma-separated list of ietf group attributes, char* */
+ BUILD_IETF_GROUP_ATTR,
+ /** a ca certificate, certificate_t* */
+ BUILD_CA_CERT,
+ /** a certificate, certificate_t* */
+ BUILD_CERT,
+ /** enforce an additional X509 flag, x509_flag_t */
+ BUILD_X509_FLAG,
+ /** end of variable argument builder list */
+ BUILD_END,
+};
+
+/**
+ * enum names for build_part_t
+ */
+extern enum_name_t *builder_part_names;
+
+/**
+ * Credential construction API.
+ *
+ * The builder allows the construction of credentials in a generic and
+ * flexible way.
+ */
+struct builder_t {
+
+ /**
+ * Add a part to the construct.
+ *
+ * Any added parts get owned by the builder/construct, so clone/refcount
+ * them if needed.
+ *
+ * @param part kind of part
+ * @param ... part specific variable argument
+ */
+ void (*add)(builder_t *this, builder_part_t part, ...);
+
+ /**
+ * Build the construct with all supplied parts.
+ *
+ * Once build() is called, the builder gets destroyed.
+ *
+ * @return specific interface, as requested with constructor.
+ */
+ void* (*build)(builder_t *this);
+};
+
+#endif /* BUILDER_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/ac.h b/src/libstrongswan/credentials/certificates/ac.h
new file mode 100644
index 000000000..4e33390bb
--- /dev/null
+++ b/src/libstrongswan/credentials/certificates/ac.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
+ * Copyright (C) 2003 Martin Berner, Lukas Suter
+ * Copyright (C) 2002-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: ac.h 3300 2007-10-12 21:53:18Z andreas $
+ */
+
+/**
+ * @defgroup ac ac
+ * @{ @ingroup certificates
+ */
+
+#ifndef AC_H_
+#define AC_H_
+
+#include <library.h>
+#include <credentials/certificates/certificate.h>
+
+typedef struct ac_t ac_t;
+
+/**
+ * X.509 attribute certificate interface.
+ *
+ * This interface adds additional methods to the certificate_t type to
+ * allow further operations on these certificates.
+ */
+struct ac_t {
+
+ /**
+ * Implements the certificate_t interface
+ */
+ certificate_t certificate;
+
+ /**
+ * Get the attribute certificate's serial number.
+ *
+ * @return chunk pointing to serialNumber
+ */
+ chunk_t (*get_serial)(ac_t *this);
+
+ /**
+ * Get the serial number of the holder certificate.
+ *
+ * @return chunk pointing to serialNumber
+ */
+ chunk_t (*get_holderSerial)(ac_t *this);
+
+ /**
+ * Get the issuer of the holder certificate.
+ *
+ * @return holderIssuer as identification_t*
+ */
+ identification_t* (*get_holderIssuer)(ac_t *this);
+
+ /**
+ * Get the thauthorityKeyIdentifier.
+ *
+ * @return authKeyIdentifier as identification_t*
+ */
+ identification_t* (*get_authKeyIdentifier)(ac_t *this);
+
+ /**
+ * @brief Checks if two attribute certificates belong to the same holder
+ *
+ * @param this calling attribute certificate
+ * @param that other attribute certificate
+ * @return TRUE if same holder
+ */
+ bool (*equals_holder) (ac_t *this, ac_t *other);
+};
+
+#endif /* AC_H_ @}*/
+
diff --git a/src/libstrongswan/credentials/certificates/certificate.c b/src/libstrongswan/credentials/certificates/certificate.c
new file mode 100644
index 000000000..c5bc9a68d
--- /dev/null
+++ b/src/libstrongswan/credentials/certificates/certificate.c
@@ -0,0 +1,41 @@
+/*
+ * 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: certificate.c 3664 2008-03-26 15:21:50Z martin $
+ */
+
+#include "certificate.h"
+
+#include <credentials/certificates/x509.h>
+
+ENUM(certificate_type_names, CERT_ANY, CERT_PGP,
+ "ANY",
+ "X509",
+ "X509_CRL",
+ "X509_OCSP_REQUEST",
+ "X509_OCSP_RESPONSE",
+ "X509_AC",
+ "X509_CHAIN",
+ "TRUSTED_PUBKEY",
+ "PGP",
+);
+
+ENUM(cert_validation_names, VALIDATION_GOOD, VALIDATION_SKIPPED,
+ "VALIDATION_GOOD",
+ "VALIDATION_STALE",
+ "VALIDATION_REVOKED",
+ "VALIDATION_FAILED",
+ "VALIDATION_SKIPPED",
+);
+
diff --git a/src/libstrongswan/credentials/certificates/certificate.h b/src/libstrongswan/credentials/certificates/certificate.h
new file mode 100644
index 000000000..14f4de389
--- /dev/null
+++ b/src/libstrongswan/credentials/certificates/certificate.h
@@ -0,0 +1,192 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup certificate certificate
+ * @{ @ingroup certificates
+ */
+
+#ifndef CERTIFICATE_H_
+#define CERTIFICATE_H_
+
+typedef struct certificate_t certificate_t;
+typedef enum certificate_type_t certificate_type_t;
+typedef enum cert_validation_t cert_validation_t;
+
+#include <library.h>
+#include <utils/identification.h>
+#include <credentials/keys/public_key.h>
+
+/**
+ * Kind of a certificate_t
+ */
+enum certificate_type_t {
+ /** just any certificate */
+ CERT_ANY,
+ /** X.509 certificate */
+ CERT_X509,
+ /** X.509 certificate revocation list */
+ CERT_X509_CRL,
+ /** X.509 online certificate status protocol request */
+ CERT_X509_OCSP_REQUEST,
+ /** X.509 online certificate status protocol response */
+ CERT_X509_OCSP_RESPONSE,
+ /** X.509 attribute certificate */
+ CERT_X509_AC,
+ /** trusted, preinstalled public key */
+ CERT_TRUSTED_PUBKEY,
+ /** PGP certificate */
+ CERT_PGP,
+};
+
+/**
+ * Enum names for certificate_type_t
+ */
+extern enum_name_t *certificate_type_names;
+
+/**
+ * Result of a certificate validation.
+ */
+enum cert_validation_t {
+ /** certificate has been validated successfully */
+ VALIDATION_GOOD,
+ /** certificate has been validated, but check based on stale information */
+ VALIDATION_STALE,
+ /** certificate has been revoked */
+ VALIDATION_REVOKED,
+ /** validation failed due to a processing error */
+ VALIDATION_FAILED,
+ /** validation has been skipped due to missing validation information */
+ VALIDATION_SKIPPED,
+};
+
+/**
+ * Enum names for cert_validation_t
+ */
+extern enum_name_t *cert_validation_names;
+
+/**
+ * An abstract certificate.
+ *
+ * A certificate designs a subject-issuer relationship. It may have an
+ * associated public key.
+ */
+struct certificate_t {
+
+ /**
+ * Get the type of the certificate.
+ *
+ * @return certifcate type
+ */
+ certificate_type_t (*get_type)(certificate_t *this);
+
+ /**
+ * Get the primary subject to which this certificate belongs.
+ *
+ * @return subject identity
+ */
+ identification_t* (*get_subject)(certificate_t *this);
+
+ /**
+ * Check if certificate contains a subject ID.
+ *
+ * A certificate may contain additional subject identifiers, which are
+ * not returned by get_subject (e.g. subjectAltNames)
+ *
+ * @param subject subject identity
+ * @return matching value of best match
+ */
+ id_match_t (*has_subject)(certificate_t *this, identification_t *subject);
+
+ /**
+ * Get the issuer which signed this certificate.
+ *
+ * @return issuer identity
+ */
+ identification_t* (*get_issuer)(certificate_t *this);
+
+ /**
+ * Check if certificate contains an issuer ID.
+ *
+ * A certificate may contain additional issuer identifiers, which are
+ * not returned by get_issuer (e.g. issuerAltNames)
+ *
+ * @param subject isser identity
+ * @return matching value of best match
+ */
+ id_match_t (*has_issuer)(certificate_t *this, identification_t *issuer);
+
+ /**
+ * Check if this certificate is issued and signed by a specific issuer.
+ *
+ * @param issuer issuer's certificate
+ * @return TRUE if certificate issued by issuer and trusted
+ */
+ bool (*issued_by)(certificate_t *this, certificate_t *issuer);
+
+ /**
+ * Get the public key associated to this certificate.
+ *
+ * @return newly referenced public_key, NULL if none available
+ */
+ public_key_t* (*get_public_key)(certificate_t *this);
+
+ /**
+ * Check the lifetime of the certificate.
+ *
+ * @param when check validity at a certain time (NULL for now)
+ * @param not_before receives certificates start of lifetime
+ * @param not_after receives certificates end of lifetime
+ * @return TRUE if when between not_after and not_before
+ */
+ bool (*get_validity)(certificate_t *this, time_t *when,
+ time_t *not_before, time_t *not_after);
+
+ /**
+ * Is this newer than that?
+ *
+ * @return TRUE if newer, FALSE otherwise
+ */
+ bool (*is_newer)(certificate_t *this, certificate_t *that);
+
+ /**
+ * Get the certificate in an encoded form.
+ *
+ * @return allocated chunk of encoded cert
+ */
+ chunk_t (*get_encoding)(certificate_t *this);
+
+ /**
+ * Check if two certificates are equal.
+ *
+ * @param other certificate to compair against this
+ * @return TRUE if certificates are equal
+ */
+ bool (*equals)(certificate_t *this, certificate_t *other);
+
+ /**
+ * Get a new reference to the certificate.
+ *
+ * @return this, with an increased refcount
+ */
+ certificate_t* (*get_ref)(certificate_t *this);
+
+ /**
+ * Destroy a certificate.
+ */
+ void (*destroy)(certificate_t *this);
+};
+
+#endif /* CERTIFICATE_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/crl.c b/src/libstrongswan/credentials/certificates/crl.c
new file mode 100644
index 000000000..1fdc095c1
--- /dev/null
+++ b/src/libstrongswan/credentials/certificates/crl.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2006 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: crl.c 3656 2008-03-25 22:28:27Z andreas $
+ */
+
+#include "crl.h"
+
+ENUM(crl_reason_names, CRL_UNSPECIFIED, CRL_REMOVE_FROM_CRL,
+ "unspecified",
+ "key compromise",
+ "ca compromise",
+ "affiliation changed",
+ "superseded",
+ "cessation of operation",
+ "certificate hold",
+ "reason #7",
+ "remove from crl",
+);
diff --git a/src/libstrongswan/credentials/certificates/crl.h b/src/libstrongswan/credentials/certificates/crl.h
new file mode 100644
index 000000000..f1fb70efd
--- /dev/null
+++ b/src/libstrongswan/credentials/certificates/crl.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2006 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: crl.h 3656 2008-03-25 22:28:27Z andreas $
+ */
+
+/**
+ * @defgroup crl crl
+ * @{ @ingroup certificates
+ */
+
+#ifndef CRL_H_
+#define CRL_H_
+
+typedef struct crl_t crl_t;
+typedef enum crl_reason_t crl_reason_t;
+
+#include <library.h>
+#include <credentials/certificates/certificate.h>
+
+/**
+ * RFC 2459 CRL reason codes
+ */
+enum crl_reason_t {
+ CRL_UNSPECIFIED = 0,
+ CRL_KEY_COMPROMISE = 1,
+ CRL_CA_COMPROMISE = 2,
+ CRL_AFFILIATION_CHANGED = 3,
+ CRL_SUPERSEDED = 4,
+ CRL_CESSATION_OF_OPERATON = 5,
+ CRL_CERTIFICATE_HOLD = 6,
+ CRL_REMOVE_FROM_CRL = 8,
+};
+
+/**
+ * enum names for crl_reason_t
+ */
+extern enum_name_t *crl_reason_names;
+
+/**
+ * X509 certificate revocation list (CRL) interface definition.
+ */
+struct crl_t {
+
+ /**
+ * Implements (parts of) the certificate_t interface
+ */
+ certificate_t certificate;
+
+ /**
+ * Get the CRL serial number.
+ *
+ * @return chunk pointing to internal crlNumber
+ */
+ chunk_t (*get_serial)(crl_t *this);
+
+ /**
+ * Get the the authorityKeyIdentifier.
+ *
+ * @return authKeyIdentifier as identification_t*
+ */
+ identification_t* (*get_authKeyIdentifier)(crl_t *this);
+
+ /**
+ * Create an enumerator over all revoked certificates.
+ *
+ * The enumerator takes 3 pointer arguments:
+ * chunk_t serial, time_t revocation_date, crl_reason_t reason
+ *
+ * @return enumerator over revoked certificates.
+ */
+ enumerator_t* (*create_enumerator)(crl_t *this);
+
+};
+
+#endif /* CRL_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/ocsp_request.h b/src/libstrongswan/credentials/certificates/ocsp_request.h
new file mode 100644
index 000000000..377eabd23
--- /dev/null
+++ b/src/libstrongswan/credentials/certificates/ocsp_request.h
@@ -0,0 +1,41 @@
+/*
+ * 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_request ocsp_request
+ * @{ @ingroup certificates
+ */
+
+#ifndef OCSP_REQUEST_H_
+#define OCSP_REQUEST_H_
+
+#include <credentials/certificates/certificate.h>
+
+typedef struct ocsp_request_t ocsp_request_t;
+
+/**
+ * OCSP request message.
+ */
+struct ocsp_request_t {
+
+ /**
+ * Implements certificiate_t interface
+ */
+ certificate_t interface;
+};
+
+#endif /* OCSP_REQUEST_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/ocsp_response.c b/src/libstrongswan/credentials/certificates/ocsp_response.c
new file mode 100644
index 000000000..02e12f761
--- /dev/null
+++ b/src/libstrongswan/credentials/certificates/ocsp_response.c
@@ -0,0 +1,29 @@
+/*
+ * 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.h"
+
+ENUM(ocsp_status_names, OCSP_SUCCESSFUL, OCSP_UNAUTHORIZED,
+ "successful",
+ "malformed request",
+ "internal error",
+ "try later",
+ "status #4",
+ "signature required",
+ "unauthorized"
+);
+
diff --git a/src/libstrongswan/credentials/certificates/ocsp_response.h b/src/libstrongswan/credentials/certificates/ocsp_response.h
new file mode 100644
index 000000000..416f712f3
--- /dev/null
+++ b/src/libstrongswan/credentials/certificates/ocsp_response.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$
+ */
+
+/**
+ * @defgroup ocsp_response ocsp_response
+ * @{ @ingroup certificates
+ */
+
+#ifndef OCSP_RESPONSE_H_
+#define OCSP_RESPONSE_H_
+
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+
+typedef struct ocsp_response_t ocsp_response_t;
+typedef enum ocsp_status_t ocsp_status_t;
+
+/**
+ * OCSP response status
+ */
+enum ocsp_status_t {
+ OCSP_SUCCESSFUL = 0,
+ OCSP_MALFORMEDREQUEST = 1,
+ OCSP_INTERNALERROR = 2,
+ OCSP_TRYLATER = 3,
+ OCSP_SIGREQUIRED = 5,
+ OCSP_UNAUTHORIZED = 6,
+};
+
+/**
+ * enum names for ocsp_status_t
+ */
+extern enum_name_t *ocsp_status_names;
+
+/**
+ * OCSP response message.
+ */
+struct ocsp_response_t {
+
+ /**
+ * Implements certificiate_t interface
+ */
+ certificate_t certificate;
+
+ /**
+ * Check the status of a certificate by this OCSP response.
+ *
+ * @param subject certificate to check status
+ * @param issuer issuer certificate of subject
+ * @param revocation_time receives time of revocation, if revoked
+ * @param revocation_reason receives reason of revocation, if revoked
+ * @param this_update creation time of revocation list
+ * @param next_update exptected time of next revocation list
+ * @return certificate revocation status
+ */
+ cert_validation_t (*get_status)(ocsp_response_t *this,
+ x509_t *subject, x509_t *issuer,
+ time_t *revocation_time,
+ crl_reason_t *revocation_reason,
+ time_t *this_update, time_t *next_update);
+
+ /**
+ * Create an enumerator over the contained certificates.
+ *
+ * @return enumerator over certificate_t*
+ */
+ enumerator_t* (*create_cert_enumerator)(ocsp_response_t *this);
+};
+
+#endif /* OCSP_RESPONSE_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/x509.c b/src/libstrongswan/credentials/certificates/x509.c
new file mode 100644
index 000000000..15d223e3e
--- /dev/null
+++ b/src/libstrongswan/credentials/certificates/x509.c
@@ -0,0 +1,26 @@
+/*
+ * 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: x509.c 3656 2008-03-25 22:28:27Z andreas $
+ */
+
+#include "x509.h"
+
+ENUM(x509_flag_names, X509_CA, X509_SELF_SIGNED,
+ "X509_CA",
+ "X509_AA",
+ "X509_OCSP_SIGNER",
+ "X509_SELF_SIGNED",
+);
+
diff --git a/src/libstrongswan/credentials/certificates/x509.h b/src/libstrongswan/credentials/certificates/x509.h
new file mode 100644
index 000000000..737dcdc67
--- /dev/null
+++ b/src/libstrongswan/credentials/certificates/x509.h
@@ -0,0 +1,107 @@
+/*
+ * 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: x509.h 3656 2008-03-25 22:28:27Z andreas $
+ */
+
+/**
+ * @defgroup x509 x509
+ * @{ @ingroup certificates
+ */
+
+#ifndef X509_H_
+#define X509_H_
+
+#include <utils/enumerator.h>
+#include <credentials/certificates/certificate.h>
+
+typedef struct x509_t x509_t;
+typedef enum x509_flag_t x509_flag_t;
+
+/**
+ * X.509 certificate flags.
+ */
+enum x509_flag_t {
+ /** cert has CA constraint */
+ X509_CA = (1<<0),
+ /** cert has AA constraint */
+ X509_AA = (1<<1),
+ /** cert has OCSP signer constraint */
+ X509_OCSP_SIGNER = (1<<2),
+ /** cert is self-signed */
+ X509_SELF_SIGNED = (1<<3),
+};
+
+/**
+ * enum names for x509 flags
+ */
+extern enum_name_t *x509_flag_names;
+
+/**
+ * X.509 certificate interface.
+ *
+ * This interface adds additional methods to the certificate_t type to
+ * allow further operations on these certificates.
+ */
+struct x509_t {
+
+ /**
+ * Implements certificate_t.
+ */
+ certificate_t interface;
+
+ /**
+ * Get the flags set for this certificate.
+ *
+ * @return set of flags
+ */
+ x509_flag_t (*get_flags)(x509_t *this);
+
+ /**
+ * Get the certificate serial number.
+ *
+ * @return chunk pointing to internal serial number
+ */
+ chunk_t (*get_serial)(x509_t *this);
+
+ /**
+ * Get the the authorityKeyIdentifier.
+ *
+ * @return authKeyIdentifier as identification_t*
+ */
+ identification_t* (*get_authKeyIdentifier)(x509_t *this);
+
+ /**
+ * Create an enumerator over all subjectAltNames.
+ *
+ * @return enumerator over subjectAltNames as identification_t*
+ */
+ enumerator_t* (*create_subjectAltName_enumerator)(x509_t *this);
+
+ /**
+ * Create an enumerator over all CRL URIs.
+ *
+ * @return enumerator over URIs as char*
+ */
+ enumerator_t* (*create_crl_uri_enumerator)(x509_t *this);
+
+ /**
+ * Create an enumerator over all OCSP URIs.
+ *
+ * @return enumerator over URIs as char*
+ */
+ enumerator_t* (*create_ocsp_uri_enumerator)(x509_t *this);
+};
+
+#endif /* X509_H_ @}*/
diff --git a/src/libstrongswan/credentials/credential_factory.c b/src/libstrongswan/credentials/credential_factory.c
new file mode 100644
index 000000000..52ee2060d
--- /dev/null
+++ b/src/libstrongswan/credentials/credential_factory.c
@@ -0,0 +1,312 @@
+/*
+ * 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: credential_factory.c 4059 2008-06-11 14:10:02Z martin $
+ */
+
+#include "credential_factory.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+#include <credentials/certificates/x509.h>
+
+ENUM(credential_type_names, CRED_PRIVATE_KEY, CRED_CERTIFICATE,
+ "CRED_PRIVATE_KEY",
+ "CRED_PUBLIC_KEY",
+ "CRED_CERTIFICATE",
+);
+
+typedef struct private_credential_factory_t private_credential_factory_t;
+
+/**
+ * private data of credential_factory
+ */
+struct private_credential_factory_t {
+
+ /**
+ * public functions
+ */
+ credential_factory_t public;
+
+ /**
+ * list with entry_t
+ */
+ linked_list_t *constructors;
+
+ /**
+ * mutex to lock access to modules
+ */
+ mutex_t *mutex;
+};
+
+typedef struct entry_t entry_t;
+struct entry_t {
+ /** kind of credential builder */
+ credential_type_t type;
+ /** subtype of credential, e.g. certificate_type_t */
+ int subtype;
+ /** builder construction function */
+ builder_constructor_t constructor;
+};
+
+/**
+ * Implementation of credential_factory_t.create_builder.
+ */
+static builder_t* create_builder(private_credential_factory_t *this,
+ credential_type_t type, int subtype)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ builder_t *builder = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->constructors->create_enumerator(this->constructors);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->type == type && entry->subtype == subtype)
+ {
+ builder = entry->constructor(subtype);
+ if (builder)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return builder;
+}
+
+/**
+ * Implementation of credential_factory_t.add_builder_constructor.
+ */
+static void add_builder(private_credential_factory_t *this,
+ credential_type_t type, int subtype,
+ builder_constructor_t constructor)
+{
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->type = type;
+ entry->subtype = subtype;
+ entry->constructor = constructor;
+ this->mutex->lock(this->mutex);
+ this->constructors->insert_last(this->constructors, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of credential_factory_t.remove_builder.
+ */
+static void remove_builder(private_credential_factory_t *this,
+ builder_constructor_t constructor)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->constructors->create_enumerator(this->constructors);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->constructor == constructor)
+ {
+ this->constructors->remove_at(this->constructors, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of credential_factory_t.create.
+ */
+static void* create(private_credential_factory_t *this, credential_type_t type,
+ int subtype, ...)
+{
+ builder_t *builder;
+ builder_part_t part;
+ va_list args;
+
+ builder = create_builder(this, type, subtype);
+ if (builder)
+ {
+ va_start(args, subtype);
+ while (TRUE)
+ {
+ part = va_arg(args, builder_part_t);
+
+ switch (part)
+ {
+ case BUILD_END:
+ break;
+ case BUILD_BLOB_ASN1_DER:
+ case BUILD_SERIAL:
+ builder->add(builder, part, va_arg(args, chunk_t));
+ continue;
+ case BUILD_X509_FLAG:
+ builder->add(builder, part, va_arg(args, x509_flag_t));
+ continue;
+ case BUILD_KEY_SIZE:
+ builder->add(builder, part, va_arg(args, u_int));
+ continue;
+ case BUILD_NOT_BEFORE_TIME:
+ case BUILD_NOT_AFTER_TIME:
+ builder->add(builder, part, va_arg(args, time_t));
+ continue;
+ case BUILD_BLOB_ASN1_PEM:
+ case BUILD_FROM_FILE:
+ case BUILD_SIGNING_KEY:
+ case BUILD_PUBLIC_KEY:
+ case BUILD_SUBJECT:
+ case BUILD_SUBJECT_ALTNAME:
+ case BUILD_ISSUER:
+ case BUILD_ISSUER_ALTNAME:
+ case BUILD_SIGNING_CERT:
+ case BUILD_CA_CERT:
+ case BUILD_CERT:
+ case BUILD_IETF_GROUP_ATTR:
+ builder->add(builder, part, va_arg(args, void*));
+ continue;
+ default:
+ DBG1("builder part %N not supported by factory",
+ builder_part_names, part);
+ break;
+ }
+ break;
+ }
+ va_end(args);
+
+ return builder->build(builder);
+ }
+ else
+ {
+ DBG1("failed to create a builder for credential type %N,"
+ " subtype (%d)", credential_type_names, type, subtype);
+ }
+
+ /** shredder all data on failure */
+ va_start(args, subtype);
+ while (TRUE)
+ {
+ part = va_arg(args, builder_part_t);
+
+ switch (part)
+ {
+ case BUILD_END:
+ break;
+ case BUILD_BLOB_ASN1_DER:
+ {
+ chunk_t chunk = va_arg(args, chunk_t);
+ free(chunk.ptr);
+ continue;
+ }
+ case BUILD_SERIAL:
+ {
+ va_arg(args, chunk_t);
+ continue;
+ }
+ case BUILD_X509_FLAG:
+ {
+ va_arg(args, x509_flag_t);
+ continue;
+ }
+ case BUILD_KEY_SIZE:
+ {
+ va_arg(args, u_int);
+ continue;
+ }
+ case BUILD_NOT_BEFORE_TIME:
+ case BUILD_NOT_AFTER_TIME:
+ {
+ va_arg(args, time_t);
+ continue;
+ }
+ case BUILD_SIGNING_KEY:
+ {
+ private_key_t *private = va_arg(args, private_key_t*);
+ private->destroy(private);
+ continue;
+ }
+ case BUILD_PUBLIC_KEY:
+ {
+ public_key_t *public = va_arg(args, public_key_t*);
+ public->destroy(public);
+ continue;
+ }
+ case BUILD_SUBJECT:
+ case BUILD_SUBJECT_ALTNAME:
+ case BUILD_ISSUER:
+ case BUILD_ISSUER_ALTNAME:
+ {
+ identification_t *id = va_arg(args, identification_t*);
+ id->destroy(id);
+ continue;
+ }
+ case BUILD_SIGNING_CERT:
+ case BUILD_CA_CERT:
+ case BUILD_CERT:
+ {
+ certificate_t *cert = va_arg(args, certificate_t*);
+ cert->destroy(cert);
+ continue;
+ }
+ case BUILD_BLOB_ASN1_PEM:
+ case BUILD_FROM_FILE:
+ case BUILD_IETF_GROUP_ATTR:
+ {
+ va_arg(args, void*);
+ continue;
+ }
+ default:
+ DBG1("builder part %N not supported by factory",
+ builder_part_names, part);
+ continue;
+ }
+ break;
+ }
+ va_end(args);
+ return NULL;
+}
+
+/**
+ * Implementation of credential_factory_t.destroy
+ */
+static void destroy(private_credential_factory_t *this)
+{
+ this->constructors->destroy_function(this->constructors, free);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+credential_factory_t *credential_factory_create()
+{
+ private_credential_factory_t *this = malloc_thing(private_credential_factory_t);
+
+ this->public.create = (void*(*)(credential_factory_t*, credential_type_t type, int subtype, ...))create;
+ this->public.create_builder = (builder_t*(*)(credential_factory_t*, credential_type_t type, int subtype))create_builder;
+ this->public.add_builder = (void(*)(credential_factory_t*,credential_type_t type, int subtype, builder_constructor_t constructor))add_builder;
+ this->public.remove_builder = (void(*)(credential_factory_t*,builder_constructor_t constructor))remove_builder;
+ this->public.destroy = (void(*)(credential_factory_t*))destroy;
+
+ this->constructors = linked_list_create();
+
+ this->mutex = mutex_create(MUTEX_RECURSIVE);
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/credentials/credential_factory.h b/src/libstrongswan/credentials/credential_factory.h
new file mode 100644
index 000000000..873cf8ab2
--- /dev/null
+++ b/src/libstrongswan/credentials/credential_factory.h
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup credential_factory credential_factory
+ * @{ @ingroup credentials
+ */
+
+#ifndef CREDENTIAL_FACTORY_H_
+#define CREDENTIAL_FACTORY_H_
+
+typedef struct credential_factory_t credential_factory_t;
+typedef enum credential_type_t credential_type_t;
+
+#include <credentials/keys/private_key.h>
+#include <credentials/keys/public_key.h>
+#include <credentials/certificates/certificate.h>
+#include <credentials/builder.h>
+
+/**
+ * Kind of credential.
+ */
+enum credential_type_t {
+ /** private key, implemented in private_key_t */
+ CRED_PRIVATE_KEY,
+ /** public key, implemented in public_key_t */
+ CRED_PUBLIC_KEY,
+ /** certificates, implemented in certificate_t */
+ CRED_CERTIFICATE,
+};
+
+/**
+ * enum names for credential_type_t
+ */
+extern enum_name_t *credential_type_names;
+
+/**
+ * Manages credential construction functions and creates instances.
+ */
+struct credential_factory_t {
+
+ /**
+ * Create a credential using a list of builder_part_t's.
+ *
+ * The variable argument list takes builder_part_t types followed
+ * by the type specific value. The list must be terminated using BUILD_END.
+ *
+ * @param type credential type to build
+ * @param subtype subtype specific for type of the credential
+ * @param ... build_part_t arguments, BUILD_END terminated.
+ * @return type specific credential, NULL if failed
+ */
+ void* (*create)(credential_factory_t *this, credential_type_t type,
+ int subtype, ...);
+
+ /**
+ * Create a builder instance to build credentials.
+ *
+ * @param type type of credentials the builder creates
+ * @param subtype type specific subtype, such as certificate_type_t
+ * @return builder instance
+ */
+ builder_t* (*create_builder)(credential_factory_t *this,
+ credential_type_t type, int subtype);
+ /**
+ * Register a builder_t constructor function.
+ *
+ * @param type type of credential the builder creates
+ * @param constructor builder constructor function to register
+ */
+ void (*add_builder)(credential_factory_t *this,
+ credential_type_t type, int subtype,
+ builder_constructor_t constructor);
+ /**
+ * Unregister a builder_t constructor function.
+ *
+ * @param constructor constructor function to unregister.
+ */
+ void (*remove_builder)(credential_factory_t *this,
+ builder_constructor_t constructor);
+
+ /**
+ * Destroy a credential_factory instance.
+ */
+ void (*destroy)(credential_factory_t *this);
+};
+
+/**
+ * Create a credential_factory instance.
+ */
+credential_factory_t *credential_factory_create();
+
+#endif /* CREDENTIAL_FACTORY_H_ @}*/
diff --git a/src/libstrongswan/credentials/keys/private_key.c b/src/libstrongswan/credentials/keys/private_key.c
new file mode 100644
index 000000000..018cab1c0
--- /dev/null
+++ b/src/libstrongswan/credentials/keys/private_key.c
@@ -0,0 +1,19 @@
+/*
+ * 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: private_key.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "private_key.h"
+
diff --git a/src/libstrongswan/credentials/keys/private_key.h b/src/libstrongswan/credentials/keys/private_key.h
new file mode 100644
index 000000000..c28988309
--- /dev/null
+++ b/src/libstrongswan/credentials/keys/private_key.h
@@ -0,0 +1,114 @@
+/*
+ * 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: private_key.h 3620 2008-03-19 14:21:56Z martin $
+ */
+
+/**
+ * @defgroup private_key private_key
+ * @{ @ingroup keys
+ */
+
+#ifndef PRIVATE_KEY_H_
+#define PRIVATE_KEY_H_
+
+typedef struct private_key_t private_key_t;
+
+#include <utils/identification.h>
+#include <credentials/keys/public_key.h>
+
+/**
+ * Abstract private key interface.
+ */
+struct private_key_t {
+
+ /**
+ * Get the key type.
+ *
+ * @return type of the key
+ */
+ key_type_t (*get_type)(private_key_t *this);
+
+ /**
+ * Create a signature over a chunk of data.
+ *
+ * @param scheme signature scheme to use
+ * @param data chunk of data to sign
+ * @param signature where to allocate created signature
+ * @return TRUE if signature created
+ */
+ bool (*sign)(private_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t *signature);
+ /**
+ * Decrypt a chunk of data.
+ *
+ * @param crypto chunk containing encrypted data
+ * @param plain where to allocate decrypted data
+ * @return TRUE if data decrypted and plaintext allocated
+ */
+ bool (*decrypt)(private_key_t *this, chunk_t crypto, chunk_t *plain);
+
+ /**
+ * Get the strength of the key in bytes.
+ *
+ * @return strength of the key in bytes
+ */
+ size_t (*get_keysize) (private_key_t *this);
+
+ /**
+ * Get a unique key identifier, such as a hash over the public key.
+ *
+ * @param type type of the key ID to get
+ * @return unique ID of the key as identification_t, or NULL
+ */
+ identification_t* (*get_id) (private_key_t *this, id_type_t type);
+
+ /**
+ * Get the public part from the private key.
+ *
+ * @return public key
+ */
+ public_key_t* (*get_public_key)(private_key_t *this);
+
+ /**
+ * Check if a private key belongs to a public key.
+ *
+ * @param public public key
+ * @return TRUE, if keys belong together
+ */
+ bool (*belongs_to) (private_key_t *this, public_key_t *public);
+
+ /**
+ * Get an encoded form of the private key.
+ *
+ * @todo Do we need a encoding type specification?
+ *
+ * @return allocated chunk containing encoded private key
+ */
+ chunk_t (*get_encoding)(private_key_t *this);
+
+ /**
+ * Increase the refcount to this private key.
+ *
+ * @return this, with an increased refcount
+ */
+ private_key_t* (*get_ref)(private_key_t *this);
+
+ /**
+ * Decrease refcount, destroy private_key if no more references.
+ */
+ void (*destroy)(private_key_t *this);
+};
+
+#endif /* PRIVATE_KEY_H_ @} */
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c
new file mode 100644
index 000000000..80b9f03c3
--- /dev/null
+++ b/src/libstrongswan/credentials/keys/public_key.c
@@ -0,0 +1,37 @@
+/*
+ * 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: public_key.c 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+#include "public_key.h"
+
+ENUM(key_type_names, KEY_RSA, KEY_ECDSA,
+ "RSA",
+ "ECDSA"
+);
+
+ENUM(signature_scheme_names, SIGN_DEFAULT, SIGN_ECDSA_521,
+ "DEFAULT",
+ "RSA_EMSA_PKCS1_MD5",
+ "RSA_EMSA_PKCS1_SHA1",
+ "RSA_EMSA_PKCS1_SHA256",
+ "RSA_EMSA_PKCS1_SHA384",
+ "RSA_EMSA_PKCS1_SHA512",
+ "ECDSA_WITH_SHA1",
+ "ECDSA-256",
+ "ECDSA-384",
+ "ECDSA-521",
+);
+
diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h
new file mode 100644
index 000000000..62dbe4303
--- /dev/null
+++ b/src/libstrongswan/credentials/keys/public_key.h
@@ -0,0 +1,155 @@
+/*
+ * 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: public_key.h 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+/**
+ * @defgroup public_key public_key
+ * @{ @ingroup keys
+ */
+
+#ifndef PUBLIC_KEY_H_
+#define PUBLIC_KEY_H_
+
+typedef struct public_key_t public_key_t;
+typedef enum key_type_t key_type_t;
+typedef enum key_id_type_t key_id_type_t;
+typedef enum signature_scheme_t signature_scheme_t;
+
+#include <library.h>
+#include <utils/identification.h>
+
+/**
+ * Type of a key pair, the used crypto system
+ */
+enum key_type_t {
+ /** key type wildcard */
+ KEY_ANY,
+ /** RSA crypto system as in PKCS#1 */
+ KEY_RSA,
+ /** ECDSA as in ANSI X9.62 */
+ KEY_ECDSA,
+ /** DSS, ElGamal, ... */
+};
+
+/**
+ * Enum names for key_type_t
+ */
+extern enum_name_t *key_type_names;
+
+/**
+ * Signature scheme for signature creation
+ *
+ * EMSA-PKCS1 signatures are from the PKCS#1 standard. They include
+ * the ASN1-OID of the used hash algorithm.
+ */
+enum signature_scheme_t {
+ /** default scheme of that underlying crypto system */
+ SIGN_DEFAULT,
+ /** EMSA-PKCS1 with MD5 */
+ SIGN_RSA_EMSA_PKCS1_MD5,
+ /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA1 as hash. */
+ SIGN_RSA_EMSA_PKCS1_SHA1,
+ /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA256 as hash. */
+ SIGN_RSA_EMSA_PKCS1_SHA256,
+ /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA384 as hash. */
+ SIGN_RSA_EMSA_PKCS1_SHA384,
+ /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA512 as hash. */
+ SIGN_RSA_EMSA_PKCS1_SHA512,
+ /** ECDSA using SHA-1 as hash. */
+ SIGN_ECDSA_WITH_SHA1,
+ /** ECDSA with SHA-256 on the P-256 curve as in RFC 4754 */
+ SIGN_ECDSA_256,
+ /** ECDSA with SHA-384 on the P-384 curve as in RFC 4754 */
+ SIGN_ECDSA_384,
+ /** ECDSA with SHA-512 on the P-521 curve as in RFC 4754 */
+ SIGN_ECDSA_521,
+};
+
+/**
+ * Enum names for signature_scheme_t
+ */
+extern enum_name_t *signature_scheme_names;
+
+/**
+ * Abstract interface of a public key.
+ */
+struct public_key_t {
+
+ /**
+ * Get the key type.
+ *
+ * @return type of the key
+ */
+ key_type_t (*get_type)(public_key_t *this);
+
+ /**
+ * Verifies a signature against a chunk of data.
+ *
+ * @param scheme signature scheme to use for verification, may be default
+ * @param data data to check signature against
+ * @param signature signature to check
+ * @return TRUE if signature matches
+ */
+ bool (*verify)(public_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t signature);
+
+ /**
+ * Encrypt a chunk of data.
+ *
+ * @param crypto chunk containing plaintext data
+ * @param plain where to allocate encrypted data
+ * @return TRUE if data successfully encrypted
+ */
+ bool (*encrypt)(public_key_t *this, chunk_t crypto, chunk_t *plain);
+
+ /**
+ * Get the strength of the key in bytes.
+ *
+ * @return strength of the key in bytes
+ */
+ size_t (*get_keysize) (public_key_t *this);
+
+ /**
+ * Get a unique key identifier, such as a hash over the key.
+ *
+ * @param type type of the key ID to get
+ * @return unique ID of the key as identification_t, or NULL
+ */
+ identification_t* (*get_id) (public_key_t *this, id_type_t type);
+
+ /**
+ * Get an encoded form of the key.
+ *
+ * @todo Do we need a encoding type specification?
+ *
+ * @return allocated chunk containing encoded key
+ */
+ chunk_t (*get_encoding)(public_key_t *this);
+
+ /**
+ * Increase the refcount of the key.
+ *
+ * @return this with an increased refcount
+ */
+ public_key_t* (*get_ref)(public_key_t *this);
+
+ /**
+ * Destroy a public_key instance.
+ */
+ void (*destroy)(public_key_t *this);
+};
+
+#endif /* PUBLIC_KEY_H_ @} */
diff --git a/src/libstrongswan/credentials/keys/shared_key.c b/src/libstrongswan/credentials/keys/shared_key.c
new file mode 100644
index 000000000..f55b52c3a
--- /dev/null
+++ b/src/libstrongswan/credentials/keys/shared_key.c
@@ -0,0 +1,111 @@
+/*
+ * 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: shared_key.c 3600 2008-03-14 15:11:29Z martin $
+ */
+
+#include "shared_key.h"
+
+ENUM(shared_key_type_names, SHARED_ANY, SHARED_PIN,
+ "ANY",
+ "IKE",
+ "EAP",
+ "PRIVATE_KEY_PASS",
+ "PIN",
+);
+
+typedef struct private_shared_key_t private_shared_key_t;
+
+/**
+ * private data of shared_key
+ */
+struct private_shared_key_t {
+
+ /**
+ * public functions
+ */
+ shared_key_t public;
+
+ /**
+ * type of this shared key
+ */
+ shared_key_type_t type;
+
+ /**
+ * associated shared key data
+ */
+ chunk_t key;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * Implements shared_key_t.get_type
+ */
+static shared_key_type_t get_type(private_shared_key_t *this)
+{
+ return this->type;
+}
+
+/**
+ * Implements shared_key_t.get_key
+ */
+static chunk_t get_key(private_shared_key_t *this)
+{
+ return this->key;
+}
+
+/**
+ * Implements shared_key_t.get_ref
+ */
+static shared_key_t* get_ref(private_shared_key_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
+/**
+ * Implementation of shared_key_t.destroy
+ */
+static void destroy(private_shared_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->key.ptr);
+ free(this);
+ }
+}
+
+/*
+ * see header file
+ */
+shared_key_t *shared_key_create(shared_key_type_t type, chunk_t key)
+{
+ private_shared_key_t *this = malloc_thing(private_shared_key_t);
+
+ this->public.get_type = (shared_key_type_t (*)(shared_key_t *this))get_type;
+ this->public.get_key = (chunk_t (*)(shared_key_t *this))get_key;
+ this->public.get_ref = (shared_key_t* (*)(shared_key_t *this))get_ref;
+ this->public.destroy = (void(*)(shared_key_t*))destroy;
+
+ this->type = type;
+ this->key = key;
+ this->ref = 1;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/credentials/keys/shared_key.h b/src/libstrongswan/credentials/keys/shared_key.h
new file mode 100644
index 000000000..ceb1309b7
--- /dev/null
+++ b/src/libstrongswan/credentials/keys/shared_key.h
@@ -0,0 +1,95 @@
+/*
+ * 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 shared_key shared_key
+ * @{ @ingroup keys
+ */
+
+#ifndef SHARED_KEY_H_
+#define SHARED_KEY_H_
+
+#include <utils/enumerator.h>
+#include <utils/identification.h>
+
+typedef struct shared_key_t shared_key_t;
+typedef enum shared_key_type_t shared_key_type_t;
+
+/**
+ * Type of a shared key.
+ */
+enum shared_key_type_t {
+ /** wildcard for all keys */
+ SHARED_ANY,
+ /** PSK for IKE authentication */
+ SHARED_IKE,
+ /** key for a EAP authentication method */
+ SHARED_EAP,
+ /** key to decrypt encrypted private keys */
+ SHARED_PRIVATE_KEY_PASS,
+ /** PIN to unlock a smartcard */
+ SHARED_PIN,
+};
+
+/**
+ * enum names for shared_key_type_t
+ */
+extern enum_name_t *shared_key_type_names;
+
+/**
+ * A symmetric key shared between multiple owners.
+ *
+ * This class is not thread save, do not add owners while others might be
+ * reading.
+ */
+struct shared_key_t {
+
+ /**
+ * Get the kind of this key.
+ *
+ * @return type of the key
+ */
+ shared_key_type_t (*get_type)(shared_key_t *this);
+
+ /**
+ * Get the shared key data.
+ *
+ * @return chunk pointing to the internal key
+ */
+ chunk_t (*get_key)(shared_key_t *this);
+
+ /**
+ * Increase refcount of the key.
+ *
+ * @return this with an increased refcount
+ */
+ shared_key_t* (*get_ref)(shared_key_t *this);
+
+ /**
+ * Destroy a shared_key instance if all references are gone.
+ */
+ void (*destroy)(shared_key_t *this);
+};
+
+/**
+ * A simple private key implementation
+ *
+ * @param type type of the shared key
+ * @param key key data, gets owned by instance
+ * @return simple shared key instance
+ */
+shared_key_t *shared_key_create(shared_key_type_t type, chunk_t key);
+
+#endif /** SHARED_KEY_H_ @} */
diff --git a/src/libstrongswan/crypto/ac.c b/src/libstrongswan/crypto/ac.c
deleted file mode 100644
index 641ce5d64..000000000
--- a/src/libstrongswan/crypto/ac.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/**
- * @file ac.c
- *
- * @brief Implementation of x509ac_t.
- *
- */
-
-/*
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2007 Andreas Steffen, Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ac.c 3355 2007-11-20 12:06:40Z martin $
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include <library.h>
-#include <debug.h>
-
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <crypto/x509.h>
-#include <crypto/ietf_attr_list.h>
-#include <utils/identification.h>
-#include <utils/linked_list.h>
-#include <utils/lexparser.h>
-
-#include "ac.h"
-
-#define ACERT_WARNING_INTERVAL 1 /* day */
-
-typedef struct private_x509ac_t private_x509ac_t;
-
-/**
- * Private data of a x509ac_t object.
- */
-struct private_x509ac_t {
- /**
- * Public interface for this attribute certificate.
- */
- x509ac_t public;
-
- /**
- * Time when attribute certificate was installed
- */
- time_t installed;
-
- /**
- * X.509 attribute certificate in DER format
- */
- chunk_t certificate;
-
- /**
- * X.509 attribute certificate body over which signature is computed
- */
- chunk_t certificateInfo;
-
- /**
- * Version of the X.509 attribute certificate
- */
- u_int version;
-
- /**
- * Serial number of the X.509 attribute certificate
- */
- chunk_t serialNumber;
-
- /**
- * ID representing the issuer of the holder certificate
- */
- identification_t *holderIssuer;
-
- /**
- * Serial number of the holder certificate
- */
- chunk_t holderSerial;
-
- /**
- * ID representing the holder
- */
- identification_t *entityName;
-
- /**
- * ID representing the attribute certificate issuer
- */
- identification_t *issuerName;
-
- /**
- * Signature algorithm
- */
- int sigAlg;
-
- /**
- * Start time of certificate validity
- */
- time_t notBefore;
-
- /**
- * End time of certificate validity
- */
- time_t notAfter;
-
- /**
- * List of charging attributes
- */
- linked_list_t *charging;
-
- /**
- * List of groub attributes
- */
- linked_list_t *groups;
-
- /**
- * Authority Key Identifier
- */
- chunk_t authKeyID;
-
- /**
- * Authority Key Serial Number
- */
- chunk_t authKeySerialNumber;
-
- /**
- * No revocation information available
- */
- bool noRevAvail;
-
- /**
- * Signature algorithm (must be identical to sigAlg)
- */
- int algorithm;
-
- /**
- * Signature
- */
- chunk_t signature;
-};
-
-/**
- * ASN.1 definition of roleSyntax
- */
-static const asn1Object_t roleSyntaxObjects[] =
-{
- { 0, "roleSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "roleAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_OBJ }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
- { 1, "roleName", ASN1_CONTEXT_C_1, ASN1_OBJ } /* 3 */
-};
-
-#define ROLE_ROOF 4
-
-/**
- * ASN.1 definition of an X509 attribute certificate
- */
-static const asn1Object_t acObjects[] =
-{
- { 0, "AttributeCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "AttributeCertificateInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "version", ASN1_INTEGER, ASN1_DEF |
- ASN1_BODY }, /* 2 */
- { 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
- { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */
- { 4, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
- ASN1_BODY }, /* 7 */
- { 4, "end opt", ASN1_EOC, ASN1_END }, /* 8 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
- { 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_OBJ }, /* 10 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
- { 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */
- { 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13*/
- { 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
- ASN1_BODY }, /* 14 */
- { 4, "end opt", ASN1_EOC, ASN1_END }, /* 15*/
- { 4, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 16 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 17 */
- { 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */
- { 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_OBJ }, /* 19 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
- { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */
- { 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
- { 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */
- { 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */
- { 5, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
- ASN1_BODY }, /* 25 */
- { 5, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
- { 3, "objectDigestInfo", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 28 */
- { 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */
- { 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */
- { 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
- ASN1_BODY }, /* 31 */
- { 5, "end opt", ASN1_EOC, ASN1_END }, /* 32 */
- { 5, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 33 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 34 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */
- { 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */
- { 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
- { 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
- { 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */
- { 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 41 */
- { 4, "type", ASN1_OID, ASN1_BODY }, /* 42 */
- { 4, "values", ASN1_SET, ASN1_LOOP }, /* 43 */
- { 5, "value", ASN1_EOC, ASN1_RAW }, /* 44 */
- { 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 46 */
- { 2, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 47 */
- { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 48 */
- { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 49 */
- { 4, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 50 */
- { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 51 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 52 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 53 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 54 */
-};
-
-#define AC_OBJ_CERTIFICATE 0
-#define AC_OBJ_CERTIFICATE_INFO 1
-#define AC_OBJ_VERSION 2
-#define AC_OBJ_HOLDER_ISSUER 5
-#define AC_OBJ_HOLDER_SERIAL 6
-#define AC_OBJ_ENTITY_NAME 10
-#define AC_OBJ_ISSUER_NAME 19
-#define AC_OBJ_ISSUER 23
-#define AC_OBJ_SIG_ALG 35
-#define AC_OBJ_SERIAL_NUMBER 36
-#define AC_OBJ_NOT_BEFORE 38
-#define AC_OBJ_NOT_AFTER 39
-#define AC_OBJ_ATTRIBUTE_TYPE 42
-#define AC_OBJ_ATTRIBUTE_VALUE 44
-#define AC_OBJ_EXTN_ID 49
-#define AC_OBJ_CRITICAL 50
-#define AC_OBJ_EXTN_VALUE 51
-#define AC_OBJ_ALGORITHM 53
-#define AC_OBJ_SIGNATURE 54
-#define AC_OBJ_ROOF 55
-
-/**
- * Implements x509ac_t.is_valid
- */
-static err_t is_valid(const private_x509ac_t *this, time_t *until)
-{
- time_t current_time = time(NULL);
-
- DBG2(" not before : %T", &this->notBefore);
- DBG2(" current time: %T", &current_time);
- DBG2(" not after : %T", &this->notAfter);
-
- if (until != NULL &&
- (*until == UNDEFINED_TIME || this->notAfter < *until))
- {
- *until = this->notAfter;
- }
- if (current_time < this->notBefore)
- {
- return "is not valid yet";
- }
- if (current_time > this->notAfter)
- {
- return "has expired";
- }
- DBG2(" attribute certificate is valid");
- return NULL;
-}
-
-/**
- * Implements x509ac_t.is_newer
- */
-static bool is_newer(const private_x509ac_t *this, const private_x509ac_t *other)
-{
- return this->notBefore > other->notBefore;
-}
-
-/**
- * Implements x509ac_t.equals_holder.
- */
-static bool equals_holder(const private_x509ac_t *this, const private_x509ac_t *other)
-{
- return this->holderIssuer->equals(this->holderIssuer, other->holderIssuer)
- && chunk_equals(this->holderSerial, other->holderSerial);
-}
-
-/**
- * parses a directoryName
- */
-static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name)
-{
- bool has_directoryName;
- linked_list_t *list = linked_list_create();
-
- x509_parse_generalNames(blob, level, implicit, list);
- has_directoryName = list->get_count(list) > 0;
-
- if (has_directoryName)
- {
- iterator_t *iterator = list->create_iterator(list, TRUE);
- identification_t *directoryName;
- bool first = TRUE;
-
- while (iterator->iterate(iterator, (void**)&directoryName))
- {
- if (first)
- {
- *name = directoryName;
- first = FALSE;
- }
- else
- {
- DBG1("more than one directory name - first selected");
- directoryName->destroy(directoryName);
- }
- }
- iterator->destroy(iterator);
- }
- else
- {
- DBG1("no directoryName found");
- }
-
- list->destroy(list);
- return has_directoryName;
-}
-
-/**
- * parses roleSyntax
- */
-static void parse_roleSyntax(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
- while (objectID < ROLE_ROOF)
- {
- if (!extract_object(roleSyntaxObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
-
- switch (objectID)
- {
- default:
- break;
- }
- objectID++;
- }
-}
-
-/**
- * Parses an X.509 attribute certificate
- */
-static bool parse_certificate(chunk_t blob, private_x509ac_t *this)
-{
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int type = OID_UNKNOWN;
- int extn_oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, 0, FALSE, FALSE);
- while (objectID < AC_OBJ_ROOF)
- {
- if (!extract_object(acObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- /* those objects which will parsed further need the next higher level */
- level++;
-
- switch (objectID)
- {
- case AC_OBJ_CERTIFICATE:
- this->certificate = object;
- break;
- case AC_OBJ_CERTIFICATE_INFO:
- this->certificateInfo = object;
- break;
- case AC_OBJ_VERSION:
- this->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
- DBG2(" v%d", this->version);
- if (this->version != 2)
- {
- DBG1("v%d attribute certificates are not supported", this->version);
- return FALSE;
- }
- break;
- case AC_OBJ_HOLDER_ISSUER:
- if (!parse_directoryName(object, level, FALSE, &this->holderIssuer))
- {
- return FALSE;
- }
- break;
- case AC_OBJ_HOLDER_SERIAL:
- this->holderSerial = object;
- break;
- case AC_OBJ_ENTITY_NAME:
- if (!parse_directoryName(object, level, TRUE, &this->entityName))
- {
- return FALSE;
- }
- break;
- case AC_OBJ_ISSUER_NAME:
- if (!parse_directoryName(object, level, FALSE, &this->issuerName))
- {
- return FALSE;
- }
- break;
- case AC_OBJ_SIG_ALG:
- this->sigAlg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case AC_OBJ_SERIAL_NUMBER:
- this->serialNumber = object;
- break;
- case AC_OBJ_NOT_BEFORE:
- this->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case AC_OBJ_NOT_AFTER:
- this->notAfter = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case AC_OBJ_ATTRIBUTE_TYPE:
- type = known_oid(object);
- break;
- case AC_OBJ_ATTRIBUTE_VALUE:
- {
- switch (type)
- {
- case OID_AUTHENTICATION_INFO:
- DBG2(" need to parse authenticationInfo");
- break;
- case OID_ACCESS_IDENTITY:
- DBG2(" need to parse accessIdentity");
- break;
- case OID_CHARGING_IDENTITY:
- ietfAttr_list_create_from_chunk(object, this->charging, level);
- break;
- case OID_GROUP:
- ietfAttr_list_create_from_chunk(object, this->groups, level);
- break;
- case OID_ROLE:
- parse_roleSyntax(object, level);
- break;
- default:
- break;
- }
- }
- break;
- case AC_OBJ_EXTN_ID:
- extn_oid = known_oid(object);
- break;
- case AC_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG2(" %s",(critical)?"TRUE":"FALSE");
- break;
- case AC_OBJ_EXTN_VALUE:
- {
- switch (extn_oid)
- {
- case OID_CRL_DISTRIBUTION_POINTS:
- DBG2(" need to parse crlDistributionPoints");
- break;
- case OID_AUTHORITY_KEY_ID:
- x509_parse_authorityKeyIdentifier(object, level,
- &this->authKeyID, &this->authKeySerialNumber);
- break;
- case OID_TARGET_INFORMATION:
- DBG2(" need to parse targetInformation");
- break;
- case OID_NO_REV_AVAIL:
- this->noRevAvail = TRUE;
- break;
- default:
- break;
- }
- }
- break;
- case AC_OBJ_ALGORITHM:
- this->algorithm = parse_algorithmIdentifier(object, level, NULL);
- break;
- case AC_OBJ_SIGNATURE:
- this->signature = object;
- break;
- default:
- break;
- }
- objectID++;
- }
- this->installed = time(NULL);
- return TRUE;
-}
-
-/**
- * Implementation of x509ac_t.list.
- */
-static void list(const private_x509ac_t *this, FILE *out, bool utc)
-{
- time_t now = time(NULL);
-
- fprintf(out, "%#T\n", &this->installed, utc);
-
- if (this->entityName)
- {
- fprintf(out, " holder: '%D'\n", this->entityName);
- }
- if (this->holderIssuer)
- {
- fprintf(out, " hissuer: '%D'\n", this->holderIssuer);
- }
- if (this->holderSerial.ptr)
- {
- fprintf(out, " hserial: %#B\n", &this->holderSerial);
- }
-
- /* list all group attributes on a single line */
- fprintf(out, " groups: ");
- ietfAttr_list_list(this->groups, out);
- fprintf(out, "\n");
-
- fprintf(out, " issuer: '%D'\n", this->issuerName);
- fprintf(out, " serial: %#B\n", &this->serialNumber);
-
- fprintf(out, " validity: not before %#T, ", &this->notBefore, utc);
- if (now < this->notBefore)
- {
- fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore);
- }
- else
- {
- fprintf(out, "ok\n");
- }
-
- fprintf(out, " not after %#T, ", &this->notAfter, utc);
- if (now > this->notAfter)
- {
- fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter);
- }
- else
- {
- fprintf(out, "ok");
- if (now > this->notAfter - ACERT_WARNING_INTERVAL * 60 * 60 * 24)
- {
- fprintf(out, " (expires in %#V)", &now, &this->notAfter);
- }
- fprintf(out, " \n");
- }
-
- if (this->authKeyID.ptr)
- {
- fprintf(out, " authkey: %#B\n", &this->authKeyID);
- }
- if (this->authKeySerialNumber.ptr)
- {
- fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber);
- }
-}
-
-/**
- * Implements x509ac_t.destroy
- */
-static void destroy(private_x509ac_t *this)
-{
- DESTROY_IF(this->holderIssuer);
- DESTROY_IF(this->entityName);
- DESTROY_IF(this->issuerName);
- ietfAttr_list_destroy(this->charging);
- ietfAttr_list_destroy(this->groups);
- free(this->certificate.ptr);
- free(this);
-}
-
-/**
- * Described in header.
- */
-x509ac_t *x509ac_create_from_chunk(chunk_t chunk)
-{
- private_x509ac_t *this = malloc_thing(private_x509ac_t);
-
- /* initialize */
- this->holderIssuer = NULL;
- this->entityName = NULL;
- this->issuerName = NULL;
- this->charging = linked_list_create();
- this->groups = linked_list_create();
-
- /* public functions */
- this->public.is_valid = (err_t (*) (const x509ac_t*,time_t*))is_valid;
- this->public.is_newer = (bool (*) (const x509ac_t*,const x509ac_t*))is_newer;
- this->public.equals_holder = (bool (*) (const x509ac_t*,const x509ac_t*))equals_holder;
- this->public.list = (void (*) (const x509ac_t*,FILE*,bool))list;
- this->public.destroy = (void (*) (x509ac_t*))destroy;
-
- if (!parse_certificate(chunk, this))
- {
- destroy(this);
- return NULL;
- }
- return &this->public;
-}
-
-/**
- * Described in header.
- */
-x509ac_t *x509ac_create_from_file(const char *filename)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
-
- if (!pem_asn1_load_file(filename, NULL, "attribute certificate", &chunk, &pgp))
- {
- return NULL;
- }
- return x509ac_create_from_chunk(chunk);
-}
-
diff --git a/src/libstrongswan/crypto/ac.h b/src/libstrongswan/crypto/ac.h
deleted file mode 100644
index 8a4ccbd4c..000000000
--- a/src/libstrongswan/crypto/ac.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * @file ac.h
- *
- * @brief Interface of x509ac_t.
- *
- */
-
-/*
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2007 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ac.h 3300 2007-10-12 21:53:18Z andreas $
- */
-
-#ifndef AC_H_
-#define AC_H_
-
-#include <library.h>
-
-typedef struct x509ac_t x509ac_t;
-
-/**
- * @brief X.509 attribute certificate.
- *
- * @b Constructors:
- * - x509ac_create_from_chunk()
- * - x509ac_create_from_file()
- *
- * @ingroup crypto
- */
-struct x509ac_t {
-
- /**
- * @brief Checks the validity interval of the attribute certificate
- *
- * @param this certificate being examined
- * @param until until = min(until, notAfter)
- * @return NULL if the certificate is valid
- */
- err_t (*is_valid) (const x509ac_t *this, time_t *until);
-
- /** @brief Checks if this attr cert is newer than the other attr cert
- *
- * @param this calling object
- * @param other other attr cert object
- * @return TRUE if this was issued more recently than other
- */
- bool (*is_newer) (const x509ac_t *this, const x509ac_t *other);
-
- /**
- * @brief Checks if two attribute certificates belong to the same holder
- *
- * @param this calling attribute certificate
- * @param that other attribute certificate
- * @return TRUE if same holder
- */
- bool (*equals_holder) (const x509ac_t *this, const x509ac_t *other);
-
- /**
- * @brief Log the attribute certificate info to out.
- *
- * @param this calling object
- * @param out stream to write to
- * @param utc TRUE for UTC times, FALSE for local time
- */
- void (*list)(const x509ac_t *this, FILE *out, bool utc);
-
- /**
- * @brief Destroys the attribute certificate.
- *
- * @param this certificate to destroy
- */
- void (*destroy) (x509ac_t *this);
-};
-
-/**
- * @brief Read a x509 attribute certificate from a DER encoded blob.
- *
- * @param chunk chunk containing DER encoded data
- * @return created x509ac_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509ac_t *x509ac_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Read a x509 attribute certificate from a DER encoded file.
- *
- * @param filename file containing DER encoded data
- * @return created x509ac_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509ac_t *x509ac_create_from_file(const char *filename);
-
-#endif /* AC_H_ */
-
diff --git a/src/libstrongswan/crypto/ca.c b/src/libstrongswan/crypto/ca.c
deleted file mode 100644
index 510e3528e..000000000
--- a/src/libstrongswan/crypto/ca.c
+++ /dev/null
@@ -1,813 +0,0 @@
-/**
- * @file ca.c
- *
- * @brief Implementation of ca_info_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <pthread.h>
-
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "ac.h"
-#include "certinfo.h"
-#include "ocsp.h"
-
-#include <library.h>
-#include <debug.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-#include <utils/fetcher.h>
-
-typedef struct private_ca_info_t private_ca_info_t;
-
-/**
- * Private data of a ca_info_t object.
- */
-struct private_ca_info_t {
- /**
- * Public interface for this ca info record
- */
- ca_info_t public;
-
- /**
- * Name of the ca info record
- */
- char *name;
-
- /**
- * Time when ca info record was installed
- */
- time_t installed;
-
- /**
- * Distinguished Name of the CA
- */
- x509_t *cacert;
-
- /**
- * List of attribute certificates
- */
- linked_list_t *attrcerts;
-
- /**
- * List of crl URIs
- */
- linked_list_t *crluris;
-
- /**
- * List of ocsp URIs
- */
- linked_list_t *ocspuris;
-
- /**
- * CRL issued by this ca
- */
- crl_t *crl;
-
- /**
- * List of certificate info records
- */
- linked_list_t *certinfos;
-
- /**
- * mutex controls access to the elements:
- * name, crluris, ocspuris, crl, and certinfos
- */
- pthread_mutex_t mutex;
-};
-
-/**
- * static options set by ca_info_set_options()
- */
-static strict_t strict_crl_policy = STRICT_NO;
-static bool cache_crls = FALSE;
-static u_int crl_check_interval = 0;
-
-/**
- * Implements ca_info_t.equals
- */
-static bool equals(const private_ca_info_t *this, const private_ca_info_t *that)
-{
- return chunk_equals(this->cacert->get_keyid(this->cacert),
- that->cacert->get_keyid(that->cacert));
-}
-
-/**
- * Implements ca_info_t.equals_name_release_info
- */
-static bool equals_name_release_info(private_ca_info_t *this, const char *name)
-{
- bool found;
-
- pthread_mutex_lock(&(this->mutex));
- found = this->name != NULL && streq(this->name, name);
-
- if (found)
- {
- this->crluris->destroy_offset(this->crluris,
- offsetof(identification_t, destroy));
- this->crluris = linked_list_create();
-
- this->ocspuris->destroy_offset(this->ocspuris,
- offsetof(identification_t, destroy));
- this->ocspuris = linked_list_create();
-
- free(this->name);
- this->name = NULL;
- }
-
- pthread_mutex_unlock(&(this->mutex));
- return found;
-}
-
-/**
- * Implements ca_info_t.is_crl_issuer
- */
-static bool is_cert_issuer(private_ca_info_t *this, const x509_t *cert)
-{
- return cert->is_issuer(cert, this->cacert);
-}
-
-/**
- * Implements ca_info_t.is_crl_issuer
- */
-static bool is_crl_issuer(private_ca_info_t *this, const crl_t *crl)
-{
- return crl->is_issuer(crl, this->cacert);
-}
-
-/**
- * Implements ca_info_t.is_ca
- */
-static bool is_ca(private_ca_info_t *this)
-{
- return this->cacert->is_ca(this->cacert);
-}
-
-/**
- * Implements ca_info_t.is_strict
- */
-static bool is_strict(private_ca_info_t *this)
-{
- bool strict = strict_crl_policy != STRICT_NO;
-
- if (strict_crl_policy == STRICT_IFURI)
- {
- pthread_mutex_lock(&(this->mutex));
- strict = this->crluris->get_count(this->crluris) > 0 ||
- this->ocspuris->get_count(this->ocspuris) > 0;
- pthread_mutex_unlock(&(this->mutex));
- }
- return strict;
-}
-
-/**
- * Implements ca_info_t.has_crl
- */
-static bool has_crl(private_ca_info_t *this)
-{
- bool found;
-
- pthread_mutex_lock(&(this->mutex));
- found = this->crl != NULL;
- pthread_mutex_unlock(&(this->mutex));
-
- return found;
-}
-
-/**
- * Implements ca_info_t.has_certinfos
- */
-static bool has_certinfos(private_ca_info_t *this)
-{
- bool found;
-
- pthread_mutex_lock(&(this->mutex));
- found = this->certinfos->get_count(this->certinfos) > 0;
- pthread_mutex_unlock(&(this->mutex));
-
- return found;
-}
-
-/**
- * Implements ca_info_t.add_crl
- */
-static void add_crl(private_ca_info_t *this, crl_t *crl)
-{
- pthread_mutex_lock(&(this->mutex));
-
- if (this->crl)
- {
- if (crl->is_newer(crl, this->crl))
- {
- this->crl->destroy(this->crl);
- this->crl = crl;
- DBG1(" this crl is newer - existing crl replaced");
- }
- else
- {
- crl->destroy(crl);
- DBG1(" this crl is not newer - existing crl retained");
- }
- }
- else
- {
- this->crl = crl;
- DBG2(" crl added");
- }
-
- pthread_mutex_unlock(&(this->mutex));
-}
-
-/**
- * Implements ca_info_t.list_crl
- */
-static void list_crl(private_ca_info_t *this, FILE *out, bool utc)
-{
- pthread_mutex_lock(&this->mutex);
- this->crl->list(this->crl, out, utc);
- pthread_mutex_unlock(&this->mutex);
-}
-
-/**
- * Implements ca_info_t.list_certinfos
- */
-static void list_certinfos(private_ca_info_t *this, FILE *out, bool utc)
-{
- iterator_t *iterator;
- certinfo_t *certinfo;
- chunk_t authkey;
-
- pthread_mutex_lock(&this->mutex);
-
- authkey = this->cacert->get_subjectKeyID(this->cacert);
- fprintf(out," authname: '%D'\n", this->cacert->get_subject(this->cacert));
- fprintf(out," authkey: %#B\n", &authkey);
-
- iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
- while (iterator->iterate(iterator, (void**)&certinfo))
- {
- time_t nextUpdate, thisUpdate, now;
- chunk_t serial;
-
- now = time(NULL);
- nextUpdate = certinfo->get_nextUpdate(certinfo);
- thisUpdate = certinfo->get_thisUpdate(certinfo);
- serial = certinfo->get_serialNumber(certinfo);
-
- fprintf(out, "%#T, until %#T, ", &thisUpdate, utc, &nextUpdate, utc);
- if (now > nextUpdate)
- {
- fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate);
- }
- else
- {
- fprintf(out, "ok (expires in %#V)\n", &now, &nextUpdate);
- }
- fprintf(out, " serial: %#B, %N\n", &serial,
- cert_status_names, certinfo->get_status(certinfo));
- }
- iterator->destroy(iterator);
-
- pthread_mutex_unlock(&this->mutex);
-}
-
-/**
- * Find an exact copy of an identification in a linked list
- */
-static identification_t* find_identification(linked_list_t *list, identification_t *id)
-{
- identification_t *found_id = NULL, *current_id;
-
- iterator_t *iterator = list->create_iterator(list, TRUE);
-
- while (iterator->iterate(iterator, (void**)&current_id))
- {
- if (id->equals(id, current_id))
- {
- found_id = current_id;
- break;
- }
- }
- iterator->destroy(iterator);
-
- return found_id;
-}
-
-/**
- * Add a unique identification to a linked list
- */
-static identification_t *add_identification(linked_list_t *list, identification_t *id)
-{
- identification_t *found_id = find_identification(list, id);
-
- if (found_id)
- {
- id->destroy(id);
- return found_id;
- }
- else
- {
- list->insert_last(list, (void*)id);
- return id;
- }
-}
-
-/**
- * Implements ca_info_t.add_crluri
- */
-static void add_crluri(private_ca_info_t *this, chunk_t uri)
-{
- if (uri.len < 6 ||
- (strncasecmp(uri.ptr, "http", 4) != 0 &&
- strncasecmp(uri.ptr, "ldap", 4) != 0 &&
- strncasecmp(uri.ptr, "file", 4) != 0 &&
- strncasecmp(uri.ptr, "ftp", 3) != 0))
- {
- DBG1(" invalid crl uri '%.*s'", uri.len, uri.ptr);
- return;
- }
- else
- {
- identification_t *crluri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
-
- pthread_mutex_lock(&(this->mutex));
- add_identification(this->crluris, crluri);
- pthread_mutex_unlock(&(this->mutex));
- }
-}
-
-/**
- * Implements ca_info_t.add_ocspuri
- */
-static void add_ocspuri(private_ca_info_t *this, chunk_t uri)
-{
- if (uri.len < 7 || strncasecmp(uri.ptr, "http", 4) != 0)
- {
- DBG1(" invalid ocsp uri '%.*s'", uri.len, uri.ptr);
- return;
- }
- else
- {
- identification_t *ocspuri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
-
- pthread_mutex_lock(&(this->mutex));
- add_identification(this->ocspuris, ocspuri);
- pthread_mutex_unlock(&(this->mutex));
- }
-}
-
-/**
- * Implements ca_info_t.add_info.
- */
-void add_info (private_ca_info_t *this, const private_ca_info_t *that)
-{
- pthread_mutex_lock(&(this->mutex));
-
- if (this->name == NULL && that->name != NULL)
- {
- this->name = strdup(that->name);
- }
-
- pthread_mutex_unlock(&(this->mutex));
-
- {
- identification_t *uri;
-
- iterator_t *iterator = that->crluris->create_iterator(that->crluris, TRUE);
-
- while (iterator->iterate(iterator, (void**)&uri))
- {
- if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
- {
- add_crluri(this, uri->get_encoding(uri));
- }
- }
- iterator->destroy(iterator);
- }
-
- {
- identification_t *uri;
-
- iterator_t *iterator = that->ocspuris->create_iterator(that->ocspuris, TRUE);
-
- while (iterator->iterate(iterator, (void**)&uri))
- {
- if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
- {
- add_ocspuri(this, uri->get_encoding(uri));
- }
- }
- iterator->destroy(iterator);
- }
-}
-
-/**
- * Implements ca_info_t.get_certificate.
- */
-static x509_t* get_certificate(private_ca_info_t* this)
-{
- return this->cacert;
-}
-
-/**
- * caches a crl by saving it to a given crl directory
- */
-void cache_crl(private_ca_info_t* this, const char *crl_dir, crl_t *crl)
-{
- char buffer[BUF_LEN];
- char *path;
- char *pos = buffer;
- int len = BUF_LEN;
- int n;
-
- chunk_t authKeyID = this->cacert->get_subjectKeyID(this->cacert);
- chunk_t uri;
-
- uri.ptr = buffer;
- uri.len = 7 + strlen(crl_dir) + 1 + 2*authKeyID.len + 4;
-
- if (uri.len >= BUF_LEN)
- {
- DBG1("file uri exceeds buffer length of %d bytes - crl not saved", BUF_LEN);
- return;
- }
-
- /* print the file uri prefix */
- n = snprintf(pos, len, "file://");
- pos += n; len -= n;
-
- /* remember the start of the path string */
- path = pos;
-
- /* print the default crl directory path */
- n = snprintf(pos, len, "%s/", crl_dir);
- pos += n; len -= n;
-
- /* create and print a unique crl filename derived from the authKeyID */
- while (authKeyID.len-- > 0)
- {
- n = snprintf(pos, len, "%02x", *authKeyID.ptr++);
- pos += n; len -= n;
- }
-
- /* add the file suffix */
- n = snprintf(pos, len, ".crl");
-
- if (crl->write_to_file(crl, path, 0022, TRUE))
- {
- identification_t *crluri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
-
- add_identification(this->crluris, crluri);
- }
-}
-
-/**
- * Implements ca_info_t.verify_by_crl.
- */
-static cert_status_t verify_by_crl(private_ca_info_t* this, certinfo_t *certinfo,
- const char *crl_dir)
-{
- rsa_public_key_t *issuer_public_key = this->cacert->get_public_key(this->cacert);
- bool stale;
-
- pthread_mutex_lock(&(this->mutex));
- if (this->crl == NULL)
- {
- stale = TRUE;
- DBG1("no crl is locally available");
- }
- else
- {
- stale = !this->crl->is_valid(this->crl);
- DBG1("crl is %s", stale? "stale":"valid");
- }
-
- if (stale && crl_check_interval > 0)
- {
- iterator_t *iterator = this->crluris->create_iterator(this->crluris, TRUE);
- identification_t *uri;
-
- while (iterator->iterate(iterator, (void**)&uri))
- {
- fetcher_t *fetcher;
- char uri_string[BUF_LEN];
- chunk_t uri_chunk = uri->get_encoding(uri);
- chunk_t response_chunk;
-
- snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr);
- fetcher = fetcher_create(uri_string);
-
- response_chunk = fetcher->get(fetcher);
- fetcher->destroy(fetcher);
- if (response_chunk.ptr != NULL)
- {
- crl_t *crl = crl_create_from_chunk(response_chunk);
-
- if (crl == NULL)
- {
- free(response_chunk.ptr);
- continue;
- }
- if (!is_crl_issuer(this, crl))
- {
- DBG1(" fetched crl has wrong issuer");
- crl->destroy(crl);
- continue;
- }
- if (!crl->verify(crl, issuer_public_key))
- {
- DBG1("fetched crl signature is invalid");
- crl->destroy(crl);
- continue;
- }
- DBG2("fetched crl signature is valid");
-
- if (this->crl == NULL)
- {
- this->crl = crl;
- }
- else if (crl->is_newer(crl, this->crl))
- {
- this->crl->destroy(this->crl);
- this->crl = crl;
- DBG1("this crl is newer - existing crl replaced");
- }
- else
- {
- crl->destroy(crl);
- DBG1("this crl is not newer - existing crl retained");
- continue;
- }
- if (crl->is_valid(crl))
- {
- if (cache_crls && strncasecmp(uri_string, "file", 4) != 0)
- {
- cache_crl(this, crl_dir, crl);
- }
- /* we found a valid crl and therefore exit the fetch loop */
- break;
- }
- else
- {
- DBG1("fetched crl is stale");
- }
- }
- }
- iterator->destroy(iterator);
- }
-
- if (this->crl)
- {
- if (!this->crl->verify(this->crl, issuer_public_key))
- {
- DBG1("crl signature is invalid");
- goto ret;
- }
- DBG2("crl signature is valid");
-
- this->crl->get_status(this->crl, certinfo);
- }
-
-ret:
- pthread_mutex_unlock(&(this->mutex));
- return certinfo->get_status(certinfo);
-}
-
-/**
- * Implements ca_info_t.verify_by_ocsp.
- */
-static cert_status_t verify_by_ocsp(private_ca_info_t* this,
- certinfo_t *certinfo,
- credential_store_t *credentials)
-{
- bool stale;
- iterator_t *iterator;
- certinfo_t *cached_certinfo = NULL;
- int comparison = 1;
-
- pthread_mutex_lock(&(this->mutex));
-
- /* do we support OCSP at all? */
- if (this->ocspuris->get_count(this->ocspuris) == 0)
- {
- goto ret;
- }
-
- iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
-
- /* find the list insertion point in alphabetical order */
- while(iterator->iterate(iterator, (void**)&cached_certinfo))
- {
- comparison = certinfo->compare_serialNumber(certinfo, cached_certinfo);
-
- if (comparison <= 0)
- {
- break;
- }
- }
-
- /* do we have a valid certinfo_t for this serial number in our cache? */
- if (comparison == 0)
- {
- stale = cached_certinfo->get_nextUpdate(cached_certinfo) < time(NULL);
- DBG1("ocsp status in cache is %s", stale ? "stale":"fresh");
- }
- else
- {
- stale = TRUE;
- DBG1("ocsp status is not in cache");
- }
-
- if (stale)
- {
- ocsp_t *ocsp;
-
- ocsp = ocsp_create(this->cacert, this->ocspuris);
- ocsp->fetch(ocsp, certinfo, credentials);
- if (certinfo->get_status(certinfo) != CERT_UNDEFINED)
- {
- if (comparison != 0)
- {
- cached_certinfo = certinfo_create(certinfo->get_serialNumber(certinfo));
-
- if (comparison > 0)
- {
- this->certinfos->insert_last(this->certinfos, (void *)cached_certinfo);
- }
- else
- {
- iterator->insert_before(iterator, (void *)cached_certinfo);
- }
- }
- cached_certinfo->update(cached_certinfo, certinfo);
- }
- ocsp->destroy(ocsp);
- }
- else
- {
- certinfo->update(certinfo, cached_certinfo);
- }
-
- iterator->destroy(iterator);
-
-ret:
- pthread_mutex_unlock(&(this->mutex));
- return certinfo->get_status(certinfo);
-}
-
-/**
- * Implements ca_info_t.purge_ocsp
- */
-static void purge_ocsp(private_ca_info_t *this)
-{
- pthread_mutex_lock(&(this->mutex));
-
- this->certinfos->destroy_offset(this->certinfos,
- offsetof(certinfo_t, destroy));
- this->certinfos = linked_list_create();
-
- pthread_mutex_unlock(&(this->mutex));
-}
-
-/**
- * Implements ca_info_t.destroy
- */
-static void destroy(private_ca_info_t *this)
-{
- this->attrcerts->destroy_offset(this->attrcerts,
- offsetof(x509ac_t, destroy));
- this->crluris->destroy_offset(this->crluris,
- offsetof(identification_t, destroy));
- this->ocspuris->destroy_offset(this->ocspuris,
- offsetof(identification_t, destroy));
- this->certinfos->destroy_offset(this->certinfos,
- offsetof(certinfo_t, destroy));
- DESTROY_IF(this->crl);
- free(this->name);
- free(this);
-}
-
-/**
- * list the info of this CA
- */
-static void list(private_ca_info_t* this, FILE* out, bool utc)
-{
- chunk_t chunk;
- identification_t *uri;
- iterator_t *iterator;
- bool first;
-
- pthread_mutex_lock(&(this->mutex));
- fprintf(out, "%#T", &this->installed, utc);
-
- if (this->name)
- {
- fprintf(out, ", \"%s\"\n", this->name);
- }
- else
- {
- fprintf(out, "\n");
- }
-
- fprintf(out, " authname: '%D'\n", this->cacert->get_subject(this->cacert));
- chunk = this->cacert->get_subjectKeyID(this->cacert);
- fprintf(out, " authkey: %#B\n", &chunk);
- chunk = this->cacert->get_keyid(this->cacert);
- fprintf(out, " keyid: %#B\n", &chunk);
-
- first = TRUE;
- iterator = this->crluris->create_iterator(this->crluris, TRUE);
- while (iterator->iterate(iterator, (void**)&uri))
- {
- fprintf(out, " %s '%D'\n", first ? "crluris:":" ", uri);
- first = FALSE;
- }
- iterator->destroy(iterator);
-
- first = TRUE;
- iterator = this->ocspuris->create_iterator(this->ocspuris, TRUE);
- while (iterator->iterate(iterator, (void**)&uri))
- {
- fprintf(out, " %s '%D'\n", first ? "ocspuris:":" ", uri);
- first = FALSE;
- }
- iterator->destroy(iterator);
- pthread_mutex_unlock(&(this->mutex));
-}
-
-/*
- * Described in header.
- */
-void ca_info_set_options(strict_t strict, bool cache, u_int interval)
-{
- strict_crl_policy = strict;
- cache_crls = cache;
- crl_check_interval = interval;
-}
-
-/*
- * Described in header.
- */
-ca_info_t *ca_info_create(const char *name, x509_t *cacert)
-{
- private_ca_info_t *this = malloc_thing(private_ca_info_t);
-
- /* initialize */
- this->installed = time(NULL);
- this->name = (name == NULL)? NULL:strdup(name);
- this->cacert = cacert;
- this->attrcerts = linked_list_create();
- this->crluris = linked_list_create();
- this->ocspuris = linked_list_create();
- this->certinfos = linked_list_create();
- this->crl = NULL;
-
- /* initialize the mutex */
- pthread_mutex_init(&(this->mutex), NULL);
-
- /* public functions */
- this->public.equals = (bool (*) (const ca_info_t*,const ca_info_t*))equals;
- this->public.equals_name_release_info = (bool (*) (ca_info_t*,const char*))equals_name_release_info;
- this->public.is_cert_issuer = (bool (*) (ca_info_t*,const x509_t*))is_cert_issuer;
- this->public.is_crl_issuer = (bool (*) (ca_info_t*,const crl_t*))is_crl_issuer;
- this->public.is_ca = (bool (*) (ca_info_t*))is_ca;
- this->public.is_strict = (bool (*) (ca_info_t*))is_strict;
- this->public.add_info = (void (*) (ca_info_t*,const ca_info_t*))add_info;
- this->public.add_crl = (void (*) (ca_info_t*,crl_t*))add_crl;
- this->public.has_crl = (bool (*) (ca_info_t*))has_crl;
- this->public.has_certinfos = (bool (*) (ca_info_t*))has_certinfos;
- this->public.list = (void (*) (ca_info_t*,FILE*,bool))list;
- this->public.list_crl = (void (*) (ca_info_t*,FILE*,bool))list_crl;
- this->public.list_certinfos = (void (*) (ca_info_t*,FILE*,bool))list_certinfos;
- this->public.add_crluri = (void (*) (ca_info_t*,chunk_t))add_crluri;
- this->public.add_ocspuri = (void (*) (ca_info_t*,chunk_t))add_ocspuri;
- this->public.get_certificate = (x509_t* (*) (ca_info_t*))get_certificate;
- this->public.verify_by_crl = (cert_status_t (*) (ca_info_t*,certinfo_t*, const char*))verify_by_crl;
- this->public.verify_by_ocsp = (cert_status_t (*) (ca_info_t*,certinfo_t*,credential_store_t*))verify_by_ocsp;
- this->public.purge_ocsp = (void (*) (ca_info_t*))purge_ocsp;
- this->public.destroy = (void (*) (ca_info_t*))destroy;
-
- return &this->public;
-}
diff --git a/src/libstrongswan/crypto/ca.h b/src/libstrongswan/crypto/ca.h
deleted file mode 100644
index ff6271b15..000000000
--- a/src/libstrongswan/crypto/ca.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/**
- * @file ca.h
- *
- * @brief Interface of ca_info_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifndef CA_H_
-#define CA_H_
-
-typedef struct ca_info_t ca_info_t;
-
-#include <library.h>
-
-#include "x509.h"
-#include "crl.h"
-
-#define MAX_CA_PATH_LEN 7
-
-/*forward declaration */
-struct credential_store_t;
-
-/**
- * @brief X.509 certification authority information record
- *
- * @b Constructors:
- * - ca_info_create()
- *
- * @ingroup transforms
- */
-struct ca_info_t {
-
- /**
- * @brief Compare two ca info records
- *
- * Comparison is done via the keyid of the ca certificate
- *
- * @param this first ca info object
- * @param that second ca info objct
- * @return TRUE if a match is found
- */
- bool (*equals) (const ca_info_t *this, const ca_info_t* that);
-
- /**
- * @brief If the ca info record has the same name then release the name and URIs
- *
- * @param this ca info object
- * @return TRUE if a match is found
- */
- bool (*equals_name_release_info) (ca_info_t *this, const char *name);
-
- /**
- * @brief Checks if a certificate was issued by this ca
- *
- * @param this ca info object
- * @param cert certificate to be checked
- * @return TRUE if the issuing ca has been found
- */
- bool (*is_cert_issuer) (ca_info_t *this, const x509_t *cert);
-
- /**
- * @brief Checks if a crl was issued by this ca
- *
- * @param this ca info object
- * @param crl crl to be checked
- * @return TRUE if the issuing ca has been found
- */
- bool (*is_crl_issuer) (ca_info_t *this, const crl_t *crl);
-
- /**
- * @brief Checks if the ca certificate has the isCA flag set
- *
- * @param this ca info object
- * @return TRUE if the isCA flag is set
- */
- bool (*is_ca) (ca_info_t *this);
-
- /**
- * @brief Checks if the ca enforces a strict crl policy
- *
- * @param this ca info object
- * @return TRUE if the crl policy is strict
- */
- bool (*is_strict) (ca_info_t *this);
-
- /**
- * @brief Merges info from a secondary ca info object
- *
- * @param this primary ca info object
- * @param that secondary ca info object
- */
- void (*add_info) (ca_info_t *this, const ca_info_t *that);
-
- /**
- * @brief Adds a new or replaces an obsoleted CRL
- *
- * @param this ca info object
- * @param crl crl to be added
- */
- void (*add_crl) (ca_info_t *this, crl_t *crl);
-
- /**
- * @brief Does the CA have a CRL?
- *
- * @param this ca info object
- * @return TRUE if crl is available
- */
- bool (*has_crl) (ca_info_t *this);
-
- /**
- * @brief Does the CA have OCSP certinfos?
- *
- * @param this ca info object
- * @return TRUE if there are any certinfos
- */
- bool (*has_certinfos) (ca_info_t *this);
-
- /**
- * @brief Print the CA info onto the console
- *
- * @param this ca info object
- * @param out output stream
- * @param utc TRUE - utc
- FALSE - local time
- */
- void (*list) (ca_info_t *this, FILE *out, bool utc);
-
- /**
- * @brief List the CRL onto the console
- *
- * @param this ca info object
- * @param out output stream
- * @param utc TRUE - utc
- FALSE - local time
- */
- void (*list_crl) (ca_info_t *this, FILE *out, bool utc);
-
- /**
- * @brief List the OCSP certinfos onto the console
- *
- * @param this ca info object
- * @param out output stream
- * @param utc TRUE - utc
- FALSE - local time
- */
- void (*list_certinfos) (ca_info_t *this, FILE *out, bool utc);
-
- /**
- * @brief Adds a CRL URI to a list
- *
- * @param this ca info object
- * @param uri crl uri to be added
- */
- void (*add_crluri) (ca_info_t *this, chunk_t uri);
-
- /**
- * @brief Adds a OCSP URI to a list
- *
- * @param this ca info object
- * @param uri ocsp uri to be added
- */
- void (*add_ocspuri) (ca_info_t *this, chunk_t uri);
-
- /**
- * @brief Get the ca certificate
- *
- * @param this ca info object
- * @return ca certificate
- */
- x509_t* (*get_certificate) (ca_info_t *this);
-
- /**
- * @brief Verify the status of a certificate by CRL
- *
- * @param this ca info object
- * @param certinfo detailed certificate status information
- * @param crl_dir directory where fetched crls should be stored
- * @return certificate status
- */
- cert_status_t (*verify_by_crl) (ca_info_t *this, certinfo_t *certinfo, const char *crl_dir);
-
- /**
- * @brief Verify the status of a certificate by OCSP
- *
- * @param this ca info object
- * @param certinfo detailed certificate status information
- * @param credentials credential store needed for trust path verification
- * @return certificate status
- */
- cert_status_t (*verify_by_ocsp) (ca_info_t* this, certinfo_t* certinfo, struct credential_store_t* credentials);
-
- /**
- * @brief Purge the OCSP certinfos of a ca info record
- *
- * @param this ca info object
- */
- void (*purge_ocsp) (ca_info_t *this);
-
- /**
- * @brief Destroys a ca info record
- *
- * @param this ca info to destroy
- */
- void (*destroy) (ca_info_t *this);
-};
-
-/**
- * @brief Set ca info options
- *
- * @param cache TRUE if crls shall be cached by storing them
- * @param interval crl_check_interval to be set in seconds
- *
- * @ingroup crypto
- */
-void ca_info_set_options(strict_t strict, bool cache, u_int interval);
-
-/**
- * @brief Create a ca info record
- *
- * @param name name of the ca info record
- * @param cacert path to the ca certificate
- * @return created ca_info_t, or NULL if invalid.
- *
- * @ingroup crypto
- */
-ca_info_t *ca_info_create(const char *name, x509_t *cacert);
-
-#endif /* CA_H_ */
diff --git a/src/libstrongswan/crypto/certinfo.c b/src/libstrongswan/crypto/certinfo.c
deleted file mode 100644
index 8a125e247..000000000
--- a/src/libstrongswan/crypto/certinfo.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/**
- * @file certinfo.c
- *
- * @brief Implementation of certinfo_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <time.h>
-#include <stdio.h>
-
-#include <library.h>
-
-#include "certinfo.h"
-
-typedef struct private_certinfo_t private_certinfo_t;
-
-/**
- * Private data of a certinfo_t object.
- */
-struct private_certinfo_t {
- /**
- * Public interface for this certificate status information object.
- */
- certinfo_t public;
-
- /**
- * Serial number of the certificate
- */
- chunk_t serialNumber;
-
- /**
- * Certificate status
- */
- cert_status_t status;
-
- /**
- * Certificate status is for one-time use only
- */
- bool once;
-
- /**
- * Time when the certificate status info was generated
- */
- time_t thisUpdate;
-
- /**
- * Time when an updated certifcate status info will be available
- */
- time_t nextUpdate;
-
- /**
- * Time of certificate revocation
- */
- time_t revocationTime;
-
- /**
- * Reason of certificate revocation
- */
- crl_reason_t revocationReason;
-};
-
-ENUM(cert_status_names, CERT_GOOD, CERT_UNTRUSTED,
- "good",
- "revoked",
- "unknown",
- "unknown",
- "untrusted",
-);
-
-ENUM(crl_reason_names, REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL,
- "unspecified",
- "key compromise",
- "ca compromise",
- "affiliation changed",
- "superseded",
- "cessation of operation",
- "certificate hold",
- "reason #7",
- "remove from crl",
-);
-
-/**
- * Implements certinfo_t.compare_serialNumber
- */
-static int compare_serialNumber(const private_certinfo_t *this, const private_certinfo_t *that)
-{
- return chunk_compare(this->serialNumber, that->serialNumber);
-}
-
-/**
- * Implements certinfo_t.equals_serialNumber
- */
-static bool equals_serialNumber(const private_certinfo_t *this, const private_certinfo_t *that)
-{
- return chunk_equals(this->serialNumber, that->serialNumber);
-}
-
-/**
- * Implements certinfo_t.get_serialNumber
- */
-static chunk_t get_serialNumber(const private_certinfo_t *this)
-{
- return this->serialNumber;
-}
-
-/**
- * Implements certinfo_t.set_status
- */
-static void set_status(private_certinfo_t *this, cert_status_t status)
-{
- this->status = status;
-}
-
-/**
- * Implements certinfo_t.get_status
- */
-static cert_status_t get_status(const private_certinfo_t *this)
-{
- return this->status;
-}
-
-/**
- * Implements certinfo_t.set_thisUpdate
- */
-static void set_thisUpdate(private_certinfo_t *this, time_t thisUpdate)
-{
- this->thisUpdate = thisUpdate;
-}
-
-/**
- * Implements certinfo_t.get_thisUpdate
- */
-static time_t get_thisUpdate(const private_certinfo_t *this)
-{
- return this->thisUpdate;
-}
-
-/**
- * Implements certinfo_t.set_nextUpdate
- */
-static void set_nextUpdate(private_certinfo_t *this, time_t nextUpdate)
-{
- this->nextUpdate = nextUpdate;
-}
-
-/**
- * Implements certinfo_t.get_nextUpdate
- */
-static time_t get_nextUpdate(const private_certinfo_t *this)
-{
- return this->nextUpdate;
-}
-
-/**
- * Implements certinfo_t.set_revocationTime
- */
-static void set_revocationTime(private_certinfo_t *this, time_t revocationTime)
-{
- this->revocationTime = revocationTime;
-}
-
-/**
- * Implements certinfo_t.get_revocationTime
- */
-static time_t get_revocationTime(const private_certinfo_t *this)
-{
- return this->revocationTime;
-}
-
-/**
- * Implements certinfo_t.set_revocationReason
- */
-static void set_revocationReason(private_certinfo_t *this, crl_reason_t reason)
-{
- this->revocationReason = reason;
-}
-
-/**
- * Implements certinfo_t.get_revocationReason
- */
-static crl_reason_t get_revocationReason(const private_certinfo_t *this)
-{
- return this->revocationReason;
-}
-
-/**
- * Implements certinfo_t.update
- */
-static void update(private_certinfo_t *this, const private_certinfo_t *that)
-{
- if (equals_serialNumber(this, that))
- {
- chunk_t this_serialNumber = this->serialNumber;
-
- *this = *that;
- this->serialNumber = this_serialNumber;
- }
-}
-
-/**
- * Implements certinfo_t.destroy
- */
-static void destroy(private_certinfo_t *this)
-{
- free(this->serialNumber.ptr);
- free(this);
-}
-
-/*
- * Described in header.
- */
-certinfo_t *certinfo_create(chunk_t serial)
-{
- private_certinfo_t *this = malloc_thing(private_certinfo_t);
-
- /* initialize */
- this->serialNumber = chunk_clone(serial);
- this->status = CERT_UNDEFINED;
- this->thisUpdate = UNDEFINED_TIME;
- this->nextUpdate = UNDEFINED_TIME;
- this->revocationTime = UNDEFINED_TIME;
- this->revocationReason = REASON_UNSPECIFIED;
-
- /* public functions */
- this->public.compare_serialNumber = (int (*) (const certinfo_t*,const certinfo_t*))compare_serialNumber;
- this->public.equals_serialNumber = (bool (*) (const certinfo_t*,const certinfo_t*))equals_serialNumber;
- this->public.get_serialNumber = (chunk_t (*) (const certinfo_t*))get_serialNumber;
- this->public.set_status = (void (*) (certinfo_t*,cert_status_t))set_status;
- this->public.get_status = (cert_status_t (*) (const certinfo_t*))get_status;
- this->public.set_thisUpdate = (void (*) (certinfo_t*,time_t))set_thisUpdate;
- this->public.get_thisUpdate = (time_t (*) (const certinfo_t*))get_thisUpdate;
- this->public.set_nextUpdate = (void (*) (certinfo_t*,time_t))set_nextUpdate;
- this->public.get_nextUpdate = (time_t (*) (const certinfo_t*))get_nextUpdate;
- this->public.set_revocationTime = (void (*) (certinfo_t*,time_t))set_revocationTime;
- this->public.get_revocationTime = (time_t (*) (const certinfo_t*))get_revocationTime;
- this->public.set_revocationReason = (void (*) (certinfo_t*, crl_reason_t))set_revocationReason;
- this->public.get_revocationReason = (crl_reason_t(*) (const certinfo_t*))get_revocationReason;
- this->public.update = (void (*) (certinfo_t*, const certinfo_t*))update;
- this->public.destroy = (void (*) (certinfo_t*))destroy;
-
- return &this->public;
-}
diff --git a/src/libstrongswan/crypto/certinfo.h b/src/libstrongswan/crypto/certinfo.h
deleted file mode 100644
index 476befda8..000000000
--- a/src/libstrongswan/crypto/certinfo.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/**
- * @file certinfo.h
- *
- * @brief Interface of certinfo_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifndef CERTINFO_H_
-#define CERTINFO_H_
-
-typedef enum cert_status_t cert_status_t;
-typedef enum crl_reason_t crl_reason_t;
-typedef struct certinfo_t certinfo_t;
-
-#include <library.h>
-
-/**
- * RFC 2560 OCSP - certificate status
- */
-enum cert_status_t {
- CERT_GOOD = 0,
- CERT_REVOKED = 1,
- CERT_UNKNOWN = 2,
- CERT_UNDEFINED = 3,
- CERT_UNTRUSTED = 4 /* private use */
-};
-
-extern enum_name_t *cert_status_names;
-
-/**
- * RFC 2459 CRL reason codes
- */
-enum crl_reason_t {
- REASON_UNSPECIFIED = 0,
- REASON_KEY_COMPROMISE = 1,
- REASON_CA_COMPROMISE = 2,
- REASON_AFFILIATION_CHANGED = 3,
- REASON_SUPERSEDED = 4,
- REASON_CESSATION_OF_OPERATON = 5,
- REASON_CERTIFICATE_HOLD = 6,
- REASON_REMOVE_FROM_CRL = 8
-};
-
-extern enum_name_t *crl_reason_names;
-
-/**
- * @brief X.509 certificate status information
- *
- * @ingroup transforms
- */
-struct certinfo_t {
-
- /**
- * @brief Check if both certinfo objects have the same serialNumber.
- *
- * @param this calling object
- * @param that second certinfo_t object
- * @return TRUE if the same serialNumber
- */
- bool (*equals_serialNumber) (const certinfo_t *this, const certinfo_t *that);
-
- /**
- * @brief Compares two serial numbers.
- *
- * @param this calling object
- * @param that second certinfo_t object
- * @return negative if this is smaller than that
- * zero if this equals that
- * positive if this is greater than that
- */
- int (*compare_serialNumber) (const certinfo_t *this, const certinfo_t *that);
-
- /**
- * @brief Get serial number.
- *
- * @param this calling object
- * @return serialNumber
- */
- chunk_t (*get_serialNumber) (const certinfo_t *this);
-
- /**
- * @brief Set certificate status.
- *
- * @param this calling object
- * @param status status
- */
- void (*set_status) (certinfo_t *this, cert_status_t status);
-
- /**
- * @brief Get certificate status.
- *
- * @param this calling object
- * @return status
- */
- cert_status_t (*get_status) (const certinfo_t *this);
-
- /**
- * @brief Set thisUpdate.
- *
- * @param this calling object
- * @param thisUpdate thisUpdate
- */
- void (*set_thisUpdate) (certinfo_t *this, time_t thisUpdate);
-
- /**
- * @brief Get thisUpdate.
- *
- * @param this calling object
- * @return thisUpdate
- */
- time_t (*get_thisUpdate) (const certinfo_t *this);
-
- /**
- * @brief Set nextUpdate.
- *
- * @param this calling object
- * @param nextUpdate
- */
- void (*set_nextUpdate) (certinfo_t *this, time_t nextUpdate);
-
- /**
- * @brief Get nextUpdate.
- *
- * @param this calling object
- * @return nextUpdate
- */
- time_t (*get_nextUpdate) (const certinfo_t *this);
-
- /**
- * @brief Set revocationTime.
- *
- * @param this calling object
- * @param revocationTime revocationTime
- */
- void (*set_revocationTime) (certinfo_t *this, time_t revocationTime);
-
- /**
- * @brief Get revocationTime.
- *
- * @param this calling object
- * @return revocationTime
- */
- time_t (*get_revocationTime) (const certinfo_t *this);
-
- /**
- * @brief Set revocationReason.
- *
- * @param this calling object
- * @param reason revocationReason
- */
- void (*set_revocationReason) (certinfo_t *this, crl_reason_t reason);
-
- /**
- * @brief Get revocationReason.
- *
- * @param this calling object
- * @return revocationReason
- */
- crl_reason_t (*get_revocationReason) (const certinfo_t *this);
-
- /**
- * @brief Set revocationReason.
- *
- * @param this calling object to be updated
- * @param that object containing updated information
- */
- void (*update) (certinfo_t *this, const certinfo_t *that);
-
- /**
- * @brief Destroys the certinfo_t object.
- *
- * @param this certinfo_t to destroy
- */
- void (*destroy) (certinfo_t *this);
-
-};
-
-/**
- * @brief Create a certinfo_t object.
- *
- * @param serial chunk serial number of the certificate
- * @return created certinfo_t object
- *
- * @ingroup transforms
- */
-certinfo_t *certinfo_create(chunk_t serial);
-
-#endif /* CERTINFO_H_ */
diff --git a/src/libstrongswan/crypto/crl.c b/src/libstrongswan/crypto/crl.c
deleted file mode 100755
index ab23bb9ec..000000000
--- a/src/libstrongswan/crypto/crl.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/**
- * @file crl.c
- *
- * @brief Implementation of crl_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: crl.c 3355 2007-11-20 12:06:40Z martin $
- */
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <library.h>
-#include <debug.h>
-#include <asn1/oid.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-#include "certinfo.h"
-#include "x509.h"
-#include "crl.h"
-
-#define CRL_WARNING_INTERVAL 7 /* days */
-
-/* access structure for a revoked certificate */
-
-typedef struct revokedCert_t revokedCert_t;
-
-struct revokedCert_t {
- chunk_t userCertificate;
- time_t revocationDate;
- crl_reason_t revocationReason;
-};
-
-typedef struct private_crl_t private_crl_t;
-
-/**
- * Private data of a crl_t object.
- */
-struct private_crl_t {
- /**
- * Public interface for this crl.
- */
- crl_t public;
-
- /**
- * Time when crl was installed
- */
- time_t installed;
-
- /**
- * List of crlDistributionPoints
- */
- linked_list_t *crlDistributionPoints;
-
- /**
- * X.509 crl in DER format
- */
- chunk_t certificateList;
-
- /**
- * X.509 crl body over which signature is computed
- */
- chunk_t tbsCertList;
-
- /**
- * Version of the X.509 crl
- */
- u_int version;
-
- /**
- * Signature algorithm
- */
- int sigAlg;
-
- /**
- * ID representing the crl issuer
- */
- identification_t *issuer;
-
- /**
- * CRL number
- */
- chunk_t crlNumber;
-
- /**
- * Time when the crl was generated
- */
- time_t thisUpdate;
-
- /**
- * Time when an update crl will be available
- */
- time_t nextUpdate;
-
- /**
- * List of identification_t's representing subjectAltNames
- */
- linked_list_t *revokedCertificates;
-
- /**
- * Authority Key Identifier
- */
- chunk_t authKeyID;
-
- /**
- * Authority Key Serial Number
- */
- chunk_t authKeySerialNumber;
-
- /**
- * Signature algorithm (must be identical to sigAlg)
- */
- int algorithm;
-
- /**
- * Signature
- */
- chunk_t signature;
-};
-
-/**
- * ASN.1 definition of an X.509 certificate revocation list
- */
-static const asn1Object_t crlObjects[] = {
- { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "version", ASN1_INTEGER, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */
- { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */
- { 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */
- { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 8 */
- { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */
- { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */
- { 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */
- { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 12 */
- { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
- { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */
- { 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 15 */
- { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
- { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */
- { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */
- { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 23 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
- { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 28 */
- };
-
-#define CRL_OBJ_CERTIFICATE_LIST 0
-#define CRL_OBJ_TBS_CERT_LIST 1
-#define CRL_OBJ_VERSION 2
-#define CRL_OBJ_SIG_ALG 4
-#define CRL_OBJ_ISSUER 5
-#define CRL_OBJ_THIS_UPDATE 6
-#define CRL_OBJ_NEXT_UPDATE 7
-#define CRL_OBJ_USER_CERTIFICATE 10
-#define CRL_OBJ_REVOCATION_DATE 11
-#define CRL_OBJ_CRL_ENTRY_EXTN_ID 14
-#define CRL_OBJ_CRL_ENTRY_CRITICAL 15
-#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16
-#define CRL_OBJ_EXTN_ID 22
-#define CRL_OBJ_CRITICAL 23
-#define CRL_OBJ_EXTN_VALUE 24
-#define CRL_OBJ_ALGORITHM 27
-#define CRL_OBJ_SIGNATURE 28
-#define CRL_OBJ_ROOF 29
-
-/**
- * Parses a CRL revocation reason code
- */
-static crl_reason_t parse_crl_reasonCode(chunk_t object)
-{
- crl_reason_t reason = REASON_UNSPECIFIED;
-
- if (*object.ptr == ASN1_ENUMERATED && asn1_length(&object) == 1)
- {
- reason = *object.ptr;
- }
- DBG2(" '%N'", crl_reason_names, reason);
-
- return reason;
-}
-
-/**
- * Parses an X.509 Certificate Revocation List (CRL)
- */
-bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
-{
- asn1_ctx_t ctx;
- bool critical;
- chunk_t extnID;
- chunk_t userCertificate = chunk_empty;
- revokedCert_t *revokedCert = NULL;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < CRL_OBJ_ROOF)
- {
- if (!extract_object(crlObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- /* those objects which will parsed further need the next higher level */
- level++;
-
- switch (objectID)
- {
- case CRL_OBJ_CERTIFICATE_LIST:
- crl->certificateList = object;
- break;
- case CRL_OBJ_TBS_CERT_LIST:
- crl->tbsCertList = object;
- break;
- case CRL_OBJ_VERSION:
- crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
- DBG2(" v%d", crl->version);
- break;
- case CRL_OBJ_SIG_ALG:
- crl->sigAlg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case CRL_OBJ_ISSUER:
- crl->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", crl->issuer);
- break;
- case CRL_OBJ_THIS_UPDATE:
- crl->thisUpdate = parse_time(object, level);
- break;
- case CRL_OBJ_NEXT_UPDATE:
- crl->nextUpdate = parse_time(object, level);
- break;
- case CRL_OBJ_USER_CERTIFICATE:
- userCertificate = object;
- break;
- case CRL_OBJ_REVOCATION_DATE:
- revokedCert = malloc_thing(revokedCert_t);
- revokedCert->userCertificate = userCertificate;
- revokedCert->revocationDate = parse_time(object, level);
- revokedCert->revocationReason = REASON_UNSPECIFIED;
- crl->revokedCertificates->insert_last(crl->revokedCertificates, (void *)revokedCert);
- break;
- case CRL_OBJ_CRL_ENTRY_EXTN_ID:
- case CRL_OBJ_EXTN_ID:
- extnID = object;
- break;
- case CRL_OBJ_CRL_ENTRY_CRITICAL:
- case CRL_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG2(" %s",(critical)?"TRUE":"FALSE");
- break;
- case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
- case CRL_OBJ_EXTN_VALUE:
- {
- int extn_oid = known_oid(extnID);
-
- if (revokedCert && extn_oid == OID_CRL_REASON_CODE)
- {
- revokedCert->revocationReason = parse_crl_reasonCode(object);
- }
- else if (extn_oid == OID_AUTHORITY_KEY_ID)
- {
- x509_parse_authorityKeyIdentifier(object, level,
- &crl->authKeyID, &crl->authKeySerialNumber);
- }
- else if (extn_oid == OID_CRL_NUMBER)
- {
- if (!parse_asn1_simple_object(&object, ASN1_INTEGER, level, "crlNumber"))
- {
- return FALSE;
- }
- crl->crlNumber = object;
- }
- }
- break;
- case CRL_OBJ_ALGORITHM:
- crl->algorithm = parse_algorithmIdentifier(object, level, NULL);
- if (crl->algorithm != crl->sigAlg)
- {
- DBG1(" signature algorithms do not agree");
- return FALSE;
- }
- break;
- case CRL_OBJ_SIGNATURE:
- crl->signature = object;
- break;
- default:
- break;
- }
- objectID++;
- }
- time(&crl->installed);
- return TRUE;
-}
-
-/**
- * Implements crl_t.is_valid
- */
-static bool is_valid(const private_crl_t *this)
-{
- time_t current_time = time(NULL);
-
- DBG2(" this update : %T", &this->thisUpdate);
- DBG2(" current time: %T", &current_time);
- DBG2(" next update: %T", &this->nextUpdate);
-
- return current_time < this->nextUpdate;
-}
-
-/**
- * Implements crl_t.get_issuer
- */
-static identification_t *get_issuer(const private_crl_t *this)
-{
- return this->issuer;
-}
-
-/**
- * Implements crl_t.equals_issuer
- */
-static bool equals_issuer(const private_crl_t *this, const private_crl_t *other)
-{
- return (this->authKeyID.ptr)
- ? chunk_equals(this->authKeyID, other->authKeyID)
- : (this->issuer->equals(this->issuer, other->issuer)
- && chunk_equals_or_null(this->authKeySerialNumber, other->authKeySerialNumber));
-}
-
-/**
- * Implements crl_t.is_issuer
- */
-static bool is_issuer(const private_crl_t *this, const x509_t *issuer)
-{
- return (this->authKeyID.ptr)
- ? chunk_equals(this->authKeyID, issuer->get_subjectKeyID(issuer))
- : (this->issuer->equals(this->issuer, issuer->get_subject(issuer))
- && chunk_equals_or_null(this->authKeySerialNumber, issuer->get_serialNumber(issuer)));
-}
-
-/**
- * Implements crl_t.is_newer
- */
-static bool is_newer(const private_crl_t *this, const private_crl_t *other)
-{
- return (this->nextUpdate > other->nextUpdate);
-}
-
-/**
- * Implements crl_t.verify
- */
-static bool verify(const private_crl_t *this, const rsa_public_key_t *signer)
-{
- hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->algorithm);
-
- if (algorithm == HASH_UNKNOWN)
- {
- DBG1(" unknown signature algorithm");
- return FALSE;
- }
- return signer->verify_emsa_pkcs1_signature(signer, algorithm, this->tbsCertList, this->signature) == SUCCESS;
-}
-
-/**
- * Implements crl_t.get_status
- */
-static void get_status(const private_crl_t *this, certinfo_t *certinfo)
-{
- chunk_t serialNumber = certinfo->get_serialNumber(certinfo);
- iterator_t *iterator;
- revokedCert_t *revokedCert;
-
- certinfo->set_nextUpdate(certinfo, this->nextUpdate);
- certinfo->set_status(certinfo, CERT_GOOD);
-
- iterator = this->revokedCertificates->create_iterator(this->revokedCertificates, TRUE);
- while (iterator->iterate(iterator, (void**)&revokedCert))
- {
- if (chunk_equals(serialNumber, revokedCert->userCertificate))
- {
- certinfo->set_status(certinfo, CERT_REVOKED);
- certinfo->set_revocationTime(certinfo, revokedCert->revocationDate);
- certinfo->set_revocationReason(certinfo, revokedCert->revocationReason);
- break;
- }
- }
- iterator->destroy(iterator);
-}
-
-/**
- * Implements crl_t.write_to_file.
- */
-static bool write_to_file(private_crl_t *this, const char *path, mode_t mask, bool force)
-{
- return chunk_write(this->certificateList, path, "crl", mask, force);
-}
-
-/**
- * Implements crl_t.destroy
- */
-static void destroy(private_crl_t *this)
-{
- this->revokedCertificates->destroy_function(this->revokedCertificates, free);
- this->crlDistributionPoints->destroy_offset(this->crlDistributionPoints,
- offsetof(identification_t, destroy));
- DESTROY_IF(this->issuer);
- free(this->certificateList.ptr);
- free(this);
-}
-
-/**
- * Implementation of crl_t.list.
- */
-static void list(private_crl_t *this, FILE* out, bool utc)
-{
- time_t now;
-
- now = time(NULL);
-
- fprintf(out, "%#T, revoked certs: %d\n", &this->installed, utc,
- this->revokedCertificates->get_count(this->revokedCertificates));
- fprintf(out, " issuer: '%D'\n", this->issuer);
- if (this->crlNumber.ptr)
- {
- fprintf(out, " crlnumber: %#B\n", &this->crlNumber);
- }
- fprintf(out, " updates: this %#T\n", &this->thisUpdate, utc);
- fprintf(out, " next %#T ", &this->nextUpdate, utc);
- if (this->nextUpdate == UNDEFINED_TIME)
- {
- fprintf(out, "ok (expires never)\n");
- }
- else if (now > this->nextUpdate)
- {
- fprintf(out, "expired (%#V ago)\n", &now, &this->nextUpdate);
- }
- else if (now > this->nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
- {
- fprintf(out, "ok (expires in %#V)\n", &now, &this->nextUpdate);
- }
- else
- {
- fprintf(out, "ok\n");
- }
- if (this->authKeyID.ptr)
- {
- fprintf(out, " authkey: %#B\n", &this->authKeyID);
- }
- if (this->authKeySerialNumber.ptr)
- {
- fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber);
- }
-}
-
-/*
- * Described in header.
- */
-crl_t *crl_create_from_chunk(chunk_t chunk)
-{
- private_crl_t *this = malloc_thing(private_crl_t);
-
- /* initialize */
- this->crlDistributionPoints = linked_list_create();
- this->tbsCertList = chunk_empty;
- this->issuer = NULL;
- this->crlNumber = chunk_empty;
- this->revokedCertificates = linked_list_create();
- this->authKeyID = chunk_empty;
- this->authKeySerialNumber = chunk_empty;
-
- /* public functions */
- this->public.get_issuer = (identification_t* (*) (const crl_t*))get_issuer;
- this->public.equals_issuer = (bool (*) (const crl_t*,const crl_t*))equals_issuer;
- this->public.is_issuer = (bool (*) (const crl_t*,const x509_t*))is_issuer;
- this->public.is_valid = (bool (*) (const crl_t*))is_valid;
- this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer;
- this->public.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify;
- this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status;
- this->public.write_to_file = (bool (*) (const crl_t*,const char*,mode_t,bool))write_to_file;
- this->public.list = (void(*)(crl_t*, FILE* out, bool utc))list;
- this->public.destroy = (void (*) (crl_t*))destroy;
-
- if (!parse_x509crl(chunk, 0, this))
- {
- destroy(this);
- return NULL;
- }
-
- return &this->public;
-}
-
-/*
- * Described in header.
- */
-crl_t *crl_create_from_file(const char *filename)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
-
- if (!pem_asn1_load_file(filename, NULL, "crl", &chunk, &pgp))
- {
- return NULL;
- }
- return crl_create_from_chunk(chunk);
-}
diff --git a/src/libstrongswan/crypto/crl.h b/src/libstrongswan/crypto/crl.h
deleted file mode 100755
index bcf031dd4..000000000
--- a/src/libstrongswan/crypto/crl.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/**
- * @file crl.h
- *
- * @brief Interface of crl_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: crl.h 3300 2007-10-12 21:53:18Z andreas $
- */
-
-#ifndef CRL_H_
-#define CRL_H_
-
-typedef struct crl_t crl_t;
-
-#include <library.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <crypto/certinfo.h>
-#include <utils/identification.h>
-#include <utils/iterator.h>
-
-/**
- * @brief X.509 certificate revocation list
- *
- * @b Constructors:
- * - crl_create_from_chunk()
- * - crl_create_from_file()
- *
- * @ingroup transforms
- */
-struct crl_t {
-
- /**
- * @brief Get the crl's issuer ID.
- *
- * The resulting ID is always a identification_t
- * of type ID_DER_ASN1_DN.
- *
- * @param this calling object
- * @return issuers ID
- */
- identification_t *(*get_issuer) (const crl_t *this);
-
- /**
- * @brief Check if both crls have the same issuer.
- *
- * @param this calling object
- * @param other other crl
- * @return TRUE if the same issuer
- */
- bool (*equals_issuer) (const crl_t *this, const crl_t *other);
-
- /**
- * @brief Check if ia candidate cert is the issuer of the crl
- *
- * @param this calling object
- * @param issuer candidate issuer of the crl
- * @return TRUE if issuer
- */
- bool (*is_issuer) (const crl_t *this, const x509_t *issuer);
-
- /**
- * @brief Checks the validity interval of the crl
- *
- * @param this calling object
- * @return TRUE if the crl is valid
- */
- bool (*is_valid) (const crl_t *this);
-
- /**
- * @brief Checks if this crl is newer (thisUpdate) than the other crl
- *
- * @param this calling object
- * @param other other crl object
- * @return TRUE if this was issued more recently than other
- */
- bool (*is_newer) (const crl_t *this, const crl_t *other);
-
- /**
- * @brief Check if a crl is trustworthy.
- *
- * @param this calling object
- * @param signer signer's RSA public key
- * @return TRUE if crl is trustworthy
- */
- bool (*verify) (const crl_t *this, const rsa_public_key_t *signer);
-
- /**
- * @brief Get the certificate status
- *
- * @param this calling object
- * @param certinfo certinfo is updated
- */
- void (*get_status) (const crl_t *this, certinfo_t *certinfo);
-
- /**
- * @brief Log the info of this CRL to out.
- *
- * @param this calling object
- * @param out stream to write to
- * @param utc TRUE for UTC, FALSE for local time
- */
- void (*list)(crl_t *this, FILE* out, bool utc);
-
- /**
- * @brief Write a der-encoded crl to a file
- *
- * @param this calling object
- * @param path path where the file is to be stored
- * @param mask file access control rights
- * @param force overwrite the file if it already exists
- * @return TRUE if successfully written
- */
- bool (*write_to_file) (const crl_t *this, const char *path, mode_t mask, bool force);
-
- /**
- * @brief Destroys the crl.
- *
- * @param this crl to destroy
- */
- void (*destroy) (crl_t *this);
-};
-
-/**
- * @brief Read a x509 crl from a DER encoded blob.
- *
- * @param chunk chunk containing DER encoded data
- * @return created crl_t, or NULL if invalid.
- *
- * @ingroup transforms
- */
-crl_t *crl_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Read a x509 crl from a DER encoded file.
- *
- * @param filename file containing DER encoded data
- * @return created crl_t, or NULL if invalid.
- *
- * @ingroup transforms
- */
-crl_t *crl_create_from_file(const char *filename);
-
-#endif /* CRL_H_ */
diff --git a/src/libstrongswan/crypto/crypters/crypter.c b/src/libstrongswan/crypto/crypters/crypter.c
index 7f62741a7..2c291a9f5 100644
--- a/src/libstrongswan/crypto/crypters/crypter.c
+++ b/src/libstrongswan/crypto/crypters/crypter.c
@@ -1,10 +1,3 @@
-/**
- * @file crypter.c
- *
- * @brief Generic constructor for crypter_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,15 +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: crypter.c 3971 2008-05-16 13:27:21Z tobias $
*/
-
#include "crypter.h"
-#include <crypto/crypters/aes_cbc_crypter.h>
-#include <crypto/crypters/des_crypter.h>
-
-
ENUM_BEGIN(encryption_algorithm_names, ENCR_UNDEFINED, ENCR_UNDEFINED,
"UNDEFINED");
ENUM_NEXT(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32, ENCR_UNDEFINED,
@@ -40,29 +30,16 @@ ENUM_NEXT(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32, ENCR_UNDEFIN
"BLOWFISH",
"3IDEA",
"DES_IV32");
-ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CTR, ENCR_DES_IV32,
+ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CCM_ICV16, ENCR_DES_IV32,
"NULL",
"AES_CBC",
- "AES_CTR");
-ENUM_END(encryption_algorithm_names, ENCR_AES_CTR);
+ "AES_CTR",
+ "AES_CCM_8",
+ "AES_CCM_12",
+ "AES_CCM_16");
+ENUM_NEXT(encryption_algorithm_names, ENCR_AES_GCM_ICV8, ENCR_AES_GCM_ICV16, ENCR_AES_CCM_ICV16,
+ "AES_GCM_8",
+ "AES_GCM_12",
+ "AES_GCM_16");
+ENUM_END(encryption_algorithm_names, ENCR_AES_GCM_ICV16);
-/*
- * Described in header.
- */
-crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size)
-{
- switch (encryption_algorithm)
- {
- case ENCR_AES_CBC:
- {
- return (crypter_t*)aes_cbc_crypter_create(key_size);
- }
- case ENCR_DES:
- case ENCR_3DES:
- {
- return (crypter_t*)des_crypter_create(encryption_algorithm);
- }
- default:
- return NULL;
- }
-}
diff --git a/src/libstrongswan/crypto/crypters/crypter.h b/src/libstrongswan/crypto/crypters/crypter.h
index 46d94ce93..aade888fa 100644
--- a/src/libstrongswan/crypto/crypters/crypter.h
+++ b/src/libstrongswan/crypto/crypters/crypter.h
@@ -1,10 +1,3 @@
-/**
- * @file crypter.h
- *
- * @brief Interface crypter_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: crypter.h 3971 2008-05-16 13:27:21Z tobias $
+ */
+
+/**
+ * @defgroup crypter crypter
+ * @{ @ingroup crypto
*/
#ifndef CRYPTER_H_
@@ -30,21 +30,12 @@ typedef struct crypter_t crypter_t;
#include <library.h>
/**
- * @brief Encryption algorithm, as in IKEv2 RFC 3.3.2.
- *
- * Currently only the following algorithms are implemented:
- * - ENCR_AES_CBC
- * - ENCR_DES
- * - ENCR_3DES
- *
- * @ingroup crypters
+ * Encryption algorithm, as in IKEv2 RFC 3.3.2.
*/
enum encryption_algorithm_t {
ENCR_UNDEFINED = 1024,
ENCR_DES_IV64 = 1,
- /** Implemented in class des_crypter_t */
ENCR_DES = 2,
- /** Implemented in class des_crypter_t */
ENCR_3DES = 3,
ENCR_RC5 = 4,
ENCR_IDEA = 5,
@@ -53,9 +44,14 @@ enum encryption_algorithm_t {
ENCR_3IDEA = 8,
ENCR_DES_IV32 = 9,
ENCR_NULL = 11,
- /** Implemented in class aes_cbc_crypter_t */
ENCR_AES_CBC = 12,
- ENCR_AES_CTR = 13
+ ENCR_AES_CTR = 13,
+ ENCR_AES_CCM_ICV8 = 14,
+ ENCR_AES_CCM_ICV12 = 15,
+ ENCR_AES_CCM_ICV16 = 16,
+ ENCR_AES_GCM_ICV8 = 18,
+ ENCR_AES_GCM_ICV12 = 19,
+ ENCR_AES_GCM_ICV16 = 20
};
/**
@@ -64,92 +60,65 @@ enum encryption_algorithm_t {
extern enum_name_t *encryption_algorithm_names;
/**
- * @brief Generic interface for symmetric encryption algorithms.
- *
- * @b Constructors:
- * - crypter_create()
- *
- * @ingroup crypters
+ * Generic interface for symmetric encryption algorithms.
*/
struct crypter_t {
/**
- * @brief Encrypt a chunk of data and allocate space for the encrypted value.
+ * Encrypt a chunk of data and allocate space for the encrypted value.
*
- * @param this calling object
- * @param data data to encrypt
- * @param iv initializing vector
- * @param[out] encrypted pointer where the encrypted bytes will be written
- * @return
- * - SUCCESS
- * - INVALID_ARG if data size not a multiple of block size
+ * The length of the iv must equal to get_block_size(), while the length
+ * of data must be a multiple it.
+ * If encrypted is NULL, the encryption is done in-place (overwriting data).
+ *
+ * @param data data to encrypt
+ * @param iv initializing vector
+ * @param encrypted chunk to allocate encrypted data, or NULL
*/
- status_t (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted);
+ void (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted);
/**
- * @brief Decrypt a chunk of data and allocate space for the decrypted value.
+ * Decrypt a chunk of data and allocate space for the decrypted value.
+ *
+ * The length of the iv must equal to get_block_size(), while the length
+ * of data must be a multiple it.
+ * If decrpyted is NULL, the encryption is done in-place (overwriting data).
*
- * @param this calling object
- * @param data data to decrypt
- * @param iv initializing vector
- * @param[out] encrypted pointer where the decrypted bytes will be written
- * @return
- * - SUCCESS
- * - INVALID_ARG if data size not a multiple of block size
+ * @param data data to decrypt
+ * @param iv initializing vector
+ * @param encrypted chunk to allocate decrypted data, or NULL
*/
- status_t (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted);
+ void (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted);
/**
- * @brief Get the block size of this crypter_t object.
+ * Get the block size of the crypto algorithm.
*
- * @param this calling object
* @return block size in bytes
*/
size_t (*get_block_size) (crypter_t *this);
/**
- * @brief Get the key size of this crypter_t object.
+ * Get the key size of the crypto algorithm.
*
- * @param this calling object
* @return key size in bytes
*/
size_t (*get_key_size) (crypter_t *this);
/**
- * @brief Set the key for this crypter_t object.
- *
- * @param this calling object
+ * Set the key.
+ *
+ * The length of the key must match get_key_size().
+ *
* @param key key to set
- * @return
- * - SUCCESS
- * - INVALID_ARG if key length invalid
*/
- status_t (*set_key) (crypter_t *this, chunk_t key);
+ void (*set_key) (crypter_t *this, chunk_t key);
/**
- * @brief Destroys a crypter_t object.
- *
- * @param this calling object
+ * Destroys a crypter_t object.
*/
void (*destroy) (crypter_t *this);
};
-/**
- * @brief Generic constructor for crypter_t objects.
- *
- * Currently only the following algorithms are implemented:
- * - ENCR_AES_CBC
- * - ENCR_DES
- * - ENCR_3DES
- *
- * The key_size is ignored for algorithms with fixed key size.
- *
- * @param encryption_algorithm Algorithm to use for crypter
- * @param key_size size of the key in bytes
- * @return
- * - crypter_t object
- * - NULL if encryption algorithm/key_size is not supported
- */
-crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size);
-
-#endif /*CRYPTER_H_*/
+#endif /*CRYPTER_H_ @} */
diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c
new file mode 100644
index 000000000..46fa983b2
--- /dev/null
+++ b/src/libstrongswan/crypto/crypto_factory.c
@@ -0,0 +1,571 @@
+/*
+ * 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: crypto_factory.c 3806 2008-04-15 05:56:35Z martin $
+ */
+
+#include "crypto_factory.h"
+
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+
+typedef struct crypter_entry_t crypter_entry_t;
+struct crypter_entry_t {
+ /** encryption algorithm */
+ encryption_algorithm_t algo;
+ /** associated constructor */
+ crypter_constructor_t create;
+};
+
+typedef struct signer_entry_t signer_entry_t;
+struct signer_entry_t {
+ /** integrity algorithm */
+ integrity_algorithm_t algo;
+ /** associated constructor */
+ signer_constructor_t create;
+};
+
+typedef struct hasher_entry_t hasher_entry_t;
+struct hasher_entry_t {
+ /** hash algorithm */
+ hash_algorithm_t algo;
+ /** associated constructor */
+ hasher_constructor_t create;
+};
+
+typedef struct prf_entry_t prf_entry_t;
+struct prf_entry_t {
+ /** hash algorithm */
+ pseudo_random_function_t algo;
+ /** associated constructor */
+ prf_constructor_t create;
+};
+
+typedef struct rng_entry_t rng_entry_t;
+struct rng_entry_t {
+ /** quality of randomness */
+ rng_quality_t quality;
+ /** associated constructor */
+ rng_constructor_t create;
+};
+
+typedef struct dh_entry_t dh_entry_t;
+struct dh_entry_t {
+ /** hash algorithm */
+ diffie_hellman_group_t group;
+ /** associated constructor */
+ dh_constructor_t create;
+};
+
+typedef struct private_crypto_factory_t private_crypto_factory_t;
+
+/**
+ * private data of crypto_factory
+ */
+struct private_crypto_factory_t {
+
+ /**
+ * public functions
+ */
+ crypto_factory_t public;
+
+ /**
+ * registered crypters, as crypter_entry_t
+ */
+ linked_list_t *crypters;
+
+ /**
+ * registered signers, as signer_entry_t
+ */
+ linked_list_t *signers;
+
+ /**
+ * registered hashers, as hasher_entry_t
+ */
+ linked_list_t *hashers;
+
+ /**
+ * registered prfs, as prf_entry_t
+ */
+ linked_list_t *prfs;
+
+ /**
+ * registered rngs, as rng_entry_t
+ */
+ linked_list_t *rngs;
+
+ /**
+ * registered diffie hellman, as dh_entry_t
+ */
+ linked_list_t *dhs;
+
+ /**
+ * mutex to lock access to modules
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * Implementation of crypto_factory_t.create_crypter.
+ */
+static crypter_t* create_crypter(private_crypto_factory_t *this,
+ encryption_algorithm_t algo, size_t key_size)
+{
+ enumerator_t *enumerator;
+ crypter_entry_t *entry;
+ crypter_t *crypter = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->crypters->create_enumerator(this->crypters);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->algo == algo)
+ {
+ crypter = entry->create(algo, key_size);
+ if (crypter)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return crypter;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_signer.
+ */
+static signer_t* create_signer(private_crypto_factory_t *this,
+ integrity_algorithm_t algo)
+{
+ enumerator_t *enumerator;
+ signer_entry_t *entry;
+ signer_t *signer = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->signers->create_enumerator(this->signers);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->algo == algo)
+ {
+ signer = entry->create(algo);
+ if (signer)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+
+ return signer;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_hasher.
+ */
+static hasher_t* create_hasher(private_crypto_factory_t *this,
+ hash_algorithm_t algo)
+{
+ enumerator_t *enumerator;
+ hasher_entry_t *entry;
+ hasher_t *hasher = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->hashers->create_enumerator(this->hashers);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (algo == HASH_PREFERRED || entry->algo == algo)
+ {
+ hasher = entry->create(entry->algo);
+ if (hasher)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return hasher;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_prf.
+ */
+static prf_t* create_prf(private_crypto_factory_t *this,
+ pseudo_random_function_t algo)
+{
+ enumerator_t *enumerator;
+ prf_entry_t *entry;
+ prf_t *prf = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->prfs->create_enumerator(this->prfs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->algo == algo)
+ {
+ prf = entry->create(algo);
+ if (prf)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return prf;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_rng.
+ */
+static rng_t* create_rng(private_crypto_factory_t *this, rng_quality_t quality)
+{
+ enumerator_t *enumerator;
+ rng_entry_t *entry;
+ u_int diff = ~0;
+ rng_constructor_t constr = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->rngs->create_enumerator(this->rngs);
+ while (enumerator->enumerate(enumerator, &entry))
+ { /* find the best matching quality, but at least as good as requested */
+ if (entry->quality >= quality && diff > entry->quality - quality)
+ {
+ diff = entry->quality - quality;
+ constr = entry->create;
+ if (diff == 0)
+ { /* perfect match, won't get better */
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ if (constr)
+ {
+ return constr(quality);
+ }
+ return NULL;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_dh.
+ */
+static diffie_hellman_t* create_dh(private_crypto_factory_t *this,
+ diffie_hellman_group_t group)
+{
+ enumerator_t *enumerator;
+ dh_entry_t *entry;
+ diffie_hellman_t *diffie_hellman = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->dhs->create_enumerator(this->dhs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->group == group)
+ {
+ diffie_hellman = entry->create(group);
+ if (diffie_hellman)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return diffie_hellman;
+}
+
+/**
+ * Implementation of crypto_factory_t.add_crypter.
+ */
+static void add_crypter(private_crypto_factory_t *this,
+ encryption_algorithm_t algo,
+ crypter_constructor_t create)
+{
+ crypter_entry_t *entry = malloc_thing(crypter_entry_t);
+
+ entry->algo = algo;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->crypters->insert_last(this->crypters, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_crypter.
+ */
+static void remove_crypter(private_crypto_factory_t *this,
+ crypter_constructor_t create)
+{
+ crypter_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->crypters->create_enumerator(this->crypters);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->crypters->remove_at(this->crypters, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_signer.
+ */
+static void add_signer(private_crypto_factory_t *this,
+ integrity_algorithm_t algo, signer_constructor_t create)
+{
+ signer_entry_t *entry = malloc_thing(signer_entry_t);
+
+ entry->algo = algo;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->signers->insert_last(this->signers, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_signer.
+ */
+static void remove_signer(private_crypto_factory_t *this,
+ signer_constructor_t create)
+{
+ signer_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->signers->create_enumerator(this->signers);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->signers->remove_at(this->signers, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_hasher.
+ */
+static void add_hasher(private_crypto_factory_t *this, hash_algorithm_t algo,
+ hasher_constructor_t create)
+{
+ hasher_entry_t *entry = malloc_thing(hasher_entry_t);
+
+ entry->algo = algo;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->hashers->insert_last(this->hashers, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_hasher.
+ */
+static void remove_hasher(private_crypto_factory_t *this,
+ hasher_constructor_t create)
+{
+ hasher_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->hashers->create_enumerator(this->hashers);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->hashers->remove_at(this->hashers, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_prf.
+ */
+static void add_prf(private_crypto_factory_t *this,
+ pseudo_random_function_t algo, prf_constructor_t create)
+{
+ prf_entry_t *entry = malloc_thing(prf_entry_t);
+
+ entry->algo = algo;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->prfs->insert_last(this->prfs, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_prf.
+ */
+static void remove_prf(private_crypto_factory_t *this, prf_constructor_t create)
+{
+ prf_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->prfs->create_enumerator(this->prfs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->prfs->remove_at(this->prfs, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_rng.
+ */
+static void add_rng(private_crypto_factory_t *this, rng_quality_t quality,
+ rng_constructor_t create)
+{
+ rng_entry_t *entry = malloc_thing(rng_entry_t);
+
+ entry->quality = quality;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->rngs->insert_last(this->rngs, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_rng.
+ */
+static void remove_rng(private_crypto_factory_t *this, rng_constructor_t create)
+{
+ rng_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->rngs->create_enumerator(this->rngs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->rngs->remove_at(this->rngs, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_dh.
+ */
+static void add_dh(private_crypto_factory_t *this, diffie_hellman_group_t group,
+ dh_constructor_t create)
+{
+ dh_entry_t *entry = malloc_thing(dh_entry_t);
+
+ entry->group = group;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->dhs->insert_last(this->dhs, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_dh.
+ */
+static void remove_dh(private_crypto_factory_t *this, dh_constructor_t create)
+{
+ dh_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->dhs->create_enumerator(this->dhs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->dhs->remove_at(this->dhs, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.destroy
+ */
+static void destroy(private_crypto_factory_t *this)
+{
+ this->crypters->destroy_function(this->crypters, free);
+ this->signers->destroy_function(this->signers, free);
+ this->hashers->destroy_function(this->hashers, free);
+ this->prfs->destroy_function(this->prfs, free);
+ this->rngs->destroy_function(this->rngs, free);
+ this->dhs->destroy_function(this->dhs, free);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+crypto_factory_t *crypto_factory_create()
+{
+ private_crypto_factory_t *this = malloc_thing(private_crypto_factory_t);
+
+ this->public.create_crypter = (crypter_t*(*)(crypto_factory_t*, encryption_algorithm_t, size_t))create_crypter;
+ this->public.create_signer = (signer_t*(*)(crypto_factory_t*, integrity_algorithm_t))create_signer;
+ this->public.create_hasher = (hasher_t*(*)(crypto_factory_t*, hash_algorithm_t))create_hasher;
+ this->public.create_prf = (prf_t*(*)(crypto_factory_t*, pseudo_random_function_t))create_prf;
+ this->public.create_rng = (rng_t*(*)(crypto_factory_t*, rng_quality_t quality))create_rng;
+ this->public.create_dh = (diffie_hellman_t*(*)(crypto_factory_t*, diffie_hellman_group_t group))create_dh;
+ this->public.add_crypter = (void(*)(crypto_factory_t*, encryption_algorithm_t algo, crypter_constructor_t create))add_crypter;
+ this->public.remove_crypter = (void(*)(crypto_factory_t*, crypter_constructor_t create))remove_crypter;
+ this->public.add_signer = (void(*)(crypto_factory_t*, integrity_algorithm_t algo, signer_constructor_t create))add_signer;
+ this->public.remove_signer = (void(*)(crypto_factory_t*, signer_constructor_t create))remove_signer;
+ this->public.add_hasher = (void(*)(crypto_factory_t*, hash_algorithm_t algo, hasher_constructor_t create))add_hasher;
+ this->public.remove_hasher = (void(*)(crypto_factory_t*, hasher_constructor_t create))remove_hasher;
+ this->public.add_prf = (void(*)(crypto_factory_t*, pseudo_random_function_t algo, prf_constructor_t create))add_prf;
+ this->public.remove_prf = (void(*)(crypto_factory_t*, prf_constructor_t create))remove_prf;
+ this->public.add_rng = (void(*)(crypto_factory_t*, rng_quality_t quality, rng_constructor_t create))add_rng;
+ this->public.remove_rng = (void(*)(crypto_factory_t*, rng_constructor_t create))remove_rng;
+ this->public.add_dh = (void(*)(crypto_factory_t*, diffie_hellman_group_t algo, dh_constructor_t create))add_dh;
+ this->public.remove_dh = (void(*)(crypto_factory_t*, dh_constructor_t create))remove_dh;
+ this->public.destroy = (void(*)(crypto_factory_t*))destroy;
+
+ this->crypters = linked_list_create();
+ this->signers = linked_list_create();
+ this->hashers = linked_list_create();
+ this->prfs = linked_list_create();
+ this->rngs = linked_list_create();
+ this->dhs = linked_list_create();
+ this->mutex = mutex_create(MUTEX_RECURSIVE);
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/crypto/crypto_factory.h b/src/libstrongswan/crypto/crypto_factory.h
new file mode 100644
index 000000000..6bf070c31
--- /dev/null
+++ b/src/libstrongswan/crypto/crypto_factory.h
@@ -0,0 +1,235 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup crypto_factory crypto_factory
+ * @{ @ingroup crypto
+ */
+
+#ifndef CRYPTO_FACTORY_H_
+#define CRYPTO_FACTORY_H_
+
+typedef struct crypto_factory_t crypto_factory_t;
+
+#include <library.h>
+#include <crypto/crypters/crypter.h>
+#include <crypto/signers/signer.h>
+#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/prf.h>
+#include <crypto/rngs/rng.h>
+#include <crypto/diffie_hellman.h>
+
+/**
+ * Constructor function for crypters
+ */
+typedef crypter_t* (*crypter_constructor_t)(encryption_algorithm_t algo,
+ size_t key_size);
+/**
+ * Constructor function for signers
+ */
+typedef signer_t* (*signer_constructor_t)(integrity_algorithm_t algo);
+
+/**
+ * Constructor function for hashers
+ */
+typedef hasher_t* (*hasher_constructor_t)(hash_algorithm_t algo);
+
+/**
+ * Constructor function for pseudo random functions
+ */
+typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo);
+
+/**
+ * Constructor function for source of randomness
+ */
+typedef rng_t* (*rng_constructor_t)(rng_quality_t quality);
+
+/**
+ * Constructor function for diffie hellman
+ */
+typedef diffie_hellman_t* (*dh_constructor_t)(diffie_hellman_group_t group);
+
+/**
+ * Handles crypto modules and creates instances.
+ */
+struct crypto_factory_t {
+
+ /**
+ * Create a crypter instance.
+ *
+ * @param algo encryption algorithm
+ * @param key_size length of the key in bytes
+ * @return crypter_t instance, NULL if not supported
+ */
+ crypter_t* (*create_crypter)(crypto_factory_t *this,
+ encryption_algorithm_t algo, size_t key_size);
+
+ /**
+ * Create a symmetric signer instance.
+ *
+ * @param algo MAC algorithm to use
+ * @return signer_t instance, NULL if not supported
+ */
+ signer_t* (*create_signer)(crypto_factory_t *this,
+ integrity_algorithm_t algo);
+
+ /**
+ * Create a hasher instance.
+ *
+ * @param algo hash algorithm
+ * @return hasher_t instance, NULL if not supported
+ */
+ hasher_t* (*create_hasher)(crypto_factory_t *this, hash_algorithm_t algo);
+
+ /**
+ * Create a pseudo random function instance.
+ *
+ * @param algo PRF algorithm to use
+ * @return prf_t instance, NULL if not supported
+ */
+ prf_t* (*create_prf)(crypto_factory_t *this, pseudo_random_function_t algo);
+
+ /**
+ * Create a source of randomness.
+ *
+ * @param quality required randomness quality
+ * @return rng_t instance, NULL if no RNG with such a quality
+ */
+ rng_t* (*create_rng)(crypto_factory_t *this, rng_quality_t quality);
+
+ /**
+ * Create a diffie hellman instance.
+ *
+ * @param group diffie hellman group
+ * @return diffie_hellman_t instance, NULL if not supported
+ */
+ diffie_hellman_t* (*create_dh)(crypto_factory_t *this,
+ diffie_hellman_group_t group);
+
+ /**
+ * Register a crypter constructor.
+ *
+ * @param algo algorithm to constructor
+ * @param create constructor function for that algorithm
+ * @return
+ */
+ void (*add_crypter)(crypto_factory_t *this, encryption_algorithm_t algo,
+ crypter_constructor_t create);
+
+ /**
+ * Unregister a crypter constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_crypter)(crypto_factory_t *this, crypter_constructor_t create);
+
+ /**
+ * Register a signer constructor.
+ *
+ * @param algo algorithm to constructor
+ * @param create constructor function for that algorithm
+ * @return
+ */
+ void (*add_signer)(crypto_factory_t *this, integrity_algorithm_t algo,
+ signer_constructor_t create);
+
+ /**
+ * Unregister a signer constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_signer)(crypto_factory_t *this, signer_constructor_t create);
+
+ /**
+ * Register a hasher constructor.
+ *
+ * The first added hasher is the preferred hasher returned on
+ * create_hasher(HASH_PREFERRED).
+ *
+ * @param algo algorithm to constructor
+ * @param create constructor function for that algorithm
+ * @return
+ */
+ void (*add_hasher)(crypto_factory_t *this, hash_algorithm_t algo,
+ hasher_constructor_t create);
+
+ /**
+ * Unregister a hasher constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_hasher)(crypto_factory_t *this, hasher_constructor_t create);
+
+ /**
+ * Register a prf constructor.
+ *
+ * @param algo algorithm to constructor
+ * @param create constructor function for that algorithm
+ * @return
+ */
+ void (*add_prf)(crypto_factory_t *this, pseudo_random_function_t algo,
+ prf_constructor_t create);
+
+ /**
+ * Unregister a prf constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_prf)(crypto_factory_t *this, prf_constructor_t create);
+
+ /**
+ * Register a source of randomness.
+ *
+ * @param quality quality of randomness this RNG serves
+ * @param create constructor function for such a quality
+ */
+ void (*add_rng)(crypto_factory_t *this, rng_quality_t quality, rng_constructor_t create);
+
+ /**
+ * Unregister a source of randomness.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_rng)(crypto_factory_t *this, rng_constructor_t create);
+
+ /**
+ * Register a diffie hellman constructor.
+ *
+ * @param group dh group to constructor
+ * @param create constructor function for that algorithm
+ * @return
+ */
+ void (*add_dh)(crypto_factory_t *this, diffie_hellman_group_t group,
+ dh_constructor_t create);
+
+ /**
+ * Unregister a diffie hellman constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_dh)(crypto_factory_t *this, dh_constructor_t create);
+
+ /**
+ * Destroy a crypto_factory instance.
+ */
+ void (*destroy)(crypto_factory_t *this);
+};
+
+/**
+ * Create a crypto_factory instance.
+ */
+crypto_factory_t *crypto_factory_create();
+
+#endif /* CRYPTO_FACTORY_H_ @}*/
diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/diffie_hellman.c
index 605892e87..02d2cb52a 100644
--- a/src/libstrongswan/crypto/diffie_hellman.c
+++ b/src/libstrongswan/crypto/diffie_hellman.c
@@ -1,14 +1,5 @@
-/**
- * @file diffie_hellman.c
- *
- * @brief Implementation of diffie_hellman_t.
- *
- */
-
/*
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- * Copyright (C) 1999, 2000, 2001 Henry Spencer.
- * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -21,569 +12,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: diffie_hellman.c 4023 2008-05-29 06:55:03Z andreas $
*/
-#include <gmp.h>
-
#include "diffie_hellman.h"
-#include <utils/randomizer.h>
-#include <debug.h>
-
ENUM_BEGIN(diffie_hellman_group_names, MODP_NONE, MODP_1024_BIT,
"MODP_NONE",
"MODP_768_BIT",
"MODP_1024_BIT");
ENUM_NEXT(diffie_hellman_group_names, MODP_1536_BIT, MODP_1536_BIT, MODP_1024_BIT,
"MODP_1536_BIT");
-ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, MODP_8192_BIT, MODP_1536_BIT,
+ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, ECP_521_BIT, MODP_1536_BIT,
"MODP_2048_BIT",
"MODP_3072_BIT",
"MODP_4096_BIT",
"MODP_6144_BIT",
- "MODP_8192_BIT");
-ENUM_END(diffie_hellman_group_names, MODP_8192_BIT);
-
-
-/**
- * Modulus of Group 1 (MODP_768_BIT).
- */
-static u_int8_t group1_modulus[] = {
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
- 0xC4,0xC6,0x62,0x8B,0x80 ,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
- 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
- 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
- 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
- 0xF4,0x4C,0x42,0xE9,0xA6,0x3A,0x36,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
-};
-
-/**
- * Modulus of Group 2 (MODP_1024_BIT).
- */
-static u_int8_t group2_modulus[] = {
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
- 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
- 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
- 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
- 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
- 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
- 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
- 0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
-};
-
-/**
- * Modulus of Group 5 (MODP_1536_BIT).
- */
-static u_int8_t group5_modulus[] = {
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
- 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
- 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
- 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
- 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
- 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
- 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
- 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
- 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
- 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
- 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
- 0xF1,0x74,0x6C,0x08,0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
-};
-/**
- * Modulus of Group 14 (MODP_2048_BIT).
- */
-static u_int8_t group14_modulus[] = {
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
- 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
- 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
- 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
- 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
- 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
- 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
- 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
- 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
- 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
- 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
- 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
- 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
- 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
- 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
- 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
-};
-
-/**
- * Modulus of Group 15 (MODP_3072_BIT).
- */
-static u_int8_t group15_modulus[] = {
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
- 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
- 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
- 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
- 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
- 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
- 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
- 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
- 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
- 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
- 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
- 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
- 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
- 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
- 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
- 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
- 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
- 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
- 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
- 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
- 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
- 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
- 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
- 0x4B,0x82,0xD1,0x20,0xA9,0x3A,0xD2,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
-};
-
-/**
- * Modulus of Group 16 (MODP_4096_BIT).
- */
-static u_int8_t group16_modulus[] = {
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
- 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
- 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
- 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
- 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
- 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
- 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
- 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
- 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
- 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
- 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
- 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
- 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
- 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
- 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
- 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
- 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
- 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
- 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
- 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
- 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
- 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
- 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
- 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
- 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
- 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
- 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
- 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
- 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
- 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
- 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
- 0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
-};
-
-/**
- * Modulus of Group 17 (MODP_6144_BIT).
- */
-static u_int8_t group17_modulus[] = {
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
- 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
- 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
- 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
- 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
- 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
- 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
- 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
- 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
- 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
- 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
- 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
- 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
- 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
- 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
- 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
- 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
- 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
- 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
- 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
- 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
- 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
- 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
- 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
- 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
- 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
- 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
- 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
- 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
- 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
- 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
- 0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,
- 0xC1,0xD4,0xDC,0xB2,0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
- 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,0x41,0x30,0x01,0xAE,
- 0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,
- 0xDA,0x3E,0xDB,0xEB,0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
- 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,0x2B,0xD7,0xAF,0x42,
- 0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,
- 0xF0,0x32,0xEA,0x15,0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
- 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,0x90,0x0B,0x1C,0x9E,
- 0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,
- 0x0F,0x1D,0x45,0xB7,0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
- 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,0x0F,0x80,0x37,0xE0,
- 0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,
- 0xF5,0x50,0xAA,0x3D,0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
- 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,0x6E,0x3C,0x04,0x68,
- 0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,
- 0xE6,0x94,0xF9,0x1E,0x6D,0xCC,0x40,0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
-};
-
-/**
- * Modulus of Group 18 (MODP_8192_BIT).
- */
-static u_int8_t group18_modulus[] = {
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
- 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
- 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
- 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
- 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
- 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
- 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
- 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
- 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
- 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
- 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
- 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
- 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
- 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
- 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
- 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
- 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
- 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
- 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
- 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
- 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
- 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
- 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
- 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
- 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
- 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
- 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
- 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
- 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
- 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
- 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
- 0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,
- 0xC1,0xD4,0xDC,0xB2,0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
- 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,0x41,0x30,0x01,0xAE,
- 0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,
- 0xDA,0x3E,0xDB,0xEB,0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
- 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,0x2B,0xD7,0xAF,0x42,
- 0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,
- 0xF0,0x32,0xEA,0x15,0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
- 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,0x90,0x0B,0x1C,0x9E,
- 0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,
- 0x0F,0x1D,0x45,0xB7,0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
- 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,0x0F,0x80,0x37,0xE0,
- 0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,
- 0xF5,0x50,0xAA,0x3D,0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
- 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,0x6E,0x3C,0x04,0x68,
- 0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,
- 0xE6,0x94,0xF9,0x1E,0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
- 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,0x73,0xB9,0x31,0xBA,
- 0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,
- 0x25,0x76,0xF6,0x93,0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
- 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,0xE3,0x9D,0x65,0x2D,
- 0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,
- 0x13,0xEB,0x57,0xA8,0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
- 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,0xA2,0xC0,0x87,0xE8,
- 0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,
- 0x6D,0x2A,0x13,0xF8,0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
- 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,0x08,0x46,0x85,0x1D,
- 0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,
- 0xFA,0xF3,0x6B,0xC3,0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
- 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,0xD5,0xEE,0x38,0x2B,
- 0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,
- 0x9E,0x30,0x50,0xE2,0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
- 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-};
-
-typedef struct modulus_entry_t modulus_entry_t;
-
-/**
- * Entry of the modulus list.
- */
-struct modulus_entry_t {
- /**
- * Group number as it is defined in file transform_substructure.h.
- */
- diffie_hellman_group_t group;
-
- /**
- * Pointer to first byte of modulus (network order).
- */
- u_int8_t *modulus;
-
- /*
- * Length of modulus in bytes.
- */
- size_t modulus_len;
-
- /*
- * Generator value.
- */
- u_int16_t generator;
-};
-
-/**
- * All supported modulus values.
- */
-static modulus_entry_t modulus_entries[] = {
- {MODP_768_BIT, group1_modulus, sizeof(group1_modulus), 2},
- {MODP_1024_BIT, group2_modulus, sizeof(group2_modulus), 2},
- {MODP_1536_BIT, group5_modulus, sizeof(group5_modulus), 2},
- {MODP_2048_BIT, group14_modulus, sizeof(group14_modulus), 2},
- {MODP_3072_BIT, group15_modulus, sizeof(group15_modulus), 2},
- {MODP_4096_BIT, group16_modulus, sizeof(group16_modulus), 2},
- {MODP_6144_BIT, group17_modulus, sizeof(group17_modulus), 2},
- {MODP_8192_BIT, group18_modulus, sizeof(group18_modulus), 2},
-};
-
-typedef struct private_diffie_hellman_t private_diffie_hellman_t;
-
-/**
- * Private data of an diffie_hellman_t object.
- *
- */
-struct private_diffie_hellman_t {
- /**
- * Public diffie_hellman_t interface.
- */
- diffie_hellman_t public;
-
- /**
- * Diffie Hellman group number.
- */
- u_int16_t group;
-
- /*
- * Generator value.
- */
- mpz_t g;
-
- /**
- * My private value.
- */
- mpz_t xa;
-
- /**
- * My public value.
- */
- mpz_t ya;
-
- /**
- * Other public value.
- */
- mpz_t yb;
-
- /**
- * Shared secret.
- */
- mpz_t zz;
-
- /**
- * Modulus.
- */
- mpz_t p;
-
- /**
- * Modulus length.
- */
- size_t p_len;
-
- /**
- * True if shared secret is computed and stored in my_public_value.
- */
- bool computed;
-};
-
-/**
- * Implementation of diffie_hellman_t.set_other_public_value.
- */
-static void set_other_public_value(private_diffie_hellman_t *this, chunk_t value)
-{
- mpz_t p_min_1;
-
- mpz_init(p_min_1);
- mpz_sub_ui(p_min_1, this->p, 1);
-
- mpz_import(this->yb, value.len, 1, 1, 1, 0, value.ptr);
-
- /* check public value:
- * 1. 0 or 1 is invalid as 0^a = 0 and 1^a = 1
- * 2. a public value larger or equal the modulus is invalid */
- if (mpz_cmp_ui(this->yb, 1) > 0 ||
- mpz_cmp(this->yb, p_min_1) < 0)
- {
-#ifdef EXTENDED_DH_TEST
- /* 3. test if y ^ q mod p = 1, where q = (p - 1)/2. */
- mpz_t q, one;
-
- mpz_init(q);
- mpz_init(one);
- mpz_fdiv_q_2exp(q, p_min_1, 1);
- mpz_powm(one, this->yb, q, this->p);
- mpz_clear(q);
- if (mpz_cmp_ui(one, 1) == 0)
- {
- mpz_powm(this->zz, this->yb, this->xa, this->p);
- this->computed = TRUE;
- }
- else
- {
- DBG1("public DH value verification failed: y ^ q mod p != 1");
- }
- mpz_clear(one);
-#else
- mpz_powm(this->zz, this->yb, this->xa, this->p);
- this->computed = TRUE;
-#endif
- }
- else
- {
- DBG1("public DH value verification failed: y < 2 || y > p - 1 ");
- }
- mpz_clear(p_min_1);
-}
-
-/**
- * Implementation of diffie_hellman_t.get_other_public_value.
- */
-static status_t get_other_public_value(private_diffie_hellman_t *this,
- chunk_t *value)
-{
- if (!this->computed)
- {
- return FAILED;
- }
- value->len = this->p_len;
- value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->yb);
- return SUCCESS;
-}
-
-/**
- * Implementation of diffie_hellman_t.get_my_public_value.
- */
-static void get_my_public_value(private_diffie_hellman_t *this,chunk_t *value)
-{
- value->len = this->p_len;
- value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->ya);
-}
-
-/**
- * Implementation of diffie_hellman_t.get_shared_secret.
- */
-static status_t get_shared_secret(private_diffie_hellman_t *this, chunk_t *secret)
-{
- if (!this->computed)
- {
- return FAILED;
- }
- secret->len = this->p_len;
- secret->ptr = mpz_export(NULL, NULL, 1, secret->len, 1, 0, this->zz);
- return SUCCESS;
-}
-
-/**
- * Implementation of diffie_hellman_t.get_dh_group.
- */
-static diffie_hellman_group_t get_dh_group(private_diffie_hellman_t *this)
-{
- return this->group;
-}
-
-/**
- * Lookup the modulus in modulo table
- */
-static status_t set_modulus(private_diffie_hellman_t *this)
-{
- int i;
- status_t status = NOT_FOUND;
-
- for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++)
- {
- if (modulus_entries[i].group == this->group)
- {
- chunk_t chunk;
- chunk.ptr = modulus_entries[i].modulus;
- chunk.len = modulus_entries[i].modulus_len;
- mpz_import(this->p, chunk.len, 1, 1, 1, 0, chunk.ptr);
- this->p_len = chunk.len;
- mpz_set_ui(this->g, modulus_entries[i].generator);
- status = SUCCESS;
- break;
- }
- }
- return status;
-}
-
-/**
- * Implementation of diffie_hellman_t.destroy.
- */
-static void destroy(private_diffie_hellman_t *this)
-{
- mpz_clear(this->p);
- mpz_clear(this->xa);
- mpz_clear(this->ya);
- mpz_clear(this->yb);
- mpz_clear(this->zz);
- mpz_clear(this->g);
- free(this);
-}
-
-/*
- * Described in header.
- */
-diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t group)
-{
- private_diffie_hellman_t *this = malloc_thing(private_diffie_hellman_t);
- randomizer_t *randomizer;
- chunk_t random;
- status_t status;
-
- /* public functions */
- this->public.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
- this->public.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
- this->public.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
- this->public.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
- this->public.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
- this->public.destroy = (void (*)(diffie_hellman_t *)) destroy;
-
- /* private variables */
- this->group = group;
- mpz_init(this->p);
- mpz_init(this->yb);
- mpz_init(this->ya);
- mpz_init(this->xa);
- mpz_init(this->zz);
- mpz_init(this->g);
-
- this->computed = FALSE;
-
- /* find a modulus according to group */
- if (set_modulus(this) != SUCCESS)
- {
- destroy(this);
- return NULL;
- }
- randomizer = randomizer_create();
- status = randomizer->allocate_pseudo_random_bytes(
- randomizer, this->p_len, &random);
- randomizer->destroy(randomizer);
- if (status != SUCCESS)
- {
- destroy(this);
- return NULL;
- }
- mpz_import(this->xa, random.len, 1, 1, 1, 0, random.ptr);
- chunk_free(&random);
-
- mpz_powm(this->ya, this->g, this->xa, this->p);
-
- return &this->public;
-}
+ "MODP_8192_BIT",
+ "ECP_256_BIT",
+ "ECP_384_BIT",
+ "ECP_521_BIT");
+ENUM_NEXT(diffie_hellman_group_names, ECP_192_BIT, ECP_224_BIT, ECP_521_BIT,
+ "ECP_192_BIT",
+ "ECP_224_BIT");
+ENUM_END(diffie_hellman_group_names, ECP_224_BIT);
diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/diffie_hellman.h
index 8cd06d60e..c66ae56c3 100644
--- a/src/libstrongswan/crypto/diffie_hellman.h
+++ b/src/libstrongswan/crypto/diffie_hellman.h
@@ -1,10 +1,3 @@
-/**
- * @file diffie_hellman.h
- *
- * @brief Interface of diffie_hellman_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: diffie_hellman.h 4023 2008-05-29 06:55:03Z andreas $
+ */
+
+/**
+ * @defgroup diffie_hellman diffie_hellman
+ * @{ @ingroup crypto
*/
#ifndef DIFFIE_HELLMAN_H_
@@ -30,24 +30,28 @@ typedef struct diffie_hellman_t diffie_hellman_t;
#include <library.h>
/**
- * @brief Diffie-Hellman group.
+ * Diffie-Hellman group.
*
* The modulus (or group) to use for a Diffie-Hellman calculation.
- *
* See IKEv2 RFC 3.3.2 and RFC 3526.
- *
- * @ingroup crypto
+ *
+ * ECP groups are defined in RFC 4753 and RFC 5114.
*/
enum diffie_hellman_group_t {
- MODP_NONE = 0,
- MODP_768_BIT = 1,
- MODP_1024_BIT = 2,
- MODP_1536_BIT = 5,
+ MODP_NONE = 0,
+ MODP_768_BIT = 1,
+ MODP_1024_BIT = 2,
+ MODP_1536_BIT = 5,
MODP_2048_BIT = 14,
MODP_3072_BIT = 15,
MODP_4096_BIT = 16,
MODP_6144_BIT = 17,
- MODP_8192_BIT = 18
+ MODP_8192_BIT = 18,
+ ECP_256_BIT = 19,
+ ECP_384_BIT = 20,
+ ECP_521_BIT = 21,
+ ECP_192_BIT = 25,
+ ECP_224_BIT = 26,
};
/**
@@ -56,89 +60,60 @@ enum diffie_hellman_group_t {
extern enum_name_t *diffie_hellman_group_names;
/**
- * @brief Implementation of the Diffie-Hellman algorithm, as in RFC2631.
- *
- * @b Constructors:
- * - diffie_hellman_create()
- *
- * @ingroup crypto
+ * Implementation of the Diffie-Hellman algorithm, as in RFC2631.
*/
struct diffie_hellman_t {
/**
- * @brief Returns the shared secret of this diffie hellman exchange.
+ * Returns the shared secret of this diffie hellman exchange.
*
* Space for returned secret is allocated and must be
* freed by the caller.
*
- * @param this calling object
* @param secret shared secret will be written into this chunk
- * @return
- * - SUCCESS
- * - FAILED if not both DH values are set
+ * @return SUCCESS, FAILED if not both DH values are set
*/
status_t (*get_shared_secret) (diffie_hellman_t *this, chunk_t *secret);
/**
- * @brief Sets the public value of partner.
+ * Sets the public value of partner.
*
* Chunk gets cloned and can be destroyed afterwards.
*
- * @param this calling object
* @param value public value of partner
*/
void (*set_other_public_value) (diffie_hellman_t *this, chunk_t value);
/**
- * @brief Gets the public value of partner.
+ * Gets the public value of partner.
*
* Space for returned chunk is allocated and must be freed by the caller.
*
- * @param this calling object
* @param value public value of partner is stored at this location
- * @return
- * - SUCCESS
- * - FAILED if other public value not set
+ * @return SUCCESS, FAILED if other public value not set
*/
status_t (*get_other_public_value) (diffie_hellman_t *this, chunk_t *value);
/**
- * @brief Gets the own public value to transmit.
+ * Gets the own public value to transmit.
*
* Space for returned chunk is allocated and must be freed by the caller.
*
- * @param this calling object
* @param value public value of caller is stored at this location
*/
void (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value);
/**
- * @brief Get the DH group used.
+ * Get the DH group used.
*
- * @param this calling object
* @return DH group set in construction
*/
diffie_hellman_group_t (*get_dh_group) (diffie_hellman_t *this);
/**
- * @brief Destroys an diffie_hellman_t object.
- *
- * @param this diffie_hellman_t object to destroy
+ * Destroys an diffie_hellman_t object.
*/
void (*destroy) (diffie_hellman_t *this);
};
-/**
- * @brief Creates a new diffie_hellman_t object.
- *
- * @param group Diffie Hellman group number to use
- * @return
- * - diffie_hellman_t object
- * - NULL if dh group not supported
- *
- * @ingroup crypto
- */
-diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t group);
-
-#endif /*DIFFIE_HELLMAN_H_*/
-
+#endif /*DIFFIE_HELLMAN_H_ @} */
diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c
index 9fa778aa6..6c29d1d5d 100644
--- a/src/libstrongswan/crypto/hashers/hasher.c
+++ b/src/libstrongswan/crypto/hashers/hasher.c
@@ -1,10 +1,3 @@
-/**
- * @file hasher.c
- *
- * @brief Generic constructor for hasher_t.
- *
- */
-
/*
* Copyright (C) 2005 Jan Hutter
* Copyright (C) 2005-2006 Martin Willi
@@ -21,20 +14,16 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: hasher.c 3423 2008-01-22 10:32:37Z andreas $
+ * $Id: hasher.c 3619 2008-03-19 14:02:52Z martin $
*/
-
#include "hasher.h"
#include <asn1/oid.h>
-#include <crypto/hashers/sha1_hasher.h>
-#include <crypto/hashers/sha2_hasher.h>
-#include <crypto/hashers/md5_hasher.h>
-
ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512,
"HASH_UNKNOWN",
+ "HASH_PREFERRED",
"HASH_MD2",
"HASH_MD5",
"HASH_SHA1",
@@ -46,66 +35,31 @@ ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512,
/*
* Described in header.
*/
-hasher_t *hasher_create(hash_algorithm_t hash_algorithm)
-{
- switch (hash_algorithm)
- {
- case HASH_SHA1:
- {
- return (hasher_t*)sha1_hasher_create();
- }
- case HASH_SHA256:
- case HASH_SHA384:
- case HASH_SHA512:
- {
- return (hasher_t*)sha2_hasher_create(hash_algorithm);
- }
- case HASH_MD5:
- {
- return (hasher_t*)md5_hasher_create();
- }
- default:
- return NULL;
- }
-}
-
-/*
- * Described in header.
- */
hash_algorithm_t hasher_algorithm_from_oid(int oid)
{
- hash_algorithm_t algorithm;
-
switch (oid)
{
case OID_MD2:
case OID_MD2_WITH_RSA:
- algorithm = HASH_MD2;
- break;
+ return HASH_MD2;
case OID_MD5:
case OID_MD5_WITH_RSA:
- algorithm = HASH_MD5;
- break;
+ return HASH_MD5;
case OID_SHA1:
case OID_SHA1_WITH_RSA:
- algorithm = HASH_SHA1;
- break;
+ return HASH_SHA1;
case OID_SHA256:
case OID_SHA256_WITH_RSA:
- algorithm = HASH_SHA256;
- break;
+ return HASH_SHA256;
case OID_SHA384:
case OID_SHA384_WITH_RSA:
- algorithm = HASH_SHA384;
- break;
+ return HASH_SHA384;
case OID_SHA512:
case OID_SHA512_WITH_RSA:
- algorithm = HASH_SHA512;
- break;
+ return HASH_SHA512;
default:
- algorithm = HASH_UNKNOWN;
+ return HASH_UNKNOWN;
}
- return algorithm;
}
/*
diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h
index e73de7f01..e19b0318b 100644
--- a/src/libstrongswan/crypto/hashers/hasher.h
+++ b/src/libstrongswan/crypto/hashers/hasher.h
@@ -1,10 +1,3 @@
-/**
- * @file hasher.h
- *
- * @brief Interface hasher_t.
- *
- */
-
/*
* Copyright (C) 2005 Jan Hutter
* Copyright (C) 2005-2006 Martin Willi
@@ -21,7 +14,12 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: hasher.h 3423 2008-01-22 10:32:37Z andreas $
+ * $Id: hasher.h 3619 2008-03-19 14:02:52Z martin $
+ */
+
+/**
+ * @defgroup traffic_selector traffic_selector
+ * @{ @ingroup config
*/
#ifndef HASHER_H_
@@ -33,30 +31,19 @@ typedef struct hasher_t hasher_t;
#include <library.h>
/**
- * @brief Algorithms to use for hashing.
- *
- * Currently only the following algorithms are implemented:
- * - HASH_MD5
- * - HASH_SHA1
- * - HASH_SHA256
- * - HASH_SHA384
- * - HASH_SHA512
- *
- * @ingroup hashers
+ * Algorithms to use for hashing.
*/
enum hash_algorithm_t {
- HASH_UNKNOWN = 0,
- HASH_MD2 = 1,
- /** Implemented in class md5_hasher_t */
- HASH_MD5 = 2,
- /** Implemented in class sha1_hasher_t */
- HASH_SHA1 = 3,
- /** Implemented in class sha2_hasher_t */
- HASH_SHA256 = 4,
- /** Implemented in class sha2_hasher_t */
- HASH_SHA384 = 5,
- /** Implemented in class sha2_hasher_t */
- HASH_SHA512 = 6,
+ /** not specified hash function */
+ HASH_UNKNOWN = 0,
+ /** preferred hash function, general purpose */
+ HASH_PREFERRED = 1,
+ HASH_MD2 = 2,
+ HASH_MD5 = 3,
+ HASH_SHA1 = 4,
+ HASH_SHA256 = 5,
+ HASH_SHA384 = 6,
+ HASH_SHA512 = 7,
};
#define HASH_SIZE_MD2 16
@@ -65,7 +52,6 @@ enum hash_algorithm_t {
#define HASH_SIZE_SHA256 32
#define HASH_SIZE_SHA384 48
#define HASH_SIZE_SHA512 64
-#define HASH_SIZE_MAX 64
/**
* enum names for hash_algorithm_t.
@@ -73,16 +59,11 @@ enum hash_algorithm_t {
extern enum_name_t *hash_algorithm_names;
/**
- * @brief Generic interface for all hash functions.
- *
- * @b Constructors:
- * - hasher_create()
- *
- * @ingroup hashers
+ * Generic interface for all hash functions.
*/
struct hasher_t {
/**
- * @brief Hash data and write it in the buffer.
+ * Hash data and write it in the buffer.
*
* If the parameter hash is NULL, no result is written back
* and more data can be appended to already hashed data.
@@ -91,108 +72,63 @@ struct hasher_t {
* The hash output parameter must hold at least
* hash_t.get_block_size() bytes.
*
- * @param this calling object
- * @param data data to hash
- * @param[out] hash pointer where the hash will be written
+ * @param data data to hash
+ * @param hash pointer where the hash will be written
*/
void (*get_hash) (hasher_t *this, chunk_t data, u_int8_t *hash);
/**
- * @brief Hash data and allocate space for the hash.
+ * Hash data and allocate space for the hash.
*
* If the parameter hash is NULL, no result is written back
* and more data can be appended to already hashed data.
* If not, the result is written back and the hasher is reset.
*
- * @param this calling object
- * @param data chunk with data to hash
- * @param[out] hash chunk which will hold allocated hash
+ * @param data chunk with data to hash
+ * @param hash chunk which will hold allocated hash
*/
void (*allocate_hash) (hasher_t *this, chunk_t data, chunk_t *hash);
/**
- * @brief Get the size of the resulting hash.
+ * Get the size of the resulting hash.
*
- * @param this calling object
- * @return hash size in bytes
+ * @return hash size in bytes
*/
size_t (*get_hash_size) (hasher_t *this);
/**
- * @brief Resets the hashers state.
- *
- * @param this calling object
+ * Resets the hashers state.
*/
void (*reset) (hasher_t *this);
/**
- * @brief Get the state of the hasher.
- *
- * A hasher stores internal state information. This state may be
- * manipulated to include a "seed" into the hashing operation. It used by
- * some exotic protocols (such as AKA).
- * The data pointed by chunk may be manipulated, but not replaced nor freed.
- * This is more a hack than a feature. The hasher's state may be byte
- * order dependant; use with care.
- *
- * @param this calling object
- */
- chunk_t (*get_state) (hasher_t *this);
-
- /**
- * @brief Destroys a hasher object.
- *
- * @param this calling object
+ * Destroys a hasher object.
*/
void (*destroy) (hasher_t *this);
};
/**
- * @brief Generic interface to create a hasher_t.
+ * Conversion of ASN.1 OID to hash algorithm.
*
- * @param hash_algorithm Algorithm to use for hashing
- * @return
- * - hasher_t object
- * - NULL if algorithm not supported
- *
- * @ingroup hashers
- */
-hasher_t *hasher_create(hash_algorithm_t hash_algorithm);
-
-/**
- * @brief Conversion of ASN.1 OID to hash algorithm.
- *
- * @param oid ASN.1 OID
- * @return
- * - hash algorithm
- * - HASH_UNKNOWN if OID unsuported
- *
- * @ingroup hashers
+ * @param oid ASN.1 OID
+ * @return hash algorithm, HASH_UNKNOWN if OID unsuported
*/
hash_algorithm_t hasher_algorithm_from_oid(int oid);
/**
- * @brief Conversion of hash algorithm into ASN.1 OID.
+ * Conversion of hash algorithm into ASN.1 OID.
*
- * @param alg hash algorithm
- * @return
- * - ASN.1 hash OID if known hash algorithm
- * - OID_UNKNOW
- *
- * @ingroup hashers
+ * @param alg hash algorithm
+ * @return ASN.1 OID, or OID_UNKNOW
*/
int hasher_algorithm_to_oid(hash_algorithm_t alg);
/**
- * @brief Conversion of hash signature algorithm into ASN.1 OID.
- *
- * @param alg hash algorithm
- * @return
- * - ASN.1 signature OID if known hash algorithm
- * - OID_UNKNOW
+ * Conversion of hash signature algorithm into ASN.1 OID.
*
- * @ingroup hashers
+ * @param alg hash algorithm
+ * @return ASN.1 OID if, or OID_UNKNOW
*/
int hasher_signature_algorithm_to_oid(hash_algorithm_t alg);
-#endif /* HASHER_H_ */
+#endif /* HASHER_H_ @} */
diff --git a/src/libstrongswan/crypto/ocsp.c b/src/libstrongswan/crypto/ocsp.c
deleted file mode 100644
index 4bbec31de..000000000
--- a/src/libstrongswan/crypto/ocsp.c
+++ /dev/null
@@ -1,934 +0,0 @@
-/**
- * @file ocsp.c
- *
- * @brief Implementation of ocsp_t.
- *
- */
-
-/* Support of the Online Certificate Status Protocol (OCSP)
- *
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Copyright (C) 2007 Andreas Steffen
- *
- * Hochschule für Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT 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$
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <asn1/oid.h>
-#include <asn1/asn1.h>
-#include <utils/identification.h>
-#include <utils/randomizer.h>
-#include <utils/fetcher.h>
-#include <debug.h>
-
-#include "hashers/hasher.h"
-#include "rsa/rsa_public_key.h"
-#include "certinfo.h"
-#include "x509.h"
-#include "ocsp.h"
-
-#define NONCE_LENGTH 16
-
-typedef struct private_ocsp_t private_ocsp_t;
-
-/**
- * Private data of a ocsp_t object.
- */
-struct private_ocsp_t {
- /**
- * Public interface for this ocsp object.
- */
- ocsp_t public;
-
- /**
- * CA certificate.
- */
- x509_t *cacert;
-
- /**
- * Requestor certificate
- */
- x509_t *requestor_cert;
-
- /**
- * Linked list of ocsp uris
- */
- linked_list_t *uris;
-
- /**
- * Linked list of certinfos to be requested
- */
- linked_list_t *certinfos;
-
- /**
- * Nonce required for ocsp request and response
- */
- chunk_t nonce;
-
- /**
- * SHA-1 hash over issuer distinguished name
- */
- chunk_t authNameID;
-
- /**
- * SHA-1 hash over issuer public key
- */
- chunk_t authKeyID;
-};
-
-ENUM(response_status_names, STATUS_SUCCESSFUL, STATUS_UNAUTHORIZED,
- "successful",
- "malformed request",
- "internal error",
- "try later",
- "signature required",
- "unauthorized"
-);
-
-/* response container */
-typedef struct response_t response_t;
-
-struct response_t {
- chunk_t chunk;
- chunk_t tbs;
- identification_t *responder_id_name;
- chunk_t responder_id_key;
- time_t produced_at;
- chunk_t responses;
- chunk_t nonce;
- int algorithm;
- chunk_t signature;
- x509_t *responder_cert;
-
- /**
- * @brief Destroys the response_t object
- *
- * @param this response_t to destroy
- */
- void (*destroy) (response_t *this);
-};
-
-/**
- * Implements response_t.destroy.
- */
-static void response_destroy(response_t *this)
-{
- DESTROY_IF(this->responder_id_name);
- DESTROY_IF(this->responder_cert);
- free(this->chunk.ptr);
- free(this);
-}
-
-/**
- * Creates a response_t object
- */
-static response_t* response_create_from_chunk(chunk_t chunk)
-{
- response_t *this = malloc_thing(response_t);
-
- this->chunk = chunk;
- this->tbs = chunk_empty;
- this->responder_id_name = NULL;
- this->responder_id_key = chunk_empty;
- this->produced_at = UNDEFINED_TIME;
- this->responses = chunk_empty;
- this->nonce = chunk_empty;
- this->algorithm = OID_UNKNOWN;
- this->signature = chunk_empty;
- this->responder_cert = NULL;
-
- this->destroy = (void (*) (response_t*))response_destroy;
-
- return this;
-}
-
-/* some OCSP specific prefabricated ASN.1 constants */
-
-static u_char ASN1_nonce_oid_str[] = {
- 0x06, 0x09,
- 0x2B, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
-};
-
-static u_char ASN1_response_oid_str[] = {
- 0x06, 0x09,
- 0x2B, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
-};
-
-static u_char ASN1_response_content_str[] = {
- 0x04, 0x0D,
- 0x30, 0x0B,
- 0x06, 0x09,
- 0x2B, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
-};
-
-static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
-static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
-static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
-
-/* asn.1 definitions for parsing */
-
-static const asn1Object_t ocspResponseObjects[] = {
- { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
- { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
- { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
- { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
- { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
-};
-
-#define OCSP_RESPONSE_STATUS 1
-#define OCSP_RESPONSE_TYPE 4
-#define OCSP_RESPONSE 5
-#define OCSP_RESPONSE_ROOF 7
-
-static const asn1Object_t basicResponseObjects[] = {
- { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
- ASN1_DEF }, /* 2 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
- { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
- { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
- { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
- { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
- { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
- { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
- ASN1_DEF }, /* 16 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
- { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
- { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
- { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
- { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
- { 3, "certificate", ASN1_SEQUENCE, ASN1_RAW }, /* 24 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 26 */
-};
-
-#define BASIC_RESPONSE_TBS_DATA 1
-#define BASIC_RESPONSE_VERSION 3
-#define BASIC_RESPONSE_ID_BY_NAME 5
-#define BASIC_RESPONSE_ID_BY_KEY 8
-#define BASIC_RESPONSE_PRODUCED_AT 10
-#define BASIC_RESPONSE_RESPONSES 11
-#define BASIC_RESPONSE_EXT_ID 15
-#define BASIC_RESPONSE_CRITICAL 16
-#define BASIC_RESPONSE_EXT_VALUE 17
-#define BASIC_RESPONSE_ALGORITHM 20
-#define BASIC_RESPONSE_SIGNATURE 21
-#define BASIC_RESPONSE_CERTIFICATE 24
-#define BASIC_RESPONSE_ROOF 27
-
-static const asn1Object_t responsesObjects[] = {
- { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
-};
-
-#define RESPONSES_SINGLE_RESPONSE 1
-#define RESPONSES_ROOF 3
-
-static const asn1Object_t singleResponseObjects[] = {
- { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
- { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
- { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
- { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
- { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
- { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
- { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
- { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
- { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
- { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
- { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
- { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
- { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
- { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
- { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
- { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
- { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
- { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
- ASN1_DEF }, /* 24 */
- { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 27 */
-};
-
-#define SINGLE_RESPONSE_ALGORITHM 2
-#define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
-#define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
-#define SINGLE_RESPONSE_SERIAL_NUMBER 5
-#define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
-#define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
-#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
-#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
-#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
-#define SINGLE_RESPONSE_THIS_UPDATE 16
-#define SINGLE_RESPONSE_NEXT_UPDATE 18
-#define SINGLE_RESPONSE_EXT_ID 23
-#define SINGLE_RESPONSE_CRITICAL 24
-#define SINGLE_RESPONSE_EXT_VALUE 25
-#define SINGLE_RESPONSE_ROOF 28
-
-/**
- * build requestorName (into TBSRequest)
- */
-static chunk_t build_requestor_name(private_ocsp_t *this)
-{
- identification_t *requestor_name = this->requestor_cert->get_subject(this->requestor_cert);
-
- return asn1_wrap(ASN1_CONTEXT_C_1, "m",
- asn1_simple_object(ASN1_CONTEXT_C_4,
- requestor_name->get_encoding(requestor_name)));
-}
-
-/**
- * build request (into requestList)
- * no singleRequestExtensions used
- */
-static chunk_t build_request(private_ocsp_t *this, certinfo_t *certinfo)
-{
- chunk_t serialNumber = certinfo->get_serialNumber(certinfo);
-
- chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm",
- asn1_algorithmIdentifier(OID_SHA1),
- asn1_simple_object(ASN1_OCTET_STRING, this->authNameID),
- asn1_simple_object(ASN1_OCTET_STRING, this->authKeyID),
- asn1_simple_object(ASN1_INTEGER, serialNumber));
-
- return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
-}
-
-/**
- * build requestList (into TBSRequest)
- */
-static chunk_t build_request_list(private_ocsp_t *this)
-{
- chunk_t requestList;
- size_t datalen = 0;
- linked_list_t *request_list = linked_list_create();
-
- {
- iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
- certinfo_t *certinfo;
-
- while (iterator->iterate(iterator, (void**)&certinfo))
- {
- chunk_t *request = malloc_thing(chunk_t);
-
- *request = build_request(this, certinfo);
- request_list->insert_last(request_list, (void*)request);
- datalen += request->len;
- }
- iterator->destroy(iterator);
- }
- {
- iterator_t *iterator = request_list->create_iterator(request_list, TRUE);
- chunk_t *request;
-
- u_char *pos = build_asn1_object(&requestList, ASN1_SEQUENCE, datalen);
-
- while (iterator->iterate(iterator, (void**)&request))
- {
- memcpy(pos, request->ptr, request->len);
- pos += request->len;
- free(request->ptr);
- free(request);
- }
- iterator->destroy(iterator);
- request_list->destroy(request_list);
- }
- return requestList;
-}
-
-/**
- * build nonce extension (into requestExtensions)
- */
-static chunk_t build_nonce_extension(private_ocsp_t *this)
-{
- randomizer_t *randomizer = randomizer_create();
-
- /* generate a random nonce */
- randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_LENGTH, &this->nonce);
- randomizer->destroy(randomizer);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm",
- ASN1_nonce_oid,
- asn1_simple_object(ASN1_OCTET_STRING, this->nonce));
-}
-
-/**
- * build requestExtensions (into TBSRequest)
- */
-static chunk_t build_request_ext(private_ocsp_t *this)
-{
- return asn1_wrap(ASN1_CONTEXT_C_2, "m",
- asn1_wrap(ASN1_SEQUENCE, "mm",
- build_nonce_extension(this),
- asn1_wrap(ASN1_SEQUENCE, "cc",
- ASN1_response_oid,
- ASN1_response_content
- )
- )
- );
-}
-
-/**
- * build TBSRequest (into OCSPRequest)
- */
-static chunk_t build_tbs_request(private_ocsp_t *this, bool has_requestor_cert)
-{
- /* version is skipped since the default is ok */
- return asn1_wrap(ASN1_SEQUENCE, "mmm",
- (has_requestor_cert)? build_requestor_name(this): chunk_empty,
- build_request_list(this),
- build_request_ext(this));
-}
-
-/**
- * build signature into ocsp request
- * gets built only if a request cert with a corresponding private key is found
- */
-static chunk_t build_signature(private_ocsp_t *this, chunk_t tbsRequest)
-{
- /* TODO */
- return chunk_empty;
-}
-
-/**
- * assembles an ocsp request and sets the nonce field in private_ocsp_t to the sent nonce
- */
-static chunk_t ocsp_build_request(private_ocsp_t *this)
-{
- bool has_requestor_cert;
- chunk_t keyid = this->cacert->get_keyid(this->cacert);
- chunk_t tbsRequest, signature;
-
- DBG2("assembling ocsp request");
- DBG2("issuer: '%D'", this->cacert->get_subject(this->cacert));
- DBG2("keyid: %#B", &keyid);
-
- /* looks for requestor cert and matching private key */
- has_requestor_cert = FALSE;
-
- /* TODO has_requestor_cert = get_ocsp_requestor_cert(location); */
-
- /* build content */
- tbsRequest = build_tbs_request(this, has_requestor_cert);
-
- /* sign tbsReuqest */
- signature = (has_requestor_cert)? build_signature(this, tbsRequest): chunk_empty;
-
- return asn1_wrap(ASN1_SEQUENCE, "mm",
- tbsRequest,
- signature);
-
- return signature;
-}
-
-/**
- * parse a basic OCSP response
- */
-static bool ocsp_parse_basic_response(chunk_t blob, int level0, response_t *res)
-{
- u_int level, version;
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- int objectID = 0;
- int extn_oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < BASIC_RESPONSE_ROOF)
- {
- if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- switch (objectID)
- {
- case BASIC_RESPONSE_TBS_DATA:
- res->tbs = object;
- break;
- case BASIC_RESPONSE_VERSION:
- version = (object.len)? (1 + (u_int)*object.ptr) : 1;
- if (version != OCSP_BASIC_RESPONSE_VERSION)
- {
- DBG1("wrong ocsp basic response version (version= %i)", version);
- return FALSE;
- }
- break;
- case BASIC_RESPONSE_ID_BY_NAME:
- res->responder_id_name = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", res->responder_id_name);
- break;
- case BASIC_RESPONSE_ID_BY_KEY:
- res->responder_id_key = object;
- break;
- case BASIC_RESPONSE_PRODUCED_AT:
- res->produced_at = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case BASIC_RESPONSE_RESPONSES:
- res->responses = object;
- break;
- case BASIC_RESPONSE_EXT_ID:
- extn_oid = known_oid(object);
- break;
- case BASIC_RESPONSE_CRITICAL:
- critical = object.len && *object.ptr;
- DBG2(" %s", critical? "TRUE" : "FALSE");
- break;
- case BASIC_RESPONSE_EXT_VALUE:
- if (extn_oid == OID_NONCE)
- res->nonce = object;
- break;
- case BASIC_RESPONSE_ALGORITHM:
- res->algorithm = parse_algorithmIdentifier(object, level+1, NULL);
- break;
- case BASIC_RESPONSE_SIGNATURE:
- res->signature = object;
- break;
- case BASIC_RESPONSE_CERTIFICATE:
- {
- chunk_t blob = chunk_clone(object);
-
- res->responder_cert = x509_create_from_chunk(blob, level+1);
- }
- break;
- }
- objectID++;
- }
- return TRUE;
-}
-
-/**
- * parse an ocsp response and return the result as a response_t struct
- */
-static response_status ocsp_parse_response(response_t *res)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int ocspResponseType = OID_UNKNOWN;
- response_status rStatus = STATUS_INTERNALERROR;
-
- asn1_init(&ctx, res->chunk, 0, FALSE, FALSE);
-
- while (objectID < OCSP_RESPONSE_ROOF)
- {
- if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
- {
- return STATUS_INTERNALERROR;
- }
-
- switch (objectID)
- {
- case OCSP_RESPONSE_STATUS:
- rStatus = (response_status) *object.ptr;
- DBG2(" '%N'", response_status_names, rStatus);
-
- switch (rStatus)
- {
- case STATUS_SUCCESSFUL:
- break;
- case STATUS_MALFORMEDREQUEST:
- case STATUS_INTERNALERROR:
- case STATUS_TRYLATER:
- case STATUS_SIGREQUIRED:
- case STATUS_UNAUTHORIZED:
- DBG1("unsuccessful ocsp response: server said '%N'",
- response_status_names, rStatus);
- return rStatus;
- default:
- return STATUS_INTERNALERROR;
- }
- break;
- case OCSP_RESPONSE_TYPE:
- ocspResponseType = known_oid(object);
- break;
- case OCSP_RESPONSE:
- {
- switch (ocspResponseType)
- {
- case OID_BASIC:
- if (!ocsp_parse_basic_response(object, level+1, res))
- {
- return STATUS_INTERNALERROR;
- }
- break;
- default:
- DBG1("ocsp response is not of type BASIC");
- DBG1("ocsp response OID: %#B", &object);
- return STATUS_INTERNALERROR;
- }
- }
- break;
- }
- objectID++;
- }
- return rStatus;
-}
-
-/**
- * Check if the OCSP response has a valid signature
- */
-static bool ocsp_valid_response(response_t *res, x509_t *ocsp_cert)
-{
- rsa_public_key_t *public_key;
- time_t until = UNDEFINED_TIME;
- err_t ugh;
- hash_algorithm_t algorithm = hasher_algorithm_from_oid(res->algorithm);
-
- if (algorithm == HASH_UNKNOWN)
- {
- DBG1("unknown signature algorithm");
- return FALSE;
- }
-
- DBG2("verifying ocsp response signature:");
- DBG2("signer: '%D'", ocsp_cert->get_subject(ocsp_cert));
- DBG2("issuer: '%D'", ocsp_cert->get_issuer(ocsp_cert));
-
- ugh = ocsp_cert->is_valid(ocsp_cert, &until);
- if (ugh != NULL)
- {
- DBG1("ocsp signer certificate %s", ugh);
- return FALSE;
- }
- public_key = ocsp_cert->get_public_key(ocsp_cert);
-
- return public_key->verify_emsa_pkcs1_signature(public_key, algorithm, res->tbs, res->signature) == SUCCESS;
-}
-
-/**
- * parse a single OCSP response
- */
-static bool ocsp_parse_single_response(private_ocsp_t *this, chunk_t blob, int level0)
-{
- u_int level, extn_oid;
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- int objectID = 0;
-
- certinfo_t *certinfo = NULL;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < SINGLE_RESPONSE_ROOF)
- {
- if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- switch (objectID)
- {
- case SINGLE_RESPONSE_ALGORITHM:
- if (parse_algorithmIdentifier(object, level+1, NULL) != OID_SHA1)
- {
- DBG1("only sha-1 hash supported in ocsp single response");
- return FALSE;
- }
- break;
- case SINGLE_RESPONSE_ISSUER_NAME_HASH:
- if (!chunk_equals(object, this->authNameID))
- {
- DBG1("ocsp single response has wrong issuer name hash");
- return FALSE;
- }
- break;
- case SINGLE_RESPONSE_ISSUER_KEY_HASH:
- if (!chunk_equals(object, this->authKeyID))
- {
- DBG1("ocsp single response has wrong issuer key hash");
- return FALSE;
- }
- break;
- case SINGLE_RESPONSE_SERIAL_NUMBER:
- {
- iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
- certinfo_t *current_certinfo;
-
- while (iterator->iterate(iterator, (void**)&current_certinfo))
- {
- if (chunk_equals(object, current_certinfo->get_serialNumber(current_certinfo)))
- {
- certinfo = current_certinfo;
- }
- }
- iterator->destroy(iterator);
- if (certinfo == NULL)
- {
- DBG1("unrequested serial number in ocsp single response");
- return FALSE;
- }
- }
- break;
- case SINGLE_RESPONSE_CERT_STATUS_GOOD:
- certinfo->set_status(certinfo, CERT_GOOD);
- break;
- case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
- certinfo->set_status(certinfo, CERT_REVOKED);
- break;
- case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
- certinfo->set_revocationTime(certinfo,
- asn1totime(&object, ASN1_GENERALIZEDTIME));
- break;
- case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
- certinfo->set_revocationReason(certinfo,
- (object.len == 1) ? *object.ptr : REASON_UNSPECIFIED);
- break;
- case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
- certinfo->set_status(certinfo, CERT_UNKNOWN);
- break;
- case SINGLE_RESPONSE_THIS_UPDATE:
- certinfo->set_thisUpdate(certinfo,
- asn1totime(&object, ASN1_GENERALIZEDTIME));
- break;
- case SINGLE_RESPONSE_NEXT_UPDATE:
- certinfo->set_nextUpdate(certinfo,
- asn1totime(&object, ASN1_GENERALIZEDTIME));
- break;
- case SINGLE_RESPONSE_EXT_ID:
- extn_oid = known_oid(object);
- break;
- case SINGLE_RESPONSE_CRITICAL:
- critical = object.len && *object.ptr;
- DBG2(" %s", critical ? "TRUE" : "FALSE");
- case SINGLE_RESPONSE_EXT_VALUE:
- break;
- }
- objectID++;
- }
- return TRUE;
-}
-
-/**
- * verify and process ocsp response and update the ocsp cache
- */
-static void ocsp_process_response(private_ocsp_t *this, response_t *res, credential_store_t *credentials)
-{
- x509_t *ocsp_cert = NULL;
-
- /* parse the ocsp response without looking at the single responses yet */
- response_status status = ocsp_parse_response(res);
-
- if (status != STATUS_SUCCESSFUL)
- {
- DBG1("error in ocsp response");
- return;
- }
-
- /* check if there was a nonce in the request */
- if (this->nonce.ptr != NULL && res->nonce.ptr == NULL)
- {
- DBG1("ocsp response contains no nonce, replay attack possible");
- }
-
- /* check if the nonces are identical */
- if (res->nonce.ptr != NULL && !chunk_equals(res->nonce, this->nonce))
- {
- DBG1("invalid nonce in ocsp response");
- return;
- }
-
- /* check if we received a trusted responder certificate */
- if (res->responder_cert)
- {
- if (res->responder_cert->is_ocsp_signer(res->responder_cert))
- {
- DBG2("received certificate is ocsp signer");
- if (credentials->is_trusted(credentials, "OCSP signing", res->responder_cert))
- {
- DBG1("received ocsp signer certificate is trusted");
- ocsp_cert = credentials->add_auth_certificate(credentials,
- res->responder_cert, AUTH_OCSP);
- res->responder_cert = NULL;
- }
- else
- {
- DBG1("received ocsp signer certificate is not trusted - rejected");
- }
- }
- else
- {
- DBG1("received certificate is no ocsp signer - rejected");
- }
- }
-
- /* if we didn't receive a trusted responder cert, search the credential store */
- if (ocsp_cert == NULL)
- {
- ocsp_cert = credentials->get_auth_certificate(credentials,
- AUTH_OCSP|AUTH_CA, res->responder_id_name);
- if (ocsp_cert == NULL)
- {
- DBG1("no ocsp signer certificate found");
- return;
- }
- }
-
- /* check the response signature */
- if (!ocsp_valid_response(res, ocsp_cert))
- {
- DBG1("ocsp response signature is invalid");
- return;
- }
- DBG2("ocsp response signature is valid");
-
- /* now parse the single responses one at a time */
- {
- u_int level;
- asn1_ctx_t ctx;
- chunk_t object;
- int objectID = 0;
-
- asn1_init(&ctx, res->responses, 0, FALSE, FALSE);
-
- while (objectID < RESPONSES_ROOF)
- {
- if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
- if (objectID == RESPONSES_SINGLE_RESPONSE)
- {
- ocsp_parse_single_response(this, object, level+1);
- }
- objectID++;
- }
- }
-}
-
-/**
- * Implements ocsp_t.fetch.
- */
-static void fetch(private_ocsp_t *this, certinfo_t *certinfo, credential_store_t *credentials)
-{
- chunk_t request;
- response_t *response = NULL;
-
- if (this->uris->get_count(this->uris) == 0)
- {
- return;
- }
- this->certinfos->insert_last(this->certinfos, (void*)certinfo);
-
- request = ocsp_build_request(this);
- DBG3("ocsp request: %B", &request);
- {
- iterator_t *iterator = this->uris->create_iterator(this->uris, TRUE);
- identification_t *uri;
-
- while (iterator->iterate(iterator, (void**)&uri))
- {
- fetcher_t *fetcher;
- char uri_string[BUF_LEN];
- chunk_t uri_chunk = uri->get_encoding(uri);
- chunk_t response_chunk;
-
- snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr);
- fetcher = fetcher_create(uri_string);
-
- response_chunk = fetcher->post(fetcher, "application/ocsp-request", request);
- fetcher->destroy(fetcher);
- if (response_chunk.ptr != NULL)
- {
- response = response_create_from_chunk(response_chunk);
- break;
- }
- }
- iterator->destroy(iterator);
- }
- free(request.ptr);
-
- if (response == NULL)
- {
- return;
- }
- DBG3("ocsp response: %B", &response->chunk);
- ocsp_process_response(this, response, credentials);
- response->destroy(response);
-}
-
-/**
- * Implements ocsp_t.destroy.
- */
-static void destroy(private_ocsp_t *this)
-{
- this->certinfos->destroy(this->certinfos);
- free(this->authNameID.ptr);
- free(this->nonce.ptr);
- free(this);
-}
-
-/*
- * Described in header.
- */
-ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris)
-{
- private_ocsp_t *this = malloc_thing(private_ocsp_t);
-
- /* initialize */
- this->cacert = cacert;
- this->uris = uris;
- this->certinfos = linked_list_create();
- this->nonce = chunk_empty;
- this->authKeyID = cacert->get_subjectKeyID(cacert);
- {
- hasher_t *hasher = hasher_create(HASH_SHA1);
- identification_t *issuer = cacert->get_subject(cacert);
-
- hasher->allocate_hash(hasher, issuer->get_encoding(issuer),
- &this->authNameID);
- hasher->destroy(hasher);
- }
-
- /* public functions */
- this->public.fetch = (void (*) (ocsp_t*,certinfo_t*,credential_store_t*))fetch;
- this->public.destroy = (void (*) (ocsp_t*))destroy;
-
- return &this->public;
-}
diff --git a/src/libstrongswan/crypto/ocsp.h b/src/libstrongswan/crypto/ocsp.h
deleted file mode 100644
index e468bb8be..000000000
--- a/src/libstrongswan/crypto/ocsp.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * @file ocsp.h
- *
- * @brief Interface of ocsp_t
- *
- */
-
-/* Support of the Online Certificate Status Protocol (OCSP) Support
- *
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Copyright (C) 2007 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT 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$
- */
-
-#ifndef OCSP_H_
-#define OCSP_H_
-
-typedef struct ocsp_t ocsp_t;
-
-#include <credential_store.h>
-#include <utils/linked_list.h>
-
-#include "certinfo.h"
-
-/* constants */
-#define OCSP_BASIC_RESPONSE_VERSION 1
-#define OCSP_DEFAULT_VALID_TIME 120 /* validity of one-time response in seconds */
-#define OCSP_WARNING_INTERVAL 2 /* days */
-
-/* OCSP response status */
-typedef enum {
- STATUS_SUCCESSFUL = 0,
- STATUS_MALFORMEDREQUEST = 1,
- STATUS_INTERNALERROR = 2,
- STATUS_TRYLATER = 3,
- STATUS_SIGREQUIRED = 5,
- STATUS_UNAUTHORIZED= 6
-} response_status;
-
-/**
- * @brief Online Certficate Status Protocol (OCSP)
- *
- * @ingroup transforms
- */
-struct ocsp_t {
-
- /**
- * @brief Fetches the actual certificate status via OCSP
- *
- * @param uris linked list of ocsp uris
- * @param certinfo certificate status info to be updated
- * @param credentials credential store needed for trust path verification
- */
- void (*fetch) (ocsp_t *this, certinfo_t *certinfo, credential_store_t *credentials);
-
- /**
- * @brief Destroys the ocsp_t object.
- *
- * @param this ocsp object to destroy
- */
- void (*destroy) (ocsp_t *this);
-
-};
-
-/**
- * @brief Create an ocsp_t object.
- *
- * @param cacert ca certificate
- * @param uris linked list of ocsp uris
- * @return created ocsp_t object
- *
- * @ingroup transforms
- */
-ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris);
-
-#endif /* OCSP_H_ */
diff --git a/src/libstrongswan/crypto/pkcs7.c b/src/libstrongswan/crypto/pkcs7.c
deleted file mode 100644
index 48d3e2d78..000000000
--- a/src/libstrongswan/crypto/pkcs7.c
+++ /dev/null
@@ -1,1077 +0,0 @@
-/**
- * @file pkcs7.c
- *
- * @brief Implementation of pkcs7_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT 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: pkcs7.c 3438 2008-02-02 00:29:03Z andreas $
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <library.h>
-#include "debug.h"
-
-#include <asn1/asn1.h>
-#include <asn1/oid.h>
-#include <crypto/x509.h>
-#include <crypto/pkcs9.h>
-#include <crypto/hashers/hasher.h>
-#include <crypto/crypters/crypter.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <utils/randomizer.h>
-#include <utils/linked_list.h>
-
-#include "pkcs7.h"
-
-typedef struct private_pkcs7_t private_pkcs7_t;
-
-/**
- * Private data of a pkcs7_t object.
- */
-struct private_pkcs7_t {
- /**
- * Public interface for this certificate.
- */
- pkcs7_t public;
-
- /**
- * contentInfo type
- */
- int type;
-
- /**
- * ASN.1 encoded content
- */
- chunk_t content;
-
- /**
- * Has the content already been parsed?
- */
- bool parsed;
-
- /**
- * ASN.1 parsing start level
- */
- u_int level;
-
- /**
- * retrieved data
- */
- chunk_t data;
-
- /**
- * ASN.1 encoded attributes
- */
- pkcs9_t *attributes;
-
- /**
- * Linked list of X.509 certificates
- */
- linked_list_t *certs;
-};
-
-/**
- * ASN.1 definition of the PKCS#7 ContentInfo type
- */
-static const asn1Object_t contentInfoObjects[] = {
- { 0, "contentInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "contentType", ASN1_OID, ASN1_BODY }, /* 1 */
- { 1, "content", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
-};
-
-#define PKCS7_INFO_TYPE 1
-#define PKCS7_INFO_CONTENT 2
-#define PKCS7_INFO_ROOF 4
-
-/**
- * ASN.1 definition of the PKCS#7 signedData type
- */
-static const asn1Object_t signedDataObjects[] = {
- { 0, "signedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "digestAlgorithms", ASN1_SET, ASN1_LOOP }, /* 2 */
- { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 3 */
- { 1, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
- { 1, "contentInfo", ASN1_EOC, ASN1_RAW }, /* 5 */
- { 1, "certificates", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_LOOP }, /* 6 */
- { 2, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 7 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 8 */
- { 1, "crls", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_LOOP }, /* 9 */
- { 2, "crl", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 11 */
- { 1, "signerInfos", ASN1_SET, ASN1_LOOP }, /* 12 */
- { 2, "signerInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 14 */
- { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 15 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 16 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 17 */
- { 3, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 18 */
- { 3, "authenticatedAttributes", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_OBJ }, /* 19 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
- { 3, "digestEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 21 */
- { 3, "encryptedDigest", ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */
- { 3, "unauthenticatedAttributes", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 23 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 24 */
- { 1, "end loop", ASN1_EOC, ASN1_END } /* 25 */
-};
-
-#define PKCS7_DIGEST_ALG 3
-#define PKCS7_SIGNED_CONTENT_INFO 5
-#define PKCS7_SIGNED_CERT 7
-#define PKCS7_SIGNER_INFO 13
-#define PKCS7_SIGNED_ISSUER 16
-#define PKCS7_SIGNED_SERIAL_NUMBER 17
-#define PKCS7_DIGEST_ALGORITHM 18
-#define PKCS7_AUTH_ATTRIBUTES 19
-#define PKCS7_DIGEST_ENC_ALGORITHM 21
-#define PKCS7_ENCRYPTED_DIGEST 22
-#define PKCS7_SIGNED_ROOF 26
-
-/**
- * ASN.1 definition of the PKCS#7 envelopedData type
- */
-static const asn1Object_t envelopedDataObjects[] = {
- { 0, "envelopedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "recipientInfos", ASN1_SET, ASN1_LOOP }, /* 2 */
- { 2, "recipientInfo", ASN1_SEQUENCE, ASN1_BODY }, /* 3 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 7 */
- { 3, "encryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 8 */
- { 3, "encryptedKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 9 */
- { 1, "end loop", ASN1_EOC, ASN1_END }, /* 10 */
- { 1, "encryptedContentInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
- { 2, "contentType", ASN1_OID, ASN1_BODY }, /* 12 */
- { 2, "contentEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 13 */
- { 2, "encryptedContent", ASN1_CONTEXT_S_0, ASN1_BODY } /* 14 */
-};
-
-#define PKCS7_ENVELOPED_VERSION 1
-#define PKCS7_RECIPIENT_INFO_VERSION 4
-#define PKCS7_ISSUER 6
-#define PKCS7_SERIAL_NUMBER 7
-#define PKCS7_ENCRYPTION_ALG 8
-#define PKCS7_ENCRYPTED_KEY 9
-#define PKCS7_CONTENT_TYPE 12
-#define PKCS7_CONTENT_ENC_ALGORITHM 13
-#define PKCS7_ENCRYPTED_CONTENT 14
-#define PKCS7_ENVELOPED_ROOF 15
-
-/**
- * PKCS7 contentInfo OIDs
- */
-static u_char ASN1_pkcs7_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01
-};
-
-static u_char ASN1_pkcs7_signed_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02
-};
-
-static u_char ASN1_pkcs7_enveloped_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03
-};
-
-static u_char ASN1_pkcs7_signed_enveloped_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x04
-};
-
-static u_char ASN1_pkcs7_digested_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x05
-};
-
-static char ASN1_pkcs7_encrypted_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06
-};
-
-static const chunk_t ASN1_pkcs7_data_oid =
- chunk_from_buf(ASN1_pkcs7_data_oid_str);
-static const chunk_t ASN1_pkcs7_signed_data_oid =
- chunk_from_buf(ASN1_pkcs7_signed_data_oid_str);
-static const chunk_t ASN1_pkcs7_enveloped_data_oid =
- chunk_from_buf(ASN1_pkcs7_enveloped_data_oid_str);
-static const chunk_t ASN1_pkcs7_signed_enveloped_data_oid =
- chunk_from_buf(ASN1_pkcs7_signed_enveloped_data_oid_str);
-static const chunk_t ASN1_pkcs7_digested_data_oid =
- chunk_from_buf(ASN1_pkcs7_digested_data_oid_str);
-static const chunk_t ASN1_pkcs7_encrypted_data_oid =
- chunk_from_buf(ASN1_pkcs7_encrypted_data_oid_str);
-
-/**
- * 3DES and DES encryption OIDs
- */
-static u_char ASN1_3des_ede_cbc_oid_str[] = {
- 0x06, 0x08,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07
-};
-
-static u_char ASN1_des_cbc_oid_str[] = {
- 0x06, 0x05,
- 0x2B, 0x0E, 0x03, 0x02, 0x07
-};
-
-static const chunk_t ASN1_3des_ede_cbc_oid =
- chunk_from_buf(ASN1_3des_ede_cbc_oid_str);
-static const chunk_t ASN1_des_cbc_oid =
- chunk_from_buf(ASN1_des_cbc_oid_str);
-
-/**
- * Implements pkcs7_t.is_data.
- */
-static bool is_data(private_pkcs7_t *this)
-{
- return this->type == OID_PKCS7_DATA;
-}
-
-/**
- * Implements pkcs7_t.is_signedData.
- */
-static bool is_signedData(private_pkcs7_t *this)
-{
- return this->type == OID_PKCS7_SIGNED_DATA;
-}
-
-/**
- * Implements pkcs7_t.is_envelopedData.
- */
-static bool is_envelopedData(private_pkcs7_t *this)
-{
- return this->type == OID_PKCS7_ENVELOPED_DATA;
-}
-
-/**
- * Check whether to abort the requested parsing
- */
-static bool abort_parsing(private_pkcs7_t *this, int type)
-{
- if (this->type != type)
- {
- DBG1("pkcs7 content to be parsed is not of type '%s'",
- oid_names[type]);
- return TRUE;
- }
- if (this->parsed)
- {
- DBG1("pkcs7 content has already been parsed");
- return TRUE;
- }
- this->parsed = TRUE;
- return FALSE;
-}
-
-/**
- * Implements pkcs7_t.parse_data.
- */
-static bool parse_data(private_pkcs7_t *this)
-{
- chunk_t data = this->content;
-
- if (abort_parsing(this, OID_PKCS7_DATA))
- {
- return FALSE;
- }
- if (data.len == 0)
- {
- this->data = chunk_empty;
- return TRUE;
- }
- if (parse_asn1_simple_object(&data, ASN1_OCTET_STRING, this->level, "data"))
- {
- this->data = chunk_clone(data);
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-/**
- * Implements pkcs7_t.parse_signedData.
- */
-static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- int digest_alg = OID_UNKNOWN;
- int enc_alg = OID_UNKNOWN;
- int signerInfos = 0;
-
- chunk_t encrypted_digest = chunk_empty;
-
- if (abort_parsing(this, OID_PKCS7_SIGNED_DATA))
- {
- return FALSE;
- }
-
- asn1_init(&ctx, this->content, this->level, FALSE, FALSE);
-
- while (objectID < PKCS7_SIGNED_ROOF)
- {
- if (!extract_object(signedDataObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- switch (objectID)
- {
- case PKCS7_DIGEST_ALG:
- digest_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_SIGNED_CONTENT_INFO:
- {
- chunk_t pureData;
- pkcs7_t *data = pkcs7_create_from_chunk(object, level+1);
-
- if (data == NULL)
- {
- return FALSE;
- }
- if (!data->parse_data(data))
- {
- data->destroy(data);
- return FALSE;
- }
- pureData = data->get_data(data);
- this->data = (pureData.len)? chunk_clone(pureData) : chunk_empty;
- data->destroy(data);
- }
- break;
- case PKCS7_SIGNED_CERT:
- {
- x509_t *cert = x509_create_from_chunk(chunk_clone(object), level+1);
-
- if (cert)
- {
- this->certs->insert_last(this->certs, (void*)cert);
- }
- }
- break;
- case PKCS7_SIGNER_INFO:
- signerInfos++;
- DBG2(" signer #%d", signerInfos);
- break;
- case PKCS7_SIGNED_ISSUER:
- {
- identification_t *issuer;
-
- issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", issuer);
- issuer->destroy(issuer);
- }
- break;
- case PKCS7_AUTH_ATTRIBUTES:
- *object.ptr = ASN1_SET;
- this->attributes = pkcs9_create_from_chunk(object, level+1);
- *object.ptr = ASN1_CONTEXT_C_0;
- break;
- case PKCS7_DIGEST_ALGORITHM:
- digest_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_DIGEST_ENC_ALGORITHM:
- enc_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_ENCRYPTED_DIGEST:
- encrypted_digest = object;
- }
- objectID++;
- }
-
- /* check the signature only if a cacert is available */
- if (cacert != NULL)
- {
- hash_algorithm_t algorithm = hasher_algorithm_from_oid(digest_alg);
- rsa_public_key_t *signer = cacert->get_public_key(cacert);
-
- if (signerInfos == 0)
- {
- DBG1("no signerInfo object found");
- return FALSE;
- }
- else if (signerInfos > 1)
- {
- DBG1("more than one signerInfo object found");
- return FALSE;
- }
- if (this->attributes == NULL)
- {
- DBG1("no authenticatedAttributes object found");
- return FALSE;
- }
- if (enc_alg != OID_RSA_ENCRYPTION)
- {
- DBG1("only RSA digest encryption supported");
- return FALSE;
- }
- if (signer->verify_emsa_pkcs1_signature(signer, algorithm,
- this->attributes->get_encoding(this->attributes), encrypted_digest) != SUCCESS)
- {
- DBG1("invalid digest signature");
- return FALSE;
- }
- else
- {
- DBG2("digest signature is valid");
- }
- if (this->data.ptr != NULL)
- {
- chunk_t messageDigest = this->attributes->get_messageDigest(this->attributes);
-
- if (messageDigest.ptr == NULL)
- {
- DBG1("messageDigest attribute not found");
- return FALSE;
- }
- else
- {
- hasher_t *hasher = hasher_create(algorithm);
- chunk_t hash;
- bool valid;
-
- hasher->allocate_hash(hasher, this->data, &hash);
- hasher->destroy(hasher);
- DBG3("hash: %B", &hash);
-
- valid = chunk_equals(messageDigest, hash);
- free(messageDigest.ptr);
- free(hash.ptr);
- if (valid)
- {
- DBG2("messageDigest is valid");
- }
- else
- {
- DBG1("invalid messageDigest");
- return FALSE;
- }
- }
- }
- }
- return TRUE;
-}
-
-/**
- * Parse PKCS#7 envelopedData content
- */
-static bool parse_envelopedData(private_pkcs7_t *this, chunk_t serialNumber,
- rsa_private_key_t *key)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- chunk_t iv = chunk_empty;
- chunk_t symmetric_key = chunk_empty;
- chunk_t encrypted_content = chunk_empty;
-
- crypter_t *crypter = NULL;
-
- if (abort_parsing(this, OID_PKCS7_ENVELOPED_DATA))
- {
- return FALSE;
- }
-
- asn1_init(&ctx, this->content, this->level, FALSE, FALSE);
-
- while (objectID < PKCS7_ENVELOPED_ROOF)
- {
- if (!extract_object(envelopedDataObjects, &objectID, &object, &level, &ctx))
- {
- goto failed;
- }
-
- switch (objectID)
- {
- case PKCS7_ENVELOPED_VERSION:
- if (*object.ptr != 0)
- {
- DBG1("envelopedData version is not 0");
- goto failed;
- }
- break;
- case PKCS7_RECIPIENT_INFO_VERSION:
- if (*object.ptr != 0)
- {
- DBG1("recipient info version is not 0");
- goto failed;
- }
- break;
- case PKCS7_ISSUER:
- {
- identification_t *issuer;
-
- issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", issuer);
- issuer->destroy(issuer);
- }
- break;
- case PKCS7_SERIAL_NUMBER:
- if (!chunk_equals(serialNumber, object))
- {
- DBG1("serial numbers do not match");
- goto failed;
- }
- break;
- case PKCS7_ENCRYPTION_ALG:
- {
- int alg = parse_algorithmIdentifier(object, level, NULL);
-
- if (alg != OID_RSA_ENCRYPTION)
- {
- DBG1("only rsa encryption supported");
- goto failed;
- }
- }
- break;
- case PKCS7_ENCRYPTED_KEY:
- if (key->pkcs1_decrypt(key, object, &symmetric_key) != SUCCESS)
- {
- DBG1("symmetric key could not be decrypted with rsa");
- goto failed;
- }
- DBG4("symmetric key : %B", &symmetric_key);
- break;
- case PKCS7_CONTENT_TYPE:
- if (known_oid(object) != OID_PKCS7_DATA)
- {
- DBG1("encrypted content not of type pkcs7 data");
- goto failed;
- }
- break;
- case PKCS7_CONTENT_ENC_ALGORITHM:
- {
- int alg = parse_algorithmIdentifier(object, level, &iv);
-
- switch (alg)
- {
- case OID_DES_CBC:
- crypter = crypter_create(ENCR_DES, 0);
- break;
- case OID_3DES_EDE_CBC:
- crypter = crypter_create(ENCR_3DES, 0);
- break;
- default:
- DBG1("Only DES and 3DES supported for symmetric encryption");
- goto failed;
- }
- if (symmetric_key.len != crypter->get_key_size(crypter))
- {
- DBG1("symmetric key has wrong length");
- goto failed;
- }
- if (!parse_asn1_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
- {
- DBG1("IV could not be parsed");
- goto failed;
- }
- if (iv.len != crypter->get_block_size(crypter))
- {
- DBG1("IV has wrong length");
- goto failed;
- }
- }
- break;
- case PKCS7_ENCRYPTED_CONTENT:
- encrypted_content = object;
- break;
- }
- objectID++;
- }
-
- /* decrypt the content */
- crypter->set_key(crypter, symmetric_key);
- crypter->decrypt(crypter, encrypted_content, iv, &this->data);
- DBG3("decrypted content with padding: %B", &this->data);
-
- /* remove the padding */
- {
- u_char *pos = this->data.ptr + this->data.len - 1;
- u_char pattern = *pos;
- size_t padding = pattern;
-
- if (padding > this->data.len)
- {
- DBG1("padding greater than data length");
- goto failed;
- }
- this->data.len -= padding;
-
- while (padding-- > 0)
- {
- if (*pos-- != pattern)
- {
- DBG1("wrong padding pattern");
- goto failed;
- }
- }
- }
- crypter->destroy(crypter);
- free(symmetric_key.ptr);
- return TRUE;
-
-failed:
- DESTROY_IF(crypter);
- free(symmetric_key.ptr);
- chunk_free(&this->data);
- return FALSE;
-}
-
-/**
- * Implements pkcs7_t.get_data.
- */
-static chunk_t get_data(private_pkcs7_t *this)
-{
- return this->data;
-}
-
-/**
- * Implements pkcs7_t.get_contentInfo.
- */
-static chunk_t get_contentInfo(private_pkcs7_t *this)
-{
- chunk_t content_type;
-
- /* select DER-encoded OID for pkcs7_contentInfo type */
- switch(this->type)
- {
- case OID_PKCS7_DATA:
- content_type = ASN1_pkcs7_data_oid;
- break;
- case OID_PKCS7_SIGNED_DATA:
- content_type = ASN1_pkcs7_signed_data_oid;
- break;
- case OID_PKCS7_ENVELOPED_DATA:
- content_type = ASN1_pkcs7_enveloped_data_oid;
- break;
- case OID_PKCS7_SIGNED_ENVELOPED_DATA:
- content_type = ASN1_pkcs7_signed_enveloped_data_oid;
- break;
- case OID_PKCS7_DIGESTED_DATA:
- content_type = ASN1_pkcs7_digested_data_oid;
- break;
- case OID_PKCS7_ENCRYPTED_DATA:
- content_type = ASN1_pkcs7_encrypted_data_oid;
- break;
- case OID_UNKNOWN:
- default:
- DBG1("invalid pkcs7 contentInfo type");
- return chunk_empty;
- }
-
- return (this->content.ptr == NULL)
- ? asn1_simple_object(ASN1_SEQUENCE, content_type)
- : asn1_wrap(ASN1_SEQUENCE, "cm",
- content_type,
- asn1_simple_object(ASN1_CONTEXT_C_0, this->content)
- );
-}
-
-/**
- * Implements pkcs7_t.create_certificate_iterator
- */
-static iterator_t *create_certificate_iterator(const private_pkcs7_t *this)
-{
- return this->certs->create_iterator(this->certs, TRUE);
-}
-
-/**
- * Implements pkcs7_t.set_certificate
- */
-static void set_certificate(private_pkcs7_t *this, x509_t *cert)
-{
- if (cert)
- {
- /* TODO the certificate is currently not cloned */
- this->certs->insert_last(this->certs, cert);
- }
-}
-
-/**
- * Implements pkcs7_t.set_attributes
- */
-static void set_attributes(private_pkcs7_t *this, pkcs9_t *attributes)
-{
- this->attributes = attributes;
-}
-
-/**
- * build a DER-encoded issuerAndSerialNumber object
- */
-chunk_t pkcs7_build_issuerAndSerialNumber(x509_t *cert)
-{
- identification_t *issuer = cert->get_issuer(cert);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm",
- issuer->get_encoding(issuer),
- asn1_simple_object(ASN1_INTEGER, cert->get_serialNumber(cert)));
-}
-
-/**
- * Implements pkcs7_t.build_envelopedData.
- */
-bool build_envelopedData(private_pkcs7_t *this, x509_t *cert,
- encryption_algorithm_t alg)
-{
- chunk_t iv, symmetricKey, in, out, alg_oid;
- crypter_t *crypter;
-
- /* select OID of symmetric encryption algorithm */
- switch (alg)
- {
- case ENCR_DES:
- alg_oid = ASN1_des_cbc_oid;
- break;
- case ENCR_3DES:
- alg_oid = ASN1_3des_ede_cbc_oid;
- break;
- default:
- DBG1(" encryption algorithm %N not supported",
- encryption_algorithm_names, alg);
- return FALSE;
- }
-
- crypter = crypter_create(alg, 0);
- if (crypter == NULL)
- {
- DBG1(" could not create crypter for algorithm %N",
- encryption_algorithm_names, alg);
- return FALSE;
- }
-
- /* generate a true random symmetric encryption key
- * and a pseudo-random iv
- */
- {
- randomizer_t *randomizer = randomizer_create();
-
- randomizer->allocate_random_bytes(randomizer,
- crypter->get_key_size(crypter), &symmetricKey);
- DBG4(" symmetric encryption key: %B", &symmetricKey);
-
- randomizer->allocate_pseudo_random_bytes(randomizer,
- crypter->get_block_size(crypter), &iv);
- DBG4(" initialization vector: %B", &iv);
-
- randomizer->destroy(randomizer);
- }
-
- /* pad the data so that the total length becomes
- * a multiple of the block size
- */
- {
- size_t block_size = crypter->get_block_size(crypter);
- size_t padding = block_size - this->data.len % block_size;
-
- in.len = this->data.len + padding;
- in.ptr = malloc(in.len);
-
- DBG2(" padding %d bytes of data to multiple block size of %d bytes",
- (int)this->data.len, (int)in.len);
-
- /* copy data */
- memcpy(in.ptr, this->data.ptr, this->data.len);
- /* append padding */
- memset(in.ptr + this->data.len, padding, padding);
- }
- DBG3(" padded unencrypted data: %B", &in);
-
- /* symmetric encryption of data object */
- crypter->set_key(crypter, symmetricKey);
- crypter->encrypt(crypter, in, iv, &out);
- crypter->destroy(crypter);
- chunk_free_randomized(&in);
- DBG3(" encrypted data: %B", &out);
-
- /* build pkcs7 enveloped data object */
- {
- chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "cm",
- alg_oid,
- asn1_wrap(ASN1_OCTET_STRING, "m", iv));
-
- chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "cmm",
- ASN1_pkcs7_data_oid,
- contentEncryptionAlgorithm,
- asn1_wrap(ASN1_CONTEXT_S_0, "m", out));
-
- chunk_t wrappedKey, encryptedKey, recipientInfo;
-
- rsa_public_key_t *public_key = cert->get_public_key(cert);
-
- public_key->pkcs1_encrypt(public_key, symmetricKey, &wrappedKey);
- chunk_free_randomized(&symmetricKey);
-
- encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m", wrappedKey);
-
- recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmcm",
- ASN1_INTEGER_0,
- pkcs7_build_issuerAndSerialNumber(cert),
- asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
- encryptedKey);
-
- this->content = asn1_wrap(ASN1_SEQUENCE, "cmm",
- ASN1_INTEGER_0,
- asn1_wrap(ASN1_SET, "m", recipientInfo),
- encryptedContentInfo);
- this->type = OID_PKCS7_ENVELOPED_DATA;
- }
- return TRUE;
-}
-
-/**
- * Implements pkcs7_t.build_signedData.
- */
-bool build_signedData(private_pkcs7_t *this, rsa_private_key_t *private_key,
- hash_algorithm_t alg)
-{
- int signature_oid = hasher_signature_algorithm_to_oid(alg);
- chunk_t authenticatedAttributes = chunk_empty;
- chunk_t encryptedDigest = chunk_empty;
- chunk_t signerInfo;
- x509_t *cert;
-
- if (this->certs->get_first(this->certs, (void**)&cert) != SUCCESS)
- {
- DBG1(" no pkcs7 signer certificate found");
- return FALSE;
- }
-
- if (this->attributes != NULL)
- {
- if (this->data.ptr != NULL)
- {
- /* take the current time as signingTime */
- time_t now = time(NULL);
- chunk_t signingTime = timetoasn1(&now, ASN1_UTCTIME);
-
- chunk_t messageDigest, attributes;
- hasher_t *hasher = hasher_create(alg);
-
- hasher->allocate_hash(hasher, this->data, &messageDigest);
- hasher->destroy(hasher);
- this->attributes->set_attribute(this->attributes,
- OID_PKCS9_CONTENT_TYPE, ASN1_pkcs7_data_oid);
- this->attributes->set_messageDigest(this->attributes,
- messageDigest);
- this->attributes->set_attribute(this->attributes,
- OID_PKCS9_SIGNING_TIME, signingTime);
- attributes = this->attributes->get_encoding(this->attributes);
-
- free(messageDigest.ptr);
- free(signingTime.ptr);
-
- private_key->build_emsa_pkcs1_signature(private_key, alg,
- attributes, &encryptedDigest);
- authenticatedAttributes = chunk_clone(attributes);
- *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0;
- }
- }
- else if (this->data.ptr != NULL)
- {
- private_key->build_emsa_pkcs1_signature(private_key, alg,
- this->data, &encryptedDigest);
- }
- if (encryptedDigest.ptr)
- {
- encryptedDigest = asn1_wrap(ASN1_OCTET_STRING, "m", encryptedDigest);
- }
-
- signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmcmcm",
- ASN1_INTEGER_1,
- pkcs7_build_issuerAndSerialNumber(cert),
- asn1_algorithmIdentifier(signature_oid),
- authenticatedAttributes,
- asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
- encryptedDigest);
-
- if (this->data.ptr != NULL)
- {
- this->content = asn1_simple_object(ASN1_OCTET_STRING, this->data);
- chunk_free(&this->data);
- }
- this->type = OID_PKCS7_DATA;
- this->data = get_contentInfo(this);
- chunk_free(&this->content);
-
- this->type = OID_PKCS7_SIGNED_DATA;
-
- this->content = asn1_wrap(ASN1_SEQUENCE, "cmcmm",
- ASN1_INTEGER_1,
- asn1_simple_object(ASN1_SET, asn1_algorithmIdentifier(signature_oid)),
- this->data,
- asn1_simple_object(ASN1_CONTEXT_C_0, cert->get_certificate(cert)),
- asn1_wrap(ASN1_SET, "m", signerInfo));
-
- return TRUE;
-}
-
-/**
- * Implements pkcs7_t.destroy
- */
-static void destroy(private_pkcs7_t *this)
-{
- DESTROY_IF(this->attributes);
- this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy));
- free(this->content.ptr);
- free(this->data.ptr);
- free(this);
-}
-
-/**
- * Parse PKCS#7 contentInfo object
- */
-static bool parse_contentInfo(chunk_t blob, u_int level0, private_pkcs7_t *cInfo)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < PKCS7_INFO_ROOF)
- {
- if (!extract_object(contentInfoObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- if (objectID == PKCS7_INFO_TYPE)
- {
- cInfo->type = known_oid(object);
- if (cInfo->type < OID_PKCS7_DATA
- || cInfo->type > OID_PKCS7_ENCRYPTED_DATA)
- {
- DBG1("unknown pkcs7 content type");
- return FALSE;
- }
- }
- else if (objectID == PKCS7_INFO_CONTENT && object.len > 0)
- {
- cInfo->content = chunk_clone(object);
- }
- objectID++;
- }
- return TRUE;
-}
-
-/**
- * Generic private constructor
- */
-static private_pkcs7_t *pkcs7_create_empty(void)
-{
- private_pkcs7_t *this = malloc_thing(private_pkcs7_t);
-
- /* initialize */
- this->type = OID_UNKNOWN;
- this->content = chunk_empty;
- this->parsed = FALSE;
- this->level = 0;
- this->data = chunk_empty;
- this->attributes = NULL;
- this->certs = linked_list_create();
-
- /*public functions */
- this->public.is_data = (bool (*) (pkcs7_t*))is_data;
- this->public.is_signedData = (bool (*) (pkcs7_t*))is_signedData;
- this->public.is_envelopedData = (bool (*) (pkcs7_t*))is_envelopedData;
- this->public.parse_data = (bool (*) (pkcs7_t*))parse_data;
- this->public.parse_signedData = (bool (*) (pkcs7_t*,x509_t*))parse_signedData;
- this->public.parse_envelopedData = (bool (*) (pkcs7_t*,chunk_t,rsa_private_key_t*))parse_envelopedData;
- this->public.get_data = (chunk_t (*) (pkcs7_t*))get_data;
- this->public.get_contentInfo = (chunk_t (*) (pkcs7_t*))get_contentInfo;
- this->public.create_certificate_iterator = (iterator_t* (*) (pkcs7_t*))create_certificate_iterator;
- this->public.set_certificate = (void (*) (pkcs7_t*,x509_t*))set_certificate;
- this->public.set_attributes = (void (*) (pkcs7_t*,pkcs9_t*))set_attributes;
- this->public.build_envelopedData = (bool (*) (pkcs7_t*,x509_t*,encryption_algorithm_t))build_envelopedData;
- this->public.build_signedData = (bool (*) (pkcs7_t*,rsa_private_key_t*,hash_algorithm_t))build_signedData;
- this->public.destroy = (void (*) (pkcs7_t*))destroy;
-
- return this;
-}
-
-/*
- * Described in header.
- */
-pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level)
-{
- private_pkcs7_t *this = pkcs7_create_empty();
-
- this->level = level + 2;
- if (!parse_contentInfo(chunk, level, this))
- {
- destroy(this);
- return NULL;
- }
- return &this->public;
-}
-
-/*
- * Described in header.
- */
-pkcs7_t *pkcs7_create_from_data(chunk_t data)
-{
- private_pkcs7_t *this = pkcs7_create_empty();
-
- this->data = chunk_clone(data);
- this->parsed = TRUE;
-
- return &this->public;
-}
-
-/*
- * Described in header.
- */
-pkcs7_t *pkcs7_create_from_file(const char *filename, const char *label)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
- char cert_label[BUF_LEN];
- pkcs7_t *pkcs7;
-
- snprintf(cert_label, BUF_LEN, "%s pkcs7", label);
-
- if (!pem_asn1_load_file(filename, NULL, cert_label, &chunk, &pgp))
- {
- return NULL;
- }
-
- pkcs7 = pkcs7_create_from_chunk(chunk, 0);
- free(chunk.ptr);
- return pkcs7;
-}
diff --git a/src/libstrongswan/crypto/pkcs7.h b/src/libstrongswan/crypto/pkcs7.h
deleted file mode 100644
index 74bd25361..000000000
--- a/src/libstrongswan/crypto/pkcs7.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * @file pkcs7.h
- *
- * @brief Interface of pkcs7_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT 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: pkcs7.h 3437 2008-02-01 22:26:01Z andreas $
- */
-
-#ifndef _PKCS7_H
-#define _PKCS7_H
-
-typedef struct pkcs7_t pkcs7_t;
-
-#include <library.h>
-#include <crypto/x509.h>
-#include <crypto/pkcs9.h>
-#include <crypto/rsa/rsa_private_key.h>
-#include <crypto/crypters/crypter.h>
-#include <utils/iterator.h>
-
-/**
- * @brief PKCS#7 contentInfo object.
- *
- * @b Constructors:
- * -pkcs7_create_from_chunk()
- * -pkcs7_create_from_data()
- *
- * @ingroup crypto
- */
-struct pkcs7_t {
- /**
- * @brief Check if the PKCS#7 contentType is data
- *
- * @param this calling object
- * @return TRUE if the contentType is data
- */
- bool (*is_data) (pkcs7_t *this);
-
- /**
- * @brief Check if the PKCS#7 contentType is signedData
- *
- * @param this calling object
- * @return TRUE if the contentType is signedData
- */
- bool (*is_signedData) (pkcs7_t *this);
-
- /**
- * @brief Check if the PKCS#7 contentType is envelopedData
- *
- * @param this calling object
- * @return TRUE if the contentType is envelopedData
- */
- bool (*is_envelopedData) (pkcs7_t *this);
-
- /**
- * @brief Parse a PKCS#7 data content.
- *
- * @param this calling object
- * @return TRUE if parsing was successful
- */
- bool (*parse_data) (pkcs7_t *this);
-
- /**
- * @brief Parse a PKCS#7 signedData content.
- *
- * @param this calling object
- * @param cacert cacert used to verify the signature
- * @return TRUE if parsing was successful
- */
- bool (*parse_signedData) (pkcs7_t *this, x509_t *cacert);
-
- /**
- * @brief Parse a PKCS#7 envelopedData content.
- *
- * @param this calling object
- * @param serialNumber serialNumber of the request
- * @param key RSA private key used to decrypt the symmetric key
- * @return TRUE if parsing was successful
- */
- bool (*parse_envelopedData) (pkcs7_t *this, chunk_t serialNumber, rsa_private_key_t *key);
-
- /**
- * @brief Returns the parsed data object
- *
- * @param this calling object
- * @return chunk containing the data object
- */
- chunk_t (*get_data) (pkcs7_t *this);
-
- /**
- * @brief Returns the a DER-encoded contentInfo object
- *
- * @param this calling object
- * @return chunk containing the contentInfo object
- */
- chunk_t (*get_contentInfo) (pkcs7_t *this);
-
- /**
- * @brief Create an iterator for the certificates.
- *
- * @param this calling object
- * @return iterator for the certificates
- */
- iterator_t *(*create_certificate_iterator) (pkcs7_t *this);
-
- /**
- * @brief Add a certificate.
- *
- * @param this calling object
- * @param cert certificate to be included
- */
- void (*set_certificate) (pkcs7_t *this, x509_t *cert);
-
- /**
- * @brief Add authenticated attributes.
- *
- * @param this calling object
- * @param attributes attributes to be included
- */
- void (*set_attributes) (pkcs7_t *this, pkcs9_t *attributes);
-
- /**
- * @brief Build a data object
- *
- * @param this PKCS#7 data to be built
- * @return TRUE if build was successful
- */
- bool (*build_data) (pkcs7_t *this);
-
- /**
- * @brief Build an envelopedData object
- *
- * @param this PKCS#7 data object to envelop
- * @param cert receivers's certificate
- * @param alg encryption algorithm
- * @return TRUE if build was successful
- */
- bool (*build_envelopedData) (pkcs7_t *this, x509_t *cert, encryption_algorithm_t alg);
-
- /**
- * @brief Build an signedData object
- *
- * @param this PKCS#7 data object to sign
- * @param key signer's RSA private key
- * @param alg digest algorithm used for signature
- * @return TRUE if build was successful
- */
- bool (*build_signedData) (pkcs7_t *this, rsa_private_key_t *key, hash_algorithm_t alg);
-
- /**
- * @brief Destroys the contentInfo object.
- *
- * @param this PKCS#7 contentInfo object to destroy
- */
- void (*destroy) (pkcs7_t *this);
-};
-
-/**
- * @brief Read a PKCS#7 contentInfo object from a DER encoded chunk.
- *
- * @param chunk chunk containing DER encoded data
- * @param level ASN.1 parsing start level
- * @return created pkcs7_contentInfo object, or NULL if invalid.
- *
- * @ingroup crypto
- */
-pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level);
-
-/**
- * @brief Create a PKCS#7 contentInfo object
- *
- * @param chunk chunk containing data
- * @return created pkcs7_contentInfo object.
- *
- * @ingroup crypto
- */
-pkcs7_t *pkcs7_create_from_data(chunk_t data);
-
-/**
- * @brief Read a X.509 certificate from a DER encoded file.
- *
- * @param filename file containing DER encoded data
- * @param label label describing kind of PKCS#7 file
- * @return created pkcs7_t object, or NULL if invalid.
- *
- * @ingroup crypto
- */
-pkcs7_t *pkcs7_create_from_file(const char *filename, const char *label);
-
-
-#endif /* _PKCS7_H */
diff --git a/src/libstrongswan/crypto/pkcs9.c b/src/libstrongswan/crypto/pkcs9.c
index 1003c9011..1c1b5a586 100644
--- a/src/libstrongswan/crypto/pkcs9.c
+++ b/src/libstrongswan/crypto/pkcs9.c
@@ -1,13 +1,5 @@
-/**
- * @file pkcs9.c
- *
- * @brief Implementation of pkcs9_t.
- *
- */
-
/*
* Copyright (C)2008 Andreas Steffen
- *
* Hochschule fuer Technik Rapperswil, Switzerland
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: pkcs7.c 3423 2008-01-22 10:32:37Z andreas $
+ * $Id: pkcs9.c 3891 2008-04-28 16:00:52Z andreas $
*/
#include <library.h>
@@ -28,6 +20,7 @@
#include <asn1/oid.h>
#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
#include <utils/linked_list.h>
#include "pkcs9.h"
@@ -84,22 +77,6 @@ struct attribute_t {
};
-/* ASN.1 definition of the X.501 atttribute type */
-
-static const asn1Object_t attributesObjects[] = {
- { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */
- { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */
- { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */
- { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
-};
-
-#define ATTRIBUTE_OBJ_TYPE 2
-#define ATTRIBUTE_OBJ_VALUE 4
-#define ATTRIBUTE_OBJ_ROOF 7
-
/**
* PKCS#9 attribute type OIDs
*/
@@ -267,7 +244,7 @@ static void build_encoding(private_pkcs9_t *this)
/* allocate memory for the attributes and build the encoding */
{
- u_char *pos = build_asn1_object(&this->encoding, ASN1_SET, attributes_len);
+ u_char *pos = asn1_build_object(&this->encoding, ASN1_SET, attributes_len);
iterator = this->attributes->create_iterator(this->attributes, TRUE);
@@ -335,7 +312,8 @@ static chunk_t get_messageDigest(private_pkcs9_t *this)
{
return chunk_empty;
}
- if (!parse_asn1_simple_object(&value, asn1_attributeType(oid), 0, oid_names[oid].name))
+ if (!asn1_parse_simple_object(&value, asn1_attributeType(oid), 0,
+ oid_names[oid].name))
{
return chunk_empty;
}
@@ -398,29 +376,41 @@ pkcs9_t *pkcs9_create(void)
}
/**
+ * ASN.1 definition of the X.501 atttribute type
+ */
+static const asn1Object_t attributesObjects[] = {
+ { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */
+ { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */
+ { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */
+ { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define ATTRIBUTE_OBJ_TYPE 2
+#define ATTRIBUTE_OBJ_VALUE 4
+
+/**
* Parse a PKCS#9 attribute list
*/
static bool parse_attributes(chunk_t chunk, int level0, private_pkcs9_t* this)
{
- asn1_ctx_t ctx;
+ asn1_parser_t *parser;
chunk_t object;
- u_int level;
+ int objectID;
int oid = OID_UNKNOWN;
- int objectID = 0;
+ bool success = FALSE;
- asn1_init(&ctx, chunk, level0, FALSE, FALSE);
+ parser = asn1_parser_create(attributesObjects, chunk);
+ parser->set_top_level(parser, level0);
- while (objectID < ATTRIBUTE_OBJ_ROOF)
+ while (parser->iterate(parser, &objectID, &object))
{
- if (!extract_object(attributesObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
switch (objectID)
{
case ATTRIBUTE_OBJ_TYPE:
- oid = known_oid(object);
+ oid = asn1_known_oid(object);
break;
case ATTRIBUTE_OBJ_VALUE:
if (oid == OID_UNKNOWN)
@@ -431,7 +421,8 @@ static bool parse_attributes(chunk_t chunk, int level0, private_pkcs9_t* this)
{
attribute_t *attribute = attribute_create(oid, object);
- this->attributes->insert_last(this->attributes, (void*)attribute);
+ this->attributes->insert_last(this->attributes,
+ (void*)attribute);
}
/* parse known attributes */
{
@@ -439,16 +430,21 @@ static bool parse_attributes(chunk_t chunk, int level0, private_pkcs9_t* this)
if (type != ASN1_EOC)
{
- if (!parse_asn1_simple_object(&object, type, level+1, oid_names[oid].name))
+ if (!asn1_parse_simple_object(&object, type,
+ parser->get_level(parser)+1,
+ oid_names[oid].name))
{
- return FALSE;
+ goto end;
}
}
}
}
- objectID++;
}
- return TRUE;
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
}
diff --git a/src/libstrongswan/crypto/pkcs9.h b/src/libstrongswan/crypto/pkcs9.h
index 44915720c..89cdec83d 100644
--- a/src/libstrongswan/crypto/pkcs9.h
+++ b/src/libstrongswan/crypto/pkcs9.h
@@ -1,13 +1,5 @@
-/**
- * @file pkcs7.h
- *
- * @brief Interface of pkcs9_t.
- *
- */
-
/*
- * Copyright (C) 2008 Andreas Steffen
- *
+ * Copyright (C) 2008 Andreas Steffen
* Hochschule fuer Technik Rapperswil, Switzerland
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,102 +12,89 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: pkcs7.h 3423 2008-01-22 10:32:37Z andreas $
+ * $Id: pkcs9.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup pkcs9 pkcs9
+ * @{ @ingroup crypto
*/
-#ifndef _PKCS9_H
-#define _PKCS9_H
+#ifndef PKCS9_H_
+#define PKCS9_H_
typedef struct pkcs9_t pkcs9_t;
#include <library.h>
/**
- * @brief PKCS#9 .
- *
- * @b Constructors:
- * -pkcs9_create_from_chunk()
- * -pkcs9_create()
- *
- * @ingroup crypto
+ * PKCS#9 attributes.
*/
struct pkcs9_t {
+
/**
- * @brief generate ASN.1 encoding of attribute list
- *
- * @param this PKCS#9 attribute list to be encoded
+ * Generate ASN.1 encoding of attribute list
*/
void (*build_encoding) (pkcs9_t *this);
/**
- * @brief gets ASN.1 encoding of PKCS#9 attribute list
+ * Gets ASN.1 encoding of PKCS#9 attribute list
*
- * @param this calling object
* @return ASN.1 encoded PKCSI#9 list
*/
chunk_t (*get_encoding) (pkcs9_t *this);
/**
- * @brief gets a PKCS#9 attribute
+ * Gets a PKCS#9 attribute
*
- * @param this calling object
* @param oid OID of the attribute
* @return ASN.1 encoded value of the attribute
*/
chunk_t (*get_attribute) (pkcs9_t *this, int oid);
/**
- * @brief adds a PKCS#9 attribute
+ * Adds a PKCS#9 attribute
*
- * @param this calling object
* @param oid OID of the attribute
* @param value ASN.1 encoded value of the attribute
*/
void (*set_attribute) (pkcs9_t *this, int oid, chunk_t value);
/**
- * @brief gets a PKCS#9 messageDigest attribute
+ * Gets a PKCS#9 messageDigest attribute
*
- * @param this calling object
* @return messageDigest
*/
chunk_t (*get_messageDigest) (pkcs9_t *this);
/**
- * @brief add a PKCS#9 messageDigest attribute
+ * Add a PKCS#9 messageDigest attribute
*
- * @param this calling object
* @param value messageDigest
*/
void (*set_messageDigest) (pkcs9_t *this, chunk_t value);
/**
- * @brief Destroys the PKCS#9 attribute list.
- *
- * @param this PKCS#9 attribute list to destroy
+ * Destroys the PKCS#9 attribute list.
*/
void (*destroy) (pkcs9_t *this);
};
/**
- * @brief Read a PKCS#9 attribute list from a DER encoded chunk.
+ * Read a PKCS#9 attribute list from a DER encoded chunk.
*
* @param chunk chunk containing DER encoded data
* @param level ASN.1 parsing start level
* @return created pkcs9 attribute list, or NULL if invalid.
- *
- * @ingroup crypto
*/
pkcs9_t *pkcs9_create_from_chunk(chunk_t chunk, u_int level);
/**
- * @brief Create an empty PKCS#9 attribute list
+ * Create an empty PKCS#9 attribute list
*
* @param chunk chunk containing data
* @return created pkcs9 attribute list.
- *
- * @ingroup crypto
*/
pkcs9_t *pkcs9_create(void);
-#endif /* _PKCS9_H */
+#endif /* PKCS9_H_ @} */
diff --git a/src/libstrongswan/crypto/prf_plus.c b/src/libstrongswan/crypto/prf_plus.c
index 6bd444b1f..de7dbff84 100644
--- a/src/libstrongswan/crypto/prf_plus.c
+++ b/src/libstrongswan/crypto/prf_plus.c
@@ -1,10 +1,3 @@
-/**
- * @file prf_plus.c
- *
- * @brief Implementation of prf_plus_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: prf_plus.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <string.h>
diff --git a/src/libstrongswan/crypto/prf_plus.h b/src/libstrongswan/crypto/prf_plus.h
index 90f9ce2eb..e63827858 100644
--- a/src/libstrongswan/crypto/prf_plus.h
+++ b/src/libstrongswan/crypto/prf_plus.h
@@ -1,10 +1,3 @@
-/**
- * @file prf_plus.h
- *
- * @brief Interface for prf_plus.h.
- *
- */
-
/*
* 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: prf_plus.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup prf_plus prf_plus
+ * @{ @ingroup crypto
*/
#ifndef PRF_PLUS_H_
@@ -29,53 +29,43 @@ typedef struct prf_plus_t prf_plus_t;
#include <crypto/prfs/prf.h>
/**
- * @brief Implementation of the prf+ function described in IKEv2 RFC.
+ * Implementation of the prf+ function described in IKEv2 RFC.
*
* This class implements the prf+ algorithm. Internally it uses a pseudo random
* function, which implements the prf_t interface.
- *
* See IKEv2 RFC 2.13.
- *
- * @b Constructors:
- * - prf_plus_create()
- *
- * @ingroup transforms
*/
struct prf_plus_t {
/**
- * @brief Get pseudo random bytes.
+ * Get pseudo random bytes.
*
* Get the next few bytes of the prf+ output. Space
* must be allocated by the caller.
*
- * @param this calling object
- * @param length number of bytes to get
- * @param[out] buffer pointer where the generated bytes will be written
+ * @param length number of bytes to get
+ * @param buffer pointer where the generated bytes will be written
*/
void (*get_bytes) (prf_plus_t *this, size_t length, u_int8_t *buffer);
/**
- * @brief Allocate pseudo random bytes.
+ * Allocate pseudo random bytes.
*
* Get the next few bytes of the prf+ output. This function
* will allocate the required space.
*
- * @param this calling object
- * @param length number of bytes to get
- * @param[out] chunk chunk which will hold generated bytes
+ * @param length number of bytes to get
+ * @param chunk chunk which will hold generated bytes
*/
void (*allocate_bytes) (prf_plus_t *this, size_t length, chunk_t *chunk);
/**
- * @brief Destroys a prf_plus_t object.
- *
- * @param this calling object
+ * Destroys a prf_plus_t object.
*/
void (*destroy) (prf_plus_t *this);
};
/**
- * @brief Creates a new prf_plus_t object.
+ * Creates a new prf_plus_t object.
*
* Seed will be cloned. prf will
* not be cloned, must be destroyed outside after
@@ -84,9 +74,7 @@ struct prf_plus_t {
* @param prf prf object to use
* @param seed input seed for prf
* @return prf_plus_t object
- *
- * @ingroup transforms
*/
prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed);
-#endif /*PRF_PLUS_H_*/
+#endif /*PRF_PLUS_H_ @} */
diff --git a/src/libstrongswan/crypto/prfs/prf.c b/src/libstrongswan/crypto/prfs/prf.c
index f803829af..812f6278d 100644
--- a/src/libstrongswan/crypto/prfs/prf.c
+++ b/src/libstrongswan/crypto/prfs/prf.c
@@ -1,10 +1,3 @@
-/**
- * @file prf.c
- *
- * @brief Generic constructor for all prf_t
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,20 +12,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: prf.c 3619 2008-03-19 14:02:52Z martin $
*/
-
#include "prf.h"
-#include <crypto/hashers/hasher.h>
-#include <crypto/prfs/hmac_prf.h>
-#include <crypto/prfs/fips_prf.h>
-
-ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_FIPS_DES,
+ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_KEYED_SHA1,
"PRF_UNDEFINED",
"PRF_FIPS_SHA1_160",
- "PRF_FIPS_DES");
-ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_FIPS_DES,
+ "PRF_FIPS_DES",
+ "PRF_KEYED_SHA1");
+ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_KEYED_SHA1,
"PRF_HMAC_MD5",
"PRF_HMAC_SHA1",
"PRF_HMAC_TIGER",
@@ -42,29 +33,3 @@ ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_FIP
"PRF_HMAC_SHA2_512");
ENUM_END(pseudo_random_function_names, PRF_HMAC_SHA2_512);
-/*
- * Described in header.
- */
-prf_t *prf_create(pseudo_random_function_t pseudo_random_function)
-{
- switch (pseudo_random_function)
- {
- case PRF_HMAC_SHA1:
- return (prf_t*)hmac_prf_create(HASH_SHA1);
- case PRF_HMAC_MD5:
- return (prf_t*)hmac_prf_create(HASH_MD5);
- case PRF_HMAC_SHA2_256:
- return (prf_t*)hmac_prf_create(HASH_SHA256);
- case PRF_HMAC_SHA2_384:
- return (prf_t*)hmac_prf_create(HASH_SHA384);
- case PRF_HMAC_SHA2_512:
- return (prf_t*)hmac_prf_create(HASH_SHA512);
- case PRF_FIPS_SHA1_160:
- return (prf_t*)fips_prf_create(20, g_sha1);
- case PRF_FIPS_DES:
- case PRF_HMAC_TIGER:
- case PRF_AES128_CBC:
- default:
- return NULL;
- }
-}
diff --git a/src/libstrongswan/crypto/prfs/prf.h b/src/libstrongswan/crypto/prfs/prf.h
index 8560a4a9c..324eb89b4 100644
--- a/src/libstrongswan/crypto/prfs/prf.h
+++ b/src/libstrongswan/crypto/prfs/prf.h
@@ -1,10 +1,3 @@
-/**
- * @file prf.h
- *
- * @brief Interface prf_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: prf.h 3916 2008-05-08 12:43:27Z martin $
+ */
+
+/**
+ * @defgroup prf prf
+ * @{ @ingroup crypto
*/
#ifndef PRF_H_
@@ -30,12 +30,10 @@ typedef struct prf_t prf_t;
#include <library.h>
/**
- * @brief Pseudo random function, as in IKEv2 RFC 3.3.2.
+ * Pseudo random function, as in IKEv2 RFC 3.3.2.
*
* PRF algorithms not defined in IKEv2 are allocated in "private use"
* space.
- *
- * @ingroup prfs
*/
enum pseudo_random_function_t {
PRF_UNDEFINED = 1024,
@@ -44,7 +42,7 @@ enum pseudo_random_function_t {
/** Implemented via hmac_prf_t. */
PRF_HMAC_SHA1 = 2,
PRF_HMAC_TIGER = 3,
- PRF_AES128_CBC = 4,
+ PRF_AES128_XCBC = 4,
/** Implemented via hmac_prf_t. */
PRF_HMAC_SHA2_256 = 5,
/** Implemented via hmac_prf_t. */
@@ -55,6 +53,11 @@ enum pseudo_random_function_t {
PRF_FIPS_SHA1_160 = 1025,
/** Could be implemented via fips_prf_t, uses fixed output size of 160bit */
PRF_FIPS_DES = 1026,
+ /**
+ * Keyed hash algorithm using SHA1, used in EAP-AKA:
+ * This PRF uses SHA1, but XORs the key into the IV. No "Final()" operation
+ * is applied to the SHA1 state. */
+ PRF_KEYED_SHA1 = 1027,
};
/**
@@ -63,80 +66,53 @@ enum pseudo_random_function_t {
extern enum_name_t *pseudo_random_function_names;
/**
- * @brief Generic interface for pseudo-random-functions.
- *
- * @b Constructors:
- * - prf_create()
- * - hmac_prf_create()
- *
- * @todo Implement more prf algorithms
- *
- * @ingroup prfs
+ * Generic interface for pseudo-random-functions.
*/
struct prf_t {
/**
- * @brief Generates pseudo random bytes and writes them in the buffer.
+ * Generates pseudo random bytes and writes them in the buffer.
*
- * @param this calling object
- * @param seed a chunk containing the seed for the next bytes
- * @param[out] buffer pointer where the generated bytes will be written
+ * @param seed a chunk containing the seed for the next bytes
+ * @param buffer pointer where the generated bytes will be written
*/
void (*get_bytes) (prf_t *this, chunk_t seed, u_int8_t *buffer);
/**
- * @brief Generates pseudo random bytes and allocate space for them.
+ * Generates pseudo random bytes and allocate space for them.
*
- * @param this calling object
- * @param seed a chunk containing the seed for the next bytes
- * @param[out] chunk chunk which will hold generated bytes
+ * @param seed a chunk containing the seed for the next bytes
+ * @param chunk chunk which will hold generated bytes
*/
void (*allocate_bytes) (prf_t *this, chunk_t seed, chunk_t *chunk);
/**
- * @brief Get the block size of this prf_t object.
+ * Get the block size of this prf_t object.
*
- * @param this calling object
- * @return block size in bytes
+ * @return block size in bytes
*/
size_t (*get_block_size) (prf_t *this);
/**
- * @brief Get the key size of this prf_t object.
+ * Get the key size of this prf_t object.
*
* This is a suggestion only, all implemented PRFs accept variable key
* length.
*
- * @param this calling object
- * @return key size in bytes
+ * @return key size in bytes
*/
size_t (*get_key_size) (prf_t *this);
/**
- * @brief Set the key for this prf_t object.
+ * Set the key for this prf_t object.
*
- * @param this calling object
- * @param key key to set
+ * @param key key to set
*/
void (*set_key) (prf_t *this, chunk_t key);
/**
- * @brief Destroys a prf object.
- *
- * @param this calling object
+ * Destroys a prf object.
*/
void (*destroy) (prf_t *this);
};
-/**
- * @brief Generic constructor for a prf_t oject.
- *
- * @param pseudo_random_function Algorithm to use
- * @return
- * - prf_t object
- * - NULL if prf algorithm not supported
- *
- * @ingroup prfs
- */
-prf_t *prf_create(pseudo_random_function_t pseudo_random_function);
-
-#endif /*PRF_H_*/
+#endif /*PRF_H_ @} */
diff --git a/src/libstrongswan/crypto/rngs/rng.c b/src/libstrongswan/crypto/rngs/rng.c
new file mode 100644
index 000000000..435e043e8
--- /dev/null
+++ b/src/libstrongswan/crypto/rngs/rng.c
@@ -0,0 +1,24 @@
+/*
+ * 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 "rng.h"
+
+ENUM(rng_quality_names, RNG_WEAK, RNG_REAL,
+ "RNG_WEAK",
+ "RNG_STRONG",
+ "RNG_REAL",
+);
diff --git a/src/libstrongswan/crypto/rngs/rng.h b/src/libstrongswan/crypto/rngs/rng.h
new file mode 100644
index 000000000..08f7af209
--- /dev/null
+++ b/src/libstrongswan/crypto/rngs/rng.h
@@ -0,0 +1,75 @@
+/*
+ * 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: rng.h 3619 2008-03-19 14:02:52Z martin $
+ */
+
+/**
+ * @defgroup rng rng
+ * @{ @ingroup crypto
+ */
+
+#ifndef RNG_H_
+#define RNG_H_
+
+typedef enum rng_quality_t rng_quality_t;
+typedef struct rng_t rng_t;
+
+#include <library.h>
+
+/**
+ * Quality of generated random bytes.
+ */
+enum rng_quality_t {
+ /** weak randomness, usable for nonces, IVs */
+ RNG_WEAK,
+ /** stronger randomness, usable for session keys */
+ RNG_STRONG,
+ /** real random, key material */
+ RNG_REAL,
+};
+
+/**
+ * enum name for rng_quality_t.
+ */
+extern enum_name_t *rng_quality_names;
+
+/**
+ * Generic interface for random number generators.
+ */
+struct rng_t {
+
+ /**
+ * Generates random bytes and writes them in the buffer.
+ *
+ * @param len number of bytes to get
+ * @param buffer pointer where the generated bytes will be written
+ */
+ void (*get_bytes) (rng_t *this, u_int len, u_int8_t *buffer);
+
+ /**
+ * Generates random bytes and allocate space for them.
+ *
+ * @param len number of bytes to get
+ * @param chunk chunk which will hold generated bytes
+ */
+ void (*allocate_bytes) (rng_t *this, u_int len, chunk_t *chunk);
+
+ /**
+ * Destroys a rng object.
+ */
+ void (*destroy) (rng_t *this);
+};
+
+#endif /*RNG_H_ @} */
diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.c b/src/libstrongswan/crypto/rsa/rsa_private_key.c
deleted file mode 100644
index 1b1499887..000000000
--- a/src/libstrongswan/crypto/rsa/rsa_private_key.c
+++ /dev/null
@@ -1,722 +0,0 @@
-/**
- * @file rsa_private_key.c
- *
- * @brief Implementation of rsa_private_key_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: rsa_private_key.c 3429 2008-01-27 20:59:22Z andreas $
- */
-
-#include <gmp.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "rsa_public_key.h"
-#include "rsa_private_key.h"
-
-#include <debug.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <utils/randomizer.h>
-
-/**
- * defined in rsa_public_key.c
- */
-extern chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e);
-extern chunk_t rsa_public_key_id_create(const mpz_t n, const mpz_t e);
-
-/**
- * Public exponent to use for key generation.
- */
-#define PUBLIC_EXPONENT 0x10001
-
-typedef struct private_rsa_private_key_t private_rsa_private_key_t;
-
-/**
- * Private data of a rsa_private_key_t object.
- */
-struct private_rsa_private_key_t {
- /**
- * Public interface for this signer.
- */
- rsa_private_key_t public;
-
- /**
- * Version of key, as encoded in PKCS#1
- */
- u_int version;
-
- /**
- * Public modulus.
- */
- mpz_t n;
-
- /**
- * Public exponent.
- */
- mpz_t e;
-
- /**
- * Private prime 1.
- */
- mpz_t p;
-
- /**
- * Private Prime 2.
- */
- mpz_t q;
-
- /**
- * Private exponent.
- */
- mpz_t d;
-
- /**
- * Private exponent 1.
- */
- mpz_t exp1;
-
- /**
- * Private exponent 2.
- */
- mpz_t exp2;
-
- /**
- * Private coefficient.
- */
- mpz_t coeff;
-
- /**
- * Keysize in bytes.
- */
- size_t k;
-
- /**
- * Keyid formed as a SHA-1 hash of a publicKeyInfo object
- */
- chunk_t keyid;
-
- /**
- * @brief Implements the RSADP algorithm specified in PKCS#1.
- *
- * @param this calling object
- * @param data data to process
- * @return processed data
- */
- chunk_t (*rsadp) (private_rsa_private_key_t *this, chunk_t data);
-
- /**
- * @brief Implements the RSASP1 algorithm specified in PKCS#1.
- * @param this calling object
- * @param data data to process
- * @return processed data
- */
- chunk_t (*rsasp1) (private_rsa_private_key_t *this, chunk_t data);
-};
-
-/* ASN.1 definition of a PKCS#1 RSA private key */
-static const asn1Object_t privkey_objects[] = {
- { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
- { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
- { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
- { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
- { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
- { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
- { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 10 */
- { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
- { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
- { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
- { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END } /* 15 */
-};
-
-#define PRIV_KEY_VERSION 1
-#define PRIV_KEY_MODULUS 2
-#define PRIV_KEY_PUB_EXP 3
-#define PRIV_KEY_PRIV_EXP 4
-#define PRIV_KEY_PRIME1 5
-#define PRIV_KEY_PRIME2 6
-#define PRIV_KEY_EXP1 7
-#define PRIV_KEY_EXP2 8
-#define PRIV_KEY_COEFF 9
-#define PRIV_KEY_ROOF 16
-
-/**
- * Auxiliary function overwriting private key material with
- * pseudo-random bytes before releasing it
- */
-static void mpz_clear_randomized(mpz_t z)
-{
- size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE;
- u_int8_t *random_bytes = alloca(len);
-
- randomizer_t *randomizer = randomizer_create();
-
- randomizer->get_pseudo_random_bytes(randomizer, len, random_bytes);
-
- /* overwrite mpz_t with pseudo-random bytes before clearing it */
- mpz_import(z, len, 1, 1, 1, 0, random_bytes);
- mpz_clear(z);
-
- randomizer->destroy(randomizer);
-}
-
-/**
- * Generate a random prime number with prime_len bytes
- */
-static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_len, mpz_t *prime)
-{
- randomizer_t *randomizer;
- chunk_t random_bytes;
- status_t status;
-
- randomizer = randomizer_create();
- mpz_init(*prime);
-
- do
- {
- DBG1(" generating %d bit prime from %s ...", BITS_PER_BYTE * prime_len, DEV_RANDOM);
- status = randomizer->allocate_random_bytes(randomizer, prime_len, &random_bytes);
- if (status != SUCCESS)
- {
- randomizer->destroy(randomizer);
- mpz_clear(*prime);
- return FAILED;
- }
-
- /* make sure most significant bit is set */
- random_bytes.ptr[0] = random_bytes.ptr[0] | 0x80;
-
- /* convert chunk to mpz value */
- mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
-
- /* get next prime */
- mpz_nextprime (*prime, *prime);
-
- /* free the random_bytes after overwriting them with a pseudo-random sequence */
- chunk_free_randomized(&random_bytes);
- }
- /* check if it isnt too large */
- while (((mpz_sizeinbase(*prime, 2) + 7) / BITS_PER_BYTE) > prime_len);
-
- randomizer->destroy(randomizer);
- return SUCCESS;
-}
-
-/**
- * Implementation of private_rsa_private_key_t.rsadp and private_rsa_private_key_t.rsasp1.
- */
-static chunk_t rsadp(private_rsa_private_key_t *this, chunk_t data)
-{
- mpz_t t1, t2;
- chunk_t decrypted;
-
- mpz_init(t1);
- mpz_init(t2);
-
- mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr);
-
- mpz_powm(t2, t1, this->exp1, this->p); /* m1 = c^dP mod p */
- mpz_powm(t1, t1, this->exp2, this->q); /* m2 = c^dQ mod Q */
- mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
- mpz_mod(t2, t2, this->p);
- mpz_mul(t2, t2, this->coeff);
- mpz_mod(t2, t2, this->p);
-
- mpz_mul(t2, t2, this->q); /* m = m2 + h q */
- mpz_add(t1, t1, t2);
-
- decrypted.len = this->k;
- decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1);
-
- mpz_clear_randomized(t1);
- mpz_clear_randomized(t2);
-
- return decrypted;
-}
-
-/**
- * Implementation of rsa_private_key_t.pkcs1_decrypt.
- */
-static status_t pkcs1_decrypt(private_rsa_private_key_t *this,
- chunk_t in, chunk_t *out)
-{
- status_t status = FAILED;
- chunk_t em, em_ori;
-
- /* decrypt the input data */
- em = em_ori = this->rsadp(this, in);
-
- /* PKCS#1 v1.5 EME encryption formatting
- * EM = 00 || 02 || PS || 00 || M
- * PS = pseudo-random nonzero octets
- */
-
- /* check for magic bytes */
- if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x02)
- {
- DBG1("incorrect padding - probably wrong RSA key");
- goto end;
- }
- em.ptr += 2;
- em.len -= 2;
-
- /* the plaintext data starts after first 0x00 byte */
- while (em.len-- > 0 && *em.ptr++ != 0x00);
-
- if (em.len == 0)
- {
- DBG1("no plaintext data found");
- goto end;
- }
-
- *out = chunk_clone(em);
- status = SUCCESS;
-
-end:
- free(em_ori.ptr);
- return status;
-}
-
-/**
- * Implementation of rsa_private_key_t.build_emsa_pkcs1_signature.
- */
-static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this,
- hash_algorithm_t hash_algorithm,
- chunk_t data, chunk_t *signature)
-{
- hasher_t *hasher;
- chunk_t em, digestInfo, hash;
- int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
-
- if (hash_oid == OID_UNKNOWN)
- {
- return NOT_SUPPORTED;
- }
-
- /* get hasher */
- hasher = hasher_create(hash_algorithm);
- if (hasher == NULL)
- {
- return NOT_SUPPORTED;
- }
-
- /* build hash */
- hasher->allocate_hash(hasher, data, &hash);
- hasher->destroy(hasher);
-
- /* build DER-encoded digestInfo */
- digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
- asn1_algorithmIdentifier(hash_oid),
- asn1_simple_object(ASN1_OCTET_STRING, hash)
- );
- chunk_free(&hash);
-
- /* build chunk to rsa-decrypt:
- * EM = 0x00 || 0x01 || PS || 0x00 || T.
- * PS = 0xFF padding, with length to fill em
- * T = encoded_hash
- */
- em.len = this->k;
- em.ptr = malloc(em.len);
-
- /* fill em with padding */
- memset(em.ptr, 0xFF, em.len);
- /* set magic bytes */
- *(em.ptr) = 0x00;
- *(em.ptr+1) = 0x01;
- *(em.ptr + em.len - digestInfo.len - 1) = 0x00;
- /* set DER-encoded hash */
- memcpy(em.ptr + em.len - digestInfo.len, digestInfo.ptr, digestInfo.len);
-
- /* build signature */
- *signature = this->rsasp1(this, em);
-
- free(digestInfo.ptr);
- free(em.ptr);
-
- return SUCCESS;
-}
-
-/**
- * Implementation of rsa_private_key_t.pkcs1_write.
- */
-static bool pkcs1_write(private_rsa_private_key_t *this, const char *filename, bool force)
-{
- bool status;
-
- chunk_t pkcs1 = asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm",
- ASN1_INTEGER_0,
- asn1_integer_from_mpz(this->n),
- asn1_integer_from_mpz(this->e),
- asn1_integer_from_mpz(this->d),
- asn1_integer_from_mpz(this->p),
- asn1_integer_from_mpz(this->q),
- asn1_integer_from_mpz(this->exp1),
- asn1_integer_from_mpz(this->exp2),
- asn1_integer_from_mpz(this->coeff));
-
- status = chunk_write(pkcs1, filename, "pkcs1", 0066, force);
- chunk_free_randomized(&pkcs1);
- return status;
-}
-
-/**
- * Implementation of rsa_private_key_t.get_public_key.
- */
-rsa_public_key_t *get_public_key(private_rsa_private_key_t *this)
-{
- return rsa_public_key_create(this->n, this->e);
-}
-
-/**
- * Implementation of rsa_private_key.belongs_to.
- */
-static bool belongs_to(private_rsa_private_key_t *this, rsa_public_key_t *public)
-{
- return chunk_equals(this->keyid, public->get_keyid(public));
-}
-
-/**
- * Check the loaded key if it is valid and usable
- * TODO: Log errors
- */
-static status_t check(private_rsa_private_key_t *this)
-{
- mpz_t t, u, q1;
- status_t status = SUCCESS;
-
- /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
- * We actually require more (for security).
- */
- if (this->k < 512 / BITS_PER_BYTE)
- {
- return FAILED;
- }
-
- /* we picked a max modulus size to simplify buffer allocation */
- if (this->k > 8192 / BITS_PER_BYTE)
- {
- return FAILED;
- }
-
- mpz_init(t);
- mpz_init(u);
- mpz_init(q1);
-
- /* check that n == p * q */
- mpz_mul(u, this->p, this->q);
- if (mpz_cmp(u, this->n) != 0)
- {
- status = FAILED;
- }
-
- /* check that e divides neither p-1 nor q-1 */
- mpz_sub_ui(t, this->p, 1);
- mpz_mod(t, t, this->e);
- if (mpz_cmp_ui(t, 0) == 0)
- {
- status = FAILED;
- }
-
- mpz_sub_ui(t, this->q, 1);
- mpz_mod(t, t, this->e);
- if (mpz_cmp_ui(t, 0) == 0)
- {
- status = FAILED;
- }
-
- /* check that d is e^-1 (mod lcm(p-1, q-1)) */
- /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
- mpz_sub_ui(q1, this->q, 1);
- mpz_sub_ui(u, this->p, 1);
- mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */
- mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */
- mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */
-
- mpz_mul(t, this->d, this->e);
- mpz_mod(t, t, u);
- if (mpz_cmp_ui(t, 1) != 0)
- {
- status = FAILED;
- }
-
- /* check that exp1 is d mod (p-1) */
- mpz_sub_ui(u, this->p, 1);
- mpz_mod(t, this->d, u);
- if (mpz_cmp(t, this->exp1) != 0)
- {
- status = FAILED;
- }
-
- /* check that exp2 is d mod (q-1) */
- mpz_sub_ui(u, this->q, 1);
- mpz_mod(t, this->d, u);
- if (mpz_cmp(t, this->exp2) != 0)
- {
- status = FAILED;
- }
-
- /* check that coeff is (q^-1) mod p */
- mpz_mul(t, this->coeff, this->q);
- mpz_mod(t, t, this->p);
- if (mpz_cmp_ui(t, 1) != 0)
- {
- status = FAILED;
- }
-
- mpz_clear_randomized(t);
- mpz_clear_randomized(u);
- mpz_clear_randomized(q1);
- return status;
-}
-
-/**
- * Implementation of rsa_private_key.destroy.
- */
-static void destroy(private_rsa_private_key_t *this)
-{
- mpz_clear_randomized(this->n);
- mpz_clear_randomized(this->e);
- mpz_clear_randomized(this->p);
- mpz_clear_randomized(this->q);
- mpz_clear_randomized(this->d);
- mpz_clear_randomized(this->exp1);
- mpz_clear_randomized(this->exp2);
- mpz_clear_randomized(this->coeff);
- chunk_free_randomized(&this->keyid);
- free(this);
-}
-
-/**
- * Internal generic constructor
- */
-static private_rsa_private_key_t *rsa_private_key_create_empty(void)
-{
- private_rsa_private_key_t *this = malloc_thing(private_rsa_private_key_t);
-
- /* public functions */
- this->public.pkcs1_decrypt = (status_t (*) (rsa_private_key_t*,chunk_t,chunk_t*))pkcs1_decrypt;
- this->public.build_emsa_pkcs1_signature = (status_t (*) (rsa_private_key_t*,hash_algorithm_t,chunk_t,chunk_t*))build_emsa_pkcs1_signature;
- this->public.pkcs1_write = (bool (*) (rsa_private_key_t*,const char*,bool))pkcs1_write;
- this->public.get_public_key = (rsa_public_key_t* (*) (rsa_private_key_t*))get_public_key;
- this->public.belongs_to = (bool (*) (rsa_private_key_t*,rsa_public_key_t*))belongs_to;
- this->public.destroy = (void (*) (rsa_private_key_t*))destroy;
-
- /* private functions */
- this->rsadp = rsadp;
- this->rsasp1 = rsadp; /* same algorithm */
-
- this->keyid = chunk_empty;
-
- return this;
-}
-
-/*
- * See header
- */
-rsa_private_key_t *rsa_private_key_create(size_t key_size)
-{
- mpz_t p, q, n, e, d, exp1, exp2, coeff;
- mpz_t m, q1, t;
- private_rsa_private_key_t *this;
- size_t key_len = key_size / BITS_PER_BYTE;
- size_t prime_len = key_len / 2;
-
- /* Get values of primes p and q */
- if (compute_prime(this, prime_len, &p) != SUCCESS)
- {
- return NULL;
- }
- if (compute_prime(this, prime_len, &q) != SUCCESS)
- {
- mpz_clear(p);
- return NULL;
- }
-
- mpz_init(t);
- mpz_init(n);
- mpz_init(d);
- mpz_init(exp1);
- mpz_init(exp2);
- mpz_init(coeff);
-
- /* Swapping Primes so p is larger then q */
- if (mpz_cmp(p, q) < 0)
- {
- mpz_swap(p, q);
- }
-
- mpz_mul(n, p, q); /* n = p*q */
- mpz_init_set_ui(e, PUBLIC_EXPONENT); /* assign public exponent */
- mpz_init_set(m, p); /* m = p */
- mpz_sub_ui(m, m, 1); /* m = m -1 */
- mpz_init_set(q1, q); /* q1 = q */
- mpz_sub_ui(q1, q1, 1); /* q1 = q1 -1 */
- mpz_gcd(t, m, q1); /* t = gcd(p-1, q-1) */
- mpz_mul(m, m, q1); /* m = (p-1)*(q-1) */
- mpz_divexact(m, m, t); /* m = m / t */
- mpz_gcd(t, m, e); /* t = gcd(m, e) (greatest common divisor) */
-
- mpz_invert(d, e, m); /* e has an inverse mod m */
- if (mpz_cmp_ui(d, 0) < 0) /* make sure d is positive */
- {
- mpz_add(d, d, m);
- }
- mpz_sub_ui(t, p, 1); /* t = p-1 */
- mpz_mod(exp1, d, t); /* exp1 = d mod p-1 */
- mpz_sub_ui(t, q, 1); /* t = q-1 */
- mpz_mod(exp2, d, t); /* exp2 = d mod q-1 */
-
- mpz_invert(coeff, q, p); /* coeff = q^-1 mod p */
- if (mpz_cmp_ui(coeff, 0) < 0) /* make coeff d is positive */
- {
- mpz_add(coeff, coeff, p);
- }
-
- mpz_clear_randomized(q1);
- mpz_clear_randomized(m);
- mpz_clear_randomized(t);
-
- /* determine exact the modulus size in bits */
- key_size = mpz_sizeinbase(n, 2);
-
- /* create and fill in rsa_private_key_t object */
- this = rsa_private_key_create_empty();
- this->k = (key_size + 7) / BITS_PER_BYTE;
- this->keyid = rsa_public_key_id_create(n, e);
- *(this->p) = *p;
- *(this->q) = *q;
- *(this->n) = *n;
- *(this->e) = *e;
- *(this->d) = *d;
- *(this->exp1) = *exp1;
- *(this->exp2) = *exp2;
- *(this->coeff) = *coeff;
- DBG1("generated %d bit RSA key with keyid: %#B", key_size, &this->keyid);
-
- return &this->public;
-}
-
-/*
- * see header
- */
-rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- private_rsa_private_key_t *this;
-
- this = rsa_private_key_create_empty();
-
- mpz_init(this->n);
- mpz_init(this->e);
- mpz_init(this->p);
- mpz_init(this->q);
- mpz_init(this->d);
- mpz_init(this->exp1);
- mpz_init(this->exp2);
- mpz_init(this->coeff);
-
- asn1_init(&ctx, blob, 0, FALSE, TRUE);
-
- while (objectID < PRIV_KEY_ROOF)
- {
- if (!extract_object(privkey_objects, &objectID, &object, &level, &ctx))
- {
- destroy(this);
- return FALSE;
- }
- switch (objectID)
- {
- case PRIV_KEY_VERSION:
- if (object.len > 0 && *object.ptr != 0)
- {
- destroy(this);
- return NULL;
- }
- break;
- case PRIV_KEY_MODULUS:
- mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_PUB_EXP:
- mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_PRIV_EXP:
- mpz_import(this->d, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_PRIME1:
- mpz_import(this->p, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_PRIME2:
- mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_EXP1:
- mpz_import(this->exp1, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_EXP2:
- mpz_import(this->exp2, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_COEFF:
- mpz_import(this->coeff, object.len, 1, 1, 1, 0, object.ptr);
- break;
- }
- objectID++;
- }
-
- this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
- this->keyid = rsa_public_key_id_create(this->n, this->e);
-
- if (check(this) != SUCCESS)
- {
- destroy(this);
- return NULL;
- }
- else
- {
- return &this->public;
- }
-}
-
-/*
- * see header
- */
-rsa_private_key_t *rsa_private_key_create_from_file(char *filename, chunk_t *passphrase)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
- rsa_private_key_t *key = NULL;
-
- if (!pem_asn1_load_file(filename, passphrase, "private key", &chunk, &pgp))
- return NULL;
-
- key = rsa_private_key_create_from_chunk(chunk);
- chunk_free_randomized(&chunk);
- return key;
-}
diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.h b/src/libstrongswan/crypto/rsa/rsa_private_key.h
deleted file mode 100644
index 8013f03c2..000000000
--- a/src/libstrongswan/crypto/rsa/rsa_private_key.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
- * @file rsa_private_key.h
- *
- * @brief Interface of rsa_private_key_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: rsa_private_key.h 3423 2008-01-22 10:32:37Z andreas $
- */
-
-#ifndef RSA_PRIVATE_KEY_H_
-#define RSA_PRIVATE_KEY_H_
-
-typedef struct rsa_private_key_t rsa_private_key_t;
-
-#include <library.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief RSA private key with associated functions.
- *
- * Currently only supports signing using EMSA encoding.
- *
- * @b Constructors:
- * - rsa_private_key_create()
- * - rsa_private_key_create_from_chunk()
- * - rsa_private_key_create_from_file()
- *
- * @see rsa_public_key_t
- *
- * @ingroup rsa
- */
-struct rsa_private_key_t {
-
- /**
- * @brief Decrypt a data block based on EME-PKCS1 encoding.
- *
- *
- * @param this calling object
- * @param data encrypted input data
- * @param out decrypted output data
- * @return
- * - SUCCESS
- * - FAILED if padding is not correct
- */
- status_t (*pkcs1_decrypt) (rsa_private_key_t *this, chunk_t in, chunk_t *out);
-
- /**
- * @brief Build a signature over a chunk using EMSA-PKCS1 encoding.
- *
- * This signature creates a hash using the specified hash algorithm, concatenates
- * it with an ASN1-OID of the hash algorithm and runs the RSASP1 function
- * on it.
- *
- * @param this calling object
- * @param hash_algorithm hash algorithm to use for hashing
- * @param data data to sign
- * @param[out] signature allocated signature
- * @return
- * - SUCCESS
- * - INVALID_STATE, if key not set
- * - NOT_SUPPORTED, if hash algorithm not supported
- */
- status_t (*build_emsa_pkcs1_signature) (rsa_private_key_t *this, hash_algorithm_t hash_algorithm, chunk_t data, chunk_t *signature);
-
- /**
- * @brief Writes an RSA private key to a file in PKCS#1 format.
- *
- * @param this calling object
- * @param filename file to which the key should be written.
- * @param force if TRUE overwrite existing file
- * @return TRUE if successful - FALSE otherwise
- */
- bool (*pkcs1_write) (rsa_private_key_t *this, const char *filename, bool force);
-
- /**
- * @brief Create a rsa_public_key_t with the public part of the key.
- *
- * @param this calling object
- * @return public_key
- */
- rsa_public_key_t *(*get_public_key) (rsa_private_key_t *this);
-
- /**
- * @brief Check if a private key belongs to a public key.
- *
- * Compares the public part of the private key with the
- * public key, return TRUE if it equals.
- *
- * @param this private key
- * @param public public key
- * @return TRUE, if keys belong together
- */
- bool (*belongs_to) (rsa_private_key_t *this, rsa_public_key_t *public);
-
- /**
- * @brief Destroys the private key.
- *
- * @param this private key to destroy
- */
- void (*destroy) (rsa_private_key_t *this);
-};
-
-/**
- * @brief Generate a new RSA key with specified key length.
- *
- * @param key_size size of the key in bits
- * @return generated rsa_private_key_t.
- *
- * @ingroup rsa
- */
-rsa_private_key_t *rsa_private_key_create(size_t key_size);
-
-/**
- * @brief Load an RSA private key from a chunk.
- *
- * Load a key from a chunk, encoded as described in PKCS#1
- * (ASN1 DER encoded).
- *
- * @param chunk chunk containing the DER encoded key
- * @return loaded rsa_private_key_t, or NULL
- *
- * @ingroup rsa
- */
-rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Load an RSA private key from a file.
- *
- * Load a key from a file, which is either in a unencrypted binary
- * format (DER), or in a (encrypted) PEM format. The supplied
- * passphrase is used to decrypt an ecrypted key.
- *
- * @param filename filename which holds the key
- * @param passphrase optional passphase for decryption, can be NULL
- * @return loaded rsa_private_key_t, or NULL
- *
- * @todo Implement PEM file loading
- * @todo Implement key decryption
- *
- * @ingroup rsa
- */
-rsa_private_key_t *rsa_private_key_create_from_file(char *filename, chunk_t *passphrase);
-
-#endif /*RSA_PRIVATE_KEY_H_*/
diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.c b/src/libstrongswan/crypto/rsa/rsa_public_key.c
deleted file mode 100644
index 10af0527e..000000000
--- a/src/libstrongswan/crypto/rsa/rsa_public_key.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/**
- * @file rsa_public_key.c
- *
- * @brief Implementation of rsa_public_key_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: rsa_public_key.c 3428 2008-01-27 20:58:52Z andreas $
- */
-
-#include <gmp.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "rsa_public_key.h"
-
-#include <debug.h>
-#include <utils/randomizer.h>
-#include <crypto/hashers/hasher.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-
-/* ASN.1 definition of RSApublicKey */
-static const asn1Object_t pubkeyObjects[] = {
- { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
-};
-
-#define PUB_KEY_RSA_PUBLIC_KEY 0
-#define PUB_KEY_MODULUS 1
-#define PUB_KEY_EXPONENT 2
-#define PUB_KEY_ROOF 3
-
-/* ASN.1 definition of digestInfo */
-static const asn1Object_t digestInfoObjects[] = {
- { 0, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 1, "digest", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
-};
-
-#define DIGEST_INFO 0
-#define DIGEST_INFO_ALGORITHM 1
-#define DIGEST_INFO_DIGEST 2
-#define DIGEST_INFO_ROOF 3
-
-typedef struct private_rsa_public_key_t private_rsa_public_key_t;
-
-/**
- * Private data structure with signing context.
- */
-struct private_rsa_public_key_t {
- /**
- * Public interface for this signer.
- */
- rsa_public_key_t public;
-
- /**
- * Public modulus.
- */
- mpz_t n;
-
- /**
- * Public exponent.
- */
- mpz_t e;
-
- /**
- * Keysize in bytes.
- */
- size_t k;
-
- /**
- * Keyid formed as a SHA-1 hash of a publicKeyInfo object
- */
- chunk_t keyid;
-
- /**
- * @brief Implements the RSAEP algorithm specified in PKCS#1.
- *
- * @param this calling object
- * @param data data to process
- * @return processed data
- */
- chunk_t (*rsaep) (const private_rsa_public_key_t *this, chunk_t data);
-
- /**
- * @brief Implements the RSASVP1 algorithm specified in PKCS#1.
- *
- * @param this calling object
- * @param data data to process
- * @return processed data
- */
- chunk_t (*rsavp1) (const private_rsa_public_key_t *this, chunk_t data);
-};
-
-/**
- * Implementation of private_rsa_public_key_t.rsaep and private_rsa_public_key_t.rsavp1
- */
-static chunk_t rsaep(const private_rsa_public_key_t *this, chunk_t data)
-{
- mpz_t m, c;
- chunk_t encrypted;
-
- mpz_init(c);
- mpz_init(m);
-
- mpz_import(m, data.len, 1, 1, 1, 0, data.ptr);
-
- mpz_powm(c, m, this->e, this->n);
-
- encrypted.len = this->k;
- encrypted.ptr = mpz_export(NULL, NULL, 1, encrypted.len, 1, 0, c);
-
- mpz_clear(c);
- mpz_clear(m);
-
- return encrypted;
-}
-
-/**
- * Implementation of rsa_public_key_t.eme_pkcs1_encrypt.
- */
-static status_t pkcs1_encrypt(private_rsa_public_key_t *this,
- chunk_t in, chunk_t *out)
-{
- chunk_t em;
- u_char *pos;
- int padding = this->k - in.len - 3;
-
- if (padding < 8)
- {
- DBG1("rsa padding of %d bytes is too small", padding);
- return FAILED;
- }
- em.len = this->k;
- em.ptr = pos = malloc(em.len);
-
- /* add padding according to PKCS#1 7.2.1 1.+2. */
- *pos++ = 0x00;
- *pos++ = 0x02;
-
- /* pad with pseudo random bytes unequal to zero */
- {
- randomizer_t *randomizer = randomizer_create();
-
- /* pad with pseudo random bytes unequal to zero */
- while (padding--)
- {
- randomizer->get_pseudo_random_bytes(randomizer, 1, pos);
- while (!*pos)
- {
- randomizer->get_pseudo_random_bytes(randomizer, 1, pos);
- }
- pos++;
- }
- randomizer->destroy(randomizer);
- }
-
- /* append the padding terminator */
- *pos++ = 0x00;
-
- /* now add the data */
- memcpy(pos, in.ptr, in.len);
- *out = this->rsaep(this, em);
- free(em.ptr);
- return SUCCESS;
-}
-
-/**
- * Implementation of rsa_public_key.verify_emsa_pkcs1_signature.
- */
-static status_t verify_emsa_pkcs1_signature(const private_rsa_public_key_t *this,
- hash_algorithm_t algorithm,
- chunk_t data, chunk_t signature)
-{
- chunk_t em_ori, em;
- status_t res = FAILED;
-
- /* remove any preceding 0-bytes from signature */
- while (signature.len && *(signature.ptr) == 0x00)
- {
- signature.len -= 1;
- signature.ptr++;
- }
-
- if (signature.len > this->k)
- {
- return INVALID_ARG;
- }
-
- /* unpack signature */
- em_ori = em = this->rsavp1(this, signature);
-
- /* result should look like this:
- * EM = 0x00 || 0x01 || PS || 0x00 || T.
- * PS = 0xFF padding, with length to fill em
- * T = oid || hash
- */
-
- /* check magic bytes */
- if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x01)
- {
- DBG2("incorrect padding - probably wrong RSA key");
- goto end;
- }
- em.ptr += 2;
- em.len -= 2;
-
- /* find magic 0x00 */
- while (em.len > 0)
- {
- if (*em.ptr == 0x00)
- {
- /* found magic byte, stop */
- em.ptr++;
- em.len--;
- break;
- }
- else if (*em.ptr != 0xFF)
- {
- /* bad padding, decryption failed ?!*/
- goto end;
- }
- em.ptr++;
- em.len--;
- }
-
- if (em.len == 0)
- {
- /* no digestInfo found */
- goto end;
- }
-
- /* parse ASN.1-based digestInfo */
- {
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- hash_algorithm_t hash_algorithm = HASH_UNKNOWN;
-
- asn1_init(&ctx, em, 0, FALSE, FALSE);
-
- while (objectID < DIGEST_INFO_ROOF)
- {
- if (!extract_object(digestInfoObjects, &objectID, &object, &level, &ctx))
- {
- goto end;
- }
- switch (objectID)
- {
- case DIGEST_INFO:
- if (em.len > object.len)
- {
- DBG1("digestInfo field in signature is followed by %u surplus bytes",
- em.len - object.len);
- goto end;
- }
- break;
- case DIGEST_INFO_ALGORITHM:
- {
- int hash_oid = parse_algorithmIdentifier(object, level+1, NULL);
-
- hash_algorithm = hasher_algorithm_from_oid(hash_oid);
- if (hash_algorithm == HASH_UNKNOWN
- || (algorithm != HASH_UNKNOWN && hash_algorithm != algorithm))
- {
- DBG1("wrong hash algorithm used in signature");
- goto end;
- }
- }
- break;
- case DIGEST_INFO_DIGEST:
- {
- chunk_t hash;
- hasher_t *hasher = hasher_create(hash_algorithm);
-
- if (object.len != hasher->get_hash_size(hasher))
- {
- DBG1("hash size in signature is %u bytes instead of %u bytes",
- object.len, hasher->get_hash_size(hasher));
- hasher->destroy(hasher);
- goto end;
- }
-
- /* build our own hash */
- hasher->allocate_hash(hasher, data, &hash);
- hasher->destroy(hasher);
-
- /* compare the hashes */
- res = memeq(object.ptr, hash.ptr, hash.len) ? SUCCESS : FAILED;
- free(hash.ptr);
- }
- break;
- default:
- break;
- }
- objectID++;
- }
- }
-
-end:
- free(em_ori.ptr);
- return res;
-}
-
-
-/**
- * Implementation of rsa_public_key_t.get_modulus.
- */
-static mpz_t *get_modulus(const private_rsa_public_key_t *this)
-{
- return (mpz_t*)&this->n;
-}
-
-/**
- * Implementation of rsa_public_key_t.get_keysize.
- */
-static size_t get_keysize(const private_rsa_public_key_t *this)
-{
- return this->k;
-}
-
-/**
- * Build a DER-encoded publicKeyInfo object from an RSA public key.
- * Also used in rsa_private_key.c.
- */
-chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e)
-{
- chunk_t publicKey = asn1_wrap(ASN1_SEQUENCE, "mm",
- asn1_integer_from_mpz(n),
- asn1_integer_from_mpz(e));
-
- return asn1_wrap(ASN1_SEQUENCE, "cm",
- asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
- asn1_bitstring("m", publicKey));
-}
-
-/**
- * Form the RSA keyid as a SHA-1 hash of a publicKeyInfo object
- * Also used in rsa_private_key.c.
- */
-chunk_t rsa_public_key_id_create(mpz_t n, mpz_t e)
-{
- chunk_t keyid;
- chunk_t publicKeyInfo = rsa_public_key_info_to_asn1(n, e);
- hasher_t *hasher = hasher_create(HASH_SHA1);
-
- hasher->allocate_hash(hasher, publicKeyInfo, &keyid);
- hasher->destroy(hasher);
- free(publicKeyInfo.ptr);
-
- return keyid;
-}
-
-/**
- * Implementation of rsa_public_key_t.get_publicKeyInfo.
- */
-static chunk_t get_publicKeyInfo(const private_rsa_public_key_t *this)
-{
- return rsa_public_key_info_to_asn1(this->n, this->e);
-}
-
-/**
- * Implementation of rsa_public_key_t.get_keyid.
- */
-static chunk_t get_keyid(const private_rsa_public_key_t *this)
-{
- return this->keyid;
-}
-
-/* forward declaration used by rsa_public_key_t.clone */
-private_rsa_public_key_t *rsa_public_key_create_empty(void);
-
-/**
- * Implementation of rsa_public_key_t.clone.
- */
-static rsa_public_key_t* _clone(const private_rsa_public_key_t *this)
-{
- private_rsa_public_key_t *clone = rsa_public_key_create_empty();
-
- mpz_init_set(clone->n, this->n);
- mpz_init_set(clone->e, this->e);
- clone->keyid = chunk_clone(this->keyid);
- clone->k = this->k;
-
- return &clone->public;
-}
-
-/**
- * Implementation of rsa_public_key_t.destroy.
- */
-static void destroy(private_rsa_public_key_t *this)
-{
- mpz_clear(this->n);
- mpz_clear(this->e);
- free(this->keyid.ptr);
- free(this);
-}
-
-/**
- * Generic private constructor
- */
-private_rsa_public_key_t *rsa_public_key_create_empty(void)
-{
- private_rsa_public_key_t *this = malloc_thing(private_rsa_public_key_t);
-
- /* public functions */
- this->public.pkcs1_encrypt = (status_t (*) (rsa_public_key_t*,chunk_t,chunk_t*))pkcs1_encrypt;
- this->public.verify_emsa_pkcs1_signature = (status_t (*) (const rsa_public_key_t*,hash_algorithm_t,chunk_t,chunk_t))verify_emsa_pkcs1_signature;
- this->public.get_modulus = (mpz_t *(*) (const rsa_public_key_t*))get_modulus;
- this->public.get_keysize = (size_t (*) (const rsa_public_key_t*))get_keysize;
- this->public.get_publicKeyInfo = (chunk_t (*) (const rsa_public_key_t*))get_publicKeyInfo;
- this->public.get_keyid = (chunk_t (*) (const rsa_public_key_t*))get_keyid;
- this->public.clone = (rsa_public_key_t* (*) (const rsa_public_key_t*))_clone;
- this->public.destroy = (void (*) (rsa_public_key_t*))destroy;
-
- /* private functions */
- this->rsaep = rsaep;
- this->rsavp1 = rsaep; /* same algorithm */
-
- return this;
-}
-
-/*
- * See header
- */
-rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e)
-{
- private_rsa_public_key_t *this = rsa_public_key_create_empty();
-
- mpz_init_set(this->n, n);
- mpz_init_set(this->e, e);
-
- this->k = (mpz_sizeinbase(n, 2) + 7) / BITS_PER_BYTE;
- this->keyid = rsa_public_key_id_create(n, e);
- return &this->public;
-}
-/*
- * See header
- */
-rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t blob)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- private_rsa_public_key_t *this = rsa_public_key_create_empty();
-
- mpz_init(this->n);
- mpz_init(this->e);
-
- asn1_init(&ctx, blob, 0, FALSE, FALSE);
-
- while (objectID < PUB_KEY_ROOF)
- {
- if (!extract_object(pubkeyObjects, &objectID, &object, &level, &ctx))
- {
- destroy(this);
- return FALSE;
- }
- switch (objectID)
- {
- case PUB_KEY_MODULUS:
- mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PUB_KEY_EXPONENT:
- mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
- break;
- }
- objectID++;
- }
-
- this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
- this->keyid = rsa_public_key_id_create(this->n, this->e);
- return &this->public;
-}
-
-/*
- * See header
- */
-rsa_public_key_t *rsa_public_key_create_from_file(char *filename)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
- rsa_public_key_t *pubkey = NULL;
-
- if (!pem_asn1_load_file(filename, NULL, "public key", &chunk, &pgp))
- {
- return NULL;
- }
- pubkey = rsa_public_key_create_from_chunk(chunk);
- free(chunk.ptr);
- return pubkey;
-}
diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.h b/src/libstrongswan/crypto/rsa/rsa_public_key.h
deleted file mode 100644
index c0bd3e351..000000000
--- a/src/libstrongswan/crypto/rsa/rsa_public_key.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * @file rsa_public_key.h
- *
- * @brief Interface of rsa_public_key_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: rsa_public_key.h 3423 2008-01-22 10:32:37Z andreas $
- */
-
-#ifndef RSA_PUBLIC_KEY_H_
-#define RSA_PUBLIC_KEY_H_
-
-typedef struct rsa_public_key_t rsa_public_key_t;
-
-#include <gmp.h>
-
-#include <library.h>
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief RSA public key with associated functions.
- *
- * Currently only supports signature verification using
- * the EMSA encoding (see PKCS1)
- *
- * @b Constructors:
- * - rsa_public_key_create()
- * - rsa_public_key_create_from_chunk()
- * - rsa_public_key_create_from_file()
- *
- * @ingroup rsa
- */
-struct rsa_public_key_t {
-
- /**
- * @brief Encrypt a data block using EME-PKCS1 encoding.
- *
- *
- * @param this calling object
- * @param data plaintext input data
- * @param out encrypted output data
- * @return
- * - SUCCESS
- * - FAILED if data block is too large
- */
- status_t (*pkcs1_encrypt) (rsa_public_key_t *this, chunk_t in, chunk_t *out);
-
- /**
- * @brief Verify an EMSA-PKCS1 encoded signature.
- *
- * Processes the supplied signature with the RSAVP1 function,
- * selects the hash algorithm form the resultign ASN1-OID and
- * verifies the hash against the supplied data.
- *
- * @param this rsa_public_key to use
- * @param data data to sign
- # @param algorithm hash algorithm the signature is based on
- * @param signature signature to verify
- * @return
- * - SUCCESS, if signature ok
- * - INVALID_STATE, if key not set
- * - NOT_SUPPORTED, if hash algorithm not supported
- * - INVALID_ARG, if signature is not a signature
- * - FAILED if signature invalid or unable to verify
- */
- status_t (*verify_emsa_pkcs1_signature) (const rsa_public_key_t *this,
- hash_algorithm_t algorithm,
- chunk_t data, chunk_t signature);
-
- /**
- * @brief Get the modulus of the key.
- *
- * @param this calling object
- * @return modulus (n) of the key
- */
- mpz_t *(*get_modulus) (const rsa_public_key_t *this);
-
- /**
- * @brief Get the size of the modulus in bytes.
- *
- * @param this calling object
- * @return size of the modulus (n) in bytes
- */
- size_t (*get_keysize) (const rsa_public_key_t *this);
-
- /**
- * @brief Get the DER encoded publicKeyInfo object.
- *
- * @param this calling object
- * @return DER encoded publicKeyInfo object
- */
- chunk_t (*get_publicKeyInfo) (const rsa_public_key_t *this);
-
- /**
- * @brief Get the keyid formed as the SHA-1 hash of a publicKeyInfo object.
- *
- * @param this calling object
- * @return keyid in the form of a SHA-1 hash
- */
- chunk_t (*get_keyid) (const rsa_public_key_t *this);
-
- /**
- * @brief Clone the public key.
- *
- * @param this public key to clone
- * @return clone of this
- */
- rsa_public_key_t *(*clone) (const rsa_public_key_t *this);
-
- /**
- * @brief Destroys the public key.
- *
- * @param this public key to destroy
- */
- void (*destroy) (rsa_public_key_t *this);
-};
-
-/**
- * @brief Create a RSA public key from modulus and public exponent.
- *
- * @param n modulus
- * @param e public exponent
- * @return created rsa_public_key_t
- *
- * @ingroup rsa
- */
-rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e);
-
-/**
- * @brief Load an RSA public key from a chunk.
- *
- * Load a key from a chunk, encoded in the more frequently
- * used publicKeyInfo object (ASN1 DER encoded).
- *
- * @param chunk chunk containing the DER encoded key
- * @return loaded rsa_public_key_t, or NULL
- *
- * @ingroup rsa
- */
-rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Load an RSA public key from a file.
- *
- * Load a key from a file, which is either in binary
- * format (DER), or in PEM format.
- *
- * @param filename filename which holds the key
- * @return loaded rsa_public_key_t, or NULL
- *
- * @ingroup rsa
- */
-rsa_public_key_t *rsa_public_key_create_from_file(char *filename);
-
-#endif /*RSA_PUBLIC_KEY_H_*/
diff --git a/src/libstrongswan/crypto/signers/signer.c b/src/libstrongswan/crypto/signers/signer.c
index 747bc5efa..8412ff62e 100644
--- a/src/libstrongswan/crypto/signers/signer.c
+++ b/src/libstrongswan/crypto/signers/signer.c
@@ -1,10 +1,3 @@
-/**
- * @file signer.c
- *
- * @brief Implementation of generic signer_t constructor.
- *
- */
-
/*
* 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: signer.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "signer.h"
-#include <crypto/signers/hmac_signer.h>
-
ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_HMAC_SHA1_128,
"UNDEFINED",
"AUTH_HMAC_SHA1_128");
@@ -40,26 +33,3 @@ ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_SHA2_256_128, AUTH_HMAC_SHA2_512_
"AUTH_HMAC_SHA2_512_256");
ENUM_END(integrity_algorithm_names, AUTH_HMAC_SHA2_512_256);
-/*
- * Described in header.
- */
-signer_t *signer_create(integrity_algorithm_t integrity_algorithm)
-{
- switch(integrity_algorithm)
- {
- case AUTH_HMAC_SHA1_96:
- return (signer_t *)hmac_signer_create(HASH_SHA1, 12);
- case AUTH_HMAC_SHA1_128:
- return (signer_t *)hmac_signer_create(HASH_SHA1, 16);
- case AUTH_HMAC_MD5_96:
- return (signer_t *)hmac_signer_create(HASH_MD5, 12);
- case AUTH_HMAC_SHA2_256_128:
- return (signer_t *)hmac_signer_create(HASH_SHA256, 16);
- case AUTH_HMAC_SHA2_384_192:
- return (signer_t *)hmac_signer_create(HASH_SHA384, 24);
- case AUTH_HMAC_SHA2_512_256:
- return (signer_t *)hmac_signer_create(HASH_SHA512, 32);
- default:
- return NULL;
- }
-}
diff --git a/src/libstrongswan/crypto/signers/signer.h b/src/libstrongswan/crypto/signers/signer.h
index 4218e4146..f67c38f07 100644
--- a/src/libstrongswan/crypto/signers/signer.h
+++ b/src/libstrongswan/crypto/signers/signer.h
@@ -1,10 +1,3 @@
-/**
- * @file signer.h
- *
- * @brief Interface for signer_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: signer.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup signer signer
+ * @{ @ingroup crypto
*/
#ifndef SIGNER_H_
@@ -30,11 +30,9 @@ typedef struct signer_t signer_t;
#include <library.h>
/**
- * @brief Integrity algorithm, as in IKEv2 RFC 3.3.2.
+ * Integrity algorithm, as in IKEv2 RFC 3.3.2.
*
* Algorithms not specified in IKEv2 are allocated in private use space.
- *
- * @ingroup signers
*/
enum integrity_algorithm_t {
AUTH_UNDEFINED = 1024,
@@ -61,93 +59,65 @@ enum integrity_algorithm_t {
extern enum_name_t *integrity_algorithm_names;
/**
- * @brief Generig interface for a symmetric signature algorithm.
- *
- * @b Constructors:
- * - signer_create()
- * - hmac_signer_create()
- *
- * @todo Implement more integrity algorithms
- *
- * @ingroup signers
+ * Generig interface for a symmetric signature algorithm.
*/
struct signer_t {
/**
- * @brief Generate a signature.
+ * Generate a signature.
*
* If buffer is NULL, data is processed and prepended to a next call until
* buffer is a valid pointer.
*
- * @param this calling object
- * @param data a chunk containing the data to sign
- * @param[out] buffer pointer where the signature will be written
+ * @param data a chunk containing the data to sign
+ * @param buffer pointer where the signature will be written
*/
void (*get_signature) (signer_t *this, chunk_t data, u_int8_t *buffer);
/**
- * @brief Generate a signature and allocate space for it.
+ * Generate a signature and allocate space for it.
*
* If chunk is NULL, data is processed and prepended to a next call until
* chunk is a valid chunk pointer.
*
- * @param this calling object
- * @param data a chunk containing the data to sign
- * @param[out] chunk chunk which will hold the allocated signature
+ * @param data a chunk containing the data to sign
+ * @param chunk chunk which will hold the allocated signature
*/
void (*allocate_signature) (signer_t *this, chunk_t data, chunk_t *chunk);
/**
- * @brief Verify a signature.
+ * Verify a signature.
*
- * @param this calling object
- * @param data a chunk containing the data to verify
- * @param signature a chunk containing the signature
- * @return TRUE, if signature is valid, FALSE otherwise
+ * @param data a chunk containing the data to verify
+ * @param signature a chunk containing the signature
+ * @return TRUE, if signature is valid, FALSE otherwise
*/
bool (*verify_signature) (signer_t *this, chunk_t data, chunk_t signature);
/**
- * @brief Get the block size of this signature algorithm.
+ * Get the block size of this signature algorithm.
*
- * @param this calling object
- * @return block size in bytes
+ * @return block size in bytes
*/
size_t (*get_block_size) (signer_t *this);
/**
- * @brief Get the key size of the signature algorithm.
+ * Get the key size of the signature algorithm.
*
- * @param this calling object
- * @return key size in bytes
+ * @return key size in bytes
*/
size_t (*get_key_size) (signer_t *this);
/**
- * @brief Set the key for this object.
+ * Set the key for this object.
*
- * @param this calling object
- * @param key key to set
+ * @param key key to set
*/
void (*set_key) (signer_t *this, chunk_t key);
/**
- * @brief Destroys a signer_t object.
- *
- * @param this calling object
+ * Destroys a signer_t object.
*/
void (*destroy) (signer_t *this);
};
-/**
- * @brief Creates a new signer_t object.
- *
- * @param integrity_algorithm Algorithm to use for signing and verifying.
- * @return
- * - signer_t object
- * - NULL if signer not supported
- *
- * @ingroup signers
- */
-signer_t *signer_create(integrity_algorithm_t integrity_algorithm);
-
-#endif /*SIGNER_H_*/
+#endif /*SIGNER_H_ @} */
diff --git a/src/libstrongswan/crypto/x509.c b/src/libstrongswan/crypto/x509.c
deleted file mode 100755
index eadf11327..000000000
--- a/src/libstrongswan/crypto/x509.c
+++ /dev/null
@@ -1,1562 +0,0 @@
-/**
- * @file x509.c
- *
- * @brief Implementation of x509_t.
- *
- */
-
-/*
- * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
- * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
- * Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2006 Martin Willi
- * Copyright (C) 2000-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: x509.c 3423 2008-01-22 10:32:37Z andreas $
- */
-
-#include <gmp.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "x509.h"
-#include "hashers/hasher.h"
-#include <library.h>
-#include <debug.h>
-#include <asn1/oid.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-#define CERT_WARNING_INTERVAL 30 /* days */
-
-/**
- * Different kinds of generalNames
- */
-typedef enum generalNames_t generalNames_t;
-
-enum generalNames_t {
- GN_OTHER_NAME = 0,
- GN_RFC822_NAME = 1,
- GN_DNS_NAME = 2,
- GN_X400_ADDRESS = 3,
- GN_DIRECTORY_NAME = 4,
- GN_EDI_PARTY_NAME = 5,
- GN_URI = 6,
- GN_IP_ADDRESS = 7,
- GN_REGISTERED_ID = 8,
-};
-
-typedef struct private_x509_t private_x509_t;
-
-/**
- * Private data of a x509_t object.
- */
-struct private_x509_t {
- /**
- * Public interface for this certificate.
- */
- x509_t public;
-
- /**
- * Time when certificate was installed
- */
- time_t installed;
-
- /**
- * Time until certificate can be trusted
- */
- time_t until;
-
- /**
- * Certificate status
- */
- cert_status_t status;
-
- /**
- * Authority flags
- */
- u_int authority_flags;
-
- /**
- * X.509 Certificate in DER format
- */
- chunk_t certificate;
-
- /**
- * X.509 certificate body over which signature is computed
- */
- chunk_t tbsCertificate;
-
- /**
- * Version of the X.509 certificate
- */
- u_int version;
-
- /**
- * Serial number of the X.509 certificate
- */
- chunk_t serialNumber;
-
- /**
- * Signature algorithm
- */
- int signatureAlgorithm;
-
- /**
- * ID representing the certificate issuer
- */
- identification_t *issuer;
-
- /**
- * link to the info recored of the certificate issuer
- */
- ca_info_t *ca_info;
-
- /**
- * Start time of certificate validity
- */
- time_t notBefore;
-
- /**
- * End time of certificate validity
- */
- time_t notAfter;
-
- /**
- * ID representing the certificate subject
- */
- identification_t *subject;
-
- /**
- * List of identification_t's representing subjectAltNames
- */
- linked_list_t *subjectAltNames;
-
- /**
- * List of identification_t's representing crlDistributionPoints
- */
- linked_list_t *crlDistributionPoints;
-
- /**
- * List of identification_t's representing ocspAccessLocations
- */
- linked_list_t *ocspAccessLocations;
-
- /**
- * Subject public key
- */
- chunk_t subjectPublicKey;
-
- /**
- * Subject RSA public key, if subjectPublicKeyAlgorithm == RSA
- */
- rsa_public_key_t *public_key;
-
- /**
- * Subject Key Identifier
- */
- chunk_t subjectKeyID;
-
- /**
- * Authority Key Identifier
- */
- chunk_t authKeyID;
-
- /**
- * Authority Key Serial Number
- */
- chunk_t authKeySerialNumber;
-
- /**
- * Indicates if the certificate is self-signed
- */
- bool isSelfSigned;
-
- /**
- * CA basic constraints flag
- */
- bool isCA;
-
- /**
- * OCSPSigner extended key usage flag
- */
- bool isOcspSigner;
-
- /**
- * Signature
- */
- chunk_t signature;
-
-};
-
-/**
- * ASN.1 definition of generalName
- */
-static const asn1Object_t generalNameObjects[] = {
- { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
- { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
- { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
- { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
- { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT|ASN1_BODY }, /* 8 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT|ASN1_BODY }, /* 10 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
- { 0, "URI", ASN1_CONTEXT_S_6, ASN1_OPT|ASN1_BODY }, /* 12 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
- { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT|ASN1_BODY }, /* 14 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
- { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT|ASN1_BODY }, /* 16 */
- { 0, "end choice", ASN1_EOC, ASN1_END } /* 17 */
-};
-#define GN_OBJ_OTHER_NAME 0
-#define GN_OBJ_RFC822_NAME 2
-#define GN_OBJ_DNS_NAME 4
-#define GN_OBJ_X400_ADDRESS 6
-#define GN_OBJ_DIRECTORY_NAME 8
-#define GN_OBJ_EDI_PARTY_NAME 10
-#define GN_OBJ_URI 12
-#define GN_OBJ_IP_ADDRESS 14
-#define GN_OBJ_REGISTERED_ID 16
-#define GN_OBJ_ROOF 18
-
-/**
- * ASN.1 definition of otherName
- */
-static const asn1Object_t otherNameObjects[] = {
- {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
- {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY } /* 1 */
-};
-#define ON_OBJ_ID_TYPE 0
-#define ON_OBJ_VALUE 1
-#define ON_OBJ_ROOF 2
-/**
- * ASN.1 definition of a basicConstraints extension
- */
-static const asn1Object_t basicConstraintsObjects[] = {
- { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */
- { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
-};
-#define BASIC_CONSTRAINTS_CA 1
-#define BASIC_CONSTRAINTS_ROOF 4
-
-/**
- * ASN.1 definition of a keyIdentifier
- */
-static const asn1Object_t keyIdentifierObjects[] = {
- { 0, "keyIdentifier", ASN1_OCTET_STRING, ASN1_BODY } /* 0 */
-};
-
-/**
- * ASN.1 definition of a authorityKeyIdentifier extension
- */
-static const asn1Object_t authorityKeyIdentifierObjects[] = {
- { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_OBJ }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
- { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
- { 1, "authorityCertSerialNumber",ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
-};
-#define AUTH_KEY_ID_KEY_ID 1
-#define AUTH_KEY_ID_CERT_ISSUER 3
-#define AUTH_KEY_ID_CERT_SERIAL 5
-#define AUTH_KEY_ID_ROOF 7
-
-/**
- * ASN.1 definition of a authorityInfoAccess extension
- */
-static const asn1Object_t authorityInfoAccessObjects[] = {
- { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */
- { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 4 */
-};
-#define AUTH_INFO_ACCESS_METHOD 2
-#define AUTH_INFO_ACCESS_LOCATION 3
-#define AUTH_INFO_ACCESS_ROOF 5
-
-/**
- * ASN.1 definition of a extendedKeyUsage extension
- */
-static const asn1Object_t extendedKeyUsageObjects[] = {
- { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
-};
-
-#define EXT_KEY_USAGE_PURPOSE_ID 1
-#define EXT_KEY_USAGE_ROOF 3
-
-/**
- * ASN.1 definition of generalNames
- */
-static const asn1Object_t generalNamesObjects[] = {
- { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
-};
-#define GENERAL_NAMES_GN 1
-#define GENERAL_NAMES_ROOF 3
-
-
-/**
- * ASN.1 definition of crlDistributionPoints
- */
-static const asn1Object_t crlDistributionPointsObjects[] = {
- { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 2 */
- { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */
- { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
- { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */
- { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
- { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
- { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_BODY }, /* 10 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
-};
-#define CRL_DIST_POINTS_FULLNAME 3
-#define CRL_DIST_POINTS_ROOF 13
-
-/**
- * ASN.1 definition of an X.509v3 x509
- */
-static const asn1Object_t certObjects[] = {
- { 0, "x509", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
- { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
- { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
- { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
- { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
- { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
- { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
- { 3, "algorithm", ASN1_EOC, ASN1_RAW }, /* 12 */
- { 3, "subjectPublicKey", ASN1_BIT_STRING, ASN1_NONE }, /* 13 */
- { 4, "RSAPublicKey", ASN1_SEQUENCE, ASN1_RAW }, /* 14 */
- { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 15 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 16 */
- { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 17 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 19 */
- { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 23 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
- { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 28 */
-};
-#define X509_OBJ_CERTIFICATE 0
-#define X509_OBJ_TBS_CERTIFICATE 1
-#define X509_OBJ_VERSION 3
-#define X509_OBJ_SERIAL_NUMBER 4
-#define X509_OBJ_SIG_ALG 5
-#define X509_OBJ_ISSUER 6
-#define X509_OBJ_NOT_BEFORE 8
-#define X509_OBJ_NOT_AFTER 9
-#define X509_OBJ_SUBJECT 10
-#define X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM 12
-#define X509_OBJ_SUBJECT_PUBLIC_KEY 13
-#define X509_OBJ_RSA_PUBLIC_KEY 14
-#define X509_OBJ_EXTN_ID 22
-#define X509_OBJ_CRITICAL 23
-#define X509_OBJ_EXTN_VALUE 24
-#define X509_OBJ_ALGORITHM 27
-#define X509_OBJ_SIGNATURE 28
-#define X509_OBJ_ROOF 29
-
-
-static u_char ASN1_subjectAltName_oid_str[] = {
- 0x06, 0x03, 0x55, 0x1D, 0x11
-};
-
-static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_subjectAltName_oid_str);
-
-
-/**
- * compare two X.509 x509s by comparing their signatures
- */
-static bool equals(const private_x509_t *this, const private_x509_t *other)
-{
- return chunk_equals(this->signature, other->signature);
-}
-
-/**
- * extracts the basicConstraints extension
- */
-static bool parse_basicConstraints(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- bool isCA = FALSE;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < BASIC_CONSTRAINTS_ROOF) {
-
- if (!extract_object(basicConstraintsObjects, &objectID, &object,&level, &ctx))
- {
- break;
- }
- if (objectID == BASIC_CONSTRAINTS_CA)
- {
- isCA = object.len && *object.ptr;
- DBG2(" %s", isCA ? "TRUE" : "FALSE");
- }
- objectID++;
- }
- return isCA;
-}
-
-/**
- * extracts an otherName
- */
-static bool parse_otherName(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < ON_OBJ_ROOF)
- {
- if (!extract_object(otherNameObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- switch (objectID)
- {
- case ON_OBJ_ID_TYPE:
- oid = known_oid(object);
- break;
- case ON_OBJ_VALUE:
- if (oid == OID_XMPP_ADDR)
- {
- if (!parse_asn1_simple_object(&object, ASN1_UTF8STRING, level + 1, "xmppAddr"))
- return FALSE;
- }
- break;
- default:
- break;
- }
- objectID++;
- }
- return TRUE;
-}
-
-/**
- * extracts a generalName
- */
-static identification_t *parse_generalName(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- int objectID = 0;
- u_int level;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < GN_OBJ_ROOF)
- {
- id_type_t id_type = ID_ANY;
-
- if (!extract_object(generalNameObjects, &objectID, &object, &level, &ctx))
- return NULL;
-
- switch (objectID)
- {
- case GN_OBJ_RFC822_NAME:
- id_type = ID_RFC822_ADDR;
- break;
- case GN_OBJ_DNS_NAME:
- id_type = ID_FQDN;
- break;
- case GN_OBJ_URI:
- id_type = ID_DER_ASN1_GN_URI;
- break;
- case GN_OBJ_DIRECTORY_NAME:
- id_type = ID_DER_ASN1_DN;
- break;
- case GN_OBJ_IP_ADDRESS:
- id_type = (object.len == 4)? ID_IPV4_ADDR : ID_IPV6_ADDR;
- break;
- case GN_OBJ_OTHER_NAME:
- if (!parse_otherName(object, level + 1))
- return NULL;
- break;
- case GN_OBJ_X400_ADDRESS:
- case GN_OBJ_EDI_PARTY_NAME:
- case GN_OBJ_REGISTERED_ID:
- break;
- default:
- break;
- }
-
- if (id_type != ID_ANY)
- {
- identification_t *gn = identification_create_from_encoding(id_type, object);
- DBG2(" '%D'", gn);
- return gn;
- }
- objectID++;
- }
- return NULL;
-}
-
-
-/*
- * Defined in header.
- */
-void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, implicit, FALSE);
-
- while (objectID < GENERAL_NAMES_ROOF)
- {
- if (!extract_object(generalNamesObjects, &objectID, &object, &level, &ctx))
- return;
-
- if (objectID == GENERAL_NAMES_GN)
- {
- identification_t *gn = parse_generalName(object, level+1);
-
- if (gn != NULL)
- list->insert_last(list, (void *)gn);
- }
- objectID++;
- }
- return;
-}
-
-/**
- * extracts a keyIdentifier
- */
-static chunk_t parse_keyIdentifier(chunk_t blob, int level0, bool implicit)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, implicit, FALSE);
-
- extract_object(keyIdentifierObjects, &objectID, &object, &level, &ctx);
- return object;
-}
-
-/*
- * Defined in header.
- */
-void x509_parse_authorityKeyIdentifier(chunk_t blob, int level0 , chunk_t *authKeyID, chunk_t *authKeySerialNumber)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- *authKeyID = chunk_empty;
- *authKeySerialNumber = chunk_empty;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < AUTH_KEY_ID_ROOF)
- {
- if (!extract_object(authorityKeyIdentifierObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
- switch (objectID)
- {
- case AUTH_KEY_ID_KEY_ID:
- *authKeyID = parse_keyIdentifier(object, level+1, TRUE);
- break;
- case AUTH_KEY_ID_CERT_ISSUER:
- {
- /* TODO: parse_generalNames(object, level+1, TRUE); */
- break;
- }
- case AUTH_KEY_ID_CERT_SERIAL:
- *authKeySerialNumber = object;
- break;
- default:
- break;
- }
- objectID++;
- }
-}
-
-/**
- * extracts an authorityInfoAcess location
- */
-static void parse_authorityInfoAccess(chunk_t blob, int level0, linked_list_t *list)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int accessMethod = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
- while (objectID < AUTH_INFO_ACCESS_ROOF)
- {
- if (!extract_object(authorityInfoAccessObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
- switch (objectID)
- {
- case AUTH_INFO_ACCESS_METHOD:
- accessMethod = known_oid(object);
- break;
- case AUTH_INFO_ACCESS_LOCATION:
- {
- switch (accessMethod)
- {
- case OID_OCSP:
- case OID_CA_ISSUERS:
- {
- identification_t *accessLocation;
-
- accessLocation = parse_generalName(object, level+1);
- if (accessLocation == NULL)
- {
- /* parsing went wrong - abort */
- return;
- }
- DBG2(" '%D'", accessLocation);
- if (accessMethod == OID_OCSP)
- {
- list->insert_last(list, (void *)accessLocation);
- }
- else
- {
- /* caIsssuer accessLocation is not used yet */
- accessLocation->destroy(accessLocation);
- }
- }
- break;
- default:
- /* unkown accessMethod, ignoring */
- break;
- }
- break;
- }
- default:
- break;
- }
- objectID++;
- }
-}
-
-/**
- * extracts extendedKeyUsage OIDs
- */
-static bool parse_extendedKeyUsage(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
- while (objectID < EXT_KEY_USAGE_ROOF)
- {
- if (!extract_object(extendedKeyUsageObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
- if (objectID == EXT_KEY_USAGE_PURPOSE_ID &&
- known_oid(object) == OID_OCSP_SIGNING)
- {
- return TRUE;
- }
- objectID++;
- }
- return FALSE;
-}
-
-/**
- * extracts one or several crlDistributionPoints and puts them into
- * a chained list
- */
-static void parse_crlDistributionPoints(chunk_t blob, int level0, linked_list_t *list)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
- while (objectID < CRL_DIST_POINTS_ROOF)
- {
- if (!extract_object(crlDistributionPointsObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
- if (objectID == CRL_DIST_POINTS_FULLNAME)
- {
- /* append extracted generalNames to existing chained list */
- x509_parse_generalNames(object, level+1, TRUE, list);
-
- }
- objectID++;
- }
-}
-
-
-/**
- * Parses an X.509v3 certificate
- */
-static bool parse_certificate(chunk_t blob, u_int level0, private_x509_t *this)
-{
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int extn_oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
- while (objectID < X509_OBJ_ROOF)
- {
- if (!extract_object(certObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- /* those objects which will parsed further need the next higher level */
- level++;
-
- switch (objectID)
- {
- case X509_OBJ_CERTIFICATE:
- this->certificate = object;
- break;
- case X509_OBJ_TBS_CERTIFICATE:
- this->tbsCertificate = object;
- break;
- case X509_OBJ_VERSION:
- this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
- DBG2(" v%d", this->version);
- break;
- case X509_OBJ_SERIAL_NUMBER:
- this->serialNumber = object;
- break;
- case X509_OBJ_SIG_ALG:
- this->signatureAlgorithm = parse_algorithmIdentifier(object, level, NULL);
- break;
- case X509_OBJ_ISSUER:
- this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", this->issuer);
- break;
- case X509_OBJ_NOT_BEFORE:
- this->notBefore = parse_time(object, level);
- break;
- case X509_OBJ_NOT_AFTER:
- this->notAfter = parse_time(object, level);
- break;
- case X509_OBJ_SUBJECT:
- this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", this->subject);
- break;
- case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
- if (parse_algorithmIdentifier(object, level, NULL) != OID_RSA_ENCRYPTION)
- {
- DBG1(" unsupported public key algorithm");
- return FALSE;
- }
- break;
- case X509_OBJ_SUBJECT_PUBLIC_KEY:
- if (ctx.blobs[4].len > 0 && *ctx.blobs[4].ptr == 0x00)
- {
- /* skip initial bit string octet defining 0 unused bits */
- ctx.blobs[4].ptr++; ctx.blobs[4].len--;
- }
- else
- {
- DBG1(" invalid RSA public key format");
- return FALSE;
- }
- break;
- case X509_OBJ_RSA_PUBLIC_KEY:
- this->subjectPublicKey = object;
- break;
- case X509_OBJ_EXTN_ID:
- extn_oid = known_oid(object);
- break;
- case X509_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG2(" %s", critical ? "TRUE" : "FALSE");
- break;
- case X509_OBJ_EXTN_VALUE:
- {
- switch (extn_oid)
- {
- case OID_SUBJECT_KEY_ID:
- this->subjectKeyID = chunk_clone(parse_keyIdentifier(object, level, FALSE));
- break;
- case OID_SUBJECT_ALT_NAME:
- x509_parse_generalNames(object, level, FALSE, this->subjectAltNames);
- break;
- case OID_BASIC_CONSTRAINTS:
- this->isCA = parse_basicConstraints(object, level);
- break;
- case OID_CRL_DISTRIBUTION_POINTS:
- parse_crlDistributionPoints(object, level, this->crlDistributionPoints);
- break;
- case OID_AUTHORITY_KEY_ID:
- x509_parse_authorityKeyIdentifier(object, level,
- &this->authKeyID, &this->authKeySerialNumber);
- break;
- case OID_AUTHORITY_INFO_ACCESS:
- parse_authorityInfoAccess(object, level, this->ocspAccessLocations);
- break;
- case OID_EXTENDED_KEY_USAGE:
- this->isOcspSigner = parse_extendedKeyUsage(object, level);
- break;
- case OID_NS_REVOCATION_URL:
- case OID_NS_CA_REVOCATION_URL:
- case OID_NS_CA_POLICY_URL:
- case OID_NS_COMMENT:
- if (!parse_asn1_simple_object(&object, ASN1_IA5STRING , level, oid_names[extn_oid].name))
- return FALSE;
- break;
- default:
- break;
- }
- break;
- }
- case X509_OBJ_ALGORITHM:
- {
- int alg = parse_algorithmIdentifier(object, level, NULL);
-
- if (alg != this->signatureAlgorithm)
- {
- DBG1(" signature algorithms do not agree");
- return FALSE;
- }
- }
- break;
- case X509_OBJ_SIGNATURE:
- this->signature = object;
- break;
- default:
- break;
- }
- objectID++;
- }
-
- /* generate the subjectKeyID if it is missing in the certificate */
- if (this->subjectKeyID.ptr == NULL)
- {
- hasher_t *hasher = hasher_create(HASH_SHA1);
-
- hasher->allocate_hash(hasher, this->subjectPublicKey, &this->subjectKeyID);
- hasher->destroy(hasher);
- }
-
- this->installed = time(NULL);
- return TRUE;
-}
-
-/**
- * Implements x509_t.is_valid
- */
-static err_t is_valid(const private_x509_t *this, time_t *until)
-{
- time_t current_time = time(NULL);
-
- DBG2(" not before : %T", &this->notBefore);
- DBG2(" current time: %T", &current_time);
- DBG2(" not after : %T", &this->notAfter);
-
- if (until != NULL &&
- (*until == UNDEFINED_TIME || this->notAfter < *until))
- {
- *until = this->notAfter;
- }
- if (current_time < this->notBefore)
- {
- return "is not valid yet";
- }
- if (current_time > this->notAfter)
- {
- return "has expired";
- }
- DBG2(" certificate is valid");
- return NULL;
-}
-
-/**
- * Implements x509_t.is_ca
- */
-static bool is_ca(const private_x509_t *this)
-{
- return this->isCA;
-}
-
-/**
- * Implements x509_t.is_ocsp_signer
- */
-static bool is_ocsp_signer(const private_x509_t *this)
-{
- return this->isOcspSigner;
-}
-
-/**
- * Implements x509_t.is_self_signed
- */
-static bool is_self_signed(const private_x509_t *this)
-{
- return this->isSelfSigned;
-}
-
-/**
- * Implements x509_t.equals_subjectAltName
- */
-static bool equals_subjectAltName(const private_x509_t *this, identification_t *id)
-{
- bool found = FALSE;
- identification_t *subjectAltName;
- iterator_t *iterator;
-
- iterator = this->subjectAltNames->create_iterator(this->subjectAltNames, TRUE);
- while (iterator->iterate(iterator, (void**)&subjectAltName))
- {
- if (id->equals(id, subjectAltName))
- {
- found = TRUE;
- break;
- }
- }
- iterator->destroy(iterator);
- return found;
-}
-
-/**
- * Implements x509_t.is_issuer
- */
-static bool is_issuer(const private_x509_t *this, const private_x509_t *issuer)
-{
- return (this->authKeyID.ptr)
- ? chunk_equals(this->authKeyID, issuer->subjectKeyID)
- : (this->issuer->equals(this->issuer, issuer->subject)
- && chunk_equals_or_null(this->authKeySerialNumber, issuer->serialNumber));
-}
-
-/**
- * Implements x509_t.get_certificate
- */
-static chunk_t get_certificate(const private_x509_t *this)
-{
- return this->certificate;
-}
-
-/**
- * Implements x509_t.get_public_key
- */
-static rsa_public_key_t *get_public_key(const private_x509_t *this)
-{
- return this->public_key;
-}
-
-/**
- * Implements x509_t.get_serialNumber
- */
-static chunk_t get_serialNumber(const private_x509_t *this)
-{
- return this->serialNumber;
-}
-
-/**
- * Implements x509_t.get_subjectKeyID
- */
-static chunk_t get_subjectKeyID(const private_x509_t *this)
-{
- return this->subjectKeyID;
-}
-
-/**
- * Implements x509_t.get_keyid
- */
-static chunk_t get_keyid(const private_x509_t *this)
-{
- return this->public_key->get_keyid(this->public_key);
-}
-
-/**
- * Implements x509_t.get_issuer
- */
-static identification_t *get_issuer(const private_x509_t *this)
-{
- return this->issuer;
-}
-
-/**
- * Implements x509_t.get_subject
- */
-static identification_t *get_subject(const private_x509_t *this)
-{
- return this->subject;
-}
-
-/**
- * Implements x509_t.set_ca_info
- */
-static void set_ca_info(private_x509_t *this, ca_info_t *ca_info)
-{
- this->ca_info = ca_info;
-}
-
-/**
- * Implements x509_t.get_ca_info
- */
-static ca_info_t *get_ca_info(const private_x509_t *this)
-{
- return this->ca_info;
-}
-
-/**
- * Implements x509_t.set_until
- */
-static void set_until(private_x509_t *this, time_t until)
-{
- this->until = until;
-}
-
-/**
- * Implements x509_t.get_until
- */
-static time_t get_until(const private_x509_t *this)
-{
- return this->until;
-}
-
-/**
- * Implements x509_t.set_status
- */
-static void set_status(private_x509_t *this, cert_status_t status)
-{
- this->status = status;
-}
-
-/**
- * Implements x509_t.get_status
- */
-static cert_status_t get_status(const private_x509_t *this)
-{
- return this->status;
-}
-
-/**
- * Implements x509_t.add_authority_flags
- */
-static void add_authority_flags(private_x509_t *this, u_int flags)
-{
- this->authority_flags |= flags;
-}
-
-/**
- * Implements x509_t.add_authority_flags
- */
-static u_int get_authority_flags(private_x509_t *this)
-{
- return this->authority_flags;
-}
-
-/**
- * Implements x509_t.has_authority_flag
- */
-static bool has_authority_flag(private_x509_t *this, u_int flags)
-{
- return (this->authority_flags & flags) != AUTH_NONE;
-}
-
-/**
- * Implements x509_t.create_crluri_iterator
- */
-static iterator_t *create_crluri_iterator(const private_x509_t *this)
-{
- return this->crlDistributionPoints->create_iterator(this->crlDistributionPoints, TRUE);
-}
-
-/**
- * Implements x509_t.create_crluri_iterator
- */
-static iterator_t *create_ocspuri_iterator(const private_x509_t *this)
-{
- return this->ocspAccessLocations->create_iterator(this->ocspAccessLocations, TRUE);
-}
-
-/**
- * Implements x509_t.verify
- */
-static bool verify(const private_x509_t *this, const rsa_public_key_t *signer)
-{
- hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->signatureAlgorithm);
-
- if (algorithm == HASH_UNKNOWN)
- {
- DBG1(" unknown signature algorithm");
- return FALSE;
- }
- return signer->verify_emsa_pkcs1_signature(signer, algorithm, this->tbsCertificate, this->signature) == SUCCESS;
-}
-
-/**
- * Implementation of x509_t.list.
- */
-static void list(private_x509_t *this, FILE *out, bool utc)
-{
- iterator_t *iterator;
- time_t now = time(NULL);
-
- fprintf(out, "%#T\n", &this->installed, utc);
-
- if (this->subjectAltNames->get_count(this->subjectAltNames))
- {
- identification_t *subjectAltName;
- bool first = TRUE;
-
- fprintf(out, " altNames: ");
- iterator = this->subjectAltNames->create_iterator(this->subjectAltNames, TRUE);
- while (iterator->iterate(iterator, (void**)&subjectAltName))
- {
- if (first)
- {
- first = FALSE;
- }
- else
- {
- fprintf(out, ", ");
- }
- fprintf(out, "'%D'", subjectAltName);
- }
- iterator->destroy(iterator);
- fprintf(out, "\n");
- }
- fprintf(out, " subject: '%D'\n", this->subject);
- fprintf(out, " issuer: '%D'\n", this->issuer);
- fprintf(out, " serial: %#B\n", &this->serialNumber);
- fprintf(out, " validity: not before %#T, ", &this->notBefore, utc);
- if (now < this->notBefore)
- {
- fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore);
- }
- else
- {
- fprintf(out, "ok\n");
- }
-
- fprintf(out, " not after %#T, ", &this->notAfter, utc);
- if (now > this->notAfter)
- {
- fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter);
- }
- else
- {
- fprintf(out, "ok");
- if (now > this->notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
- {
- fprintf(out, " (expires in %#V)", &now, &this->notAfter);
- }
- fprintf(out, " \n");
- }
-
- {
- chunk_t keyid = this->public_key->get_keyid(this->public_key);
- fprintf(out, " keyid: %#B\n", &keyid);
- }
-
- if (this->subjectKeyID.ptr)
- {
- fprintf(out, " subjkey: %#B\n", &this->subjectKeyID);
- }
- if (this->authKeyID.ptr)
- {
- fprintf(out, " authkey: %#B\n", &this->authKeyID);
- }
- if (this->authKeySerialNumber.ptr)
- {
- fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber);
- }
-
- fprintf(out, " pubkey: RSA %d bits", BITS_PER_BYTE *
- this->public_key->get_keysize(this->public_key));
- fprintf(out, ", status %N",
- cert_status_names, this->status);
-
- switch (this->status)
- {
- case CERT_GOOD:
- fprintf(out, " until %#T", &this->until, utc);
- break;
- case CERT_REVOKED:
- fprintf(out, " on %#T", &this->until, utc);
- break;
- case CERT_UNKNOWN:
- case CERT_UNDEFINED:
- case CERT_UNTRUSTED:
- default:
- break;
- }
-}
-
-/**
- * Implements x509_t.add_subjectAltNames.
- */
-static void add_subjectAltNames(private_x509_t *this, linked_list_t *subjectAltNames)
-{
- iterator_t *iterator = subjectAltNames->create_iterator(subjectAltNames, TRUE);
- identification_t *name = NULL;
-
- while (iterator->iterate(iterator, (void**)&name))
- {
- name = name->clone(name);
- this->subjectAltNames->insert_last(this->subjectAltNames, (void*)name);
- }
- iterator->destroy(iterator);
-}
-
-/*
- * Defined in header.
- */
-chunk_t x509_build_generalNames(linked_list_t *list)
-{
- linked_list_t *generalNames = linked_list_create();
- iterator_t *iterator = list->create_iterator(list, TRUE);
- identification_t *name;
- chunk_t names = chunk_empty;
- size_t len = 0;
-
- while (iterator->iterate(iterator, (void**)&name))
- {
- asn1_t asn1_type = ASN1_EOC;
- chunk_t *generalName;
-
- switch (name->get_type(name))
- {
- case ID_RFC822_ADDR:
- asn1_type = ASN1_CONTEXT_S_1;
- break;
- case ID_FQDN:
- asn1_type = ASN1_CONTEXT_S_2;
- break;
- case ID_DER_ASN1_DN:
- asn1_type = ASN1_CONTEXT_C_4;
- break;
- case ID_DER_ASN1_GN_URI:
- asn1_type = ASN1_CONTEXT_S_6;
- break;
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- asn1_type = ASN1_CONTEXT_S_7;
- break;
- default:
- continue;
- }
-
- generalName = malloc_thing(chunk_t);
- *generalName = asn1_simple_object(asn1_type, name->get_encoding(name));
- len += generalName->len;
- generalNames->insert_last(generalNames, (void*)generalName);
- }
- iterator->destroy(iterator);
-
- if (len > 0)
- {
- iterator_t *iterator = generalNames->create_iterator(generalNames, TRUE);
- chunk_t *generalName;
- u_char *pos = build_asn1_object(&names, ASN1_SEQUENCE, len);
-
- while (iterator->iterate(iterator, (void**)&generalName))
- {
- memcpy(pos, generalName->ptr, generalName->len);
- pos += generalName->len;
- free(generalName->ptr);
- free(generalName);
- }
- iterator->destroy(iterator);
- }
- generalNames->destroy(generalNames);
- return names;
-}
-
-/*
- * Defined in header.
- */
-chunk_t x509_build_subjectAltNames(linked_list_t *list)
-{
- chunk_t generalNames = x509_build_generalNames(list);
-
- if (generalNames.len)
- {
- return asn1_wrap(ASN1_SEQUENCE, "cm",
- ASN1_subjectAltName_oid,
- asn1_wrap(ASN1_OCTET_STRING, "m", generalNames)
- );
- }
- else
- {
- return chunk_empty;
- }
-}
-
-/**
- * Build a to-be-signed X.509 certificate body
- */
-static chunk_t x509_build_tbs(private_x509_t *this)
-{
- /* version is always X.509v3 */
- chunk_t version = asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2);
-
- chunk_t extensions = chunk_empty;
-
- if (this->subjectAltNames->get_count(this->subjectAltNames))
- {
- extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m",
- asn1_wrap(ASN1_SEQUENCE, "m",
- x509_build_subjectAltNames(this->subjectAltNames)));
- }
-
- return asn1_wrap(ASN1_SEQUENCE, "mmccmcmm",
- version,
- asn1_simple_object(ASN1_INTEGER, this->serialNumber),
- asn1_algorithmIdentifier(this->signatureAlgorithm),
- this->issuer->get_encoding(this->issuer),
- asn1_wrap(ASN1_SEQUENCE, "mm",
- timetoasn1(&this->notBefore, ASN1_UTCTIME),
- timetoasn1(&this->notAfter, ASN1_UTCTIME)
- ),
- this->subject->get_encoding(this->subject),
- this->public_key->get_publicKeyInfo(this->public_key),
- extensions
- );
-}
-
-/**
- * Implementation of x509_t.build_encoding.
- */
-static void build_encoding(private_x509_t *this, hash_algorithm_t alg,
- rsa_private_key_t *private_key)
-{
- chunk_t signature;
-
- this->signatureAlgorithm = hasher_signature_algorithm_to_oid(alg);
- this->tbsCertificate = x509_build_tbs(this);
- private_key->build_emsa_pkcs1_signature(private_key, alg,
- this->tbsCertificate, &signature);
- this->signature = asn1_bitstring("m", signature);
- this->certificate = asn1_wrap(ASN1_SEQUENCE, "mcm",
- this->tbsCertificate,
- asn1_algorithmIdentifier(this->signatureAlgorithm),
- this->signature);
-
-}
-
-/**
- * Implements x509_t.destroy
- */
-static void destroy(private_x509_t *this)
-{
- this->subjectAltNames->destroy_offset(this->subjectAltNames,
- offsetof(identification_t, destroy));
- this->crlDistributionPoints->destroy_offset(this->crlDistributionPoints,
- offsetof(identification_t, destroy));
- this->ocspAccessLocations->destroy_offset(this->ocspAccessLocations,
- offsetof(identification_t, destroy));
- DESTROY_IF(this->issuer);
- DESTROY_IF(this->subject);
- DESTROY_IF(this->public_key);
- free(this->subjectKeyID.ptr);
- free(this->certificate.ptr);
- free(this);
-}
-
-/**
- * Internal generic constructor
- */
-static private_x509_t *x509_create_empty(void)
-{
- private_x509_t *this = malloc_thing(private_x509_t);
-
- /* initialize */
- this->subjectPublicKey = chunk_empty;
- this->public_key = NULL;
- this->subject = NULL;
- this->issuer = NULL;
- this->ca_info = NULL;
- this->subjectAltNames = linked_list_create();
- this->crlDistributionPoints = linked_list_create();
- this->ocspAccessLocations = linked_list_create();
- this->subjectKeyID = chunk_empty;
- this->authKeyID = chunk_empty;
- this->authKeySerialNumber = chunk_empty;
- this->authority_flags = AUTH_NONE;
- this->isCA = FALSE;
- this->isOcspSigner = FALSE;
-
- /* public functions */
- this->public.equals = (bool (*) (const x509_t*,const x509_t*))equals;
- this->public.equals_subjectAltName = (bool (*) (const x509_t*,identification_t*))equals_subjectAltName;
- this->public.is_issuer = (bool (*) (const x509_t*,const x509_t*))is_issuer;
- this->public.is_valid = (err_t (*) (const x509_t*,time_t*))is_valid;
- this->public.is_ca = (bool (*) (const x509_t*))is_ca;
- this->public.is_self_signed = (bool (*) (const x509_t*))is_self_signed;
- this->public.is_ocsp_signer = (bool (*) (const x509_t*))is_ocsp_signer;
- this->public.get_certificate = (chunk_t (*) (const x509_t*))get_certificate;
- this->public.get_public_key = (rsa_public_key_t* (*) (const x509_t*))get_public_key;
- this->public.get_serialNumber = (chunk_t (*) (const x509_t*))get_serialNumber;
- this->public.get_subjectKeyID = (chunk_t (*) (const x509_t*))get_subjectKeyID;
- this->public.get_keyid = (chunk_t (*) (const x509_t*))get_keyid;
- this->public.get_issuer = (identification_t* (*) (const x509_t*))get_issuer;
- this->public.get_subject = (identification_t* (*) (const x509_t*))get_subject;
- this->public.set_ca_info = (void (*) (x509_t*,ca_info_t*))set_ca_info;
- this->public.get_ca_info = (ca_info_t* (*) (const x509_t*))get_ca_info;
- this->public.set_until = (void (*) (x509_t*,time_t))set_until;
- this->public.get_until = (time_t (*) (const x509_t*))get_until;
- this->public.set_status = (void (*) (x509_t*,cert_status_t))set_status;
- this->public.get_status = (cert_status_t (*) (const x509_t*))get_status;
- this->public.add_authority_flags = (void (*) (x509_t*,u_int))add_authority_flags;
- this->public.get_authority_flags = (u_int (*) (x509_t*))get_authority_flags;
- this->public.has_authority_flag = (bool (*) (x509_t*,u_int))has_authority_flag;
- this->public.create_crluri_iterator = (iterator_t* (*) (const x509_t*))create_crluri_iterator;
- this->public.create_ocspuri_iterator = (iterator_t* (*) (const x509_t*))create_ocspuri_iterator;
- this->public.verify = (bool (*) (const x509_t*,const rsa_public_key_t*))verify;
- this->public.list = (void (*) (x509_t*, FILE *out, bool utc))list;
- this->public.add_subjectAltNames = (void (*) (x509_t*,linked_list_t*))add_subjectAltNames;
- this->public.build_encoding = (void (*) (x509_t*,hash_algorithm_t,rsa_private_key_t*))build_encoding;
- this->public.destroy = (void (*) (x509_t*))destroy;
-
- return this;
-}
-
-/*
- * Described in header.
- */
-x509_t *x509_create(chunk_t serialNumber, identification_t *issuer,
- time_t notBefore, time_t notAfter,
- identification_t *subject,
- rsa_public_key_t *public_key)
-{
- private_x509_t *this = x509_create_empty();
-
- this->serialNumber = serialNumber;
- this->issuer = issuer->clone(issuer);
- this->notBefore = notBefore;
- this->notAfter = notAfter;
- this->subject = subject->clone(subject);
- this->public_key = public_key->clone(public_key);
-
- return &this->public;
-}
-
-/*
- * Described in header.
- */
-x509_t *x509_create_from_chunk(chunk_t chunk, u_int level)
-{
- private_x509_t *this = x509_create_empty();
-
- if (!parse_certificate(chunk, level, this))
- {
- destroy(this);
- return NULL;
- }
-
- /* extract public key from certificate */
- this->public_key = rsa_public_key_create_from_chunk(this->subjectPublicKey);
- if (this->public_key == NULL)
- {
- destroy(this);
- return NULL;
- }
-
- /* set trusted lifetime of public key to notAfter */
- this->until = this->notAfter;
-
- /* check if the certificate is self-signed */
- this->isSelfSigned = FALSE;
- if (this->subject->equals(this->subject, this->issuer))
- {
- hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->signatureAlgorithm);
-
- if (algorithm == HASH_UNKNOWN)
- {
- destroy(this);
- return NULL;
- }
- this->isSelfSigned = this->public_key->verify_emsa_pkcs1_signature(this->public_key,
- algorithm, this->tbsCertificate, this->signature) == SUCCESS;
- }
- if (this->isSelfSigned)
- {
- DBG2(" certificate is self-signed");
- this->status = CERT_GOOD;
- }
- else
- {
- this->status = CERT_UNDEFINED;
- }
-
- return &this->public;
-}
-
-/*
- * Described in header.
- */
-x509_t *x509_create_from_file(const char *filename, const char *label)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
- char cert_label[BUF_LEN];
-
- snprintf(cert_label, BUF_LEN, "%s certificate", label);
-
- if (!pem_asn1_load_file(filename, NULL, cert_label, &chunk, &pgp))
- {
- return NULL;
- }
- return x509_create_from_chunk(chunk, 0);
-}
diff --git a/src/libstrongswan/crypto/x509.h b/src/libstrongswan/crypto/x509.h
deleted file mode 100755
index def45be6b..000000000
--- a/src/libstrongswan/crypto/x509.h
+++ /dev/null
@@ -1,406 +0,0 @@
-/**
- * @file x509.h
- *
- * @brief Interface of x509_t.
- *
- */
-
-/*
- * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
- * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
- * Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2006 Martin Willi
- * Copyright (C) 2000-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: x509.h 3421 2008-01-22 01:09:19Z andreas $
- */
-
-#ifndef X509_H_
-#define X509_H_
-
-typedef struct x509_t x509_t;
-
-#include <library.h>
-#include <crypto/rsa/rsa_private_key.h>
-#include <crypto/hashers/hasher.h>
-#include <crypto/certinfo.h>
-#include <crypto/ca.h>
-#include <utils/identification.h>
-#include <utils/iterator.h>
-#include <utils/linked_list.h>
-
-/* authority flags */
-
-#define AUTH_NONE 0x00 /* no authorities */
-#define AUTH_CA 0x01 /* certification authority */
-#define AUTH_AA 0x02 /* authorization authority */
-#define AUTH_OCSP 0x04 /* ocsp signing authority */
-
-/**
- * @brief X.509 certificate.
- *
- * @b Constructors:
- * - x509_create()
- * - x509_create_from_chunk()
- * - x509_create_from_file()
- *
- * @ingroup crypto
- */
-struct x509_t {
-
- /**
- * @brief Set trusted public key life.
- *
- * @param this calling object
- * @param until time until public key is trusted
- */
- void (*set_until) (x509_t *this, time_t until);
-
- /**
- * @brief Get trusted public key life.
- *
- * @param this calling object
- * @return time until public key is trusted
- */
- time_t (*get_until) (const x509_t *this);
-
- /**
- * @brief Set the certificate status
- *
- * @param this calling object
- * @param status certificate status
- */
- void (*set_status) (x509_t *this, cert_status_t status);
-
- /**
- * @brief Get the certificate status
- *
- * @param this calling object
- * @return certificate status
- */
- cert_status_t (*get_status) (const x509_t *this);
-
- /**
- * @brief Add authority flags
- *
- * @param this calling object
- * @param flag flags to be added
- */
- void (*add_authority_flags) (x509_t *this, u_int flags);
-
- /**
- * @brief Get authority flags
- *
- * @param this calling object
- * @return authority flags
- */
- u_int (*get_authority_flags) (x509_t *this);
-
- /**
- * @brief Check a specific authority flag
- *
- * @param this calling object
- * @param flag flag to be checked
- * @return TRUE if flag is present
- */
- bool (*has_authority_flag) (x509_t *this, u_int flag);
-
- /**
- * @brief Get the DER-encoded X.509 certificate body
- *
- * @param this calling object
- * @return DER-encoded X.509 certificate
- */
- chunk_t (*get_certificate) (const x509_t *this);
-
- /**
- * @brief Get the RSA public key from the certificate.
- *
- * @param this calling object
- * @return public_key
- */
- rsa_public_key_t *(*get_public_key) (const x509_t *this);
-
- /**
- * @brief Get serial number from the certificate.
- *
- * @param this calling object
- * @return serialNumber
- */
- chunk_t (*get_serialNumber) (const x509_t *this);
-
- /**
- * @brief Get subjectKeyID from the certificate.
- *
- * @param this calling object
- * @return subjectKeyID
- */
- chunk_t (*get_subjectKeyID) (const x509_t *this);
-
- /**
- * @brief Get keyid from the certificate's public key.
- *
- * @param this calling object
- * @return keyid
- */
- chunk_t (*get_keyid) (const x509_t *this);
-
- /**
- * @brief Get the issuerDistinguishedName
- *
- * The resulting ID is always a identification_t
- * of type ID_DER_ASN1_DN.
- *
- * @param this calling object
- * @return issuers ID
- */
- identification_t *(*get_issuer) (const x509_t *this);
-
- /**
- * @brief Get the subjectDistinguishedName.
- *
- * The resulting ID is always a identification_t
- * of type ID_DER_ASN1_DN.
- *
- * @param this calling object
- * @return subjects ID
- */
- identification_t *(*get_subject) (const x509_t *this);
-
- /**
- * @brief Set a link ca info
- *
- * @param this calling object
- * @param ca_info link to the info record of the issuing ca
- */
- void (*set_ca_info) (x509_t *this, ca_info_t *ca_info);
-
- /**
- * @brief Get the .
- *
- * The resulting ID is always a identification_t
- * of type ID_DER_ASN1_DN.
- *
- * @param this calling object
- * @return link to the info record of the issuing ca
- * or NULL if it does not [yet] exist
- */
- ca_info_t *(*get_ca_info) (const x509_t *this);
-
- /**
- * @brief Create an iterator for the crlDistributionPoints.
- *
- * @param this calling object
- * @return iterator for crlDistributionPoints
- */
- iterator_t *(*create_crluri_iterator) (const x509_t *this);
-
- /**
- * @brief Create an iterator for the ocspAccessLocations.
- *
- * @param this calling object
- * @return iterator for ocspAccessLocations
- */
- iterator_t *(*create_ocspuri_iterator) (const x509_t *this);
-
- /**
- * @brief Check if a certificate is trustworthy
- *
- * @param this calling object
- * @param signer signer's RSA public key
- */
- bool (*verify) (const x509_t *this, const rsa_public_key_t *signer);
-
- /**
- * @brief Compare two certificates.
- *
- * Comparison is done via the certificates signature.
- *
- * @param this first cert for compare
- * @param other second cert for compare
- * @return TRUE if signature is equal
- */
- bool (*equals) (const x509_t *this, const x509_t *that);
-
- /**
- * @brief Checks if the certificate contains a subjectAltName equal to id.
- *
- * @param this certificate being examined
- * @param id id which is being compared to the subjectAltNames
- * @return TRUE if a match is found
- */
- bool (*equals_subjectAltName) (const x509_t *this, identification_t *id);
-
- /**
- * @brief Checks if the subject of the other cert is the issuer of this cert.
- *
- * @param this certificate
- * @param issuer potential issuer certificate
- * @return TRUE if issuer is found
- */
- bool (*is_issuer) (const x509_t *this, const x509_t *issuer);
-
- /**
- * @brief Checks the validity interval of the certificate
- *
- * @param this certificate being examined
- * @param until until = min(until, notAfter)
- * @return NULL if the certificate is valid
- */
- err_t (*is_valid) (const x509_t *this, time_t *until);
-
- /**
- * @brief Returns the CA basic constraints flag
- *
- * @param this certificate being examined
- * @return TRUE if the CA flag is set
- */
- bool (*is_ca) (const x509_t *this);
-
- /**
- * @brief Returns the OCSPSigner extended key usage flag
- *
- * @param this certificate being examined
- * @return TRUE if the OCSPSigner flag is set
- */
- bool (*is_ocsp_signer) (const x509_t *this);
-
- /**
- * @brief Checks if the certificate is self-signed (subject equals issuer)
- *
- * @param this certificate being examined
- * @return TRUE if self-signed
- */
- bool (*is_self_signed) (const x509_t *this);
-
- /**
- * @brief Log the certificate info to out.
- *
- * @param this calling object
- * @param out stream to write to
- * @param utc TRUE for UTC times, FALSE for local time
- */
- void (*list) (x509_t *this, FILE *out, bool utc);
-
- /**
- * @brief Adds a list of subjectAltNames
- *
- * @param this calling object
- * @param subjectAltNames list of subjectAltNames to be added
- */
- void (*add_subjectAltNames) (x509_t *this, linked_list_t *subjectAltNames);
-
- /**
- * @brief Builds a DER-encoded signed X.509 certificate
- *
- * @param this calling object
- * @param alg hash algorithm used to compute the certificate digest
- * @param private_key RSA private key used to sign the certificate digest
- */
- void (*build_encoding) (x509_t *this, hash_algorithm_t alg, rsa_private_key_t *private_key);
-
- /**
- * @brief Destroys the certificate.
- *
- * @param this certificate to destroy
- */
- void (*destroy) (x509_t *this);
-};
-
-/**
- * @brief Create a X.509 certificate from its components
- *
- * @param serialNumber chunk containing the serialNumber
- * @param issuer issuer distinguished name
- * @param notBefore start date of validity
- * @param notAfter end date of validity
- * @param subject subject distinguished name
- * @param public_key public key
- *
- * @return created x509_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509_t *x509_create(chunk_t serialNumber, identification_t *issuer,
- time_t notBefore, time_t notAfter,
- identification_t *subject,
- rsa_public_key_t *public_key);
-
-/**
- * @brief Read a X.509 certificate from a DER encoded blob.
- *
- * @param chunk chunk containing DER encoded data
- * @return created x509_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509_t *x509_create_from_chunk(chunk_t chunk, u_int level);
-
-/**
- * @brief Read a X.509 certificate from a DER encoded file.
- *
- * @param filename file containing DER encoded data
- * @param label label describing kind of certificate
- * @return created x509_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509_t *x509_create_from_file(const char *filename, const char *label);
-
-/**
- * @brief Parses a DER encoded authorityKeyIdentifier
- *
- * @param blob blob containing DER encoded data
- * @param level0 indicates the current parsing level
- * @param authKeyID assigns the authorityKeyIdentifier
- * @param authKeySerialNumber assigns the authKeySerialNumber
- *
- * @ingroup crypto
- */
-void x509_parse_authorityKeyIdentifier(chunk_t blob, int level0, chunk_t *authKeyID, chunk_t *authKeySerialNumber);
-
-/**
- * @brief Parses DER encoded generalNames
- *
- * @param blob blob containing DER encoded data
- * @param level0 indicates the current parsing level
- * @param implicit implicit coding is used
- * @param list list of decoded generalNames
- *
- * @ingroup crypto
- */
-void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list);
-
-/**
- * @brief Builds a DER encoded list of generalNames
- *
- * @param list list of generalNames to be encoded
- * @return DER encoded list of generalNames
- *
- * @ingroup crypto
- */
-chunk_t x509_build_generalNames(linked_list_t *list);
-
-/**
- * @brief Builds a DER encoded list of subjectAltNames
- *
- * @param list list of subjectAltNames to be encoded
- * @return DER encoded list of subjectAltNames
- *
- * @ingroup crypto
- */
-chunk_t x509_build_subjectAltNames(linked_list_t *list);
-
-#endif /* X509_H_ */
diff --git a/src/libstrongswan/database/database.h b/src/libstrongswan/database/database.h
new file mode 100644
index 000000000..1cf5c2542
--- /dev/null
+++ b/src/libstrongswan/database/database.h
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup databasei database
+ * @{ @ingroup database
+ */
+
+#ifndef DATABASE_H_
+#define DATABASE_H_
+
+typedef enum db_type_t db_type_t;
+typedef struct database_t database_t;
+
+#include <utils/enumerator.h>
+
+/**
+ * Database column types
+ */
+enum db_type_t {
+ /** integer type, argument is an "int" */
+ DB_INT,
+ /** unsigned integer, argument is an "u_int" */
+ DB_UINT,
+ /** string type, argument is a "char*" */
+ DB_TEXT,
+ /** binary large object type, argument is a "chunk_t" */
+ DB_BLOB,
+ /** floating point, argument is a "double" */
+ DB_DOUBLE,
+ /** NULL, takes no argument */
+ DB_NULL,
+};
+
+
+/**
+ * Interface for a database implementation.
+ *
+ * @code
+ int affected, rowid, aint;
+ char *atext;
+ database_t *db;
+ enumerator_t *enumerator;
+
+ db = lib->database->create("mysql://user:pass@host/database");
+ affected = db->execute(db, &rowid, "INSERT INTO table VALUES (?, ?)",
+ DB_INT, 77, DB_TEXT, "a text");
+ printf("inserted %d row, new row ID: %d\n", affected, rowid);
+
+ enumerator = db->query(db, "SELECT aint, atext FROM table WHERE aint > ?",
+ DB_INT, 10, // 1 argument to SQL string
+ DB_INT, DB_TEXT); // 2 enumerated types in query
+ if (enumerator)
+ {
+ while (enumerator->enumerate(enumerator, &aint, &atext))
+ {
+ printf("%d: %s\n", aint, atext);
+ }
+ enumerator->destroy(enumerator);
+ }
+ @endcode
+ */
+struct database_t {
+
+ /**
+ * Run a query which returns rows, such as a SELECT.
+ *
+ * @param sql sql query string, containing '?' placeholders
+ * @param ... list of sql placeholder db_type_t followed by its value,
+ * followed by enumerators arguments as db_type_t's
+ * @return enumerator as defined with arguments, NULL on failure
+ */
+ enumerator_t* (*query)(database_t *this, char *sql, ...);
+
+ /**
+ * Execute a query which dows not return rows, such as INSERT.
+ *
+ * @param rowid pointer to write inserted AUTO_INCREMENT row ID, or NULL
+ * @param sql sql string, containing '?' placeholders
+ * @param ... list of sql placeholder db_type_t followed by its value
+ * @return number of affected rows, < 0 on failure
+ */
+ int (*execute)(database_t *this, int *rowid, char *sql, ...);
+
+ /**
+ * Destroy a database connection.
+ */
+ void (*destroy)(database_t *this);
+};
+
+#endif /* DATABASE_H_ @}*/
diff --git a/src/libstrongswan/database/database_factory.c b/src/libstrongswan/database/database_factory.c
new file mode 100644
index 000000000..9ceb829c6
--- /dev/null
+++ b/src/libstrongswan/database/database_factory.c
@@ -0,0 +1,119 @@
+/*
+ * 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: database_factory.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "database_factory.h"
+
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+
+typedef struct private_database_factory_t private_database_factory_t;
+
+/**
+ * private data of database_factory
+ */
+struct private_database_factory_t {
+
+ /**
+ * public functions
+ */
+ database_factory_t public;
+
+ /**
+ * list of registered database_t implementations
+ */
+ linked_list_t *databases;
+
+ /**
+ * mutex to lock access to databases
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * Implementation of database_factory_t.create.
+ */
+static database_t* create(private_database_factory_t *this, char *uri)
+{
+ enumerator_t *enumerator;
+ database_t *database = NULL;
+ database_constructor_t create;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->databases->create_enumerator(this->databases);
+ while (enumerator->enumerate(enumerator, &create))
+ {
+ database = create(uri);
+ if (database)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return database;
+}
+
+/**
+ * Implementation of database_factory_t.add_database.
+ */
+static void add_database(private_database_factory_t *this,
+ database_constructor_t create)
+{
+ this->mutex->lock(this->mutex);
+ this->databases->insert_last(this->databases, create);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of database_factory_t.remove_database.
+ */
+static void remove_database(private_database_factory_t *this,
+ database_constructor_t create)
+{
+ this->mutex->lock(this->mutex);
+ this->databases->remove(this->databases, create, NULL);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of database_factory_t.destroy
+ */
+static void destroy(private_database_factory_t *this)
+{
+ this->databases->destroy(this->databases);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+database_factory_t *database_factory_create()
+{
+ private_database_factory_t *this = malloc_thing(private_database_factory_t);
+
+ this->public.create = (database_t*(*)(database_factory_t*, char *url))create;
+ this->public.add_database = (void(*)(database_factory_t*, database_constructor_t))add_database;
+ this->public.remove_database = (void(*)(database_factory_t*, database_constructor_t))remove_database;
+ this->public.destroy = (void(*)(database_factory_t*))destroy;
+
+ this->databases = linked_list_create();
+ this->mutex = mutex_create(MUTEX_DEFAULT);
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/database/database_factory.h b/src/libstrongswan/database/database_factory.h
new file mode 100644
index 000000000..358f49054
--- /dev/null
+++ b/src/libstrongswan/database/database_factory.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.
+ */
+
+/**
+ * @defgroup database_factory database_factory
+ * @{ @ingroup database
+ */
+
+#ifndef DATABASE_FACTORY_H_
+#define DATABASE_FACTORY_H_
+
+typedef struct database_factory_t database_factory_t;
+
+#include <database/database.h>
+
+/**
+ * Generic database construction function.
+ *
+ * @param uri implementation specific connection URI
+ */
+typedef database_t*(*database_constructor_t)(char *uri);
+
+/**
+ * Create instances of database connections using registered constructors.
+ */
+struct database_factory_t {
+
+ /**
+ * Create a database connection instance.
+ *
+ * @param uri implementation specific connection URI
+ * @return database_t instance, NULL if not supported/failed
+ */
+ database_t* (*create)(database_factory_t *this, char *uri);
+
+ /**
+ * Register a database constructor.
+ *
+ * @param create database constructor to register
+ */
+ void (*add_database)(database_factory_t *this, database_constructor_t create);
+
+ /**
+ * Unregister a previously registered database constructor.
+ *
+ * @param create database constructor to unregister
+ */
+ void (*remove_database)(database_factory_t *this, database_constructor_t create);
+
+ /**
+ * Destroy a database_factory instance.
+ */
+ void (*destroy)(database_factory_t *this);
+};
+
+/**
+ * Create a database_factory instance.
+ */
+database_factory_t *database_factory_create();
+
+#endif /* DATABASE_FACTORY_H_ @}*/
diff --git a/src/libstrongswan/debug.c b/src/libstrongswan/debug.c
index a71e978b8..e20bef2da 100644
--- a/src/libstrongswan/debug.c
+++ b/src/libstrongswan/debug.c
@@ -1,10 +1,3 @@
-/**
- * @file library.c
- *
- * @brief Logging functions for the library.
- *
- */
-
/*
* 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: debug.c 4058 2008-06-11 14:09:46Z martin $
*/
#include <stdarg.h>
@@ -30,12 +25,15 @@
*/
void dbg_default(int level, char *fmt, ...)
{
- va_list args;
+ if (level <= 1)
+ {
+ va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, "\n");
- va_end(args);
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ va_end(args);
+ }
}
void (*dbg) (int level, char *fmt, ...) = dbg_default;
diff --git a/src/libstrongswan/debug.h b/src/libstrongswan/debug.h
index 71f2c7dfd..b120cc601 100644
--- a/src/libstrongswan/debug.h
+++ b/src/libstrongswan/debug.h
@@ -1,10 +1,3 @@
-/**
- * @file log.h
- *
- * @brief Logging functions for the library.
- *
- */
-
/*
* 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: debug.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup debug debug
+ * @{ @ingroup libstrongswan
*/
#ifndef DEBUG_H_
@@ -60,4 +60,4 @@ extern void (*dbg) (int level, char *fmt, ...);
/** default logging function, prints to stderr */
void dbg_default(int level, char *fmt, ...);
-#endif /* DEBUG_H_ */
+#endif /* DEBUG_H_ @} */
diff --git a/src/libstrongswan/enum.c b/src/libstrongswan/enum.c
index ade7c16a1..5eb283807 100644
--- a/src/libstrongswan/enum.c
+++ b/src/libstrongswan/enum.c
@@ -1,10 +1,3 @@
-/**
- * @file library.c
- *
- * @brief enum value to string conversion functions.
- *
- */
-
/*
* 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: enum.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
@@ -46,7 +41,7 @@ static char *enum_name(enum_name_t *e, int val)
/**
* output handler in printf() for enum names
*/
-static int print_enum(FILE *stream, const struct printf_info *info,
+static int print(FILE *stream, const struct printf_info *info,
const void *const *args)
{
enum_name_t *ed = *((enum_name_t**)(args[0]));
@@ -65,9 +60,25 @@ static int print_enum(FILE *stream, const struct printf_info *info,
}
/**
- * register printf() handlers
+ * arginfo handler for printf() hook
+ */
+static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (n > 1)
+ {
+ argtypes[0] = PA_POINTER;
+ argtypes[1] = PA_INT;
+ }
+ return 2;
+}
+
+/**
+ * return printf hook functions
*/
-static void __attribute__ ((constructor))print_register()
+printf_hook_functions_t enum_get_printf_hooks()
{
- register_printf_function(PRINTF_ENUM, print_enum, arginfo_ptr_int);
+ printf_hook_functions_t hooks = {print, arginfo};
+
+ return hooks;
}
+
diff --git a/src/libstrongswan/enum.h b/src/libstrongswan/enum.h
index cd06e424b..5e44293c0 100644
--- a/src/libstrongswan/enum.h
+++ b/src/libstrongswan/enum.h
@@ -1,12 +1,5 @@
-/**
- * @file enum.h
- *
- * @brief enum value to string conversion functions.
- *
- */
-
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,15 +11,24 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: enum.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup enum enum
+ * @{ @ingroup libstrongswan
*/
#ifndef ENUM_H_
#define ENUM_H_
+#include <printf_hook.h>
+
typedef struct enum_name_t enum_name_t;
/**
- * @brief Struct to store names for enums.
+ * Struct to store names for enums.
*
* To print the string representation of enumeration values, the strings
* are stored in these structures. Every enum_name contains a range
@@ -34,14 +36,16 @@ typedef struct enum_name_t enum_name_t;
* Use the convenience macros to define these linked ranges.
*
* For a single range, use:
- * ENUM(name, first, last, string1, string2, ...)
- *
+ * @code
+ ENUM(name, first, last, string1, string2, ...)
+ @endcode
* For multiple linked ranges, use:
- * ENUM_BEGIN(name, first, last, string1, string2, ...)
- * ENUM_NEXT(name, first, last, last_from_previous, string3, ...)
- * ENUM_NEXT(name, first, last, last_from_previous, string4, ...)
- * ENUM_END(name, last_from_previous)
- *
+ * @code
+ ENUM_BEGIN(name, first, last, string1, string2, ...)
+ ENUM_NEXT(name, first, last, last_from_previous, string3, ...)
+ ENUM_NEXT(name, first, last, last_from_previous, string4, ...)
+ ENUM_END(name, last_from_previous)
+ @endcode
* The ENUM and the ENUM_END define a enum_name_t pointer with the name supplied
* in "name".
*
@@ -62,7 +66,7 @@ struct enum_name_t {
};
/**
- * @brief Begin a new enum_name list.
+ * Begin a new enum_name list.
*
* @param name name of the enum_name list
* @param first enum value of the first enum string
@@ -72,7 +76,7 @@ struct enum_name_t {
#define ENUM_BEGIN(name, first, last, ...) static enum_name_t name##last = {first, last, NULL, { __VA_ARGS__ }}
/**
- * @brief Continue a enum name list startetd with ENUM_BEGIN.
+ * Continue a enum name list startetd with ENUM_BEGIN.
*
* @param name name of the enum_name list
* @param first enum value of the first enum string
@@ -83,7 +87,7 @@ struct enum_name_t {
#define ENUM_NEXT(name, first, last, prev, ...) static enum_name_t name##last = {first, last, &name##prev, { __VA_ARGS__ }}
/**
- * @brief Complete enum name list started with ENUM_BEGIN.
+ * Complete enum name list started with ENUM_BEGIN.
*
* @param name name of the enum_name list
* @param prev enum value of the "last" defined in ENUM_BEGIN/previous ENUM_NEXT
@@ -91,7 +95,7 @@ struct enum_name_t {
#define ENUM_END(name, prev) enum_name_t *name = &name##prev;
/**
- * @brief Define a enum name with only one range.
+ * Define a enum name with only one range.
*
* This is a convenience macro to use when a enum_name list contains only
* one range, and is equal as defining ENUM_BEGIN followed by ENUM_END.
@@ -103,4 +107,13 @@ struct enum_name_t {
*/
#define ENUM(name, first, last, ...) ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last)
-#endif /* ENUM_H_ */
+/**
+ * Get printf hook functions for enum_names_t.
+ *
+ * The handler takes the arguments: enum_names_t *names, int value
+ *
+ * @return printf hook functions
+ */
+printf_hook_functions_t enum_get_printf_hooks();
+
+#endif /* ENUM_H_ @}*/
diff --git a/src/libstrongswan/fetcher/fetcher.h b/src/libstrongswan/fetcher/fetcher.h
new file mode 100644
index 000000000..4fc37e35e
--- /dev/null
+++ b/src/libstrongswan/fetcher/fetcher.h
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup fetcheri fetcher
+ * @{ @ingroup fetcher
+ */
+
+#ifndef FETCHER_H_
+#define FETCHER_H_
+
+typedef struct fetcher_t fetcher_t;
+typedef enum fetcher_option_t fetcher_option_t;
+
+#include <stdarg.h>
+
+#include <library.h>
+
+/**
+ * Fetching options to use for fetcher_t.fetch() call.
+ */
+enum fetcher_option_t {
+
+ /**
+ * Data to include in fetch request, e.g. on a HTTP post.
+ * Additional argument is a chunk_t
+ */
+ FETCH_REQUEST_DATA,
+
+ /**
+ * Mime-Type of data included in FETCH_REQUEST_DATA.
+ * Additional argument is a char*.
+ */
+ FETCH_REQUEST_TYPE,
+
+ /**
+ * Timeout to use for fetch, in seconds.
+ * Additional argument is u_int
+ */
+ FETCH_TIMEOUT,
+
+ /**
+ * end of fetching options
+ */
+ FETCH_END,
+};
+
+/**
+ * Constructor function which creates fetcher instances.
+ *
+ * @return fetcher instance
+ */
+typedef fetcher_t* (*fetcher_constructor_t)();
+
+/**
+ * Fetcher interface, an implementation fetches data from an URL.
+ */
+struct fetcher_t {
+
+ /**
+ * Fetch data from URI into chunk.
+ *
+ * The fetcher returns NOT_SUPPORTED to indicate that it is uncappable
+ * to handle such URLs. Other return values indicate a failure, and
+ * fetching of that URL gets cancelled.
+ *
+ * @param uri URI to fetch from
+ * @param result chunk which receives allocated data
+ * @return
+ * - SUCCESS if fetch was successful
+ * - NOT_SUPPORTED if fetcher does not support such URLs
+ * - FAILED, NOT_FOUND, PARSE_ERROR on failure
+ */
+ status_t (*fetch)(fetcher_t *this, char *uri, chunk_t *result);
+
+ /**
+ * Set a fetcher option, as defined in fetcher_option_t.
+ *
+ * Arguments passed to options must stay in memory until fetch() returns.
+ *
+ * @param option option to set
+ * @param ... variable argument(s) to option
+ * @return TRUE if option supported, FALSE otherwise
+ */
+ bool (*set_option)(fetcher_t *this, fetcher_option_t option, ...);
+
+ /**
+ * Destroy the fetcher instance.
+ */
+ void (*destroy)(fetcher_t *this);
+};
+
+#endif /* FETCHER_H_ @}*/
diff --git a/src/libstrongswan/fetcher/fetcher_manager.c b/src/libstrongswan/fetcher/fetcher_manager.c
new file mode 100644
index 000000000..517c9dfc9
--- /dev/null
+++ b/src/libstrongswan/fetcher/fetcher_manager.c
@@ -0,0 +1,208 @@
+/*
+ * 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: fetcher_manager.c 3630 2008-03-20 11:27:55Z martin $
+ */
+
+#define _GNU_SOURCE
+
+#include "fetcher_manager.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+
+typedef struct private_fetcher_manager_t private_fetcher_manager_t;
+
+/**
+ * private data of fetcher_manager
+ */
+struct private_fetcher_manager_t {
+
+ /**
+ * public functions
+ */
+ fetcher_manager_t public;
+
+ /**
+ * list of registered fetchers, as entry_t
+ */
+ linked_list_t *fetchers;
+
+ /**
+ * read write lock to list
+ */
+ pthread_rwlock_t lock;
+};
+
+typedef struct {
+ /** assocaited fetcher construction function */
+ fetcher_constructor_t create;
+ /** URL this fetcher support */
+ char *url;
+} entry_t;
+
+/**
+ * destroy an entry_t
+ */
+static void entry_destroy(entry_t *entry)
+{
+ free(entry->url);
+ free(entry);
+}
+
+/**
+ * Implementation of fetcher_manager_t.fetch.
+ */
+static status_t fetch(private_fetcher_manager_t *this,
+ char *url, chunk_t *response, ...)
+{
+ enumerator_t *enumerator;
+ status_t status = NOT_SUPPORTED;
+ entry_t *entry;
+ bool capable = FALSE;
+
+ pthread_rwlock_rdlock(&this->lock);
+ enumerator = this->fetchers->create_enumerator(this->fetchers);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ fetcher_option_t opt;
+ fetcher_t *fetcher;
+ bool good = TRUE;
+ va_list args;
+
+ /* check URL support of fetcher */
+ if (strncasecmp(entry->url, url, strlen(entry->url)))
+ {
+ continue;
+ }
+ /* create fetcher instance and set options */
+ fetcher = entry->create();
+ if (!fetcher)
+ {
+ continue;
+ }
+ va_start(args, response);
+ while (good)
+ {
+ opt = va_arg(args, fetcher_option_t);
+ switch (opt)
+ {
+ case FETCH_REQUEST_DATA:
+ good = fetcher->set_option(fetcher, opt, va_arg(args, chunk_t));
+ continue;
+ case FETCH_REQUEST_TYPE:
+ good = fetcher->set_option(fetcher, opt, va_arg(args, char*));
+ continue;
+ case FETCH_TIMEOUT:
+ good = fetcher->set_option(fetcher, opt, va_arg(args, u_int));
+ continue;
+ case FETCH_END:
+ break;;
+ }
+ break;
+ }
+ va_end(args);
+ if (!good)
+ { /* fetcher does not support supplied options, try another */
+ fetcher->destroy(fetcher);
+ continue;
+ }
+
+ status = fetcher->fetch(fetcher, url, response);
+ fetcher->destroy(fetcher);
+ /* try another fetcher only if this one does not support that URL */
+ if (status == NOT_SUPPORTED)
+ {
+ continue;
+ }
+ capable = TRUE;
+ break;
+ }
+ enumerator->destroy(enumerator);
+ pthread_rwlock_unlock(&this->lock);
+ if (!capable)
+ {
+ DBG1("unable to fetch from %s, no capable fetcher found", url);
+ }
+ return status;
+}
+
+/**
+ * Implementation of fetcher_manager_t.add_fetcher.
+ */
+static void add_fetcher(private_fetcher_manager_t *this,
+ fetcher_constructor_t create, char *url)
+{
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->url = strdup(url);
+ entry->create = create;
+
+ pthread_rwlock_wrlock(&this->lock);
+ this->fetchers->insert_last(this->fetchers, entry);
+ pthread_rwlock_unlock(&this->lock);
+}
+
+/**
+ * Implementation of fetcher_manager_t.remove_fetcher.
+ */
+static void remove_fetcher(private_fetcher_manager_t *this,
+ fetcher_constructor_t create)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+
+ pthread_rwlock_wrlock(&this->lock);
+ enumerator = this->fetchers->create_enumerator(this->fetchers);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->fetchers->remove_at(this->fetchers, enumerator);
+ entry_destroy(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ pthread_rwlock_unlock(&this->lock);
+}
+
+/**
+ * Implementation of fetcher_manager_t.destroy
+ */
+static void destroy(private_fetcher_manager_t *this)
+{
+ this->fetchers->destroy_function(this->fetchers, (void*)entry_destroy);
+ pthread_rwlock_destroy(&this->lock);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+fetcher_manager_t *fetcher_manager_create()
+{
+ private_fetcher_manager_t *this = malloc_thing(private_fetcher_manager_t);
+
+ this->public.fetch = (status_t(*)(fetcher_manager_t*, char *url, chunk_t *response, ...))fetch;
+ this->public.add_fetcher = (void(*)(fetcher_manager_t*, fetcher_constructor_t,char*))add_fetcher;
+ this->public.remove_fetcher = (void(*)(fetcher_manager_t*, fetcher_constructor_t))remove_fetcher;
+ this->public.destroy = (void(*)(fetcher_manager_t*))destroy;
+
+ this->fetchers = linked_list_create();
+ pthread_rwlock_init(&this->lock, NULL);
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/fetcher/fetcher_manager.h b/src/libstrongswan/fetcher/fetcher_manager.h
new file mode 100644
index 000000000..e94d44494
--- /dev/null
+++ b/src/libstrongswan/fetcher/fetcher_manager.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup fetcher_manager fetcher_manager
+ * @{ @ingroup fetcher
+ */
+
+#ifndef FETCHER_MANAGER_H_
+#define FETCHER_MANAGER_H_
+
+typedef struct fetcher_manager_t fetcher_manager_t;
+
+#include <fetcher/fetcher.h>
+
+/**
+ * Fetches from URIs using registerd fetcher_t instances.
+ */
+struct fetcher_manager_t {
+
+ /**
+ * Fetch data from URI into chunk.
+ *
+ * The variable argument list contains fetcher_option_t's, followed
+ * by a option specific data argument.
+ *
+ * @param uri URI to fetch from
+ * @param result chunk which receives allocated data
+ * @param options FETCH_END terminated fetcher_option_t arguments
+ * @return status indicating result of fetch
+ */
+ status_t (*fetch)(fetcher_manager_t *this, char *url, chunk_t *response, ...);
+
+ /**
+ * Register a fetcher implementation.
+ *
+ * @param constructor fetcher constructor function
+ * @param url URL type this fetcher fetches, e.g. "http://"
+ */
+ void (*add_fetcher)(fetcher_manager_t *this,
+ fetcher_constructor_t constructor, char *url);
+
+ /**
+ * Unregister a previously registered fetcher implementation.
+ *
+ * @param constructor fetcher constructor function to unregister
+ */
+ void (*remove_fetcher)(fetcher_manager_t *this,
+ fetcher_constructor_t constructor);
+
+ /**
+ * Destroy a fetcher_manager instance.
+ */
+ void (*destroy)(fetcher_manager_t *this);
+};
+
+/**
+ * Create a fetcher_manager instance.
+ */
+fetcher_manager_t *fetcher_manager_create();
+
+#endif /* FETCHER_MANAGER_H_ @}*/
diff --git a/src/libstrongswan/fips/fips.c b/src/libstrongswan/fips/fips.c
index aba292d81..c268a7429 100644
--- a/src/libstrongswan/fips/fips.c
+++ b/src/libstrongswan/fips/fips.c
@@ -1,10 +1,3 @@
-/**
- * @file fips.c
- *
- * @brief Implementation of the libstrongswan integrity test.
- *
- */
-
/*
* Copyright (C) 2007 Bruno Krieg, Daniel Wydler
* Hochschule fuer Technik Rapperswil
@@ -18,12 +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: fips.c 3681 2008-03-28 10:21:04Z martin $
*/
#include <stdio.h>
#include <debug.h>
-#include <crypto/signers/hmac_signer.h>
+#include <crypto/signers/signer.h>
#include "fips.h"
extern const u_char FIPS_rodata_start[];
@@ -61,7 +56,7 @@ bool fips_compute_hmac_signature(const char *key, char *signature)
DBG1(" RODATA: %p + %6d = %p",
FIPS_rodata_start, (int)rodata_len, FIPS_rodata_end);
- signer = (signer_t *)hmac_signer_create(HASH_SHA1, HASH_SIZE_SHA1);
+ signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA1_128);
if (signer == NULL)
{
DBG1(" SHA-1 HMAC signer could not be created");
@@ -69,7 +64,7 @@ bool fips_compute_hmac_signature(const char *key, char *signature)
}
else
{
- chunk_t hmac_key = { key, strlen(key) };
+ chunk_t hmac_key = { (u_char *)key, strlen(key) };
chunk_t text_chunk = { text_start, text_len };
chunk_t rodata_chunk = { (u_char *)FIPS_rodata_start, rodata_len };
chunk_t signature_chunk = chunk_empty;
diff --git a/src/libstrongswan/fips/fips.h b/src/libstrongswan/fips/fips.h
index decf73bfd..a4ff440ba 100644
--- a/src/libstrongswan/fips/fips.h
+++ b/src/libstrongswan/fips/fips.h
@@ -1,11 +1,3 @@
-/**
- * @file fips.h
- *
- * @brief Interface of the libstrongswan integrity test
- *
- * @ingroup fips
- */
-
/*
* Copyright (C) 2007 Bruno Krieg, Daniel Wydler
* Hochschule fuer Technik Rapperswil
@@ -19,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: fips.h 3877 2008-04-26 09:40:22Z andreas $
+ */
+
+/**
+ * @defgroup fips1 fips
+ * @{ @ingroup fips
*/
#ifndef FIPS_H_
@@ -27,21 +26,21 @@
#include <library.h>
/**
- * @brief compute HMAC signature over RODATA and TEXT sections of libstrongswan
+ * compute HMAC signature over RODATA and TEXT sections of libstrongswan
*
- * @param key key used for HMAC signature in ASCII string format
- * @param signature HMAC signature in HEX string format
- * @return TRUE if HMAC signature computation was successful
+ * @param key key used for HMAC signature in ASCII string format
+ * @param signature HMAC signature in HEX string format
+ * @return TRUE if HMAC signature computation was successful
*/
bool fips_compute_hmac_signature(const char *key, char *signature);
/**
- * @brief verify HMAC signature over RODATA and TEXT sections of libstrongswan
+ * verify HMAC signature over RODATA and TEXT sections of libstrongswan
*
- * @param key key used for HMAC signature in ASCII string format
- * @param signature signature value from fips_signature.h in HEX string format
- * @return TRUE if signatures agree
+ * @param key key used for HMAC signature in ASCII string format
+ * @param signature signature value from fips_signature.h in HEX string format
+ * @return TRUE if signatures agree
*/
bool fips_verify_hmac_signature(const char *key, const char *signature);
-#endif /*FIPS_H_*/
+#endif /*FIPS_H_ @} */
diff --git a/src/libstrongswan/fips/fips_canister_end.c b/src/libstrongswan/fips/fips_canister_end.c
index 46d41a664..93f78e696 100644
--- a/src/libstrongswan/fips/fips_canister_end.c
+++ b/src/libstrongswan/fips/fips_canister_end.c
@@ -1,14 +1,9 @@
-/**
- * @file fips_canister_end.c
- *
- * @brief Marks the end of TEXT and RODATA.
- *
- */
-
/* ====================================================================
* Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
* and usage in source and binary forms are granted according to the
* OpenSSL license.
+ *
+ * $Id: fips_canister_end.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdio.h>
diff --git a/src/libstrongswan/fips/fips_canister_start.c b/src/libstrongswan/fips/fips_canister_start.c
index eaf2571f8..a15517ec1 100644
--- a/src/libstrongswan/fips/fips_canister_start.c
+++ b/src/libstrongswan/fips/fips_canister_start.c
@@ -1,14 +1,9 @@
-/**
- * @file fips_canister_start.c
- *
- * @brief Marks the start of TEXT and RODATA.
- *
- */
-
/* ====================================================================
* Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
* and usage in source and binary forms are granted according to the
* OpenSSL license.
+ *
+ * $Id: fips_canister_start.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdio.h>
diff --git a/src/libstrongswan/fips/fips_signer.c b/src/libstrongswan/fips/fips_signer.c
index 7fb61d5b7..81a5874f7 100644
--- a/src/libstrongswan/fips/fips_signer.c
+++ b/src/libstrongswan/fips/fips_signer.c
@@ -1,10 +1,3 @@
-/**
- * @file fips_signer.c
- *
- * @brief Computes a HMAC signature and stores it in fips_signature.h.
- *
- */
-
/*
* Copyright (C) 2007 Bruno Krieg, Daniel Wydler
* Hochschule fuer Technik Rapperswil, Switzerland
@@ -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: fips_signer.c 3964 2008-05-15 14:01:26Z martin $
*/
#include <stdio.h>
@@ -31,6 +26,10 @@ int main(int argc, char* argv[])
char *hmac_key = "strongSwan Version " VERSION;
char hmac_signature[BUF_LEN];
+ /* initialize library */
+ library_init(STRONGSWAN_CONF);
+ lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR, "sha1 hmac");
+
if (!fips_compute_hmac_signature(hmac_key, hmac_signature))
{
exit(1);
@@ -57,7 +56,9 @@ int main(int argc, char* argv[])
fprintf(f, "const char *hmac_key = \"%s\";\n", hmac_key);
fprintf(f, "const char *hmac_signature = \"%s\";\n", hmac_signature);
fprintf(f, "\n");
- fprintf(f, "#endif /* FIPS_SIGNATURE_H_ */\n");
+ fprintf(f, "#endif /* FIPS_SIGNATURE_H_ @} */\n");
fclose(f);
+
+ library_deinit();
exit(0);
}
diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c
index f66818bc2..cc3ee6bd6 100644
--- a/src/libstrongswan/library.c
+++ b/src/libstrongswan/library.c
@@ -1,13 +1,5 @@
-/**
- * @file library.c
- *
- * @brief Helper functions and definitions.
- *
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
+ * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -19,175 +11,101 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: library.c 3750 2008-04-04 11:38:16Z martin $
*/
-#include <string.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <pthread.h>
-
#include "library.h"
-#include <printf_hook.h>
+#include <stdlib.h>
-ENUM(status_names, SUCCESS, DESTROY_ME,
- "SUCCESS",
- "FAILED",
- "OUT_OF_RES",
- "ALREADY_DONE",
- "NOT_SUPPORTED",
- "INVALID_ARG",
- "NOT_FOUND",
- "PARSE_ERROR",
- "VERIFY_ERROR",
- "INVALID_STATE",
- "DESTROY_ME",
- "NEED_MORE",
-);
+#include <utils.h>
+#include <chunk.h>
+#include <utils/identification.h>
+#include <utils/host.h>
+#ifdef LEAK_DETECTIVE
+#include <utils/leak_detective.h>
+#endif
-/**
- * Described in header.
- */
-void *clalloc(void * pointer, size_t size)
-{
- void *data;
- data = malloc(size);
-
- memcpy(data, pointer,size);
-
- return (data);
-}
+typedef struct private_library_t private_library_t;
/**
- * Described in header.
+ * private data of library
*/
-void memxor(u_int8_t dest[], u_int8_t src[], size_t n)
-{
- size_t i;
- for (i = 0; i < n; i++)
- {
- dest[i] ^= src[i];
- }
-}
+struct private_library_t {
-/**
- * We use a single mutex for all refcount variables. This
- * is not optimal for performance, but the critical section
- * is not that long...
- * TODO: Consider to include a mutex in each refcount_t variable.
- */
-static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
+ /**
+ * public functions
+ */
+ library_t public;
-/**
- * Described in header.
- *
- * TODO: May be implemented with atomic CPU instructions
- * instead of a mutex.
- */
-void ref_get(refcount_t *ref)
-{
- pthread_mutex_lock(&ref_mutex);
- (*ref)++;
- pthread_mutex_unlock(&ref_mutex);
-}
+#ifdef LEAK_DETECTIVE
+ /**
+ * Memory leak detective, if enabled
+ */
+ leak_detective_t *detective;
+#endif /* LEAK_DETECTIVE */
+};
/**
- * Described in header.
- *
- * TODO: May be implemented with atomic CPU instructions
- * instead of a mutex.
+ * library instance
*/
-bool ref_put(refcount_t *ref)
-{
- bool more_refs;
-
- pthread_mutex_lock(&ref_mutex);
- more_refs = --(*ref);
- pthread_mutex_unlock(&ref_mutex);
- return !more_refs;
-}
+library_t *lib;
/**
- * output handler in printf() for time_t
+ * Implementation of library_t.destroy
*/
-static int print_time(FILE *stream, const struct printf_info *info,
- const void *const *args)
+void library_deinit()
{
- static const char* months[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
- time_t *time = *((time_t**)(args[0]));
- bool utc = TRUE;
- struct tm t;
+ private_library_t *this = (private_library_t*)lib;
+
+ this->public.plugins->destroy(this->public.plugins);
+ this->public.settings->destroy(this->public.settings);
+ this->public.creds->destroy(this->public.creds);
+ this->public.crypto->destroy(this->public.crypto);
+ this->public.fetcher->destroy(this->public.fetcher);
+ this->public.db->destroy(this->public.db);
+ this->public.printf_hook->destroy(this->public.printf_hook);
- if (info->alt)
- {
- utc = *((bool*)(args[1]));
- }
- if (time == UNDEFINED_TIME)
- {
- return fprintf(stream, "--- -- --:--:--%s----",
- info->alt ? " UTC " : " ");
- }
- if (utc)
- {
- gmtime_r(time, &t);
- }
- else
+#ifdef LEAK_DETECTIVE
+ if (this->detective)
{
- localtime_r(time, &t);
+ this->detective->destroy(this->detective);
}
- return fprintf(stream, "%s %02d %02d:%02d:%02d%s%04d",
- months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min,
- t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900);
+#endif /* LEAK_DETECTIVE */
+ free(this);
+ lib = NULL;
}
-/**
- * output handler in printf() for time deltas
+/*
+ * see header file
*/
-static int print_time_delta(FILE *stream, const struct printf_info *info,
- const void *const *args)
+void library_init(char *settings)
{
- char* unit = "second";
- time_t *arg1, *arg2;
- time_t delta;
+ printf_hook_t *pfh;
+ private_library_t *this = malloc_thing(private_library_t);
+ lib = &this->public;
- arg1 = *((time_t**)(args[0]));
- if (info->alt)
- {
- arg2 = *((time_t**)(args[1]));
- delta = abs(*arg1 - *arg2);
- }
- else
- {
- delta = *arg1;
- }
+#ifdef LEAK_DETECTIVE
+ this->detective = leak_detective_create();
+#endif /* LEAK_DETECTIVE */
- if (delta > 2 * 60 * 60 * 24)
- {
- delta /= 60 * 60 * 24;
- unit = "day";
- }
- else if (delta > 2 * 60 * 60)
- {
- delta /= 60 * 60;
- unit = "hour";
- }
- else if (delta > 2 * 60)
- {
- delta /= 60;
- unit = "minute";
- }
- return fprintf(stream, "%d %s%s", delta, unit, (delta == 1)? "":"s");
+ pfh = printf_hook_create();
+ this->public.printf_hook = pfh;
+
+ pfh->add_handler(pfh, 'b', mem_get_printf_hooks());
+ pfh->add_handler(pfh, 'B', chunk_get_printf_hooks());
+ pfh->add_handler(pfh, 'D', identification_get_printf_hooks());
+ pfh->add_handler(pfh, 'H', host_get_printf_hooks());
+ pfh->add_handler(pfh, 'N', enum_get_printf_hooks());
+ pfh->add_handler(pfh, 'T', time_get_printf_hooks());
+ pfh->add_handler(pfh, 'V', time_delta_get_printf_hooks());
+
+ this->public.crypto = crypto_factory_create();
+ this->public.creds = credential_factory_create();
+ this->public.fetcher = fetcher_manager_create();
+ this->public.db = database_factory_create();
+ this->public.settings = settings_create(settings);
+ this->public.plugins = plugin_loader_create();
}
-/**
- * register printf() handlers for time_t
- */
-static void __attribute__ ((constructor))print_register()
-{
- register_printf_function(PRINTF_TIME, print_time, arginfo_ptr_alt_ptr_int);
- register_printf_function(PRINTF_TIME_DELTA, print_time_delta, arginfo_ptr_alt_ptr_ptr);
-}
diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h
index 51b72bfce..6cb57ef20 100644
--- a/src/libstrongswan/library.h
+++ b/src/libstrongswan/library.h
@@ -1,12 +1,5 @@
-/**
- * @file library.h
- *
- * @brief Helper functions and definitions.
- *
- */
-
/*
- * 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
@@ -19,318 +12,119 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: library.h 3255 2007-10-07 13:35:42Z andreas $
+ * $Id: library.h 3589 2008-03-13 14:14:44Z martin $
*/
-#ifndef LIBRARY_H_
-#define LIBRARY_H_
-
/**
* @defgroup libstrongswan libstrongswan
*
- * libstrongswan: library with various cryptographic, X.509 trust chain and
- * identity management functions.
- */
-
-/**
* @defgroup asn1 asn1
- *
- * ASN.1 definitions, parser and generator functions.
- *
* @ingroup libstrongswan
- */
-
-/**
- * @defgroup crypto crypto
- *
- * Various cryptographic algorithms.
*
+ * @defgroup credentials credentials
* @ingroup libstrongswan
- */
-
-/**
- * @defgroup crypters crypters
- *
- * Symmetric encryption algorithms, used for
- * encryption and decryption.
- *
- * @ingroup crypto
- */
-
-/**
- * @defgroup hashers hashers
- *
- * Hashing algorithms, such as MD5 or SHA1
- *
- * @ingroup crypto
- */
-
-/**
- * @defgroup prfs prfs
- *
- * Pseudo random functions, used to generate
- * pseude random byte sequences.
- *
- * @ingroup crypto
- */
-
-/**
- * @defgroup rsa rsa
- *
- * RSA private/public key algorithm.
*
- * @ingroup crypto
- */
-
-/**
- * @defgroup signers signers
+ * @defgroup keys keys
+ * @ingroup credentials
*
- * Symmetric signing algorithms,
- * used to ensure message integrity.
+ * @defgroup certificates certificates
+ * @ingroup credentials
*
- * @ingroup crypto
- */
-
-/**
+ * @defgroup crypto crypto
+ * @ingroup libstrongswan
+
+ * @defgroup database database
+ * @ingroup libstrongswan
+
+ * @defgroup fetcher fetcher
+ * @ingroup libstrongswan
+
* @defgroup fips fips
- *
- * Code integrity check of libstrongswan
- *
* @ingroup libstrongswan
- */
-
-/**
+
+ * @defgroup plugins plugins
+ * @ingroup libstrongswan
+
* @defgroup utils utils
- *
- * Generic helper classes.
- *
* @ingroup libstrongswan
*/
-#include <gmp.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <printf.h>
-
-#include <enum.h>
-
-/**
- * Number of bits in a byte
- */
-#define BITS_PER_BYTE 8
-
-/**
- * Default length for various auxiliary text buffers
- */
-#define BUF_LEN 512
-
-/**
- * Macro compares two strings for equality
- */
-#define streq(x,y) (strcmp(x, y) == 0)
-
-/**
- * Macro compares two strings for equality
- */
-#define strneq(x,y,len) (strncmp(x, y, len) == 0)
-
-/**
- * Macro compares two binary blobs for equality
- */
-#define memeq(x,y,len) (memcmp(x, y, len) == 0)
-
-/**
- * Macro gives back larger of two values.
- */
-#define max(x,y) ((x) > (y) ? (x):(y))
-
-/**
- * Macro gives back smaller of two values.
- */
-#define min(x,y) ((x) < (y) ? (x):(y))
-
-/**
- * Call destructor of an object, if object != NULL
- */
-#define DESTROY_IF(obj) if (obj) obj->destroy(obj)
-
-/**
- * Call offset destructor of an object, if object != NULL
- */
-#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
-
/**
- * Call function destructor of an object, if object != NULL
+ * @defgroup library library
+ * @{ @ingroup libstrongswan
*/
-#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
-/**
- * Debug macro to follow control flow
- */
-#define POS printf("%s, line %d\n", __FILE__, __LINE__)
-
-/**
- * Macro to allocate a sized type.
- */
-#define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
+#ifndef LIBRARY_H_
+#define LIBRARY_H_
-/**
- * Assign a function as a class method
- */
-#define ASSIGN(method, function) (method = (typeof(method))function)
+#include <utils.h>
+#include <chunk.h>
+#include <settings.h>
+#include <printf_hook.h>
+#include <plugins/plugin_loader.h>
+#include <crypto/crypto_factory.h>
+#include <credentials/credential_factory.h>
+#include <fetcher/fetcher_manager.h>
+#include <database/database_factory.h>
-/**
- * time_t not defined
- */
-#define UNDEFINED_TIME 0
+typedef struct library_t library_t;
/**
- * General purpose boolean type.
+ * Libstrongswan library context, contains library relevant globals.
*/
-typedef int bool;
-#define FALSE 0
-#define TRUE 1
-
-typedef enum status_t status_t;
+struct library_t {
-/**
- * Return values of function calls.
- */
-enum status_t {
- /**
- * Call succeeded.
- */
- SUCCESS,
-
- /**
- * Call failed.
- */
- FAILED,
-
- /**
- * Out of resources.
- */
- OUT_OF_RES,
-
- /**
- * The suggested operation is already done
- */
- ALREADY_DONE,
-
/**
- * Not supported.
+ * Printf hook registering facility
*/
- NOT_SUPPORTED,
+ printf_hook_t *printf_hook;
/**
- * One of the arguments is invalid.
+ * crypto algorithm registry and factory
*/
- INVALID_ARG,
+ crypto_factory_t *crypto;
/**
- * Something could not be found.
+ * credential constructor registry and factory
*/
- NOT_FOUND,
+ credential_factory_t *creds;
/**
- * Error while parsing.
+ * URL fetching facility
*/
- PARSE_ERROR,
+ fetcher_manager_t *fetcher;
/**
- * Error while verifying.
+ * database construction factory
*/
- VERIFY_ERROR,
+ database_factory_t *db;
/**
- * Object in invalid state.
+ * plugin loading facility
*/
- INVALID_STATE,
+ plugin_loader_t *plugins;
/**
- * Destroy object which called method belongs to.
+ * various settings loaded from settings file
*/
- DESTROY_ME,
-
- /**
- * Another call to the method is required.
- */
- NEED_MORE,
+ settings_t *settings;
};
/**
- * used by strict_crl_policy
- */
-typedef enum {
- STRICT_NO,
- STRICT_YES,
- STRICT_IFURI
-} strict_t;
-
-/**
- * enum_names for type status_t.
- */
-extern enum_name_t *status_names;
-
-/**
- * deprecated pluto style return value:
- * error message, NULL for success
- */
-typedef const char *err_t;
-
-/**
- * Handle struct timeval like an own type.
- */
-typedef struct timeval timeval_t;
-
-/**
- * Handle struct timespec like an own type.
- */
-typedef struct timespec timespec_t;
-
-/**
- * Handle struct chunk_t like an own type.
- */
-typedef struct sockaddr sockaddr_t;
-
-/**
- * Clone a data to a newly allocated buffer
- */
-void *clalloc(void *pointer, size_t size);
-
-/**
- * Same as memcpy, but XORs src into dst instead of copy
- */
-void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
-
-/**
- * Special type to count references
+ * Initialize library, creates "lib" instance.
+ *
+ * @param settings file to read settings from, may be NULL for none
*/
-typedef volatile u_int refcount_t;
+void library_init(char *settings);
/**
- * @brief Get a new reference.
- *
- * Increments the reference counter atomic.
- *
- * @param ref pointer to ref counter
+ * Deinitialize library, destroys "lib" instance.
*/
-void ref_get(refcount_t *ref);
+void library_deinit();
/**
- * @brief Put back a unused reference.
- *
- * Decrements the reference counter atomic and
- * says if more references available.
- *
- * @param ref pointer to ref counter
- * @return TRUE if no more references counted
+ * Library instance, set after between library_init() and library_deinit() calls.
*/
-bool ref_put(refcount_t *ref);
-
-
-#include <chunk.h>
-#include <printf_hook.h>
+extern library_t *lib;
-#endif /* LIBRARY_H_ */
+#endif /* LIBRARY_H_ @}*/
diff --git a/src/libstrongswan/plugins/aes/Makefile.am b/src/libstrongswan/plugins/aes/Makefile.am
new file mode 100644
index 000000000..e73040f27
--- /dev/null
+++ b/src/libstrongswan/plugins/aes/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-aes.la
+
+libstrongswan_aes_la_SOURCES = aes_plugin.h aes_plugin.c aes_crypter.c aes_crypter.h
+libstrongswan_aes_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in
new file mode 100644
index 000000000..ed3dfb621
--- /dev/null
+++ b/src/libstrongswan/plugins/aes/Makefile.in
@@ -0,0 +1,494 @@
+# 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/libstrongswan/plugins/aes
+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_aes_la_LIBADD =
+am_libstrongswan_aes_la_OBJECTS = aes_plugin.lo aes_crypter.lo
+libstrongswan_aes_la_OBJECTS = $(am_libstrongswan_aes_la_OBJECTS)
+libstrongswan_aes_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_aes_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_aes_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_aes_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-aes.la
+libstrongswan_aes_la_SOURCES = aes_plugin.h aes_plugin.c aes_crypter.c aes_crypter.h
+libstrongswan_aes_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/libstrongswan/plugins/aes/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/aes/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-aes.la: $(libstrongswan_aes_la_OBJECTS) $(libstrongswan_aes_la_DEPENDENCIES)
+ $(libstrongswan_aes_la_LINK) -rpath $(plugindir) $(libstrongswan_aes_la_OBJECTS) $(libstrongswan_aes_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_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/libstrongswan/crypto/crypters/aes_cbc_crypter.c b/src/libstrongswan/plugins/aes/aes_crypter.c
index 947188af3..ce4c6da99 100644
--- a/src/libstrongswan/crypto/crypters/aes_cbc_crypter.c
+++ b/src/libstrongswan/plugins/aes/aes_crypter.c
@@ -1,11 +1,4 @@
-/**
- * @file aes_cbc_crypter.c
- *
- * @brief Implementation of aes_cbc_crypter_t
- *
- */
-
- /*
+/*
* Copyright (C) 2001 Dr B. R. Gladman <brg@gladman.uk.net>
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -20,11 +13,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: aes_crypter.c 3900 2008-04-30 14:02:25Z martin $
*/
-#include "aes_cbc_crypter.h"
-
-
+#include "aes_crypter.h"
/*
* The number of key schedule words for different block and key lengths
@@ -43,19 +36,19 @@
#define AES_BLOCK_SIZE 16
-typedef struct private_aes_cbc_crypter_t private_aes_cbc_crypter_t;
+typedef struct private_aes_crypter_t private_aes_crypter_t;
/**
- * @brief Class implementing the AES symmetric encryption algorithm.
+ * Class implementing the AES symmetric encryption algorithm.
*
* @ingroup crypters
*/
-struct private_aes_cbc_crypter_t {
+struct private_aes_crypter_t {
/**
* Public part of this class.
*/
- aes_cbc_crypter_t public;
+ aes_crypter_t public;
/**
* Number of words in the key input block.
@@ -81,28 +74,6 @@ struct private_aes_cbc_crypter_t {
* Key size of this AES cypher object.
*/
u_int32_t key_size;
-
- /**
- * Decrypts a block.
- *
- * No memory gets allocated.
- *
- * @param this calling object
- * @param[in] in_blk block to decrypt
- * @param[out] out_blk decrypted data are written to this location
- */
- void (*decrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
-
- /**
- * Encrypts a block.
- *
- * No memory gets allocated.
- *
- * @param this calling object
- * @param[in] in_blk block to encrypt
- * @param[out] out_blk encrypted data are written to this location
- */
- void (*encrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
};
@@ -1243,9 +1214,9 @@ switch(nc) \
#endif
/**
- * Implementation of private_aes_cbc_crypter_t.encrypt_block.
+ * Encrypt a single block of data.
*/
-static void encrypt_block(const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
+static void encrypt_block(const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
{ u_int32_t locals(b0, b1);
const u_int32_t *kp = this->aes_e_key;
@@ -1304,9 +1275,9 @@ static void encrypt_block(const private_aes_cbc_crypter_t *this, const unsigned
}
/**
- * Implementation of private_aes_cbc_crypter_t.decrypt_block.
+ * Decrypt a single block of data.
*/
-static void decrypt_block(const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
+static void decrypt_block(const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
{ u_int32_t locals(b0, b1);
const u_int32_t *kp = this->aes_d_key;
@@ -1367,38 +1338,38 @@ static void decrypt_block(const private_aes_cbc_crypter_t *this, const unsigned
/**
* Implementation of crypter_t.decrypt.
*/
-static status_t decrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
+static void decrypt(private_aes_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted)
{
- int ret, pos;
+ int pos;
const u_int32_t *iv_i;
u_int8_t *in, *out;
- ret = data.len;
- if (((data.len) % 16) != 0)
+ if (decrypted)
{
- /* data length must be padded to a multiple of blocksize */
- return INVALID_ARG;
+ *decrypted = chunk_alloc(data.len);
+ out = decrypted->ptr;
}
-
- decrypted->ptr = malloc(data.len);
- if (decrypted->ptr == NULL)
+ else
{
- return OUT_OF_RES;
+ out = data.ptr;
}
- decrypted->len = data.len;
-
in = data.ptr;
- out = decrypted->ptr;
- pos=data.len-16;
- in+=pos;
- out+=pos;
- while(pos>=0) {
- this->decrypt_block(this,in,out);
+ pos = data.len-16;
+ in += pos;
+ out += pos;
+ while (pos >= 0)
+ {
+ decrypt_block(this, in, out);
if (pos==0)
+ {
iv_i=(const u_int32_t*) (iv.ptr);
+ }
else
+ {
iv_i=(const u_int32_t*) (in-16);
+ }
*((u_int32_t *)(&out[ 0])) ^= iv_i[0];
*((u_int32_t *)(&out[ 4])) ^= iv_i[1];
*((u_int32_t *)(&out[ 8])) ^= iv_i[2];
@@ -1407,60 +1378,53 @@ static status_t decrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t
out-=16;
pos-=16;
}
-
- return SUCCESS;
}
/**
* Implementation of crypter_t.decrypt.
*/
-static status_t encrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
+static void encrypt (private_aes_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted)
{
- int ret, pos;
+ int pos;
const u_int32_t *iv_i;
u_int8_t *in, *out;
- ret = data.len;
- if (((data.len) % 16) != 0)
+ in = data.ptr;
+ out = data.ptr;
+ if (encrypted)
{
- /* data length must be padded to a multiple of blocksize */
- return INVALID_ARG;
+ *encrypted = chunk_alloc(data.len);
+ out = encrypted->ptr;
}
- encrypted->ptr = malloc(data.len);
- if (encrypted->ptr == NULL)
- {
- return OUT_OF_RES;
- }
- encrypted->len = data.len;
-
- in = data.ptr;
- out = encrypted->ptr;
-
pos=0;
while(pos<data.len)
{
if (pos==0)
+ {
iv_i=(const u_int32_t*) iv.ptr;
+ }
else
+ {
iv_i=(const u_int32_t*) (out-16);
+ }
*((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0]));
*((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4]));
*((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8]));
*((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12]));
- this->encrypt_block(this,out,out);
+ encrypt_block(this, out, out);
in+=16;
out+=16;
pos+=16;
}
- return SUCCESS;
}
/**
* Implementation of crypter_t.get_block_size.
*/
-static size_t get_block_size (private_aes_cbc_crypter_t *this)
+static size_t get_block_size (private_aes_crypter_t *this)
{
return AES_BLOCK_SIZE;
}
@@ -1468,7 +1432,7 @@ static size_t get_block_size (private_aes_cbc_crypter_t *this)
/**
* Implementation of crypter_t.get_key_size.
*/
-static size_t get_key_size (private_aes_cbc_crypter_t *this)
+static size_t get_key_size (private_aes_crypter_t *this)
{
return this->key_size;
}
@@ -1476,16 +1440,11 @@ static size_t get_key_size (private_aes_cbc_crypter_t *this)
/**
* Implementation of crypter_t.set_key.
*/
-static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t key)
+static void set_key (private_aes_crypter_t *this, chunk_t key)
{
u_int32_t *kf, *kt, rci, f = 0;
u_int8_t *in_key = key.ptr;
- if (key.len != this->key_size)
- {
- return INVALID_ARG;
- }
-
this->aes_Nrnd = (this->aes_Nkey > (nc) ? this->aes_Nkey : (nc)) + 6;
this->aes_e_key[0] = const_word_in(in_key );
@@ -1565,14 +1524,12 @@ static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t key)
}
cpy(kt, kf);
}
-
- return SUCCESS;
}
/**
- * Implementation of crypter_t.destroy and aes_cbc_crypter_t.destroy.
+ * Implementation of crypter_t.destroy and aes_crypter_t.destroy.
*/
-static void destroy (private_aes_cbc_crypter_t *this)
+static void destroy (private_aes_crypter_t *this)
{
free(this);
}
@@ -1580,16 +1537,24 @@ static void destroy (private_aes_cbc_crypter_t *this)
/*
* Described in header
*/
-aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size)
+aes_crypter_t *aes_crypter_create(encryption_algorithm_t algo, size_t key_size)
{
- private_aes_cbc_crypter_t *this = malloc_thing(private_aes_cbc_crypter_t);
+ private_aes_crypter_t *this;
+
+ if (algo != ENCR_AES_CBC)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_aes_crypter_t);
#if !defined(FIXED_TABLES)
if(!tab_gen) { gen_tabs(); tab_gen = 1; }
#endif
this->key_size = key_size;
- switch(key_size) {
+ switch(key_size)
+ {
case 32: /* bytes */
this->aes_Nkey = 8;
break;
@@ -1604,17 +1569,12 @@ aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size)
return NULL;
}
- /* functions of crypter_t interface */
- this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
- this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
- this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
- /* private functions */
- this->decrypt_block = decrypt_block;
- this->encrypt_block = encrypt_block;
-
return &(this->public);
}
diff --git a/src/libstrongswan/crypto/crypters/aes_cbc_crypter.h b/src/libstrongswan/plugins/aes/aes_crypter.h
index 5da248b8c..e42a6bc5b 100644
--- a/src/libstrongswan/crypto/crypters/aes_cbc_crypter.h
+++ b/src/libstrongswan/plugins/aes/aes_crypter.h
@@ -1,13 +1,5 @@
-/**
- * @file aes_cbc_crypter.h
- *
- * @brief Interface of aes_cbc_crypter_t
- *
- */
-
/*
- * Copyright (C) 2001 Dr B. R. Gladman <brg@gladman.uk.net>
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -22,22 +14,22 @@
* for more details.
*/
-#ifndef AES_CBC_CRYPTER_H_
-#define AES_CBC_CRYPTER_H_
+/**
+ * @defgroup aes_crypter aes_crypter
+ * @{ @ingroup aes_p
+ */
+
+#ifndef AES_CRYPTER_H_
+#define AES_CRYPTER_H_
-typedef struct aes_cbc_crypter_t aes_cbc_crypter_t;
+typedef struct aes_crypter_t aes_crypter_t;
#include <crypto/crypters/crypter.h>
/**
- * @brief Class implementing the AES symmetric encryption algorithm.
- *
- * @b Constructors:
- * - aes_cbc_crypter_create()
- *
- * @ingroup crypters
+ * Class implementing the AES encryption algorithm.
*/
-struct aes_cbc_crypter_t {
+struct aes_crypter_t {
/**
* The crypter_t interface.
@@ -46,16 +38,13 @@ struct aes_cbc_crypter_t {
};
/**
- * @brief Constructor to create aes_cbc_crypter_t objects.
- *
- * Supported key sizes are: 16, 24 or 32.
+ * Constructor to create aes_crypter_t objects.
*
* @param key_size key size in bytes
- * @return
- * - aes_cbc_crypter_t object
- * - NULL if key size not supported
+ * @param algo algorithm to implement
+ * @return aes_crypter_t object, NULL if not supported
*/
-aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size);
-
+aes_crypter_t *aes_crypter_create(encryption_algorithm_t algo,
+ size_t key_size);
-#endif /* AES_CBC_CRYPTER_H_ */
+#endif /* AES_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/aes/aes_plugin.c b/src/libstrongswan/plugins/aes/aes_plugin.c
new file mode 100644
index 000000000..71e49ad73
--- /dev/null
+++ b/src/libstrongswan/plugins/aes/aes_plugin.c
@@ -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: aes_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "aes_plugin.h"
+
+#include <library.h>
+#include "aes_crypter.h"
+
+typedef struct private_aes_plugin_t private_aes_plugin_t;
+
+/**
+ * private data of aes_plugin
+ */
+struct private_aes_plugin_t {
+
+ /**
+ * public functions
+ */
+ aes_plugin_t public;
+};
+
+/**
+ * Implementation of aes_plugin_t.destroy
+ */
+static void destroy(private_aes_plugin_t *this)
+{
+ lib->crypto->remove_crypter(lib->crypto,
+ (crypter_constructor_t)aes_crypter_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_aes_plugin_t *this = malloc_thing(private_aes_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
+ (crypter_constructor_t)aes_crypter_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/aes/aes_plugin.h b/src/libstrongswan/plugins/aes/aes_plugin.h
new file mode 100644
index 000000000..4cf0bc15e
--- /dev/null
+++ b/src/libstrongswan/plugins/aes/aes_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup aes_p aes
+ * @ingroup plugins
+ *
+ * @defgroup aes_plugin aes_plugin
+ * @{ @ingroup aes_p
+ */
+
+#ifndef AES_PLUGIN_H_
+#define AES_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct aes_plugin_t aes_plugin_t;
+
+/**
+ * Plugin implementing AES based algorithms in software.
+ */
+struct aes_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a aes_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* AES_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/curl/Makefile.am b/src/libstrongswan/plugins/curl/Makefile.am
new file mode 100644
index 000000000..1b44516b2
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-curl.la
+
+libstrongswan_curl_la_SOURCES = curl_plugin.h curl_plugin.c curl_fetcher.c curl_fetcher.h
+libstrongswan_curl_la_LDFLAGS = -module
+libstrongswan_curl_la_LIBADD = -lcurl
+
diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in
new file mode 100644
index 000000000..d3f7b443d
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/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/libstrongswan/plugins/curl
+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_curl_la_DEPENDENCIES =
+am_libstrongswan_curl_la_OBJECTS = curl_plugin.lo curl_fetcher.lo
+libstrongswan_curl_la_OBJECTS = $(am_libstrongswan_curl_la_OBJECTS)
+libstrongswan_curl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_curl_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_curl_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_curl_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-curl.la
+libstrongswan_curl_la_SOURCES = curl_plugin.h curl_plugin.c curl_fetcher.c curl_fetcher.h
+libstrongswan_curl_la_LDFLAGS = -module
+libstrongswan_curl_la_LIBADD = -lcurl
+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/libstrongswan/plugins/curl/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/curl/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-curl.la: $(libstrongswan_curl_la_OBJECTS) $(libstrongswan_curl_la_DEPENDENCIES)
+ $(libstrongswan_curl_la_LINK) -rpath $(plugindir) $(libstrongswan_curl_la_OBJECTS) $(libstrongswan_curl_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curl_fetcher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curl_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/libstrongswan/plugins/curl/curl_fetcher.c b/src/libstrongswan/plugins/curl/curl_fetcher.c
new file mode 100644
index 000000000..4754d569e
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/curl_fetcher.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: curl_fetcher.c 3529 2008-03-05 15:26:24Z martin $
+ */
+
+#include <curl/curl.h>
+
+#include <library.h>
+#include <debug.h>
+
+#include "curl_fetcher.h"
+
+#define DEFAULT_TIMEOUT 10
+
+typedef struct private_curl_fetcher_t private_curl_fetcher_t;
+
+/**
+ * private data of a curl_fetcher_t object.
+ */
+struct private_curl_fetcher_t {
+ /**
+ * Public data
+ */
+ curl_fetcher_t public;
+
+ /**
+ * CURL handle
+ */
+ CURL* curl;
+
+ /**
+ * request type, as set with FETCH_REQUEST_TYPE
+ */
+ char *request_type;
+};
+
+/**
+ * writes data into a dynamically resizeable chunk_t
+ */
+static size_t append(void *ptr, size_t size, size_t nmemb, chunk_t *data)
+{
+ size_t realsize = size * nmemb;
+
+ data->ptr = (u_char*)realloc(data->ptr, data->len + realsize);
+ if (data->ptr)
+ {
+ memcpy(&data->ptr[data->len], ptr, realsize);
+ data->len += realsize;
+ }
+ return realsize;
+}
+
+/**
+ * Implements fetcher_t.fetch.
+ */
+static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
+{
+ struct curl_slist *headers = NULL;
+ char error[CURL_ERROR_SIZE];
+ char buf[256];;
+ status_t status;
+
+ *result = chunk_empty;
+
+ if (curl_easy_setopt(this->curl, CURLOPT_URL, uri) != CURLE_OK)
+ { /* URL type not supported by curl */
+ return NOT_SUPPORTED;
+ }
+ curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, error);
+ curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
+ curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
+ curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, DEFAULT_TIMEOUT);
+ curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, (void*)append);
+ curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void*)result);
+ if (this->request_type)
+ {
+ snprintf(buf, sizeof(buf), "Content-Type: %s", this->request_type);
+ headers = curl_slist_append(headers, buf);
+ curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers);
+ }
+
+ DBG2("sending http request to '%s'...", uri);
+ switch (curl_easy_perform(this->curl))
+ {
+ case CURLE_UNSUPPORTED_PROTOCOL:
+ status = NOT_SUPPORTED;
+ break;
+ case CURLE_OK:
+ status = SUCCESS;
+ break;
+ default:
+ DBG1("libcurl http request failed: %s", error);
+ status = FAILED;
+ break;
+ }
+ curl_slist_free_all(headers);
+ return status;
+}
+
+/**
+ * Implementation of fetcher_t.set_option.
+ */
+static bool set_option(private_curl_fetcher_t *this, fetcher_option_t option, ...)
+{
+ va_list args;
+
+ va_start(args, option);
+ switch (option)
+ {
+ case FETCH_REQUEST_DATA:
+ {
+ chunk_t data = va_arg(args, chunk_t);
+ curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, data.ptr);
+ curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, data.len);
+ return TRUE;
+ }
+ case FETCH_REQUEST_TYPE:
+ {
+ this->request_type = va_arg(args, char*);
+ return TRUE;
+ }
+ case FETCH_TIMEOUT:
+ {
+ curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT,
+ va_arg(args, u_int));
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ * Implements fetcher_t.destroy
+ */
+static void destroy(private_curl_fetcher_t *this)
+{
+ curl_easy_cleanup(this->curl);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+curl_fetcher_t *curl_fetcher_create()
+{
+ private_curl_fetcher_t *this = malloc_thing(private_curl_fetcher_t);
+
+ this->curl = curl_easy_init();
+ if (this->curl == NULL)
+ {
+ free(this);
+ return NULL;
+ }
+ this->request_type = NULL;
+
+ this->public.interface.fetch = (status_t(*)(fetcher_t*,char*,chunk_t*))fetch;
+ this->public.interface.set_option = (bool(*)(fetcher_t*, fetcher_option_t option, ...))set_option;
+ this->public.interface.destroy = (void (*)(fetcher_t*))destroy;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/curl/curl_fetcher.h b/src/libstrongswan/plugins/curl/curl_fetcher.h
new file mode 100644
index 000000000..3028eac1b
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/curl_fetcher.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup curl_fetcher curl_fetcher
+ * @{ @ingroup curl_p
+ */
+
+#ifndef CURL_FETCHER_H_
+#define CURL_FETCHER_H_
+
+typedef struct curl_fetcher_t curl_fetcher_t;
+
+/**
+ * Fetcher implementation using libcurl
+ */
+struct curl_fetcher_t {
+
+ /**
+ * Implements fetcher interface
+ */
+ fetcher_t interface;
+
+ /**
+ * Destroy a curl_fetcher instance.
+ */
+ void (*destroy)(curl_fetcher_t *this);
+};
+
+/**
+ * Create a curl_fetcher instance.
+ */
+curl_fetcher_t *curl_fetcher_create();
+
+#endif /* CURL_FETCHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/curl/curl_plugin.c b/src/libstrongswan/plugins/curl/curl_plugin.c
new file mode 100644
index 000000000..a41c3815c
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/curl_plugin.c
@@ -0,0 +1,79 @@
+/*
+ * 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: curl_plugin.c 3529 2008-03-05 15:26:24Z martin $
+ */
+
+#include "curl_plugin.h"
+
+#include <library.h>
+#include <debug.h>
+#include "curl_fetcher.h"
+
+#include <curl/curl.h>
+
+typedef struct private_curl_plugin_t private_curl_plugin_t;
+
+/**
+ * private data of curl_plugin
+ */
+struct private_curl_plugin_t {
+
+ /**
+ * public functions
+ */
+ curl_plugin_t public;
+};
+
+/**
+ * Implementation of curl_plugin_t.curltroy
+ */
+static void destroy(private_curl_plugin_t *this)
+{
+ lib->fetcher->remove_fetcher(lib->fetcher,
+ (fetcher_constructor_t)curl_fetcher_create);
+ curl_global_cleanup();
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ CURLcode res;
+ private_curl_plugin_t *this = malloc_thing(private_curl_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ res = curl_global_init(CURL_GLOBAL_NOTHING);
+ if (res == CURLE_OK)
+ {
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)curl_fetcher_create, "file://");
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)curl_fetcher_create, "http://");
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)curl_fetcher_create, "https://");
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)curl_fetcher_create, "ftp://");
+ }
+ else
+ {
+ DBG1("global libcurl initializing failed: %s, curl disabled",
+ curl_easy_strerror(res));
+ }
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/curl/curl_plugin.h b/src/libstrongswan/plugins/curl/curl_plugin.h
new file mode 100644
index 000000000..73166a25b
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/curl_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup curl_p curl
+ * @ingroup plugins
+ *
+ * @defgroup curl_plugin curl_plugin
+ * @{ @ingroup curl_p
+ */
+
+#ifndef CURL_PLUGIN_H_
+#define CURL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct curl_plugin_t curl_plugin_t;
+
+/**
+ * Plugin implementing fetcher interface using libcurl http library.
+ */
+struct curl_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a curl_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* CURL_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/des/Makefile.am b/src/libstrongswan/plugins/des/Makefile.am
new file mode 100644
index 000000000..ea94eda8a
--- /dev/null
+++ b/src/libstrongswan/plugins/des/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-des.la
+
+libstrongswan_des_la_SOURCES = des_plugin.h des_plugin.c des_crypter.c des_crypter.h
+libstrongswan_des_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in
new file mode 100644
index 000000000..5072a2cab
--- /dev/null
+++ b/src/libstrongswan/plugins/des/Makefile.in
@@ -0,0 +1,494 @@
+# 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/libstrongswan/plugins/des
+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_des_la_LIBADD =
+am_libstrongswan_des_la_OBJECTS = des_plugin.lo des_crypter.lo
+libstrongswan_des_la_OBJECTS = $(am_libstrongswan_des_la_OBJECTS)
+libstrongswan_des_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_des_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_des_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_des_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-des.la
+libstrongswan_des_la_SOURCES = des_plugin.h des_plugin.c des_crypter.c des_crypter.h
+libstrongswan_des_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/libstrongswan/plugins/des/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/des/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-des.la: $(libstrongswan_des_la_OBJECTS) $(libstrongswan_des_la_DEPENDENCIES)
+ $(libstrongswan_des_la_LINK) -rpath $(plugindir) $(libstrongswan_des_la_OBJECTS) $(libstrongswan_des_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des_crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des_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/libstrongswan/crypto/crypters/des_crypter.c b/src/libstrongswan/plugins/des/des_crypter.c
index 655cc03ce..43aff4dd1 100644
--- a/src/libstrongswan/crypto/crypters/des_crypter.c
+++ b/src/libstrongswan/plugins/des/des_crypter.c
@@ -1,10 +1,3 @@
-/**
- * @file des_crypter.c
- *
- * @brief Implementation of des_crypter_t
- *
- */
-
/* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -61,6 +54,8 @@
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
+ *
+ * $Id: des_crypter.c 3910 2008-05-07 11:54:30Z martin $
*/
#include "des_crypter.h"
@@ -1365,84 +1360,84 @@ static void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, long len
/**
* Implementation of crypter_t.decrypt for DES.
*/
-static status_t decrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
+static void decrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted)
{
des_cblock ivb;
+ u_int8_t *out;
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
+ out = data.ptr;
+ if (decrypted)
{
- return INVALID_ARG;
+ *decrypted = chunk_alloc(data.len);
+ out = decrypted->ptr;
}
-
- *decrypted = chunk_alloc(data.len);
memcpy(&ivb, iv.ptr, sizeof(des_cblock));
- des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(decrypted->ptr),
+ des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
data.len, this->ks, &ivb, DES_DECRYPT);
- return SUCCESS;
}
/**
* Implementation of crypter_t.decrypt for DES.
*/
-static status_t encrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
+static void encrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted)
{
des_cblock ivb;
+ u_int8_t *out;
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
+ out = data.ptr;
+ if (encrypted)
{
- return INVALID_ARG;
+ *encrypted = chunk_alloc(data.len);
+ out = encrypted->ptr;
}
-
- *encrypted = chunk_alloc(data.len);
memcpy(&ivb, iv.ptr, sizeof(des_cblock));
- des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(encrypted->ptr),
+ des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
data.len, this->ks, &ivb, DES_ENCRYPT);
- return SUCCESS;
}
/**
* Implementation of crypter_t.decrypt for 3DES.
*/
-static status_t decrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
+static void decrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted)
{
des_cblock ivb;
+ u_int8_t *out;
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
+ out = data.ptr;
+ if (decrypted)
{
- return INVALID_ARG;
+ *decrypted = chunk_alloc(data.len);
+ out = decrypted->ptr;
}
-
- *decrypted = chunk_alloc(data.len);
memcpy(&ivb, iv.ptr, sizeof(des_cblock));
- des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(decrypted->ptr),
+ des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
data.len, this->ks3[0], this->ks3[1], this->ks3[2],
&ivb, DES_DECRYPT);
- return SUCCESS;
}
/**
* Implementation of crypter_t.decrypt for 3DES.
*/
-static status_t encrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
+static void encrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted)
{
des_cblock ivb;
+ u_int8_t *out;
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
+ out = data.ptr;
+ if (encrypted)
{
- return INVALID_ARG;
+ *encrypted = chunk_alloc(data.len);
+ out = encrypted->ptr;
}
-
- *encrypted = chunk_alloc(data.len);
memcpy(&ivb, iv.ptr, sizeof(des_cblock));
- des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(encrypted->ptr),
+ des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
data.len, this->ks3[0], this->ks3[1], this->ks3[2],
&ivb, DES_ENCRYPT);
- return SUCCESS;
}
/**
@@ -1464,33 +1459,19 @@ static size_t get_key_size (private_des_crypter_t *this)
/**
* Implementation of crypter_t.set_key for DES.
*/
-static status_t set_key(private_des_crypter_t *this, chunk_t key)
+static void set_key(private_des_crypter_t *this, chunk_t key)
{
- if (key.len != sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
des_set_key((des_cblock*)(key.ptr), &this->ks);
-
- return SUCCESS;
}
/**
* Implementation of crypter_t.set_key for 3DES.
*/
-static status_t set_key3(private_des_crypter_t *this, chunk_t key)
-{
- if (key.len != 3 * sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
+static void set_key3(private_des_crypter_t *this, chunk_t key)
+{
des_set_key((des_cblock*)(key.ptr) + 0, &this->ks3[0]);
des_set_key((des_cblock*)(key.ptr) + 1, &this->ks3[1]);
des_set_key((des_cblock*)(key.ptr) + 2, &this->ks3[2]);
-
- return SUCCESS;
}
/**
@@ -1518,19 +1499,19 @@ des_crypter_t *des_crypter_create(encryption_algorithm_t algo)
{
case ENCR_DES:
this->key_size = sizeof(des_cblock);
- this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key;
- this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
- this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
break;
case ENCR_3DES:
this->key_size = 3 * sizeof(des_cblock);
- this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key3;
- this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt3;
- this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt3;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key3;
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt3;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt3;
break;
default:
free(this);
return NULL;
}
- return &(this->public);
+ return &this->public;
}
diff --git a/src/libstrongswan/crypto/crypters/des_crypter.h b/src/libstrongswan/plugins/des/des_crypter.h
index 0c87b0a9c..d40d9cf2f 100644
--- a/src/libstrongswan/crypto/crypters/des_crypter.h
+++ b/src/libstrongswan/plugins/des/des_crypter.h
@@ -1,12 +1,5 @@
-/**
- * @file des_crypter.h
- *
- * @brief Interface of des_crypter_t
- *
- */
-
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-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 des_crypter des_crypter
+ * @{ @ingroup des_p
+ */
+
#ifndef DES_CRYPTER_H_
#define DES_CRYPTER_H_
@@ -29,12 +27,7 @@ typedef struct des_crypter_t des_crypter_t;
/**
- * @brief Class implementing the DES and 3DES encryption algorithms.
- *
- * @b Constructors:
- * - des_crypter_create()
- *
- * @ingroup crypters
+ * Class implementing the DES and 3DES encryption algorithms.
*/
struct des_crypter_t {
@@ -45,14 +38,12 @@ struct des_crypter_t {
};
/**
- * @brief Constructor to create des_crypter_t objects.
+ * Constructor to create des_crypter_t objects.
*
* @param algo ENCR_DES for single DES, ENCR_3DES for triple DES
- * @return
- * - des_crypter_t object
- * - NULL if algo not supported
+ * @return des_crypter_t object, NULL if algo not supported
*/
des_crypter_t *des_crypter_create(encryption_algorithm_t algo);
-#endif /* DES_CRYPTER_H_ */
+#endif /* DES_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/des/des_plugin.c b/src/libstrongswan/plugins/des/des_plugin.c
new file mode 100644
index 000000000..c32096ad0
--- /dev/null
+++ b/src/libstrongswan/plugins/des/des_plugin.c
@@ -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: des_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "des_plugin.h"
+
+#include <library.h>
+#include "des_crypter.h"
+
+typedef struct private_des_plugin_t private_des_plugin_t;
+
+/**
+ * private data of des_plugin
+ */
+struct private_des_plugin_t {
+
+ /**
+ * public functions
+ */
+ des_plugin_t public;
+};
+
+/**
+ * Implementation of des_plugin_t.destroy
+ */
+static void destroy(private_des_plugin_t *this)
+{
+ lib->crypto->remove_crypter(lib->crypto,
+ (crypter_constructor_t)des_crypter_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_des_plugin_t *this = malloc_thing(private_des_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_crypter(lib->crypto, ENCR_DES,
+ (crypter_constructor_t)des_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_3DES,
+ (crypter_constructor_t)des_crypter_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/des/des_plugin.h b/src/libstrongswan/plugins/des/des_plugin.h
new file mode 100644
index 000000000..8cabd082b
--- /dev/null
+++ b/src/libstrongswan/plugins/des/des_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup des_p des
+ * @ingroup plugins
+ *
+ * @defgroup des_plugin des_plugin
+ * @{ @ingroup des_p
+ */
+
+#ifndef DES_PLUGIN_H_
+#define DES_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct des_plugin_t des_plugin_t;
+
+/**
+ * Plugin implementing DES based algorithms in software.
+ */
+struct des_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a des_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* DES_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.am b/src/libstrongswan/plugins/fips_prf/Makefile.am
new file mode 100644
index 000000000..73f28825a
--- /dev/null
+++ b/src/libstrongswan/plugins/fips_prf/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-fips-prf.la
+
+libstrongswan_fips_prf_la_SOURCES = fips_prf_plugin.h fips_prf_plugin.c fips_prf.c fips_prf.h
+libstrongswan_fips_prf_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in
new file mode 100644
index 000000000..fa51b0db5
--- /dev/null
+++ b/src/libstrongswan/plugins/fips_prf/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/libstrongswan/plugins/fips_prf
+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_fips_prf_la_LIBADD =
+am_libstrongswan_fips_prf_la_OBJECTS = fips_prf_plugin.lo fips_prf.lo
+libstrongswan_fips_prf_la_OBJECTS = \
+ $(am_libstrongswan_fips_prf_la_OBJECTS)
+libstrongswan_fips_prf_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_fips_prf_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_fips_prf_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_fips_prf_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-fips-prf.la
+libstrongswan_fips_prf_la_SOURCES = fips_prf_plugin.h fips_prf_plugin.c fips_prf.c fips_prf.h
+libstrongswan_fips_prf_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/libstrongswan/plugins/fips_prf/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/fips_prf/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-fips-prf.la: $(libstrongswan_fips_prf_la_OBJECTS) $(libstrongswan_fips_prf_la_DEPENDENCIES)
+ $(libstrongswan_fips_prf_la_LINK) -rpath $(plugindir) $(libstrongswan_fips_prf_la_OBJECTS) $(libstrongswan_fips_prf_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_prf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_prf_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/libstrongswan/crypto/prfs/fips_prf.c b/src/libstrongswan/plugins/fips_prf/fips_prf.c
index 0ab80b089..df3d130a9 100644
--- a/src/libstrongswan/crypto/prfs/fips_prf.c
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf.c
@@ -1,10 +1,3 @@
-/**
- * @file fips_prf.c
- *
- * @brief Implementation for fips_prf_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: fips_prf.c 3619 2008-03-19 14:02:52Z martin $
*/
#include "fips_prf.h"
@@ -48,17 +43,14 @@ struct private_fips_prf_t {
size_t b;
/**
+ * Keyed SHA1 prf: It does not use SHA1Final operation
+ */
+ prf_t *keyed_prf;
+
+ /**
* G function, either SHA1 or DES
*/
- void (*g)(u_int8_t t[], chunk_t c, u_int8_t res[]);
-};
-
-/**
- * t used in G(), equals to initial SHA1 value
- */
-static u_int8_t t[] = {
- 0x67,0x45,0x23,0x01,0xEF,0xCD,0xAB,0x89,0x98,0xBA,
- 0xDC,0xFE,0x10,0x32,0x54,0x76,0xC3,0xD2,0xE1,0xF0,
+ void (*g)(private_fips_prf_t *this, chunk_t c, u_int8_t res[]);
};
/**
@@ -139,7 +131,7 @@ static void get_bytes(private_fips_prf_t *this, chunk_t seed, u_int8_t w[])
add_mod(this->b, xkey, xseed, xval);
DBG3("XVAL %b", xval, this->b);
/* b. wi = G(t, XVAL ) */
- this->g(t, xval_chunk, &w[i * this->b]);
+ this->g(this, xval_chunk, &w[i * this->b]);
DBG3("w[%d] %b", i, &w[i * this->b], this->b);
/* c. XKEY = (1 + XKEY + wi) mod 2b */
add_mod(this->b, xkey, &w[i * this->b], sum);
@@ -186,12 +178,9 @@ static void set_key(private_fips_prf_t *this, chunk_t key)
/**
* Implementation of the G() function based on SHA1
*/
-void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[])
+void g_sha1(private_fips_prf_t *this, chunk_t c, u_int8_t res[])
{
- hasher_t *hasher;
u_int8_t buf[64];
- chunk_t state_chunk;
- u_int32_t *state, *iv, *hash;
if (c.len < sizeof(buf))
{
@@ -207,24 +196,9 @@ void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[])
c.len = sizeof(buf);
}
- /* our SHA1 hasher's state is 32-Bit integers in host order. We must
- * convert them */
- hasher = hasher_create(HASH_SHA1);
- state_chunk = hasher->get_state(hasher);
- state = (u_int32_t*)state_chunk.ptr;
- iv = (u_int32_t*)t;
- hash = (u_int32_t*)res;
- state[0] = htonl(iv[0]);
- state[1] = htonl(iv[1]);
- state[2] = htonl(iv[2]);
- state[3] = htonl(iv[3]);
- hasher->get_hash(hasher, c, NULL);
- hash[0] = htonl(state[0]);
- hash[1] = htonl(state[1]);
- hash[2] = htonl(state[2]);
- hash[3] = htonl(state[3]);
- hash[4] = htonl(state[4]);
- hasher->destroy(hasher);
+ /* use the keyed hasher, but use an empty key to use SHA1 IV */
+ this->keyed_prf->set_key(this->keyed_prf, chunk_empty);
+ this->keyed_prf->get_bytes(this->keyed_prf, c, res);
}
/**
@@ -232,6 +206,7 @@ void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[])
*/
static void destroy(private_fips_prf_t *this)
{
+ this->keyed_prf->destroy(this->keyed_prf);
free(this->key);
free(this);
}
@@ -239,7 +214,7 @@ static void destroy(private_fips_prf_t *this)
/*
* Described in header.
*/
-fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]))
+fips_prf_t *fips_prf_create(pseudo_random_function_t algo)
{
private_fips_prf_t *this = malloc_thing(private_fips_prf_t);
@@ -250,9 +225,28 @@ fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]))
this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
- this->g = g;
- this->b = b;
- this->key = malloc(b);
+ switch (algo)
+ {
+ case PRF_FIPS_SHA1_160:
+ {
+ this->g = g_sha1;
+ this->b = 20;
+ this->keyed_prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1);
+ if (this->keyed_prf == NULL)
+ {
+ free(this);
+ return NULL;
+ }
+ break;
+ }
+ case PRF_FIPS_DES:
+ /* not implemented yet */
+ default:
+ free(this);
+ return NULL;
+ }
+ this->key = malloc(this->b);
- return &(this->public);
+ return &this->public;
}
+
diff --git a/src/libstrongswan/crypto/prfs/fips_prf.h b/src/libstrongswan/plugins/fips_prf/fips_prf.h
index 283ee1f61..3fead6b9b 100644
--- a/src/libstrongswan/crypto/prfs/fips_prf.h
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf.h
@@ -1,12 +1,5 @@
-/**
- * @file fips_prf.h
- *
- * @brief Interface of fips_prf_t.
- *
- */
-
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-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 fips_prf fips_prf
+ * @{ @ingroup fips_prf_p
+ */
+
#ifndef FIPS_PRF_H_
#define FIPS_PRF_H_
@@ -30,19 +28,13 @@ typedef struct fips_prf_t fips_prf_t;
#include <crypto/hashers/hasher.h>
/**
- * @brief Implementation of prf_t using the FIPS 186-2-change1 standard.
+ * Implementation of prf_t using the FIPS 186-2-change1 standard.
*
* FIPS defines a "General Purpose Random Number Generator" (Revised
* Algorithm for Computing m values of x (Appendix 3.1 of FIPS 186-2)). This
* implementation is not intended for private key generation and therefore does
* not include the "mod q" operation (see FIPS 186-2-change1 p74).
* The FIPS PRF is stateful; the key changes every time when bytes are acquired.
- *
- * @b Constructors:
- * - fips_prf_create()
- * - prf_create() using one of the FIPS algorithms
- *
- * @ingroup prfs
*/
struct fips_prf_t {
@@ -53,28 +45,15 @@ struct fips_prf_t {
};
/**
- * @brief Creates a new fips_prf_t object.
+ * Creates a new fips_prf_t object.
*
* FIPS 186-2 defines G() functions used in the PRF function. It can
* be implemented either based on SHA1 or DES.
+ * The G() function is selected using the algo parameter.
*
- * @param b size of b (in bytes, not bits)
- * @param g G() function to use (e.g. g_sha1)
- * @return
- * - fips_prf_t object
- * - NULL if b invalid not supported
- *
- * @ingroup prfs
- */
-fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]));
-
-/**
- * @brief Implementation of the G() function based on SHA1.
- *
- * @param t initialization vector for SHA1 hasher, 20 bytes long
- * @param c value to hash, not longer than 512 bit
- * @param res result of G(), requries 20 bytes
+ * @param algo specific FIPS PRF implementation, specifies G() function
+ * @return fips_prf_t object, NULL if not supported.
*/
-void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[]);
+fips_prf_t *fips_prf_create(pseudo_random_function_t algo);
-#endif /* FIPS_PRF_H_ */
+#endif /* FIPS_PRF_H_ @}*/
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c
new file mode 100644
index 000000000..60fce8632
--- /dev/null
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c
@@ -0,0 +1,59 @@
+/*
+ * 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: fips_prf_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "fips_prf_plugin.h"
+
+#include <library.h>
+#include "fips_prf.h"
+
+typedef struct private_fips_prf_plugin_t private_fips_prf_plugin_t;
+
+/**
+ * private data of fips_prf_plugin
+ */
+struct private_fips_prf_plugin_t {
+
+ /**
+ * public functions
+ */
+ fips_prf_plugin_t public;
+};
+
+/**
+ * Implementation of fips_prf_plugin_t.destroy
+ */
+static void destroy(private_fips_prf_plugin_t *this)
+{
+ lib->crypto->remove_prf(lib->crypto,
+ (prf_constructor_t)fips_prf_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_fips_prf_plugin_t *this = malloc_thing(private_fips_prf_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_prf(lib->crypto, PRF_FIPS_SHA1_160,
+ (prf_constructor_t)fips_prf_create);
+
+ return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.h b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.h
new file mode 100644
index 000000000..6816eb66f
--- /dev/null
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup fips_prf_p fips_prf
+ * @ingroup plugins
+ *
+ * @defgroup fips_prf_plugin fips_prf_plugin
+ * @{ @ingroup fips_prf_p
+ */
+
+#ifndef FIPS_PRF_PLUGIN_H_
+#define FIPS_PRF_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct fips_prf_plugin_t fips_prf_plugin_t;
+
+/**
+ * Plugin implementing the fips_prf algorithm in software.
+ */
+struct fips_prf_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a fips_prf_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* FIPS_PRF_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/gmp/Makefile.am b/src/libstrongswan/plugins/gmp/Makefile.am
new file mode 100644
index 000000000..f073b5d48
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/Makefile.am
@@ -0,0 +1,15 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-gmp.la
+
+libstrongswan_gmp_la_SOURCES = gmp_plugin.h gmp_plugin.c \
+ gmp_diffie_hellman.c gmp_diffie_hellman.h \
+ gmp_rsa_private_key.c gmp_rsa_private_key.h \
+ gmp_rsa_public_key.c gmp_rsa_public_key.h
+
+libstrongswan_gmp_la_LDFLAGS = -module
+libstrongswan_gmp_la_LIBADD = -lgmp
+
diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in
new file mode 100644
index 000000000..1d9bfb88e
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/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/libstrongswan/plugins/gmp
+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_gmp_la_DEPENDENCIES =
+am_libstrongswan_gmp_la_OBJECTS = gmp_plugin.lo gmp_diffie_hellman.lo \
+ gmp_rsa_private_key.lo gmp_rsa_public_key.lo
+libstrongswan_gmp_la_OBJECTS = $(am_libstrongswan_gmp_la_OBJECTS)
+libstrongswan_gmp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_gmp_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_gmp_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_gmp_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-gmp.la
+libstrongswan_gmp_la_SOURCES = gmp_plugin.h gmp_plugin.c \
+ gmp_diffie_hellman.c gmp_diffie_hellman.h \
+ gmp_rsa_private_key.c gmp_rsa_private_key.h \
+ gmp_rsa_public_key.c gmp_rsa_public_key.h
+
+libstrongswan_gmp_la_LDFLAGS = -module
+libstrongswan_gmp_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/libstrongswan/plugins/gmp/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/gmp/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-gmp.la: $(libstrongswan_gmp_la_OBJECTS) $(libstrongswan_gmp_la_DEPENDENCIES)
+ $(libstrongswan_gmp_la_LINK) -rpath $(plugindir) $(libstrongswan_gmp_la_OBJECTS) $(libstrongswan_gmp_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmp_diffie_hellman.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmp_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmp_rsa_private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmp_rsa_public_key.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/libstrongswan/plugins/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
new file mode 100644
index 000000000..3d9856b63
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
+ * Copyright (C) 1999, 2000, 2001 Henry Spencer.
+ * Copyright (C) 2005-2008 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: gmp_diffie_hellman.c 3806 2008-04-15 05:56:35Z martin $
+ */
+
+#include <gmp.h>
+
+#include "gmp_diffie_hellman.h"
+
+#include <debug.h>
+
+
+/**
+ * Modulus of Group 1 (MODP_768_BIT).
+ */
+static u_int8_t group1_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80 ,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x3A,0x36,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 2 (MODP_1024_BIT).
+ */
+static u_int8_t group2_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 5 (MODP_1536_BIT).
+ */
+static u_int8_t group5_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+/**
+ * Modulus of Group 14 (MODP_2048_BIT).
+ */
+static u_int8_t group14_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 15 (MODP_3072_BIT).
+ */
+static u_int8_t group15_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x3A,0xD2,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 16 (MODP_4096_BIT).
+ */
+static u_int8_t group16_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+ 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
+ 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
+ 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+ 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
+ 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
+ 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+ 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
+ 0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 17 (MODP_6144_BIT).
+ */
+static u_int8_t group17_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+ 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
+ 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
+ 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+ 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
+ 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
+ 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+ 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
+ 0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,
+ 0xC1,0xD4,0xDC,0xB2,0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
+ 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,0x41,0x30,0x01,0xAE,
+ 0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,
+ 0xDA,0x3E,0xDB,0xEB,0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
+ 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,0x2B,0xD7,0xAF,0x42,
+ 0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,
+ 0xF0,0x32,0xEA,0x15,0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
+ 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,0x90,0x0B,0x1C,0x9E,
+ 0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,
+ 0x0F,0x1D,0x45,0xB7,0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
+ 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,0x0F,0x80,0x37,0xE0,
+ 0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,
+ 0xF5,0x50,0xAA,0x3D,0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
+ 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,0x6E,0x3C,0x04,0x68,
+ 0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,
+ 0xE6,0x94,0xF9,0x1E,0x6D,0xCC,0x40,0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 18 (MODP_8192_BIT).
+ */
+static u_int8_t group18_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+ 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
+ 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
+ 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+ 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
+ 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
+ 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+ 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
+ 0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,
+ 0xC1,0xD4,0xDC,0xB2,0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
+ 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,0x41,0x30,0x01,0xAE,
+ 0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,
+ 0xDA,0x3E,0xDB,0xEB,0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
+ 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,0x2B,0xD7,0xAF,0x42,
+ 0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,
+ 0xF0,0x32,0xEA,0x15,0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
+ 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,0x90,0x0B,0x1C,0x9E,
+ 0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,
+ 0x0F,0x1D,0x45,0xB7,0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
+ 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,0x0F,0x80,0x37,0xE0,
+ 0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,
+ 0xF5,0x50,0xAA,0x3D,0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
+ 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,0x6E,0x3C,0x04,0x68,
+ 0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,
+ 0xE6,0x94,0xF9,0x1E,0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
+ 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,0x73,0xB9,0x31,0xBA,
+ 0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,
+ 0x25,0x76,0xF6,0x93,0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
+ 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,0xE3,0x9D,0x65,0x2D,
+ 0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,
+ 0x13,0xEB,0x57,0xA8,0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
+ 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,0xA2,0xC0,0x87,0xE8,
+ 0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,
+ 0x6D,0x2A,0x13,0xF8,0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
+ 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,0x08,0x46,0x85,0x1D,
+ 0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,
+ 0xFA,0xF3,0x6B,0xC3,0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
+ 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,0xD5,0xEE,0x38,0x2B,
+ 0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,
+ 0x9E,0x30,0x50,0xE2,0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
+ 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+};
+
+typedef struct modulus_entry_t modulus_entry_t;
+
+/**
+ * Entry of the modulus list.
+ */
+struct modulus_entry_t {
+ /**
+ * Group number as it is defined in file transform_substructure.h.
+ */
+ diffie_hellman_group_t group;
+
+ /**
+ * Pointer to first byte of modulus (network order).
+ */
+ u_int8_t *modulus;
+
+ /*
+ * Length of modulus in bytes.
+ */
+ size_t modulus_len;
+
+ /*
+ * Generator value.
+ */
+ u_int16_t generator;
+};
+
+/**
+ * All supported modulus values.
+ */
+static modulus_entry_t modulus_entries[] = {
+ {MODP_768_BIT, group1_modulus, sizeof(group1_modulus), 2},
+ {MODP_1024_BIT, group2_modulus, sizeof(group2_modulus), 2},
+ {MODP_1536_BIT, group5_modulus, sizeof(group5_modulus), 2},
+ {MODP_2048_BIT, group14_modulus, sizeof(group14_modulus), 2},
+ {MODP_3072_BIT, group15_modulus, sizeof(group15_modulus), 2},
+ {MODP_4096_BIT, group16_modulus, sizeof(group16_modulus), 2},
+ {MODP_6144_BIT, group17_modulus, sizeof(group17_modulus), 2},
+ {MODP_8192_BIT, group18_modulus, sizeof(group18_modulus), 2},
+};
+
+typedef struct private_gmp_diffie_hellman_t private_gmp_diffie_hellman_t;
+
+/**
+ * Private data of an gmp_diffie_hellman_t object.
+ */
+struct private_gmp_diffie_hellman_t {
+ /**
+ * Public gmp_diffie_hellman_t interface.
+ */
+ gmp_diffie_hellman_t public;
+
+ /**
+ * Diffie Hellman group number.
+ */
+ u_int16_t group;
+
+ /*
+ * Generator value.
+ */
+ mpz_t g;
+
+ /**
+ * My private value.
+ */
+ mpz_t xa;
+
+ /**
+ * My public value.
+ */
+ mpz_t ya;
+
+ /**
+ * Other public value.
+ */
+ mpz_t yb;
+
+ /**
+ * Shared secret.
+ */
+ mpz_t zz;
+
+ /**
+ * Modulus.
+ */
+ mpz_t p;
+
+ /**
+ * Modulus length.
+ */
+ size_t p_len;
+
+ /**
+ * True if shared secret is computed and stored in my_public_value.
+ */
+ bool computed;
+};
+
+/**
+ * Implementation of gmp_diffie_hellman_t.set_other_public_value.
+ */
+static void set_other_public_value(private_gmp_diffie_hellman_t *this, chunk_t value)
+{
+ mpz_t p_min_1;
+
+ mpz_init(p_min_1);
+ mpz_sub_ui(p_min_1, this->p, 1);
+
+ mpz_import(this->yb, value.len, 1, 1, 1, 0, value.ptr);
+
+ /* check public value:
+ * 1. 0 or 1 is invalid as 0^a = 0 and 1^a = 1
+ * 2. a public value larger or equal the modulus is invalid */
+ if (mpz_cmp_ui(this->yb, 1) > 0 ||
+ mpz_cmp(this->yb, p_min_1) < 0)
+ {
+#ifdef EXTENDED_DH_TEST
+ /* 3. test if y ^ q mod p = 1, where q = (p - 1)/2. */
+ mpz_t q, one;
+
+ mpz_init(q);
+ mpz_init(one);
+ mpz_fdiv_q_2exp(q, p_min_1, 1);
+ mpz_powm(one, this->yb, q, this->p);
+ mpz_clear(q);
+ if (mpz_cmp_ui(one, 1) == 0)
+ {
+ mpz_powm(this->zz, this->yb, this->xa, this->p);
+ this->computed = TRUE;
+ }
+ else
+ {
+ DBG1("public DH value verification failed: y ^ q mod p != 1");
+ }
+ mpz_clear(one);
+#else
+ mpz_powm(this->zz, this->yb, this->xa, this->p);
+ this->computed = TRUE;
+#endif
+ }
+ else
+ {
+ DBG1("public DH value verification failed: y < 2 || y > p - 1 ");
+ }
+ mpz_clear(p_min_1);
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_other_public_value.
+ */
+static status_t get_other_public_value(private_gmp_diffie_hellman_t *this,
+ chunk_t *value)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+ value->len = this->p_len;
+ value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->yb);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_my_public_value.
+ */
+static void get_my_public_value(private_gmp_diffie_hellman_t *this,chunk_t *value)
+{
+ value->len = this->p_len;
+ value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->ya);
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_shared_secret.
+ */
+static status_t get_shared_secret(private_gmp_diffie_hellman_t *this, chunk_t *secret)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+ secret->len = this->p_len;
+ secret->ptr = mpz_export(NULL, NULL, 1, secret->len, 1, 0, this->zz);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_gmp_diffie_hellman_t *this)
+{
+ return this->group;
+}
+
+/**
+ * Lookup the modulus in modulo table
+ */
+static status_t set_modulus(private_gmp_diffie_hellman_t *this)
+{
+ int i;
+ status_t status = NOT_FOUND;
+
+ for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++)
+ {
+ if (modulus_entries[i].group == this->group)
+ {
+ chunk_t chunk;
+ chunk.ptr = modulus_entries[i].modulus;
+ chunk.len = modulus_entries[i].modulus_len;
+ mpz_import(this->p, chunk.len, 1, 1, 1, 0, chunk.ptr);
+ this->p_len = chunk.len;
+ mpz_set_ui(this->g, modulus_entries[i].generator);
+ status = SUCCESS;
+ break;
+ }
+ }
+ return status;
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.destroy.
+ */
+static void destroy(private_gmp_diffie_hellman_t *this)
+{
+ mpz_clear(this->p);
+ mpz_clear(this->xa);
+ mpz_clear(this->ya);
+ mpz_clear(this->yb);
+ mpz_clear(this->zz);
+ mpz_clear(this->g);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group)
+{
+ private_gmp_diffie_hellman_t *this = malloc_thing(private_gmp_diffie_hellman_t);
+ rng_t *rng;
+ chunk_t random;
+
+ /* public functions */
+ this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
+ this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
+ this->public.dh.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
+ this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
+ this->public.dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
+ this->public.dh.destroy = (void (*)(diffie_hellman_t *)) destroy;
+
+ /* private variables */
+ this->group = group;
+ mpz_init(this->p);
+ mpz_init(this->yb);
+ mpz_init(this->ya);
+ mpz_init(this->xa);
+ mpz_init(this->zz);
+ mpz_init(this->g);
+
+ this->computed = FALSE;
+
+ /* find a modulus according to group */
+ if (set_modulus(this) != SUCCESS)
+ {
+ destroy(this);
+ return NULL;
+ }
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ if (!rng)
+ {
+ DBG1("no RNG found for quality %N", rng_quality_names, RNG_STRONG);
+ destroy(this);
+ return NULL;
+ }
+ rng->allocate_bytes(rng, this->p_len, &random);
+ rng->destroy(rng);
+ mpz_import(this->xa, random.len, 1, 1, 1, 0, random.ptr);
+ chunk_free(&random);
+
+ mpz_powm(this->ya, this->g, this->xa, this->p);
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h
new file mode 100644
index 000000000..e2d4d6851
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup gmp_diffie_hellman gmp_diffie_hellman
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_DIFFIE_HELLMAN_H_
+#define GMP_DIFFIE_HELLMAN_H_
+
+typedef struct gmp_diffie_hellman_t gmp_diffie_hellman_t;
+
+#include <library.h>
+
+/**
+ * Implementation of the Diffie-Hellman algorithm, as in RFC2631. Uses libgmp.
+ */
+struct gmp_diffie_hellman_t {
+
+ /**
+ * Implements diffie_hellman_t interface.
+ */
+ diffie_hellman_t dh;
+};
+
+/**
+ * Creates a new gmp_diffie_hellman_t object.
+ *
+ * @param group Diffie Hellman group number to use
+ * @return gmp_diffie_hellman_t object, NULL if not supported
+ */
+gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group);
+
+#endif /*GMP_DIFFIE_HELLMAN_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.c b/src/libstrongswan/plugins/gmp/gmp_plugin.c
new file mode 100644
index 000000000..56fb0ddd8
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_plugin.c
@@ -0,0 +1,85 @@
+/*
+ * 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: gmp_plugin.c 3962 2008-05-15 12:39:35Z tobias $
+ */
+
+#include "gmp_plugin.h"
+
+#include <library.h>
+#include "gmp_diffie_hellman.h"
+#include "gmp_rsa_private_key.h"
+#include "gmp_rsa_public_key.h"
+
+typedef struct private_gmp_plugin_t private_gmp_plugin_t;
+
+/**
+ * private data of gmp_plugin
+ */
+struct private_gmp_plugin_t {
+
+ /**
+ * public functions
+ */
+ gmp_plugin_t public;
+};
+
+/**
+ * Implementation of gmp_plugin_t.gmptroy
+ */
+static void destroy(private_gmp_plugin_t *this)
+{
+ lib->crypto->remove_dh(lib->crypto,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)gmp_rsa_private_key_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)gmp_rsa_public_key_builder);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_gmp_plugin_t *this = malloc_thing(private_gmp_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_dh(lib->crypto, MODP_768_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_1024_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_1536_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_2048_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_3072_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_4096_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_6144_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_8192_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ (builder_constructor_t)gmp_rsa_private_key_builder);
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ (builder_constructor_t)gmp_rsa_public_key_builder);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.h b/src/libstrongswan/plugins/gmp/gmp_plugin.h
new file mode 100644
index 000000000..a853064b7
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup gmp_p gmp
+ * @ingroup plugins
+ *
+ * @defgroup gmp_plugin gmp_plugin
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_PLUGIN_H_
+#define GMP_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct gmp_plugin_t gmp_plugin_t;
+
+/**
+ * Plugin implementing asymmetric crypto algorithms using the GNU MP library.
+ */
+struct gmp_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a gmp_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* GMP_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
new file mode 100644
index 000000000..cd951f0e4
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
@@ -0,0 +1,842 @@
+/*
+ * Copyright (C) 2005-2008 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: gmp_rsa_private_key.c 4014 2008-05-23 19:23:04Z andreas $
+ */
+
+#include <gmp.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "gmp_rsa_private_key.h"
+#include "gmp_rsa_public_key.h"
+
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+
+/**
+ * Public exponent to use for key generation.
+ */
+#define PUBLIC_EXPONENT 0x10001
+
+typedef struct private_gmp_rsa_private_key_t private_gmp_rsa_private_key_t;
+
+/**
+ * Private data of a gmp_rsa_private_key_t object.
+ */
+struct private_gmp_rsa_private_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ gmp_rsa_private_key_t public;
+
+ /**
+ * Version of key, as encoded in PKCS#1
+ */
+ u_int version;
+
+ /**
+ * Public modulus.
+ */
+ mpz_t n;
+
+ /**
+ * Public exponent.
+ */
+ mpz_t e;
+
+ /**
+ * Private prime 1.
+ */
+ mpz_t p;
+
+ /**
+ * Private Prime 2.
+ */
+ mpz_t q;
+
+ /**
+ * Private exponent.
+ */
+ mpz_t d;
+
+ /**
+ * Private exponent 1.
+ */
+ mpz_t exp1;
+
+ /**
+ * Private exponent 2.
+ */
+ mpz_t exp2;
+
+ /**
+ * Private coefficient.
+ */
+ mpz_t coeff;
+
+ /**
+ * Keysize in bytes.
+ */
+ size_t k;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKey object
+ */
+ identification_t* keyid;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+ */
+ identification_t* keyid_info;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+/**
+ * shared functions, implemented in gmp_rsa_public_key.c
+ */
+bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, identification_t **keyid,
+ identification_t **keyid_info);
+gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e);
+
+/**
+ * Auxiliary function overwriting private key material with zero bytes
+ */
+static void mpz_clear_randomized(mpz_t z)
+{
+ size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE;
+ u_int8_t *random = alloca(len);
+
+ memset(random, 0, len);
+ /* overwrite mpz_t with zero bytes before clearing it */
+ mpz_import(z, len, 1, 1, 1, 0, random);
+ mpz_clear(z);
+}
+
+/**
+ * Create a mpz prime of at least prime_size
+ */
+static status_t compute_prime(private_gmp_rsa_private_key_t *this,
+ size_t prime_size, mpz_t *prime)
+{
+ rng_t *rng;
+ chunk_t random_bytes;
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_REAL);
+ if (!rng)
+ {
+ DBG1("no RNG of quality %N found", rng_quality_names, RNG_REAL);
+ return FAILED;
+ }
+
+ mpz_init(*prime);
+ do
+ {
+ rng->allocate_bytes(rng, prime_size, &random_bytes);
+ /* make sure most significant bit is set */
+ random_bytes.ptr[0] = random_bytes.ptr[0] | 0x80;
+
+ mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
+ mpz_nextprime (*prime, *prime);
+ chunk_clear(&random_bytes);
+ }
+ /* check if it isn't too large */
+ while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_size);
+
+ rng->destroy(rng);
+ return SUCCESS;
+}
+
+/**
+ * PKCS#1 RSADP function
+ */
+static chunk_t rsadp(private_gmp_rsa_private_key_t *this, chunk_t data)
+{
+ mpz_t t1, t2;
+ chunk_t decrypted;
+
+ mpz_init(t1);
+ mpz_init(t2);
+
+ mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr);
+
+ mpz_powm(t2, t1, this->exp1, this->p); /* m1 = c^dP mod p */
+ mpz_powm(t1, t1, this->exp2, this->q); /* m2 = c^dQ mod Q */
+ mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
+ mpz_mod(t2, t2, this->p);
+ mpz_mul(t2, t2, this->coeff);
+ mpz_mod(t2, t2, this->p);
+
+ mpz_mul(t2, t2, this->q); /* m = m2 + h q */
+ mpz_add(t1, t1, t2);
+
+ decrypted.len = this->k;
+ decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1);
+
+ mpz_clear_randomized(t1);
+ mpz_clear_randomized(t2);
+
+ return decrypted;
+}
+
+/**
+ * PKCS#1 RSASP1 function
+ */
+static chunk_t rsasp1(private_gmp_rsa_private_key_t *this, chunk_t data)
+{
+ return rsadp(this, data);
+}
+
+/**
+ * Implementation of gmp_rsa_private_key_t.build_emsa_pkcs1_signature.
+ */
+static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
+ hash_algorithm_t hash_algorithm,
+ chunk_t data, chunk_t *signature)
+{
+ hasher_t *hasher;
+ chunk_t em, digestInfo, hash;
+ int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
+
+ if (hash_oid == OID_UNKNOWN)
+ {
+ return FALSE;
+ }
+
+ /* get hasher */
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+ if (hasher == NULL)
+ {
+ return FALSE;
+ }
+
+ /* build hash */
+ hasher->allocate_hash(hasher, data, &hash);
+ hasher->destroy(hasher);
+
+ /* build DER-encoded digestInfo */
+ digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
+ asn1_algorithmIdentifier(hash_oid),
+ asn1_simple_object(ASN1_OCTET_STRING, hash)
+ );
+ chunk_free(&hash);
+
+ /* build chunk to rsa-decrypt:
+ * EM = 0x00 || 0x01 || PS || 0x00 || T.
+ * PS = 0xFF padding, with length to fill em
+ * T = encoded_hash
+ */
+ em.len = this->k;
+ em.ptr = malloc(em.len);
+
+ /* fill em with padding */
+ memset(em.ptr, 0xFF, em.len);
+ /* set magic bytes */
+ *(em.ptr) = 0x00;
+ *(em.ptr+1) = 0x01;
+ *(em.ptr + em.len - digestInfo.len - 1) = 0x00;
+ /* set DER-encoded hash */
+ memcpy(em.ptr + em.len - digestInfo.len, digestInfo.ptr, digestInfo.len);
+
+ /* build signature */
+ *signature = rsasp1(this, em);
+
+ free(digestInfo.ptr);
+ free(em.ptr);
+
+ return TRUE;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static key_type_t get_type(private_gmp_rsa_private_key_t *this)
+{
+ return KEY_RSA;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static bool sign(private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t *signature)
+{
+ switch (scheme)
+ {
+ case SIGN_DEFAULT:
+ /* default is EMSA-PKCS1 using SHA1 */
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return build_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return build_emsa_pkcs1_signature(this, HASH_SHA256, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return build_emsa_pkcs1_signature(this, HASH_SHA384, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return build_emsa_pkcs1_signature(this, HASH_SHA512, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return build_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
+ default:
+ DBG1("signature scheme %N not supported in RSA",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static bool decrypt(private_gmp_rsa_private_key_t *this,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1("RSA private key decryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static size_t get_keysize(private_gmp_rsa_private_key_t *this)
+{
+ return this->k;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static identification_t* get_id(private_gmp_rsa_private_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.get_public_key.
+ */
+static gmp_rsa_public_key_t* get_public_key(private_gmp_rsa_private_key_t *this)
+{
+ return gmp_rsa_public_key_create_from_n_e(this->n, this->e);
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static bool belongs_to(private_gmp_rsa_private_key_t *this, public_key_t *public)
+{
+ identification_t *keyid;
+
+ if (public->get_type(public) != KEY_RSA)
+ {
+ return FALSE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * convert a MP integer into a DER coded ASN.1 object
+ */
+chunk_t gmp_mpz_to_asn1(const mpz_t value)
+{
+ chunk_t n;
+
+ n.len = 1 + mpz_sizeinbase(value, 2) / 8; /* size in bytes */
+ n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
+ if (n.ptr == NULL)
+ { /* if we have zero in "value", gmp returns NULL */
+ n.len = 0;
+ }
+ return asn1_wrap(ASN1_INTEGER, "m", n);
+}
+
+/**
+ * Implementation of private_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_gmp_rsa_private_key_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm",
+ ASN1_INTEGER_0,
+ gmp_mpz_to_asn1(this->n),
+ gmp_mpz_to_asn1(this->e),
+ gmp_mpz_to_asn1(this->d),
+ gmp_mpz_to_asn1(this->p),
+ gmp_mpz_to_asn1(this->q),
+ gmp_mpz_to_asn1(this->exp1),
+ gmp_mpz_to_asn1(this->exp2),
+ gmp_mpz_to_asn1(this->coeff));
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static private_gmp_rsa_private_key_t* get_ref(private_gmp_rsa_private_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static void destroy(private_gmp_rsa_private_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ mpz_clear_randomized(this->n);
+ mpz_clear_randomized(this->e);
+ mpz_clear_randomized(this->p);
+ mpz_clear_randomized(this->q);
+ mpz_clear_randomized(this->d);
+ mpz_clear_randomized(this->exp1);
+ mpz_clear_randomized(this->exp2);
+ mpz_clear_randomized(this->coeff);
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Check the loaded key if it is valid and usable
+ */
+static status_t check(private_gmp_rsa_private_key_t *this)
+{
+ mpz_t t, u, q1;
+ status_t status = SUCCESS;
+
+ /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
+ * We actually require more (for security).
+ */
+ if (this->k < 512/8)
+ {
+ DBG1("key shorter than 512 bits");
+ return FAILED;
+ }
+
+ /* we picked a max modulus size to simplify buffer allocation */
+ if (this->k > 8192/8)
+ {
+ DBG1("key larger than 8192 bits");
+ return FAILED;
+ }
+
+ mpz_init(t);
+ mpz_init(u);
+ mpz_init(q1);
+
+ /* check that n == p * q */
+ mpz_mul(u, this->p, this->q);
+ if (mpz_cmp(u, this->n) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that e divides neither p-1 nor q-1 */
+ mpz_sub_ui(t, this->p, 1);
+ mpz_mod(t, t, this->e);
+ if (mpz_cmp_ui(t, 0) == 0)
+ {
+ status = FAILED;
+ }
+
+ mpz_sub_ui(t, this->q, 1);
+ mpz_mod(t, t, this->e);
+ if (mpz_cmp_ui(t, 0) == 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that d is e^-1 (mod lcm(p-1, q-1)) */
+ /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
+ mpz_sub_ui(q1, this->q, 1);
+ mpz_sub_ui(u, this->p, 1);
+ mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */
+ mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */
+ mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */
+
+ mpz_mul(t, this->d, this->e);
+ mpz_mod(t, t, u);
+ if (mpz_cmp_ui(t, 1) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that exp1 is d mod (p-1) */
+ mpz_sub_ui(u, this->p, 1);
+ mpz_mod(t, this->d, u);
+ if (mpz_cmp(t, this->exp1) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that exp2 is d mod (q-1) */
+ mpz_sub_ui(u, this->q, 1);
+ mpz_mod(t, this->d, u);
+ if (mpz_cmp(t, this->exp2) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that coeff is (q^-1) mod p */
+ mpz_mul(t, this->coeff, this->q);
+ mpz_mod(t, t, this->p);
+ if (mpz_cmp_ui(t, 1) != 0)
+ {
+ status = FAILED;
+ }
+
+ mpz_clear_randomized(t);
+ mpz_clear_randomized(u);
+ mpz_clear_randomized(q1);
+ if (status != SUCCESS)
+ {
+ DBG1("key integrity tests failed");
+ }
+ return status;
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_gmp_rsa_private_key_t *gmp_rsa_private_key_create_empty(void)
+{
+ private_gmp_rsa_private_key_t *this = malloc_thing(private_gmp_rsa_private_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
+ this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
+ this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
+ this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
+ this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
+ this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
+ this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
+ this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
+
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * Generate an RSA key of specified key size
+ */
+static gmp_rsa_private_key_t *generate(size_t key_size)
+{
+ mpz_t p, q, n, e, d, exp1, exp2, coeff;
+ mpz_t m, q1, t;
+ private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
+
+ key_size = key_size / 8;
+
+ /* Get values of primes p and q */
+ if (compute_prime(this, key_size/2, &p) != SUCCESS)
+ {
+ free(this);
+ return NULL;
+ }
+ if (compute_prime(this, key_size/2, &q) != SUCCESS)
+ {
+ mpz_clear(p);
+ free(this);
+ return NULL;
+ }
+
+ mpz_init(t);
+ mpz_init(n);
+ mpz_init(d);
+ mpz_init(exp1);
+ mpz_init(exp2);
+ mpz_init(coeff);
+
+ /* Swapping Primes so p is larger then q */
+ if (mpz_cmp(p, q) < 0)
+ {
+ mpz_swap(p, q);
+ }
+
+ mpz_mul(n, p, q); /* n = p*q */
+ mpz_init_set_ui(e, PUBLIC_EXPONENT); /* assign public exponent */
+ mpz_init_set(m, p); /* m = p */
+ mpz_sub_ui(m, m, 1); /* m = m -1 */
+ mpz_init_set(q1, q); /* q1 = q */
+ mpz_sub_ui(q1, q1, 1); /* q1 = q1 -1 */
+ mpz_gcd(t, m, q1); /* t = gcd(p-1, q-1) */
+ mpz_mul(m, m, q1); /* m = (p-1)*(q-1) */
+ mpz_divexact(m, m, t); /* m = m / t */
+ mpz_gcd(t, m, e); /* t = gcd(m, e) */
+
+ mpz_invert(d, e, m); /* e has an inverse mod m */
+ if (mpz_cmp_ui(d, 0) < 0) /* make sure d is positive */
+ {
+ mpz_add(d, d, m);
+ }
+ mpz_sub_ui(t, p, 1); /* t = p-1 */
+ mpz_mod(exp1, d, t); /* exp1 = d mod p-1 */
+ mpz_sub_ui(t, q, 1); /* t = q-1 */
+ mpz_mod(exp2, d, t); /* exp2 = d mod q-1 */
+
+ mpz_invert(coeff, q, p); /* coeff = q^-1 mod p */
+ if (mpz_cmp_ui(coeff, 0) < 0) /* make coeff d is positive */
+ {
+ mpz_add(coeff, coeff, p);
+ }
+
+ mpz_clear_randomized(q1);
+ mpz_clear_randomized(m);
+ mpz_clear_randomized(t);
+
+ /* apply values */
+ *(this->p) = *p;
+ *(this->q) = *q;
+ *(this->n) = *n;
+ *(this->e) = *e;
+ *(this->d) = *d;
+ *(this->exp1) = *exp1;
+ *(this->exp2) = *exp2;
+ *(this->coeff) = *coeff;
+
+ /* set key size in bytes */
+ this->k = key_size;
+
+ return &this->public;
+}
+
+/**
+ * ASN.1 definition of a PKCS#1 RSA private key
+ */
+static const asn1Object_t privkeyObjects[] = {
+ { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
+ { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
+ { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
+ { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
+ { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
+ { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
+ { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
+ { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
+ { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
+ { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_LOOP }, /* 10 */
+ { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
+ { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
+ { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
+ { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
+ { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 15 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PRIV_KEY_VERSION 1
+#define PRIV_KEY_MODULUS 2
+#define PRIV_KEY_PUB_EXP 3
+#define PRIV_KEY_PRIV_EXP 4
+#define PRIV_KEY_PRIME1 5
+#define PRIV_KEY_PRIME2 6
+#define PRIV_KEY_EXP1 7
+#define PRIV_KEY_EXP2 8
+#define PRIV_KEY_COEFF 9
+
+/**
+ * load private key from a ASN1 encoded blob
+ */
+static gmp_rsa_private_key_t *load(chunk_t blob)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID ;
+ bool success = FALSE;
+
+ private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
+
+ mpz_init(this->n);
+ mpz_init(this->e);
+ mpz_init(this->p);
+ mpz_init(this->q);
+ mpz_init(this->d);
+ mpz_init(this->exp1);
+ mpz_init(this->exp2);
+ mpz_init(this->coeff);
+
+ parser = asn1_parser_create(privkeyObjects, blob);
+ parser->set_flags(parser, FALSE, TRUE);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PRIV_KEY_VERSION:
+ if (object.len > 0 && *object.ptr != 0)
+ {
+ goto end;
+ }
+ break;
+ case PRIV_KEY_MODULUS:
+ mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PUB_EXP:
+ mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PRIV_EXP:
+ mpz_import(this->d, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PRIME1:
+ mpz_import(this->p, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PRIME2:
+ mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_EXP1:
+ mpz_import(this->exp1, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_EXP2:
+ mpz_import(this->exp2, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_COEFF:
+ mpz_import(this->coeff, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ chunk_clear(&blob);
+
+ if (!success)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
+
+ if (!gmp_rsa_public_key_build_id(this->n, this->e,
+ &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (check(this) != SUCCESS)
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading/generation
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded/generated private key */
+ gmp_rsa_private_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static gmp_rsa_private_key_t *build(private_builder_t *this)
+{
+ gmp_rsa_private_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ case BUILD_KEY_SIZE:
+ {
+ va_start(args, part);
+ this->key = generate(va_arg(args, u_int));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *gmp_rsa_private_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_RSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h
new file mode 100644
index 000000000..6f59b2ad2
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup gmp_rsa_private_key gmp_rsa_private_key
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_RSA_PRIVATE_KEY_H_
+#define GMP_RSA_PRIVATE_KEY_H_
+
+#include <credentials/keys/private_key.h>
+
+typedef struct gmp_rsa_private_key_t gmp_rsa_private_key_t;
+
+/**
+ * Private_key_t implementation of RSA algorithm using libgmp.
+ */
+struct gmp_rsa_private_key_t {
+
+ /**
+ * Implements private_key_t interface
+ */
+ private_key_t interface;
+};
+
+/**
+ * Create the builder for a private key.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @return builder instance
+ */
+builder_t *gmp_rsa_private_key_builder(key_type_t type);
+
+#endif /*GMP_RSA_PRIVATE_KEY_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
new file mode 100644
index 000000000..e4f898ecc
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
@@ -0,0 +1,587 @@
+/*
+ * Copyright (C) 2005-2008 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: gmp_rsa_public_key.c 3988 2008-05-21 13:01:58Z martin $
+ */
+
+#include <gmp.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "gmp_rsa_public_key.h"
+
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/pem.h>
+#include <crypto/hashers/hasher.h>
+
+/**
+ * defined in gmp_rsa_private_key.c
+ */
+extern chunk_t gmp_mpz_to_asn1(const mpz_t value);
+
+typedef struct private_gmp_rsa_public_key_t private_gmp_rsa_public_key_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_gmp_rsa_public_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ gmp_rsa_public_key_t public;
+
+ /**
+ * Public modulus.
+ */
+ mpz_t n;
+
+ /**
+ * Public exponent.
+ */
+ mpz_t e;
+
+ /**
+ * Keysize in bytes.
+ */
+ size_t k;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+ */
+ identification_t *keyid_info;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKey object
+ */
+ identification_t *keyid;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * RSAEP algorithm specified in PKCS#1.
+ */
+static chunk_t rsaep(private_gmp_rsa_public_key_t *this, chunk_t data)
+{
+ mpz_t m, c;
+ chunk_t encrypted;
+
+ mpz_init(c);
+ mpz_init(m);
+
+ mpz_import(m, data.len, 1, 1, 1, 0, data.ptr);
+
+ mpz_powm(c, m, this->e, this->n);
+
+ encrypted.len = this->k;
+ encrypted.ptr = mpz_export(NULL, NULL, 1, encrypted.len, 1, 0, c);
+
+ mpz_clear(c);
+ mpz_clear(m);
+
+ return encrypted;
+}
+
+/**
+ * RSAVP1 algorithm specified in PKCS#1.
+ */
+static chunk_t rsavp1(private_gmp_rsa_public_key_t *this, chunk_t data)
+{
+ return rsaep(this, data);
+}
+
+/**
+ * ASN.1 definition of digestInfo
+ */
+static const asn1Object_t digestInfoObjects[] = {
+ { 0, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 1, "digest", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define DIGEST_INFO 0
+#define DIGEST_INFO_ALGORITHM 1
+#define DIGEST_INFO_DIGEST 2
+
+/**
+ * Verification of an EMPSA PKCS1 signature described in PKCS#1
+ */
+static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
+ hash_algorithm_t algorithm,
+ chunk_t data, chunk_t signature)
+{
+ chunk_t em_ori, em;
+ bool success = FALSE;
+
+ /* remove any preceding 0-bytes from signature */
+ while (signature.len && *(signature.ptr) == 0x00)
+ {
+ signature.len -= 1;
+ signature.ptr++;
+ }
+
+ if (signature.len > this->k)
+ {
+ return INVALID_ARG;
+ }
+
+ /* unpack signature */
+ em_ori = em = rsavp1(this, signature);
+
+ /* result should look like this:
+ * EM = 0x00 || 0x01 || PS || 0x00 || T.
+ * PS = 0xFF padding, with length to fill em
+ * T = oid || hash
+ */
+
+ /* check magic bytes */
+ if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x01)
+ {
+ goto end;
+ }
+ em.ptr += 2;
+ em.len -= 2;
+
+ /* find magic 0x00 */
+ while (em.len > 0)
+ {
+ if (*em.ptr == 0x00)
+ {
+ /* found magic byte, stop */
+ em.ptr++;
+ em.len--;
+ break;
+ }
+ else if (*em.ptr != 0xFF)
+ {
+ /* bad padding, decryption failed ?!*/
+ goto end;
+ }
+ em.ptr++;
+ em.len--;
+ }
+
+ if (em.len == 0)
+ {
+ /* no digestInfo found */
+ goto end;
+ }
+
+ /* parse ASN.1-based digestInfo */
+ {
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ hash_algorithm_t hash_algorithm = HASH_UNKNOWN;
+
+ parser = asn1_parser_create(digestInfoObjects, em);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case DIGEST_INFO:
+ {
+ if (em.len > object.len)
+ {
+ DBG1("digestInfo field in signature is followed by %u surplus bytes",
+ em.len - object.len);
+ goto end_parser;
+ }
+ break;
+ }
+ case DIGEST_INFO_ALGORITHM:
+ {
+ int hash_oid = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
+
+ hash_algorithm = hasher_algorithm_from_oid(hash_oid);
+ if (hash_algorithm == HASH_UNKNOWN ||
+ (algorithm != HASH_UNKNOWN && hash_algorithm != algorithm))
+ {
+ DBG1("expected hash algorithm %N, but found %N (OID: %#B)",
+ hash_algorithm_names, algorithm,
+ hash_algorithm_names, hash_algorithm, &object);
+ goto end_parser;
+ }
+ break;
+ }
+ case DIGEST_INFO_DIGEST:
+ {
+ chunk_t hash;
+ hasher_t *hasher;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+ if (hasher == NULL)
+ {
+ DBG1("hash algorithm %N not supported",
+ hash_algorithm_names, hash_algorithm);
+ goto end_parser;
+ }
+
+ if (object.len != hasher->get_hash_size(hasher))
+ {
+ DBG1("hash size in signature is %u bytes instead of %u "
+ "bytes", object.len, hasher->get_hash_size(hasher));
+ hasher->destroy(hasher);
+ goto end_parser;
+ }
+
+ /* build our own hash and compare */
+ hasher->allocate_hash(hasher, data, &hash);
+ hasher->destroy(hasher);
+ success = memeq(object.ptr, hash.ptr, hash.len);
+ free(hash.ptr);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+end_parser:
+ success &= parser->success(parser);
+ parser->destroy(parser);
+ }
+
+end:
+ free(em_ori.ptr);
+ return success;
+}
+
+/**
+ * Implementation of public_key_t.get_type.
+ */
+static key_type_t get_type(private_gmp_rsa_public_key_t *this)
+{
+ return KEY_RSA;
+}
+
+/**
+ * Implementation of public_key_t.verify.
+ */
+static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t signature)
+{
+ switch (scheme)
+ {
+ case SIGN_DEFAULT: /* default is EMSA-PKCS1 using included OID */
+ return verify_emsa_pkcs1_signature(this, HASH_UNKNOWN, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return verify_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return verify_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return verify_emsa_pkcs1_signature(this, HASH_SHA256, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return verify_emsa_pkcs1_signature(this, HASH_SHA384, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return verify_emsa_pkcs1_signature(this, HASH_SHA512, data, signature);
+ default:
+ DBG1("signature scheme %N not supported in RSA",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static bool encrypt(private_gmp_rsa_public_key_t *this, chunk_t crypto, chunk_t *plain)
+{
+ DBG1("RSA public key encryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static size_t get_keysize(private_gmp_rsa_public_key_t *this)
+{
+ return this->k;
+}
+
+/**
+ * Implementation of public_key_t.get_id.
+ */
+static identification_t *get_id(private_gmp_rsa_public_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * Implementation of public_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_gmp_rsa_public_key_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "mm",
+ gmp_mpz_to_asn1(this->n),
+ gmp_mpz_to_asn1(this->e));
+}
+
+/**
+ * Implementation of public_key_t.get_ref.
+ */
+static private_gmp_rsa_public_key_t* get_ref(private_gmp_rsa_public_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of gmp_rsa_public_key.destroy.
+ */
+static void destroy(private_gmp_rsa_public_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ mpz_clear(this->n);
+ mpz_clear(this->e);
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Generic private constructor
+ */
+static private_gmp_rsa_public_key_t *gmp_rsa_public_key_create_empty()
+{
+ private_gmp_rsa_public_key_t *this = malloc_thing(private_gmp_rsa_public_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
+ this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
+ this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt;
+ this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
+ this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
+ this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
+
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * Build the RSA key identifier from n and e using SHA1 hashed publicKey(Info).
+ * Also used in rsa_private_key.c.
+ */
+bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, identification_t **keyid,
+ identification_t **keyid_info)
+{
+ chunk_t publicKeyInfo, publicKey, hash;
+ hasher_t *hasher;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher == NULL)
+ {
+ DBG1("SHA1 hash algorithm not supported, unable to use RSA");
+ return FALSE;
+ }
+ publicKey = asn1_wrap(ASN1_SEQUENCE, "mm",
+ gmp_mpz_to_asn1(n),
+ gmp_mpz_to_asn1(e));
+ hasher->allocate_hash(hasher, publicKey, &hash);
+ *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
+ chunk_free(&hash);
+
+ publicKeyInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
+ asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
+ asn1_bitstring("m", publicKey));
+ hasher->allocate_hash(hasher, publicKeyInfo, &hash);
+ *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash);
+ chunk_free(&hash);
+
+ hasher->destroy(hasher);
+ chunk_free(&publicKeyInfo);
+
+ return TRUE;
+}
+
+/**
+ * Create a public key from mpz values, used in gmp_rsa_private_key
+ */
+gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e)
+{
+ private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty();
+
+ mpz_init_set(this->n, n);
+ mpz_init_set(this->e, e);
+
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
+ if (!gmp_rsa_public_key_build_id(this->n, this->e,
+ &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+/**
+ * ASN.1 definition of RSApublicKey
+ */
+static const asn1Object_t pubkeyObjects[] = {
+ { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
+ { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PUB_KEY_RSA_PUBLIC_KEY 0
+#define PUB_KEY_MODULUS 1
+#define PUB_KEY_EXPONENT 2
+
+/**
+ * Load a public key from an ASN1 encoded blob
+ */
+static gmp_rsa_public_key_t *load(chunk_t blob)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool success = FALSE;
+
+ private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty();
+
+ mpz_init(this->n);
+ mpz_init(this->e);
+
+ parser = asn1_parser_create(pubkeyObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PUB_KEY_MODULUS:
+ mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PUB_KEY_EXPONENT:
+ mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ }
+ }
+ success = parser->success(parser);
+ free(blob.ptr);
+ parser->destroy(parser);
+
+ if (!success)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
+
+ if (!gmp_rsa_public_key_build_id(this->n, this->e,
+ &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded public key */
+ gmp_rsa_public_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static gmp_rsa_public_key_t *build(private_builder_t *this)
+{
+ gmp_rsa_public_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *gmp_rsa_public_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_RSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h
new file mode 100644
index 000000000..2e502b7e6
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005-2008 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: gmp_rsa_public_key.h 3721 2008-04-01 14:51:31Z martin $
+ */
+
+/**
+ * @defgroup gmp_rsa_public_key gmp_rsa_public_key
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_RSA_PUBLIC_KEY_H_
+#define GMP_RSA_PUBLIC_KEY_H_
+
+typedef struct gmp_rsa_public_key_t gmp_rsa_public_key_t;
+
+#include <credentials/keys/public_key.h>
+
+/**
+ * public_key_t implementation of RSA algorithm using libgmp.
+ */
+struct gmp_rsa_public_key_t {
+
+ /**
+ * Implements the public_key_t interface
+ */
+ public_key_t interface;
+};
+
+/**
+ * Create the builder for a public key.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @return builder instance
+ */
+builder_t *gmp_rsa_public_key_builder(key_type_t type);
+
+#endif /*GMP_RSA_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/hmac/Makefile.am b/src/libstrongswan/plugins/hmac/Makefile.am
new file mode 100644
index 000000000..89e0638f3
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-hmac.la
+
+libstrongswan_hmac_la_SOURCES = hmac_plugin.h hmac_plugin.c hmac.h hmac.c \
+ hmac_prf.h hmac_prf.c hmac_signer.h hmac_signer.c
+libstrongswan_hmac_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in
new file mode 100644
index 000000000..b6e851cd4
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/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/libstrongswan/plugins/hmac
+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_hmac_la_LIBADD =
+am_libstrongswan_hmac_la_OBJECTS = hmac_plugin.lo hmac.lo hmac_prf.lo \
+ hmac_signer.lo
+libstrongswan_hmac_la_OBJECTS = $(am_libstrongswan_hmac_la_OBJECTS)
+libstrongswan_hmac_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_hmac_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_hmac_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_hmac_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-hmac.la
+libstrongswan_hmac_la_SOURCES = hmac_plugin.h hmac_plugin.c hmac.h hmac.c \
+ hmac_prf.h hmac_prf.c hmac_signer.h hmac_signer.c
+
+libstrongswan_hmac_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/libstrongswan/plugins/hmac/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/hmac/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-hmac.la: $(libstrongswan_hmac_la_OBJECTS) $(libstrongswan_hmac_la_DEPENDENCIES)
+ $(libstrongswan_hmac_la_LINK) -rpath $(plugindir) $(libstrongswan_hmac_la_OBJECTS) $(libstrongswan_hmac_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac_prf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac_signer.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/libstrongswan/crypto/hmac.c b/src/libstrongswan/plugins/hmac/hmac.c
index df4f90bc8..b2f99bdc3 100644
--- a/src/libstrongswan/crypto/hmac.c
+++ b/src/libstrongswan/plugins/hmac/hmac.c
@@ -1,9 +1,3 @@
-/**
- * @file hmac.c
- *
- * @brief Implementation of hmac_t.
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -18,6 +12,8 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General hmac License
* for more details.
+ *
+ * $Id: hmac.c 3488 2008-02-21 15:10:02Z martin $
*/
#include <string.h>
@@ -173,9 +169,7 @@ static void destroy(private_hmac_t *this)
*/
hmac_t *hmac_create(hash_algorithm_t hash_algorithm)
{
- private_hmac_t *this;
-
- this = malloc_thing(private_hmac_t);
+ private_hmac_t *this = malloc_thing(private_hmac_t);
/* set hmac_t methods */
this->hmac.get_mac = (void (*)(hmac_t *,chunk_t,u_int8_t*))get_mac;
@@ -200,9 +194,14 @@ hmac_t *hmac_create(hash_algorithm_t hash_algorithm)
free(this);
return NULL;
}
-
+
/* build the hasher */
- this->h = hasher_create(hash_algorithm);
+ this->h = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+ if (this->h == NULL)
+ {
+ free(this);
+ return NULL;
+ }
/* build ipad and opad */
this->opaded_key.ptr = malloc(this->b);
diff --git a/src/libstrongswan/crypto/hmac.h b/src/libstrongswan/plugins/hmac/hmac.h
index 06b75aaf9..5f266e133 100644
--- a/src/libstrongswan/crypto/hmac.h
+++ b/src/libstrongswan/plugins/hmac/hmac.h
@@ -1,11 +1,5 @@
-/**
- * @file hmac.h
- *
- * @brief Interface of hmac_t.
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -20,6 +14,11 @@
* for more details.
*/
+/**
+ * @defgroup hmac hmac
+ * @{ @ingroup hmac_p
+ */
+
#ifndef HMAC_H_
#define HMAC_H_
@@ -28,90 +27,67 @@ typedef struct hmac_t hmac_t;
#include <crypto/hashers/hasher.h>
/**
- * @brief Message authentication using hash functions.
+ * Message authentication using hash functions.
*
* This class implements the message authenticaion algorithm
* described in RFC2104. It uses a hash function, wich must
* be implemented as a hasher_t class.
- *
- * See http://www.faqs.org/rfcs/rfc2104.html for RFC.
- * @see
- * - hasher_t
- * - prf_hmac_t
- *
- * @b Constructors:
- * - hmac_create()
- *
- * @ingroup crypto
*/
struct hmac_t {
/**
- * @brief Generate message authentication code.
+ * Generate message authentication code.
*
* If buffer is NULL, no result is given back. A next call will
* append the data to already supplied data. If buffer is not NULL,
* the mac of all apended data is calculated, returned and the
* state of the hmac_t is reseted.
*
- * @param this calling object
- * @param data chunk of data to authenticate
- * @param[out] buffer pointer where the generated bytes will be written
+ * @param data chunk of data to authenticate
+ * @param buffer pointer where the generated bytes will be written
*/
void (*get_mac) (hmac_t *this, chunk_t data, u_int8_t *buffer);
/**
- * @brief Generates message authentication code and
- * allocate space for them.
+ * Generates message authentication code and allocate space for them.
*
* If chunk is NULL, no result is given back. A next call will
* append the data to already supplied. If chunk is not NULL,
* the mac of all apended data is calculated, returned and the
* state of the hmac_t reset;
*
- * @param this calling object
- * @param data chunk of data to authenticate
- * @param[out] chunk chunk which will hold generated bytes
+ * @param data chunk of data to authenticate
+ * @param chunk chunk which will hold generated bytes
*/
void (*allocate_mac) (hmac_t *this, chunk_t data, chunk_t *chunk);
/**
- * @brief Get the block size of this hmac_t object.
+ * Get the block size of this hmac_t object.
*
- * @param this calling object
- * @return block size in bytes
+ * @return block size in bytes
*/
size_t (*get_block_size) (hmac_t *this);
/**
- * @brief Set the key for this hmac_t object.
+ * Set the key for this hmac_t object.
*
* Any key length is accepted.
*
- * @param this calling object
- * @param key key to set
+ * @param key key to set
*/
void (*set_key) (hmac_t *this, chunk_t key);
/**
- * @brief Destroys a hmac_t object.
- *
- * @param this calling object
+ * Destroys a hmac_t object.
*/
void (*destroy) (hmac_t *this);
};
/**
- * @brief Creates a new hmac_t object.
- *
- * Creates a hasher_t object internally.
- *
- * @param hash_algorithm hash algorithm to use
- * @return
- * - hmac_t object
- * - NULL if hash algorithm is not supported
+ * Creates a new hmac_t object.
*
- * @ingroup transforms
+ * @param hash_algorithm hash algorithm to use
+ * @return hmac_t object, NULL if not supported
*/
hmac_t *hmac_create(hash_algorithm_t hash_algorithm);
-#endif /*HMAC_H_*/
+#endif /*HMAC_H_ @}*/
diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.c b/src/libstrongswan/plugins/hmac/hmac_plugin.c
new file mode 100644
index 000000000..bfa2df35f
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/hmac_plugin.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.
+ *
+ * $Id: hmac_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "hmac_plugin.h"
+
+#include <library.h>
+#include "hmac_signer.h"
+#include "hmac_prf.h"
+
+typedef struct private_hmac_plugin_t private_hmac_plugin_t;
+
+/**
+ * private data of hmac_plugin
+ */
+struct private_hmac_plugin_t {
+
+ /**
+ * public functions
+ */
+ hmac_plugin_t public;
+};
+
+/**
+ * Implementation of hmac_plugin_t.hmactroy
+ */
+static void destroy(private_hmac_plugin_t *this)
+{
+ lib->crypto->remove_prf(lib->crypto,
+ (prf_constructor_t)hmac_prf_create);
+ lib->crypto->remove_signer(lib->crypto,
+ (signer_constructor_t)hmac_signer_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_hmac_plugin_t *this = malloc_thing(private_hmac_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_prf(lib->crypto, PRF_HMAC_MD5,
+ (prf_constructor_t)hmac_prf_create);
+ lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA1,
+ (prf_constructor_t)hmac_prf_create);
+ lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_256,
+ (prf_constructor_t)hmac_prf_create);
+ lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_384,
+ (prf_constructor_t)hmac_prf_create);
+ lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_512,
+ (prf_constructor_t)hmac_prf_create);
+
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_MD5_96,
+ (signer_constructor_t)hmac_signer_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_96,
+ (signer_constructor_t)hmac_signer_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_128,
+ (signer_constructor_t)hmac_signer_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_256_128,
+ (signer_constructor_t)hmac_signer_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_384_192,
+ (signer_constructor_t)hmac_signer_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_512_256,
+ (signer_constructor_t)hmac_signer_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.h b/src/libstrongswan/plugins/hmac/hmac_plugin.h
new file mode 100644
index 000000000..55ba0b5f4
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/hmac_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup hmac_p hmac
+ * @ingroup plugins
+ *
+ * @defgroup hmac_plugin hmac_plugin
+ * @{ @ingroup hmac_p
+ */
+
+#ifndef HMAC_PLUGIN_H_
+#define HMAC_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct hmac_plugin_t hmac_plugin_t;
+
+/**
+ * Plugin implementing HMAC algorithm to prvoide hash based PRF and signers.
+ */
+struct hmac_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a hmac_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* HMAC_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/crypto/prfs/hmac_prf.c b/src/libstrongswan/plugins/hmac/hmac_prf.c
index f315f880d..8d843bc5a 100644
--- a/src/libstrongswan/crypto/prfs/hmac_prf.c
+++ b/src/libstrongswan/plugins/hmac/hmac_prf.c
@@ -1,10 +1,3 @@
-/**
- * @file hmac_prf.c
- *
- * @brief Implementation for hmac_prf_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,11 +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: hmac_prf.c 3488 2008-02-21 15:10:02Z martin $
*/
#include "hmac_prf.h"
-#include <crypto/hmac.h>
+#include "hmac.h"
typedef struct private_hmac_prf_t private_hmac_prf_t;
@@ -96,23 +91,47 @@ static void destroy(private_hmac_prf_t *this)
/*
* Described in header.
*/
-hmac_prf_t *hmac_prf_create(hash_algorithm_t hash_algorithm)
+hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo)
{
- private_hmac_prf_t *this = malloc_thing(private_hmac_prf_t);
+ private_hmac_prf_t *this;
+ hash_algorithm_t hash;
- this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
- this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
- this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
- this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
- this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
- this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
+ switch (algo)
+ {
+ case PRF_HMAC_SHA1:
+ hash = HASH_SHA1;
+ break;
+ case PRF_HMAC_MD5:
+ hash = HASH_MD5;
+ break;
+ case PRF_HMAC_SHA2_256:
+ hash = HASH_SHA256;
+ break;
+ case PRF_HMAC_SHA2_384:
+ hash = HASH_SHA384;
+ break;
+ case PRF_HMAC_SHA2_512:
+ hash = HASH_SHA512;
+ break;
+ default:
+ return NULL;
+ }
- this->hmac = hmac_create(hash_algorithm);
+ this = malloc_thing(private_hmac_prf_t);
+ this->hmac = hmac_create(hash);
if (this->hmac == NULL)
{
free(this);
return NULL;
}
+ this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
+ this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
+ this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
+ this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
+ this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
+ this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
+
return &(this->public);
}
+
diff --git a/src/libstrongswan/crypto/prfs/hmac_prf.h b/src/libstrongswan/plugins/hmac/hmac_prf.h
index 9b06ee3a2..46d05f03a 100644
--- a/src/libstrongswan/crypto/prfs/hmac_prf.h
+++ b/src/libstrongswan/plugins/hmac/hmac_prf.h
@@ -1,12 +1,5 @@
-/**
- * @file hmac_prf.h
- *
- * @brief Interface of hmac_prf_t.
- *
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -21,26 +14,23 @@
* for more details.
*/
+/**
+ * @defgroup hmac_prf hmac_prf
+ * @{ @ingroup hmac_p
+ */
+
#ifndef PRF_HMAC_H_
#define PRF_HMAC_H_
typedef struct hmac_prf_t hmac_prf_t;
-#include <library.h>
#include <crypto/prfs/prf.h>
-#include <crypto/hashers/hasher.h>
/**
- * @brief Implementation of prf_t interface using the
- * HMAC algorithm.
+ * Implementation of prf_t interface using the HMAC algorithm.
*
* This simply wraps a hmac_t in a prf_t. More a question of
* interface matching.
- *
- * @b Constructors:
- * - hmac_prf_create()
- *
- * @ingroup prfs
*/
struct hmac_prf_t {
@@ -51,15 +41,11 @@ struct hmac_prf_t {
};
/**
- * @brief Creates a new hmac_prf_t object.
- *
- * @param hash_algorithm hmac's hash algorithm
- * @return
- * - hmac_prf_t object
- * - NULL if hash not supported
+ * Creates a new hmac_prf_t object.
*
- * @ingroup prfs
+ * @param algo algorithm to implement
+ * @return hmac_prf_t object, NULL if hash not supported
*/
-hmac_prf_t *hmac_prf_create(hash_algorithm_t hash_algorithm);
+hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo);
-#endif /*PRF_HMAC_SHA1_H_*/
+#endif /*PRF_HMAC_SHA1_H_ @}*/
diff --git a/src/libstrongswan/crypto/signers/hmac_signer.c b/src/libstrongswan/plugins/hmac/hmac_signer.c
index ad5b882a6..cdfc819f1 100644
--- a/src/libstrongswan/crypto/signers/hmac_signer.c
+++ b/src/libstrongswan/plugins/hmac/hmac_signer.c
@@ -1,12 +1,5 @@
-/**
- * @file hmac_signer.c
- *
- * @brief Implementation of hmac_signer_t.
- *
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -19,13 +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: hmac_signer.c 3488 2008-02-21 15:10:02Z martin $
*/
#include <string.h>
#include "hmac_signer.h"
-
-#include <crypto/prfs/hmac_prf.h>
+#include "hmac.h"
typedef struct private_hmac_signer_t private_hmac_signer_t;
@@ -41,7 +35,7 @@ struct private_hmac_signer_t {
/**
* Assigned hmac function.
*/
- prf_t *hmac_prf;
+ hmac_t *hmac;
/**
* Block size (truncation of HMAC Hash)
@@ -52,69 +46,60 @@ struct private_hmac_signer_t {
/**
* Implementation of signer_t.get_signature.
*/
-static void get_signature(private_hmac_signer_t *this, chunk_t data, u_int8_t *buffer)
+static void get_signature(private_hmac_signer_t *this,
+ chunk_t data, u_int8_t *buffer)
{
if (buffer == NULL)
{ /* append mode */
- this->hmac_prf->get_bytes(this->hmac_prf, data, NULL);
+ this->hmac->get_mac(this->hmac, data, NULL);
}
else
{
- u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
+ u_int8_t mac[this->hmac->get_block_size(this->hmac)];
- this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
- memcpy(buffer, full_mac, this->block_size);
+ this->hmac->get_mac(this->hmac, data, mac);
+ memcpy(buffer, mac, this->block_size);
}
}
/**
* Implementation of signer_t.allocate_signature.
*/
-static void allocate_signature (private_hmac_signer_t *this, chunk_t data, chunk_t *chunk)
+static void allocate_signature (private_hmac_signer_t *this,
+ chunk_t data, chunk_t *chunk)
{
if (chunk == NULL)
{ /* append mode */
- this->hmac_prf->get_bytes(this->hmac_prf, data, NULL);
+ this->hmac->get_mac(this->hmac, data, NULL);
}
else
{
- chunk_t signature;
- u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
+ u_int8_t mac[this->hmac->get_block_size(this->hmac)];
- this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
+ this->hmac->get_mac(this->hmac, data, mac);
- signature.ptr = malloc(this->block_size);
- signature.len = this->block_size;
+ chunk->ptr = malloc(this->block_size);
+ chunk->len = this->block_size;
- memcpy(signature.ptr, full_mac, this->block_size);
-
- *chunk = signature;
+ memcpy(chunk->ptr, mac, this->block_size);
}
}
/**
* Implementation of signer_t.verify_signature.
*/
-static bool verify_signature(private_hmac_signer_t *this, chunk_t data, chunk_t signature)
+static bool verify_signature(private_hmac_signer_t *this,
+ chunk_t data, chunk_t signature)
{
- u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
+ u_int8_t mac[this->hmac->get_block_size(this->hmac)];
- this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
+ this->hmac->get_mac(this->hmac, data, mac);
if (signature.len != this->block_size)
{
return FALSE;
}
-
- /* compare mac aka signature :-) */
- if (memcmp(signature.ptr, full_mac, this->block_size) == 0)
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ return memeq(signature.ptr, mac, this->block_size);
}
/**
@@ -122,8 +107,7 @@ static bool verify_signature(private_hmac_signer_t *this, chunk_t data, chunk_t
*/
static size_t get_key_size(private_hmac_signer_t *this)
{
- /* for HMAC signer, IKEv2 uses block size as key size */
- return this->hmac_prf->get_block_size(this->hmac_prf);
+ return this->hmac->get_block_size(this->hmac);
}
/**
@@ -139,7 +123,7 @@ static size_t get_block_size(private_hmac_signer_t *this)
*/
static void set_key(private_hmac_signer_t *this, chunk_t key)
{
- this->hmac_prf->set_key(this->hmac_prf, key);
+ this->hmac->set_key(this->hmac, key);
}
/**
@@ -147,7 +131,7 @@ static void set_key(private_hmac_signer_t *this, chunk_t key)
*/
static status_t destroy(private_hmac_signer_t *this)
{
- this->hmac_prf->destroy(this->hmac_prf);
+ this->hmac->destroy(this->hmac);
free(this);
return SUCCESS;
}
@@ -155,22 +139,51 @@ static status_t destroy(private_hmac_signer_t *this)
/*
* Described in header
*/
-hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, size_t block_size)
+hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo)
{
- size_t hmac_block_size;
- private_hmac_signer_t *this = malloc_thing(private_hmac_signer_t);
-
- this->hmac_prf = (prf_t *) hmac_prf_create(hash_algoritm);
- if (this->hmac_prf == NULL)
+ private_hmac_signer_t *this;
+ size_t trunc;
+ hash_algorithm_t hash;
+
+ switch (algo)
+ {
+ case AUTH_HMAC_SHA1_96:
+ hash = HASH_SHA1;
+ trunc = 12;
+ break;
+ case AUTH_HMAC_SHA1_128:
+ hash = HASH_SHA1;
+ trunc = 16;
+ break;
+ case AUTH_HMAC_MD5_96:
+ hash = HASH_MD5;
+ trunc = 12;
+ break;
+ case AUTH_HMAC_SHA2_256_128:
+ hash = HASH_SHA256;
+ trunc = 16;
+ break;
+ case AUTH_HMAC_SHA2_384_192:
+ hash = HASH_SHA384;
+ trunc = 24;
+ break;
+ case AUTH_HMAC_SHA2_512_256:
+ hash = HASH_SHA512;
+ trunc = 32;
+ break;
+ default:
+ return NULL;
+ }
+
+ this = malloc_thing(private_hmac_signer_t);
+ this->hmac = hmac_create(hash);
+ if (this->hmac == NULL)
{
- /* algorithm not supported */
free(this);
return NULL;
}
-
/* prevent invalid truncation */
- hmac_block_size = this->hmac_prf->get_block_size(this->hmac_prf);
- this->block_size = min(block_size, hmac_block_size);
+ this->block_size = min(trunc, this->hmac->get_block_size(this->hmac));
/* interface functions */
this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature;
@@ -183,3 +196,4 @@ hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, size_t block_s
return &(this->public);
}
+
diff --git a/src/libstrongswan/crypto/signers/hmac_signer.h b/src/libstrongswan/plugins/hmac/hmac_signer.h
index 2449069bd..969f482e7 100644
--- a/src/libstrongswan/crypto/signers/hmac_signer.h
+++ b/src/libstrongswan/plugins/hmac/hmac_signer.h
@@ -1,12 +1,5 @@
-/**
- * @file hmac_signer.h
- *
- * @brief Interface of hmac_signer_t.
- *
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -21,21 +14,22 @@
* for more details.
*/
+/**
+ * @defgroup hmac_signer hmac_signer
+ * @{ @ingroup hmac_p
+ */
+
#ifndef HMAC_SIGNER_H_
#define HMAC_SIGNER_H_
typedef struct hmac_signer_t hmac_signer_t;
#include <crypto/signers/signer.h>
-#include <crypto/hashers/hasher.h>
/**
- * @brief Implementation of signer_t interface using HMAC.
+ * Implementation of signer_t interface using HMAC.
*
- * HMAC uses a standard hash function implemented in a hasher_t to build
- * a MAC.
- *
- * @ingroup signers
+ * HMAC uses a standard hash function implemented in a hasher_t to build a MAC.
*/
struct hmac_signer_t {
@@ -46,23 +40,16 @@ struct hmac_signer_t {
};
/**
- * @brief Creates a new hmac_signer_t.
+ * Creates a new hmac_signer_t.
*
* HMAC signatures are often truncated to shorten them to a more usable, but
* still secure enough length.
* Block size must be equal or smaller then the hash algorithms
* hash.
*
- * @param hash_algoritm Hash algorithm to use with signer
- * @param block_size Size of resulting signature (truncated to block_size)
- * @return
- * - hmac_signer_t
- * - NULL if hash algorithm not supported
- *
- * @ingroup signers
+ * @param algo algorithm to implement
+ * @return hmac_signer_t, NULL if not supported
*/
-hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm,
- size_t block_size);
-
+hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo);
-#endif /*HMAC_SIGNER_H_*/
+#endif /*HMAC_SIGNER_H_ @}*/
diff --git a/src/libstrongswan/plugins/ldap/Makefile.am b/src/libstrongswan/plugins/ldap/Makefile.am
new file mode 100644
index 000000000..ac6b4be00
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-ldap.la
+
+libstrongswan_ldap_la_SOURCES = ldap_plugin.h ldap_plugin.c ldap_fetcher.h ldap_fetcher.c
+libstrongswan_ldap_la_LDFLAGS = -module
+libstrongswan_ldap_la_LIBADD = -lldap -llber
+
diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in
new file mode 100644
index 000000000..8c28f1307
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/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/libstrongswan/plugins/ldap
+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_ldap_la_DEPENDENCIES =
+am_libstrongswan_ldap_la_OBJECTS = ldap_plugin.lo ldap_fetcher.lo
+libstrongswan_ldap_la_OBJECTS = $(am_libstrongswan_ldap_la_OBJECTS)
+libstrongswan_ldap_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_ldap_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_ldap_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_ldap_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-ldap.la
+libstrongswan_ldap_la_SOURCES = ldap_plugin.h ldap_plugin.c ldap_fetcher.h ldap_fetcher.c
+libstrongswan_ldap_la_LDFLAGS = -module
+libstrongswan_ldap_la_LIBADD = -lldap -llber
+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/libstrongswan/plugins/ldap/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/ldap/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-ldap.la: $(libstrongswan_ldap_la_OBJECTS) $(libstrongswan_ldap_la_DEPENDENCIES)
+ $(libstrongswan_ldap_la_LINK) -rpath $(plugindir) $(libstrongswan_ldap_la_OBJECTS) $(libstrongswan_ldap_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldap_fetcher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldap_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/libstrongswan/plugins/ldap/ldap_fetcher.c b/src/libstrongswan/plugins/ldap/ldap_fetcher.c
new file mode 100644
index 000000000..8e55b800e
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/ldap_fetcher.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: ldap_fetcher.c 3693 2008-03-28 22:44:45Z andreas $
+ */
+
+#ifndef LDAP_DEPRECATED
+#define LDAP_DEPRECATED 1
+#endif /* LDAP_DEPRECATED */
+#include <ldap.h>
+
+#include <errno.h>
+
+#include <library.h>
+#include <debug.h>
+
+#include "ldap_fetcher.h"
+
+#define DEFAULT_TIMEOUT 10
+
+typedef struct private_ldap_fetcher_t private_ldap_fetcher_t;
+
+/**
+ * Private Data of a ldap_fetcher_t object.
+ */
+struct private_ldap_fetcher_t {
+ /**
+ * Public data
+ */
+ ldap_fetcher_t public;
+
+ /**
+ * timeout to use for fetches
+ */
+ u_int timeout;
+};
+
+/**
+ * Parses the result returned by an ldap query
+ */
+static bool parse(LDAP *ldap, LDAPMessage *result, chunk_t *response)
+{
+ LDAPMessage *entry = ldap_first_entry(ldap, result);
+ bool success = FALSE;
+
+ if (entry)
+ {
+ BerElement *ber = NULL;
+ char *attr;
+
+ attr = ldap_first_attribute(ldap, entry, &ber);
+ if (attr)
+ {
+ struct berval **values = ldap_get_values_len(ldap, entry, attr);
+
+ if (values)
+ {
+ if (values[0])
+ {
+ *response = chunk_alloc(values[0]->bv_len);
+ memcpy(response->ptr, values[0]->bv_val, response->len);
+ success = TRUE;
+ }
+ else
+ {
+ DBG1("LDAP response contains no values");
+ }
+ ldap_value_free_len(values);
+ }
+ else
+ {
+ DBG1("getting LDAP values failed: %s",
+ ldap_err2string(ldap_result2error(ldap, entry, 0)));
+ }
+ ldap_memfree(attr);
+ }
+ else
+ {
+ DBG1("finding LDAP attributes failed: %s",
+ ldap_err2string(ldap_result2error(ldap, entry, 0)));
+ }
+ ber_free(ber, 0);
+ }
+ else
+ {
+ DBG1("finding first LDAP entry failed: %s",
+ ldap_err2string(ldap_result2error(ldap, entry, 0)));
+ }
+ return success;
+}
+
+
+static status_t fetch(private_ldap_fetcher_t *this, char *url,
+ chunk_t *result, va_list args)
+{
+ LDAP *ldap;
+ LDAPURLDesc *lurl;
+ LDAPMessage *msg;
+ int res;
+ int ldap_version = LDAP_VERSION3;
+ struct timeval timeout;
+ status_t status = FAILED;
+
+ if (!strneq(url, "ldap", 4))
+ {
+ return NOT_SUPPORTED;
+ }
+ if (ldap_url_parse(url, &lurl) != LDAP_SUCCESS)
+ {
+ return NOT_SUPPORTED;
+ }
+ ldap = ldap_init(lurl->lud_host, lurl->lud_port);
+ if (ldap == NULL)
+ {
+ DBG1("LDAP initialization failed: %s", strerror(errno));
+ ldap_free_urldesc(lurl);
+ return FAILED;
+ }
+
+ timeout.tv_sec = this->timeout;
+ timeout.tv_usec = 0;
+
+ ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
+ ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
+
+ DBG2("sending LDAP request to '%s'...", url);
+
+ res = ldap_simple_bind_s(ldap, NULL, NULL);
+ if (res == LDAP_SUCCESS)
+ {
+ res = ldap_search_st(ldap, lurl->lud_dn, lurl->lud_scope,
+ lurl->lud_filter, lurl->lud_attrs,
+ 0, &timeout, &msg);
+
+ if (res == LDAP_SUCCESS)
+ {
+ if (parse(ldap, msg, result))
+ {
+ status = SUCCESS;
+ }
+ ldap_msgfree(msg);
+ }
+ else
+ {
+ DBG1("LDAP search failed: %s", ldap_err2string(res));
+ }
+ }
+ else
+ {
+ DBG1("LDAP bind to '%s' failed: %s", url, ldap_err2string(res));
+ }
+ ldap_unbind_s(ldap);
+ ldap_free_urldesc(lurl);
+ return status;
+}
+
+
+/**
+ * Implementation of fetcher_t.set_option.
+ */
+static bool set_option(private_ldap_fetcher_t *this, fetcher_option_t option, ...)
+{
+ va_list args;
+
+ va_start(args, option);
+ switch (option)
+ {
+ case FETCH_TIMEOUT:
+ {
+ this->timeout = va_arg(args, u_int);
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ * Implements ldap_fetcher_t.destroy
+ */
+static void destroy(private_ldap_fetcher_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+ldap_fetcher_t *ldap_fetcher_create()
+{
+ private_ldap_fetcher_t *this = malloc_thing(private_ldap_fetcher_t);
+
+ this->public.interface.fetch = (status_t(*)(fetcher_t*,char*,chunk_t*))fetch;
+ this->public.interface.set_option = (bool(*)(fetcher_t*, fetcher_option_t option, ...))set_option;
+ this->public.interface.destroy = (void (*)(fetcher_t*))destroy;
+
+ this->timeout = DEFAULT_TIMEOUT;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/ldap/ldap_fetcher.h b/src/libstrongswan/plugins/ldap/ldap_fetcher.h
new file mode 100644
index 000000000..bde60c799
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/ldap_fetcher.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup ldap_fetcher ldap_fetcher
+ * @{ @ingroup ldap_p
+ */
+
+#ifndef LDAP_FETCHER_H_
+#define LDAP_FETCHER_H_
+
+typedef struct ldap_fetcher_t ldap_fetcher_t;
+
+/**
+ * Fetcher implementation using OpenLDAP.
+ */
+struct ldap_fetcher_t {
+
+ /**
+ * Implements fetcher interface
+ */
+ fetcher_t interface;
+};
+
+/**
+ * Create a ldap_fetcher instance.
+ */
+ldap_fetcher_t *ldap_fetcher_create();
+
+#endif /* LDAP_FETCHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/ldap/ldap_plugin.c b/src/libstrongswan/plugins/ldap/ldap_plugin.c
new file mode 100644
index 000000000..0925cb395
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/ldap_plugin.c
@@ -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: ldap_plugin.c 3529 2008-03-05 15:26:24Z martin $
+ */
+
+#include "ldap_plugin.h"
+
+#include <library.h>
+#include "ldap_fetcher.h"
+
+typedef struct private_ldap_plugin_t private_ldap_plugin_t;
+
+/**
+ * private data of ldap_plugin
+ */
+struct private_ldap_plugin_t {
+
+ /**
+ * public functions
+ */
+ ldap_plugin_t public;
+};
+
+/**
+ * Implementation of ldap_plugin_t.destroy
+ */
+static void destroy(private_ldap_plugin_t *this)
+{
+ lib->fetcher->remove_fetcher(lib->fetcher,
+ (fetcher_constructor_t)ldap_fetcher_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_ldap_plugin_t *this = malloc_thing(private_ldap_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)ldap_fetcher_create, "ldap://");
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)ldap_fetcher_create, "ldaps://");
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/ldap/ldap_plugin.h b/src/libstrongswan/plugins/ldap/ldap_plugin.h
new file mode 100644
index 000000000..7b2bb3232
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/ldap_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup ldap_p ldap
+ * @ingroup plugins
+ *
+ * @defgroup ldap_plugin ldap_plugin
+ * @{ @ingroup ldap_p
+ */
+
+#ifndef LDAP_PLUGIN_H_
+#define LDAP_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct ldap_plugin_t ldap_plugin_t;
+
+/**
+ * Plugin implementing LDAP fetcher using OpenLDAP.
+ */
+struct ldap_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a ldap_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* LDAP_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/md5/Makefile.am b/src/libstrongswan/plugins/md5/Makefile.am
new file mode 100644
index 000000000..0a9c5cbf4
--- /dev/null
+++ b/src/libstrongswan/plugins/md5/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-md5.la
+
+libstrongswan_md5_la_SOURCES = md5_plugin.h md5_plugin.c md5_hasher.c md5_hasher.h
+libstrongswan_md5_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in
new file mode 100644
index 000000000..6a4b2a78b
--- /dev/null
+++ b/src/libstrongswan/plugins/md5/Makefile.in
@@ -0,0 +1,494 @@
+# 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/libstrongswan/plugins/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_md5_la_LIBADD =
+am_libstrongswan_md5_la_OBJECTS = md5_plugin.lo md5_hasher.lo
+libstrongswan_md5_la_OBJECTS = $(am_libstrongswan_md5_la_OBJECTS)
+libstrongswan_md5_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_md5_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_md5_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_md5_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-md5.la
+libstrongswan_md5_la_SOURCES = md5_plugin.h md5_plugin.c md5_hasher.c md5_hasher.h
+libstrongswan_md5_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/libstrongswan/plugins/md5/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/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-md5.la: $(libstrongswan_md5_la_OBJECTS) $(libstrongswan_md5_la_DEPENDENCIES)
+ $(libstrongswan_md5_la_LINK) -rpath $(plugindir) $(libstrongswan_md5_la_OBJECTS) $(libstrongswan_md5_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/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/libstrongswan/crypto/hashers/md5_hasher.c b/src/libstrongswan/plugins/md5/md5_hasher.c
index d4dde3693..2354139bb 100644
--- a/src/libstrongswan/crypto/hashers/md5_hasher.c
+++ b/src/libstrongswan/plugins/md5/md5_hasher.c
@@ -1,10 +1,3 @@
-/**
- * @file md5_hasher.c
- *
- * @brief Implementation of md5_hasher_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -24,6 +17,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: md5_hasher.c 3488 2008-02-21 15:10:02Z martin $
*/
#include <string.h>
@@ -364,19 +359,6 @@ static void reset(private_md5_hasher_t *this)
}
/**
- * Implementation of hasher_t.get_state
- */
-static chunk_t get_state(private_md5_hasher_t *this)
-{
- chunk_t chunk;
-
- chunk.ptr = (u_char*)&this->state[0];
- chunk.len = sizeof(this->state);
-
- return chunk;
-}
-
-/**
* Implementation of hasher_t.destroy.
*/
static void destroy(private_md5_hasher_t *this)
@@ -387,15 +369,20 @@ static void destroy(private_md5_hasher_t *this)
/*
* Described in header.
*/
-md5_hasher_t *md5_hasher_create(void)
+md5_hasher_t *md5_hasher_create(hash_algorithm_t algo)
{
- private_md5_hasher_t *this = malloc_thing(private_md5_hasher_t);
-
+ private_md5_hasher_t *this;
+
+ if (algo != HASH_MD5)
+ {
+ return NULL;
+ }
+ this = malloc_thing(private_md5_hasher_t);
+
this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
- this->public.hasher_interface.get_state = (chunk_t (*) (hasher_t*))get_state;
this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
/* initialize */
diff --git a/src/libstrongswan/crypto/hashers/md5_hasher.h b/src/libstrongswan/plugins/md5/md5_hasher.h
index 715f11663..d4a0417ab 100644
--- a/src/libstrongswan/crypto/hashers/md5_hasher.h
+++ b/src/libstrongswan/plugins/md5/md5_hasher.h
@@ -1,12 +1,5 @@
-/**
- * @file md5_hasher.h
- *
- * @brief Interface for md5_hasher_t.
- *
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -21,6 +14,11 @@
* for more details.
*/
+/**
+ * @defgroup md5_hasher md5_hasher
+ * @{ @ingroup md5_p
+ */
+
#ifndef MD5_HASHER_H_
#define MD5_HASHER_H_
@@ -29,16 +27,7 @@ typedef struct md5_hasher_t md5_hasher_t;
#include <crypto/hashers/hasher.h>
/**
- * @brief Implementation of hasher_t interface using the
- * MD5 algorithm.
- *
- * @b Constructors:
- * - hasher_create() using HASH_MD5 as algorithm
- * - md5_hasher_create()
- *
- * @see hasher_t
- *
- * @ingroup hashers
+ * Implementation of hasher_t interface using the MD5 algorithm.
*/
struct md5_hasher_t {
@@ -49,12 +38,11 @@ struct md5_hasher_t {
};
/**
- * @brief Creates a new md5_hasher_t.
- *
- * @return md5_hasher_t object
+ * Creates a new md5_hasher_t.
*
- * @ingroup hashers
+ * @param algo hash algorithm, must be HASH_MD5
+ * @return md5_hasher_t object, NULL if not supported
*/
-md5_hasher_t *md5_hasher_create(void);
+md5_hasher_t *md5_hasher_create(hash_algorithm_t algo);
-#endif /*MD5_HASHER_H_*/
+#endif /*MD5_HASHER_H_@}*/
diff --git a/src/libstrongswan/plugins/md5/md5_plugin.c b/src/libstrongswan/plugins/md5/md5_plugin.c
new file mode 100644
index 000000000..c1c9a0805
--- /dev/null
+++ b/src/libstrongswan/plugins/md5/md5_plugin.c
@@ -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: md5_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "md5_plugin.h"
+
+#include <library.h>
+#include "md5_hasher.h"
+
+typedef struct private_md5_plugin_t private_md5_plugin_t;
+
+/**
+ * private data of md5_plugin
+ */
+struct private_md5_plugin_t {
+
+ /**
+ * public functions
+ */
+ md5_plugin_t public;
+};
+
+/**
+ * Implementation of md5_plugin_t.destroy
+ */
+static void destroy(private_md5_plugin_t *this)
+{
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)md5_hasher_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_md5_plugin_t *this = malloc_thing(private_md5_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_hasher(lib->crypto, HASH_MD5,
+ (hasher_constructor_t)md5_hasher_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/md5/md5_plugin.h b/src/libstrongswan/plugins/md5/md5_plugin.h
new file mode 100644
index 000000000..e8e8dd535
--- /dev/null
+++ b/src/libstrongswan/plugins/md5/md5_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup md5_p md5
+ * @ingroup plugins
+ *
+ * @defgroup md5_plugin md5_plugin
+ * @{ @ingroup md5_p
+ */
+
+#ifndef MD5_PLUGIN_H_
+#define MD5_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct md5_plugin_t md5_plugin_t;
+
+/**
+ * Plugin implementing the MD5 hash algorithm in software.
+ */
+struct md5_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a md5_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* MD5_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/mysql/Makefile.am b/src/libstrongswan/plugins/mysql/Makefile.am
new file mode 100644
index 000000000..ec94b8fda
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/Makefile.am
@@ -0,0 +1,12 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-mysql.la
+
+libstrongswan_mysql_la_SOURCES = mysql_plugin.h mysql_plugin.c \
+ mysql_database.h mysql_database.c
+libstrongswan_mysql_la_LDFLAGS = -module
+libstrongswan_mysql_la_LIBADD = -lmysqlclient_r
+
diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in
new file mode 100644
index 000000000..6de9dc13d
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/Makefile.in
@@ -0,0 +1,497 @@
+# 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/libstrongswan/plugins/mysql
+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_mysql_la_DEPENDENCIES =
+am_libstrongswan_mysql_la_OBJECTS = mysql_plugin.lo mysql_database.lo
+libstrongswan_mysql_la_OBJECTS = $(am_libstrongswan_mysql_la_OBJECTS)
+libstrongswan_mysql_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_mysql_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_mysql_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_mysql_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-mysql.la
+libstrongswan_mysql_la_SOURCES = mysql_plugin.h mysql_plugin.c \
+ mysql_database.h mysql_database.c
+
+libstrongswan_mysql_la_LDFLAGS = -module
+libstrongswan_mysql_la_LIBADD = -lmysqlclient_r
+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/libstrongswan/plugins/mysql/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/mysql/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-mysql.la: $(libstrongswan_mysql_la_OBJECTS) $(libstrongswan_mysql_la_DEPENDENCIES)
+ $(libstrongswan_mysql_la_LINK) -rpath $(plugindir) $(libstrongswan_mysql_la_OBJECTS) $(libstrongswan_mysql_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mysql_database.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mysql_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/libstrongswan/plugins/mysql/mysql_database.c b/src/libstrongswan/plugins/mysql/mysql_database.c
new file mode 100644
index 000000000..58202c5ae
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/mysql_database.c
@@ -0,0 +1,695 @@
+/*
+ * 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: mysql_database.c 4111 2008-06-26 07:31:52Z martin $
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <pthread.h>
+#include <mysql/mysql.h>
+
+#include "mysql_database.h"
+
+#include <debug.h>
+#include <utils/mutex.h>
+#include <utils/linked_list.h>
+
+/* Older mysql.h headers do not define it, but we need it. It is not returned
+ * in in MySQL 4 by default, but by MySQL 5. To avoid this problem, we catch
+ * it in all cases. */
+#ifndef MYSQL_DATA_TRUNCATED
+#define MYSQL_DATA_TRUNCATED 101
+#endif
+
+typedef struct private_mysql_database_t private_mysql_database_t;
+
+/**
+ * private data of mysql_database
+ */
+struct private_mysql_database_t {
+
+ /**
+ * public functions
+ */
+ mysql_database_t public;
+
+ /**
+ * connection pool, contains conn_t
+ */
+ linked_list_t *pool;
+
+ /**
+ * mutex to lock pool
+ */
+ mutex_t *mutex;
+
+ /**
+ * hostname to connect to
+ */
+ char *host;
+
+ /**
+ * username to use
+ */
+ char *username;
+
+ /**
+ * password
+ */
+ char *password;
+
+ /**
+ * database name
+ */
+ char *database;
+
+ /**
+ * tcp port
+ */
+ int port;
+};
+
+typedef struct conn_t conn_t;
+
+/**
+ * connection pool entry
+ */
+struct conn_t {
+
+ /**
+ * MySQL database connection
+ */
+ MYSQL *mysql;
+
+ /**
+ * connection in use?
+ */
+ bool in_use;
+};
+
+/**
+ * Release a mysql connection
+ */
+static void conn_release(conn_t *conn)
+{
+ conn->in_use = FALSE;
+}
+/**
+ * thread specific initialization flag
+ */
+pthread_key_t initialized;
+
+/**
+ * Initialize a thread for mysql usage
+ */
+static void thread_initialize()
+{
+ if (pthread_getspecific(initialized) == NULL)
+ {
+ pthread_setspecific(initialized, (void*)TRUE);
+ mysql_thread_init();
+ }
+}
+
+/**
+ * mysql library initialization function
+ */
+bool mysql_database_init()
+{
+ if (mysql_library_init(0, NULL, NULL))
+ {
+ return FALSE;
+ }
+ if (pthread_key_create(&initialized, (void*)mysql_thread_end))
+ {
+ mysql_library_end();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * mysql library cleanup function
+ */
+void mysql_database_deinit()
+{
+ pthread_key_delete(initialized);
+ mysql_thread_end();
+ /* mysql_library_end(); would be the clean way, however, it hangs... */
+}
+
+/**
+ * Destroy a mysql connection
+ */
+static void conn_destroy(conn_t *this)
+{
+ mysql_close(this->mysql);
+ free(this);
+}
+
+/**
+ * Acquire/Reuse a mysql connection
+ */
+static conn_t *conn_get(private_mysql_database_t *this)
+{
+ conn_t *current, *found = NULL;
+ enumerator_t *enumerator;
+
+ thread_initialize();
+
+ while (TRUE)
+ {
+ this->mutex->lock(this->mutex);
+ enumerator = this->pool->create_enumerator(this->pool);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (!current->in_use)
+ {
+ found = current;
+ found->in_use = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ if (found)
+ { /* check connection if found, release if ping fails */
+ if (mysql_ping(found->mysql) == 0)
+ {
+ break;
+ }
+ this->mutex->lock(this->mutex);
+ this->pool->remove(this->pool, found, NULL);
+ this->mutex->unlock(this->mutex);
+ conn_destroy(found);
+ found = NULL;
+ continue;
+ }
+ break;
+ }
+ if (found == NULL)
+ {
+ found = malloc_thing(conn_t);
+ found->in_use = TRUE;
+ found->mysql = mysql_init(NULL);
+ if (!mysql_real_connect(found->mysql, this->host, this->username,
+ this->password, this->database, this->port,
+ NULL, 0))
+ {
+ DBG1("connecting to mysql://%s:***@%s:%d/%s failed: %s",
+ this->username, this->host, this->port, this->database,
+ mysql_error(found->mysql));
+ conn_destroy(found);
+ found = NULL;
+ }
+ else
+ {
+ this->mutex->lock(this->mutex);
+ this->pool->insert_last(this->pool, found);
+ DBG2("increased MySQL connection pool size to %d",
+ this->pool->get_count(this->pool));
+ this->mutex->unlock(this->mutex);
+ }
+ }
+ return found;
+}
+
+/**
+ * Create and run a MySQL stmt using a sql string and args
+ */
+static MYSQL_STMT* run(MYSQL *mysql, char *sql, va_list *args)
+{
+ MYSQL_STMT *stmt;
+ int params;
+
+ stmt = mysql_stmt_init(mysql);
+ if (stmt == NULL)
+ {
+ DBG1("creating MySQL statement failed: %s", mysql_error(mysql));
+ return NULL;
+ }
+ if (mysql_stmt_prepare(stmt, sql, strlen(sql)))
+ {
+ DBG1("preparing MySQL statement failed: %s", mysql_stmt_error(stmt));
+ mysql_stmt_close(stmt);
+ return NULL;
+ }
+ params = mysql_stmt_param_count(stmt);
+ if (params > 0)
+ {
+ int i;
+ MYSQL_BIND *bind;
+
+ bind = alloca(sizeof(MYSQL_BIND) * params);
+ memset(bind, 0, sizeof(MYSQL_BIND) * params);
+
+ for (i = 0; i < params; i++)
+ {
+ switch (va_arg(*args, db_type_t))
+ {
+ case DB_INT:
+ {
+ bind[i].buffer_type = MYSQL_TYPE_LONG;
+ bind[i].buffer = (char*)alloca(sizeof(int));
+ *(int*)bind[i].buffer = va_arg(*args, int);
+ bind[i].buffer_length = sizeof(int);
+ break;
+ }
+ case DB_UINT:
+ {
+ bind[i].buffer_type = MYSQL_TYPE_LONG;
+ bind[i].buffer = (char*)alloca(sizeof(u_int));
+ *(u_int*)bind[i].buffer = va_arg(*args, u_int);
+ bind[i].buffer_length = sizeof(u_int);
+ bind[i].is_unsigned = TRUE;
+ break;
+ }
+ case DB_TEXT:
+ {
+ bind[i].buffer_type = MYSQL_TYPE_STRING;;
+ bind[i].buffer = va_arg(*args, char*);
+ if (bind[i].buffer)
+ {
+ bind[i].buffer_length = strlen(bind[i].buffer);
+ }
+ break;
+ }
+ case DB_BLOB:
+ {
+ chunk_t chunk = va_arg(*args, chunk_t);
+ bind[i].buffer_type = MYSQL_TYPE_BLOB;
+ bind[i].buffer = chunk.ptr;
+ bind[i].buffer_length = chunk.len;
+ break;
+ }
+ case DB_DOUBLE:
+ {
+ bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
+ bind[i].buffer = (char*)alloca(sizeof(double));
+ *(double*)bind[i].buffer = va_arg(*args, double);
+ bind[i].buffer_length = sizeof(double);
+ break;
+ }
+ case DB_NULL:
+ {
+ bind[i].buffer_type = MYSQL_TYPE_NULL;
+ break;
+ }
+ default:
+ DBG1("invalid data type supplied");
+ mysql_stmt_close(stmt);
+ return NULL;
+ }
+ }
+ if (mysql_stmt_bind_param(stmt, bind))
+ {
+ DBG1("binding MySQL param failed: %s", mysql_stmt_error(stmt));
+ mysql_stmt_close(stmt);
+ return NULL;
+ }
+ }
+ if (mysql_stmt_execute(stmt))
+ {
+ DBG1("executing MySQL statement failed: %s", mysql_stmt_error(stmt));
+ mysql_stmt_close(stmt);
+ return NULL;
+ }
+ return stmt;
+}
+
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** associated MySQL statement */
+ MYSQL_STMT *stmt;
+ /** result bindings */
+ MYSQL_BIND *bind;
+ /** pooled connection handle */
+ conn_t *conn;
+ /** value for INT, UINT, double */
+ union {
+ void *p_void;;
+ int *p_int;
+ u_int *p_uint;
+ double *p_double;
+ } val;
+ /* length for TEXT and BLOB */
+ unsigned long *length;
+} mysql_enumerator_t;
+
+/**
+ * create a mysql enumerator
+ */
+static void mysql_enumerator_destroy(mysql_enumerator_t *this)
+{
+ int columns, i;
+
+ columns = mysql_stmt_field_count(this->stmt);
+
+ for (i = 0; i < columns; i++)
+ {
+ switch (this->bind[i].buffer_type)
+ {
+ case MYSQL_TYPE_STRING:
+ case MYSQL_TYPE_BLOB:
+ {
+ free(this->bind[i].buffer);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ mysql_stmt_close(this->stmt);
+ conn_release(this->conn);
+ free(this->bind);
+ free(this->val.p_void);
+ free(this->length);
+ free(this);
+}
+
+/**
+ * Implementation of database.query().enumerate
+ */
+static bool mysql_enumerator_enumerate(mysql_enumerator_t *this, ...)
+{
+ int i, columns;
+ va_list args;
+
+ columns = mysql_stmt_field_count(this->stmt);
+
+ /* free/reset data set of previous call */
+ for (i = 0; i < columns; i++)
+ {
+ switch (this->bind[i].buffer_type)
+ {
+ case MYSQL_TYPE_STRING:
+ case MYSQL_TYPE_BLOB:
+ {
+ free(this->bind[i].buffer);
+ this->bind[i].buffer = NULL;
+ this->bind[i].buffer_length = 0;
+ this->bind[i].length = &this->length[i];
+ this->length[i] = 0;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ switch (mysql_stmt_fetch(this->stmt))
+ {
+ case 0:
+ case MYSQL_DATA_TRUNCATED:
+ break;
+ case MYSQL_NO_DATA:
+ return FALSE;
+ default:
+ DBG1("fetching MySQL row failed: %s", mysql_stmt_error(this->stmt));
+ return FALSE;
+ }
+
+ va_start(args, this);
+ for (i = 0; i < columns; i++)
+ {
+ switch (this->bind[i].buffer_type)
+ {
+ case MYSQL_TYPE_LONG:
+ {
+ if (this->bind[i].is_unsigned)
+ {
+ u_int *value = va_arg(args, u_int*);
+ *value = this->val.p_uint[i];
+ }
+ else
+ {
+ int *value = va_arg(args, int*);
+ *value = this->val.p_int[i];
+ }
+ break;
+ }
+ case MYSQL_TYPE_STRING:
+ {
+ char **value = va_arg(args, char**);
+ this->bind[i].buffer = malloc(this->length[i]+1);
+ this->bind[i].buffer_length = this->length[i];
+ *value = this->bind[i].buffer;
+ mysql_stmt_fetch_column(this->stmt, &this->bind[i], i, 0);
+ ((char*)this->bind[i].buffer)[this->length[i]] = '\0';
+ break;
+ }
+ case MYSQL_TYPE_BLOB:
+ {
+ chunk_t *value = va_arg(args, chunk_t*);
+ this->bind[i].buffer = malloc(this->length[i]);
+ this->bind[i].buffer_length = this->length[i];
+ value->ptr = this->bind[i].buffer;
+ value->len = this->length[i];
+ mysql_stmt_fetch_column(this->stmt, &this->bind[i], i, 0);
+ break;
+ }
+ case MYSQL_TYPE_DOUBLE:
+ {
+ double *value = va_arg(args, double*);
+ *value = this->val.p_double[i];
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Implementation of database_t.query.
+ */
+static enumerator_t* query(private_mysql_database_t *this, char *sql, ...)
+{
+ MYSQL_STMT *stmt;
+ va_list args;
+ mysql_enumerator_t *enumerator = NULL;
+ conn_t *conn;
+
+ conn = conn_get(this);
+ if (!conn)
+ {
+ return NULL;
+ }
+
+ va_start(args, sql);
+ stmt = run(conn->mysql, sql, &args);
+ if (stmt)
+ {
+ int columns, i;
+
+ enumerator = malloc_thing(mysql_enumerator_t);
+ enumerator->public.enumerate = (void*)mysql_enumerator_enumerate;
+ enumerator->public.destroy = (void*)mysql_enumerator_destroy;
+ enumerator->stmt = stmt;
+ enumerator->conn = conn;
+ columns = mysql_stmt_field_count(stmt);
+ enumerator->bind = calloc(columns, sizeof(MYSQL_BIND));
+ enumerator->length = calloc(columns, sizeof(unsigned long));
+ enumerator->val.p_void = calloc(columns, sizeof(enumerator->val));
+ for (i = 0; i < columns; i++)
+ {
+ switch (va_arg(args, db_type_t))
+ {
+ case DB_INT:
+ {
+ enumerator->bind[i].buffer_type = MYSQL_TYPE_LONG;
+ enumerator->bind[i].buffer = (char*)&enumerator->val.p_int[i];
+ break;
+ }
+ case DB_UINT:
+ {
+ enumerator->bind[i].buffer_type = MYSQL_TYPE_LONG;
+ enumerator->bind[i].buffer = (char*)&enumerator->val.p_uint[i];
+ enumerator->bind[i].is_unsigned = TRUE;
+ break;
+ }
+ case DB_TEXT:
+ {
+ enumerator->bind[i].buffer_type = MYSQL_TYPE_STRING;
+ enumerator->bind[i].length = &enumerator->length[i];
+ break;
+ }
+ case DB_BLOB:
+ {
+ enumerator->bind[i].buffer_type = MYSQL_TYPE_BLOB;
+ enumerator->bind[i].length = &enumerator->length[i];
+ break;
+ }
+ case DB_DOUBLE:
+ {
+ enumerator->bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
+ enumerator->bind[i].buffer = (char*)&enumerator->val.p_double[i];
+ break;
+ }
+ default:
+ DBG1("invalid result data type supplied");
+ mysql_enumerator_destroy(enumerator);
+ va_end(args);
+ return NULL;
+ }
+ }
+ if (mysql_stmt_bind_result(stmt, enumerator->bind))
+ {
+ DBG1("binding MySQL result failed: %s", mysql_stmt_error(stmt));
+ mysql_enumerator_destroy(enumerator);
+ enumerator = NULL;
+ }
+ }
+ else
+ {
+ conn_release(conn);
+ }
+ va_end(args);
+ return (enumerator_t*)enumerator;
+}
+
+/**
+ * Implementation of database_t.execute.
+ */
+static int execute(private_mysql_database_t *this, int *rowid, char *sql, ...)
+{
+ MYSQL_STMT *stmt;
+ va_list args;
+ conn_t *conn;
+ int affected = -1;
+
+ conn = conn_get(this);
+ if (!conn)
+ {
+ return -1;
+ }
+ va_start(args, sql);
+ stmt = run(conn->mysql, sql, &args);
+ if (stmt)
+ {
+ if (rowid)
+ {
+ *rowid = mysql_stmt_insert_id(stmt);
+ }
+ affected = mysql_stmt_affected_rows(stmt);
+ mysql_stmt_close(stmt);
+ }
+ va_end(args);
+ conn_release(conn);
+ return affected;
+}
+
+/**
+ * Implementation of database_t.destroy
+ */
+static void destroy(private_mysql_database_t *this)
+{
+ this->pool->destroy_function(this->pool, (void*)conn_destroy);
+ this->mutex->destroy(this->mutex);
+ free(this->host);
+ free(this->username);
+ free(this->password);
+ free(this->database);
+ free(this);
+}
+
+static bool parse_uri(private_mysql_database_t *this, char *uri)
+{
+ char *username, *password, *host, *port = "0", *database, *pos;
+
+ /**
+ * parse mysql://username:pass@host:port/database uri
+ */
+ username = strdupa(uri + 8);
+ pos = strchr(username, ':');
+ if (pos)
+ {
+ *pos = '\0';
+ password = pos + 1;
+ pos = strrchr(password, '@');
+ if (pos)
+ {
+ *pos = '\0';
+ host = pos + 1;
+ pos = strrchr(host, ':');
+ if (pos)
+ {
+ *pos = '\0';
+ port = pos + 1;
+ pos = strchr(port, '/');
+ }
+ else
+ {
+ pos = strchr(host, '/');
+ }
+ if (pos)
+ {
+ *pos = '\0';
+ database = pos + 1;
+
+ this->host = strdup(host);
+ this->username = strdup(username);
+ this->password = strdup(password);
+ this->database = strdup(database);
+ this->port = atoi(port);
+ return TRUE;
+ }
+ }
+ }
+ DBG1("parsing MySQL database uri '%s' failed", uri);
+ return FALSE;
+}
+
+
+/*
+ * see header file
+ */
+mysql_database_t *mysql_database_create(char *uri)
+{
+ conn_t *conn;
+ private_mysql_database_t *this;
+
+ if (!strneq(uri, "mysql://", 8))
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_mysql_database_t);
+
+ this->public.db.query = (enumerator_t* (*)(database_t *this, char *sql, ...))query;
+ this->public.db.execute = (int (*)(database_t *this, int *rowid, char *sql, ...))execute;
+ this->public.db.destroy = (void(*)(database_t*))destroy;
+
+ if (!parse_uri(this, uri))
+ {
+ free(this);
+ return NULL;
+ }
+ this->mutex = mutex_create(MUTEX_DEFAULT);
+ this->pool = linked_list_create();
+
+ /* check connectivity */
+ conn = conn_get(this);
+ if (!conn)
+ {
+ destroy(this);
+ return NULL;
+ }
+ conn_release(conn);
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/mysql/mysql_database.h b/src/libstrongswan/plugins/mysql/mysql_database.h
new file mode 100644
index 000000000..d04aa79fa
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/mysql_database.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup mysql_database mysql_database
+ * @{ @ingroup mysql_p
+ */
+
+#ifndef MYSQL_DATABASE_H_
+#define MYSQL_DATABASE_H_
+
+#include <database/database.h>
+
+typedef struct mysql_database_t mysql_database_t;
+
+/**
+ * MySQL databse_t implementation.
+ */
+struct mysql_database_t {
+
+ /**
+ * Implements database_t
+ */
+ database_t db;
+};
+
+/**
+ * Create a mysql_database instance.
+ *
+ * @param uri connection URI, mysql://user:pass@host:port/database
+ */
+mysql_database_t *mysql_database_create(char *uri);
+
+/**
+ * MySQL client library initialization function
+ *
+ * @return FALSE if initialization failed
+ */
+bool mysql_database_init();
+
+/**
+ * Mysql client library cleanup function
+ */
+void mysql_database_deinit();
+
+#endif /* MYSQL_DATABASE_H_ @}*/
diff --git a/src/libstrongswan/plugins/mysql/mysql_plugin.c b/src/libstrongswan/plugins/mysql/mysql_plugin.c
new file mode 100644
index 000000000..29348ac14
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/mysql_plugin.c
@@ -0,0 +1,69 @@
+/*
+ * 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: mysql_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "mysql_plugin.h"
+
+#include <library.h>
+#include <debug.h>
+#include "mysql_database.h"
+
+typedef struct private_mysql_plugin_t private_mysql_plugin_t;
+
+/**
+ * private data of mysql_plugin
+ */
+struct private_mysql_plugin_t {
+
+ /**
+ * public functions
+ */
+ mysql_plugin_t public;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_mysql_plugin_t *this)
+{
+ lib->db->remove_database(lib->db,
+ (database_constructor_t)mysql_database_create);
+ mysql_database_deinit();
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_mysql_plugin_t *this;
+
+ if (!mysql_database_init())
+ {
+ DBG1("MySQL client library initialization failed");
+ return NULL;
+ }
+
+ this = malloc_thing(private_mysql_plugin_t);
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->db->add_database(lib->db,
+ (database_constructor_t)mysql_database_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/mysql/mysql_plugin.h b/src/libstrongswan/plugins/mysql/mysql_plugin.h
new file mode 100644
index 000000000..dbcabaafe
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/mysql_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup mysql_p mysql
+ * @ingroup plugins
+ *
+ * @defgroup mysql_plugin mysql_plugin
+ * @{ @ingroup mysql_p
+ */
+
+#ifndef MYSQL_PLUGIN_H_
+#define MYSQL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct mysql_plugin_t mysql_plugin_t;
+
+/**
+ * Plugin implementing mysql database connectivity.
+ */
+struct mysql_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a mysql_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* MYSQL_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/Makefile.am b/src/libstrongswan/plugins/openssl/Makefile.am
new file mode 100644
index 000000000..f331a78eb
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/Makefile.am
@@ -0,0 +1,21 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-openssl.la
+
+libstrongswan_openssl_la_SOURCES = openssl_plugin.h openssl_plugin.c \
+ openssl_util.c openssl_util.h \
+ openssl_crypter.c openssl_crypter.h \
+ openssl_hasher.c openssl_hasher.h \
+ openssl_diffie_hellman.c openssl_diffie_hellman.h \
+ openssl_rsa_private_key.c openssl_rsa_private_key.h \
+ openssl_rsa_public_key.c openssl_rsa_public_key.h \
+ openssl_ec_diffie_hellman.c openssl_ec_diffie_hellman.h \
+ openssl_ec_private_key.c openssl_ec_private_key.h \
+ openssl_ec_public_key.c openssl_ec_public_key.h
+
+libstrongswan_openssl_la_LDFLAGS = -module
+libstrongswan_openssl_la_LIBADD = -lcrypto
+
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
new file mode 100644
index 000000000..f83b0ce38
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/Makefile.in
@@ -0,0 +1,518 @@
+# 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/libstrongswan/plugins/openssl
+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_openssl_la_DEPENDENCIES =
+am_libstrongswan_openssl_la_OBJECTS = openssl_plugin.lo \
+ openssl_util.lo openssl_crypter.lo openssl_hasher.lo \
+ openssl_diffie_hellman.lo openssl_rsa_private_key.lo \
+ openssl_rsa_public_key.lo openssl_ec_diffie_hellman.lo \
+ openssl_ec_private_key.lo openssl_ec_public_key.lo
+libstrongswan_openssl_la_OBJECTS = \
+ $(am_libstrongswan_openssl_la_OBJECTS)
+libstrongswan_openssl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_openssl_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_openssl_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_openssl_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-openssl.la
+libstrongswan_openssl_la_SOURCES = openssl_plugin.h openssl_plugin.c \
+ openssl_util.c openssl_util.h \
+ openssl_crypter.c openssl_crypter.h \
+ openssl_hasher.c openssl_hasher.h \
+ openssl_diffie_hellman.c openssl_diffie_hellman.h \
+ openssl_rsa_private_key.c openssl_rsa_private_key.h \
+ openssl_rsa_public_key.c openssl_rsa_public_key.h \
+ openssl_ec_diffie_hellman.c openssl_ec_diffie_hellman.h \
+ openssl_ec_private_key.c openssl_ec_private_key.h \
+ openssl_ec_public_key.c openssl_ec_public_key.h
+
+libstrongswan_openssl_la_LDFLAGS = -module
+libstrongswan_openssl_la_LIBADD = -lcrypto
+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/libstrongswan/plugins/openssl/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/openssl/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-openssl.la: $(libstrongswan_openssl_la_OBJECTS) $(libstrongswan_openssl_la_DEPENDENCIES)
+ $(libstrongswan_openssl_la_LINK) -rpath $(plugindir) $(libstrongswan_openssl_la_OBJECTS) $(libstrongswan_openssl_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_diffie_hellman.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ec_diffie_hellman.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ec_private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ec_public_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_rsa_private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_rsa_public_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_util.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/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c
new file mode 100644
index 000000000..e59c4d615
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c
@@ -0,0 +1,258 @@
+/*
+ * 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: openssl_crypter.c 4020 2008-05-28 12:20:38Z andreas $
+ */
+
+#include "openssl_crypter.h"
+
+#include <openssl/evp.h>
+
+typedef struct private_openssl_crypter_t private_openssl_crypter_t;
+
+/**
+ * Private data of openssl_crypter_t
+ */
+struct private_openssl_crypter_t {
+
+ /**
+ * Public part of this class.
+ */
+ openssl_crypter_t public;
+
+ /*
+ * the key
+ */
+ chunk_t key;
+
+ /*
+ * the cipher to use
+ */
+ const EVP_CIPHER *cipher;
+};
+
+/**
+ * Mapping from the algorithms defined in IKEv2 to
+ * OpenSSL algorithm names and their key length
+ */
+typedef struct {
+ /**
+ * Identifier specified in IKEv2
+ */
+ int ikev2_id;
+
+ /**
+ * Name of the algorithm, as used in OpenSSL
+ */
+ char *name;
+
+ /**
+ * Minimum valid key length in bytes
+ */
+ size_t key_size_min;
+
+ /**
+ * Maximum valid key length in bytes
+ */
+ size_t key_size_max;
+} openssl_algorithm_t;
+
+#define END_OF_LIST -1
+
+/**
+ * Algorithms for encryption
+ */
+static openssl_algorithm_t encryption_algs[] = {
+/* {ENCR_DES_IV64, "***", 0, 0}, */
+ {ENCR_DES, "des", 8, 8}, /* 64 bits */
+ {ENCR_3DES, "des3", 24, 24}, /* 192 bits */
+ {ENCR_RC5, "rc5", 5, 255}, /* 40 to 2040 bits, RFC 2451 */
+ {ENCR_IDEA, "idea", 16, 16}, /* 128 bits, RFC 2451 */
+ {ENCR_CAST, "cast", 5, 16}, /* 40 to 128 bits, RFC 2451 */
+ {ENCR_BLOWFISH, "blowfish", 5, 56}, /* 40 to 448 bits, RFC 2451 */
+/* {ENCR_3IDEA, "***", 0, 0}, */
+/* {ENCR_DES_IV32, "***", 0, 0}, */
+/* {ENCR_NULL, "***", 0, 0}, */ /* handled separately */
+/* {ENCR_AES_CBC, "***", 0, 0}, */ /* handled separately */
+/* {ENCR_AES_CTR, "***", 0, 0}, */ /* disabled in evp.h */
+ {END_OF_LIST, NULL, 0, 0},
+};
+
+/**
+ * Look up an OpenSSL algorithm name and validate its key size
+ */
+static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
+ u_int16_t ikev2_algo, size_t *key_size)
+{
+ while (openssl_algo->ikev2_id != END_OF_LIST)
+ {
+ if (ikev2_algo == openssl_algo->ikev2_id)
+ {
+ /* set the key size if it is not set */
+ if (*key_size == 0 &&
+ (openssl_algo->key_size_min == openssl_algo->key_size_max))
+ {
+ *key_size = openssl_algo->key_size_min;
+ }
+
+ /* validate key size */
+ if (*key_size < openssl_algo->key_size_min ||
+ *key_size > openssl_algo->key_size_max)
+ {
+ return NULL;
+ }
+ return openssl_algo->name;
+ }
+ openssl_algo++;
+ }
+ return NULL;
+}
+
+static void crypt(private_openssl_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst, int enc)
+{
+ int len;
+ u_char *out;
+
+ out = data.ptr;
+ if (dst)
+ {
+ *dst = chunk_alloc(data.len);
+ out = dst->ptr;
+ }
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+ EVP_CipherInit_ex(&ctx, this->cipher, NULL, this->key.ptr, iv.ptr, enc);
+ EVP_CIPHER_CTX_set_padding(&ctx, 0); /* disable padding */
+ EVP_CipherUpdate(&ctx, out, &len, data.ptr, data.len);
+ EVP_CipherFinal_ex(&ctx, out, &len); /* since padding is disabled this does nothing */
+ EVP_CIPHER_CTX_cleanup(&ctx);
+}
+
+/**
+ * Implementation of crypter_t.decrypt.
+ */
+static void decrypt(private_openssl_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst)
+{
+ crypt(this, data, iv, dst, 0);
+}
+
+
+/**
+ * Implementation of crypter_t.encrypt.
+ */
+static void encrypt (private_openssl_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst)
+{
+ crypt(this, data, iv, dst, 1);
+}
+
+/**
+ * Implementation of crypter_t.get_block_size.
+ */
+static size_t get_block_size(private_openssl_crypter_t *this)
+{
+ return this->cipher->block_size;
+}
+
+/**
+ * Implementation of crypter_t.get_key_size.
+ */
+static size_t get_key_size(private_openssl_crypter_t *this)
+{
+ return this->key.len;
+}
+
+/**
+ * Implementation of crypter_t.set_key.
+ */
+static void set_key(private_openssl_crypter_t *this, chunk_t key)
+{
+ memcpy(this->key.ptr, key.ptr, min(key.len, this->key.len));
+}
+
+/**
+ * Implementation of crypter_t.destroy.
+ */
+static void destroy (private_openssl_crypter_t *this)
+{
+ free(this->key.ptr);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
+ size_t key_size)
+{
+ private_openssl_crypter_t *this;
+
+ this = malloc_thing(private_openssl_crypter_t);
+
+ switch (algo)
+ {
+ case ENCR_NULL:
+ this->cipher = EVP_enc_null();
+ break;
+ case ENCR_AES_CBC:
+ switch (key_size)
+ {
+ case 16: /* AES 128 */
+ this->cipher = EVP_get_cipherbyname("aes128");
+ break;
+ case 24: /* AES-192 */
+ this->cipher = EVP_get_cipherbyname("aes192");
+ break;
+ case 32: /* AES-256 */
+ this->cipher = EVP_get_cipherbyname("aes256");
+ break;
+ default:
+ free(this);
+ return NULL;
+ }
+ break;
+ default:
+ {
+ char* name = lookup_algorithm(encryption_algs, algo, &key_size);
+ if (!name)
+ {
+ /* algo unavailable or key_size invalid */
+ free(this);
+ return NULL;
+ }
+ this->cipher = EVP_get_cipherbyname(name);
+ break;
+ }
+ }
+
+ if (!this->cipher)
+ {
+ /* OpenSSL does not support the requested algo */
+ free(this);
+ return NULL;
+ }
+
+ this->key = chunk_alloc(key_size);
+
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
+ this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
+ this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
+ this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.h b/src/libstrongswan/plugins/openssl/openssl_crypter.h
new file mode 100644
index 000000000..f80d0dec6
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.h
@@ -0,0 +1,51 @@
+/*
+ * 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: openssl_crypter.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_crypter openssl_crypter
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_CRYPTER_H_
+#define OPENSSL_CRYPTER_H_
+
+typedef struct openssl_crypter_t openssl_crypter_t;
+
+#include <crypto/crypters/crypter.h>
+
+/**
+ * Implementation of crypters using OpenSSL.
+ */
+struct openssl_crypter_t {
+
+ /**
+ * The crypter_t interface.
+ */
+ crypter_t crypter_interface;
+};
+
+/**
+ * Constructor to create openssl_crypter_t.
+ *
+ * @param algo algorithm to implement
+ * @param key_size key size in bytes
+ * @return openssl_crypter_t, NULL if not supported
+ */
+openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
+ size_t key_size);
+
+#endif /* OPENSSL_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
new file mode 100644
index 000000000..95c079b0b
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
@@ -0,0 +1,242 @@
+/*
+ * 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: openssl_diffie_hellman.c 3896 2008-04-29 15:42:34Z tobias $
+ */
+
+#include <openssl/dh.h>
+
+#include "openssl_diffie_hellman.h"
+
+#include <debug.h>
+
+typedef struct modulus_entry_t modulus_entry_t;
+
+/**
+ * Entry of the modulus list.
+ */
+struct modulus_entry_t {
+ /**
+ * Group number as it is defined in file transform_substructure.h.
+ */
+ diffie_hellman_group_t group;
+
+ /**
+ * Pointer to the function to get the modulus.
+ */
+ BIGNUM *(*get_prime)(BIGNUM *bn);
+
+ /*
+ * Generator value.
+ */
+ u_int16_t generator;
+};
+
+/**
+ * All supported modulus values.
+ */
+static modulus_entry_t modulus_entries[] = {
+ {MODP_768_BIT, get_rfc2409_prime_768, 2},
+ {MODP_1024_BIT, get_rfc2409_prime_1024, 2},
+ {MODP_1536_BIT, get_rfc3526_prime_1536, 2},
+ {MODP_2048_BIT, get_rfc3526_prime_2048, 2},
+ {MODP_3072_BIT, get_rfc3526_prime_3072, 2},
+ {MODP_4096_BIT, get_rfc3526_prime_4096, 2},
+ {MODP_6144_BIT, get_rfc3526_prime_6144, 2},
+ {MODP_8192_BIT, get_rfc3526_prime_8192, 2},
+};
+
+typedef struct private_openssl_diffie_hellman_t private_openssl_diffie_hellman_t;
+
+/**
+ * Private data of an openssl_diffie_hellman_t object.
+ */
+struct private_openssl_diffie_hellman_t {
+ /**
+ * Public openssl_diffie_hellman_t interface.
+ */
+ openssl_diffie_hellman_t public;
+
+ /**
+ * Diffie Hellman group number.
+ */
+ u_int16_t group;
+
+ /**
+ * Diffie Hellman object
+ */
+ DH *dh;
+
+ /**
+ * Other public value
+ */
+ BIGNUM *pub_key;
+
+ /**
+ * Shared secret
+ */
+ chunk_t shared_secret;
+
+ /**
+ * True if shared secret is computed
+ */
+ bool computed;
+};
+
+/**
+ * Convert a BIGNUM to a chunk
+ */
+static void bn2chunk(BIGNUM *bn, chunk_t *chunk)
+{
+ chunk->len = BN_num_bytes(bn);
+ chunk->ptr = malloc(chunk->len);
+ BN_bn2bin(bn, chunk->ptr);
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.set_other_public_value.
+ */
+static void set_other_public_value(private_openssl_diffie_hellman_t *this, chunk_t value)
+{
+ int len;
+ BN_bin2bn(value.ptr, value.len, this->pub_key);
+
+ len = DH_size(this->dh);
+ chunk_free(&this->shared_secret);
+ this->shared_secret = chunk_alloc(len);
+
+ if (DH_compute_key(this->shared_secret.ptr, this->pub_key, this->dh) < 0) {
+ DBG1("DH shared secret computation failed");
+ return;
+ }
+
+ this->computed = TRUE;
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.get_other_public_value.
+ */
+static status_t get_other_public_value(private_openssl_diffie_hellman_t *this,
+ chunk_t *value)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+ bn2chunk(this->pub_key, value);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.get_my_public_value.
+ */
+static void get_my_public_value(private_openssl_diffie_hellman_t *this,chunk_t *value)
+{
+ bn2chunk(this->dh->pub_key, value);
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.get_shared_secret.
+ */
+static status_t get_shared_secret(private_openssl_diffie_hellman_t *this, chunk_t *secret)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+ *secret = chunk_clone(this->shared_secret);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_openssl_diffie_hellman_t *this)
+{
+ return this->group;
+}
+
+/**
+ * Lookup the modulus in modulo table
+ */
+static status_t set_modulus(private_openssl_diffie_hellman_t *this)
+{
+ int i;
+ for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++)
+ {
+ if (modulus_entries[i].group == this->group)
+ {
+ this->dh->p = modulus_entries[i].get_prime(NULL);
+ this->dh->g = BN_new();
+ BN_set_word(this->dh->g, modulus_entries[i].generator);
+ return SUCCESS;
+ }
+ }
+ return NOT_FOUND;
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.destroy.
+ */
+static void destroy(private_openssl_diffie_hellman_t *this)
+{
+ BN_clear_free(this->pub_key);
+ DH_free(this->dh);
+ chunk_free(&this->shared_secret);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+openssl_diffie_hellman_t *openssl_diffie_hellman_create(diffie_hellman_group_t group)
+{
+ private_openssl_diffie_hellman_t *this = malloc_thing(private_openssl_diffie_hellman_t);
+
+ this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
+ this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
+ this->public.dh.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
+ this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
+ this->public.dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
+ this->public.dh.destroy = (void (*)(diffie_hellman_t *)) destroy;
+
+ this->dh = DH_new();
+ if (!this->dh)
+ {
+ free(this);
+ return NULL;
+ }
+
+ this->group = group;
+ this->computed = FALSE;
+
+ this->pub_key = BN_new();
+ this->shared_secret = chunk_empty;
+
+ /* find a modulus according to group */
+ if (set_modulus(this) != SUCCESS)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ /* generate my public and private values */
+ if (!DH_generate_key(this->dh))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
new file mode 100644
index 000000000..c72b4aab0
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
@@ -0,0 +1,50 @@
+/*
+ * 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: openssl_diffie_hellman.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_diffie_hellman openssl_diffie_hellman
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_DIFFIE_HELLMAN_H_
+#define OPENSSL_DIFFIE_HELLMAN_H_
+
+typedef struct openssl_diffie_hellman_t openssl_diffie_hellman_t;
+
+#include <library.h>
+
+/**
+ * Implementation of the Diffie-Hellman algorithm using OpenSSL.
+ */
+struct openssl_diffie_hellman_t {
+
+ /**
+ * Implements diffie_hellman_t interface.
+ */
+ diffie_hellman_t dh;
+};
+
+/**
+ * Creates a new openssl_diffie_hellman_t object.
+ *
+ * @param group Diffie Hellman group number to use
+ * @return openssl_diffie_hellman_t object, NULL if not supported
+ */
+openssl_diffie_hellman_t *openssl_diffie_hellman_create(diffie_hellman_group_t group);
+
+#endif /*OPENSSL_DIFFIE_HELLMAN_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
new file mode 100644
index 000000000..9d2bd44cd
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
@@ -0,0 +1,342 @@
+/*
+ * 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: openssl_ec_diffie_hellman.c 4052 2008-06-10 09:19:18Z tobias $
+ */
+
+#include <openssl/ec.h>
+#include <openssl/objects.h>
+
+#include "openssl_ec_diffie_hellman.h"
+#include "openssl_util.h"
+
+#include <debug.h>
+
+typedef struct private_openssl_ec_diffie_hellman_t private_openssl_ec_diffie_hellman_t;
+
+/**
+ * Private data of an openssl_ec_diffie_hellman_t object.
+ */
+struct private_openssl_ec_diffie_hellman_t {
+ /**
+ * Public openssl_ec_diffie_hellman_t interface.
+ */
+ openssl_ec_diffie_hellman_t public;
+
+ /**
+ * Diffie Hellman group number.
+ */
+ u_int16_t group;
+
+ /**
+ * EC private (public) key
+ */
+ EC_KEY *key;
+
+ /**
+ * EC group
+ */
+ const EC_GROUP *ec_group;
+
+ /**
+ * Other public key
+ */
+ EC_POINT *pub_key;
+
+ /**
+ * Shared secret
+ */
+ chunk_t shared_secret;
+
+ /**
+ * True if shared secret is computed
+ */
+ bool computed;
+};
+
+/**
+ * Convert a chunk to an EC_POINT (which must already exist). The x and y
+ * coordinates of the point have to be concatenated in the chunk.
+ */
+static bool chunk2ecp(const EC_GROUP *group, chunk_t chunk, EC_POINT *point)
+{
+ BN_CTX *ctx;
+ BIGNUM *x, *y;
+ bool ret = FALSE;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ {
+ return FALSE;
+ }
+
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (!x || !y)
+ {
+ goto error;
+ }
+
+ if (!openssl_bn_split(chunk, x, y))
+ {
+ goto error;
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
+ {
+ goto error;
+ }
+
+ ret = TRUE;
+error:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return ret;
+}
+
+/**
+ * Convert an EC_POINT to a chunk by concatenating the x and y coordinates of
+ * the point. This function allocates memory for the chunk.
+ */
+static bool ecp2chunk(const EC_GROUP *group, const EC_POINT *point, chunk_t *chunk)
+{
+ BN_CTX *ctx;
+ BIGNUM *x, *y;
+ bool ret = FALSE;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ {
+ return FALSE;
+ }
+
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (!x || !y)
+ {
+ goto error;
+ }
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
+ {
+ goto error;
+ }
+
+ if (!openssl_bn_cat(EC_FIELD_ELEMENT_LEN(group), x, y, chunk))
+ {
+ goto error;
+ }
+
+ ret = TRUE;
+error:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return ret;
+}
+
+/**
+ * Compute the shared secret.
+ *
+ * We cannot use the function ECDH_compute_key() because that returns only the
+ * x coordinate of the shared secret point (which is defined, for instance, in
+ * 'NIST SP 800-56A').
+ * However, we need both coordinates as RFC 4753 says: "The Diffie-Hellman
+ * public value is obtained by concatenating the x and y values. The format
+ * of the Diffie-Hellman shared secret value is the same as that of the
+ * Diffie-Hellman public value."
+ */
+static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this, chunk_t *shared_secret)
+{
+ const BIGNUM *priv_key;
+ EC_POINT *secret = NULL;
+ bool ret = FALSE;
+
+ priv_key = EC_KEY_get0_private_key(this->key);
+ if (!priv_key)
+ {
+ goto error;
+ }
+
+ secret = EC_POINT_new(this->ec_group);
+ if (!secret)
+ {
+ goto error;
+ }
+
+ if (!EC_POINT_mul(this->ec_group, secret, NULL, this->pub_key, priv_key, NULL))
+ {
+ goto error;
+ }
+
+ if (!ecp2chunk(this->ec_group, secret, shared_secret))
+ {
+ goto error;
+ }
+
+ ret = TRUE;
+error:
+ if (secret)
+ {
+ EC_POINT_clear_free(secret);
+ }
+ return ret;
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.set_other_public_value.
+ */
+static void set_other_public_value(private_openssl_ec_diffie_hellman_t *this, chunk_t value)
+{
+ if (!chunk2ecp(this->ec_group, value, this->pub_key))
+ {
+ DBG1("ECDH public value is malformed");
+ return;
+ }
+
+ chunk_free(&this->shared_secret);
+
+ if (!compute_shared_key(this, &this->shared_secret)) {
+ DBG1("ECDH shared secret computation failed");
+ return;
+ }
+
+ this->computed = TRUE;
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.get_other_public_value.
+ */
+static status_t get_other_public_value(private_openssl_ec_diffie_hellman_t *this,
+ chunk_t *value)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+
+ if (!ecp2chunk(this->ec_group, this->pub_key, value))
+ {
+ return FAILED;
+ }
+ return SUCCESS;
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.get_my_public_value.
+ */
+static void get_my_public_value(private_openssl_ec_diffie_hellman_t *this,chunk_t *value)
+{
+ ecp2chunk(this->ec_group, EC_KEY_get0_public_key(this->key), value);
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.get_shared_secret.
+ */
+static status_t get_shared_secret(private_openssl_ec_diffie_hellman_t *this, chunk_t *secret)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+ *secret = chunk_clone(this->shared_secret);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_openssl_ec_diffie_hellman_t *this)
+{
+ return this->group;
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.destroy.
+ */
+static void destroy(private_openssl_ec_diffie_hellman_t *this)
+{
+ EC_POINT_clear_free(this->pub_key);
+ EC_KEY_free(this->key);
+ chunk_free(&this->shared_secret);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group)
+{
+ private_openssl_ec_diffie_hellman_t *this = malloc_thing(private_openssl_ec_diffie_hellman_t);
+
+ this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
+ this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
+ this->public.dh.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
+ this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
+ this->public.dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
+ this->public.dh.destroy = (void (*)(diffie_hellman_t *)) destroy;
+
+ switch (group)
+ {
+ case ECP_192_BIT:
+ this->key = EC_KEY_new_by_curve_name(NID_X9_62_prime192v1);
+ break;
+ case ECP_224_BIT:
+ this->key = EC_KEY_new_by_curve_name(NID_secp224r1);
+ break;
+ case ECP_256_BIT:
+ this->key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+ break;
+ case ECP_384_BIT:
+ this->key = EC_KEY_new_by_curve_name(NID_secp384r1);
+ break;
+ case ECP_521_BIT:
+ this->key = EC_KEY_new_by_curve_name(NID_secp521r1);
+ break;
+ default:
+ this->key = NULL;
+ break;
+ }
+
+ if (!this->key)
+ {
+ free(this);
+ return NULL;
+ }
+
+ /* caching the EC group */
+ this->ec_group = EC_KEY_get0_group(this->key);
+
+ this->pub_key = EC_POINT_new(this->ec_group);
+ if (!this->pub_key)
+ {
+ free(this);
+ return NULL;
+ }
+
+ /* generate an EC private (public) key */
+ if (!EC_KEY_generate_key(this->key))
+ {
+ free(this);
+ return NULL;
+ }
+
+ this->group = group;
+ this->computed = FALSE;
+
+ this->shared_secret = chunk_empty;
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h
new file mode 100644
index 000000000..e89f1cbd7
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h
@@ -0,0 +1,50 @@
+/*
+ * 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: openssl_ec_diffie_hellman.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_ec_diffie_hellman openssl_ec_diffie_hellman
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_EC_DIFFIE_HELLMAN_H_
+#define OPENSSL_EC_DIFFIE_HELLMAN_H_
+
+typedef struct openssl_ec_diffie_hellman_t openssl_ec_diffie_hellman_t;
+
+#include <library.h>
+
+/**
+ * Implementation of the EC Diffie-Hellman algorithm using OpenSSL.
+ */
+struct openssl_ec_diffie_hellman_t {
+
+ /**
+ * Implements diffie_hellman_t interface.
+ */
+ diffie_hellman_t dh;
+};
+
+/**
+ * Creates a new openssl_ec_diffie_hellman_t object.
+ *
+ * @param group EC Diffie Hellman group number to use
+ * @return openssl_ec_diffie_hellman_t object, NULL if not supported
+ */
+openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group);
+
+#endif /*OPENSSL_EC_DIFFIE_HELLMAN_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
new file mode 100644
index 000000000..9f7df4bca
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
@@ -0,0 +1,445 @@
+/*
+ * 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: openssl_ec_private_key.c 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+#include "openssl_ec_private_key.h"
+#include "openssl_ec_public_key.h"
+#include "openssl_util.h"
+
+#include <debug.h>
+
+#include <openssl/evp.h>
+#include <openssl/ecdsa.h>
+
+typedef struct private_openssl_ec_private_key_t private_openssl_ec_private_key_t;
+
+/**
+ * Private data of a openssl_ec_private_key_t object.
+ */
+struct private_openssl_ec_private_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ openssl_ec_private_key_t public;
+
+ /**
+ * EC key object
+ */
+ EC_KEY *ec;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a privateKey object
+ */
+ identification_t* keyid;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a privateKeyInfo object
+ */
+ identification_t* keyid_info;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+/**
+ * Mapping from the signature scheme defined in (RFC 4754) to the elliptic
+ * curve and the hash algorithm
+ */
+typedef struct {
+ /**
+ * Scheme specified in RFC 4754
+ */
+ int scheme;
+
+ /**
+ * NID of the hash
+ */
+ int hash;
+
+ /**
+ * NID of the curve
+ */
+ int curve;
+} openssl_ecdsa_scheme_t;
+
+#define END_OF_LIST -1
+
+/**
+ * Signature schemes
+ */
+static openssl_ecdsa_scheme_t ecdsa_schemes[] = {
+ {SIGN_ECDSA_256, NID_sha256, NID_X9_62_prime256v1},
+ {SIGN_ECDSA_384, NID_sha384, NID_secp384r1},
+ {SIGN_ECDSA_521, NID_sha512, NID_secp521r1},
+ {END_OF_LIST, 0, 0},
+};
+
+/**
+ * Look up the hash and curve of a signature scheme
+ */
+static bool lookup_scheme(int scheme, int *hash, int *curve)
+{
+ openssl_ecdsa_scheme_t *ecdsa_scheme = ecdsa_schemes;
+ while (ecdsa_scheme->scheme != END_OF_LIST)
+ {
+ if (scheme == ecdsa_scheme->scheme)
+ {
+ *hash = ecdsa_scheme->hash;
+ *curve = ecdsa_scheme->curve;
+ return TRUE;
+ }
+ ecdsa_scheme++;
+ }
+ return FALSE;
+}
+
+/**
+ * shared functions, implemented in openssl_ec_public_key.c
+ */
+bool openssl_ec_public_key_build_id(EC_KEY *ec, identification_t **keyid,
+ identification_t **keyid_info);
+
+openssl_ec_public_key_t *openssl_ec_public_key_create_from_private_key(EC_KEY *ec);
+
+
+/**
+ * Convert an ECDSA_SIG to a chunk by concatenating r and s.
+ * This function allocates memory for the chunk.
+ */
+static bool sig2chunk(const EC_GROUP *group, ECDSA_SIG *sig, chunk_t *chunk)
+{
+ return openssl_bn_cat(EC_FIELD_ELEMENT_LEN(group), sig->r, sig->s, chunk);
+}
+
+/**
+ * Build the signature
+ */
+static bool build_signature(private_openssl_ec_private_key_t *this,
+ int hash_type, chunk_t data, chunk_t *signature)
+{
+ chunk_t hash = chunk_empty;
+ ECDSA_SIG *sig;
+ bool ret = FALSE;
+
+ if (!openssl_hash_chunk(hash_type, data, &hash))
+ {
+ return FALSE;
+ }
+
+ sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec);
+ if (!sig)
+ {
+ goto error;
+ }
+
+ if (!sig2chunk(EC_KEY_get0_group(this->ec), sig, signature))
+ {
+ goto error;
+ }
+
+ ret = TRUE;
+error:
+ chunk_free(&hash);
+ if (sig)
+ {
+ ECDSA_SIG_free(sig);
+ }
+ return ret;
+}
+
+/**
+ * Implementation of private_key_t.get_type.
+ */
+static key_type_t get_type(private_openssl_ec_private_key_t *this)
+{
+ return KEY_ECDSA;
+}
+
+/**
+ * Implementation of private_key_t.sign.
+ */
+static bool sign(private_openssl_ec_private_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t *signature)
+{
+ EC_GROUP *req_group;
+ const EC_GROUP *my_group;
+ int hash, curve;
+
+ if (!lookup_scheme(scheme, &hash, &curve))
+ {
+ DBG1("signature scheme %N not supported in EC",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+
+ req_group = EC_GROUP_new_by_curve_name(curve);
+ if (!req_group)
+ {
+ DBG1("signature scheme %N not supported in EC (required curve not supported)",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+
+ my_group = EC_KEY_get0_group(this->ec);
+ if (EC_GROUP_cmp(my_group, req_group, NULL) != 0)
+ {
+ DBG1("signature scheme %N not supported by private key",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+
+ EC_GROUP_free(req_group);
+
+ return build_signature(this, hash, data, signature);
+}
+
+/**
+ * Implementation of private_key_t.destroy.
+ */
+static bool decrypt(private_openssl_ec_private_key_t *this,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1("EC private key decryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of private_key_t.get_keysize.
+ */
+static size_t get_keysize(private_openssl_ec_private_key_t *this)
+{
+ return EC_FIELD_ELEMENT_LEN(EC_KEY_get0_group(this->ec));
+}
+
+/**
+ * Implementation of private_key_t.get_id.
+ */
+static identification_t* get_id(private_openssl_ec_private_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Implementation of private_key_t.get_public_key.
+ */
+static openssl_ec_public_key_t* get_public_key(private_openssl_ec_private_key_t *this)
+{
+ return openssl_ec_public_key_create_from_private_key(this->ec);
+}
+
+/**
+ * Implementation of private_key_t.belongs_to.
+ */
+static bool belongs_to(private_openssl_ec_private_key_t *this, public_key_t *public)
+{
+ identification_t *keyid;
+
+ if (public->get_type(public) != KEY_ECDSA)
+ {
+ return FALSE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of private_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_openssl_ec_private_key_t *this)
+{
+ chunk_t enc = chunk_alloc(i2d_ECPrivateKey(this->ec, NULL));
+ u_char *p = enc.ptr;
+ i2d_ECPrivateKey(this->ec, &p);
+ return enc;
+}
+
+/**
+ * Implementation of private_key_t.get_ref.
+ */
+static private_openssl_ec_private_key_t* get_ref(private_openssl_ec_private_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+
+}
+
+/**
+ * Implementation of private_key_t.destroy.
+ */
+static void destroy(private_openssl_ec_private_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ if (this->ec)
+ {
+ EC_KEY_free(this->ec);
+ }
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_openssl_ec_private_key_t *openssl_ec_private_key_create_empty(void)
+{
+ private_openssl_ec_private_key_t *this = malloc_thing(private_openssl_ec_private_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
+ this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
+ this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
+ this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
+ this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
+ this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
+ this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
+ this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
+
+ this->ec = NULL;
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * load private key from an ASN1 encoded blob
+ */
+static openssl_ec_private_key_t *load(chunk_t blob)
+{
+ u_char *p = blob.ptr;
+ private_openssl_ec_private_key_t *this = openssl_ec_private_key_create_empty();
+
+ this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&p, blob.len);
+
+ chunk_clear(&blob);
+
+ if (!this->ec)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!openssl_ec_public_key_build_id(this->ec, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!EC_KEY_check_key(this->ec))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading/generation
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded/generated private key */
+ openssl_ec_private_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static openssl_ec_private_key_t *build(private_builder_t *this)
+{
+ openssl_ec_private_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *openssl_ec_private_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_ECDSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
new file mode 100644
index 000000000..629fc9574
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
@@ -0,0 +1,49 @@
+/*
+ * 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: openssl_ec_private_key.h 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+/**
+ * @defgroup openssl_ec_private_key openssl_ec_private_key
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_EC_PRIVATE_KEY_H_
+#define OPENSSL_EC_PRIVATE_KEY_H_
+
+#include <credentials/keys/private_key.h>
+
+typedef struct openssl_ec_private_key_t openssl_ec_private_key_t;
+
+/**
+ * private_key_t implementation of ECDSA using OpenSSL.
+ */
+struct openssl_ec_private_key_t {
+
+ /**
+ * Implements private_key_t interface
+ */
+ private_key_t interface;
+};
+
+/**
+ * Create the builder for a private key.
+ *
+ * @param type type of the key, must be KEY_ECDSA
+ * @return builder instance
+ */
+builder_t *openssl_ec_private_key_builder(key_type_t type);
+
+#endif /*OPENSSL_EC_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
new file mode 100644
index 000000000..2056575ba
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
@@ -0,0 +1,447 @@
+/*
+ * 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: openssl_ec_public_key.c 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+#include "openssl_ec_public_key.h"
+#include "openssl_util.h"
+
+#include <debug.h>
+
+#include <openssl/evp.h>
+#include <openssl/ecdsa.h>
+#include <openssl/x509.h>
+
+typedef struct private_openssl_ec_public_key_t private_openssl_ec_public_key_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_openssl_ec_public_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ openssl_ec_public_key_t public;
+
+ /**
+ * EC key object
+ */
+ EC_KEY *ec;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+ */
+ identification_t *keyid_info;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKey object
+ */
+ identification_t *keyid;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * Convert a chunk to an ECDSA_SIG (which must already exist). r and s
+ * of the signature have to be concatenated in the chunk.
+ */
+static bool chunk2sig(const EC_GROUP *group, chunk_t chunk, ECDSA_SIG *sig)
+{
+ return openssl_bn_split(chunk, sig->r, sig->s);
+}
+
+/**
+ * Verification of a signature as in RFC 4754
+ */
+static bool verify_signature(private_openssl_ec_public_key_t *this,
+ int hash_type, chunk_t data, chunk_t signature)
+{
+ chunk_t hash = chunk_empty;
+ ECDSA_SIG *sig;
+ bool valid = FALSE;
+
+ if (!openssl_hash_chunk(hash_type, data, &hash))
+ {
+ return FALSE;
+ }
+
+ sig = ECDSA_SIG_new();
+ if (!sig)
+ {
+ goto error;
+ }
+
+ if (!chunk2sig(EC_KEY_get0_group(this->ec), signature, sig))
+ {
+ goto error;
+ }
+
+ valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1);
+
+error:
+ if (sig)
+ {
+ ECDSA_SIG_free(sig);
+ }
+ chunk_free(&hash);
+ return valid;
+}
+
+
+/**
+ * Verification of the default signature using SHA-1
+ */
+static bool verify_default_signature(private_openssl_ec_public_key_t *this,
+ chunk_t data, chunk_t signature)
+{
+ bool valid = FALSE;
+ chunk_t hash = chunk_empty;
+ u_char *p;
+ ECDSA_SIG *sig;
+
+ /* remove any preceding 0-bytes from signature */
+ while (signature.len && *(signature.ptr) == 0x00)
+ {
+ signature.len -= 1;
+ signature.ptr++;
+ }
+
+ p = signature.ptr;
+ sig = d2i_ECDSA_SIG(NULL, (const u_char**)&p, signature.len);
+ if (!sig)
+ {
+ return FALSE;
+ }
+
+ if (!openssl_hash_chunk(NID_sha1, data, &hash))
+ {
+ goto error;
+ }
+
+ valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1);
+
+error:
+ if (sig)
+ {
+ ECDSA_SIG_free(sig);
+ }
+ chunk_free(&hash);
+ return valid;
+}
+
+/**
+ * Implementation of public_key_t.get_type.
+ */
+static key_type_t get_type(private_openssl_ec_public_key_t *this)
+{
+ return KEY_ECDSA;
+}
+
+/**
+ * Implementation of public_key_t.verify.
+ */
+static bool verify(private_openssl_ec_public_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t signature)
+{
+ switch (scheme)
+ {
+ case SIGN_ECDSA_WITH_SHA1:
+ return verify_default_signature(this, data, signature);
+ case SIGN_ECDSA_256:
+ return verify_signature(this, NID_sha256, data, signature);
+ case SIGN_ECDSA_384:
+ return verify_signature(this, NID_sha384, data, signature);
+ case SIGN_ECDSA_521:
+ return verify_signature(this, NID_sha512, data, signature);
+ default:
+ DBG1("signature scheme %N not supported in EC",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static bool encrypt(private_openssl_ec_public_key_t *this, chunk_t crypto, chunk_t *plain)
+{
+ DBG1("EC public key encryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static size_t get_keysize(private_openssl_ec_public_key_t *this)
+{
+ return EC_FIELD_ELEMENT_LEN(EC_KEY_get0_group(this->ec));
+}
+
+/**
+ * Implementation of public_key_t.get_id.
+ */
+static identification_t *get_id(private_openssl_ec_public_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Encodes the public key
+ */
+static chunk_t get_encoding_raw(EC_KEY *ec)
+{
+ /* since the points can be stored in three different forms this may not
+ * be correct for all cases */
+ const EC_GROUP *group = EC_KEY_get0_group(ec);
+ const EC_POINT *pub = EC_KEY_get0_public_key(ec);
+ chunk_t enc = chunk_alloc(EC_POINT_point2oct(group, pub,
+ POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL));
+ EC_POINT_point2oct(group, pub, POINT_CONVERSION_UNCOMPRESSED,
+ enc.ptr, enc.len, NULL);
+ return enc;
+}
+
+/**
+ * Encodes the public key info (public key with ec parameters)
+ */
+static chunk_t get_encoding_full(EC_KEY *ec)
+{
+ chunk_t enc = chunk_alloc(i2d_EC_PUBKEY(ec, NULL));
+ u_char *p = enc.ptr;
+ i2d_EC_PUBKEY(ec, &p);
+ return enc;
+}
+
+/*
+ * Implementation of public_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_openssl_ec_public_key_t *this)
+{
+ return get_encoding_full(this->ec);
+}
+
+/**
+ * Implementation of public_key_t.get_ref.
+ */
+static private_openssl_ec_public_key_t* get_ref(private_openssl_ec_public_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of openssl_ec_public_key.destroy.
+ */
+static void destroy(private_openssl_ec_public_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ if (this->ec)
+ {
+ EC_KEY_free(this->ec);
+ }
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Generic private constructor
+ */
+static private_openssl_ec_public_key_t *openssl_ec_public_key_create_empty()
+{
+ private_openssl_ec_public_key_t *this = malloc_thing(private_openssl_ec_public_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
+ this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
+ this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt;
+ this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
+ this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
+ this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
+
+ this->ec = NULL;
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * Build key identifier from the public key using SHA1 hashed publicKey(Info).
+ * Also used in openssl_ec_private_key.c.
+ */
+bool openssl_ec_public_key_build_id(EC_KEY *ec, identification_t **keyid,
+ identification_t **keyid_info)
+{
+ chunk_t publicKeyInfo, publicKey, hash;
+ hasher_t *hasher;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher == NULL)
+ {
+ DBG1("SHA1 hash algorithm not supported, unable to use EC");
+ return FALSE;
+ }
+
+ publicKey = get_encoding_raw(ec);
+
+ hasher->allocate_hash(hasher, publicKey, &hash);
+ *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
+ chunk_free(&hash);
+
+ publicKeyInfo = get_encoding_full(ec);
+
+ hasher->allocate_hash(hasher, publicKeyInfo, &hash);
+ *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash);
+ chunk_free(&hash);
+
+ hasher->destroy(hasher);
+ chunk_free(&publicKeyInfo);
+ chunk_free(&publicKey);
+
+ return TRUE;
+}
+
+/**
+ * Create a public key from BIGNUM values, used in openssl_ec_private_key.c
+ */
+openssl_ec_public_key_t *openssl_ec_public_key_create_from_private_key(EC_KEY *ec)
+{
+ private_openssl_ec_public_key_t *this = openssl_ec_public_key_create_empty();
+
+ this->ec = EC_KEY_new();
+ EC_KEY_set_public_key(this->ec, EC_KEY_get0_public_key(ec));
+
+ if (!openssl_ec_public_key_build_id(this->ec, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+/**
+ * Load a public key from an ASN1 encoded blob
+ */
+static openssl_ec_public_key_t *load(chunk_t blob)
+{
+ u_char *p = blob.ptr;
+ private_openssl_ec_public_key_t *this = openssl_ec_public_key_create_empty();
+
+ this->ec = d2i_EC_PUBKEY(NULL, (const u_char**)&p, blob.len);
+
+ chunk_clear(&blob);
+
+ if (!this->ec)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!openssl_ec_public_key_build_id(this->ec, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded public key */
+ openssl_ec_public_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static openssl_ec_public_key_t *build(private_builder_t *this)
+{
+ openssl_ec_public_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *openssl_ec_public_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_ECDSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
new file mode 100644
index 000000000..92684402c
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
@@ -0,0 +1,49 @@
+/*
+ * 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: openssl_ec_public_key.h 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+/**
+ * @defgroup openssl_ec_public_key openssl_ec_public_key
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_EC_PUBLIC_KEY_H_
+#define OPENSSL_EC_PUBLIC_KEY_H_
+
+typedef struct openssl_ec_public_key_t openssl_ec_public_key_t;
+
+#include <credentials/keys/public_key.h>
+
+/**
+ * public_key_t implementation of ECDSA using OpenSSL.
+ */
+struct openssl_ec_public_key_t {
+
+ /**
+ * Implements the public_key_t interface
+ */
+ public_key_t interface;
+};
+
+/**
+ * Create the builder for a public key.
+ *
+ * @param type type of the key, must be KEY_ECDSA
+ * @return builder instance
+ */
+builder_t *openssl_ec_public_key_builder(key_type_t type);
+
+#endif /*OPENSSL_EC_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.c b/src/libstrongswan/plugins/openssl/openssl_hasher.c
new file mode 100644
index 000000000..1275cdfb0
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.c
@@ -0,0 +1,185 @@
+/*
+ * 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: openssl_hasher.c 3898 2008-04-30 09:23:13Z tobias $
+ */
+
+#include "openssl_hasher.h"
+
+#include <openssl/evp.h>
+
+typedef struct private_openssl_hasher_t private_openssl_hasher_t;
+
+/**
+ * Private data of openssl_hasher_t
+ */
+struct private_openssl_hasher_t {
+
+ /**
+ * Public part of this class.
+ */
+ openssl_hasher_t public;
+
+ /**
+ * the hasher to use
+ */
+ const EVP_MD *hasher;
+
+ /**
+ * the current digest context
+ */
+ EVP_MD_CTX *ctx;
+};
+
+/**
+ * Mapping from the algorithms defined in IKEv2 to
+ * OpenSSL algorithm names
+ */
+typedef struct {
+ /**
+ * Identifier specified in IKEv2
+ */
+ int ikev2_id;
+
+ /**
+ * Name of the algorithm, as used in OpenSSL
+ */
+ char *name;
+} openssl_algorithm_t;
+
+#define END_OF_LIST -1
+
+/**
+ * Algorithms for integrity
+ */
+static openssl_algorithm_t integrity_algs[] = {
+ {HASH_MD2, "md2"},
+ {HASH_MD5, "md5"},
+ {HASH_SHA1, "sha1"},
+ {HASH_SHA256, "sha256"},
+ {HASH_SHA384, "sha384"},
+ {HASH_SHA512, "sha512"},
+ {END_OF_LIST, NULL},
+};
+
+/**
+ * Look up an OpenSSL algorithm name
+ */
+static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
+ u_int16_t ikev2_algo)
+{
+ while (openssl_algo->ikev2_id != END_OF_LIST)
+ {
+ if (ikev2_algo == openssl_algo->ikev2_id)
+ {
+ return openssl_algo->name;
+ }
+ openssl_algo++;
+ }
+ return NULL;
+}
+
+/**
+ * Implementation of hasher_t.get_hash_size.
+ */
+static size_t get_hash_size(private_openssl_hasher_t *this)
+{
+ return this->hasher->md_size;
+}
+
+/**
+ * Implementation of hasher_t.reset.
+ */
+static void reset(private_openssl_hasher_t *this)
+{
+ EVP_DigestInit_ex(this->ctx, this->hasher, NULL);
+}
+
+/**
+ * Implementation of hasher_t.get_hash.
+ */
+static void get_hash(private_openssl_hasher_t *this, chunk_t chunk,
+ u_int8_t *hash)
+{
+ EVP_DigestUpdate(this->ctx, chunk.ptr, chunk.len);
+ if (hash)
+ {
+ EVP_DigestFinal_ex(this->ctx, hash, NULL);
+ reset(this);
+ }
+}
+
+/**
+ * Implementation of hasher_t.allocate_hash.
+ */
+static void allocate_hash(private_openssl_hasher_t *this, chunk_t chunk,
+ chunk_t *hash)
+{
+ if (hash)
+ {
+ *hash = chunk_alloc(get_hash_size(this));
+ get_hash(this, chunk, hash->ptr);
+ }
+ else
+ {
+ get_hash(this, chunk, NULL);
+ }
+}
+
+/**
+ * Implementation of hasher_t.destroy.
+ */
+static void destroy (private_openssl_hasher_t *this)
+{
+ EVP_MD_CTX_destroy(this->ctx);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
+{
+ private_openssl_hasher_t *this;
+
+ char* name = lookup_algorithm(integrity_algs, algo);
+ if (!name)
+ {
+ /* algo unavailable */
+ return NULL;
+ }
+
+ this = malloc_thing(private_openssl_hasher_t);
+
+ this->hasher = EVP_get_digestbyname(name);
+ if (!this->hasher)
+ {
+ /* OpenSSL does not support the requested algo */
+ free(this);
+ return NULL;
+ }
+
+ this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
+ this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
+ this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
+ this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
+ this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
+
+ this->ctx = EVP_MD_CTX_create();
+
+ /* initialization */
+ reset(this);
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/crypto/hashers/sha1_hasher.h b/src/libstrongswan/plugins/openssl/openssl_hasher.h
index 380fa9845..f776e9fd4 100644
--- a/src/libstrongswan/crypto/hashers/sha1_hasher.h
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.h
@@ -1,13 +1,5 @@
-/**
- * @file sha1_hasher.h
- *
- * @brief Interface of sha1_hasher_t
- *
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
+ * Copyright (C) 2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -19,42 +11,40 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: openssl_hasher.h 4000 2008-05-22 12:13:10Z tobias $
*/
-#ifndef SHA1_HASHER_H_
-#define SHA1_HASHER_H_
+/**
+ * @defgroup openssl_hasher openssl_hasher
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_HASHER_H_
+#define OPENSSL_HASHER_H_
-typedef struct sha1_hasher_t sha1_hasher_t;
+typedef struct openssl_hasher_t openssl_hasher_t;
#include <crypto/hashers/hasher.h>
/**
- * @brief Implementation of hasher_t interface using the
- * SHA1 algorithm.
- *
- * @b Constructors:
- * - hasher_create() using HASH_SHA1 as algorithm
- * - sha1_hasher_create()
- *
- * @see hasher_t
- *
- * @ingroup hashers
+ * Implementation of hashers using OpenSSL.
*/
-struct sha1_hasher_t {
+struct openssl_hasher_t {
/**
- * Generic hasher_t interface for this hasher.
+ * The hasher_t interface.
*/
hasher_t hasher_interface;
};
/**
- * @brief Creates a new sha1_hasher_t.
- *
- * @return sha1_hasher_t object
+ * Constructor to create openssl_hasher_t.
*
- * @ingroup hashers
+ * @param algo algorithm
+ * @param key_size key size in bytes
+ * @return openssl_hasher_t, NULL if not supported
*/
-sha1_hasher_t *sha1_hasher_create(void);
+openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo);
-#endif /*SHA1_HASHER_H_*/
+#endif /* OPENSSL_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
new file mode 100644
index 000000000..7fdd7c224
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -0,0 +1,164 @@
+/*
+ * 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: openssl_plugin.c 4107 2008-06-25 12:39:32Z tobias $
+ */
+
+#include <openssl/evp.h>
+#include <openssl/engine.h>
+
+#include "openssl_plugin.h"
+
+#include <library.h>
+#include "openssl_crypter.h"
+#include "openssl_hasher.h"
+#include "openssl_diffie_hellman.h"
+#include "openssl_ec_diffie_hellman.h"
+#include "openssl_rsa_private_key.h"
+#include "openssl_rsa_public_key.h"
+#include "openssl_ec_private_key.h"
+#include "openssl_ec_public_key.h"
+
+typedef struct private_openssl_plugin_t private_openssl_plugin_t;
+
+/**
+ * private data of openssl_plugin
+ */
+struct private_openssl_plugin_t {
+
+ /**
+ * public functions
+ */
+ openssl_plugin_t public;
+};
+
+/**
+ * Implementation of openssl_plugin_t.destroy
+ */
+static void destroy(private_openssl_plugin_t *this)
+{
+ lib->crypto->remove_crypter(lib->crypto,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->remove_dh(lib->crypto,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->remove_dh(lib->crypto,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)openssl_rsa_private_key_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)openssl_rsa_public_key_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)openssl_ec_private_key_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)openssl_ec_public_key_builder);
+
+ ENGINE_cleanup();
+ EVP_cleanup();
+
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_openssl_plugin_t *this = malloc_thing(private_openssl_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ OpenSSL_add_all_algorithms();
+
+ /* activate support for hardware accelerators */
+ ENGINE_load_builtin_engines();
+ ENGINE_register_all_complete();
+
+ /* crypter */
+ lib->crypto->add_crypter(lib->crypto, ENCR_DES,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_3DES,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_RC5,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_IDEA,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_CAST,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_BLOWFISH,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_NULL,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
+ (crypter_constructor_t)openssl_crypter_create);
+
+ /* hasher */
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_MD2,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_MD5,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA512,
+ (hasher_constructor_t)openssl_hasher_create);
+
+ /* diffie hellman */
+ lib->crypto->add_dh(lib->crypto, MODP_768_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_1024_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_1536_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_2048_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_3072_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_4096_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_6144_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_8192_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+
+ /* ec diffie hellman */
+ lib->crypto->add_dh(lib->crypto, ECP_192_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, ECP_224_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, ECP_256_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, ECP_384_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, ECP_521_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+
+ /* rsa */
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ (builder_constructor_t)openssl_rsa_private_key_builder);
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ (builder_constructor_t)openssl_rsa_public_key_builder);
+
+ /* ec */
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
+ (builder_constructor_t)openssl_ec_private_key_builder);
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
+ (builder_constructor_t)openssl_ec_public_key_builder);
+
+ return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.h b/src/libstrongswan/plugins/openssl/openssl_plugin.h
new file mode 100644
index 000000000..40f741dfa
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.h
@@ -0,0 +1,49 @@
+/*
+ * 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: openssl_plugin.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_p openssl
+ * @ingroup plugins
+ *
+ * @defgroup openssl_plugin openssl_plugin
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_PLUGIN_H_
+#define OPENSSL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct openssl_plugin_t openssl_plugin_t;
+
+/**
+ * Plugin implementing crypto functions via the OpenSSL library
+ */
+struct openssl_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a openssl_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* OPENSSL_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
new file mode 100644
index 000000000..7595eed3a
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
@@ -0,0 +1,422 @@
+/*
+ * 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: openssl_rsa_private_key.c 3963 2008-05-15 12:41:06Z tobias $
+ */
+
+#include "openssl_rsa_private_key.h"
+#include "openssl_rsa_public_key.h"
+
+#include <debug.h>
+
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+
+/**
+ * Public exponent to use for key generation.
+ */
+#define PUBLIC_EXPONENT 0x10001
+
+typedef struct private_openssl_rsa_private_key_t private_openssl_rsa_private_key_t;
+
+/**
+ * Private data of a openssl_rsa_private_key_t object.
+ */
+struct private_openssl_rsa_private_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ openssl_rsa_private_key_t public;
+
+ /**
+ * RSA object from OpenSSL
+ */
+ RSA *rsa;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a privateKey object
+ */
+ identification_t* keyid;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a privateKeyInfo object
+ */
+ identification_t* keyid_info;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+/**
+ * shared functions, implemented in openssl_rsa_public_key.c
+ */
+bool openssl_rsa_public_key_build_id(RSA *rsa, identification_t **keyid,
+ identification_t **keyid_info);
+
+
+openssl_rsa_public_key_t *openssl_rsa_public_key_create_from_n_e(BIGNUM *n, BIGNUM *e);
+
+
+/**
+ * Build an EMPSA PKCS1 signature described in PKCS#1
+ */
+static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this,
+ int type, chunk_t data, chunk_t *signature)
+{
+ bool success = FALSE;
+ const EVP_MD *hasher = EVP_get_digestbynid(type);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+
+ EVP_MD_CTX *ctx = EVP_MD_CTX_create();
+ EVP_PKEY *key = EVP_PKEY_new();
+ if (!ctx || !key)
+ {
+ goto error;
+ }
+
+ if (!EVP_PKEY_set1_RSA(key, this->rsa))
+ {
+ goto error;
+ }
+
+ if (!EVP_SignInit_ex(ctx, hasher, NULL))
+ {
+ goto error;
+ }
+
+ if (!EVP_SignUpdate(ctx, data.ptr, data.len))
+ {
+ goto error;
+ }
+
+ *signature = chunk_alloc(RSA_size(this->rsa));
+
+ if (!EVP_SignFinal(ctx, signature->ptr, &signature->len, key))
+ {
+ goto error;
+ }
+
+ success = TRUE;
+
+error:
+ if (key)
+ {
+ EVP_PKEY_free(key);
+ }
+ if (ctx)
+ {
+ EVP_MD_CTX_destroy(ctx);
+ }
+ return success;
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static key_type_t get_type(private_openssl_rsa_private_key_t *this)
+{
+ return KEY_RSA;
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t *signature)
+{
+ switch (scheme)
+ {
+ case SIGN_DEFAULT:
+ /* default is EMSA-PKCS1 using SHA1 */
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return build_emsa_pkcs1_signature(this, NID_sha1, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return build_emsa_pkcs1_signature(this, NID_sha256, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return build_emsa_pkcs1_signature(this, NID_sha384, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return build_emsa_pkcs1_signature(this, NID_sha512, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return build_emsa_pkcs1_signature(this, NID_md5, data, signature);
+ default:
+ DBG1("signature scheme %N not supported in RSA",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static bool decrypt(private_openssl_rsa_private_key_t *this,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1("RSA private key decryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static size_t get_keysize(private_openssl_rsa_private_key_t *this)
+{
+ return RSA_size(this->rsa);
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static identification_t* get_id(private_openssl_rsa_private_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static openssl_rsa_public_key_t* get_public_key(private_openssl_rsa_private_key_t *this)
+{
+ return openssl_rsa_public_key_create_from_n_e(this->rsa->n, this->rsa->e);
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static bool belongs_to(private_openssl_rsa_private_key_t *this, public_key_t *public)
+{
+ identification_t *keyid;
+
+ if (public->get_type(public) != KEY_RSA)
+ {
+ return FALSE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of private_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_openssl_rsa_private_key_t *this)
+{
+ chunk_t enc = chunk_alloc(i2d_RSAPrivateKey(this->rsa, NULL));
+ u_char *p = enc.ptr;
+ i2d_RSAPrivateKey(this->rsa, &p);
+ return enc;
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static private_openssl_rsa_private_key_t* get_ref(private_openssl_rsa_private_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static void destroy(private_openssl_rsa_private_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ if (this->rsa)
+ {
+ RSA_free(this->rsa);
+ }
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_openssl_rsa_private_key_t *openssl_rsa_private_key_create_empty(void)
+{
+ private_openssl_rsa_private_key_t *this = malloc_thing(private_openssl_rsa_private_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
+ this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
+ this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
+ this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
+ this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
+ this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
+ this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
+ this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
+
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * Generate an RSA key of specified key size
+ */
+static openssl_rsa_private_key_t *generate(size_t key_size)
+{
+ private_openssl_rsa_private_key_t *this = openssl_rsa_private_key_create_empty();
+
+ this->rsa = RSA_generate_key(key_size, PUBLIC_EXPONENT, NULL, NULL);
+
+ if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
+/**
+ * load private key from an ASN1 encoded blob
+ */
+static openssl_rsa_private_key_t *load(chunk_t blob)
+{
+ u_char *p = blob.ptr;
+ private_openssl_rsa_private_key_t *this = openssl_rsa_private_key_create_empty();
+
+ this->rsa = d2i_RSAPrivateKey(NULL, (const u_char**)&p, blob.len);
+
+ chunk_clear(&blob);
+
+ if (!this->rsa)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!RSA_check_key(this->rsa))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading/generation
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded/generated private key */
+ openssl_rsa_private_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static openssl_rsa_private_key_t *build(private_builder_t *this)
+{
+ openssl_rsa_private_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ case BUILD_KEY_SIZE:
+ {
+ va_start(args, part);
+ this->key = generate(va_arg(args, u_int));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *openssl_rsa_private_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_RSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
new file mode 100644
index 000000000..81d81b2db
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
@@ -0,0 +1,49 @@
+/*
+ * 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: openssl_rsa_private_key.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_rsa_private_key openssl_rsa_private_key
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_RSA_PRIVATE_KEY_H_
+#define OPENSSL_RSA_PRIVATE_KEY_H_
+
+#include <credentials/keys/private_key.h>
+
+typedef struct openssl_rsa_private_key_t openssl_rsa_private_key_t;
+
+/**
+ * private_key_t implementation of RSA algorithm using OpenSSL.
+ */
+struct openssl_rsa_private_key_t {
+
+ /**
+ * Implements private_key_t interface
+ */
+ private_key_t interface;
+};
+
+/**
+ * Create the builder for a private key.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @return builder instance
+ */
+builder_t *openssl_rsa_private_key_builder(key_type_t type);
+
+#endif /*OPENSSL_RSA_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
new file mode 100644
index 000000000..755b86e96
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
@@ -0,0 +1,433 @@
+/*
+ * 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: openssl_rsa_public_key.c 3963 2008-05-15 12:41:06Z tobias $
+ */
+
+#include "openssl_rsa_public_key.h"
+
+#include <debug.h>
+
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/x509.h>
+
+typedef struct private_openssl_rsa_public_key_t private_openssl_rsa_public_key_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_openssl_rsa_public_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ openssl_rsa_public_key_t public;
+
+ /**
+ * RSA object from OpenSSL
+ */
+ RSA *rsa;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+ */
+ identification_t *keyid_info;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKey object
+ */
+ identification_t *keyid;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * Verification of an EMPSA PKCS1 signature described in PKCS#1
+ */
+static bool verify_emsa_pkcs1_signature(private_openssl_rsa_public_key_t *this,
+ int type, chunk_t data, chunk_t signature)
+{
+ bool valid = FALSE;
+ const EVP_MD *hasher = EVP_get_digestbynid(type);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+
+ EVP_MD_CTX *ctx = EVP_MD_CTX_create();
+ EVP_PKEY *key = EVP_PKEY_new();
+ if (!ctx || !key)
+ {
+ goto error;
+ }
+
+ if (!EVP_PKEY_set1_RSA(key, this->rsa))
+ {
+ goto error;
+ }
+
+ if (!EVP_VerifyInit_ex(ctx, hasher, NULL))
+ {
+ goto error;
+ }
+
+ if (!EVP_VerifyUpdate(ctx, data.ptr, data.len))
+ {
+ goto error;
+ }
+
+ /* remove any preceding 0-bytes from signature */
+ while (signature.len && *(signature.ptr) == 0x00)
+ {
+ signature.len -= 1;
+ signature.ptr++;
+ }
+
+ valid = (EVP_VerifyFinal(ctx, signature.ptr, signature.len, key) == 1);
+
+error:
+ if (key)
+ {
+ EVP_PKEY_free(key);
+ }
+ if (ctx)
+ {
+ EVP_MD_CTX_destroy(ctx);
+ }
+ return valid;
+}
+
+/**
+ * Implementation of public_key_t.get_type.
+ */
+static key_type_t get_type(private_openssl_rsa_public_key_t *this)
+{
+ return KEY_RSA;
+}
+
+/**
+ * Implementation of public_key_t.verify.
+ */
+static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t signature)
+{
+ switch (scheme)
+ {
+ case SIGN_DEFAULT:
+ /* default is EMSA-PKCS1 using SHA1 */
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return verify_emsa_pkcs1_signature(this, NID_sha1, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return verify_emsa_pkcs1_signature(this, NID_sha256, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return verify_emsa_pkcs1_signature(this, NID_sha384, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return verify_emsa_pkcs1_signature(this, NID_sha512, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return verify_emsa_pkcs1_signature(this, NID_md5, data, signature);
+ default:
+ DBG1("signature scheme %N not supported in RSA",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static bool encrypt(private_openssl_rsa_public_key_t *this, chunk_t crypto, chunk_t *plain)
+{
+ DBG1("RSA public key encryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static size_t get_keysize(private_openssl_rsa_public_key_t *this)
+{
+ return RSA_size(this->rsa);
+}
+
+/**
+ * Implementation of public_key_t.get_id.
+ */
+static identification_t *get_id(private_openssl_rsa_public_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Encodes the public key
+ */
+static chunk_t get_encoding_raw(RSA *rsa)
+{
+ chunk_t enc = chunk_alloc(i2d_RSAPublicKey(rsa, NULL));
+ u_char *p = enc.ptr;
+ i2d_RSAPublicKey(rsa, &p);
+ return enc;
+}
+
+/**
+ * Encodes the public key with the algorithm used
+ */
+static chunk_t get_encoding_with_algo(RSA *rsa)
+{
+ u_char *p;
+ chunk_t enc;
+ X509_PUBKEY *pubkey = X509_PUBKEY_new();
+
+ ASN1_OBJECT_free(pubkey->algor->algorithm);
+ pubkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
+
+ if (pubkey->algor->parameter == NULL ||
+ pubkey->algor->parameter->type != V_ASN1_NULL)
+ {
+ ASN1_TYPE_free(pubkey->algor->parameter);
+ pubkey->algor->parameter = ASN1_TYPE_new();
+ pubkey->algor->parameter->type = V_ASN1_NULL;
+ }
+
+ enc = get_encoding_raw(rsa);
+ M_ASN1_BIT_STRING_set(pubkey->public_key, enc.ptr, enc.len);
+ chunk_free(&enc);
+
+ enc = chunk_alloc(i2d_X509_PUBKEY(pubkey, NULL));
+ p = enc.ptr;
+ i2d_X509_PUBKEY(pubkey, &p);
+ X509_PUBKEY_free(pubkey);
+ return enc;
+}
+
+/*
+ * Implementation of public_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_openssl_rsa_public_key_t *this)
+{
+ return get_encoding_raw(this->rsa);
+}
+
+/**
+ * Implementation of public_key_t.get_ref.
+ */
+static private_openssl_rsa_public_key_t* get_ref(private_openssl_rsa_public_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of openssl_rsa_public_key.destroy.
+ */
+static void destroy(private_openssl_rsa_public_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ if (this->rsa)
+ {
+ RSA_free(this->rsa);
+ }
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Generic private constructor
+ */
+static private_openssl_rsa_public_key_t *openssl_rsa_public_key_create_empty()
+{
+ private_openssl_rsa_public_key_t *this = malloc_thing(private_openssl_rsa_public_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
+ this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
+ this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt;
+ this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
+ this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
+ this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
+
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * Build the RSA key identifier from n and e using SHA1 hashed publicKey(Info).
+ * Also used in openssl_rsa_private_key.c.
+ */
+bool openssl_rsa_public_key_build_id(RSA *rsa, identification_t **keyid,
+ identification_t **keyid_info)
+{
+ chunk_t publicKeyInfo, publicKey, hash;
+ hasher_t *hasher;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher == NULL)
+ {
+ DBG1("SHA1 hash algorithm not supported, unable to use RSA");
+ return FALSE;
+ }
+
+ publicKey = get_encoding_raw(rsa);
+
+ hasher->allocate_hash(hasher, publicKey, &hash);
+ *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
+ chunk_free(&hash);
+
+ publicKeyInfo = get_encoding_with_algo(rsa);
+
+ hasher->allocate_hash(hasher, publicKeyInfo, &hash);
+ *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash);
+ chunk_free(&hash);
+
+ hasher->destroy(hasher);
+ chunk_free(&publicKeyInfo);
+ chunk_free(&publicKey);
+
+ return TRUE;
+}
+
+/**
+ * Create a public key from BIGNUM values, used in openssl_rsa_private_key.c
+ */
+openssl_rsa_public_key_t *openssl_rsa_public_key_create_from_n_e(BIGNUM *n, BIGNUM *e)
+{
+ private_openssl_rsa_public_key_t *this = openssl_rsa_public_key_create_empty();
+
+ this->rsa = RSA_new();
+ this->rsa->n = BN_dup(n);
+ this->rsa->e = BN_dup(e);
+
+ if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+/**
+ * Load a public key from an ASN1 encoded blob
+ */
+static openssl_rsa_public_key_t *load(chunk_t blob)
+{
+ u_char *p = blob.ptr;
+ private_openssl_rsa_public_key_t *this = openssl_rsa_public_key_create_empty();
+
+ this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&p, blob.len);
+
+ chunk_clear(&blob);
+
+ if (!this->rsa)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded public key */
+ openssl_rsa_public_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static openssl_rsa_public_key_t *build(private_builder_t *this)
+{
+ openssl_rsa_public_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *openssl_rsa_public_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_RSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
new file mode 100644
index 000000000..570fb69cb
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
@@ -0,0 +1,49 @@
+/*
+ * 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: openssl_rsa_public_key.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_rsa_public_key openssl_rsa_public_key
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_RSA_PUBLIC_KEY_H_
+#define OPENSSL_RSA_PUBLIC_KEY_H_
+
+typedef struct openssl_rsa_public_key_t openssl_rsa_public_key_t;
+
+#include <credentials/keys/public_key.h>
+
+/**
+ * public_key_t implementation of RSA algorithm using OpenSSL.
+ */
+struct openssl_rsa_public_key_t {
+
+ /**
+ * Implements the public_key_t interface
+ */
+ public_key_t interface;
+};
+
+/**
+ * Create the builder for a public key.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @return builder instance
+ */
+builder_t *openssl_rsa_public_key_builder(key_type_t type);
+
+#endif /*OPENSSL_RSA_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_util.c b/src/libstrongswan/plugins/openssl/openssl_util.c
new file mode 100644
index 000000000..3c4f6595b
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_util.c
@@ -0,0 +1,120 @@
+/*
+ * 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: openssl_util.c 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+#include "openssl_util.h"
+
+#include <debug.h>
+
+#include <openssl/evp.h>
+
+/**
+ * Described in header.
+ */
+bool openssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash)
+{
+ EVP_MD_CTX *ctx;
+ bool ret = FALSE;
+ const EVP_MD *hasher = EVP_get_digestbynid(hash_type);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+
+ ctx = EVP_MD_CTX_create();
+ if (!ctx)
+ {
+ goto error;
+ }
+
+ if (!EVP_DigestInit_ex(ctx, hasher, NULL))
+ {
+ goto error;
+ }
+
+ if (!EVP_DigestUpdate(ctx, data.ptr, data.len))
+ {
+ goto error;
+ }
+
+ *hash = chunk_alloc(hasher->md_size);
+ if (!EVP_DigestFinal_ex(ctx, hash->ptr, NULL))
+ {
+ chunk_free(hash);
+ goto error;
+ }
+
+ ret = TRUE;
+error:
+ if (ctx)
+ {
+ EVP_MD_CTX_destroy(ctx);
+ }
+ return ret;
+}
+
+/**
+ * Described in header.
+ */
+bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk)
+{
+ int offset;
+
+ chunk->len = len * 2;
+ chunk->ptr = malloc(chunk->len);
+ memset(chunk->ptr, 0, chunk->len);
+
+ offset = len - BN_num_bytes(a);
+ if (!BN_bn2bin(a, chunk->ptr + offset))
+ {
+ goto error;
+ }
+
+ offset = len - BN_num_bytes(b);
+ if (!BN_bn2bin(b, chunk->ptr + len + offset))
+ {
+ goto error;
+ }
+
+ return TRUE;
+error:
+ chunk_free(chunk);
+ return FALSE;
+}
+
+
+/**
+ * Described in header.
+ */
+bool openssl_bn_split(chunk_t chunk, BIGNUM *a, BIGNUM *b)
+{
+ int len;
+
+ if ((chunk.len % 2) != 0)
+ {
+ return FALSE;
+ }
+
+ len = chunk.len / 2;
+
+ if (!BN_bin2bn(chunk.ptr, len, a) ||
+ !BN_bin2bn(chunk.ptr + len, len, b))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_util.h b/src/libstrongswan/plugins/openssl/openssl_util.h
new file mode 100644
index 000000000..2dbd5054e
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_util.h
@@ -0,0 +1,70 @@
+/*
+ * 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: openssl_util.h 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+/**
+ * @defgroup openssl_util openssl_util
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_UTIL_H_
+#define OPENSSL_UTIL_H_
+
+#include <library.h>
+#include <openssl/bn.h>
+
+/**
+ * Returns the length in bytes of a field element
+ */
+#define EC_FIELD_ELEMENT_LEN(group) ((EC_GROUP_get_degree(group) + 7) / 8)
+
+/**
+ * Creates a hash of a given type of a chunk of data.
+ *
+ * Note: this function allocates memory for the hash
+ *
+ * @param hash_type NID of the hash
+ * @param data the chunk of data to hash
+ * @param hash chunk that contains the hash
+ * @return TRUE on success, FALSE otherwise
+ */
+bool openssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash);
+
+/**
+ * Concatenates two bignums into a chunk, thereby enfocing the length of
+ * a single BIGNUM, if necessary, by pre-pending it with zeros.
+ *
+ * Note: this function allocates memory for the chunk
+ *
+ * @param len the length of a single BIGNUM
+ * @param a first BIGNUM
+ * @param b second BIGNUM
+ * @param chunk resulting chunk
+ * @return TRUE on success, FALSE otherwise
+ */
+bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk);
+
+/**
+ * Splits a chunk into two bignums of equal binary length.
+ *
+ * @param chunk a chunk that contains the two BIGNUMs
+ * @param a first BIGNUM
+ * @param b second BIGNUM
+ * @return TRUE on success, FALSE otherwise
+ */
+bool openssl_bn_split(chunk_t chunk, BIGNUM *a, BIGNUM *b);
+
+#endif /*OPENSSL_UTIL_H_ @}*/
diff --git a/src/libstrongswan/plugins/padlock/Makefile.am b/src/libstrongswan/plugins/padlock/Makefile.am
new file mode 100644
index 000000000..e2e76e9e6
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/Makefile.am
@@ -0,0 +1,12 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-padlock.la
+
+libstrongswan_padlock_la_SOURCES = padlock_plugin.h padlock_plugin.c \
+ padlock_aes_crypter.c padlock_aes_crypter.h \
+ padlock_sha1_hasher.c padlock_sha1_hasher.h
+libstrongswan_padlock_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in
new file mode 100644
index 000000000..d96b2cf6d
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/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/libstrongswan/plugins/padlock
+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_padlock_la_LIBADD =
+am_libstrongswan_padlock_la_OBJECTS = padlock_plugin.lo \
+ padlock_aes_crypter.lo padlock_sha1_hasher.lo
+libstrongswan_padlock_la_OBJECTS = \
+ $(am_libstrongswan_padlock_la_OBJECTS)
+libstrongswan_padlock_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_padlock_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_padlock_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_padlock_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-padlock.la
+libstrongswan_padlock_la_SOURCES = padlock_plugin.h padlock_plugin.c \
+ padlock_aes_crypter.c padlock_aes_crypter.h \
+ padlock_sha1_hasher.c padlock_sha1_hasher.h
+
+libstrongswan_padlock_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/libstrongswan/plugins/padlock/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/padlock/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-padlock.la: $(libstrongswan_padlock_la_OBJECTS) $(libstrongswan_padlock_la_DEPENDENCIES)
+ $(libstrongswan_padlock_la_LINK) -rpath $(plugindir) $(libstrongswan_padlock_la_OBJECTS) $(libstrongswan_padlock_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/padlock_aes_crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/padlock_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/padlock_sha1_hasher.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/libstrongswan/plugins/padlock/padlock_aes_crypter.c b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c
new file mode 100644
index 000000000..f6f9b3501
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c
@@ -0,0 +1,201 @@
+/*
+ * 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$
+ */
+
+#include "padlock_aes_crypter.h"
+#include <stdio.h>
+
+#define AES_BLOCK_SIZE 16
+#define PADLOCK_ALIGN __attribute__ ((__aligned__(16)))
+
+typedef struct private_padlock_aes_crypter_t private_padlock_aes_crypter_t;
+
+/**
+ * Private data of padlock_aes_crypter_t
+ */
+struct private_padlock_aes_crypter_t {
+
+ /**
+ * Public part of this class.
+ */
+ padlock_aes_crypter_t public;
+
+ /*
+ * the key
+ */
+ chunk_t key;
+};
+
+/**
+ * Control word structure to pass to crypt operations
+ */
+typedef struct {
+ u_int __attribute__ ((__packed__))
+ rounds:4,
+ algo:3,
+ keygen:1,
+ interm:1,
+ encdec:1,
+ ksize:2;
+ /* microcode needs additional bytes for calculation */
+ u_char buf[124];
+} cword;
+
+/**
+ * Invoke the actual de/encryption
+ */
+static void padlock_crypt(void *key, void *ctrl, void *src, void *dst,
+ int count, void *iv)
+{
+ asm volatile(
+ "pushl %%eax\n pushl %%ebx\n pushl %%ecx\n"
+ "pushl %%edx\n pushl %%esi\n pushl %%edi\n"
+ "pushfl\n popfl\n"
+ "movl %0, %%eax\n"
+ "movl %1, %%ebx\n"
+ "movl %2, %%ecx\n"
+ "movl %3, %%edx\n"
+ "movl %4, %%esi\n"
+ "movl %5, %%edi\n"
+ "rep\n"
+ ".byte 0x0f, 0xa7, 0xd0\n"
+ "popl %%edi\n popl %%esi\n popl %%edx\n"
+ "popl %%ecx\n popl %%ebx\n popl %%eax\n"
+ :
+ : "m"(iv),"m"(key), "m"(count), "m"(ctrl), "m"(src), "m"(dst)
+ : "eax", "ecx", "edx", "esi", "edi");
+}
+
+/*
+ * Implementation of crypter_t.crypt
+ */
+static void crypt(private_padlock_aes_crypter_t *this, char *iv,
+ chunk_t src, chunk_t *dst, bool enc)
+{
+ cword cword PADLOCK_ALIGN;
+ u_char key_aligned[256] PADLOCK_ALIGN;
+ u_char iv_aligned[16] PADLOCK_ALIGN;
+
+ memset(&cword, 0, sizeof(cword));
+
+ /* set encryption/decryption flag */
+ cword.encdec = enc;
+ /* calculate rounds and key size */
+ cword.rounds = 10 + (this->key.len - 16) / 4;
+ cword.ksize = (this->key.len - 16) / 8;
+ /* enable autoalign */
+ cword.algo |= 2;
+
+ /* move data to aligned buffers */
+ memcpy(iv_aligned, iv, sizeof(iv_aligned));
+ memcpy(key_aligned, this->key.ptr, this->key.len);
+
+ *dst = chunk_alloc(src.len);
+ padlock_crypt(key_aligned, &cword, src.ptr, dst->ptr,
+ src.len / AES_BLOCK_SIZE, iv_aligned);
+}
+
+/**
+ * Implementation of crypter_t.decrypt.
+ */
+static void decrypt(private_padlock_aes_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst)
+{
+ crypt(this, iv.ptr, data, dst, TRUE);
+}
+
+
+/**
+ * Implementation of crypter_t.encrypt.
+ */
+static void encrypt (private_padlock_aes_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst)
+{
+ crypt(this, iv.ptr, data, dst, FALSE);
+}
+
+/**
+ * Implementation of crypter_t.get_block_size.
+ */
+static size_t get_block_size(private_padlock_aes_crypter_t *this)
+{
+ return AES_BLOCK_SIZE;
+}
+
+/**
+ * Implementation of crypter_t.get_key_size.
+ */
+static size_t get_key_size(private_padlock_aes_crypter_t *this)
+{
+ return this->key.len;
+}
+
+/**
+ * Implementation of crypter_t.set_key.
+ */
+static void set_key(private_padlock_aes_crypter_t *this, chunk_t key)
+{
+ memcpy(this->key.ptr, key.ptr, min(key.len, this->key.len));
+}
+
+/**
+ * Implementation of crypter_t.destroy and aes_crypter_t.destroy.
+ */
+static void destroy (private_padlock_aes_crypter_t *this)
+{
+ free(this->key.ptr);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+padlock_aes_crypter_t *padlock_aes_crypter_create(encryption_algorithm_t algo,
+ size_t key_size)
+{
+ private_padlock_aes_crypter_t *this;
+
+ if (algo != ENCR_AES_CBC)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_padlock_aes_crypter_t);
+
+ switch (key_size)
+ {
+ case 16: /* AES 128 */
+ break;
+ case 24: /* AES-192 */
+ case 32: /* AES-256 */
+ /* These need an expanded key, currently not supported, FALL */
+ default:
+ free(this);
+ return NULL;
+ }
+
+ this->key = chunk_alloc(key_size);
+
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
+ this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
+ this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
+ this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/padlock/padlock_aes_crypter.h b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.h
new file mode 100644
index 000000000..e8b01633d
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.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.
+ */
+
+/**
+ * @defgroup padlock_aes_crypter padlock_aes_crypter
+ * @{ @ingroup padlock_p
+ */
+
+#ifndef PADLOCK_AES_CRYPTER_H_
+#define PADLOCK_AES_CRYPTER_H_
+
+typedef struct padlock_aes_crypter_t padlock_aes_crypter_t;
+
+#include <crypto/crypters/crypter.h>
+
+/**
+ * Implementation of AES-128 using VIA Padlock.
+ */
+struct padlock_aes_crypter_t {
+
+ /**
+ * The crypter_t interface.
+ */
+ crypter_t crypter_interface;
+};
+
+/**
+ * Constructor to create padlock_aes_crypter_t.
+ *
+ * @param key_size key size in bytes, currently supports only 16.
+ * @param algo algorithm to implement, must be ENCR_AES_CBC
+ * @return padlock_aes_crypter_t, NULL if not supported
+ */
+padlock_aes_crypter_t *padlock_aes_crypter_create(encryption_algorithm_t algo,
+ size_t key_size);
+
+#endif /* PADLOCK_AES_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/padlock/padlock_plugin.c b/src/libstrongswan/plugins/padlock/padlock_plugin.c
new file mode 100644
index 000000000..822acc4a2
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_plugin.c
@@ -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$
+ */
+
+#include "padlock_plugin.h"
+
+#include <library.h>
+#include "padlock_aes_crypter.h"
+#include "padlock_sha1_hasher.h"
+
+typedef struct private_padlock_plugin_t private_padlock_plugin_t;
+
+/**
+ * private data of aes_plugin
+ */
+struct private_padlock_plugin_t {
+
+ /**
+ * public functions
+ */
+ padlock_plugin_t public;
+};
+
+/**
+ * Implementation of aes_plugin_t.destroy
+ */
+static void destroy(private_padlock_plugin_t *this)
+{
+ lib->crypto->remove_crypter(lib->crypto,
+ (crypter_constructor_t)padlock_aes_crypter_create);
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)padlock_sha1_hasher_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_padlock_plugin_t *this = malloc_thing(private_padlock_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
+ (crypter_constructor_t)padlock_aes_crypter_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
+ (hasher_constructor_t)padlock_sha1_hasher_create);
+
+ return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/padlock/padlock_plugin.h b/src/libstrongswan/plugins/padlock/padlock_plugin.h
new file mode 100644
index 000000000..7e013a5f7
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup padlock_p padlock
+ * @ingroup plugins
+ *
+ * @defgroup padlock_plugin padlock_plugin
+ * @{ @ingroup padlock_p
+ */
+
+#ifndef PADLOCK_PLUGIN_H_
+#define PADLOCK_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct padlock_plugin_t padlock_plugin_t;
+
+/**
+ * Plugin implementing VIA Padlock crypto functions
+ */
+struct padlock_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a padlock_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* PADLOCK_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c
new file mode 100644
index 000000000..4ac5ddf4d
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c
@@ -0,0 +1,177 @@
+/*
+ * 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$
+ */
+
+#include <string.h>
+#include <arpa/inet.h>
+#include <byteswap.h>
+
+#include "padlock_sha1_hasher.h"
+
+#define PADLOCK_ALIGN __attribute__ ((__aligned__(16)))
+
+typedef struct private_padlock_sha1_hasher_t private_padlock_sha1_hasher_t;
+
+/**
+ * Private data structure with hasing context.
+ */
+struct private_padlock_sha1_hasher_t {
+ /**
+ * Public interface for this hasher.
+ */
+ padlock_sha1_hasher_t public;
+
+ /**
+ * data collected to hash
+ */
+ chunk_t data;
+};
+
+/**
+ * Invoke the actual padlock sha1() operation
+ */
+static void padlock_sha1(int len, u_char *in, u_char *out)
+{
+ /* rep xsha1 */
+ asm volatile (
+ ".byte 0xf3, 0x0f, 0xa6, 0xc8"
+ : "+S"(in), "+D"(out)
+ : "c"(len), "a"(0));
+}
+
+/**
+ * sha1() a buffer of data into digest
+ */
+static void sha1(chunk_t data, u_int32_t *digest)
+{
+ u_int32_t hash[128] PADLOCK_ALIGN;
+
+ hash[0] = 0x67452301;
+ hash[1] = 0xefcdab89;
+ hash[2] = 0x98badcfe;
+ hash[3] = 0x10325476;
+ hash[4] = 0xc3d2e1f0;
+
+ padlock_sha1(data.len, data.ptr, (u_char*)hash);
+
+ digest[0] = bswap_32(hash[0]);
+ digest[1] = bswap_32(hash[1]);
+ digest[2] = bswap_32(hash[2]);
+ digest[3] = bswap_32(hash[3]);
+ digest[4] = bswap_32(hash[4]);
+}
+
+/**
+ * append data to the to-be-hashed buffer
+ */
+static void append_data(private_padlock_sha1_hasher_t *this, chunk_t data)
+{
+ this->data.ptr = realloc(this->data.ptr, this->data.len + data.len);
+ memcpy(this->data.ptr + this->data.len, data.ptr, data.len);
+ this->data.len += data.len;
+}
+
+/**
+ * Implementation of hasher_t.reset.
+ */
+static void reset(private_padlock_sha1_hasher_t *this)
+{
+ chunk_free(&this->data);
+}
+
+/**
+ * Implementation of hasher_t.get_hash.
+ */
+static void get_hash(private_padlock_sha1_hasher_t *this, chunk_t chunk,
+ u_int8_t *hash)
+{
+ if (hash)
+ {
+ if (this->data.len)
+ {
+ append_data(this, chunk);
+ sha1(this->data, (u_int32_t*)hash);
+ }
+ else
+ { /* hash directly if no previous data found */
+ sha1(chunk, (u_int32_t*)hash);
+ }
+ reset(this);
+ }
+ else
+ {
+ append_data(this, chunk);
+ }
+}
+
+/**
+ * Implementation of hasher_t.allocate_hash.
+ */
+static void allocate_hash(private_padlock_sha1_hasher_t *this, chunk_t chunk,
+ chunk_t *hash)
+{
+ if (hash)
+ {
+ *hash = chunk_alloc(HASH_SIZE_SHA1);
+ get_hash(this, chunk, hash->ptr);
+ }
+ else
+ {
+ get_hash(this, chunk, NULL);
+ }
+}
+
+/**
+ * Implementation of hasher_t.get_hash_size.
+ */
+static size_t get_hash_size(private_padlock_sha1_hasher_t *this)
+{
+ return HASH_SIZE_SHA1;
+}
+
+/**
+ * Implementation of hasher_t.destroy.
+ */
+static void destroy(private_padlock_sha1_hasher_t *this)
+{
+ free(this->data.ptr);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+padlock_sha1_hasher_t *padlock_sha1_hasher_create(hash_algorithm_t algo)
+{
+ private_padlock_sha1_hasher_t *this;
+
+ if (algo != HASH_SHA1)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_padlock_sha1_hasher_t);
+ this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
+ this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
+ this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
+ this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
+ this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
+
+ this->data = chunk_empty;
+
+ return &(this->public);
+}
diff --git a/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h
new file mode 100644
index 000000000..6855b827f
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup sha1_hasher sha1_hasher
+ * @{ @ingroup sha1_p
+ */
+
+#ifndef PADLOCK_SHA1_HASHER_H_
+#define PADLOCK_SHA1_HASHER_H_
+
+typedef struct padlock_sha1_hasher_t padlock_sha1_hasher_t;
+
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Implementation of hasher_t interface using the SHA1 algorithm.
+ */
+struct padlock_sha1_hasher_t {
+
+ /**
+ * Implements hasher_t interface.
+ */
+ hasher_t hasher_interface;
+};
+
+/**
+ * Creates a new sha1_hasher_t.
+ *
+ * @param algo algorithm, must be HASH_SHA1
+ * @return sha1_hasher_t object
+ */
+padlock_sha1_hasher_t *padlock_sha1_hasher_create(hash_algorithm_t algo);
+
+#endif /*SHA1_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/plugin.h b/src/libstrongswan/plugins/plugin.h
new file mode 100644
index 000000000..cf0b728a3
--- /dev/null
+++ b/src/libstrongswan/plugins/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.
+ */
+
+/**
+ * @defgroup plugin plugin
+ * @{ @ingroup plugins
+ */
+
+#ifndef PLUGIN_H_
+#define PLUGIN_H_
+
+typedef struct plugin_t plugin_t;
+
+/**
+ * Interface definition of a plugin.
+ */
+struct plugin_t {
+
+ /**
+ * Destroy a plugin instance.
+ */
+ void (*destroy)(plugin_t *this);
+};
+
+
+/**
+ * Plugin constructor function definiton.
+ *
+ * Each plugin has a constructor functions. This function is called on daemon
+ * startup to initialize each plugin.
+ * The plugin function is named plugin_create().
+ *
+ * @return plugin_t instance
+ */
+typedef plugin_t *(*plugin_constructor_t)(void);
+
+#endif /* PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c
new file mode 100644
index 000000000..4c5095e4a
--- /dev/null
+++ b/src/libstrongswan/plugins/plugin_loader.c
@@ -0,0 +1,193 @@
+/*
+ * 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: plugin_loader.c 4108 2008-06-25 14:53:49Z martin $
+ */
+
+#define _GNU_SOURCE
+#include "plugin_loader.h"
+
+#include <string.h>
+#include <dlfcn.h>
+#include <limits.h>
+#include <stdio.h>
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <plugins/plugin.h>
+
+typedef struct private_plugin_loader_t private_plugin_loader_t;
+
+/**
+ * private data of plugin_loader
+ */
+struct private_plugin_loader_t {
+
+ /**
+ * public functions
+ */
+ plugin_loader_t public;
+
+ /**
+ * list of loaded plugins
+ */
+ linked_list_t *plugins;
+
+ /**
+ * names of loaded plugins
+ */
+ linked_list_t *names;
+};
+
+/**
+ * load a single plugin
+ */
+static plugin_t* load_plugin(private_plugin_loader_t *this,
+ char *path, char *name)
+{
+ char file[PATH_MAX];
+ void *handle;
+ plugin_t *plugin;
+ plugin_constructor_t constructor;
+
+ snprintf(file, sizeof(file), "%s/libstrongswan-%s.so", path, name);
+
+ handle = dlopen(file, RTLD_LAZY);
+ if (handle == NULL)
+ {
+ DBG1("loading plugin '%s' failed: %s", name, dlerror());
+ return NULL;
+ }
+ constructor = dlsym(handle, "plugin_create");
+ if (constructor == NULL)
+ {
+ DBG1("loading plugin '%s' failed: no plugin_create() function", name);
+ dlclose(handle);
+ return NULL;
+ }
+ plugin = constructor();
+ if (plugin == NULL)
+ {
+ DBG1("loading plugin '%s' failed: plugin_create() returned NULL", name);
+ dlclose(handle);
+ return NULL;
+ }
+ DBG2("plugin '%s' loaded successfully", name);
+
+ /* we do not store or free dlopen() handles, leak_detective requires
+ * the modules to keep loaded until leak report */
+ return plugin;
+}
+
+/**
+ * Implementation of plugin_loader_t.load_plugins.
+ */
+static int load(private_plugin_loader_t *this, char *path, char *list)
+{
+ plugin_t *plugin;
+ char *pos;
+ int count = 0;
+
+ list = strdupa(list);
+ while (TRUE)
+ {
+ /* eat any whitespace in front */
+ while (*list == ' ')
+ {
+ list++;
+ }
+ /* have we reached the end of the list? */
+ if (!*list)
+ {
+ break;
+ }
+ pos = strchr(list, ' ');
+ if (pos)
+ {
+ *pos++ = '\0';
+ }
+ plugin = load_plugin(this, path, list);
+ if (plugin)
+ { /* insert in front to destroy them in reverse order */
+ this->plugins->insert_last(this->plugins, plugin);
+ this->names->insert_last(this->names, strdup(list));
+ count++;
+ }
+ if (pos)
+ {
+ list = pos;
+ }
+ else
+ {
+ break;
+ }
+ }
+ return count;
+}
+
+/**
+ * Implementation of plugin_loader_t.unload
+ */
+static void unload(private_plugin_loader_t *this)
+{
+ plugin_t *plugin;
+ char *name;
+
+ while (this->plugins->remove_first(this->plugins,
+ (void**)&plugin) == SUCCESS)
+ {
+ plugin->destroy(plugin);
+ }
+ while (this->names->remove_first(this->names, (void**)&name) == SUCCESS)
+ {
+ free(name);
+ }
+}
+
+/**
+ * Implementation of plugin_loader_t.create_plugin_enumerator
+ */
+static enumerator_t* create_plugin_enumerator(private_plugin_loader_t *this)
+{
+ return this->names->create_enumerator(this->names);
+}
+
+/**
+ * Implementation of plugin_loader_t.destroy
+ */
+static void destroy(private_plugin_loader_t *this)
+{
+ this->plugins->destroy_offset(this->plugins, offsetof(plugin_t, destroy));
+ this->names->destroy_function(this->names, free);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_loader_t *plugin_loader_create()
+{
+ private_plugin_loader_t *this = malloc_thing(private_plugin_loader_t);
+
+ this->public.load = (int(*)(plugin_loader_t*, char *path, char *prefix))load;
+ this->public.unload = (void(*)(plugin_loader_t*))unload;
+ this->public.create_plugin_enumerator = (enumerator_t*(*)(plugin_loader_t*))create_plugin_enumerator;
+ this->public.destroy = (void(*)(plugin_loader_t*))destroy;
+
+ this->plugins = linked_list_create();
+ this->names = linked_list_create();
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/plugin_loader.h b/src/libstrongswan/plugins/plugin_loader.h
new file mode 100644
index 000000000..bd24e7558
--- /dev/null
+++ b/src/libstrongswan/plugins/plugin_loader.h
@@ -0,0 +1,67 @@
+/*
+ * 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 plugin_loader plugin_loader
+ * @{ @ingroup plugin
+ */
+
+#ifndef PLUGIN_LOADER_H_
+#define PLUGIN_LOADER_H_
+
+typedef struct plugin_loader_t plugin_loader_t;
+
+#include <utils/enumerator.h>
+
+/**
+ * The plugin_loader loads plugins from a directory and initializes them
+ */
+struct plugin_loader_t {
+
+ /**
+ * Load a list of plugins from a directory.
+ *
+ * @param path path containing loadable plugins
+ * @param list space separated list of plugins to load
+ * @return number of successfully loaded plugins
+ */
+ int (*load)(plugin_loader_t *this, char *path, char *list);
+
+ /**
+ * Unload all loaded plugins.
+ */
+ void (*unload)(plugin_loader_t *this);
+
+ /**
+ * Create an enumerator over all loaded plugin names.
+ *
+ * @return enumerator over char*
+ */
+ enumerator_t* (*create_plugin_enumerator)(plugin_loader_t *this);
+
+ /**
+ * Unload loaded plugins, destroy plugin_loader instance.
+ */
+ void (*destroy)(plugin_loader_t *this);
+};
+
+/**
+ * Create a plugin_loader instance.
+ *
+ * @return plugin loader instance
+ */
+plugin_loader_t *plugin_loader_create();
+
+#endif /* PLUGIN_LOADER_H_ @}*/
diff --git a/src/libstrongswan/plugins/pubkey/Makefile.am b/src/libstrongswan/plugins/pubkey/Makefile.am
new file mode 100644
index 000000000..3b512614f
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/Makefile.am
@@ -0,0 +1,13 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-pubkey.la
+
+libstrongswan_pubkey_la_SOURCES = pubkey_plugin.h pubkey_plugin.c \
+ pubkey_cert.h pubkey_cert.c\
+ pubkey_public_key.h pubkey_public_key.c
+
+libstrongswan_pubkey_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in
new file mode 100644
index 000000000..ced339d15
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/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/libstrongswan/plugins/pubkey
+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_pubkey_la_LIBADD =
+am_libstrongswan_pubkey_la_OBJECTS = pubkey_plugin.lo pubkey_cert.lo \
+ pubkey_public_key.lo
+libstrongswan_pubkey_la_OBJECTS = \
+ $(am_libstrongswan_pubkey_la_OBJECTS)
+libstrongswan_pubkey_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_pubkey_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_pubkey_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_pubkey_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-pubkey.la
+libstrongswan_pubkey_la_SOURCES = pubkey_plugin.h pubkey_plugin.c \
+ pubkey_cert.h pubkey_cert.c\
+ pubkey_public_key.h pubkey_public_key.c
+
+libstrongswan_pubkey_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/libstrongswan/plugins/pubkey/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/pubkey/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-pubkey.la: $(libstrongswan_pubkey_la_OBJECTS) $(libstrongswan_pubkey_la_DEPENDENCIES)
+ $(libstrongswan_pubkey_la_LINK) -rpath $(plugindir) $(libstrongswan_pubkey_la_OBJECTS) $(libstrongswan_pubkey_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey_cert.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey_public_key.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/libstrongswan/plugins/pubkey/pubkey_cert.c b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
new file mode 100644
index 000000000..63dffb47b
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
@@ -0,0 +1,284 @@
+/*
+ * 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 "pubkey_cert.h"
+
+#include <debug.h>
+
+typedef struct private_pubkey_cert_t private_pubkey_cert_t;
+
+/**
+ * private data of pubkey_cert
+ */
+struct private_pubkey_cert_t {
+
+ /**
+ * public functions
+ */
+ pubkey_cert_t public;
+
+ /**
+ * wrapped public key
+ */
+ public_key_t *key;
+
+ /**
+ * dummy issuer id, ID_ANY
+ */
+ identification_t *issuer;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_pubkey_cert_t *this)
+{
+ return CERT_TRUSTED_PUBKEY;
+}
+
+/**
+ * Implementation of certificate_t.get_subject
+ */
+static identification_t* get_subject(private_pubkey_cert_t *this)
+{
+ return this->key->get_id(this->key, ID_PUBKEY_SHA1);
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_pubkey_cert_t *this)
+{
+ return this->issuer;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_subject(private_pubkey_cert_t *this,
+ identification_t *subject)
+{
+ identification_t *id;
+
+ id = this->key->get_id(this->key, subject->get_type(subject));
+ if (id)
+ {
+ return id->matches(id, subject);
+ }
+ return ID_MATCH_NONE;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_issuer(private_pubkey_cert_t *this,
+ identification_t *issuer)
+{
+ return ID_MATCH_NONE;
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_pubkey_cert_t *this, certificate_t *other)
+{
+ if (this == (private_pubkey_cert_t*)other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != CERT_TRUSTED_PUBKEY)
+ {
+ return FALSE;
+ }
+ return other->has_subject(other, this->key->get_id(this->key, ID_PUBKEY_SHA1));
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_pubkey_cert_t *this, certificate_t *issuer)
+{
+ return equals(this, issuer);
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_pubkey_cert_t *this)
+{
+ this->key->get_ref(this->key);
+ return this->key;
+}
+/**
+ * Implementation of certificate_t.get_validity.
+ */
+static bool get_validity(private_pubkey_cert_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ if (not_before)
+ {
+ *not_before = 0;
+ }
+ if (not_after)
+ {
+ *not_after = ~0;
+ }
+ return TRUE;
+}
+
+/**
+ * Implementation of certificate_t.is_newer.
+ */
+static bool is_newer(certificate_t *this, certificate_t *that)
+{
+ return FALSE;
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_pubkey_cert_t *this)
+{
+ return this->key->get_encoding(this->key);
+}
+
+/**
+ * Implementation of certificate_t.get_ref
+ */
+static private_pubkey_cert_t* get_ref(private_pubkey_cert_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of pubkey_cert_t.destroy
+ */
+static void destroy(private_pubkey_cert_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->issuer->destroy(this->issuer);
+ this->key->destroy(this->key);
+ free(this);
+ }
+}
+
+/*
+ * see header file
+ */
+static pubkey_cert_t *pubkey_cert_create(public_key_t *key)
+{
+ private_pubkey_cert_t *this = malloc_thing(private_pubkey_cert_t);
+
+ this->public.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
+ this->public.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
+ this->public.interface.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.interface.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
+ this->public.interface.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
+ this->public.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
+ this->public.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(certificate_t *this))destroy;
+
+ this->ref = 1;
+ this->key = key;
+ this->issuer = identification_create_from_encoding(ID_ANY, chunk_empty);
+
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded public key */
+ pubkey_cert_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static pubkey_cert_t *build(private_builder_t *this)
+{
+ pubkey_cert_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_PUBLIC_KEY:
+ {
+ va_start(args, part);
+ this->key = pubkey_cert_create(va_arg(args, public_key_t*));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *pubkey_cert_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_TRUSTED_PUBKEY)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.h b/src/libstrongswan/plugins/pubkey/pubkey_cert.h
new file mode 100644
index 000000000..71ffe5099
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.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 pubkey_cert pubkey_cert
+ * @{ @ingroup certificates
+ */
+
+#ifndef PUBKEY_CERT_H_
+#define PUBKEY_CERT_H_
+
+#include <credentials/certificates/certificate.h>
+
+typedef struct pubkey_cert_t pubkey_cert_t;
+
+/**
+ * A trusted public key wrapped into certificate of type CERT_TRUSTED_PUBKEY.
+ */
+struct pubkey_cert_t {
+
+ /**
+ * Implements certificate_t.
+ */
+ certificate_t interface;
+};
+
+/**
+ * Create the builder for a trusted public key.
+ *
+ * The builders add() function takes BUILD_PUBLIC_KEY to enwrap.
+ *
+ * @param type type of the certificate, must be CERT_pubkey_cert
+ * @return builder instance
+ */
+builder_t *pubkey_cert_builder(certificate_type_t type);
+
+#endif /* PUBKEY_CERT_H_ @}*/
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_plugin.c b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c
new file mode 100644
index 000000000..dd7ac6fd1
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c
@@ -0,0 +1,65 @@
+/*
+ * 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 "pubkey_plugin.h"
+
+#include <library.h>
+#include "pubkey_cert.h"
+#include "pubkey_public_key.h"
+
+typedef struct private_pubkey_plugin_t private_pubkey_plugin_t;
+
+/**
+ * private data of pubkey_plugin
+ */
+struct private_pubkey_plugin_t {
+
+ /**
+ * public functions
+ */
+ pubkey_plugin_t public;
+};
+
+/**
+ * Implementation of pubkey_plugin_t.pubkeytroy
+ */
+static void destroy(private_pubkey_plugin_t *this)
+{
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)pubkey_cert_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)pubkey_public_key_builder);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_pubkey_plugin_t *this = malloc_thing(private_pubkey_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
+ (builder_constructor_t)pubkey_cert_builder);
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+ (builder_constructor_t)pubkey_public_key_builder);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_plugin.h b/src/libstrongswan/plugins/pubkey/pubkey_plugin.h
new file mode 100644
index 000000000..64d0995fc
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup pubkey_p pubkey
+ * @ingroup plugins
+ *
+ * @defgroup pubkey_plugin pubkey_plugin
+ * @{ @ingroup pubkey_p
+ */
+
+#ifndef PUBKEY_PLUGIN_H_
+#define PUBKEY_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct pubkey_plugin_t pubkey_plugin_t;
+
+/**
+ * Plugin implementing CERT_TRUSTED_PUBKEY certificate type.
+ */
+struct pubkey_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a pubkey_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* PUBKEY_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_public_key.c b/src/libstrongswan/plugins/pubkey/pubkey_public_key.c
new file mode 100644
index 000000000..0527ed758
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_public_key.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2000-2008 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: pubkey_public_key.c 4059 2008-06-11 14:10:02Z martin $
+ */
+
+#include "pubkey_public_key.h"
+
+#include <debug.h>
+#include <asn1/pem.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+
+/**
+ * ASN.1 definition of a subjectPublicKeyInfo structure
+ */
+static const asn1Object_t pkinfoObjects[] = {
+ { 0, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "algorithm", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 1, "subjectPublicKey", ASN1_BIT_STRING, ASN1_BODY }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM 1
+#define PKINFO_SUBJECT_PUBLIC_KEY 2
+
+
+/**
+ * Load a public key from an ASN1 encoded blob
+ */
+static public_key_t *load(chunk_t blob)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ public_key_t *key = NULL;
+ key_type_t type = KEY_ANY;
+
+ parser = asn1_parser_create(pkinfoObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM:
+ {
+ int oid = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
+
+ if (oid == OID_RSA_ENCRYPTION)
+ {
+ type = KEY_RSA;
+ }
+ else if (oid == OID_EC_PUBLICKEY)
+ {
+ /* we need the whole subjectPublicKeyInfo for EC public keys */
+ key = lib->creds->create(lib->creds,
+ CRED_PUBLIC_KEY, KEY_ECDSA, BUILD_BLOB_ASN1_DER,
+ chunk_clone(blob), BUILD_END);
+ goto end;
+ }
+ else
+ {
+ /* key type not supported */
+ goto end;
+ }
+ break;
+ }
+ case PKINFO_SUBJECT_PUBLIC_KEY:
+ if (object.len > 0 && *object.ptr == 0x00)
+ {
+ /* skip initial bit string octet defining 0 unused bits */
+ object = chunk_skip(object, 1);
+ }
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type,
+ BUILD_BLOB_ASN1_DER, chunk_clone(object),
+ BUILD_END);
+ break;
+ }
+ }
+
+end:
+ parser->destroy(parser);
+ free(blob.ptr);
+ return key;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded public key */
+ public_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static public_key_t *build(private_builder_t *this)
+{
+ public_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+ va_start(args, part);
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ this->key = load(va_arg(args, chunk_t));
+ break;
+ }
+ case BUILD_BLOB_ASN1_PEM:
+ {
+ bool pgp;
+ char *pem;
+ chunk_t blob;
+
+ pem = va_arg(args, char *);
+ blob = chunk_clone(chunk_create(pem, strlen(pem)));
+ if (pem_to_bin(&blob, &chunk_empty, &pgp))
+ {
+ this->key = load(chunk_clone(blob));
+ }
+ free(blob.ptr);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+ va_end(args);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *pubkey_public_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_ANY)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_public_key.h b/src/libstrongswan/plugins/pubkey/pubkey_public_key.h
new file mode 100644
index 000000000..914ad74e9
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_public_key.h
@@ -0,0 +1,36 @@
+/*
+ * 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: pubkey_public_key.h 3961 2008-05-15 12:33:00Z tobias $
+ */
+
+/**
+ * @defgroup pubkey_public_key pubkey_public_key
+ * @{ @ingroup pubkey_p
+ */
+
+#ifndef PUBKEY_PUBLIC_KEY_H_
+#define PUBKEY_PUBLIC_KEY_H_
+
+#include <credentials/keys/public_key.h>
+
+/**
+ * Create the builder for a generic public key.
+ *
+ * @param type type of the key, must be KEY_ANY
+ * @return builder instance
+ */
+builder_t *pubkey_public_key_builder(key_type_t type);
+
+#endif /*PUBKEY_RSA_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/random/Makefile.am b/src/libstrongswan/plugins/random/Makefile.am
new file mode 100644
index 000000000..8b61d7094
--- /dev/null
+++ b/src/libstrongswan/plugins/random/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-random.la
+
+libstrongswan_random_la_SOURCES = random_plugin.h random_plugin.c \
+ random_rng.c random_rng.h
+libstrongswan_random_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in
new file mode 100644
index 000000000..c4baa04b3
--- /dev/null
+++ b/src/libstrongswan/plugins/random/Makefile.in
@@ -0,0 +1,497 @@
+# 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/libstrongswan/plugins/random
+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_random_la_LIBADD =
+am_libstrongswan_random_la_OBJECTS = random_plugin.lo random_rng.lo
+libstrongswan_random_la_OBJECTS = \
+ $(am_libstrongswan_random_la_OBJECTS)
+libstrongswan_random_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_random_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_random_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_random_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-random.la
+libstrongswan_random_la_SOURCES = random_plugin.h random_plugin.c \
+ random_rng.c random_rng.h
+
+libstrongswan_random_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/libstrongswan/plugins/random/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/random/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-random.la: $(libstrongswan_random_la_OBJECTS) $(libstrongswan_random_la_DEPENDENCIES)
+ $(libstrongswan_random_la_LINK) -rpath $(plugindir) $(libstrongswan_random_la_OBJECTS) $(libstrongswan_random_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random_rng.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/libstrongswan/plugins/random/random_plugin.c b/src/libstrongswan/plugins/random/random_plugin.c
new file mode 100644
index 000000000..3eff81ee0
--- /dev/null
+++ b/src/libstrongswan/plugins/random/random_plugin.c
@@ -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$
+ */
+
+#include "random_plugin.h"
+
+#include <library.h>
+#include "random_rng.h"
+
+typedef struct private_random_plugin_t private_random_plugin_t;
+
+/**
+ * private data of random_plugin
+ */
+struct private_random_plugin_t {
+
+ /**
+ * public functions
+ */
+ random_plugin_t public;
+};
+
+/**
+ * Implementation of random_plugin_t.gmptroy
+ */
+static void destroy(private_random_plugin_t *this)
+{
+ lib->crypto->remove_rng(lib->crypto,
+ (rng_constructor_t)random_rng_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_random_plugin_t *this = malloc_thing(private_random_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_rng(lib->crypto, RNG_STRONG,
+ (rng_constructor_t)random_rng_create);
+ lib->crypto->add_rng(lib->crypto, RNG_REAL,
+ (rng_constructor_t)random_rng_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/random/random_plugin.h b/src/libstrongswan/plugins/random/random_plugin.h
new file mode 100644
index 000000000..9e8b99387
--- /dev/null
+++ b/src/libstrongswan/plugins/random/random_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup random_p random
+ * @ingroup plugins
+ *
+ * @defgroup random_plugin random_plugin
+ * @{ @ingroup random_p
+ */
+
+#ifndef RANDOM_PLUGIN_H_
+#define RANDOM_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct random_plugin_t random_plugin_t;
+
+/**
+ * Plugin implementing a RNG reading from /dev/[u]random.
+ */
+struct random_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a random_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* RANDOM_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/random/random_rng.c b/src/libstrongswan/plugins/random/random_rng.c
new file mode 100644
index 000000000..1aadc88bd
--- /dev/null
+++ b/src/libstrongswan/plugins/random/random_rng.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2005-2008 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$
+ */
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "random_rng.h"
+
+#ifndef DEV_RANDOM
+# define DEV_RANDOM "/dev/random"
+#endif
+
+#ifndef DEV_URANDOM
+# define DEV_URANDOM "/dev/urandom"
+#endif
+
+typedef struct private_random_rng_t private_random_rng_t;
+
+/**
+ * Private data of an random_rng_t object.
+ */
+struct private_random_rng_t {
+
+ /**
+ * Public random_rng_t interface.
+ */
+ random_rng_t public;
+
+ /**
+ * random device, depends on quality
+ */
+ int dev;
+
+ /**
+ * file we read random bytes from
+ */
+ char *file;
+};
+
+/**
+ * Implementation of random_rng_t.get_bytes.
+ */
+static void get_bytes(private_random_rng_t *this, size_t bytes,
+ u_int8_t *buffer)
+{
+ size_t done, got;
+
+ done = 0;
+
+ while (done < bytes)
+ {
+ got = read(this->dev, buffer + done, bytes - done);
+ if (got <= 0)
+ {
+ DBG1("reading from \"%s\" failed: %s, retrying...",
+ this->file, strerror(errno));
+ close(this->dev);
+ sleep(1);
+ this->dev = open(this->file, 0);
+ }
+ done += got;
+ }
+}
+
+/**
+ * Implementation of random_rng_t.allocate_bytes.
+ */
+static void allocate_bytes(private_random_rng_t *this, size_t bytes,
+ chunk_t *chunk)
+{
+ *chunk = chunk_alloc(bytes);
+ get_bytes(this, chunk->len, chunk->ptr);
+}
+
+/**
+ * Implementation of random_rng_t.destroy.
+ */
+static void destroy(private_random_rng_t *this)
+{
+ close(this->dev);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+random_rng_t *random_rng_create(rng_quality_t quality)
+{
+ private_random_rng_t *this = malloc_thing(private_random_rng_t);
+
+ /* public functions */
+ this->public.rng.get_bytes = (void (*) (rng_t *, size_t, u_int8_t*)) get_bytes;
+ this->public.rng.allocate_bytes = (void (*) (rng_t *, size_t, chunk_t*)) allocate_bytes;
+ this->public.rng.destroy = (void (*) (rng_t *))destroy;
+
+ if (quality == RNG_REAL)
+ {
+ this->file = DEV_RANDOM;
+ }
+ else
+ {
+ this->file = DEV_URANDOM;
+ }
+
+ this->dev = open(this->file, 0);
+ if (this->dev < 0)
+ {
+ DBG1("opening \"%s\" failed: %s", this->file, strerror(errno));
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/random/random_rng.h b/src/libstrongswan/plugins/random/random_rng.h
new file mode 100644
index 000000000..7f82353d8
--- /dev/null
+++ b/src/libstrongswan/plugins/random/random_rng.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 random_rng random_rng
+ * @{ @ingroup utils
+ */
+
+#ifndef RANDOM_RNG_H_
+#define RANDOM_RNG_H_
+
+typedef struct random_rng_t random_rng_t;
+
+#include <library.h>
+
+/**
+ * rng_t implementation on top of /dev/[u]random
+ */
+struct random_rng_t {
+
+ /**
+ * Implements rng_t.
+ */
+ rng_t rng;
+};
+
+/**
+ * Creates an random_rng_t instance.
+ *
+ * @param quality required quality of randomness
+ * @return created random_rng_t
+ */
+random_rng_t *random_rng_create(rng_quality_t quality);
+
+#endif /*RANDOM_RNG_H_ @} */
diff --git a/src/libstrongswan/plugins/sha1/Makefile.am b/src/libstrongswan/plugins/sha1/Makefile.am
new file mode 100644
index 000000000..299e85083
--- /dev/null
+++ b/src/libstrongswan/plugins/sha1/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-sha1.la
+
+libstrongswan_sha1_la_SOURCES = sha1_plugin.h sha1_plugin.c sha1_hasher.c sha1_hasher.h
+libstrongswan_sha1_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in
new file mode 100644
index 000000000..b57c46aee
--- /dev/null
+++ b/src/libstrongswan/plugins/sha1/Makefile.in
@@ -0,0 +1,494 @@
+# 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/libstrongswan/plugins/sha1
+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_sha1_la_LIBADD =
+am_libstrongswan_sha1_la_OBJECTS = sha1_plugin.lo sha1_hasher.lo
+libstrongswan_sha1_la_OBJECTS = $(am_libstrongswan_sha1_la_OBJECTS)
+libstrongswan_sha1_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_sha1_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_sha1_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_sha1_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-sha1.la
+libstrongswan_sha1_la_SOURCES = sha1_plugin.h sha1_plugin.c sha1_hasher.c sha1_hasher.h
+libstrongswan_sha1_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/libstrongswan/plugins/sha1/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/sha1/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-sha1.la: $(libstrongswan_sha1_la_OBJECTS) $(libstrongswan_sha1_la_DEPENDENCIES)
+ $(libstrongswan_sha1_la_LINK) -rpath $(plugindir) $(libstrongswan_sha1_la_OBJECTS) $(libstrongswan_sha1_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1_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/libstrongswan/crypto/hashers/sha1_hasher.c b/src/libstrongswan/plugins/sha1/sha1_hasher.c
index 6a86937ae..c496be8f4 100644
--- a/src/libstrongswan/crypto/hashers/sha1_hasher.c
+++ b/src/libstrongswan/plugins/sha1/sha1_hasher.c
@@ -1,10 +1,3 @@
-/**
- * @file sha1_hasher.c
- *
- * @brief Implementation of hasher_sha_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -22,9 +15,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: sha1_hasher.c 3619 2008-03-19 14:02:52Z martin $
*/
#include <string.h>
+#include <arpa/inet.h>
#include "sha1_hasher.h"
@@ -51,6 +47,7 @@
typedef struct private_sha1_hasher_t private_sha1_hasher_t;
+typedef struct private_sha1_keyed_prf_t private_sha1_keyed_prf_t;
/**
* Private data structure with hasing context.
@@ -69,6 +66,21 @@ struct private_sha1_hasher_t {
u_int8_t buffer[64];
};
+/**
+ * Private data structure with keyed prf context.
+ */
+struct private_sha1_keyed_prf_t {
+ /**
+ * public prf interface
+ */
+ sha1_keyed_prf_t public;
+
+ /**
+ * internal used hasher
+ */
+ private_sha1_hasher_t *hasher;
+};
+
/*
* Hash a single 512-bit block. This is the core of the algorithm. *
*/
@@ -181,6 +193,19 @@ static void SHA1Final(private_sha1_hasher_t *this, u_int8_t *digest)
}
}
+/**
+ * Implementation of hasher_t.reset.
+ */
+static void reset(private_sha1_hasher_t *this)
+{
+ this->state[0] = 0x67452301;
+ this->state[1] = 0xEFCDAB89;
+ this->state[2] = 0x98BADCFE;
+ this->state[3] = 0x10325476;
+ this->state[4] = 0xC3D2E1F0;
+ this->count[0] = 0;
+ this->count[1] = 0;
+}
/**
* Implementation of hasher_t.get_hash.
@@ -191,28 +216,23 @@ static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffe
if (buffer != NULL)
{
SHA1Final(this, buffer);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ reset(this);
}
}
-
/**
* Implementation of hasher_t.allocate_hash.
*/
static void allocate_hash(private_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash)
{
- chunk_t allocated_hash;
-
SHA1Update(this, chunk.ptr, chunk.len);
if (hash != NULL)
{
- allocated_hash.ptr = malloc(HASH_SIZE_SHA1);
- allocated_hash.len = HASH_SIZE_SHA1;
+ hash->ptr = malloc(HASH_SIZE_SHA1);
+ hash->len = HASH_SIZE_SHA1;
- SHA1Final(this, allocated_hash.ptr);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
-
- *hash = allocated_hash;
+ SHA1Final(this, hash->ptr);
+ reset(this);
}
}
@@ -225,33 +245,6 @@ static size_t get_hash_size(private_sha1_hasher_t *this)
}
/**
- * Implementation of hasher_t.reset.
- */
-static void reset(private_sha1_hasher_t *this)
-{
- this->state[0] = 0x67452301;
- this->state[1] = 0xEFCDAB89;
- this->state[2] = 0x98BADCFE;
- this->state[3] = 0x10325476;
- this->state[4] = 0xC3D2E1F0;
- this->count[0] = 0;
- this->count[1] = 0;
-}
-
-/**
- * Implementation of hasher_t.get_state
- */
-static chunk_t get_state(private_sha1_hasher_t *this)
-{
- chunk_t chunk;
-
- chunk.ptr = (u_char*)&this->state[0];
- chunk.len = sizeof(this->state);
-
- return chunk;
-}
-
-/**
* Implementation of hasher_t.destroy.
*/
static void destroy(private_sha1_hasher_t *this)
@@ -262,15 +255,18 @@ static void destroy(private_sha1_hasher_t *this)
/*
* Described in header.
*/
-sha1_hasher_t *sha1_hasher_create(void)
+sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo)
{
- private_sha1_hasher_t *this = malloc_thing(private_sha1_hasher_t);
-
+ private_sha1_hasher_t *this;
+ if (algo != HASH_SHA1)
+ {
+ return NULL;
+ }
+ this = malloc_thing(private_sha1_hasher_t);
this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
- this->public.hasher_interface.get_state = (chunk_t (*) (hasher_t*))get_state;
this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
/* initialize */
@@ -278,3 +274,93 @@ sha1_hasher_t *sha1_hasher_create(void)
return &(this->public);
}
+
+/**
+ * Implementation of prf_t.get_bytes.
+ */
+static void get_bytes(private_sha1_keyed_prf_t *this, chunk_t seed, u_int8_t *bytes)
+{
+ u_int32_t *hash = (u_int32_t*)bytes;
+
+ SHA1Update(this->hasher, seed.ptr, seed.len);
+
+ hash[0] = htonl(this->hasher->state[0]);
+ hash[1] = htonl(this->hasher->state[1]);
+ hash[2] = htonl(this->hasher->state[2]);
+ hash[3] = htonl(this->hasher->state[3]);
+ hash[4] = htonl(this->hasher->state[4]);
+}
+
+/**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_block_size(private_sha1_keyed_prf_t *this)
+{
+ return HASH_SIZE_SHA1;
+}
+
+/**
+ * Implementation of prf_t.allocate_bytes.
+ */
+static void allocate_bytes(private_sha1_keyed_prf_t *this, chunk_t seed, chunk_t *chunk)
+{
+ *chunk = chunk_alloc(HASH_SIZE_SHA1);
+ get_bytes(this, seed, chunk->ptr);
+}
+
+/**
+ * Implementation of prf_t.get_key_size.
+ */
+static size_t get_key_size(private_sha1_keyed_prf_t *this)
+{
+ return sizeof(this->hasher->state);
+}
+
+/**
+ * Implementation of prf_t.set_key.
+ */
+static void set_key(private_sha1_keyed_prf_t *this, chunk_t key)
+{
+ int i, rounds;
+ u_int32_t *iv = (u_int32_t*)key.ptr;
+
+ reset(this->hasher);
+ rounds = min(key.len/sizeof(u_int32_t), sizeof(this->hasher->state));
+ for (i = 0; i < rounds; i++)
+ {
+ this->hasher->state[i] ^= htonl(iv[i]);
+ }
+}
+
+/**
+ * Implementation of prf_t.destroy.
+ */
+static void destroy_p(private_sha1_keyed_prf_t *this)
+{
+ destroy(this->hasher);
+ free(this);
+}
+
+/**
+ * see header
+ */
+sha1_keyed_prf_t *sha1_keyed_prf_create(pseudo_random_function_t algo)
+{
+ private_sha1_keyed_prf_t *this;
+ if (algo != PRF_KEYED_SHA1)
+ {
+ return NULL;
+ }
+ this = malloc_thing(private_sha1_keyed_prf_t);
+ this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
+ this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
+ this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
+ this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
+ this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
+ this->public.prf_interface.destroy = (void (*) (prf_t *))destroy_p;
+
+ this->hasher = (private_sha1_hasher_t*)sha1_hasher_create(HASH_SHA1);
+
+ return &(this->public);
+}
+
diff --git a/src/libstrongswan/plugins/sha1/sha1_hasher.h b/src/libstrongswan/plugins/sha1/sha1_hasher.h
new file mode 100644
index 000000000..2e44797d8
--- /dev/null
+++ b/src/libstrongswan/plugins/sha1/sha1_hasher.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup sha1_hasher sha1_hasher
+ * @{ @ingroup sha1_p
+ */
+
+#ifndef SHA1_HASHER_H_
+#define SHA1_HASHER_H_
+
+typedef struct sha1_hasher_t sha1_hasher_t;
+typedef struct sha1_keyed_prf_t sha1_keyed_prf_t;
+
+#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/prf.h>
+
+/**
+ * Implementation of hasher_t interface using the SHA1 algorithm.
+ */
+struct sha1_hasher_t {
+
+ /**
+ * Implements hasher_t interface.
+ */
+ hasher_t hasher_interface;
+};
+
+/**
+ * Implementation of prf_t interface using keyed SHA1 algorithm (used for EAP-AKA).
+ */
+struct sha1_keyed_prf_t {
+
+ /**
+ * Implements prf_t interface.
+ */
+ prf_t prf_interface;
+};
+
+/**
+ * Creates a new sha1_hasher_t.
+ *
+ * @param algo algorithm, must be HASH_SHA1
+ * @return sha1_hasher_t object
+ */
+sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo);
+
+/**
+ * Creates a new sha1_keyed_prf_t.
+ *
+ * @param algo algorithm, must be PRF_KEYED_SHA1
+ * @return sha1_keyed_prf_tobject
+ */
+sha1_keyed_prf_t *sha1_keyed_prf_create(pseudo_random_function_t algo);
+
+#endif /*SHA1_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha1/sha1_plugin.c b/src/libstrongswan/plugins/sha1/sha1_plugin.c
new file mode 100644
index 000000000..e8da99e6c
--- /dev/null
+++ b/src/libstrongswan/plugins/sha1/sha1_plugin.c
@@ -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: sha1_plugin.c 3619 2008-03-19 14:02:52Z martin $
+ */
+
+#include "sha1_plugin.h"
+
+#include <library.h>
+#include "sha1_hasher.h"
+
+typedef struct private_sha1_plugin_t private_sha1_plugin_t;
+
+/**
+ * private data of sha1_plugin
+ */
+struct private_sha1_plugin_t {
+
+ /**
+ * public functions
+ */
+ sha1_plugin_t public;
+};
+
+/**
+ * Implementation of sha1_plugin_t.destroy
+ */
+static void destroy(private_sha1_plugin_t *this)
+{
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)sha1_hasher_create);
+ lib->crypto->remove_prf(lib->crypto,
+ (prf_constructor_t)sha1_keyed_prf_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_sha1_plugin_t *this = malloc_thing(private_sha1_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
+ (hasher_constructor_t)sha1_hasher_create);
+ lib->crypto->add_prf(lib->crypto, PRF_KEYED_SHA1,
+ (prf_constructor_t)sha1_keyed_prf_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/sha1/sha1_plugin.h b/src/libstrongswan/plugins/sha1/sha1_plugin.h
new file mode 100644
index 000000000..82ab04c86
--- /dev/null
+++ b/src/libstrongswan/plugins/sha1/sha1_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup sha1_p sha1
+ * @ingroup plugins
+ *
+ * @defgroup sha1_plugin sha1_plugin
+ * @{ @ingroup sha1_p
+ */
+
+#ifndef SHA1_PLUGIN_H_
+#define SHA1_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sha1_plugin_t sha1_plugin_t;
+
+/**
+ * Plugin implementing the SHA1 algorithm in software.
+ */
+struct sha1_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a sha1_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SHA1_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha2/Makefile.am b/src/libstrongswan/plugins/sha2/Makefile.am
new file mode 100644
index 000000000..066e49476
--- /dev/null
+++ b/src/libstrongswan/plugins/sha2/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-sha2.la
+
+libstrongswan_sha2_la_SOURCES = sha2_plugin.h sha2_plugin.c sha2_hasher.c sha2_hasher.h
+libstrongswan_sha2_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in
new file mode 100644
index 000000000..ec0e45248
--- /dev/null
+++ b/src/libstrongswan/plugins/sha2/Makefile.in
@@ -0,0 +1,494 @@
+# 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/libstrongswan/plugins/sha2
+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_sha2_la_LIBADD =
+am_libstrongswan_sha2_la_OBJECTS = sha2_plugin.lo sha2_hasher.lo
+libstrongswan_sha2_la_OBJECTS = $(am_libstrongswan_sha2_la_OBJECTS)
+libstrongswan_sha2_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_sha2_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_sha2_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_sha2_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-sha2.la
+libstrongswan_sha2_la_SOURCES = sha2_plugin.h sha2_plugin.c sha2_hasher.c sha2_hasher.h
+libstrongswan_sha2_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/libstrongswan/plugins/sha2/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/sha2/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-sha2.la: $(libstrongswan_sha2_la_OBJECTS) $(libstrongswan_sha2_la_DEPENDENCIES)
+ $(libstrongswan_sha2_la_LINK) -rpath $(plugindir) $(libstrongswan_sha2_la_OBJECTS) $(libstrongswan_sha2_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2_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/libstrongswan/crypto/hashers/sha2_hasher.c b/src/libstrongswan/plugins/sha2/sha2_hasher.c
index b68972cec..ca9c2f926 100644
--- a/src/libstrongswan/crypto/hashers/sha2_hasher.c
+++ b/src/libstrongswan/plugins/sha2/sha2_hasher.c
@@ -1,10 +1,3 @@
-/**
- * @file sha2_hasher.c
- *
- * @brief Implementation of hasher_sha_t.
- *
- */
-
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -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: sha2_hasher.c 3488 2008-02-21 15:10:02Z martin $
*/
#include <string.h>
@@ -587,38 +582,6 @@ static void reset512(private_sha512_hasher_t *ctx)
}
/**
- * Implementation of hasher_t.get_state for SHA256
- */
-static chunk_t get_state256(private_sha256_hasher_t *ctx)
-{
- chunk_t chunk;
- chunk.ptr = (u_char*)&ctx->sha_H[0];
- chunk.len = HASH_SIZE_SHA256;
- return chunk;
-}
-
-/**
- * Implementation of hasher_t.get_state for SHA384
- */
-static chunk_t get_state384(private_sha512_hasher_t *ctx)
-{
- chunk_t chunk;
- chunk.ptr = (u_char*)&ctx->sha_H[0];
- chunk.len = HASH_SIZE_SHA384;
- return chunk;
-}
-/**
- * Implementation of hasher_t.get_state for SHA512
- */
-static chunk_t get_state512(private_sha512_hasher_t *ctx)
-{
- chunk_t chunk;
- chunk.ptr = (u_char*)&ctx->sha_H[0];
- chunk.len = HASH_SIZE_SHA512;
- return chunk;
-}
-
-/**
* Implementation of hasher_t.destroy.
*/
static void destroy(sha2_hasher_t *this)
@@ -638,7 +601,6 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
case HASH_SHA256:
this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
this->hasher_interface.reset = (void(*)(hasher_t*))reset256;
- this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state256;
this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size256;
this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash256;
this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash256;
@@ -647,7 +609,6 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
/* uses SHA512 data structure */
this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
this->hasher_interface.reset = (void(*)(hasher_t*))reset384;
- this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state384;
this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size384;
this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash384;
this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash384;
@@ -655,7 +616,6 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
case HASH_SHA512:
this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
this->hasher_interface.reset = (void(*)(hasher_t*))reset512;
- this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state512;
this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size512;
this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash512;
this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash512;
diff --git a/src/libstrongswan/crypto/hashers/sha2_hasher.h b/src/libstrongswan/plugins/sha2/sha2_hasher.h
index 91e82fedb..6d732495a 100644
--- a/src/libstrongswan/crypto/hashers/sha2_hasher.h
+++ b/src/libstrongswan/plugins/sha2/sha2_hasher.h
@@ -1,12 +1,5 @@
-/**
- * @file sha2_hasher.h
- *
- * @brief Interface of sha2_hasher_t
- *
- */
-
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-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 sha2_hasher sha2_hasher
+ * @{ @ingroup sha2_p
+ */
+
#ifndef SHA2_HASHER_H_
#define SHA2_HASHER_H_
@@ -28,18 +26,10 @@ typedef struct sha2_hasher_t sha2_hasher_t;
#include <crypto/hashers/hasher.h>
/**
- * @brief Implementation of hasher_t interface using the SHA2 algorithms.
+ * Implementation of hasher_t interface using the SHA2 algorithms.
*
* SHA2 is an other name for the SHA-256, SHA-384 and SHA-512 variants of
* the SHA hash algorithm.
- *
- * @b Constructors:
- * - hasher_create() using HASH_SHA256, HASH_SHA384 or HASH_SHA512 as algorithm
- * - sha2_hasher_create()
- *
- * @see hasher_t
- *
- * @ingroup hashers
*/
struct sha2_hasher_t {
@@ -50,13 +40,11 @@ struct sha2_hasher_t {
};
/**
- * @brief Creates a new sha2_hasher_t.
+ * Creates a new sha2_hasher_t.
*
* @param algorithm HASH_SHA256, HASH_SHA384 or HASH_SHA512
- * @return sha2_hasher_t object
- *
- * @ingroup hashers
+ * @return sha2_hasher_t object, NULL if not supported
*/
sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm);
-#endif /* SHA2_HASHER_H_ */
+#endif /* SHA2_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha2/sha2_plugin.c b/src/libstrongswan/plugins/sha2/sha2_plugin.c
new file mode 100644
index 000000000..ebb2947ef
--- /dev/null
+++ b/src/libstrongswan/plugins/sha2/sha2_plugin.c
@@ -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: sha2_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "sha2_plugin.h"
+
+#include <library.h>
+#include "sha2_hasher.h"
+
+typedef struct private_sha2_plugin_t private_sha2_plugin_t;
+
+/**
+ * private data of sha2_plugin
+ */
+struct private_sha2_plugin_t {
+
+ /**
+ * public functions
+ */
+ sha2_plugin_t public;
+};
+
+/**
+ * Implementation of sha2_plugin_t.destroy
+ */
+static void destroy(private_sha2_plugin_t *this)
+{
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)sha2_hasher_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_sha2_plugin_t *this = malloc_thing(private_sha2_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
+ (hasher_constructor_t)sha2_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
+ (hasher_constructor_t)sha2_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA512,
+ (hasher_constructor_t)sha2_hasher_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/sha2/sha2_plugin.h b/src/libstrongswan/plugins/sha2/sha2_plugin.h
new file mode 100644
index 000000000..859597758
--- /dev/null
+++ b/src/libstrongswan/plugins/sha2/sha2_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup sha2_p sha2
+ * @ingroup plugins
+ *
+ * @defgroup sha2_plugin sha2_plugin
+ * @{ @ingroup sha2_p
+ */
+
+#ifndef SHA2_PLUGIN_H_
+#define SHA2_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sha2_plugin_t sha2_plugin_t;
+
+/**
+ * Plugin implementing the SHA256, SHA384 and SHA512 algorithms in software.
+ */
+struct sha2_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a sha2_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SHA2_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/sqlite/Makefile.am b/src/libstrongswan/plugins/sqlite/Makefile.am
new file mode 100644
index 000000000..7c3017abf
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/Makefile.am
@@ -0,0 +1,12 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-sqlite.la
+
+libstrongswan_sqlite_la_SOURCES = sqlite_plugin.h sqlite_plugin.c \
+ sqlite_database.h sqlite_database.c
+libstrongswan_sqlite_la_LDFLAGS = -module
+libstrongswan_sqlite_la_LIBADD = -lsqlite3
+
diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in
new file mode 100644
index 000000000..3a73829dc
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/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/libstrongswan/plugins/sqlite
+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_sqlite_la_DEPENDENCIES =
+am_libstrongswan_sqlite_la_OBJECTS = sqlite_plugin.lo \
+ sqlite_database.lo
+libstrongswan_sqlite_la_OBJECTS = \
+ $(am_libstrongswan_sqlite_la_OBJECTS)
+libstrongswan_sqlite_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_sqlite_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_sqlite_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_sqlite_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-sqlite.la
+libstrongswan_sqlite_la_SOURCES = sqlite_plugin.h sqlite_plugin.c \
+ sqlite_database.h sqlite_database.c
+
+libstrongswan_sqlite_la_LDFLAGS = -module
+libstrongswan_sqlite_la_LIBADD = -lsqlite3
+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/libstrongswan/plugins/sqlite/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/sqlite/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-sqlite.la: $(libstrongswan_sqlite_la_OBJECTS) $(libstrongswan_sqlite_la_DEPENDENCIES)
+ $(libstrongswan_sqlite_la_LINK) -rpath $(plugindir) $(libstrongswan_sqlite_la_OBJECTS) $(libstrongswan_sqlite_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqlite_database.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqlite_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/libstrongswan/plugins/sqlite/sqlite_database.c b/src/libstrongswan/plugins/sqlite/sqlite_database.c
new file mode 100644
index 000000000..d5a03894d
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/sqlite_database.c
@@ -0,0 +1,321 @@
+/*
+ * 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: sqlite_database.c 3911 2008-05-07 14:41:13Z martin $
+ */
+
+#include "sqlite_database.h"
+
+#include <sqlite3.h>
+#include <library.h>
+#include <debug.h>
+#include <utils/mutex.h>
+
+typedef struct private_sqlite_database_t private_sqlite_database_t;
+
+/**
+ * private data of sqlite_database
+ */
+struct private_sqlite_database_t {
+
+ /**
+ * public functions
+ */
+ sqlite_database_t public;
+
+ /**
+ * sqlite database connection
+ */
+ sqlite3 *db;
+
+ /**
+ * mutex used to lock execute()
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * Create and run a sqlite stmt using a sql string and args
+ */
+static sqlite3_stmt* run(private_sqlite_database_t *this, char *sql,
+ va_list *args)
+{
+ sqlite3_stmt *stmt = NULL;
+ int params, i, res = SQLITE_OK;
+
+#ifdef HAVE_SQLITE3_PREPARE_V2
+ if (sqlite3_prepare_v2(this->db, sql, -1, &stmt, NULL) == SQLITE_OK)
+#else
+ if (sqlite3_prepare(this->db, sql, -1, &stmt, NULL) == SQLITE_OK)
+#endif
+ {
+ params = sqlite3_bind_parameter_count(stmt);
+ for (i = 1; i <= params; i++)
+ {
+ switch (va_arg(*args, db_type_t))
+ {
+ case DB_INT:
+ {
+ res = sqlite3_bind_int(stmt, i, va_arg(*args, int));
+ break;
+ }
+ case DB_UINT:
+ {
+ res = sqlite3_bind_int64(stmt, i, va_arg(*args, u_int));
+ break;
+ }
+ case DB_TEXT:
+ {
+ const char *text = va_arg(*args, const char*);
+ res = sqlite3_bind_text(stmt, i, text, -1, SQLITE_STATIC);
+ break;
+ }
+ case DB_BLOB:
+ {
+ chunk_t c = va_arg(*args, chunk_t);
+ res = sqlite3_bind_blob(stmt, i, c.ptr, c.len, SQLITE_STATIC);
+ break;
+ }
+ case DB_DOUBLE:
+ {
+ res = sqlite3_bind_double(stmt, i, va_arg(*args, double));
+ break;
+ }
+ case DB_NULL:
+ {
+ res = sqlite3_bind_null(stmt, i);
+ break;
+ }
+ default:
+ {
+ res = SQLITE_MISUSE;
+ break;
+ }
+ }
+ if (res != SQLITE_OK)
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ DBG1("preparing sqlite statement failed: %s", sqlite3_errmsg(this->db));
+ }
+ if (res != SQLITE_OK)
+ {
+ DBG1("binding sqlite statement failed: %s", sqlite3_errmsg(this->db));
+ sqlite3_finalize(stmt);
+ return NULL;
+ }
+ return stmt;
+}
+
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** associated sqlite statement */
+ sqlite3_stmt *stmt;
+ /** number of result columns */
+ int count;
+ /** column types */
+ db_type_t *columns;
+ /** reference to db connection */
+ sqlite3 *db;
+} sqlite_enumerator_t;
+
+/**
+ * destroy a sqlite enumerator
+ */
+static void sqlite_enumerator_destroy(sqlite_enumerator_t *this)
+{
+ sqlite3_finalize(this->stmt);
+ free(this->columns);
+ free(this);
+}
+
+/**
+ * Implementation of database.query().enumerate
+ */
+static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...)
+{
+ int i;
+ va_list args;
+
+ switch (sqlite3_step(this->stmt))
+ {
+ case SQLITE_ROW:
+ break;
+ default:
+ DBG1("stepping sqlite statement failed: %s", sqlite3_errmsg(this->db));
+ /* fall */
+ case SQLITE_DONE:
+ return FALSE;
+ }
+ va_start(args, this);
+ for (i = 0; i < this->count; i++)
+ {
+ switch (this->columns[i])
+ {
+ case DB_INT:
+ {
+ int *value = va_arg(args, int*);
+ *value = sqlite3_column_int(this->stmt, i);
+ break;
+ }
+ case DB_UINT:
+ {
+ u_int *value = va_arg(args, u_int*);
+ *value = (u_int)sqlite3_column_int64(this->stmt, i);
+ break;
+ }
+ case DB_TEXT:
+ {
+ const unsigned char **value = va_arg(args, const unsigned char**);
+ *value = sqlite3_column_text(this->stmt, i);
+ break;
+ }
+ case DB_BLOB:
+ {
+ chunk_t *chunk = va_arg(args, chunk_t*);
+ chunk->len = sqlite3_column_bytes(this->stmt, i);
+ chunk->ptr = (u_char*)sqlite3_column_blob(this->stmt, i);
+ break;
+ }
+ case DB_DOUBLE:
+ {
+ double *value = va_arg(args, double*);
+ *value = sqlite3_column_double(this->stmt, i);
+ break;
+ }
+ default:
+ DBG1("invalid result type supplied");
+ return FALSE;
+ }
+ }
+ va_end(args);
+ return TRUE;
+}
+
+/**
+ * Implementation of database_t.query.
+ */
+static enumerator_t* query(private_sqlite_database_t *this, char *sql, ...)
+{
+ sqlite3_stmt *stmt;
+ va_list args;
+ sqlite_enumerator_t *enumerator = NULL;
+ int i;
+
+
+ va_start(args, sql);
+ stmt = run(this, sql, &args);
+ if (stmt)
+ {
+ enumerator = malloc_thing(sqlite_enumerator_t);
+ enumerator->public.enumerate = (void*)sqlite_enumerator_enumerate;
+ enumerator->public.destroy = (void*)sqlite_enumerator_destroy;
+ enumerator->stmt = stmt;
+ enumerator->count = sqlite3_column_count(stmt);
+ enumerator->columns = malloc(sizeof(db_type_t) * enumerator->count);
+ enumerator->db = this->db;
+ for (i = 0; i < enumerator->count; i++)
+ {
+ enumerator->columns[i] = va_arg(args, db_type_t);
+ }
+ }
+ va_end(args);
+ return (enumerator_t*)enumerator;
+}
+
+/**
+ * Implementation of database_t.execute.
+ */
+static int execute(private_sqlite_database_t *this, int *rowid, char *sql, ...)
+{
+ sqlite3_stmt *stmt;
+ int affected = -1;
+ va_list args;
+
+ /* we need a lock to get our rowid/changes correctly */
+ this->mutex->lock(this->mutex);
+ va_start(args, sql);
+ stmt = run(this, sql, &args);
+ va_end(args);
+ if (stmt)
+ {
+ if (sqlite3_step(stmt) == SQLITE_DONE)
+ {
+ if (rowid)
+ {
+ *rowid = sqlite3_last_insert_rowid(this->db);
+ }
+ affected = sqlite3_changes(this->db);
+ }
+ else
+ {
+ DBG1("sqlite execute failed: %s", sqlite3_errmsg(this->db));
+ }
+ sqlite3_finalize(stmt);
+ }
+ this->mutex->unlock(this->mutex);
+ return affected;
+}
+
+/**
+ * Implementation of database_t.destroy
+ */
+static void destroy(private_sqlite_database_t *this)
+{
+ sqlite3_close(this->db);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+sqlite_database_t *sqlite_database_create(char *uri)
+{
+ char *file;
+ private_sqlite_database_t *this;
+
+ /**
+ * parse sqlite:///path/to/file.db uri
+ */
+ if (!strneq(uri, "sqlite://", 9))
+ {
+ return NULL;
+ }
+ file = uri + 9;
+
+ this = malloc_thing(private_sqlite_database_t);
+
+ this->public.db.query = (enumerator_t* (*)(database_t *this, char *sql, ...))query;
+ this->public.db.execute = (int (*)(database_t *this, int *rowid, char *sql, ...))execute;
+ this->public.db.destroy = (void(*)(database_t*))destroy;
+
+ this->mutex = mutex_create(MUTEX_DEFAULT);
+
+ if (sqlite3_open(file, &this->db) != SQLITE_OK)
+ {
+ DBG1("opening SQLite database '%s' failed: %s",
+ file, sqlite3_errmsg(this->db));
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_database.h b/src/libstrongswan/plugins/sqlite/sqlite_database.h
new file mode 100644
index 000000000..795785627
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/sqlite_database.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup sqlite_database sqlite_database
+ * @{ @ingroup sqlite_p
+ */
+
+#ifndef SQLITE_DATABASE_H_
+#define SQLITE_DATABASE_H_
+
+#include <database/database.h>
+
+typedef struct sqlite_database_t sqlite_database_t;
+
+/**
+ * sqlite databse_t implementation.
+ */
+struct sqlite_database_t {
+
+ /**
+ * Implements database_t
+ */
+ database_t db;
+};
+
+/**
+ * Create a sqlite_database instance.
+ *
+ * @param uri connection URI, sqlite:///path/to/file.db
+ */
+sqlite_database_t *sqlite_database_create(char *uri);
+
+#endif /* SQLITE_DATABASE_H_ @}*/
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_plugin.c b/src/libstrongswan/plugins/sqlite/sqlite_plugin.c
new file mode 100644
index 000000000..441e59a5e
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/sqlite_plugin.c
@@ -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: sqlite_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "sqlite_plugin.h"
+
+#include <library.h>
+#include "sqlite_database.h"
+
+typedef struct private_sqlite_plugin_t private_sqlite_plugin_t;
+
+/**
+ * private data of sqlite_plugin
+ */
+struct private_sqlite_plugin_t {
+
+ /**
+ * public functions
+ */
+ sqlite_plugin_t public;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_sqlite_plugin_t *this)
+{
+ lib->db->remove_database(lib->db,
+ (database_constructor_t)sqlite_database_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_sqlite_plugin_t *this = malloc_thing(private_sqlite_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->db->add_database(lib->db,
+ (database_constructor_t)sqlite_database_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_plugin.h b/src/libstrongswan/plugins/sqlite/sqlite_plugin.h
new file mode 100644
index 000000000..07bf9618f
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/sqlite_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup sqlite_p sqlite
+ * @ingroup plugins
+ *
+ * @defgroup sqlite_plugin sqlite_plugin
+ * @{ @ingroup sqlite_p
+ */
+
+#ifndef SQLITE_PLUGIN_H_
+#define SQLITE_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sqlite_plugin_t sqlite_plugin_t;
+
+/**
+ * Plugin implementing sqlite database connectivity
+ */
+struct sqlite_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a sqlite_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SQLITE_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/Makefile.am b/src/libstrongswan/plugins/x509/Makefile.am
new file mode 100644
index 000000000..3f9f85c36
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/Makefile.am
@@ -0,0 +1,16 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-x509.la
+
+libstrongswan_x509_la_SOURCES = x509_plugin.h x509_plugin.c \
+ x509_cert.h x509_cert.c \
+ x509_crl.h x509_crl.c \
+ x509_ac.h x509_ac.c \
+ x509_ocsp_request.h x509_ocsp_request.c \
+ x509_ocsp_response.h x509_ocsp_response.c \
+ ietf_attr_list.h ietf_attr_list.c
+libstrongswan_x509_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in
new file mode 100644
index 000000000..9178d6c8c
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/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/libstrongswan/plugins/x509
+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_x509_la_LIBADD =
+am_libstrongswan_x509_la_OBJECTS = x509_plugin.lo x509_cert.lo \
+ x509_crl.lo x509_ac.lo x509_ocsp_request.lo \
+ x509_ocsp_response.lo ietf_attr_list.lo
+libstrongswan_x509_la_OBJECTS = $(am_libstrongswan_x509_la_OBJECTS)
+libstrongswan_x509_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_x509_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_x509_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_x509_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-x509.la
+libstrongswan_x509_la_SOURCES = x509_plugin.h x509_plugin.c \
+ x509_cert.h x509_cert.c \
+ x509_crl.h x509_crl.c \
+ x509_ac.h x509_ac.c \
+ x509_ocsp_request.h x509_ocsp_request.c \
+ x509_ocsp_response.h x509_ocsp_response.c \
+ ietf_attr_list.h ietf_attr_list.c
+
+libstrongswan_x509_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/libstrongswan/plugins/x509/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/x509/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-x509.la: $(libstrongswan_x509_la_OBJECTS) $(libstrongswan_x509_la_DEPENDENCIES)
+ $(libstrongswan_x509_la_LINK) -rpath $(plugindir) $(libstrongswan_x509_la_OBJECTS) $(libstrongswan_x509_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ietf_attr_list.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_ac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_cert.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_crl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_ocsp_request.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_ocsp_response.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_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/libstrongswan/crypto/ietf_attr_list.c b/src/libstrongswan/plugins/x509/ietf_attr_list.c
index 1ecadf679..17f6949b2 100644
--- a/src/libstrongswan/crypto/ietf_attr_list.c
+++ b/src/libstrongswan/plugins/x509/ietf_attr_list.c
@@ -1,10 +1,3 @@
-/**
- * @file ietf_attr.c
- *
- * @brief Implementation of ietfAttr_t.
- *
- */
-
/*
* Copyright (C) 2007 Andreas Steffen, Hochschule fuer Technik Rapperswil
*
@@ -23,7 +16,11 @@
#include <stdio.h>
#include <debug.h>
+#include <library.h>
+
+#include <asn1/oid.h>
#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
#include <utils/lexparser.h>
#include "ietf_attr_list.h"
@@ -227,7 +224,7 @@ void ietfAttr_list_list(linked_list_t *list, FILE *out)
break;
case IETF_ATTRIBUTE_OID:
{
- int oid = known_oid(attr->value);
+ int oid = asn1_known_oid(attr->value);
if (oid == OID_UNKNOWN)
{
@@ -299,33 +296,27 @@ static const asn1Object_t ietfAttrSyntaxObjects[] =
{ 2, "string", ASN1_UTF8STRING, ASN1_OPT |
ASN1_BODY }, /* 8 */
{ 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 1, "end loop", ASN1_EOC, ASN1_END } /* 10 */
+ { 1, "end loop", ASN1_EOC, ASN1_END }, /* 10 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
#define IETF_ATTR_OCTETS 4
#define IETF_ATTR_OID 6
#define IETF_ATTR_STRING 8
-#define IETF_ATTR_ROOF 11
/*
* Described in header.
*/
void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0)
{
- asn1_ctx_t ctx;
+ asn1_parser_t *parser;
chunk_t object;
- u_int level;
- int objectID = 0;
+ int objectID;
- asn1_init(&ctx, chunk, level0, FALSE, FALSE);
+ parser = asn1_parser_create(ietfAttrSyntaxObjects, chunk);
+ parser->set_top_level(parser, level0);
- while (objectID < IETF_ATTR_ROOF)
+ while (parser->iterate(parser, &objectID, &object))
{
- if (!extract_object(ietfAttrSyntaxObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
-
switch (objectID)
{
case IETF_ATTR_OCTETS:
@@ -340,8 +331,8 @@ void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int lev
default:
break;
}
- objectID++;
}
+ parser->destroy(parser);
}
/*
@@ -364,7 +355,7 @@ chunk_t ietfAttr_list_encode(linked_list_t *list)
}
iterator->destroy(iterator);
- pos = build_asn1_object(&ietfAttributes, ASN1_SEQUENCE, size);
+ pos = asn1_build_object(&ietfAttributes, ASN1_SEQUENCE, size);
iterator = list->create_iterator(list, TRUE);
while (iterator->iterate(iterator, (void **)&attr))
diff --git a/src/libstrongswan/crypto/ietf_attr_list.h b/src/libstrongswan/plugins/x509/ietf_attr_list.h
index 75407bbf6..e3e4add61 100644
--- a/src/libstrongswan/crypto/ietf_attr_list.h
+++ b/src/libstrongswan/plugins/x509/ietf_attr_list.h
@@ -1,10 +1,3 @@
-/**
- * @file ietf_attr_list.h
- *
- * @brief Handling of ietfAttr_t linked lists
- *
- */
-
/*
* Copyright (C) 2007 Andreas Steffen
*
@@ -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$
+ */
+
+/**
+ * @defgroup ietf_attr_list ietf_attr_list
+ * @{ @ingroup x509_p
*/
#ifndef IETF_ATTR_LIST_H_
@@ -34,8 +34,6 @@
* @param list_a first alphabetically-sorted list
* @param list_b second alphabetically-sorted list
* @return TRUE if equal
- *
- * @ingroup crypto
*/
bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b);
@@ -43,9 +41,7 @@ bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b);
* @brief Lists a linked list of ietfAttr_t objects
*
* @param list alphabetically-sorted linked list of attributes
- @param out output file
- *
- * @ingroup crypto
+ * @param out output file
*/
void ietfAttr_list_list(linked_list_t *list, FILE *out);
@@ -54,9 +50,7 @@ void ietfAttr_list_list(linked_list_t *list, FILE *out);
*
* @param msg string with comma-separated group names
* @param list alphabetically-sorted linked list of attributes
- *
- * @ingroup crypto
- */
+ */
void ietfAttr_list_create_from_string(char *msg, linked_list_t *list);
/**
@@ -80,10 +74,8 @@ chunk_t ietfAttr_list_encode(linked_list_t *list);
* @brief Destroys a linked list of ietfAttr_t objects
*
* @param list list to be destroyed
- *
- * @ingroup crypto
*/
void ietfAttr_list_destroy(linked_list_t *list);
-#endif /* IETF_ATTR_LIST_H_ */
+#endif /* IETF_ATTR_LIST_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c
new file mode 100644
index 000000000..cfa38c66b
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ac.c
@@ -0,0 +1,1140 @@
+/*
+ * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
+ * Copyright (C) 2003 Martin Berner, Lukas Suter
+ * Copyright (C) 2002-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "x509_ac.h"
+#include "ietf_attr_list.h"
+
+#include <library.h>
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/pem.h>
+#include <utils/identification.h>
+#include <utils/linked_list.h>
+#include <credentials/certificates/x509.h>
+
+extern identification_t* x509_parse_authorityKeyIdentifier(chunk_t blob,
+ int level0, chunk_t *authKeySerialNumber);
+
+typedef struct private_x509_ac_t private_x509_ac_t;
+
+/**
+ * private data of x509_ac_t object
+ */
+struct private_x509_ac_t {
+
+ /**
+ * public functions
+ */
+ x509_ac_t public;
+
+ /**
+ * X.509 attribute certificate encoding in ASN.1 DER format
+ */
+ chunk_t encoding;
+
+ /**
+ * X.509 attribute certificate body over which signature is computed
+ */
+ chunk_t certificateInfo;
+
+ /**
+ * Version of the X.509 attribute certificate
+ */
+ u_int version;
+
+ /**
+ * Serial number of the X.509 attribute certificate
+ */
+ chunk_t serialNumber;
+
+ /**
+ * ID representing the issuer of the holder certificate
+ */
+ identification_t *holderIssuer;
+
+ /**
+ * Serial number of the holder certificate
+ */
+ chunk_t holderSerial;
+
+ /**
+ * ID representing the holder
+ */
+ identification_t *entityName;
+
+ /**
+ * ID representing the attribute certificate issuer
+ */
+ identification_t *issuerName;
+
+ /**
+ * Start time of certificate validity
+ */
+ time_t notBefore;
+
+ /**
+ * End time of certificate validity
+ */
+ time_t notAfter;
+
+ /**
+ * List of charging attributes
+ */
+ linked_list_t *charging;
+
+ /**
+ * List of groub attributes
+ */
+ linked_list_t *groups;
+
+ /**
+ * Authority Key Identifier
+ */
+ identification_t *authKeyIdentifier;
+
+ /**
+ * Authority Key Serial Number
+ */
+ chunk_t authKeySerialNumber;
+
+ /**
+ * No revocation information available
+ */
+ bool noRevAvail;
+
+ /**
+ * Signature algorithm
+ */
+ int algorithm;
+
+ /**
+ * Signature
+ */
+ chunk_t signature;
+
+ /**
+ * Holder certificate
+ */
+ certificate_t *holderCert;
+
+ /**
+ * Signer certificate
+ */
+ certificate_t *signerCert;
+
+ /**
+ * Signer private key;
+ */
+ private_key_t *signerKey;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+static u_char ASN1_group_oid_str[] = {
+ 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
+};
+
+static const chunk_t ASN1_group_oid = chunk_from_buf(ASN1_group_oid_str);
+
+static u_char ASN1_authorityKeyIdentifier_oid_str[] = {
+ 0x06, 0x03,
+ 0x55, 0x1d, 0x23
+};
+
+static const chunk_t ASN1_authorityKeyIdentifier_oid =
+ chunk_from_buf(ASN1_authorityKeyIdentifier_oid_str);
+
+static u_char ASN1_noRevAvail_ext_str[] = {
+ 0x30, 0x09,
+ 0x06, 0x03,
+ 0x55, 0x1d, 0x38,
+ 0x04, 0x02,
+ 0x05, 0x00
+};
+
+static const chunk_t ASN1_noRevAvail_ext = chunk_from_buf(ASN1_noRevAvail_ext_str);
+
+/**
+ * declaration of function implemented in x509_cert.c
+ */
+extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
+ linked_list_t *list);
+/**
+ * parses a directoryName
+ */
+static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name)
+{
+ bool has_directoryName;
+ linked_list_t *list = linked_list_create();
+
+ x509_parse_generalNames(blob, level, implicit, list);
+ has_directoryName = list->get_count(list) > 0;
+
+ if (has_directoryName)
+ {
+ iterator_t *iterator = list->create_iterator(list, TRUE);
+ identification_t *directoryName;
+ bool first = TRUE;
+
+ while (iterator->iterate(iterator, (void**)&directoryName))
+ {
+ if (first)
+ {
+ *name = directoryName;
+ first = FALSE;
+ }
+ else
+ {
+ DBG1("more than one directory name - first selected");
+ directoryName->destroy(directoryName);
+ }
+ }
+ iterator->destroy(iterator);
+ }
+ else
+ {
+ DBG1("no directoryName found");
+ }
+
+ list->destroy(list);
+ return has_directoryName;
+}
+
+/**
+ * ASN.1 definition of roleSyntax
+ */
+static const asn1Object_t roleSyntaxObjects[] =
+{
+ { 0, "roleSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "roleAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
+ ASN1_OBJ }, /* 1 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
+ { 1, "roleName", ASN1_CONTEXT_C_1, ASN1_OBJ }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+
+/**
+ * Parses roleSyntax
+ */
+static void parse_roleSyntax(chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+
+ parser = asn1_parser_create(roleSyntaxObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ default:
+ break;
+ }
+ }
+ parser->destroy(parser);
+}
+
+/**
+ * ASN.1 definition of an X509 attribute certificate
+ */
+static const asn1Object_t acObjects[] =
+{
+ { 0, "AttributeCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "AttributeCertificateInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "version", ASN1_INTEGER, ASN1_DEF |
+ ASN1_BODY }, /* 2 */
+ { 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
+ { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
+ { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
+ { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */
+ { 4, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
+ ASN1_BODY }, /* 7 */
+ { 4, "end opt", ASN1_EOC, ASN1_END }, /* 8 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
+ { 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT |
+ ASN1_OBJ }, /* 10 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
+ { 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */
+ { 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13 */
+ { 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
+ ASN1_BODY }, /* 14 */
+ { 4, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
+ { 4, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 16 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 17 */
+ { 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */
+ { 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_OBJ }, /* 19 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
+ { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */
+ { 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
+ { 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */
+ { 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */
+ { 5, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
+ ASN1_BODY }, /* 25 */
+ { 5, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
+ { 3, "objectDigestInfo", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 28 */
+ { 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */
+ { 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */
+ { 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
+ ASN1_BODY }, /* 31 */
+ { 5, "end opt", ASN1_EOC, ASN1_END }, /* 32 */
+ { 5, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 33 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 34 */
+ { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */
+ { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */
+ { 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */
+ { 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
+ { 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
+ { 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */
+ { 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 41 */
+ { 4, "type", ASN1_OID, ASN1_BODY }, /* 42 */
+ { 4, "values", ASN1_SET, ASN1_LOOP }, /* 43 */
+ { 5, "value", ASN1_EOC, ASN1_RAW }, /* 44 */
+ { 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 46 */
+ { 2, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 47 */
+ { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 48 */
+ { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 49 */
+ { 4, "critical", ASN1_BOOLEAN, ASN1_DEF |
+ ASN1_BODY }, /* 50 */
+ { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 51 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 52 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 53 */
+ { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 54 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define AC_OBJ_CERTIFICATE_INFO 1
+#define AC_OBJ_VERSION 2
+#define AC_OBJ_HOLDER_ISSUER 5
+#define AC_OBJ_HOLDER_SERIAL 6
+#define AC_OBJ_ENTITY_NAME 10
+#define AC_OBJ_ISSUER_NAME 19
+#define AC_OBJ_ISSUER 23
+#define AC_OBJ_SIG_ALG 35
+#define AC_OBJ_SERIAL_NUMBER 36
+#define AC_OBJ_NOT_BEFORE 38
+#define AC_OBJ_NOT_AFTER 39
+#define AC_OBJ_ATTRIBUTE_TYPE 42
+#define AC_OBJ_ATTRIBUTE_VALUE 44
+#define AC_OBJ_EXTN_ID 49
+#define AC_OBJ_CRITICAL 50
+#define AC_OBJ_EXTN_VALUE 51
+#define AC_OBJ_ALGORITHM 53
+#define AC_OBJ_SIGNATURE 54
+
+/**
+ * Parses an X.509 attribute certificate
+ */
+static bool parse_certificate(private_x509_ac_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int type = OID_UNKNOWN;
+ int extn_oid = OID_UNKNOWN;
+ int sig_alg = OID_UNKNOWN;
+ bool success = FALSE;
+ bool critical;
+
+ parser = asn1_parser_create(acObjects, this->encoding);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ u_int level = parser->get_level(parser)+1;
+
+ switch (objectID)
+ {
+ case AC_OBJ_CERTIFICATE_INFO:
+ this->certificateInfo = object;
+ break;
+ case AC_OBJ_VERSION:
+ this->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
+ DBG2(" v%d", this->version);
+ if (this->version != 2)
+ {
+ DBG1("v%d attribute certificates are not supported", this->version);
+ goto end;
+ }
+ break;
+ case AC_OBJ_HOLDER_ISSUER:
+ if (!parse_directoryName(object, level, FALSE, &this->holderIssuer))
+ {
+ goto end;
+ }
+ break;
+ case AC_OBJ_HOLDER_SERIAL:
+ this->holderSerial = object;
+ break;
+ case AC_OBJ_ENTITY_NAME:
+ if (!parse_directoryName(object, level, TRUE, &this->entityName))
+ {
+ goto end;
+ }
+ break;
+ case AC_OBJ_ISSUER_NAME:
+ if (!parse_directoryName(object, level, FALSE, &this->issuerName))
+ {
+ goto end;
+ }
+ break;
+ case AC_OBJ_SIG_ALG:
+ sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case AC_OBJ_SERIAL_NUMBER:
+ this->serialNumber = object;
+ break;
+ case AC_OBJ_NOT_BEFORE:
+ this->notBefore = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case AC_OBJ_NOT_AFTER:
+ this->notAfter = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case AC_OBJ_ATTRIBUTE_TYPE:
+ type = asn1_known_oid(object);
+ break;
+ case AC_OBJ_ATTRIBUTE_VALUE:
+ {
+ switch (type)
+ {
+ case OID_AUTHENTICATION_INFO:
+ DBG2(" need to parse authenticationInfo");
+ break;
+ case OID_ACCESS_IDENTITY:
+ DBG2(" need to parse accessIdentity");
+ break;
+ case OID_CHARGING_IDENTITY:
+ ietfAttr_list_create_from_chunk(object, this->charging, level);
+ break;
+ case OID_GROUP:
+ ietfAttr_list_create_from_chunk(object, this->groups, level);
+ break;
+ case OID_ROLE:
+ parse_roleSyntax(object, level);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case AC_OBJ_EXTN_ID:
+ extn_oid = asn1_known_oid(object);
+ break;
+ case AC_OBJ_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG2(" %s",(critical)?"TRUE":"FALSE");
+ break;
+ case AC_OBJ_EXTN_VALUE:
+ {
+ switch (extn_oid)
+ {
+ case OID_CRL_DISTRIBUTION_POINTS:
+ DBG2(" need to parse crlDistributionPoints");
+ break;
+ case OID_AUTHORITY_KEY_ID:
+ this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
+ level, &this->authKeySerialNumber);
+ break;
+ case OID_TARGET_INFORMATION:
+ DBG2(" need to parse targetInformation");
+ break;
+ case OID_NO_REV_AVAIL:
+ this->noRevAvail = TRUE;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case AC_OBJ_ALGORITHM:
+ this->algorithm = asn1_parse_algorithmIdentifier(object, level,
+ NULL);
+ if (this->algorithm != sig_alg)
+ {
+ DBG1(" signature algorithms do not agree");
+ success = FALSE;
+ goto end;
+ }
+ break;
+ case AC_OBJ_SIGNATURE:
+ this->signature = object;
+ break;
+ default:
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * build directoryName
+ */
+static chunk_t build_directoryName(asn1_t tag, chunk_t name)
+{
+ return asn1_wrap(tag, "m",
+ asn1_simple_object(ASN1_CONTEXT_C_4, name));
+}
+
+/**
+ * build holder
+ */
+static chunk_t build_holder(private_x509_ac_t *this)
+{
+ x509_t* x509 = (x509_t*)this->holderCert;
+ identification_t *issuer = this->holderCert->get_issuer(this->holderCert);
+ identification_t *subject = this->holderCert->get_subject(this->holderCert);
+
+ return asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_wrap(ASN1_CONTEXT_C_0, "mm",
+ build_directoryName(ASN1_SEQUENCE, issuer->get_encoding(issuer)),
+ asn1_simple_object(ASN1_INTEGER, x509->get_serial(x509))
+ ),
+ build_directoryName(ASN1_CONTEXT_C_1, subject->get_encoding(subject)));
+}
+
+/**
+ * build v2Form
+ */
+static chunk_t build_v2_form(private_x509_ac_t *this)
+{
+ identification_t *subject = this->signerCert->get_subject(this->signerCert);
+
+ return asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ build_directoryName(ASN1_SEQUENCE, subject->get_encoding(subject)));
+}
+
+/**
+ * build attrCertValidityPeriod
+ */
+static chunk_t build_attr_cert_validity(private_x509_ac_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_from_time(&this->notBefore, ASN1_GENERALIZEDTIME),
+ asn1_from_time(&this->notAfter, ASN1_GENERALIZEDTIME));
+}
+
+
+/**
+ * build attribute type
+ */
+static chunk_t build_attribute_type(const chunk_t type, chunk_t content)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "cm",
+ type,
+ asn1_wrap(ASN1_SET, "m", content));
+}
+
+/**
+ * build attributes
+ */
+static chunk_t build_attributes(private_x509_ac_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "m",
+ build_attribute_type(ASN1_group_oid, ietfAttr_list_encode(this->groups)));
+}
+
+/**
+ * build authorityKeyIdentifier
+ */
+static chunk_t build_authorityKeyIdentifier(private_x509_ac_t *this)
+{
+ chunk_t keyIdentifier;
+ chunk_t authorityCertIssuer;
+ chunk_t authorityCertSerialNumber;
+ x509_t *x509 = (x509_t*)this->signerCert;
+ identification_t *issuer = this->signerCert->get_issuer(this->signerCert);
+ public_key_t *public = this->signerCert->get_public_key(this->signerCert);
+
+ if (public)
+ {
+ identification_t *keyid = public->get_id(public, ID_PUBKEY_SHA1);
+
+ this->authKeyIdentifier = keyid = keyid->clone(keyid);
+ keyIdentifier = keyid->get_encoding(keyid);
+ public->destroy(public);
+ }
+ else
+ {
+ keyIdentifier = chunk_empty;
+ }
+ authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1,
+ issuer->get_encoding(issuer));
+ authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2,
+ x509->get_serial(x509));
+ return asn1_wrap(ASN1_SEQUENCE, "cm",
+ ASN1_authorityKeyIdentifier_oid,
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_wrap(ASN1_SEQUENCE, "cmm",
+ keyIdentifier,
+ authorityCertIssuer,
+ authorityCertSerialNumber
+ )
+ )
+ );
+}
+
+/**
+ * build extensions
+ */
+static chunk_t build_extensions(private_x509_ac_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "mc",
+ build_authorityKeyIdentifier(this),
+ ASN1_noRevAvail_ext);
+}
+
+/**
+ * build attributeCertificateInfo
+ */
+static chunk_t build_attr_cert_info(private_x509_ac_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
+ ASN1_INTEGER_1,
+ build_holder(this),
+ build_v2_form(this),
+ asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
+ asn1_simple_object(ASN1_INTEGER, this->serialNumber),
+ build_attr_cert_validity(this),
+ build_attributes(this),
+ build_extensions(this));
+}
+
+
+/**
+ * build an X.509 attribute certificate
+ */
+static chunk_t build_ac(private_x509_ac_t *this)
+{
+ chunk_t signatureValue;
+ chunk_t attributeCertificateInfo;
+
+ attributeCertificateInfo = build_attr_cert_info(this);
+
+ this->signerKey->sign(this->signerKey, SIGN_RSA_EMSA_PKCS1_SHA1,
+ attributeCertificateInfo, &signatureValue);
+
+ return asn1_wrap(ASN1_SEQUENCE, "mcm",
+ attributeCertificateInfo,
+ asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
+ asn1_bitstring("m", signatureValue));
+}
+
+/**
+ * Implementation of ac_t.get_serial.
+ */
+static chunk_t get_serial(private_x509_ac_t *this)
+{
+ return this->serialNumber;
+}
+
+/**
+ * Implementation of ac_t.get_holderSerial.
+ */
+static chunk_t get_holderSerial(private_x509_ac_t *this)
+{
+ return this->holderSerial;
+}
+
+/**
+ * Implementation of ac_t.get_holderIssuer.
+ */
+static identification_t* get_holderIssuer(private_x509_ac_t *this)
+{
+ return this->holderIssuer;
+}
+
+/**
+ * Implementation of ac_t.get_authKeyIdentifier.
+ */
+static identification_t* get_authKeyIdentifier(private_x509_ac_t *this)
+{
+ return this->authKeyIdentifier;
+}
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_ac_t *this)
+{
+ return CERT_X509_AC;
+}
+
+/**
+ * Implementation of certificate_t.get_subject
+ */
+static identification_t* get_subject(private_x509_ac_t *this)
+{
+ return this->entityName;
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_ac_t *this)
+{
+ return this->issuerName;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_subject(private_x509_ac_t *this, identification_t *subject)
+{
+ return ID_MATCH_NONE;
+}
+
+/**
+ * Implementation of certificate_t.has_issuer.
+ */
+static id_match_t has_issuer(private_x509_ac_t *this, identification_t *issuer)
+{
+ id_match_t match;
+
+ if (issuer->get_type(issuer) == ID_PUBKEY_SHA1)
+ {
+ if (this->authKeyIdentifier)
+ {
+ match = issuer->matches(issuer, this->authKeyIdentifier);
+ }
+ else
+ {
+ match = ID_MATCH_NONE;
+ }
+ }
+ else
+ {
+ match = this->issuerName->matches(this->issuerName, issuer);
+ }
+ return match;
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_ac_t *this, certificate_t *issuer)
+{
+ public_key_t *key;
+ signature_scheme_t scheme;
+ bool valid;
+ x509_t *x509 = (x509_t*)issuer;
+
+ /* check if issuer is an X.509 AA certificate */
+ if (issuer->get_type(issuer) != CERT_X509)
+ {
+ return FALSE;
+ }
+ if (!(x509->get_flags(x509) & X509_AA))
+ {
+ return FALSE;
+ }
+
+ /* get the public key of the issuer */
+ key = issuer->get_public_key(issuer);
+
+ /* compare keyIdentifiers if available, otherwise use DNs */
+ if (this->authKeyIdentifier && key)
+ {
+ identification_t *subjectKeyIdentifier = key->get_id(key, ID_PUBKEY_SHA1);
+
+ if (!subjectKeyIdentifier->equals(subjectKeyIdentifier,
+ this->authKeyIdentifier))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!this->issuerName->equals(this->issuerName, issuer->get_subject(issuer)))
+ {
+ return FALSE;
+ }
+ }
+ /* TODO: generic OID to scheme mapper? */
+ switch (this->algorithm)
+ {
+ case OID_MD5_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_MD5;
+ break;
+ case OID_SHA1_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ break;
+ case OID_SHA256_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
+ break;
+ case OID_SHA384_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
+ break;
+ case OID_SHA512_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
+ break;
+ case OID_ECDSA_WITH_SHA1:
+ scheme = SIGN_ECDSA_WITH_SHA1;
+ break;
+ default:
+ return FALSE;
+ }
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ valid = key->verify(key, scheme, this->certificateInfo, this->signature);
+ key->destroy(key);
+ return valid;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key.
+ */
+static public_key_t* get_public_key(private_x509_ac_t *this)
+{
+ return NULL;
+}
+
+/**
+ * Implementation of certificate_t.get_ref.
+ */
+static private_x509_ac_t* get_ref(private_x509_ac_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of certificate_t.get_validity.
+ */
+static bool get_validity(private_x509_ac_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ time_t t;
+
+ if (when)
+ {
+ t = *when;
+ }
+ else
+ {
+ t = time(NULL);
+ }
+ if (not_before)
+ {
+ *not_before = this->notBefore;
+ }
+ if (not_after)
+ {
+ *not_after = this->notAfter;
+ }
+ return (t >= this->notBefore && t <= this->notAfter);
+}
+
+/**
+ * Implementation of certificate_t.is_newer.
+ */
+static bool is_newer(private_x509_ac_t *this, ac_t *that)
+{
+ certificate_t *this_cert = &this->public.interface.certificate;
+ certificate_t *that_cert = &that->certificate;
+ time_t this_update, that_update, now = time(NULL);
+ bool new;
+
+ this_cert->get_validity(this_cert, &now, &this_update, NULL);
+ that_cert->get_validity(that_cert, &now, &that_update, NULL);
+ new = this_update > that_update;
+ DBG1(" attr cert from %#T is %s - existing attr_cert from %#T %s",
+ &this_update, FALSE, new ? "newer":"not newer",
+ &that_update, FALSE, new ? "replaced":"retained");
+ return new;
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_ac_t *this)
+{
+ return chunk_clone(this->encoding);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_ac_t *this, certificate_t *other)
+{
+ chunk_t encoding;
+ bool equal;
+
+ if ((certificate_t*)this == other)
+ {
+ return TRUE;
+ }
+ if (other->equals == (void*)equals)
+ { /* skip allocation if we have the same implementation */
+ return chunk_equals(this->encoding, ((private_x509_ac_t*)other)->encoding);
+ }
+ encoding = other->get_encoding(other);
+ equal = chunk_equals(this->encoding, encoding);
+ free(encoding.ptr);
+ return equal;
+}
+
+/**
+ * Implementation of x509_ac_t.destroy
+ */
+static void destroy(private_x509_ac_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF(this->holderIssuer);
+ DESTROY_IF(this->entityName);
+ DESTROY_IF(this->issuerName);
+ DESTROY_IF(this->authKeyIdentifier);
+ DESTROY_IF(this->holderCert);
+ DESTROY_IF(this->signerCert);
+ DESTROY_IF(this->signerKey);
+
+ ietfAttr_list_destroy(this->charging);
+ ietfAttr_list_destroy(this->groups);
+ free(this->encoding.ptr);
+ free(this);
+ }
+}
+
+/**
+ * create an empty but initialized X.509 attribute certificate
+ */
+static private_x509_ac_t *create_empty(void)
+{
+ private_x509_ac_t *this = malloc_thing(private_x509_ac_t);
+
+ /* public functions */
+ this->public.interface.get_serial = (chunk_t (*)(ac_t*))get_serial;
+ this->public.interface.get_holderSerial = (chunk_t (*)(ac_t*))get_holderSerial;
+ this->public.interface.get_holderIssuer = (identification_t* (*)(ac_t*))get_holderIssuer;
+ this->public.interface.get_authKeyIdentifier = (identification_t* (*)(ac_t*))get_authKeyIdentifier;
+ this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
+ this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
+ this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
+ this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
+ this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
+ this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
+
+ /* initialize */
+ this->encoding = chunk_empty;
+ this->holderSerial = chunk_empty;
+ this->holderIssuer = NULL;
+ this->entityName = NULL;
+ this->issuerName = NULL;
+ this->authKeyIdentifier = NULL;
+ this->holderCert = NULL;
+ this->signerCert = NULL;
+ this->signerKey = NULL;
+ this->charging = linked_list_create();
+ this->groups = linked_list_create();
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * create X.509 attribute certificate from a chunk
+ */
+static private_x509_ac_t* create_from_chunk(chunk_t chunk)
+{
+ private_x509_ac_t *this = create_empty();
+
+ this->encoding = chunk;
+ if (!parse_certificate(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return this;
+}
+
+/**
+ * create X.509 crl from a file
+ */
+static private_x509_ac_t* create_from_file(char *path)
+{
+ bool pgp = FALSE;
+ chunk_t chunk;
+ private_x509_ac_t *this;
+
+ if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
+ {
+ return NULL;
+ }
+
+ this = create_from_chunk(chunk);
+
+ if (this == NULL)
+ {
+ DBG1(" could not parse loaded attribute certificate file '%s'", path);
+ return NULL;
+ }
+ DBG1(" loaded attribute certificate file '%s'", path);
+ return this;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** X.509 attribute certificate to build */
+ private_x509_ac_t *ac;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static private_x509_ac_t* build(private_builder_t *this)
+{
+ private_x509_ac_t *ac = this->ac;
+
+ free(this);
+
+ /* synthesis if encoding does not exist */
+ if (ac && ac->encoding.ptr == NULL)
+ {
+ if (ac->holderCert && ac->signerCert && ac->signerKey)
+ {
+ ac->encoding = build_ac(ac);
+ return ac;
+ }
+ destroy(ac);
+ return NULL;
+ }
+ else
+ {
+ return ac;
+ }
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+ certificate_t *cert;
+
+ va_start(args, part);
+ switch (part)
+ {
+ case BUILD_FROM_FILE:
+ if (this->ac)
+ {
+ destroy(this->ac);
+ }
+ this->ac = create_from_file(va_arg(args, char*));
+ break;
+ case BUILD_BLOB_ASN1_DER:
+ if (this->ac)
+ {
+ destroy(this->ac);
+ }
+ this->ac = create_from_chunk(va_arg(args, chunk_t));
+ break;
+ case BUILD_NOT_BEFORE_TIME:
+ this->ac->notBefore = va_arg(args, time_t);
+ break;
+ case BUILD_NOT_AFTER_TIME:
+ this->ac->notAfter = va_arg(args, time_t);
+ break;
+ case BUILD_SERIAL:
+ this->ac->serialNumber = va_arg(args, chunk_t);
+ break;
+ case BUILD_IETF_GROUP_ATTR:
+ ietfAttr_list_create_from_string(va_arg(args, char*),
+ this->ac->groups);
+ break;
+ case BUILD_CERT:
+ cert = va_arg(args, certificate_t*);
+ if (cert->get_type(cert) == CERT_X509)
+ {
+ this->ac->holderCert = cert;
+ }
+ else
+ {
+ cert->destroy(cert);
+ }
+ break;
+ case BUILD_SIGNING_CERT:
+ cert = va_arg(args, certificate_t*);
+ if (cert->get_type(cert) == CERT_X509)
+ {
+ this->ac->signerCert = cert;
+ }
+ else
+ {
+ cert->destroy(cert);
+ }
+ break;
+ case BUILD_SIGNING_KEY:
+ this->ac->signerKey = va_arg(args, private_key_t*);
+ break;
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+ va_end(args);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_ac_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_X509_AC)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->ac = create_empty();
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_ac.h b/src/libstrongswan/plugins/x509/x509_ac.h
new file mode 100644
index 000000000..2fd165e45
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ac.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
+ * Copyright (C) 2003 Martin Berner, Lukas Suter
+ * Copyright (C) 2002-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup x509_ac x509_ac
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_AC_H_
+#define X509_AC_H_
+
+#include <credentials/certificates/ac.h>
+
+typedef struct x509_ac_t x509_ac_t;
+
+/**
+ * Implementation of ac_t using own ASN1 parser.
+ */
+struct x509_ac_t {
+
+ /**
+ * Implements the ac_t interface
+ */
+ ac_t interface;
+};
+
+/**
+ * Create the building facility for X.509 attribute certificates.
+ *
+ * The resulting builder accepts:
+ * BUILD_USER_CERT: user certificate, exactly one
+ * BUILD_SIGNER_CERT: signer certificate, exactly one
+ * BUILD_SIGNER_KEY: signer private key, exactly one
+ * BUILD_SERIAL: serial number, exactly one
+ * BUILD_GROUP_ATTR: group attribute, optional, several possible
+ *
+ * @param type certificate type, CERT_X509_AC only
+ * @return builder instance to build X.509 attribute certificates
+ */
+builder_t *x509_ac_builder(certificate_type_t type);
+
+#endif /* X509_AC_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
new file mode 100644
index 000000000..714258865
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -0,0 +1,1295 @@
+/*
+ * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
+ * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
+ * Copyright (C) 2002 Mario Strasser
+ * Copyright (C) 2000-2006 Andreas Steffen
+ * Copyright (C) 2006-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: x509_cert.c 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+#define _GNU_SOURCE
+
+#include "x509_cert.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <library.h>
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/pem.h>
+#include <crypto/hashers/hasher.h>
+#include <utils/linked_list.h>
+#include <utils/identification.h>
+
+/**
+ * Different kinds of generalNames
+ */
+typedef enum {
+ GN_OTHER_NAME = 0,
+ GN_RFC822_NAME = 1,
+ GN_DNS_NAME = 2,
+ GN_X400_ADDRESS = 3,
+ GN_DIRECTORY_NAME = 4,
+ GN_EDI_PARTY_NAME = 5,
+ GN_URI = 6,
+ GN_IP_ADDRESS = 7,
+ GN_REGISTERED_ID = 8,
+} generalNames_t;
+
+
+typedef struct private_x509_cert_t private_x509_cert_t;
+
+/**
+ * Private data of a x509_cert_t object.
+ */
+struct private_x509_cert_t {
+ /**
+ * Public interface for this certificate.
+ */
+ x509_cert_t public;
+
+ /**
+ * X.509 certificate encoding in ASN.1 DER format
+ */
+ chunk_t encoding;
+
+ /**
+ * SHA1 hash of the DER encoding of this X.509 certificate
+ */
+ chunk_t encoding_hash;
+
+ /**
+ * X.509 certificate body over which signature is computed
+ */
+ chunk_t tbsCertificate;
+
+ /**
+ * Version of the X.509 certificate
+ */
+ u_int version;
+
+ /**
+ * Serial number of the X.509 certificate
+ */
+ chunk_t serialNumber;
+
+ /**
+ * ID representing the certificate issuer
+ */
+ identification_t *issuer;
+
+ /**
+ * Start time of certificate validity
+ */
+ time_t notBefore;
+
+ /**
+ * End time of certificate validity
+ */
+ time_t notAfter;
+
+ /**
+ * ID representing the certificate subject
+ */
+ identification_t *subject;
+
+ /**
+ * List of subjectAltNames as identification_t
+ */
+ linked_list_t *subjectAltNames;
+
+ /**
+ * List of crlDistributionPoints as allocated char*
+ */
+ linked_list_t *crl_uris;
+
+ /**
+ * List ocspAccessLocations as identification_t
+ */
+ linked_list_t *ocsp_uris;
+
+ /**
+ * certificates embedded public key
+ */
+ public_key_t *public_key;
+
+ /**
+ * Subject Key Identifier
+ */
+ chunk_t subjectKeyID;
+
+ /**
+ * Authority Key Identifier
+ */
+ identification_t *authKeyIdentifier;
+
+ /**
+ * Authority Key Serial Number
+ */
+ chunk_t authKeySerialNumber;
+
+ /**
+ * x509 constraints and other flags
+ */
+ x509_flag_t flags;
+
+ /**
+ * Signature algorithm
+ */
+ int algorithm;
+
+ /**
+ * Signature
+ */
+ chunk_t signature;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+static u_char ASN1_sAN_oid_buf[] = {
+ 0x06, 0x03, 0x55, 0x1D, 0x11
+};
+static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_sAN_oid_buf);
+
+/**
+ * ASN.1 definition of a basicConstraints extension
+ */
+static const asn1Object_t basicConstraintsObjects[] = {
+ { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */
+ { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define BASIC_CONSTRAINTS_CA 1
+
+/**
+ * Extracts the basicConstraints extension
+ */
+static bool parse_basicConstraints(chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool isCA = FALSE;
+
+ parser = asn1_parser_create(basicConstraintsObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == BASIC_CONSTRAINTS_CA)
+ {
+ isCA = object.len && *object.ptr;
+ DBG2(" %s", isCA ? "TRUE" : "FALSE");
+ }
+ }
+ parser->destroy(parser);
+
+ return isCA;
+}
+
+/**
+ * ASN.1 definition of otherName
+ */
+static const asn1Object_t otherNameObjects[] = {
+ {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
+ {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY }, /* 1 */
+ {0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define ON_OBJ_ID_TYPE 0
+#define ON_OBJ_VALUE 1
+
+/**
+ * Extracts an otherName
+ */
+static bool parse_otherName(chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int oid = OID_UNKNOWN;
+ bool success = FALSE;
+
+ parser = asn1_parser_create(otherNameObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case ON_OBJ_ID_TYPE:
+ oid = asn1_known_oid(object);
+ break;
+ case ON_OBJ_VALUE:
+ if (oid == OID_XMPP_ADDR)
+ {
+ if (!asn1_parse_simple_object(&object, ASN1_UTF8STRING,
+ parser->get_level(parser)+1, "xmppAddr"))
+ {
+ goto end;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * ASN.1 definition of generalName
+ */
+static const asn1Object_t generalNameObjects[] = {
+ { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
+ { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
+ { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
+ { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT|ASN1_BODY }, /* 8 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
+ { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT|ASN1_BODY }, /* 10 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
+ { 0, "URI", ASN1_CONTEXT_S_6, ASN1_OPT|ASN1_BODY }, /* 12 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
+ { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT|ASN1_BODY }, /* 14 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
+ { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT|ASN1_BODY }, /* 16 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 17 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define GN_OBJ_OTHER_NAME 0
+#define GN_OBJ_RFC822_NAME 2
+#define GN_OBJ_DNS_NAME 4
+#define GN_OBJ_X400_ADDRESS 6
+#define GN_OBJ_DIRECTORY_NAME 8
+#define GN_OBJ_EDI_PARTY_NAME 10
+#define GN_OBJ_URI 12
+#define GN_OBJ_IP_ADDRESS 14
+#define GN_OBJ_REGISTERED_ID 16
+
+/**
+ * Extracts a generalName
+ */
+static identification_t *parse_generalName(chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID ;
+
+ identification_t *gn = NULL;
+
+ parser = asn1_parser_create(generalNameObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ id_type_t id_type = ID_ANY;
+
+ switch (objectID)
+ {
+ case GN_OBJ_RFC822_NAME:
+ id_type = ID_RFC822_ADDR;
+ break;
+ case GN_OBJ_DNS_NAME:
+ id_type = ID_FQDN;
+ break;
+ case GN_OBJ_URI:
+ id_type = ID_DER_ASN1_GN_URI;
+ break;
+ case GN_OBJ_DIRECTORY_NAME:
+ id_type = ID_DER_ASN1_DN;
+ break;
+ case GN_OBJ_IP_ADDRESS:
+ id_type = ID_IPV4_ADDR;
+ break;
+ case GN_OBJ_OTHER_NAME:
+ if (!parse_otherName(object, parser->get_level(parser)+1))
+ {
+ goto end;
+ }
+ break;
+ case GN_OBJ_X400_ADDRESS:
+ case GN_OBJ_EDI_PARTY_NAME:
+ case GN_OBJ_REGISTERED_ID:
+ default:
+ break;
+ }
+ if (id_type != ID_ANY)
+ {
+ gn = identification_create_from_encoding(id_type, object);
+ DBG2(" '%D'", gn);
+ goto end;
+ }
+ }
+
+end:
+ parser->destroy(parser);
+ return gn;
+}
+
+/**
+ * ASN.1 definition of generalNames
+ */
+static const asn1Object_t generalNamesObjects[] = {
+ { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define GENERAL_NAMES_GN 1
+
+/**
+ * Extracts one or several GNs and puts them into a chained list
+ */
+void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+
+ parser = asn1_parser_create(generalNamesObjects, blob);
+ parser->set_top_level(parser, level0);
+ parser->set_flags(parser, implicit, FALSE);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == GENERAL_NAMES_GN)
+ {
+ identification_t *gn = parse_generalName(object,
+ parser->get_level(parser)+1);
+
+ if (gn)
+ {
+ list->insert_last(list, (void *)gn);
+ }
+ }
+ }
+ parser->destroy(parser);
+}
+
+/**
+ * ASN.1 definition of a authorityKeyIdentifier extension
+ */
+static const asn1Object_t authKeyIdentifierObjects[] = {
+ { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_BODY }, /* 1 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
+ { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
+ { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define AUTH_KEY_ID_KEY_ID 1
+#define AUTH_KEY_ID_CERT_ISSUER 3
+#define AUTH_KEY_ID_CERT_SERIAL 5
+
+/**
+ * Extracts an authoritykeyIdentifier
+ */
+identification_t* x509_parse_authorityKeyIdentifier(chunk_t blob, int level0,
+ chunk_t *authKeySerialNumber)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ identification_t *authKeyIdentifier = NULL;
+
+ *authKeySerialNumber = chunk_empty;
+
+ parser = asn1_parser_create(authKeyIdentifierObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case AUTH_KEY_ID_KEY_ID:
+ authKeyIdentifier = identification_create_from_encoding(
+ ID_PUBKEY_SHA1, object);
+ break;
+ case AUTH_KEY_ID_CERT_ISSUER:
+ /* TODO: x509_parse_generalNames(object, level+1, TRUE); */
+ break;
+ case AUTH_KEY_ID_CERT_SERIAL:
+ *authKeySerialNumber = object;
+ break;
+ default:
+ break;
+ }
+ }
+ parser->destroy(parser);
+ return authKeyIdentifier;
+}
+
+/**
+ * ASN.1 definition of a authorityInfoAccess extension
+ */
+static const asn1Object_t authInfoAccessObjects[] = {
+ { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */
+ { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define AUTH_INFO_ACCESS_METHOD 2
+#define AUTH_INFO_ACCESS_LOCATION 3
+
+/**
+ * Extracts an authorityInfoAcess location
+ */
+static void parse_authorityInfoAccess(chunk_t blob, int level0,
+ private_x509_cert_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int accessMethod = OID_UNKNOWN;
+
+ parser = asn1_parser_create(authInfoAccessObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case AUTH_INFO_ACCESS_METHOD:
+ accessMethod = asn1_known_oid(object);
+ break;
+ case AUTH_INFO_ACCESS_LOCATION:
+ {
+ switch (accessMethod)
+ {
+ case OID_OCSP:
+ case OID_CA_ISSUERS:
+ {
+ identification_t *id;
+ char *uri;
+
+ id = parse_generalName(object,
+ parser->get_level(parser)+1);
+ if (id == NULL)
+ {
+ /* parsing went wrong - abort */
+ goto end;
+ }
+ DBG2(" '%D'", id);
+ if (accessMethod == OID_OCSP &&
+ asprintf(&uri, "%D", id) > 0)
+ {
+ this->ocsp_uris->insert_last(this->ocsp_uris, uri);
+ }
+ id->destroy(id);
+ }
+ break;
+ default:
+ /* unkown accessMethod, ignoring */
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+end:
+ parser->destroy(parser);
+}
+
+/**
+ * ASN.1 definition of a extendedKeyUsage extension
+ */
+static const asn1Object_t extendedKeyUsageObjects[] = {
+ { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define EXT_KEY_USAGE_PURPOSE_ID 1
+
+/**
+ * Extracts extendedKeyUsage OIDs - currently only OCSP_SIGING is returned
+ */
+static bool parse_extendedKeyUsage(chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool ocsp_signing = FALSE;
+
+ parser = asn1_parser_create(extendedKeyUsageObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == EXT_KEY_USAGE_PURPOSE_ID &&
+ asn1_known_oid(object) == OID_OCSP_SIGNING)
+ {
+ ocsp_signing = TRUE;
+ }
+ }
+ parser->destroy(parser);
+ return ocsp_signing;
+}
+
+/**
+ * ASN.1 definition of crlDistributionPoints
+ */
+static const asn1Object_t crlDistributionPointsObjects[] = {
+ { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 2 */
+ { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */
+ { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
+ { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */
+ { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
+ { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
+ { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_BODY }, /* 10 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define CRL_DIST_POINTS_FULLNAME 3
+
+/**
+ * Extracts one or several crlDistributionPoints into a list
+ */
+static void parse_crlDistributionPoints(chunk_t blob, int level0,
+ private_x509_cert_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ linked_list_t *list = linked_list_create();
+
+ parser = asn1_parser_create(crlDistributionPointsObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == CRL_DIST_POINTS_FULLNAME)
+ {
+ identification_t *id;
+
+ /* append extracted generalNames to existing chained list */
+ x509_parse_generalNames(object, parser->get_level(parser)+1,
+ TRUE, list);
+
+ while (list->remove_last(list, (void**)&id) == SUCCESS)
+ {
+ char *uri;
+
+ if (asprintf(&uri, "%D", id) > 0)
+ {
+ this->crl_uris->insert_last(this->crl_uris, uri);
+ }
+ id->destroy(id);
+ }
+ }
+ }
+ parser->destroy(parser);
+ list->destroy(list);
+}
+
+/**
+ * ASN.1 definition of an X.509v3 x509_cert
+ */
+static const asn1Object_t certObjects[] = {
+ { 0, "x509", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
+ { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
+ { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
+ { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
+ { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
+ { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
+ { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
+ { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
+ { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
+ { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_RAW }, /* 11 */
+ { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
+ { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 14 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
+ { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 16 */
+ { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 17 */
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 18 */
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 19 */
+ { 5, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 20 */
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 21 */
+ { 3, "end loop", ASN1_EOC, ASN1_END }, /* 22 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 23 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 24 */
+ { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 25 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define X509_OBJ_TBS_CERTIFICATE 1
+#define X509_OBJ_VERSION 3
+#define X509_OBJ_SERIAL_NUMBER 4
+#define X509_OBJ_SIG_ALG 5
+#define X509_OBJ_ISSUER 6
+#define X509_OBJ_NOT_BEFORE 8
+#define X509_OBJ_NOT_AFTER 9
+#define X509_OBJ_SUBJECT 10
+#define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO 11
+#define X509_OBJ_EXTN_ID 19
+#define X509_OBJ_CRITICAL 20
+#define X509_OBJ_EXTN_VALUE 21
+#define X509_OBJ_ALGORITHM 24
+#define X509_OBJ_SIGNATURE 25
+
+/**
+ * Parses an X.509v3 certificate
+ */
+static bool parse_certificate(private_x509_cert_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int extn_oid = OID_UNKNOWN;
+ int sig_alg = OID_UNKNOWN;
+ bool success = FALSE;
+ bool critical;
+
+ parser = asn1_parser_create(certObjects, this->encoding);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ u_int level = parser->get_level(parser)+1;
+
+ switch (objectID)
+ {
+ case X509_OBJ_TBS_CERTIFICATE:
+ this->tbsCertificate = object;
+ break;
+ case X509_OBJ_VERSION:
+ this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
+ DBG2(" v%d", this->version);
+ break;
+ case X509_OBJ_SERIAL_NUMBER:
+ this->serialNumber = object;
+ break;
+ case X509_OBJ_SIG_ALG:
+ sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case X509_OBJ_ISSUER:
+ this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
+ DBG2(" '%D'", this->issuer);
+ break;
+ case X509_OBJ_NOT_BEFORE:
+ this->notBefore = asn1_parse_time(object, level);
+ break;
+ case X509_OBJ_NOT_AFTER:
+ this->notAfter = asn1_parse_time(object, level);
+ break;
+ case X509_OBJ_SUBJECT:
+ this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
+ DBG2(" '%D'", this->subject);
+ break;
+ case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO:
+ this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
+ KEY_ANY, BUILD_BLOB_ASN1_DER, chunk_clone(object), BUILD_END);
+ if (this->public_key == NULL)
+ {
+ DBG1("could not create public key");
+ goto end;
+ }
+ break;
+ case X509_OBJ_EXTN_ID:
+ extn_oid = asn1_known_oid(object);
+ break;
+ case X509_OBJ_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG2(" %s", critical ? "TRUE" : "FALSE");
+ break;
+ case X509_OBJ_EXTN_VALUE:
+ {
+ switch (extn_oid)
+ {
+ case OID_SUBJECT_KEY_ID:
+ if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
+ level, "keyIdentifier"))
+ {
+ goto end;
+ }
+ this->subjectKeyID = object;
+ break;
+ case OID_SUBJECT_ALT_NAME:
+ x509_parse_generalNames(object, level, FALSE,
+ this->subjectAltNames);
+ break;
+ case OID_BASIC_CONSTRAINTS:
+ if (parse_basicConstraints(object, level))
+ {
+ this->flags |= X509_CA;
+ }
+ break;
+ case OID_CRL_DISTRIBUTION_POINTS:
+ parse_crlDistributionPoints(object, level, this);
+ break;
+ case OID_AUTHORITY_KEY_ID:
+ this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
+ level, &this->authKeySerialNumber);
+ break;
+ case OID_AUTHORITY_INFO_ACCESS:
+ parse_authorityInfoAccess(object, level, this);
+ break;
+ case OID_EXTENDED_KEY_USAGE:
+ if (parse_extendedKeyUsage(object, level))
+ {
+ this->flags |= X509_OCSP_SIGNER;
+ }
+ break;
+ case OID_NS_REVOCATION_URL:
+ case OID_NS_CA_REVOCATION_URL:
+ case OID_NS_CA_POLICY_URL:
+ case OID_NS_COMMENT:
+ if (!asn1_parse_simple_object(&object, ASN1_IA5STRING,
+ level, oid_names[extn_oid].name))
+ {
+ goto end;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case X509_OBJ_ALGORITHM:
+ this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
+ if (this->algorithm != sig_alg)
+ {
+ DBG1(" signature algorithms do not agree");
+ goto end;
+ }
+ break;
+ case X509_OBJ_SIGNATURE:
+ this->signature = object;
+ break;
+ default:
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_cert_t *this)
+{
+ return CERT_X509;
+}
+
+/**
+ * Implementation of certificate_t.get_subject
+ */
+static identification_t* get_subject(private_x509_cert_t *this)
+{
+ return this->subject;
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_cert_t *this)
+{
+ return this->issuer;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_subject(private_x509_cert_t *this, identification_t *subject)
+{
+ identification_t *current;
+ enumerator_t *enumerator;
+ id_match_t match, best;
+
+ if (this->encoding_hash.ptr && subject->get_type(subject) == ID_CERT_DER_SHA1 &&
+ chunk_equals(this->encoding_hash, subject->get_encoding(subject)))
+ {
+ return ID_MATCH_PERFECT;
+ }
+
+ best = this->subject->matches(this->subject, subject);
+ enumerator = this->subjectAltNames->create_enumerator(this->subjectAltNames);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ match = current->matches(current, subject);
+ if (match > best)
+ {
+ best = match;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return best;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_issuer(private_x509_cert_t *this, identification_t *issuer)
+{
+ /* issuerAltNames currently not supported */
+ return this->issuer->matches(this->issuer, issuer);
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_cert_t *this, certificate_t *issuer)
+{
+ public_key_t *key;
+ signature_scheme_t scheme;
+ bool valid;
+ x509_t *x509 = (x509_t*)issuer;
+
+ if (&this->public.interface.interface == issuer)
+ {
+ if (this->flags & X509_SELF_SIGNED)
+ {
+ return TRUE;
+ }
+ }
+ else
+ {
+ if (issuer->get_type(issuer) != CERT_X509)
+ {
+ return FALSE;
+ }
+ if (!(x509->get_flags(x509) & X509_CA))
+ {
+ return FALSE;
+ }
+ }
+ if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
+ {
+ return FALSE;
+ }
+ /* TODO: generic OID to scheme mapper? */
+ switch (this->algorithm)
+ {
+ case OID_MD5_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_MD5;
+ break;
+ case OID_SHA1_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ break;
+ case OID_SHA256_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
+ break;
+ case OID_SHA384_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
+ break;
+ case OID_SHA512_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
+ break;
+ case OID_ECDSA_WITH_SHA1:
+ scheme = SIGN_ECDSA_WITH_SHA1;
+ break;
+ default:
+ return FALSE;
+ }
+ key = issuer->get_public_key(issuer);
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ /* TODO: add a lightweight check option (comparing auth/subject keyids only) */
+ valid = key->verify(key, scheme, this->tbsCertificate, this->signature);
+ key->destroy(key);
+ return valid;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_cert_t *this)
+{
+ this->public_key->get_ref(this->public_key);
+ return this->public_key;
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static private_x509_cert_t* get_ref(private_x509_cert_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of x509_cert_t.get_flags.
+ */
+static x509_flag_t get_flags(private_x509_cert_t *this)
+{
+ return this->flags;
+}
+
+/**
+ * Implementation of x509_cert_t.get_validity.
+ */
+static bool get_validity(private_x509_cert_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ time_t t;
+
+ if (when)
+ {
+ t = *when;
+ }
+ else
+ {
+ t = time(NULL);
+ }
+ if (not_before)
+ {
+ *not_before = this->notBefore;
+ }
+ if (not_after)
+ {
+ *not_after = this->notAfter;
+ }
+ return (t >= this->notBefore && t <= this->notAfter);
+}
+
+/**
+ * Implementation of certificate_t.is_newer.
+ */
+static bool is_newer(certificate_t *this, certificate_t *that)
+{
+ time_t this_update, that_update, now = time(NULL);
+ bool new;
+
+ this->get_validity(this, &now, &this_update, NULL);
+ that->get_validity(that, &now, &that_update, NULL);
+ new = this_update > that_update;
+ DBG1(" certificate from %#T is %s - existing certificate from %#T %s",
+ &this_update, FALSE, new ? "newer":"not newer",
+ &that_update, FALSE, new ? "replaced":"retained");
+ return new;
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_cert_t *this)
+{
+ return chunk_clone(this->encoding);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_cert_t *this, certificate_t *other)
+{
+ chunk_t encoding;
+ bool equal;
+
+ if (this == (private_x509_cert_t*)other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != CERT_X509)
+ {
+ return FALSE;
+ }
+ if (other->equals == (void*)equals)
+ { /* skip allocation if we have the same implementation */
+ return chunk_equals(this->encoding, ((private_x509_cert_t*)other)->encoding);
+ }
+ encoding = other->get_encoding(other);
+ equal = chunk_equals(this->encoding, encoding);
+ free(encoding.ptr);
+ return equal;
+}
+
+/**
+ * Implementation of x509_t.get_serial.
+ */
+static chunk_t get_serial(private_x509_cert_t *this)
+{
+ return this->serialNumber;
+}
+
+/**
+ * Implementation of x509_t.get_authKeyIdentifier.
+ */
+static identification_t *get_authKeyIdentifier(private_x509_cert_t *this)
+{
+ return this->authKeyIdentifier;
+}
+
+/**
+ * Implementation of x509_cert_t.create_subjectAltName_enumerator.
+ */
+static enumerator_t* create_subjectAltName_enumerator(private_x509_cert_t *this)
+{
+ return this->subjectAltNames->create_enumerator(this->subjectAltNames);
+}
+
+/**
+ * Implementation of x509_cert_t.create_ocsp_uri_enumerator.
+ */
+static enumerator_t* create_ocsp_uri_enumerator(private_x509_cert_t *this)
+{
+ return this->ocsp_uris->create_enumerator(this->ocsp_uris);
+}
+
+/**
+ * Implementation of x509_cert_t.create_crl_uri_enumerator.
+ */
+static enumerator_t* create_crl_uri_enumerator(private_x509_cert_t *this)
+{
+ return this->crl_uris->create_enumerator(this->crl_uris);
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static void destroy(private_x509_cert_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->subjectAltNames->destroy_offset(this->subjectAltNames,
+ offsetof(identification_t, destroy));
+ this->crl_uris->destroy_function(this->crl_uris, free);
+ this->ocsp_uris->destroy_function(this->ocsp_uris, free);
+ DESTROY_IF(this->issuer);
+ DESTROY_IF(this->subject);
+ DESTROY_IF(this->public_key);
+ DESTROY_IF(this->authKeyIdentifier);
+ chunk_free(&this->encoding);
+ chunk_free(&this->encoding_hash);
+ free(this);
+ }
+}
+
+/**
+ * create an empty but initialized X.509 certificate
+ */
+static private_x509_cert_t* create_empty(void)
+{
+ private_x509_cert_t *this = malloc_thing(private_x509_cert_t);
+
+ this->public.interface.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.interface.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
+ this->public.interface.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.interface.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
+ this->public.interface.interface.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.interface.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.interface.interface.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
+ this->public.interface.interface.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
+ this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
+ this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.interface.interface.destroy = (void (*)(certificate_t *this))destroy;
+ this->public.interface.get_flags = (x509_flag_t (*)(x509_t*))get_flags;
+ this->public.interface.get_serial = (chunk_t (*)(x509_t*))get_serial;
+ this->public.interface.get_authKeyIdentifier = (identification_t* (*)(x509_t*))get_authKeyIdentifier;
+ this->public.interface.create_subjectAltName_enumerator = (enumerator_t* (*)(x509_t*))create_subjectAltName_enumerator;
+ this->public.interface.create_crl_uri_enumerator = (enumerator_t* (*)(x509_t*))create_crl_uri_enumerator;
+ this->public.interface.create_ocsp_uri_enumerator = (enumerator_t* (*)(x509_t*))create_ocsp_uri_enumerator;
+
+ this->encoding = chunk_empty;
+ this->encoding_hash = chunk_empty;
+ this->public_key = NULL;
+ this->subject = NULL;
+ this->issuer = NULL;
+ this->subjectAltNames = linked_list_create();
+ this->crl_uris = linked_list_create();
+ this->ocsp_uris = linked_list_create();
+ this->subjectKeyID = chunk_empty;
+ this->authKeyIdentifier = NULL;
+ this->authKeySerialNumber = chunk_empty;
+ this->flags = 0;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * create an X.509 certificate from a chunk
+ */
+static private_x509_cert_t *create_from_chunk(chunk_t chunk)
+{
+ private_x509_cert_t *this = create_empty();
+
+ this->encoding = chunk;
+ if (!parse_certificate(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ /* check if the certificate is self-signed */
+ if (issued_by(this, &this->public.interface.interface))
+ {
+ this->flags |= X509_SELF_SIGNED;
+ }
+
+ hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher != NULL)
+ {
+ hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash);
+ hasher->destroy(hasher);
+ }
+ else
+ {
+ DBG1(" unable to create hash of certificate, SHA1 not supported");
+ }
+
+ return this;
+}
+
+/**
+ * create an X.509 certificate from a file
+ */
+static private_x509_cert_t *create_from_file(char *path)
+{
+ bool pgp = FALSE;
+ chunk_t chunk;
+ private_x509_cert_t *this;
+
+ if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
+ {
+ return NULL;
+ }
+
+ this = create_from_chunk(chunk);
+
+ if (this == NULL)
+ {
+ DBG1(" could not parse loaded certificate file '%s'",path);
+ return NULL;
+ }
+ DBG1(" loaded certificate file '%s'", path);
+ return this;
+
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded certificate */
+ private_x509_cert_t *cert;
+ /** additional flags to enforce */
+ x509_flag_t flags;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static private_x509_cert_t *build(private_builder_t *this)
+{
+ private_x509_cert_t *cert = this->cert;
+ x509_flag_t flags = this->flags;
+
+ free(this);
+ if (cert == NULL)
+ {
+ return NULL;
+ }
+ if ((flags & X509_CA) && !(cert->flags & X509_CA))
+ {
+ DBG1(" ca certificate must have ca basic constraint set, discarded");
+ destroy(cert);
+ return NULL;
+ }
+ cert->flags |= flags;
+ return cert;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ va_start(args, part);
+ switch (part)
+ {
+ case BUILD_FROM_FILE:
+ this->cert = create_from_file(va_arg(args, char*));
+ break;
+ case BUILD_BLOB_ASN1_DER:
+ this->cert = create_from_chunk(va_arg(args, chunk_t));
+ break;
+ case BUILD_X509_FLAG:
+ this->flags = va_arg(args, x509_flag_t);
+ break;
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+ va_end(args);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_cert_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_X509)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->cert = NULL;
+ this->flags = 0;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_cert.h b/src/libstrongswan/plugins/x509/x509_cert.h
new file mode 100644
index 000000000..701cc3d63
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_cert.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: x509_cert.h 3650 2008-03-22 08:15:18Z andreas $
+ */
+
+/**
+ * @defgroup x509_cert x509_cert
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_CERT_H_
+#define X509_CERT_H_
+
+typedef struct x509_cert_t x509_cert_t;
+
+#include <credentials/certificates/x509.h>
+
+/**
+ * Implementation of x509_t/certificate_t using own ASN1 parser.
+ */
+struct x509_cert_t {
+
+ /**
+ * Implements the x509_t interface
+ */
+ x509_t interface;
+};
+
+/**
+ * Create the building facility for x509 certificates
+ *
+ * @param type certificate type, CERT_X509 only
+ * @return builder instance to build certificate
+ */
+builder_t *x509_cert_builder(certificate_type_t type);
+
+#endif /* X509_CERT_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
new file mode 100644
index 000000000..3bdda1701
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -0,0 +1,742 @@
+/*
+ * 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: x509_crl.c 4091 2008-06-22 17:41:07Z andreas $
+ */
+
+#include "x509_crl.h"
+
+typedef struct private_x509_crl_t private_x509_crl_t;
+typedef struct revoked_t revoked_t;
+
+#include <debug.h>
+#include <library.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/pem.h>
+#include <credentials/certificates/x509.h>
+#include <utils/linked_list.h>
+
+/**
+ * entry for a revoked certificate
+ */
+struct revoked_t {
+ /**
+ * serial of the revoked certificate
+ */
+ chunk_t serial;
+
+ /**
+ * date of revocation
+ */
+ time_t date;
+
+ /**
+ * reason for revocation
+ */
+ crl_reason_t reason;
+};
+
+/**
+ * private data of x509_crl
+ */
+struct private_x509_crl_t {
+
+ /**
+ * public functions
+ */
+ x509_crl_t public;
+
+ /**
+ * X.509 crl encoding in ASN.1 DER format
+ */
+ chunk_t encoding;
+
+ /**
+ * X.509 crl body over which signature is computed
+ */
+ chunk_t tbsCertList;
+
+ /**
+ * Version of the X.509 crl
+ */
+ u_int version;
+
+ /**
+ * ID representing the crl issuer
+ */
+ identification_t *issuer;
+
+ /**
+ * CRL number
+ */
+ chunk_t crlNumber;
+
+ /**
+ * Time when the crl was generated
+ */
+ time_t thisUpdate;
+
+ /**
+ * Time when an update crl will be available
+ */
+ time_t nextUpdate;
+
+ /**
+ * list of revoked certificates as revoked_t
+ */
+ linked_list_t *revoked;
+
+ /**
+ * Authority Key Identifier
+ */
+ identification_t *authKeyIdentifier;
+
+ /**
+ * Authority Key Serial Number
+ */
+ chunk_t authKeySerialNumber;
+
+ /**
+ * Signature algorithm
+ */
+ int algorithm;
+
+ /**
+ * Signature
+ */
+ chunk_t signature;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * from x509_cert
+ */
+extern identification_t* x509_parse_authorityKeyIdentifier(
+ chunk_t blob, int level0,
+ chunk_t *authKeySerialNumber);
+
+/**
+ * ASN.1 definition of an X.509 certificate revocation list
+ */
+static const asn1Object_t crlObjects[] = {
+ { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "version", ASN1_INTEGER, ASN1_OPT |
+ ASN1_BODY }, /* 2 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */
+ { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
+ { 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */
+ { 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */
+ { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_LOOP }, /* 8 */
+ { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */
+ { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */
+ { 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */
+ { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_LOOP }, /* 12 */
+ { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
+ { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */
+ { 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
+ ASN1_BODY }, /* 15 */
+ { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
+ { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */
+ { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */
+ { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */
+ { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
+ { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
+ ASN1_BODY }, /* 23 */
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
+ { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
+ { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 28 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define CRL_OBJ_TBS_CERT_LIST 1
+#define CRL_OBJ_VERSION 2
+#define CRL_OBJ_SIG_ALG 4
+#define CRL_OBJ_ISSUER 5
+#define CRL_OBJ_THIS_UPDATE 6
+#define CRL_OBJ_NEXT_UPDATE 7
+#define CRL_OBJ_USER_CERTIFICATE 10
+#define CRL_OBJ_REVOCATION_DATE 11
+#define CRL_OBJ_CRL_ENTRY_EXTN_ID 14
+#define CRL_OBJ_CRL_ENTRY_CRITICAL 15
+#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16
+#define CRL_OBJ_EXTN_ID 22
+#define CRL_OBJ_CRITICAL 23
+#define CRL_OBJ_EXTN_VALUE 24
+#define CRL_OBJ_ALGORITHM 27
+#define CRL_OBJ_SIGNATURE 28
+
+/**
+ * Parses an X.509 Certificate Revocation List (CRL)
+ */
+static bool parse(private_x509_crl_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ chunk_t extnID;
+ chunk_t userCertificate = chunk_empty;
+ int objectID;
+ int sig_alg = OID_UNKNOWN;
+ bool success = FALSE;
+ bool critical;
+ revoked_t *revoked = NULL;
+
+ parser = asn1_parser_create(crlObjects, this->encoding);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ u_int level = parser->get_level(parser)+1;
+
+ switch (objectID)
+ {
+ case CRL_OBJ_TBS_CERT_LIST:
+ this->tbsCertList = object;
+ break;
+ case CRL_OBJ_VERSION:
+ this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
+ DBG2(" v%d", this->version);
+ break;
+ case CRL_OBJ_SIG_ALG:
+ sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case CRL_OBJ_ISSUER:
+ this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
+ DBG2(" '%D'", this->issuer);
+ break;
+ case CRL_OBJ_THIS_UPDATE:
+ this->thisUpdate = asn1_parse_time(object, level);
+ break;
+ case CRL_OBJ_NEXT_UPDATE:
+ this->nextUpdate = asn1_parse_time(object, level);
+ break;
+ case CRL_OBJ_USER_CERTIFICATE:
+ userCertificate = object;
+ break;
+ case CRL_OBJ_REVOCATION_DATE:
+ revoked = malloc_thing(revoked_t);
+ revoked->serial = userCertificate;
+ revoked->date = asn1_parse_time(object, level);
+ revoked->reason = CRL_UNSPECIFIED;
+ this->revoked->insert_last(this->revoked, (void *)revoked);
+ break;
+ case CRL_OBJ_CRL_ENTRY_EXTN_ID:
+ case CRL_OBJ_EXTN_ID:
+ extnID = object;
+ break;
+ case CRL_OBJ_CRL_ENTRY_CRITICAL:
+ case CRL_OBJ_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG2(" %s", critical ? "TRUE" : "FALSE");
+ break;
+ case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
+ case CRL_OBJ_EXTN_VALUE:
+ {
+ int extn_oid = asn1_known_oid(extnID);
+
+ if (revoked && extn_oid == OID_CRL_REASON_CODE)
+ {
+ if (*object.ptr == ASN1_ENUMERATED &&
+ asn1_length(&object) == 1)
+ {
+ revoked->reason = *object.ptr;
+ }
+ DBG2(" '%N'", crl_reason_names, revoked->reason);
+ }
+ else if (extn_oid == OID_AUTHORITY_KEY_ID)
+ {
+
+ this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
+ level, &this->authKeySerialNumber);
+ }
+ else if (extn_oid == OID_CRL_NUMBER)
+ {
+ if (!asn1_parse_simple_object(&object, ASN1_INTEGER,
+ level, "crlNumber"))
+ {
+ goto end;
+ }
+ this->crlNumber = object;
+ }
+ }
+ break;
+ case CRL_OBJ_ALGORITHM:
+ {
+ this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
+ if (this->algorithm != sig_alg)
+ {
+ DBG1(" signature algorithms do not agree");
+ goto end;
+ }
+ break;
+ }
+ case CRL_OBJ_SIGNATURE:
+ this->signature = object;
+ break;
+ default:
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * enumerator filter callback for create_enumerator
+ */
+static bool filter(void *data, revoked_t **revoked, chunk_t *serial, void *p2,
+ time_t *date, void *p3, crl_reason_t *reason)
+{
+ if (serial)
+ {
+ *serial = (*revoked)->serial;
+ }
+ if (date)
+ {
+ *date = (*revoked)->date;
+ }
+ if (reason)
+ {
+ *reason = (*revoked)->reason;
+ }
+ return TRUE;
+}
+
+/**
+ * Implementation of crl_t.get_serial.
+ */
+static chunk_t get_serial(private_x509_crl_t *this)
+{
+ return this->crlNumber;
+}
+
+/**
+ * Implementation of crl_t.get_authKeyIdentifier.
+ */
+static identification_t* get_authKeyIdentifier(private_x509_crl_t *this)
+{
+ return this->authKeyIdentifier;
+}
+/**
+ * Implementation of crl_t.create_enumerator.
+ */
+static enumerator_t* create_enumerator(private_x509_crl_t *this)
+{
+ return enumerator_create_filter(
+ this->revoked->create_enumerator(this->revoked),
+ (void*)filter, NULL, NULL);
+}
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_crl_t *this)
+{
+ return CERT_X509_CRL;
+}
+
+/**
+ * Implementation of certificate_t.get_issuer and get_subject
+ */
+static identification_t* get_issuer(private_x509_crl_t *this)
+{
+ return this->issuer;
+}
+
+/**
+ * Implementation of certificate_t.has_subject and has_issuer.
+ */
+static id_match_t has_issuer(private_x509_crl_t *this, identification_t *issuer)
+{
+ id_match_t match;
+
+ if (issuer->get_type(issuer) == ID_PUBKEY_SHA1)
+ {
+ if (this->authKeyIdentifier)
+ {
+ match = issuer->matches(issuer, this->authKeyIdentifier);
+ }
+ else
+ {
+ match = ID_MATCH_NONE;
+ }
+ }
+ else
+ {
+ match = this->issuer->matches(this->issuer, issuer);
+ }
+ return match;
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_crl_t *this, certificate_t *issuer)
+{
+ public_key_t *key;
+ signature_scheme_t scheme;
+ bool valid;
+ x509_t *x509 = (x509_t*)issuer;
+
+ /* check if issuer is an X.509 CA certificate */
+ if (issuer->get_type(issuer) != CERT_X509)
+ {
+ return FALSE;
+ }
+ if (!(x509->get_flags(x509) & X509_CA))
+ {
+ return FALSE;
+ }
+
+ /* get the public key of the issuer */
+ key = issuer->get_public_key(issuer);
+
+ /* compare keyIdentifiers if available, otherwise use DNs */
+ if (this->authKeyIdentifier && key)
+ {
+ identification_t *subjectKeyIdentifier = key->get_id(key, ID_PUBKEY_SHA1);
+
+ if (!subjectKeyIdentifier->equals(subjectKeyIdentifier,
+ this->authKeyIdentifier))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
+ {
+ return FALSE;
+ }
+ }
+ /* TODO: generic OID to scheme mapper? */
+ switch (this->algorithm)
+ {
+ case OID_MD5_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_MD5;
+ break;
+ case OID_SHA1_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ break;
+ case OID_SHA256_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
+ break;
+ case OID_SHA384_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
+ break;
+ case OID_SHA512_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
+ break;
+ case OID_ECDSA_WITH_SHA1:
+ scheme = SIGN_ECDSA_WITH_SHA1;
+ break;
+ default:
+ return FALSE;
+ }
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ valid = key->verify(key, scheme, this->tbsCertList, this->signature);
+ key->destroy(key);
+ return valid;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_crl_t *this)
+{
+ return NULL;
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static private_x509_crl_t* get_ref(private_x509_crl_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of certificate_t.get_validity.
+ */
+static bool get_validity(private_x509_crl_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ time_t t;
+
+ if (when)
+ {
+ t = *when;
+ }
+ else
+ {
+ t = time(NULL);
+ }
+ if (not_before)
+ {
+ *not_before = this->thisUpdate;
+ }
+ if (not_after)
+ {
+ *not_after = this->nextUpdate;
+ }
+ return (t <= this->nextUpdate);
+}
+
+/**
+ * Implementation of certificate_t.is_newer.
+ */
+static bool is_newer(private_x509_crl_t *this, crl_t *that)
+{
+ chunk_t that_crlNumber = that->get_serial(that);
+ bool new;
+
+ /* compare crlNumbers if available - otherwise use thisUpdate */
+ if (this->crlNumber.ptr != NULL && that_crlNumber.ptr != NULL)
+ {
+ new = chunk_compare(this->crlNumber, that_crlNumber) > 0;
+ DBG1(" crl #%#B is %s - existing crl #%#B %s",
+ &this->crlNumber, new ? "newer":"not newer",
+ &that_crlNumber, new ? "replaced":"retained");
+ }
+ else
+ {
+ certificate_t *this_cert = &this->public.crl.certificate;
+ certificate_t *that_cert = &that->certificate;
+
+ time_t this_update, that_update, now = time(NULL);
+
+ this_cert->get_validity(this_cert, &now, &this_update, NULL);
+ that_cert->get_validity(that_cert, &now, &that_update, NULL);
+ new = this_update > that_update;
+ DBG1(" crl from %#T is %s - existing crl from %#T %s",
+ &this_update, FALSE, new ? "newer":"not newer",
+ &that_update, FALSE, new ? "replaced":"retained");
+ }
+ return new;
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_crl_t *this)
+{
+ return chunk_clone(this->encoding);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_crl_t *this, certificate_t *other)
+{
+ chunk_t encoding;
+ bool equal;
+
+ if ((certificate_t*)this == other)
+ {
+ return TRUE;
+ }
+ if (other->equals == (void*)equals)
+ { /* skip allocation if we have the same implementation */
+ return chunk_equals(this->encoding, ((private_x509_crl_t*)other)->encoding);
+ }
+ encoding = other->get_encoding(other);
+ equal = chunk_equals(this->encoding, encoding);
+ free(encoding.ptr);
+ return equal;
+}
+
+/**
+ * Implementation of certificate_t.destroy
+ */
+static void destroy(private_x509_crl_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->revoked->destroy_function(this->revoked, free);
+ DESTROY_IF(this->issuer);
+ DESTROY_IF(this->authKeyIdentifier);
+ free(this->encoding.ptr);
+ free(this);
+ }
+}
+
+/**
+ * create an empty but initialized X.509 crl
+ */
+static private_x509_crl_t* create_empty(void)
+{
+ private_x509_crl_t *this = malloc_thing(private_x509_crl_t);
+
+ this->public.crl.get_serial = (chunk_t (*)(crl_t*))get_serial;
+ this->public.crl.get_authKeyIdentifier = (identification_t* (*)(crl_t*))get_authKeyIdentifier;
+ this->public.crl.create_enumerator = (enumerator_t* (*)(crl_t*))create_enumerator;
+ this->public.crl.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.crl.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.crl.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.crl.certificate.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_issuer;
+ this->public.crl.certificate.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.crl.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.crl.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.crl.certificate.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.crl.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
+ this->public.crl.certificate.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
+ this->public.crl.certificate.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
+ this->public.crl.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.crl.certificate.destroy = (void (*)(certificate_t *this))destroy;
+
+ this->encoding = chunk_empty;
+ this->tbsCertList = chunk_empty;
+ this->issuer = NULL;
+ this->crlNumber = chunk_empty;
+ this->revoked = linked_list_create();
+ this->authKeyIdentifier = NULL;
+ this->authKeySerialNumber = chunk_empty;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * create an X.509 crl from a chunk
+ */
+static private_x509_crl_t* create_from_chunk(chunk_t chunk)
+{
+ private_x509_crl_t *this = create_empty();
+
+ this->encoding = chunk;
+ if (!parse(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return this;
+}
+
+/**
+ * create an X.509 crl from a file
+ */
+static private_x509_crl_t* create_from_file(char *path)
+{
+ bool pgp = FALSE;
+ chunk_t chunk;
+ private_x509_crl_t *this;
+
+ if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
+ {
+ return NULL;
+ }
+
+ this = create_from_chunk(chunk);
+
+ if (this == NULL)
+ {
+ DBG1(" could not parse loaded crl file '%s'",path);
+ return NULL;
+ }
+ DBG1(" loaded crl file '%s'", path);
+ return this;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded CRL */
+ private_x509_crl_t *crl;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static private_x509_crl_t *build(private_builder_t *this)
+{
+ private_x509_crl_t *crl = this->crl;
+
+ free(this);
+ return crl;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->crl)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ va_start(args, part);
+ switch (part)
+ {
+ case BUILD_FROM_FILE:
+ this->crl = create_from_file(va_arg(args, char*));
+ break;
+ case BUILD_BLOB_ASN1_DER:
+ {
+ this->crl = create_from_chunk(va_arg(args, chunk_t));
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+ va_end(args);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_crl_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_X509_CRL)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->crl = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_crl.h b/src/libstrongswan/plugins/x509/x509_crl.h
new file mode 100644
index 000000000..0d9e5cca4
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_crl.h
@@ -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.
+ */
+
+/**
+ * @defgroup x509_crl x509_crl
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_CRL_H_
+#define X509_CRL_H_
+
+typedef struct x509_crl_t x509_crl_t;
+
+#include <credentials/certificates/crl.h>
+
+/**
+ * Implementation of the X509 certification revocation list.
+ */
+struct x509_crl_t {
+
+ /**
+ * Implements the crl_t interface
+ */
+ crl_t crl;
+};
+
+
+/**
+ * Create the building facility for x509 certificate revocation lists.
+ *
+ * @param type certificate type, CERT_X509_CRL only
+ * @return builder instance to build certificate
+ */
+builder_t *x509_crl_builder(certificate_type_t type);
+
+#endif /* X509_CRL_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
new file mode 100644
index 000000000..590a974f7
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
@@ -0,0 +1,612 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: x509_ocsp_request.c 4091 2008-06-22 17:41:07Z andreas $
+ */
+
+#include "x509_ocsp_request.h"
+
+#include <library.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <utils/identification.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+#include <credentials/certificates/x509.h>
+
+#define NONCE_LEN 16
+
+typedef struct private_x509_ocsp_request_t private_x509_ocsp_request_t;
+
+/**
+ * private data of x509_ocsp_request
+ */
+struct private_x509_ocsp_request_t {
+
+ /**
+ * public functions
+ */
+ x509_ocsp_request_t public;
+
+ /**
+ * CA the candidates belong to
+ */
+ x509_t *ca;
+
+ /**
+ * Requestor name, subject of cert used if not set
+ */
+ identification_t *requestor;
+
+ /**
+ * Requestor certificate, included in request
+ */
+ certificate_t *cert;
+
+ /**
+ * Requestor private key to sign request
+ */
+ private_key_t *key;
+
+ /**
+ * list of certificates to check, x509_t
+ */
+ linked_list_t *candidates;
+
+ /**
+ * nonce used in request
+ */
+ chunk_t nonce;
+
+ /**
+ * encoded OCSP request
+ */
+ chunk_t encoding;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+static u_char ASN1_nonce_oid_str[] = {
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
+};
+
+static u_char ASN1_response_oid_str[] = {
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
+};
+
+static u_char ASN1_response_content_str[] = {
+ 0x04, 0x0D,
+ 0x30, 0x0B,
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
+};
+
+static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
+static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
+static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
+
+/**
+ * build requestorName
+ */
+static chunk_t build_requestorName(private_x509_ocsp_request_t *this)
+{
+ if (this->requestor || this->cert)
+ { /* use requestor name, fallback to his cert subject */
+ if (!this->requestor)
+ {
+ this->requestor = this->cert->get_subject(this->cert);
+ this->requestor = this->requestor->clone(this->requestor);
+ }
+ return asn1_wrap(ASN1_CONTEXT_C_1, "m",
+ asn1_simple_object(ASN1_CONTEXT_C_4,
+ this->requestor->get_encoding(this->requestor)));
+
+ }
+ return chunk_empty;
+}
+
+/**
+ * build Request, not using singleRequestExtensions
+ */
+static chunk_t build_Request(private_x509_ocsp_request_t *this,
+ chunk_t issuerNameHash, chunk_t issuerKeyHash,
+ chunk_t serialNumber)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "m",
+ asn1_wrap(ASN1_SEQUENCE, "cmmm",
+ asn1_algorithmIdentifier(OID_SHA1),
+ asn1_simple_object(ASN1_OCTET_STRING, issuerNameHash),
+ asn1_simple_object(ASN1_OCTET_STRING, issuerKeyHash),
+ asn1_simple_object(ASN1_INTEGER, serialNumber)));
+}
+
+/**
+ * build requestList
+ */
+static chunk_t build_requestList(private_x509_ocsp_request_t *this)
+{
+ chunk_t issuerNameHash, issuerKeyHash;
+ identification_t *issuer;
+ x509_t *x509;
+ certificate_t *cert;
+ chunk_t list = chunk_empty;
+ public_key_t *public;
+
+ cert = (certificate_t*)this->ca;
+ public = cert->get_public_key(cert);
+ if (public)
+ {
+ hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher)
+ {
+ identification_t *keyid = public->get_id(public, ID_PUBKEY_SHA1);
+ if (keyid)
+ {
+ enumerator_t *enumerator;
+
+ issuerKeyHash = keyid->get_encoding(keyid);
+
+ issuer = cert->get_subject(cert);
+ hasher->allocate_hash(hasher, issuer->get_encoding(issuer),
+ &issuerNameHash);
+ hasher->destroy(hasher);
+
+ enumerator = this->candidates->create_enumerator(this->candidates);
+ while (enumerator->enumerate(enumerator, &x509))
+ {
+ chunk_t request, serialNumber;
+
+ serialNumber = x509->get_serial(x509);
+ request = build_Request(this, issuerNameHash, issuerKeyHash,
+ serialNumber);
+ list = chunk_cat("mm", list, request);
+ }
+ enumerator->destroy(enumerator);
+ chunk_free(&issuerNameHash);
+ }
+ }
+ else
+ {
+ DBG1("creating OCSP request failed, SHA1 not supported");
+ }
+ public->destroy(public);
+ }
+ else
+ {
+ DBG1("creating OCSP request failed, CA certificate has no public key");
+ }
+ return asn1_wrap(ASN1_SEQUENCE, "m", list);
+}
+
+/**
+ * build nonce extension
+ */
+static chunk_t build_nonce(private_x509_ocsp_request_t *this)
+{
+ rng_t *rng;
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (rng)
+ {
+ rng->allocate_bytes(rng, NONCE_LEN, &this->nonce);
+ rng->destroy(rng);
+ return asn1_wrap(ASN1_SEQUENCE, "cm", ASN1_nonce_oid,
+ asn1_simple_object(ASN1_OCTET_STRING, this->nonce));
+ }
+ DBG1("creating OCSP request nonce failed, no RNG found");
+ return chunk_empty;
+}
+
+/**
+ * build acceptableResponses extension
+ */
+static chunk_t build_acceptableResponses(private_x509_ocsp_request_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "cc",
+ ASN1_response_oid,
+ ASN1_response_content);
+}
+
+/**
+ * build requestExtensions
+ */
+static chunk_t build_requestExtensions(private_x509_ocsp_request_t *this)
+{
+ return asn1_wrap(ASN1_CONTEXT_C_2, "m",
+ asn1_wrap(ASN1_SEQUENCE, "mm",
+ build_nonce(this),
+ build_acceptableResponses(this)));
+}
+
+/**
+ * build tbsRequest
+ */
+static chunk_t build_tbsRequest(private_x509_ocsp_request_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "mmm",
+ build_requestorName(this),
+ build_requestList(this),
+ build_requestExtensions(this));
+}
+
+/**
+ * Build the optionalSignature
+ */
+static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this,
+ chunk_t tbsRequest)
+{
+ int oid;
+ signature_scheme_t scheme;
+ chunk_t certs, signature;
+
+ switch (this->key->get_type(this->key))
+ {
+ /* TODO: use a generic mapping function */
+ case KEY_RSA:
+ oid = OID_SHA1_WITH_RSA;
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ break;
+ case KEY_ECDSA:
+ oid = OID_ECDSA_WITH_SHA1;
+ scheme = SIGN_ECDSA_WITH_SHA1;
+ break;
+ default:
+ DBG1("unable to sign OCSP request, %N signature not supported",
+ key_type_names, this->key->get_type(this->key));
+ return chunk_empty;
+ }
+
+ if (!this->key->sign(this->key, scheme, tbsRequest, &signature))
+ {
+ DBG1("creating OCSP signature failed, skipped");
+ return chunk_empty;
+ }
+ if (this->cert)
+ {
+ certs = asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ asn1_wrap(ASN1_SEQUENCE, "m",
+ this->cert->get_encoding(this->cert)));
+ }
+ return asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ asn1_wrap(ASN1_SEQUENCE, "cmm",
+ asn1_algorithmIdentifier(oid),
+ asn1_bitstring("m", signature),
+ certs));
+}
+
+/**
+ * Build the OCSPRequest data
+ *
+ */
+static chunk_t build_OCSPRequest(private_x509_ocsp_request_t *this)
+{
+ chunk_t tbsRequest, optionalSignature = chunk_empty;
+
+ tbsRequest = build_tbsRequest(this);
+ if (this->key)
+ {
+ optionalSignature = build_optionalSignature(this, tbsRequest);
+ }
+ return asn1_wrap(ASN1_SEQUENCE, "mm", tbsRequest, optionalSignature);
+}
+
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_ocsp_request_t *this)
+{
+ return CERT_X509_OCSP_REQUEST;
+}
+
+/**
+ * Implementation of certificate_t.get_subject
+ */
+static identification_t* get_subject(private_x509_ocsp_request_t *this)
+{
+ certificate_t *ca = (certificate_t*)this->ca;
+
+ if (this->requestor)
+ {
+ return this->requestor;
+ }
+ if (this->cert)
+ {
+ return this->cert->get_subject(this->cert);
+ }
+ return ca->get_subject(ca);
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_ocsp_request_t *this)
+{
+ certificate_t *ca = (certificate_t*)this->ca;
+
+ return ca->get_subject(ca);
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_subject(private_x509_ocsp_request_t *this,
+ identification_t *subject)
+{
+ certificate_t *current;
+ enumerator_t *enumerator;
+ id_match_t match, best = ID_MATCH_NONE;
+
+ enumerator = this->candidates->create_enumerator(this->candidates);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ match = current->has_subject(current, subject);
+ if (match > best)
+ {
+ best = match;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return best;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_issuer(private_x509_ocsp_request_t *this,
+ identification_t *issuer)
+{
+ certificate_t *ca = (certificate_t*)this->ca;
+
+ return ca->has_subject(ca, issuer);
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_ocsp_request_t *this, certificate_t *issuer)
+{
+ DBG1("OCSP request validation not implemented!");
+ return FALSE;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_ocsp_request_t *this)
+{
+ return NULL;
+}
+
+/**
+ * Implementation of x509_cert_t.get_validity.
+ */
+static bool get_validity(private_x509_ocsp_request_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ certificate_t *cert;
+
+ if (this->cert)
+ {
+ cert = this->cert;
+ }
+ else
+ {
+ cert = (certificate_t*)this->ca;
+ }
+ return cert->get_validity(cert, when, not_before, not_after);
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_ocsp_request_t *this)
+{
+ return chunk_clone(this->encoding);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_ocsp_request_t *this, certificate_t *other)
+{
+ chunk_t encoding;
+ bool equal;
+
+ if (this == (private_x509_ocsp_request_t*)other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != CERT_X509_OCSP_REQUEST)
+ {
+ return FALSE;
+ }
+ if (other->equals == (void*)equals)
+ { /* skip allocation if we have the same implementation */
+ return chunk_equals(this->encoding, ((private_x509_ocsp_request_t*)other)->encoding);
+ }
+ encoding = other->get_encoding(other);
+ equal = chunk_equals(this->encoding, encoding);
+ free(encoding.ptr);
+ return equal;
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static private_x509_ocsp_request_t* get_ref(private_x509_ocsp_request_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of x509_ocsp_request_t.destroy
+ */
+static void destroy(private_x509_ocsp_request_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF((certificate_t*)this->ca);
+ DESTROY_IF(this->requestor);
+ DESTROY_IF(this->cert);
+ DESTROY_IF(this->key);
+ this->candidates->destroy_offset(this->candidates, offsetof(certificate_t, destroy));
+ chunk_free(&this->nonce);
+ chunk_free(&this->encoding);
+ free(this);
+ }
+}
+
+/**
+ * create an empty but initialized OCSP request
+ */
+static private_x509_ocsp_request_t *create_empty()
+{
+ private_x509_ocsp_request_t *this = malloc_thing(private_x509_ocsp_request_t);
+
+ this->public.interface.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.interface.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
+ this->public.interface.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.interface.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
+ this->public.interface.interface.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.interface.interface.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.interface.interface.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
+ this->public.interface.interface.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
+ this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.interface.interface.destroy = (void (*)(certificate_t *this))destroy;
+
+ this->ca = NULL;
+ this->requestor = NULL;
+ this->cert = NULL;
+ this->key = NULL;
+ this->nonce = chunk_empty;
+ this->encoding = chunk_empty;
+ this->candidates = linked_list_create();
+ this->ref = 1;
+
+ return this;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** OCSP request to build */
+ private_x509_ocsp_request_t *req;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static x509_ocsp_request_t *build(private_builder_t *this)
+{
+ private_x509_ocsp_request_t *req;
+
+ req = this->req;
+ free(this);
+ if (req->ca)
+ {
+ req->encoding = build_OCSPRequest(req);
+ return &req->public;
+ }
+ destroy(req);
+ return NULL;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+ certificate_t *cert;
+
+ va_start(args, part);
+ switch (part)
+ {
+ case BUILD_CA_CERT:
+ cert = va_arg(args, certificate_t*);
+ if (cert->get_type(cert) == CERT_X509)
+ {
+ this->req->ca = (x509_t*)cert;
+ }
+ else
+ {
+ cert->destroy(cert);
+ }
+ break;
+ case BUILD_CERT:
+ cert = va_arg(args, certificate_t*);
+ if (cert->get_type(cert) == CERT_X509)
+ {
+ this->req->candidates->insert_last(this->req->candidates, cert);
+ }
+ else
+ {
+ cert->destroy(cert);
+ }
+ break;
+ case BUILD_SIGNING_CERT:
+ this->req->cert = va_arg(args, certificate_t*);
+ break;
+ case BUILD_SIGNING_KEY:
+ this->req->key = va_arg(args, private_key_t*);
+ break;
+ case BUILD_SUBJECT:
+ this->req->requestor = va_arg(args, identification_t*);
+ break;
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+ va_end(args);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_ocsp_request_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_X509_OCSP_REQUEST)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->req = create_empty();
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.h b/src/libstrongswan/plugins/x509/x509_ocsp_request.h
new file mode 100644
index 000000000..0a4016f65
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup x509_ocsp_request x509_ocsp_request
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_OCSP_REQUEST_H_
+#define X509_OCSP_REQUEST_H_
+
+#include <credentials/certificates/ocsp_request.h>
+
+typedef struct x509_ocsp_request_t x509_ocsp_request_t;
+
+/**
+ * Implementation of ocsp_request_t using own ASN1 parser.
+ */
+struct x509_ocsp_request_t {
+
+ /**
+ * Implements the ocsp_request_t interface
+ */
+ ocsp_request_t interface;
+};
+
+/**
+ * Create the building facility for OCSP requests.
+ *
+ * The resulting builder accepts:
+ * BUILD_CA_CERT: CA of the checked certificates, exactly one
+ * BUILD_CERT: certificates to check with the request, at least one
+ * BUILD_SUBJECT: subject requesting check, optional
+ * BUILD_SIGNING_CERT: certificate to create requestor signature, optional
+ * BUILD_SIGNING_KEY: private key to create requestor signature, optional
+ *
+ * @param type certificate type, CERT_X509_OCSP_REQUEST only
+ * @return builder instance to build OCSP requests
+ */
+builder_t *x509_ocsp_request_builder(certificate_type_t type);
+
+#endif /* X509_OCSP_REQUEST_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
new file mode 100644
index 000000000..33cf73cd2
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
@@ -0,0 +1,990 @@
+/**
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 Andreas Steffen
+ * Hochschule für Technik Rapperswil
+ * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: x509_ocsp_response.c 4091 2008-06-22 17:41:07Z andreas $
+ */
+
+#include "x509_ocsp_response.h"
+
+#include <time.h>
+
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <utils/identification.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
+#include <library.h>
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+
+/**
+ * how long do we use an OCSP response without a nextUpdate
+ */
+#define OCSP_DEFAULT_LIFETIME 30
+
+typedef struct private_x509_ocsp_response_t private_x509_ocsp_response_t;
+
+/**
+ * Private data of a ocsp_t object.
+ */
+struct private_x509_ocsp_response_t {
+ /**
+ * Public interface for this ocsp object.
+ */
+ x509_ocsp_response_t public;
+
+ /**
+ * complete encoded OCSP response
+ */
+ chunk_t encoding;
+
+ /**
+ * data for signature verficiation
+ */
+ chunk_t tbsResponseData;
+
+ /**
+ * signature algorithm (OID)
+ */
+ int signatureAlgorithm;
+
+ /**
+ * signature
+ */
+ chunk_t signature;
+
+ /**
+ * name or keyid of the responder
+ */
+ identification_t *responderId;
+
+ /**
+ * time of response production
+ */
+ time_t producedAt;
+
+ /**
+ * latest nextUpdate in this OCSP response
+ */
+ time_t usableUntil;
+
+ /**
+ * list of included certificates
+ */
+ linked_list_t *certs;
+
+ /**
+ * Linked list of OCSP responses, single_response_t
+ */
+ linked_list_t *responses;
+
+ /**
+ * Nonce required for ocsp request and response
+ */
+ chunk_t nonce;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * single response contained in OCSP response
+ */
+typedef struct {
+ /** hash algorithm OID to for the two hashes */
+ int hashAlgorithm;
+ /** hash of issuer DN */
+ chunk_t issuerNameHash;
+ /** issuerKeyID */
+ chunk_t issuerKeyHash;
+ /** serial number of certificate */
+ chunk_t serialNumber;
+ /** OCSP certificate status */
+ cert_validation_t status;
+ /** time of revocation, if revoked */
+ time_t revocationTime;
+ /** revocation reason, if revoked */
+ crl_reason_t revocationReason;
+ /** creation of associated CRL */
+ time_t thisUpdate;
+ /** creation of next CRL */
+ time_t nextUpdate;
+} single_response_t;
+
+/* our OCSP response version implementation */
+#define OCSP_BASIC_RESPONSE_VERSION 1
+
+/* some OCSP specific prefabricated ASN.1 constants */
+static u_char ASN1_nonce_oid_str[] = {
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
+};
+
+static u_char ASN1_response_oid_str[] = {
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
+};
+
+static u_char ASN1_response_content_str[] = {
+ 0x04, 0x0D,
+ 0x30, 0x0B,
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
+};
+
+static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
+static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
+static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
+
+/**
+ * Implementaiton of ocsp_response_t.get_status
+ */
+static cert_validation_t get_status(private_x509_ocsp_response_t *this,
+ x509_t *subject, x509_t *issuer,
+ time_t *revocation_time,
+ crl_reason_t *revocation_reason,
+ time_t *this_update, time_t *next_update)
+{
+ enumerator_t *enumerator;
+ single_response_t *response;
+ cert_validation_t status = VALIDATION_FAILED;
+ certificate_t *issuercert = &issuer->interface;
+
+ enumerator = this->responses->create_enumerator(this->responses);
+ while (enumerator->enumerate(enumerator, &response))
+ {
+ hasher_t *hasher;
+ identification_t *id;
+ chunk_t hash;
+
+ /* check serial first, is cheaper */
+ if (!chunk_equals(subject->get_serial(subject), response->serialNumber))
+ {
+ continue;
+ }
+ /* check issuerKeyHash if available */
+ if (response->issuerKeyHash.ptr)
+ {
+ public_key_t *public;
+
+ public = issuercert->get_public_key(issuercert);
+ if (!public)
+ {
+ continue;
+ }
+ switch (response->hashAlgorithm)
+ { /* TODO: generic mapper function */
+ case OID_SHA1:
+ id = public->get_id(public, ID_PUBKEY_SHA1);
+ break;
+ default:
+ public->destroy(public);
+ continue;
+ }
+ if (!chunk_equals(response->issuerKeyHash, id->get_encoding(id)))
+ {
+ public->destroy(public);
+ continue;
+ }
+ public->destroy(public);
+ }
+ /* check issuerNameHash, if available */
+ else if (response->issuerNameHash.ptr)
+ {
+ hasher = lib->crypto->create_hasher(lib->crypto,
+ hasher_algorithm_from_oid(response->hashAlgorithm));
+ if (!hasher)
+ {
+ continue;
+ }
+ id = issuercert->get_subject(issuercert);
+ hasher->allocate_hash(hasher, id->get_encoding(id), &hash);
+ hasher->destroy(hasher);
+ if (!chunk_equals(hash, response->issuerNameHash))
+ {
+ continue;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ /* got a match */
+ status = response->status;
+ *revocation_time = response->revocationTime;
+ *revocation_reason = response->revocationReason;
+ *this_update = response->thisUpdate;
+ *next_update = response->nextUpdate;
+
+ break;
+ }
+ enumerator->destroy(enumerator);
+ return status;
+}
+
+/**
+ * Implementation of ocsp_response_t.create_cert_enumerator.
+ */
+static enumerator_t* create_cert_enumerator(private_x509_ocsp_response_t *this)
+{
+ return this->certs->create_enumerator(this->certs);
+}
+
+/**
+ * ASN.1 definition of singleResponse
+ */
+static const asn1Object_t singleResponseObjects[] = {
+ { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
+ { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
+ { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
+ { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
+ { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
+ { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
+ { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
+ { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
+ { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
+ { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
+ { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
+ { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
+ { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
+ { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
+ { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
+ { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
+ { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
+ { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
+ { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
+ ASN1_DEF }, /* 24 */
+ { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define SINGLE_RESPONSE_ALGORITHM 2
+#define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
+#define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
+#define SINGLE_RESPONSE_SERIAL_NUMBER 5
+#define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
+#define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
+#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
+#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
+#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
+#define SINGLE_RESPONSE_THIS_UPDATE 16
+#define SINGLE_RESPONSE_NEXT_UPDATE 18
+#define SINGLE_RESPONSE_EXT_ID 23
+#define SINGLE_RESPONSE_CRITICAL 24
+#define SINGLE_RESPONSE_EXT_VALUE 25
+
+/**
+ * Parse a single OCSP response
+ */
+static bool parse_singleResponse(private_x509_ocsp_response_t *this,
+ chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool success = FALSE;
+
+ single_response_t *response;
+
+ response = malloc_thing(single_response_t);
+ response->hashAlgorithm = OID_UNKNOWN;
+ response->issuerNameHash = chunk_empty;
+ response->issuerKeyHash = chunk_empty;
+ response->serialNumber = chunk_empty;
+ response->status = VALIDATION_FAILED;
+ response->revocationTime = 0;
+ response->revocationReason = CRL_UNSPECIFIED;
+ response->thisUpdate = UNDEFINED_TIME;
+ /* if nextUpdate is missing, we give it a short lifetime */
+ response->nextUpdate = this->producedAt + OCSP_DEFAULT_LIFETIME;
+
+ parser = asn1_parser_create(singleResponseObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case SINGLE_RESPONSE_ALGORITHM:
+ response->hashAlgorithm = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
+ break;
+ case SINGLE_RESPONSE_ISSUER_NAME_HASH:
+ response->issuerNameHash = object;
+ break;
+ case SINGLE_RESPONSE_ISSUER_KEY_HASH:
+ response->issuerKeyHash = object;
+ break;
+ case SINGLE_RESPONSE_SERIAL_NUMBER:
+ response->serialNumber = object;
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_GOOD:
+ response->status = VALIDATION_GOOD;
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
+ response->status = VALIDATION_REVOKED;
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
+ response->revocationTime = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
+ if (object.len == 1)
+ {
+ response->revocationReason = *object.ptr;
+ }
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
+ response->status = VALIDATION_FAILED;
+ break;
+ case SINGLE_RESPONSE_THIS_UPDATE:
+ response->thisUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case SINGLE_RESPONSE_NEXT_UPDATE:
+ response->nextUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ if (response->nextUpdate > this->usableUntil)
+ {
+ this->usableUntil = response->nextUpdate;
+ }
+ break;
+ }
+ }
+ success = parser->success(parser);
+ parser->destroy(parser);
+ if (success)
+ {
+ if (this->usableUntil == UNDEFINED_TIME)
+ {
+ this->usableUntil = this->producedAt + OCSP_DEFAULT_LIFETIME;
+ }
+ this->responses->insert_last(this->responses, response);
+ }
+ return success;
+}
+
+/**
+ * ASN.1 definition of responses
+ */
+static const asn1Object_t responsesObjects[] = {
+ { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define RESPONSES_SINGLE_RESPONSE 1
+
+/**
+ * Parse all responses
+ */
+static bool parse_responses(private_x509_ocsp_response_t *this,
+ chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool success = FALSE;
+
+ parser = asn1_parser_create(responsesObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case RESPONSES_SINGLE_RESPONSE:
+ if (!parse_singleResponse(this, object,
+ parser->get_level(parser)+1))
+ {
+ goto end;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * ASN.1 definition of basicResponse
+ */
+static const asn1Object_t basicResponseObjects[] = {
+ { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
+ ASN1_DEF }, /* 2 */
+ { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
+ { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
+ { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
+ { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
+ { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
+ { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
+ { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
+ { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
+ { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
+ { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
+ ASN1_DEF }, /* 16 */
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
+ { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
+ { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
+ { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
+ { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
+ { 3, "certificate", ASN1_SEQUENCE, ASN1_RAW }, /* 24 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define BASIC_RESPONSE_TBS_DATA 1
+#define BASIC_RESPONSE_VERSION 3
+#define BASIC_RESPONSE_ID_BY_NAME 5
+#define BASIC_RESPONSE_ID_BY_KEY 8
+#define BASIC_RESPONSE_PRODUCED_AT 10
+#define BASIC_RESPONSE_RESPONSES 11
+#define BASIC_RESPONSE_EXT_ID 15
+#define BASIC_RESPONSE_CRITICAL 16
+#define BASIC_RESPONSE_EXT_VALUE 17
+#define BASIC_RESPONSE_ALGORITHM 20
+#define BASIC_RESPONSE_SIGNATURE 21
+#define BASIC_RESPONSE_CERTIFICATE 24
+
+/**
+ * Parse a basicOCSPResponse
+ */
+static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
+ chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ chunk_t responses = chunk_empty;
+ int objectID;
+ int extn_oid = OID_UNKNOWN;
+ u_int responses_level = level0;
+ certificate_t *cert;
+ bool success = FALSE;
+ bool critical;
+
+ parser = asn1_parser_create(basicResponseObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case BASIC_RESPONSE_TBS_DATA:
+ this->tbsResponseData = object;
+ break;
+ case BASIC_RESPONSE_VERSION:
+ {
+ u_int version = (object.len)? (1 + (u_int)*object.ptr) : 1;
+
+ if (version != OCSP_BASIC_RESPONSE_VERSION)
+ {
+ DBG1(" ocsp ResponseData version %d not supported", version);
+ goto end;
+ }
+ break;
+ }
+ case BASIC_RESPONSE_ID_BY_NAME:
+ this->responderId = identification_create_from_encoding(
+ ID_DER_ASN1_DN, object);
+ DBG2(" '%D'", this->responderId);
+ break;
+ case BASIC_RESPONSE_ID_BY_KEY:
+ this->responderId = identification_create_from_encoding(
+ ID_PUBKEY_INFO_SHA1, object);
+ DBG2(" '%D'", this->responderId);
+ break;
+ case BASIC_RESPONSE_PRODUCED_AT:
+ this->producedAt = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case BASIC_RESPONSE_RESPONSES:
+ responses = object;
+ responses_level = parser->get_level(parser)+1;
+ break;
+ case BASIC_RESPONSE_EXT_ID:
+ extn_oid = asn1_known_oid(object);
+ break;
+ case BASIC_RESPONSE_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG2(" %s", critical ? "TRUE" : "FALSE");
+ break;
+ case BASIC_RESPONSE_EXT_VALUE:
+ if (extn_oid == OID_NONCE)
+ {
+ this->nonce = object;
+ }
+ break;
+ case BASIC_RESPONSE_ALGORITHM:
+ this->signatureAlgorithm = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
+ break;
+ case BASIC_RESPONSE_SIGNATURE:
+ this->signature = object;
+ break;
+ case BASIC_RESPONSE_CERTIFICATE:
+ {
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,CERT_X509,
+ BUILD_BLOB_ASN1_DER,
+ chunk_clone(object),
+ BUILD_END);
+ if (cert)
+ {
+ this->certs->insert_last(this->certs, cert);
+ }
+ break;
+ }
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ if (success)
+ {
+ if (!this->responderId)
+ {
+ this->responderId = identification_create_from_encoding(ID_ANY,
+ chunk_empty);
+ }
+ success = parse_responses(this, responses, responses_level);
+ }
+ return success;
+}
+
+/**
+ * ASN.1 definition of ocspResponse
+ */
+static const asn1Object_t ocspResponseObjects[] = {
+ { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
+ { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
+ { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
+ { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
+ { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define OCSP_RESPONSE_STATUS 1
+#define OCSP_RESPONSE_TYPE 4
+#define OCSP_RESPONSE 5
+
+/**
+ * Parse OCSPResponse object
+ */
+static bool parse_OCSPResponse(private_x509_ocsp_response_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int responseType = OID_UNKNOWN;
+ bool success = FALSE;
+ ocsp_status_t status;
+
+ parser = asn1_parser_create(ocspResponseObjects, this->encoding);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case OCSP_RESPONSE_STATUS:
+ status = (ocsp_status_t)*object.ptr;
+ switch (status)
+ {
+ case OCSP_SUCCESSFUL:
+ break;
+ default:
+ DBG1(" ocsp response status: %N",
+ ocsp_status_names, status);
+ goto end;
+ }
+ break;
+ case OCSP_RESPONSE_TYPE:
+ responseType = asn1_known_oid(object);
+ break;
+ case OCSP_RESPONSE:
+ switch (responseType)
+ {
+ case OID_BASIC:
+ success = parse_basicOCSPResponse(this, object,
+ parser->get_level(parser)+1);
+ break;
+ default:
+ DBG1(" ocsp response type %#B not supported", &object);
+ goto end;
+ }
+ break;
+ }
+ }
+ success &= parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_ocsp_response_t *this)
+{
+ return CERT_X509_OCSP_RESPONSE;
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_ocsp_response_t *this)
+{
+ return this->responderId;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_issuer(private_x509_ocsp_response_t *this,
+ identification_t *issuer)
+{
+ return this->responderId->matches(this->responderId, issuer);
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer)
+{
+ public_key_t *key;
+ signature_scheme_t scheme;
+ bool valid;
+ x509_t *x509 = (x509_t*)issuer;
+
+ if (issuer->get_type(issuer) != CERT_X509)
+ {
+ return FALSE;
+ }
+ if (this->responderId->get_type(this->responderId) == ID_DER_ASN1_DN)
+ {
+ if (!this->responderId->equals(this->responderId,
+ issuer->get_subject(issuer)))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ bool equal;
+ public_key_t *public = issuer->get_public_key(issuer);
+
+ if (public == NULL)
+ {
+ return FALSE;
+ }
+ equal = this->responderId->equals(this->responderId,
+ public->get_id(public, ID_PUBKEY_SHA1));
+ public->destroy(public);
+ if (!equal)
+ {
+ return FALSE;
+ }
+ }
+ if (!(x509->get_flags(x509) & X509_OCSP_SIGNER) &&
+ !(x509->get_flags(x509) & X509_CA))
+ {
+ return FALSE;
+ }
+ /* TODO: generic OID to scheme mapper? */
+ switch (this->signatureAlgorithm)
+ {
+ case OID_MD5_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_MD5;
+ break;
+ case OID_SHA1_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ break;
+ case OID_SHA256_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
+ break;
+ case OID_SHA384_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
+ break;
+ case OID_SHA512_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
+ break;
+ case OID_ECDSA_WITH_SHA1:
+ scheme = SIGN_ECDSA_WITH_SHA1;
+ break;
+ default:
+ return FALSE;
+ }
+ key = issuer->get_public_key(issuer);
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ valid = key->verify(key, scheme, this->tbsResponseData, this->signature);
+ key->destroy(key);
+ return valid;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_ocsp_response_t *this)
+{
+ return NULL;
+}
+
+/**
+ * Implementation of certificate_t.get_validity.
+ */
+static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ time_t t;
+
+ if (when == NULL)
+ {
+ t = time(NULL);
+ }
+ else
+ {
+ t = *when;
+ }
+ if (not_before)
+ {
+ *not_before = this->producedAt;
+ }
+ if (not_after)
+ {
+ *not_after = this->usableUntil;
+ }
+ return (t < this->usableUntil);
+}
+
+/**
+ * Implementation of certificate_t.is_newer.
+ */
+static bool is_newer(certificate_t *this, certificate_t *that)
+{
+ time_t this_update, that_update, now = time(NULL);
+ bool new;
+
+ this->get_validity(this, &now, &this_update, NULL);
+ that->get_validity(that, &now, &that_update, NULL);
+ new = this_update > that_update;
+ DBG1(" ocsp response from %#T is %s - existing ocsp response from %#T %s",
+ &this_update, FALSE, new ? "newer":"not newer",
+ &that_update, FALSE, new ? "replaced":"retained");
+ return new;
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_ocsp_response_t *this)
+{
+ return chunk_clone(this->encoding);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_ocsp_response_t *this, certificate_t *other)
+{
+ chunk_t encoding;
+ bool equal;
+
+ if (this == (private_x509_ocsp_response_t*)other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != CERT_X509_OCSP_RESPONSE)
+ {
+ return FALSE;
+ }
+ if (other->equals == (void*)equals)
+ { /* skip allocation if we have the same implementation */
+ return chunk_equals(this->encoding, ((private_x509_ocsp_response_t*)other)->encoding);
+ }
+ encoding = other->get_encoding(other);
+ equal = chunk_equals(this->encoding, encoding);
+ free(encoding.ptr);
+ return equal;
+}
+
+/**
+ * Implementation of certificate_t.get_ref
+ */
+static private_x509_ocsp_response_t* get_ref(private_x509_ocsp_response_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implements ocsp_t.destroy.
+ */
+static void destroy(private_x509_ocsp_response_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
+ this->responses->destroy_function(this->responses, free);
+ DESTROY_IF(this->responderId);
+ free(this->encoding.ptr);
+ free(this);
+ }
+}
+
+/**
+ * load an OCSP response
+ */
+static x509_ocsp_response_t *load(chunk_t data)
+{
+ private_x509_ocsp_response_t *this;
+
+ this = malloc_thing(private_x509_ocsp_response_t);
+
+ this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_issuer;
+ this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
+ this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
+ this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
+ this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
+ this->public.interface.get_status = (cert_validation_t(*)(ocsp_response_t*, x509_t *subject, x509_t *issuer, time_t *revocation_time,crl_reason_t *revocation_reason,time_t *this_update, time_t *next_update))get_status;
+ this->public.interface.create_cert_enumerator = (enumerator_t*(*)(ocsp_response_t*))create_cert_enumerator;
+
+ this->ref = 1;
+ this->encoding = data;
+ this->tbsResponseData = chunk_empty;
+ this->responderId = NULL;
+ this->producedAt = UNDEFINED_TIME;
+ this->usableUntil = UNDEFINED_TIME;
+ this->responses = linked_list_create();
+ this->nonce = chunk_empty;
+ this->signatureAlgorithm = OID_UNKNOWN;
+ this->signature = chunk_empty;
+ this->certs = linked_list_create();
+
+ if (!parse_OCSPResponse(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded response */
+ x509_ocsp_response_t *res;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static x509_ocsp_response_t *build(private_builder_t *this)
+{
+ x509_ocsp_response_t *res = this->res;
+
+ free(this);
+ return res;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->res)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->res = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_ocsp_response_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_X509_OCSP_RESPONSE)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->res = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.h b/src/libstrongswan/plugins/x509/x509_ocsp_response.h
new file mode 100644
index 000000000..8b4c8328d
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup x509_ocsp_response x509_ocsp_response
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_OCSP_RESPONSE_H_
+#define X509_OCSP_RESPONSE_H_
+
+#include <credentials/certificates/ocsp_response.h>
+
+typedef struct x509_ocsp_response_t x509_ocsp_response_t;
+
+/**
+ * Implementation of ocsp_response_t using own ASN1 parser.
+ */
+struct x509_ocsp_response_t {
+
+ /**
+ * Implements the ocsp_response_t interface
+ */
+ ocsp_response_t interface;
+};
+
+/**
+ * Create the building facility for OCSP responses.
+ *
+ * @param type certificate type, CERT_X509_OCSP_RESPONSE only
+ * @return builder instance to build OCSP responses
+ */
+builder_t *x509_ocsp_response_builder(certificate_type_t type);
+
+#endif /* X509_OCSP_RESPONSE_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_plugin.c b/src/libstrongswan/plugins/x509/x509_plugin.c
new file mode 100644
index 000000000..42768487d
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_plugin.c
@@ -0,0 +1,80 @@
+/*
+ * 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: x509_plugin.c 3640 2008-03-21 10:52:11Z andreas $
+ */
+
+#include "x509_plugin.h"
+
+#include <library.h>
+#include "x509_cert.h"
+#include "x509_ac.h"
+#include "x509_crl.h"
+#include "x509_ocsp_request.h"
+#include "x509_ocsp_response.h"
+
+typedef struct private_x509_plugin_t private_x509_plugin_t;
+
+/**
+ * private data of x509_plugin
+ */
+struct private_x509_plugin_t {
+
+ /**
+ * public functions
+ */
+ x509_plugin_t public;
+};
+
+/**
+ * Implementation of x509_plugin_t.x509troy
+ */
+static void destroy(private_x509_plugin_t *this)
+{
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)x509_cert_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)x509_ac_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)x509_crl_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)x509_ocsp_request_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)x509_ocsp_response_builder);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_x509_plugin_t *this = malloc_thing(private_x509_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ (builder_constructor_t)x509_cert_builder);
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
+ (builder_constructor_t)x509_ac_builder);
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+ (builder_constructor_t)x509_crl_builder);
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
+ (builder_constructor_t)x509_ocsp_request_builder);
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
+ (builder_constructor_t)x509_ocsp_response_builder);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_plugin.h b/src/libstrongswan/plugins/x509/x509_plugin.h
new file mode 100644
index 000000000..9743a2367
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup x509_p x509
+ * @ingroup plugins
+ *
+ * @defgroup x509_plugin x509_plugin
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_PLUGIN_H_
+#define X509_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct x509_plugin_t x509_plugin_t;
+
+/**
+ * Plugin implementing x509, CRL and OCSP certificates.
+ */
+struct x509_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a x509_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* X509_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/xcbc/Makefile.am b/src/libstrongswan/plugins/xcbc/Makefile.am
new file mode 100644
index 000000000..1b10d21f8
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-xcbc.la
+
+libstrongswan_xcbc_la_SOURCES = xcbc_plugin.h xcbc_plugin.c xcbc.h xcbc.c \
+ xcbc_prf.h xcbc_prf.c xcbc_signer.h xcbc_signer.c
+libstrongswan_xcbc_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in
new file mode 100644
index 000000000..3fdf46955
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/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/libstrongswan/plugins/xcbc
+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_xcbc_la_LIBADD =
+am_libstrongswan_xcbc_la_OBJECTS = xcbc_plugin.lo xcbc.lo xcbc_prf.lo \
+ xcbc_signer.lo
+libstrongswan_xcbc_la_OBJECTS = $(am_libstrongswan_xcbc_la_OBJECTS)
+libstrongswan_xcbc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_xcbc_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_xcbc_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_xcbc_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
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-xcbc.la
+libstrongswan_xcbc_la_SOURCES = xcbc_plugin.h xcbc_plugin.c xcbc.h xcbc.c \
+ xcbc_prf.h xcbc_prf.c xcbc_signer.h xcbc_signer.c
+
+libstrongswan_xcbc_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/libstrongswan/plugins/xcbc/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/xcbc/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-xcbc.la: $(libstrongswan_xcbc_la_OBJECTS) $(libstrongswan_xcbc_la_DEPENDENCIES)
+ $(libstrongswan_xcbc_la_LINK) -rpath $(plugindir) $(libstrongswan_xcbc_la_OBJECTS) $(libstrongswan_xcbc_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcbc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcbc_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcbc_prf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcbc_signer.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/libstrongswan/plugins/xcbc/xcbc.c b/src/libstrongswan/plugins/xcbc/xcbc.c
new file mode 100644
index 000000000..ab37eca40
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc.c
@@ -0,0 +1,299 @@
+/*
+ * 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 xcbc License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General xcbc License
+ * for more details.
+ *
+ * $Id: xcbc.c 3589 2008-03-13 14:14:44Z martin $
+ */
+
+#include <string.h>
+
+#include "xcbc.h"
+
+#include <debug.h>
+
+typedef struct private_xcbc_t private_xcbc_t;
+
+/**
+ * Private data of a xcbc_t object.
+ *
+ * The variable names are the same as in the RFC.
+ */
+struct private_xcbc_t {
+ /**
+ * Public xcbc_t interface.
+ */
+ xcbc_t xcbc;
+
+ /**
+ * Block size, in bytes
+ */
+ u_int8_t b;
+
+ /**
+ * crypter using k1
+ */
+ crypter_t *k1;
+
+ /**
+ * k2
+ */
+ u_int8_t *k2;
+
+ /**
+ * k3
+ */
+ u_int8_t *k3;
+
+ /**
+ * E
+ */
+ u_int8_t *e;
+
+ /**
+ * remaining, unprocessed bytes in append mode
+ */
+ u_int8_t *remaining;
+
+ /**
+ * number of bytes in remaining
+ */
+ int remaining_bytes;
+
+ /**
+ * TRUE if we have zero bytes to xcbc in final()
+ */
+ bool zero;
+};
+
+/**
+ * xcbc supplied data, but do not run final operation
+ */
+static void update(private_xcbc_t *this, chunk_t data)
+{
+ chunk_t iv;
+
+ if (data.len)
+ {
+ this->zero = FALSE;
+ }
+
+ if (this->remaining_bytes + data.len <= this->b)
+ { /* no complete block, just copy into remaining */
+ memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len);
+ this->remaining_bytes += data.len;
+ return;
+ }
+
+ iv = chunk_alloca(this->b);
+ memset(iv.ptr, 0, iv.len);
+
+ /* (3) For each block M[i], where i = 1 ... n-1:
+ * XOR M[i] with E[i-1], then encrypt the result with Key K1,
+ * yielding E[i].
+ */
+
+ /* append data to remaining bytes, process block M[1] */
+ memcpy(this->remaining + this->remaining_bytes, data.ptr,
+ this->b - this->remaining_bytes);
+ data = chunk_skip(data, this->b - this->remaining_bytes);
+ memxor(this->e, this->remaining, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
+
+ /* process blocks M[2] ... M[n-1] */
+ while (data.len > this->b)
+ {
+ memcpy(this->remaining, data.ptr, this->b);
+ data = chunk_skip(data, this->b);
+ memxor(this->e, this->remaining, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
+ }
+
+ /* store remaining bytes of block M[n] */
+ memcpy(this->remaining, data.ptr, data.len);
+ this->remaining_bytes = data.len;
+}
+
+/**
+ * run last round, data is in this->e
+ */
+static void final(private_xcbc_t *this, u_int8_t *out)
+{
+ chunk_t iv;
+
+ iv = chunk_alloca(this->b);
+ memset(iv.ptr, 0, iv.len);
+
+ /* (4) For block M[n]: */
+ if (this->remaining_bytes == this->b && !this->zero)
+ {
+ /* a) If the blocksize of M[n] is 128 bits:
+ * XOR M[n] with E[n-1] and Key K2, then encrypt the result with
+ * Key K1, yielding E[n].
+ */
+ memxor(this->e, this->remaining, this->b);
+ memxor(this->e, this->k2, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
+ }
+ else
+ {
+ /* b) If the blocksize of M[n] is less than 128 bits:
+ *
+ * i) Pad M[n] with a single "1" bit, followed by the number of
+ * "0" bits (possibly none) required to increase M[n]'s
+ * blocksize to 128 bits.
+ */
+ if (this->remaining_bytes < this->b)
+ {
+ this->remaining[this->remaining_bytes] = 0x80;
+ while (++this->remaining_bytes < this->b)
+ {
+ this->remaining[this->remaining_bytes] = 0x00;
+ }
+ }
+ /* ii) XOR M[n] with E[n-1] and Key K3, then encrypt the result
+ * with Key K1, yielding E[n].
+ */
+ memxor(this->e, this->remaining, this->b);
+ memxor(this->e, this->k3, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
+ }
+
+ memcpy(out, this->e, this->b);
+
+ /* (2) Define E[0] = 0x00000000000000000000000000000000 */
+ memset(this->e, 0, this->b);
+ this->remaining_bytes = 0;
+ this->zero = TRUE;
+}
+
+/**
+ * Implementation of xcbc_t.get_mac.
+ */
+static void get_mac(private_xcbc_t *this, chunk_t data, u_int8_t *out)
+{
+ /* update E, do not process last block */
+ update(this, data);
+
+ if (out)
+ { /* if not in append mode, process last block and output result */
+ final(this, out);
+ }
+}
+
+/**
+ * Implementation of xcbc_t.get_block_size.
+ */
+static size_t get_block_size(private_xcbc_t *this)
+{
+ return this->b;
+}
+
+/**
+ * Implementation of xcbc_t.set_key.
+ */
+static void set_key(private_xcbc_t *this, chunk_t key)
+{
+ chunk_t iv, k1, lengthened;
+
+ /* we support variable keys from RFC4434 */
+ if (key.len == this->b)
+ {
+ lengthened = key;
+ }
+ else if (key.len < this->b)
+ { /* pad short keys */
+ lengthened = chunk_alloca(this->b);
+ memset(lengthened.ptr, 0, lengthened.len);
+ memcpy(lengthened.ptr, key.ptr, key.len);
+ }
+ else
+ { /* shorten key using xcbc */
+ lengthened = chunk_alloca(this->b);
+ memset(lengthened.ptr, 0, lengthened.len);
+ set_key(this, lengthened);
+ get_mac(this, key, lengthened.ptr);
+ }
+
+ k1 = chunk_alloca(this->b);
+ iv = chunk_alloca(this->b);
+ memset(iv.ptr, 0, iv.len);
+
+ /*
+ * (1) Derive 3 128-bit keys (K1, K2 and K3) from the 128-bit secret
+ * key K, as follows:
+ * K1 = 0x01010101010101010101010101010101 encrypted with Key K
+ * K2 = 0x02020202020202020202020202020202 encrypted with Key K
+ * K3 = 0x03030303030303030303030303030303 encrypted with Key K
+ */
+ this->k1->set_key(this->k1, lengthened);
+ memset(this->k2, 0x02, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->k2, this->b), iv, NULL);
+ memset(this->k3, 0x03, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->k3, this->b), iv, NULL);
+ memset(k1.ptr, 0x01, this->b);
+ this->k1->encrypt(this->k1, k1, iv, NULL);
+ this->k1->set_key(this->k1, k1);
+}
+
+/**
+ * Implementation of xcbc_t.destroy.
+ */
+static void destroy(private_xcbc_t *this)
+{
+ this->k1->destroy(this->k1);
+ free(this->k2);
+ free(this->k3);
+ free(this->e);
+ free(this->remaining);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+xcbc_t *xcbc_create(encryption_algorithm_t algo, size_t key_size)
+{
+ private_xcbc_t *this;
+ crypter_t *crypter;
+
+ crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size);
+ if (!crypter)
+ {
+ return NULL;
+ }
+ /* input and output of crypter must be equal for xcbc */
+ if (crypter->get_block_size(crypter) != key_size)
+ {
+ crypter->destroy(crypter);
+ return NULL;
+ }
+
+ this = malloc_thing(private_xcbc_t);
+ this->xcbc.get_mac = (void (*)(xcbc_t *,chunk_t,u_int8_t*))get_mac;
+ this->xcbc.get_block_size = (size_t (*)(xcbc_t *))get_block_size;
+ this->xcbc.set_key = (void (*)(xcbc_t *,chunk_t))set_key;
+ this->xcbc.destroy = (void (*)(xcbc_t *))destroy;
+
+ this->b = crypter->get_block_size(crypter);
+ this->k1 = crypter;
+ this->k2 = malloc(this->b);
+ this->k3 = malloc(this->b);
+ this->e = malloc(this->b);
+ memset(this->e, 0, this->b);
+ this->remaining = malloc(this->b);
+ this->remaining_bytes = 0;
+ this->zero = TRUE;
+
+ return &this->xcbc;
+}
+
diff --git a/src/libstrongswan/plugins/xcbc/xcbc.h b/src/libstrongswan/plugins/xcbc/xcbc.h
new file mode 100644
index 000000000..81812442e
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc.h
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup xcbc xcbc
+ * @{ @ingroup xcbc_p
+ */
+
+#ifndef XCBC_H_
+#define XCBC_H_
+
+typedef struct xcbc_t xcbc_t;
+
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Message authentication using CBC crypter.
+ *
+ * This class implements the message authenticaion algorithm
+ * described in RFC3566.
+ */
+struct xcbc_t {
+
+ /**
+ * Generate message authentication code.
+ *
+ * If buffer is NULL, no result is given back. A next call will
+ * append the data to already supplied data. If buffer is not NULL,
+ * the mac of all apended data is calculated, returned and the
+ * state of the xcbc_t is reseted.
+ *
+ * @param data chunk of data to authenticate
+ * @param buffer pointer where the generated bytes will be written
+ */
+ void (*get_mac) (xcbc_t *this, chunk_t data, u_int8_t *buffer);
+
+ /**
+ * Get the block size of this xcbc_t object.
+ *
+ * @return block size in bytes
+ */
+ size_t (*get_block_size) (xcbc_t *this);
+
+ /**
+ * Set the key for this xcbc_t object.
+ *
+ * @param key key to set
+ */
+ void (*set_key) (xcbc_t *this, chunk_t key);
+
+ /**
+ * Destroys a xcbc_t object.
+ */
+ void (*destroy) (xcbc_t *this);
+};
+
+/**
+ * Creates a new xcbc_t object.
+ *
+ * @param algo underlying crypto algorithm
+ * @param key_size key size to use, if required for algorithm
+ * @return xcbc_t object, NULL if not supported
+ */
+xcbc_t *xcbc_create(encryption_algorithm_t algo, size_t key_size);
+
+#endif /*xcbc_H_ @}*/
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_plugin.c b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c
new file mode 100644
index 000000000..f1501476f
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c
@@ -0,0 +1,65 @@
+/*
+ * 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 "xcbc_plugin.h"
+
+#include <library.h>
+#include "xcbc_signer.h"
+#include "xcbc_prf.h"
+
+typedef struct private_xcbc_plugin_t private_xcbc_plugin_t;
+
+/**
+ * private data of xcbc_plugin
+ */
+struct private_xcbc_plugin_t {
+
+ /**
+ * public functions
+ */
+ xcbc_plugin_t public;
+};
+
+/**
+ * Implementation of xcbc_plugin_t.xcbctroy
+ */
+static void destroy(private_xcbc_plugin_t *this)
+{
+ lib->crypto->remove_prf(lib->crypto,
+ (prf_constructor_t)xcbc_prf_create);
+ lib->crypto->remove_signer(lib->crypto,
+ (signer_constructor_t)xcbc_signer_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_xcbc_plugin_t *this = malloc_thing(private_xcbc_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_prf(lib->crypto, PRF_AES128_XCBC,
+ (prf_constructor_t)xcbc_prf_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_AES_XCBC_96,
+ (signer_constructor_t)xcbc_signer_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_plugin.h b/src/libstrongswan/plugins/xcbc/xcbc_plugin.h
new file mode 100644
index 000000000..728d84690
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup xcbc_p xcbc
+ * @ingroup plugins
+ *
+ * @defgroup xcbc_plugin xcbc_plugin
+ * @{ @ingroup xcbc_p
+ */
+
+#ifndef XCBC_PLUGIN_H_
+#define XCBC_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct xcbc_plugin_t xcbc_plugin_t;
+
+/**
+ * Plugin implementing xcbc algorithm to provide crypter based PRF and signers.
+ */
+struct xcbc_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a xcbc_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* XCBC_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_prf.c b/src/libstrongswan/plugins/xcbc/xcbc_prf.c
new file mode 100644
index 000000000..03056594d
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_prf.c
@@ -0,0 +1,131 @@
+/*
+ * 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 "xcbc_prf.h"
+
+#include "xcbc.h"
+
+typedef struct private_xcbc_prf_t private_xcbc_prf_t;
+
+/**
+ * Private data of a xcbc_prf_t object.
+ */
+struct private_xcbc_prf_t {
+
+ /**
+ * Public xcbc_prf_t interface.
+ */
+ xcbc_prf_t public;
+
+ /**
+ * xcbc to use for generation.
+ */
+ xcbc_t *xcbc;
+};
+
+/**
+ * Implementation of prf_t.get_bytes.
+ */
+static void get_bytes(private_xcbc_prf_t *this, chunk_t seed, u_int8_t *buffer)
+{
+ this->xcbc->get_mac(this->xcbc, seed, buffer);
+}
+
+/**
+ * Implementation of prf_t.allocate_bytes.
+ */
+static void allocate_bytes(private_xcbc_prf_t *this, chunk_t seed, chunk_t *chunk)
+{
+ if (chunk)
+ {
+ *chunk = chunk_alloc(this->xcbc->get_block_size(this->xcbc));
+ get_bytes(this, seed, chunk->ptr);
+ }
+ else
+ {
+ get_bytes(this, seed, NULL);
+ }
+}
+
+/**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_block_size(private_xcbc_prf_t *this)
+{
+ return this->xcbc->get_block_size(this->xcbc);
+}
+
+/**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_key_size(private_xcbc_prf_t *this)
+{
+ /* in xcbc, block and key size are always equal */
+ return this->xcbc->get_block_size(this->xcbc);
+}
+
+/**
+ * Implementation of prf_t.set_key.
+ */
+static void set_key(private_xcbc_prf_t *this, chunk_t key)
+{
+ this->xcbc->set_key(this->xcbc, key);
+}
+
+/**
+ * Implementation of prf_t.destroy.
+ */
+static void destroy(private_xcbc_prf_t *this)
+{
+ this->xcbc->destroy(this->xcbc);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+xcbc_prf_t *xcbc_prf_create(pseudo_random_function_t algo)
+{
+ private_xcbc_prf_t *this;
+ xcbc_t *xcbc;
+
+ switch (algo)
+ {
+ case PRF_AES128_XCBC:
+ xcbc = xcbc_create(ENCR_AES_CBC, 16);
+ break;
+ default:
+ return NULL;
+ }
+ if (!xcbc)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_xcbc_prf_t);
+ this->xcbc = xcbc;
+
+ this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
+ this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
+ this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
+ this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
+ this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
+ this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_prf.h b/src/libstrongswan/plugins/xcbc/xcbc_prf.h
new file mode 100644
index 000000000..e8692ae23
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_prf.h
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup xcbc_prf xcbc_prf
+ * @{ @ingroup xcbc_p
+ */
+
+#ifndef PRF_XCBC_H_
+#define PRF_XCBC_H_
+
+typedef struct xcbc_prf_t xcbc_prf_t;
+
+#include <crypto/prfs/prf.h>
+
+/**
+ * Implementation of prf_t on CBC block cipher using XCBC, RFC3664/RFC4434.
+ *
+ * This simply wraps a xcbc_t in a prf_t. More a question of
+ * interface matching.
+ */
+struct xcbc_prf_t {
+
+ /**
+ * Generic prf_t interface for this xcbc_prf_t class.
+ */
+ prf_t prf_interface;
+};
+
+/**
+ * Creates a new xcbc_prf_t object.
+ *
+ * @param algo algorithm to implement
+ * @return xcbc_prf_t object, NULL if hash not supported
+ */
+xcbc_prf_t *xcbc_prf_create(pseudo_random_function_t algo);
+
+#endif /*PRF_XCBC_SHA1_H_ @}*/
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_signer.c b/src/libstrongswan/plugins/xcbc/xcbc_signer.c
new file mode 100644
index 000000000..29eb2d25b
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_signer.c
@@ -0,0 +1,177 @@
+/*
+ * 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 "xcbc_signer.h"
+#include "xcbc.h"
+
+typedef struct private_xcbc_signer_t private_xcbc_signer_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_xcbc_signer_t {
+
+ /**
+ * Public interface of xcbc_signer_t.
+ */
+ xcbc_signer_t public;
+
+ /**
+ * Assigned xcbc function.
+ */
+ xcbc_t *xcbc;
+
+ /**
+ * Block size (truncation of XCBC MAC)
+ */
+ size_t block_size;
+};
+
+/**
+ * Implementation of signer_t.get_signature.
+ */
+static void get_signature(private_xcbc_signer_t *this,
+ chunk_t data, u_int8_t *buffer)
+{
+ if (buffer == NULL)
+ { /* append mode */
+ this->xcbc->get_mac(this->xcbc, data, NULL);
+ }
+ else
+ {
+ u_int8_t mac[this->xcbc->get_block_size(this->xcbc)];
+
+ this->xcbc->get_mac(this->xcbc, data, mac);
+ memcpy(buffer, mac, this->block_size);
+ }
+}
+
+/**
+ * Implementation of signer_t.allocate_signature.
+ */
+static void allocate_signature (private_xcbc_signer_t *this,
+ chunk_t data, chunk_t *chunk)
+{
+ if (chunk == NULL)
+ { /* append mode */
+ this->xcbc->get_mac(this->xcbc, data, NULL);
+ }
+ else
+ {
+ u_int8_t mac[this->xcbc->get_block_size(this->xcbc)];
+
+ this->xcbc->get_mac(this->xcbc, data, mac);
+
+ chunk->ptr = malloc(this->block_size);
+ chunk->len = this->block_size;
+
+ memcpy(chunk->ptr, mac, this->block_size);
+ }
+}
+
+/**
+ * Implementation of signer_t.verify_signature.
+ */
+static bool verify_signature(private_xcbc_signer_t *this,
+ chunk_t data, chunk_t signature)
+{
+ u_int8_t mac[this->xcbc->get_block_size(this->xcbc)];
+
+ if (signature.len != this->block_size)
+ {
+ return FALSE;
+ }
+
+ this->xcbc->get_mac(this->xcbc, data, mac);
+ return memeq(signature.ptr, mac, this->block_size);
+}
+
+/**
+ * Implementation of signer_t.get_key_size.
+ */
+static size_t get_key_size(private_xcbc_signer_t *this)
+{
+ return this->xcbc->get_block_size(this->xcbc);
+}
+
+/**
+ * Implementation of signer_t.get_block_size.
+ */
+static size_t get_block_size(private_xcbc_signer_t *this)
+{
+ return this->block_size;
+}
+
+/**
+ * Implementation of signer_t.set_key.
+ */
+static void set_key(private_xcbc_signer_t *this, chunk_t key)
+{
+ this->xcbc->set_key(this->xcbc, key);
+}
+
+/**
+ * Implementation of signer_t.destroy.
+ */
+static status_t destroy(private_xcbc_signer_t *this)
+{
+ this->xcbc->destroy(this->xcbc);
+ free(this);
+ return SUCCESS;
+}
+
+/*
+ * Described in header
+ */
+xcbc_signer_t *xcbc_signer_create(integrity_algorithm_t algo)
+{
+ private_xcbc_signer_t *this;
+ size_t trunc;
+ xcbc_t *xcbc;
+
+ switch (algo)
+ {
+ case AUTH_AES_XCBC_96:
+ xcbc = xcbc_create(ENCR_AES_CBC, 16);
+ trunc = 12;
+ break;
+ default:
+ return NULL;
+ }
+ if (xcbc == NULL)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_xcbc_signer_t);
+ this->xcbc = xcbc;
+ this->block_size = min(trunc, xcbc->get_block_size(xcbc));
+
+ /* interface functions */
+ this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature;
+ this->public.signer_interface.allocate_signature = (void (*) (signer_t*, chunk_t, chunk_t*))allocate_signature;
+ this->public.signer_interface.verify_signature = (bool (*) (signer_t*, chunk_t, chunk_t))verify_signature;
+ this->public.signer_interface.get_key_size = (size_t (*) (signer_t*))get_key_size;
+ this->public.signer_interface.get_block_size = (size_t (*) (signer_t*))get_block_size;
+ this->public.signer_interface.set_key = (void (*) (signer_t*,chunk_t))set_key;
+ this->public.signer_interface.destroy = (void (*) (signer_t*))destroy;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_signer.h b/src/libstrongswan/plugins/xcbc/xcbc_signer.h
new file mode 100644
index 000000000..c7eff7e17
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_signer.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup xcbc_signer xcbc_signer
+ * @{ @ingroup xcbc_p
+ */
+
+#ifndef xcbc_SIGNER_H_
+#define xcbc_SIGNER_H_
+
+typedef struct xcbc_signer_t xcbc_signer_t;
+
+#include <crypto/signers/signer.h>
+
+/**
+ * Implementation of signer_t based on CBC symmetric cypher. XCBC, RFC3566.
+ */
+struct xcbc_signer_t {
+
+ /**
+ * generic signer_t interface for this signer
+ */
+ signer_t signer_interface;
+};
+
+/**
+ * Creates a new xcbc_signer_t.
+ *
+ * @param algo algorithm to implement
+ * @return xcbc_signer_t, NULL if not supported
+ */
+xcbc_signer_t *xcbc_signer_create(integrity_algorithm_t algo);
+
+#endif /*xcbc_SIGNER_H_ @}*/
diff --git a/src/libstrongswan/printf_hook.c b/src/libstrongswan/printf_hook.c
index baf339640..d0046928f 100644
--- a/src/libstrongswan/printf_hook.c
+++ b/src/libstrongswan/printf_hook.c
@@ -1,12 +1,5 @@
-/**
- * @file printf_hook.c
- *
- * @brief Printf hook definitions and arginfo functions.
- *
- */
-
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,124 +11,55 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: printf_hook.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "printf_hook.h"
-/**
- * arginfo handler in printf() pointer
- */
-int arginfo_ptr(const struct printf_info *info, size_t n, int *argtypes)
-{
- if (n > 0)
- {
- argtypes[0] = PA_POINTER;
- }
- return 1;
-}
+#include <utils.h>
-/**
- * arginfo handler for two prt arguments
- */
-int arginfo_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes)
-{
- if (n > 1)
- {
- argtypes[0] = PA_POINTER;
- argtypes[1] = PA_POINTER;
- }
- return 2;
-}
+typedef struct private_printf_hook_t private_printf_hook_t;
/**
- * arginfo handler for one ptr, one int
+ * private data of printf_hook
*/
-int arginfo_ptr_int(const struct printf_info *info, size_t n, int *argtypes)
-{
- if (n > 1)
- {
- argtypes[0] = PA_POINTER;
- argtypes[1] = PA_INT;
- }
- return 2;
-}
+struct private_printf_hook_t {
-/**
- * arginfo handler for two int arguments
- */
-int arginfo_int_int(const struct printf_info *info, size_t n, int *argtypes)
-{
- if (n > 1)
- {
- argtypes[0] = PA_INT;
- argtypes[1] = PA_INT;
- }
- return 2;
-}
+ /**
+ * public functions
+ */
+ printf_hook_t public;
+};
/**
- * special arginfo handler respecting alt flag
+ * Implementation of printf_hook_t.add_handler.
*/
-int arginfo_int_alt_int_int(const struct printf_info *info, size_t n, int *argtypes)
+static void add_handler(private_printf_hook_t *this, char spec,
+ printf_hook_functions_t hook)
{
- if (info->alt)
- {
- if (n > 1)
- {
- argtypes[0] = PA_INT;
- argtypes[1] = PA_INT;
- }
- return 2;
- }
-
- if (n > 0)
- {
- argtypes[0] = PA_INT;
- }
- return 1;
+ register_printf_function(spec, hook.print, hook.arginfo);
}
/**
- * special arginfo handler respecting alt flag
+ * Implementation of printf_hook_t.destroy
*/
-int arginfo_ptr_alt_ptr_int(const struct printf_info *info, size_t n, int *argtypes)
+static void destroy(private_printf_hook_t *this)
{
- if (info->alt)
- {
- if (n > 1)
- {
- argtypes[0] = PA_POINTER;
- argtypes[1] = PA_INT;
- }
- return 2;
- }
-
- if (n > 0)
- {
- argtypes[0] = PA_POINTER;
- }
- return 1;
+ free(this);
}
-/**
- * special arginfo handler respecting alt flag
+/*
+ * see header file
*/
-int arginfo_ptr_alt_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes)
+printf_hook_t *printf_hook_create()
{
- if (info->alt)
- {
- if (n > 1)
- {
- argtypes[0] = PA_POINTER;
- argtypes[1] = PA_POINTER;
- }
- return 2;
- }
+ private_printf_hook_t *this = malloc_thing(private_printf_hook_t);
+
+ this->public.add_handler = (void(*)(printf_hook_t*, char, printf_hook_functions_t))add_handler;
+ this->public.destroy = (void(*)(printf_hook_t*))destroy;
+
- if (n > 0)
- {
- argtypes[0] = PA_POINTER;
- }
- return 1;
+ return &this->public;
}
diff --git a/src/libstrongswan/printf_hook.h b/src/libstrongswan/printf_hook.h
index 77b228da0..416db1a7f 100644
--- a/src/libstrongswan/printf_hook.h
+++ b/src/libstrongswan/printf_hook.h
@@ -1,12 +1,5 @@
-/**
- * @file printf_hook.h
- *
- * @brief Printf hook definitions and arginfo functions.
- *
- */
-
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,44 +11,68 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: printf_hook.h 3749 2008-04-04 11:37:19Z martin $
+ */
+
+/**
+ * @defgroup printf_hook printf_hook
+ * @{ @ingroup libstrongswan
*/
#ifndef PRINTF_HOOK_H_
#define PRINTF_HOOK_H_
+typedef struct printf_hook_t printf_hook_t;
+typedef struct printf_hook_functions_t printf_hook_functions_t;
+
#include <printf.h>
/**
- * Printf() hook characters.
- * We define all characters here to have them on a central place.
+ * Printf hook function set.
+ *
+ * A printf hook has two functions, one to print the string, one to read
+ * in the number of arguments. See <printf.h>.
*/
+struct printf_hook_functions_t {
-/** 2 arguments: u_char *buffer, int size */
-#define PRINTF_BYTES 'b'
-/** 1 argument: chunk_t *chunk; use #-modifier to print inline */
-#define PRINTF_CHUNK 'B'
-/** 1 argument: identification_t *id */
-#define PRINTF_IDENTIFICATION 'D'
-/** 1 argumnet: host_t *host; use #-modifier to include port number */
-#define PRINTF_HOST 'H'
-/** 1 argument: ike_sa_t *ike_sa */
-#define PRINTF_ENUM 'N'
-/** 1 argument: child_sa_t *child_sa */
-#define PRINTF_TRAFFIC_SELECTOR 'R'
-/** 1 argument: time_t *time; with #-modifier 2 arguments: time_t *time, bool utc */
-#define PRINTF_TIME 'T'
-/** 1 argument: time_t *delta; with #-modifier 2 arguments: time_t *begin, time_t *end */
-#define PRINTF_TIME_DELTA 'V'
+ /**
+ * Printf hook print function. This is actually of type "printf_function",
+ * however glibc does it typedef to function, but uclibc to a pointer.
+ * So we redefine it here.
+ */
+ int (*print)(FILE *, const struct printf_info *info, const void *const *args);
+
+ /**
+ * Printf hook arginfo function, which is actually of type
+ * "printf_arginfo_function".
+ */
+ int (*arginfo)(const struct printf_info *info, size_t n, int *argtypes);
+};
/**
- * Generic arginfo handlers for printf() hooks
+ * Printf handler management.
*/
-int arginfo_ptr(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_ptr_int(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_int_int(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_ptr_alt_ptr_int(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_ptr_alt_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_int_alt_int_int(const struct printf_info *info, size_t n, int *argtypes);
-
-#endif /* PRINTF_HOOK_H_ */
+struct printf_hook_t {
+
+ /**
+ * Register a printf handler.
+ *
+ * @param spec printf hook format character
+ * @param hook hook functions
+ */
+ void (*add_handler)(printf_hook_t *this, char spec,
+ printf_hook_functions_t hook);
+
+ /**
+ * Destroy a printf_hook instance.
+ */
+ void (*destroy)(printf_hook_t *this);
+};
+
+/**
+ * Create a printf_hook instance.
+ */
+printf_hook_t *printf_hook_create();
+
+#endif /* PRINTF_HOOK_H_ @}*/
diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c
new file mode 100644
index 000000000..7c87dccd8
--- /dev/null
+++ b/src/libstrongswan/settings.c
@@ -0,0 +1,411 @@
+/*
+ * 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 <stdio.h>
+#include <errno.h>
+
+#include "settings.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+
+
+typedef struct private_settings_t private_settings_t;
+typedef struct section_t section_t;
+typedef struct kv_t kv_t;
+
+/**
+ * private data of settings
+ */
+struct private_settings_t {
+
+ /**
+ * public functions
+ */
+ settings_t public;
+
+ /**
+ * top level section
+ */
+ section_t *top;
+
+ /**
+ * allocated file text
+ */
+ char *text;
+};
+
+/**
+ * section containing subsections and key value pairs
+ */
+struct section_t {
+
+ /**
+ * name of the section
+ */
+ char *name;
+
+ /**
+ * subsections, as section_t
+ */
+ linked_list_t *sections;
+
+ /**
+ * key value pairs, as kv_t
+ */
+ linked_list_t *kv;
+};
+
+/**
+ * Key value pair
+ */
+struct kv_t {
+
+ /**
+ * key string, relative
+ */
+ char *key;
+
+ /**
+ * value as string
+ */
+ char *value;
+};
+
+static char *find(section_t *section, char *key)
+{
+ char *name, *pos, *value = NULL;
+ enumerator_t *enumerator;
+ kv_t *kv;
+ section_t *current, *found = NULL;
+
+ if (section == NULL)
+ {
+ return NULL;
+ }
+
+ name = strdupa(key);
+
+ pos = strchr(name, '.');
+ if (pos)
+ {
+ *pos = '\0';
+ pos++;
+ enumerator = section->sections->create_enumerator(section->sections);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (streq(current->name, name))
+ {
+ found = current;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (found)
+ {
+ return find(found, pos);
+ }
+ }
+ else
+ {
+ enumerator = section->kv->create_enumerator(section->kv);
+ while (enumerator->enumerate(enumerator, &kv))
+ {
+ if (streq(kv->key, name))
+ {
+ value = kv->value;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ return value;
+}
+
+/**
+ * Implementation of settings_t.get.
+ */
+static char* get_str(private_settings_t *this, char *key, char *def)
+{
+ char *value;
+
+ value = find(this->top, key);
+ if (value)
+ {
+ return value;
+ }
+ return def;
+}
+
+/**
+ * Implementation of settings_t.get_bool.
+ */
+static bool get_bool(private_settings_t *this, char *key, bool def)
+{
+ char *value;
+
+ value = find(this->top, key);
+ if (value)
+ {
+ if (strcasecmp(value, "true") == 0 ||
+ strcasecmp(value, "enabled") == 0 ||
+ strcasecmp(value, "yes") == 0 ||
+ strcasecmp(value, "1") == 0)
+ {
+ return TRUE;
+ }
+ else if (strcasecmp(value, "false") == 0 ||
+ strcasecmp(value, "disabled") == 0 ||
+ strcasecmp(value, "no") == 0 ||
+ strcasecmp(value, "0") == 0)
+ {
+ return FALSE;
+ }
+ }
+ return def;
+}
+
+/**
+ * Implementation of settings_t.get_int.
+ */
+static int get_int(private_settings_t *this, char *key, int def)
+{
+ char *value;
+ int intval;
+
+ value = find(this->top, key);
+ if (value)
+ {
+ errno = 0;
+ intval = strtol(value, NULL, 10);
+ if (errno == 0)
+ {
+ return intval;
+ }
+ }
+ return def;
+}
+
+/**
+ * destry a section
+*/
+static void section_destroy(section_t *this)
+{
+ this->kv->destroy_function(this->kv, free);
+ this->sections->destroy_function(this->sections, (void*)section_destroy);
+
+ free(this);
+}
+
+/**
+ * parse text, truncate "skip" chars, delimited by term respecting brackets.
+ *
+ * Chars in "skip" are truncated at the beginning and the end of the resulting
+ * token. "term" contains a list of characters to read up to (first match),
+ * while "br" contains bracket counterparts found in "term" to skip.
+ */
+static char parse(char **text, char *skip, char *term, char *br, char **token)
+{
+ char *best = NULL;
+ char best_term = '\0';
+
+ /* skip leading chars */
+ while (strchr(skip, **text))
+ {
+ (*text)++;
+ if (!**text)
+ {
+ return 0;
+ }
+ }
+ /* mark begin of subtext */
+ *token = *text;
+ while (*term)
+ {
+ char *pos = *text;
+ int level = 1;
+
+ /* find terminator */
+ while (*pos)
+ {
+ if (*pos == *term)
+ {
+ level--;
+ }
+ else if (br && *pos == *br)
+ {
+ level++;
+ }
+ if (level == 0)
+ {
+ if (best == NULL || best > pos)
+ {
+ best = pos;
+ best_term = *term;
+ }
+ break;
+ }
+ pos++;
+ }
+ /* try next terminator */
+ term++;
+ if (br)
+ {
+ br++;
+ }
+ }
+ if (best)
+ {
+ /* update input */
+ *text = best;
+ /* null trailing bytes */
+ do
+ {
+ *best = '\0';
+ best--;
+ }
+ while (best >= *token && strchr(skip, *best));
+ /* return found terminator */
+ return best_term;
+ }
+ return 0;
+}
+
+/**
+ * Parse a section
+ */
+static section_t* parse_section(char **text, char *name)
+{
+ section_t *sub, *section;
+ bool finished = FALSE;
+ char *key, *value, *inner;
+
+ static int lev = 0;
+ lev++;
+
+ section = malloc_thing(section_t);
+ section->name = name;
+ section->sections = linked_list_create();
+ section->kv = linked_list_create();
+
+ while (!finished)
+ {
+ switch (parse(text, "\t\n ", "{=#", NULL, &key))
+ {
+ case '{':
+ if (parse(text, "\t ", "}", "{", &inner))
+ {
+ sub = parse_section(&inner, key);
+ if (sub)
+ {
+ section->sections->insert_last(section->sections, sub);
+ continue;
+ }
+ }
+ DBG1("matching '}' not found near %s", *text);
+ break;
+ case '=':
+ if (parse(text, "\t ", "\n", NULL, &value))
+ {
+ kv_t *kv = malloc_thing(kv_t);
+ kv->key = key;
+ kv->value = value;
+ section->kv->insert_last(section->kv, kv);
+ continue;
+ }
+ DBG1("parsing value failed near %s", *text);
+ break;
+ case '#':
+ parse(text, "", "\n", NULL, &value);
+ continue;
+ default:
+ finished = TRUE;
+ continue;
+ }
+ section_destroy(section);
+ return NULL;
+ }
+ return section;
+}
+
+/**
+ * Implementation of settings_t.destroy
+ */
+static void destroy(private_settings_t *this)
+{
+ if (this->top)
+ {
+ section_destroy(this->top);
+ }
+ free(this->text);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+settings_t *settings_create(char *file)
+{
+ private_settings_t *this = malloc_thing(private_settings_t);
+
+ this->public.get_str = (char*(*)(settings_t*, char *key, char* def))get_str;
+ this->public.get_int = (int(*)(settings_t*, char *key, bool def))get_int;
+ this->public.get_bool = (bool(*)(settings_t*, char *key, bool def))get_bool;
+ this->public.destroy = (void(*)(settings_t*))destroy;
+
+ this->top = NULL;
+ this->text = NULL;
+
+ if (file)
+ {
+ FILE *fd;
+ int len;
+ char *pos;
+
+ fd = fopen(file, "r");
+ if (fd == NULL)
+ {
+ DBG1("'%s' does not exist or is not readable", file);
+ return &this->public;
+ }
+ fseek(fd, 0, SEEK_END);
+ len = ftell(fd);
+ rewind(fd);
+ this->text = malloc(len + 1);
+ this->text[len] = '\0';
+ if (fread(this->text, 1, len, fd) != len)
+ {
+ free(this->text);
+ this->text = NULL;
+ return &this->public;
+ }
+ fclose(fd);
+
+ pos = this->text;
+ this->top = parse_section(&pos, NULL);
+ if (this->top == NULL)
+ {
+ free(this->text);
+ this->text = NULL;
+ return &this->public;
+ }
+ }
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/settings.h b/src/libstrongswan/settings.h
new file mode 100644
index 000000000..91770973b
--- /dev/null
+++ b/src/libstrongswan/settings.h
@@ -0,0 +1,96 @@
+/*
+ * 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 settings settings
+ * @{ @ingroup libstrongswan
+ */
+
+#ifndef SETTINGS_H_
+#define SETTINGS_H_
+
+typedef struct settings_t settings_t;
+
+#include <library.h>
+
+/**
+ * Generic configuration options read from a config file.
+ *
+ * The sytax is quite simple:
+ *
+ * settings := (section|keyvalue)*
+ * section := name { settings }
+ * keyvalue := key = value\n
+ *
+ * E.g.:
+ * @code
+ a = b
+ section-one {
+ somevalue = asdf
+ subsection {
+ othervalue = xxx
+ }
+ yetanother = zz
+ }
+ section-two {
+ }
+ @endcode
+ *
+ * The values are accesses using the get() functions using dotted keys, e.g.
+ * section-one.subsection.othervalue
+ */
+struct settings_t {
+
+ /**
+ * Get a settings value as a string.
+ *
+ * @param key key including sections
+ * @param def value returned if key not found
+ * @return value pointing to internal string
+ */
+ char* (*get_str)(settings_t *this, char *key, char *def);
+
+ /**
+ * Get a boolean yes|no, true|false value.
+ *
+ * @param jey key including sections
+ * @param def default value returned if key not found
+ * @return value of the key
+ */
+ bool (*get_bool)(settings_t *this, char *key, bool def);
+
+ /**
+ * Get an integer value.
+ *
+ * @param key key including sections
+ * @param def default value to return if key not found
+ * @return value of the key
+ */
+ int (*get_int)(settings_t *this, char *key, bool def);
+
+ /**
+ * Destroy a settings instance.
+ */
+ void (*destroy)(settings_t *this);
+};
+
+/**
+ * Load setings from a file.
+ */
+settings_t *settings_create(char *file);
+
+#endif /* SETTINGS_H_ @}*/
diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c
new file mode 100644
index 000000000..bd13b7c4d
--- /dev/null
+++ b/src/libstrongswan/utils.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: utils.c 3820 2008-04-17 11:22:37Z martin $
+ */
+
+#include "utils.h"
+
+#include <string.h>
+#include <pthread.h>
+#include <stdio.h>
+
+#include <enum.h>
+
+ENUM(status_names, SUCCESS, DESTROY_ME,
+ "SUCCESS",
+ "FAILED",
+ "OUT_OF_RES",
+ "ALREADY_DONE",
+ "NOT_SUPPORTED",
+ "INVALID_ARG",
+ "NOT_FOUND",
+ "PARSE_ERROR",
+ "VERIFY_ERROR",
+ "INVALID_STATE",
+ "DESTROY_ME",
+ "NEED_MORE",
+);
+
+/**
+ * Described in header.
+ */
+void *clalloc(void * pointer, size_t size)
+{
+ void *data;
+ data = malloc(size);
+
+ memcpy(data, pointer, size);
+
+ return (data);
+}
+
+/**
+ * Described in header.
+ */
+void memxor(u_int8_t dest[], u_int8_t src[], size_t n)
+{
+ size_t i;
+ for (i = 0; i < n; i++)
+ {
+ dest[i] ^= src[i];
+ }
+}
+
+/**
+ * return null
+ */
+void *return_null()
+{
+ return NULL;
+}
+
+/**
+ * nop operation
+ */
+void nop()
+{
+}
+
+/**
+ * We use a single mutex for all refcount variables. This
+ * is not optimal for performance, but the critical section
+ * is not that long...
+ * TODO: Consider to include a mutex in each refcount_t variable.
+ */
+static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Described in header.
+ *
+ * TODO: May be implemented with atomic CPU instructions
+ * instead of a mutex.
+ */
+void ref_get(refcount_t *ref)
+{
+ pthread_mutex_lock(&ref_mutex);
+ (*ref)++;
+ pthread_mutex_unlock(&ref_mutex);
+}
+
+/**
+ * Described in header.
+ *
+ * TODO: May be implemented with atomic CPU instructions
+ * instead of a mutex.
+ */
+bool ref_put(refcount_t *ref)
+{
+ bool more_refs;
+
+ pthread_mutex_lock(&ref_mutex);
+ more_refs = --(*ref);
+ pthread_mutex_unlock(&ref_mutex);
+ return !more_refs;
+}
+
+/**
+ * output handler in printf() for time_t
+ */
+static int time_print(FILE *stream, const struct printf_info *info,
+ const void *const *args)
+{
+ static const char* months[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+ time_t *time = *((time_t**)(args[0]));
+ bool utc = TRUE;
+ struct tm t;
+
+ if (info->alt)
+ {
+ utc = *((bool*)(args[1]));
+ }
+ if (time == UNDEFINED_TIME)
+ {
+ return fprintf(stream, "--- -- --:--:--%s----",
+ info->alt ? " UTC " : " ");
+ }
+ if (utc)
+ {
+ gmtime_r(time, &t);
+ }
+ else
+ {
+ localtime_r(time, &t);
+ }
+ return fprintf(stream, "%s %02d %02d:%02d:%02d%s%04d",
+ months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min,
+ t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900);
+}
+
+/**
+ * arginfo handler for printf() time
+ */
+static int time_arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (info->alt)
+ {
+ if (n > 1)
+ {
+ argtypes[0] = PA_POINTER;
+ argtypes[1] = PA_INT;
+ }
+ return 2;
+ }
+
+ if (n > 0)
+ {
+ argtypes[0] = PA_POINTER;
+ }
+ return 1;
+}
+
+/**
+ * output handler in printf() for time deltas
+ */
+static int time_delta_print(FILE *stream, const struct printf_info *info,
+ const void *const *args)
+{
+ char* unit = "second";
+ time_t *arg1, *arg2;
+ time_t delta;
+
+ arg1 = *((time_t**)(args[0]));
+ if (info->alt)
+ {
+ arg2 = *((time_t**)(args[1]));
+ delta = abs(*arg1 - *arg2);
+ }
+ else
+ {
+ delta = *arg1;
+ }
+
+ if (delta > 2 * 60 * 60 * 24)
+ {
+ delta /= 60 * 60 * 24;
+ unit = "day";
+ }
+ else if (delta > 2 * 60 * 60)
+ {
+ delta /= 60 * 60;
+ unit = "hour";
+ }
+ else if (delta > 2 * 60)
+ {
+ delta /= 60;
+ unit = "minute";
+ }
+ return fprintf(stream, "%d %s%s", delta, unit, (delta == 1)? "":"s");
+}
+
+/**
+ * arginfo handler for printf() time deltas
+ */
+int time_delta_arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (info->alt)
+ {
+ if (n > 1)
+ {
+ argtypes[0] = PA_POINTER;
+ argtypes[1] = PA_POINTER;
+ }
+ return 2;
+ }
+
+ if (n > 0)
+ {
+ argtypes[0] = PA_POINTER;
+ }
+ return 1;
+}
+
+/**
+ * Number of bytes per line to dump raw data
+ */
+#define BYTES_PER_LINE 16
+
+static char hexdig_upper[] = "0123456789ABCDEF";
+
+/**
+ * output handler in printf() for mem ranges
+ */
+static int mem_print(FILE *stream, const struct printf_info *info,
+ const void *const *args)
+{
+ char *bytes = *((void**)(args[0]));
+ int len = *((size_t*)(args[1]));
+
+ char buffer[BYTES_PER_LINE * 3];
+ char ascii_buffer[BYTES_PER_LINE + 1];
+ char *buffer_pos = buffer;
+ char *bytes_pos = bytes;
+ char *bytes_roof = bytes + len;
+ int line_start = 0;
+ int i = 0;
+ int written = 0;
+
+ written += fprintf(stream, "=> %d bytes @ %p", len, bytes);
+
+ while (bytes_pos < bytes_roof)
+ {
+ *buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF];
+ *buffer_pos++ = hexdig_upper[ *bytes_pos & 0xF];
+
+ ascii_buffer[i++] =
+ (*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.';
+
+ if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE)
+ {
+ int padding = 3 * (BYTES_PER_LINE - i);
+ int written;
+
+ while (padding--)
+ {
+ *buffer_pos++ = ' ';
+ }
+ *buffer_pos++ = '\0';
+ ascii_buffer[i] = '\0';
+
+ written += fprintf(stream, "\n%4d: %s %s",
+ line_start, buffer, ascii_buffer);
+
+
+ buffer_pos = buffer;
+ line_start += BYTES_PER_LINE;
+ i = 0;
+ }
+ else
+ {
+ *buffer_pos++ = ' ';
+ }
+ }
+ return written;
+}
+
+/**
+ * arginfo handler for printf() mem ranges
+ */
+int mem_arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (n > 1)
+ {
+ argtypes[0] = PA_POINTER;
+ argtypes[1] = PA_INT;
+ }
+ return 2;
+}
+
+/**
+ * return printf hook functions for a time
+ */
+printf_hook_functions_t time_get_printf_hooks()
+{
+ printf_hook_functions_t hooks = {time_print, time_arginfo};
+
+ return hooks;
+}
+
+/**
+ * return printf hook functions for a time delta
+ */
+printf_hook_functions_t time_delta_get_printf_hooks()
+{
+ printf_hook_functions_t hooks = {time_delta_print, time_delta_arginfo};
+
+ return hooks;
+}
+
+/**
+ * return printf hook functions for mem ranges
+ */
+printf_hook_functions_t mem_get_printf_hooks()
+{
+ printf_hook_functions_t hooks = {mem_print, mem_arginfo};
+
+ return hooks;
+}
+
diff --git a/src/libstrongswan/utils.h b/src/libstrongswan/utils.h
new file mode 100644
index 000000000..ee3ebbd41
--- /dev/null
+++ b/src/libstrongswan/utils.h
@@ -0,0 +1,275 @@
+/*
+ * 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: utils.h 3820 2008-04-17 11:22:37Z martin $
+ */
+
+/**
+ * @defgroup utils utils
+ * @{ @ingroup libstrongswan
+ */
+
+#ifndef UTILS_H_
+#define UTILS_H_
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#include <enum.h>
+
+/**
+ * Number of bits in a byte
+ */
+#define BITS_PER_BYTE 8
+
+/**
+ * Default length for various auxiliary text buffers
+ */
+#define BUF_LEN 512
+
+/**
+ * Macro compares two strings for equality
+ */
+#define streq(x,y) (strcmp(x, y) == 0)
+
+/**
+ * Macro compares two strings for equality
+ */
+#define strneq(x,y,len) (strncmp(x, y, len) == 0)
+
+/**
+ * Macro compares two binary blobs for equality
+ */
+#define memeq(x,y,len) (memcmp(x, y, len) == 0)
+
+/**
+ * Macro gives back larger of two values.
+ */
+#define max(x,y) ((x) > (y) ? (x):(y))
+
+/**
+ * Macro gives back smaller of two values.
+ */
+#define min(x,y) ((x) < (y) ? (x):(y))
+
+/**
+ * Call destructor of an object, if object != NULL
+ */
+#define DESTROY_IF(obj) if (obj) (obj)->destroy(obj)
+
+/**
+ * Call offset destructor of an object, if object != NULL
+ */
+#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
+
+/**
+ * Call function destructor of an object, if object != NULL
+ */
+#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
+
+/**
+ * Debug macro to follow control flow
+ */
+#define POS printf("%s, line %d\n", __FILE__, __LINE__)
+
+/**
+ * Macro to allocate a sized type.
+ */
+#define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
+
+/**
+ * Assign a function as a class method
+ */
+#define ASSIGN(method, function) (method = (typeof(method))function)
+
+/**
+ * time_t not defined
+ */
+#define UNDEFINED_TIME 0
+
+/**
+ * General purpose boolean type.
+ */
+typedef int bool;
+#define FALSE 0
+#define TRUE 1
+
+typedef enum status_t status_t;
+
+/**
+ * Return values of function calls.
+ */
+enum status_t {
+ /**
+ * Call succeeded.
+ */
+ SUCCESS,
+
+ /**
+ * Call failed.
+ */
+ FAILED,
+
+ /**
+ * Out of resources.
+ */
+ OUT_OF_RES,
+
+ /**
+ * The suggested operation is already done
+ */
+ ALREADY_DONE,
+
+ /**
+ * Not supported.
+ */
+ NOT_SUPPORTED,
+
+ /**
+ * One of the arguments is invalid.
+ */
+ INVALID_ARG,
+
+ /**
+ * Something could not be found.
+ */
+ NOT_FOUND,
+
+ /**
+ * Error while parsing.
+ */
+ PARSE_ERROR,
+
+ /**
+ * Error while verifying.
+ */
+ VERIFY_ERROR,
+
+ /**
+ * Object in invalid state.
+ */
+ INVALID_STATE,
+
+ /**
+ * Destroy object which called method belongs to.
+ */
+ DESTROY_ME,
+
+ /**
+ * Another call to the method is required.
+ */
+ NEED_MORE,
+};
+
+/**
+ * enum_names for type status_t.
+ */
+extern enum_name_t *status_names;
+
+/**
+ * deprecated pluto style return value:
+ * error message, NULL for success
+ */
+typedef const char *err_t;
+
+/**
+ * Handle struct timeval like an own type.
+ */
+typedef struct timeval timeval_t;
+
+/**
+ * Handle struct timespec like an own type.
+ */
+typedef struct timespec timespec_t;
+
+/**
+ * Handle struct chunk_t like an own type.
+ */
+typedef struct sockaddr sockaddr_t;
+
+/**
+ * Clone a data to a newly allocated buffer
+ */
+void *clalloc(void *pointer, size_t size);
+
+/**
+ * Same as memcpy, but XORs src into dst instead of copy
+ */
+void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
+
+/**
+ * returns null
+ */
+void *return_null();
+
+/**
+ * No-Operation function
+ */
+void nop();
+
+/**
+ * Special type to count references
+ */
+typedef volatile u_int refcount_t;
+
+/**
+ * Get a new reference.
+ *
+ * Increments the reference counter atomic.
+ *
+ * @param ref pointer to ref counter
+ */
+void ref_get(refcount_t *ref);
+
+/**
+ * Put back a unused reference.
+ *
+ * Decrements the reference counter atomic and
+ * says if more references available.
+ *
+ * @param ref pointer to ref counter
+ * @return TRUE if no more references counted
+ */
+bool ref_put(refcount_t *ref);
+
+/**
+ * Get printf hooks for time.
+ *
+ * Arguments are:
+ * time_t* time
+ * Arguments using #-specificer
+ * time_t* time, bool utc
+ */
+printf_hook_functions_t time_get_printf_hooks();
+
+/**
+ * Get printf hooks for time deltas.
+ *
+ * Arguments are:
+ * time_t* delta
+ * Arguments using #-specificer
+ * time_t* begin, time_t* end
+ */
+printf_hook_functions_t time_delta_get_printf_hooks();
+
+/**
+ * Get printf hooks for time deltas.
+ *
+ * Arguments are:
+ * u_char *ptr, int len
+ */
+printf_hook_functions_t mem_get_printf_hooks();
+
+#endif /* UTILS_H_ @}*/
diff --git a/src/libstrongswan/utils/enumerator.c b/src/libstrongswan/utils/enumerator.c
index 842a2e997..cac5d73fa 100644
--- a/src/libstrongswan/utils/enumerator.c
+++ b/src/libstrongswan/utils/enumerator.c
@@ -1,10 +1,3 @@
-/**
- * @file enumerator.c
- *
- * @brief Implementation of enumerator_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,10 +11,20 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: enumerator.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "enumerator.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include <debug.h>
/**
* Implementation of enumerator_create_empty().enumerate
@@ -42,3 +45,350 @@ enumerator_t* enumerator_create_empty()
return this;
}
+/**
+ * Enumerator implementation for directory enumerator
+ */
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** directory handle */
+ DIR *dir;
+ /** absolute path of current file */
+ char full[PATH_MAX];
+ /** where directory part of full ends and relative file gets written */
+ char *full_end;
+} dir_enum_t;
+
+/**
+ * Implementation of enumerator_create_directory().destroy
+ */
+static void destroy_dir_enum(dir_enum_t *this)
+{
+ closedir(this->dir);
+ free(this);
+}
+
+/**
+ * Implementation of enumerator_create_directory().enumerate
+ */
+static bool enumerate_dir_enum(dir_enum_t *this, char **relative,
+ char **absolute, struct stat *st)
+{
+ struct dirent *entry = readdir(this->dir);
+ size_t len, remaining;
+
+ if (!entry)
+ {
+ return FALSE;
+ }
+ if (streq(entry->d_name, ".") || streq(entry->d_name, ".."))
+ {
+ return enumerate_dir_enum(this, relative, absolute, st);
+ }
+ if (relative)
+ {
+ *relative = entry->d_name;
+ }
+ if (absolute || st)
+ {
+ remaining = sizeof(this->full) - (this->full_end - this->full);
+ len = snprintf(this->full_end, remaining, "%s", entry->d_name);
+ if (len < 0 || len >= remaining)
+ {
+ DBG1("buffer too small to enumerate file '%s'", entry->d_name);
+ return FALSE;
+ }
+ if (absolute)
+ {
+ *absolute = this->full;
+ }
+ if (st)
+ {
+ if (stat(this->full, st))
+ {
+ DBG1("stat() on '%s' failed: %s", this->full, strerror(errno));
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * See header
+ */
+enumerator_t* enumerator_create_directory(char *path)
+{
+ size_t len;
+ dir_enum_t *this = malloc_thing(dir_enum_t);
+ this->public.enumerate = (void*)enumerate_dir_enum;
+ this->public.destroy = (void*)destroy_dir_enum;
+
+ if (*path == '\0')
+ {
+ path = "./";
+ }
+ len = snprintf(this->full, sizeof(this->full)-1, "%s", path);
+ if (len < 0 || len >= sizeof(this->full)-1)
+ {
+ DBG1("path string %s too long", path);
+ free(this);
+ return NULL;
+ }
+ /* append a '/' if not already done */
+ if (this->full[len-1] != '/')
+ {
+ this->full[len++] = '/';
+ this->full[len] = '\0';
+ }
+ this->full_end = &this->full[len];
+
+ this->dir = opendir(path);
+ if (this->dir == NULL)
+ {
+ DBG1("opening directory %s failed: %s", path, strerror(errno));
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+/**
+ * enumerator for nested enumerations
+ */
+typedef struct {
+ /* implements enumerator_t */
+ enumerator_t public;
+ /* outer enumerator */
+ enumerator_t *outer;
+ /* inner enumerator */
+ enumerator_t *inner;
+ /* constructor for inner enumerator */
+ enumerator_t *(*create_inner)(void *outer, void *data);
+ /* data to pass to constructor above */
+ void *data;
+ /* destructor for data */
+ void (*destroy_data)(void *data);
+} nested_enumerator_t;
+
+
+/**
+ * Implementation of enumerator_create_nested().enumerate()
+ */
+static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2,
+ void *v3, void *v4, void *v5)
+{
+ while (TRUE)
+ {
+ while (this->inner == NULL)
+ {
+ void *outer;
+
+ if (!this->outer->enumerate(this->outer, &outer))
+ {
+ return FALSE;
+ }
+ this->inner = this->create_inner(outer, this->data);
+ }
+ if (this->inner->enumerate(this->inner, v1, v2, v3, v4, v5))
+ {
+ return TRUE;
+ }
+ this->inner->destroy(this->inner);
+ this->inner = NULL;
+ }
+}
+
+/**
+ * Implementation of enumerator_create_nested().destroy()
+ **/
+static void destroy_nested(nested_enumerator_t *this)
+{
+ if (this->destroy_data)
+ {
+ this->destroy_data(this->data);
+ }
+ DESTROY_IF(this->inner);
+ this->outer->destroy(this->outer);
+ free(this);
+}
+
+/**
+ * See header
+ */
+enumerator_t *enumerator_create_nested(enumerator_t *outer,
+ enumerator_t *(inner_constructor)(void *outer, void *data),
+ void *data, void (*destroy_data)(void *data))
+{
+ nested_enumerator_t *enumerator = malloc_thing(nested_enumerator_t);
+
+ enumerator->public.enumerate = (void*)enumerate_nested;
+ enumerator->public.destroy = (void*)destroy_nested;
+ enumerator->outer = outer;
+ enumerator->inner = NULL;
+ enumerator->create_inner = (void*)inner_constructor;
+ enumerator->data = data;
+ enumerator->destroy_data = destroy_data;
+
+ return &enumerator->public;
+}
+
+/**
+ * enumerator for filtered enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ enumerator_t *unfiltered;
+ void *data;
+ bool (*filter)(void *data, ...);
+ void (*destructor)(void *data);
+} filter_enumerator_t;
+
+/**
+ * Implementation of enumerator_create_filter().destroy
+ */
+void destroy_filter(filter_enumerator_t *this)
+{
+ if (this->destructor)
+ {
+ this->destructor(this->data);
+ }
+ this->unfiltered->destroy(this->unfiltered);
+ free(this);
+}
+
+/**
+ * Implementation of enumerator_create_filter().enumerate
+ */
+bool enumerate_filter(filter_enumerator_t *this, void *o1, void *o2,
+ void *o3, void *o4, void *o5)
+{
+ void *i1, *i2, *i3, *i4, *i5;
+
+ while (this->unfiltered->enumerate(this->unfiltered, &i1, &i2, &i3, &i4, &i5))
+ {
+ if (this->filter(this->data, &i1, o1, &i2, o2, &i3, o3, &i4, o4, &i5, o5))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * see header
+ */
+enumerator_t *enumerator_create_filter(enumerator_t *unfiltered,
+ bool (*filter)(void *data, ...),
+ void *data, void (*destructor)(void *data))
+{
+ filter_enumerator_t *this = malloc_thing(filter_enumerator_t);
+
+ this->public.enumerate = (void*)enumerate_filter;
+ this->public.destroy = (void*)destroy_filter;
+ this->unfiltered = unfiltered;
+ this->filter = filter;
+ this->data = data;
+ this->destructor = destructor;
+
+ return &this->public;
+}
+
+/**
+ * enumerator for cleaner enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ enumerator_t *wrapped;
+ void (*cleanup)(void *data);
+ void *data;
+} cleaner_enumerator_t;
+
+/**
+ * Implementation of enumerator_create_cleanup().destroy
+ */
+static void destroy_cleaner(cleaner_enumerator_t *this)
+{
+ this->cleanup(this->data);
+ this->wrapped->destroy(this->wrapped);
+ free(this);
+}
+
+/**
+ * Implementation of enumerator_create_cleaner().enumerate
+ */
+static bool enumerate_cleaner(cleaner_enumerator_t *this, void *v1, void *v2,
+ void *v3, void *v4, void *v5)
+{
+ return this->wrapped->enumerate(this->wrapped, v1, v2, v3, v4, v5);
+}
+
+/**
+ * see header
+ */
+enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped,
+ void (*cleanup)(void *data), void *data)
+{
+ cleaner_enumerator_t *this = malloc_thing(cleaner_enumerator_t);
+
+ this->public.enumerate = (void*)enumerate_cleaner;
+ this->public.destroy = (void*)destroy_cleaner;
+ this->wrapped = wrapped;
+ this->cleanup = cleanup;
+ this->data = data;
+
+ return &this->public;
+}
+
+/**
+ * enumerator for single enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ void *item;
+ void (*cleanup)(void *item);
+ bool done;
+} single_enumerator_t;
+
+/**
+ * Implementation of enumerator_create_single().destroy
+ */
+static void destroy_single(single_enumerator_t *this)
+{
+ if (this->cleanup)
+ {
+ this->cleanup(this->item);
+ }
+ free(this);
+}
+
+/**
+ * Implementation of enumerator_create_single().enumerate
+ */
+static bool enumerate_single(single_enumerator_t *this, void **item)
+{
+ if (this->done)
+ {
+ return FALSE;
+ }
+ *item = this->item;
+ this->done = TRUE;
+ return TRUE;
+}
+
+/**
+ * see header
+ */
+enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item))
+{
+ single_enumerator_t *this = malloc_thing(single_enumerator_t);
+
+ this->public.enumerate = (void*)enumerate_single;
+ this->public.destroy = (void*)destroy_single;
+ this->item = item;
+ this->cleanup = cleanup;
+ this->done = FALSE;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/utils/enumerator.h b/src/libstrongswan/utils/enumerator.h
index df1d78206..6b91fee72 100644
--- a/src/libstrongswan/utils/enumerator.h
+++ b/src/libstrongswan/utils/enumerator.h
@@ -1,10 +1,3 @@
-/**
- * @file enumerator.h
- *
- * @brief Interface of enumerator_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,22 +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: enumerator.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup enumerator enumerator
+ * @{ @ingroup utils
*/
#ifndef ENUMERATOR_H_
#define ENUMERATOR_H_
-#include <library.h>
-
typedef struct enumerator_t enumerator_t;
+#include <library.h>
+
/**
- * @brief Enumerate is simpler, but more flexible than iterator.
+ * Enumerate is simpler, but more flexible than iterator.
*/
struct enumerator_t {
/**
- * @brief Enumerate collection.
+ * Enumerate collection.
*
* The enumerate function takes a variable argument list containing
* pointers where the enumerated values get written.
@@ -44,14 +44,104 @@ struct enumerator_t {
bool (*enumerate)(enumerator_t *this, ...);
/**
- * @brief Destroy a enumerator instance.
+ * Destroy a enumerator instance.
*/
void (*destroy)(enumerator_t *this);
};
/**
- * @brief Create an enumerator which enumerates over nothing
+ * Create an enumerator which enumerates over nothing
+ *
+ * @return an enumerator over no values
*/
enumerator_t* enumerator_create_empty();
-#endif /* ENUMERATOR_H_ */
+/**
+ * Create an enumerator which enumerates over a single item
+ *
+ * @param item item to enumerate
+ * @param cleanup cleanup function called on destroy with the item
+ * @return an enumerator over a single value
+ */
+enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item));
+
+/**
+ * Create an enumerator over files/subdirectories in a directory.
+ *
+ * This enumerator_t.enumerate() function returns a (to the directory) relative
+ * filename (as a char*), an absolute filename (as a char*) and a file status
+ * (to a struct stat), which all may be NULL. "." and ".." entries are
+ * skipped. Example:
+ *
+ * @code
+ char *rel, *abs;
+ struct stat st;
+ enumerator_t *e;
+
+ e = enumerator_create_directory("/tmp");
+ if (e)
+ {
+ while (e->enumerate(e, &rel, &abs, &st))
+ {
+ if (S_ISDIR(st.st_mode) && *rel != '.')
+ {
+ printf("%s\n", abs);
+ }
+ }
+ e->destroy(e);
+ }
+ @endcode
+ *
+ * @param path path of the directory
+ * @return the directory enumerator, NULL on failure
+ */
+enumerator_t* enumerator_create_directory(char *path);
+
+/**
+ * Creates an enumerator which enumerates over enumerated enumerators :-).
+ *
+ * The variable argument list of enumeration values is limit to 5.
+ *
+ * @param outer outer enumerator
+ * @param inner_constructor constructor to inner enumerator
+ * @param data data to pass to each inner_constructor call
+ * @param destroy_data destructor to pass to data
+ * @return the nested enumerator
+ */
+enumerator_t *enumerator_create_nested(enumerator_t *outer,
+ enumerator_t *(inner_constructor)(void *outer, void *data),
+ void *data, void (*destroy_data)(void *data));
+
+/**
+ * Creates an enumerator which filters output of another enumerator.
+ *
+ * The filter function receives the user supplied "data" followed by a
+ * unfiltered enumeration item, followed by an output pointer where to write
+ * the filtered data. Then the next input/output pair follows.
+ * It returns TRUE to deliver the
+ * values to the caller of enumerate(), FALSE to filter this enumeration.
+ *
+ * The variable argument list of enumeration values is limit to 5.
+ *
+ * @param unfiltered unfiltered enumerator to wrap, gets destroyed
+ * @param filter filter function
+ * @param data user data to supply to filter
+ * @param destructor destructor function to clean up data after use
+ * @return the filtered enumerator
+ */
+enumerator_t *enumerator_create_filter(enumerator_t *unfiltered,
+ bool (*filter)(void *data, ...),
+ void *data, void (*destructor)(void *data));
+
+/**
+ * Create an enumerator wrapper which does a cleanup on destroy.
+ *
+ * @param wrapped wrapped enumerator
+ * @param cleanup cleanup function called on destroy
+ * @param data user data to supply to cleanup
+ * @return the enumerator with cleanup
+ */
+enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped,
+ void (*cleanup)(void *data), void *data);
+
+#endif /* ENUMERATOR_H_ @} */
diff --git a/src/libstrongswan/utils/fetcher.c b/src/libstrongswan/utils/fetcher.c
deleted file mode 100644
index 7a06999aa..000000000
--- a/src/libstrongswan/utils/fetcher.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/**
- * @file fetcher.c
- *
- * @brief Implementation of fetcher_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <fetcher://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifdef LIBCURL
-#include <curl/curl.h>
-#endif /* LIBCURL */
-
-#ifdef LIBLDAP
-#ifndef LDAP_DEPRECATED
-#define LDAP_DEPRECATED 1
-#endif
-#include <ldap.h>
-#endif /* LIBLDAP */
-
-#include <library.h>
-#include <debug.h>
-
-#include "fetcher.h"
-
-typedef struct private_fetcher_t private_fetcher_t;
-
-/**
- * @brief Private Data of a fetcher_t object.
- */
-struct private_fetcher_t {
- /**
- * Public data
- */
- fetcher_t public;
-
- /**
- * URI of the information source
- */
- const char *uri;
-
-#ifdef LIBCURL
- /**
- * we use libcurl from http://curl.haxx.se/ as a fetcher
- */
- CURL* curl;
-#endif /* LIBCURL */
-
-#ifdef LIBLDAP
- /**
- * we use libldap from http://www.openssl.org/ as a fetcher
- */
- LDAP *ldap;
- LDAPURLDesc *lurl;
-#endif /* LIBLDAP */
-};
-
-/**
- * writes data into a dynamically resizeable chunk_t
- * needed for libcurl responses
- */
-static size_t curl_write_buffer(void *ptr, size_t size, size_t nmemb, void *data)
-{
- size_t realsize = size * nmemb;
- chunk_t *mem = (chunk_t*)data;
-
- mem->ptr = (u_char *)realloc(mem->ptr, mem->len + realsize);
- if (mem->ptr) {
- memcpy(&(mem->ptr[mem->len]), ptr, realsize);
- mem->len += realsize;
- }
- return realsize;
-}
-
-/**
- * Implements fetcher_t.get for curl methods
- */
-static chunk_t curl_get(private_fetcher_t *this)
-{
- chunk_t response = chunk_empty;
-
-#ifdef LIBCURL
- if (this->curl)
- {
- CURLcode res;
- chunk_t curl_response = chunk_empty;
- char curl_error_buffer[CURL_ERROR_SIZE];
-
- curl_easy_setopt(this->curl, CURLOPT_URL, this->uri);
- curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, curl_write_buffer);
- curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void *)&curl_response);
- curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, &curl_error_buffer);
- curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
- curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, FETCHER_TIMEOUT);
- curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
-
- DBG1("sending curl request to '%s'...", this->uri);
- res = curl_easy_perform(this->curl);
-
- if (res == CURLE_OK)
- {
- DBG1("received valid curl response");
- response = chunk_clone(curl_response);
- }
- else
- {
- DBG1("curl request failed: %s", curl_error_buffer);
- }
- curl_free(curl_response.ptr);
- }
-#else
- DBG1("warning: libcurl fetching not compiled in");
-#endif /* LIBCURL */
- return response;
-}
-
-/**
- * Implements fetcher_t.post.
- */
-static chunk_t http_post(private_fetcher_t *this, const char *request_type, chunk_t request)
-{
- chunk_t response = chunk_empty;
-
-#ifdef LIBCURL
- if (this->curl)
- {
- CURLcode res;
- struct curl_slist *headers = NULL;
- chunk_t curl_response = chunk_empty;
- char curl_error_buffer[CURL_ERROR_SIZE];
- char content_type[BUF_LEN];
-
- /* set content type header */
- snprintf(content_type, BUF_LEN, "Content-Type: %s", request_type);
- headers = curl_slist_append(headers, content_type);
-
- /* set options */
- curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(this->curl, CURLOPT_URL, this->uri);
- curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, curl_write_buffer);
- curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void *)&curl_response);
- curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, request.ptr);
- curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, request.len);
- curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, &curl_error_buffer);
- curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
- curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, FETCHER_TIMEOUT);
- curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
-
- DBG1("sending http post request to '%s'...", this->uri);
- res = curl_easy_perform(this->curl);
-
- if (res == CURLE_OK)
- {
- DBG1("received valid http response");
- response = chunk_clone(curl_response);
- }
- else
- {
- DBG1("http post request using libcurl failed: %s", curl_error_buffer);
- }
- curl_slist_free_all(headers);
- curl_free(curl_response.ptr);
- }
-#else
- DBG1("warning: libcurl fetching not compiled in");
-#endif /* LIBCURL */
- return response;
-}
-
-#ifdef LIBLDAP
-/**
- * Parses the result returned by an ldap query
- */
-static chunk_t ldap_parse(LDAP *ldap, LDAPMessage *result)
-{
- chunk_t response = chunk_empty;
- err_t ugh = NULL;
-
- LDAPMessage *entry = ldap_first_entry(ldap, result);
-
- if (entry != NULL)
- {
- BerElement *ber = NULL;
- char *attr;
-
- attr = ldap_first_attribute(ldap, entry, &ber);
-
- if (attr != NULL)
- {
- struct berval **values = ldap_get_values_len(ldap, entry, attr);
-
- if (values != NULL)
- {
- if (values[0] != NULL)
- {
- response.len = values[0]->bv_len;
- response.ptr = malloc(response.len);
- memcpy(response.ptr, values[0]->bv_val, response.len);
-
- if (values[1] != NULL)
- {
- ugh = "more than one value was fetched - first selected";
- }
- }
- else
- {
- ugh = "no values in attribute";
- }
- ldap_value_free_len(values);
- }
- else
- {
- ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
- }
- ldap_memfree(attr);
- }
- else
- {
- ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
- }
- ber_free(ber, 0);
- }
- else
- {
- ugh = ldap_err2string(ldap_result2error(ldap, result, 0));
- }
- if (ugh)
- {
- DBG1("ldap request failed: %s", ugh);
- }
- return response;
-}
-#endif /* LIBLDAP */
-
-/**
- * Implements fetcher_t.get for curl methods
- */
-static chunk_t ldap_get(private_fetcher_t *this)
-{
- chunk_t response = chunk_empty;
-
-#ifdef LIBLDAP
- if (this->ldap)
- {
- err_t ugh = NULL;
- int rc;
- int ldap_version = LDAP_VERSION3;
-
- struct timeval timeout;
-
- timeout.tv_sec = FETCHER_TIMEOUT;
- timeout.tv_usec = 0;
-
- ldap_set_option(this->ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
- ldap_set_option(this->ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
-
- DBG1("sending ldap request to '%s'...", this->uri);
-
- rc = ldap_simple_bind_s(this->ldap, NULL, NULL);
- if (rc == LDAP_SUCCESS)
- {
- LDAPMessage *result;
-
- timeout.tv_sec = FETCHER_TIMEOUT;
- timeout.tv_usec = 0;
-
- rc = ldap_search_st(this->ldap, this->lurl->lud_dn,
- this->lurl->lud_scope,
- this->lurl->lud_filter,
- this->lurl->lud_attrs,
- 0, &timeout, &result);
-
- if (rc == LDAP_SUCCESS)
- {
- response = ldap_parse(this->ldap, result);
- if (response.ptr)
- {
- DBG1("received valid ldap response");
- }
- ldap_msgfree(result);
- }
- else
- {
- ugh = ldap_err2string(rc);
- }
- }
- else
- {
- ugh = ldap_err2string(rc);
- }
- ldap_unbind_s(this->ldap);
-
- if (ugh)
- {
- DBG1("ldap request failed: %s", ugh);
- }
- }
-#else /* !LIBLDAP */
- DBG1("warning: libldap fetching not compiled in");
-#endif /* !LIBLDAP */
- return response;
-}
-
-/**
- * Implements fetcher_t.destroy
- */
-static void destroy(private_fetcher_t *this)
-{
-#ifdef LIBCURL
- if (this->curl)
- {
- curl_easy_cleanup(this->curl);
- }
-#endif /* LIBCURL */
-
-#ifdef LIBLDAP
- if (this->lurl)
- {
- ldap_free_urldesc(this->lurl);
- }
-#endif /* LIBLDAP */
-
- free(this);
-}
-
-/*
- * Described in header.
- */
-fetcher_t *fetcher_create(const char *uri)
-{
- private_fetcher_t *this = malloc_thing(private_fetcher_t);
-
- /* initialize */
- this->uri = uri;
-
-#ifdef LIBCURL
- this->curl = NULL;
-#endif /* LIBCURL */
-
-#ifdef LIBLDAP
- this->lurl = NULL;
- this->ldap = NULL;
-#endif /* LIBLDAP */
-
- if (strlen(uri) >= 4 && strncasecmp(uri, "ldap", 4) == 0)
- {
-#ifdef LIBLDAP
- int rc = ldap_url_parse(uri, &this->lurl);
-
- if (rc == LDAP_SUCCESS)
- {
- this->ldap = ldap_init(this->lurl->lud_host,
- this->lurl->lud_port);
- }
- else
- {
- DBG1("ldap: %s", ldap_err2string(rc));
- this->ldap = NULL;
- }
-#endif /* LIBLDAP */
- this->public.get = (chunk_t (*) (fetcher_t*))ldap_get;
- }
- else
- {
-#ifdef LIBCURL
- this->curl = curl_easy_init();
- if (this->curl == NULL)
- {
- DBG1("curl_easy_init_failed()");
- }
-#endif /* LIBCURL */
- this->public.get = (chunk_t (*) (fetcher_t*))curl_get;
- }
-
- /* public functions */
- this->public.post = (chunk_t (*) (fetcher_t*,const char*,chunk_t))http_post;
- this->public.destroy = (void (*) (fetcher_t*))destroy;
-
- return &this->public;
-}
-
-/**
- * Described in header.
- */
-void fetcher_initialize(void)
-{
-#ifdef LIBCURL
- CURLcode res;
-
- /* initialize libcurl */
- DBG1("initializing libcurl");
- res = curl_global_init(CURL_GLOBAL_NOTHING);
- if (res != CURLE_OK)
- {
- DBG1("libcurl could not be initialized: %s", curl_easy_strerror(res));
- }
-#endif /* LIBCURL */
-}
-
-/**
- * Described in header.
- */
-void fetcher_finalize(void)
-{
-#ifdef LIBCURL
- /* finalize libcurl */
- DBG1("finalizing libcurl");
- curl_global_cleanup();
-#endif /* LIBCURL */
-}
-
diff --git a/src/libstrongswan/utils/fetcher.h b/src/libstrongswan/utils/fetcher.h
deleted file mode 100644
index 47b43a0b7..000000000
--- a/src/libstrongswan/utils/fetcher.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file fetcher.h
- *
- * @brief Interface of fetcher_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <fetcher://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT 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 FETCHER_H_
-#define FETCHER_H_
-
-typedef struct fetcher_t fetcher_t;
-
-#include <chunk.h>
-
-#define FETCHER_TIMEOUT 10 /* seconds */
-
-/**
- * @brief Fetches information from an URI (http, file, ftp, etc.)
- *
- * @ingroup utils
- */
-struct fetcher_t {
-
- /**
- * @brief Get information via a get request.
- *
- * @param this calling object
- * @param uri uri specifying the information source
- * @return chunk_t containing the information
- */
- chunk_t (*get) (fetcher_t *this);
-
- /**
- * @brief Get information via a get request.
- *
- * @param this calling object
- * @param uri uri specifying the information source
- * @param type content type of http post request
- * @param request binary data for http post request
- * @return chunk_t containing the information
- */
- chunk_t (*post) (fetcher_t *this, const char *type, chunk_t request);
-
- /**
- * @brief Destroys the fetcher_t object.
- *
- * @param this fetcher_t to destroy
- */
- void (*destroy) (fetcher_t *this);
-
-};
-
-/**
- * @brief Create a fetcher_t object.
- *
- * @return created fetcher_t object
- *
- * @ingroup utils
- */
-fetcher_t* fetcher_create(const char *uri);
-
-/**
- * @brief Initializes the fetcher_t class
- *
- * call this function only once in the main program
- *
- * @ingroup utils
- */
-void fetcher_initialize(void);
-
-/**
- * @brief Finalizes the fetcher_t class
- *
- * call this function only once befor exiting the main program
- *
- * @ingroup utils
- */
-void fetcher_finalize(void);
-
-#endif /*FETCHER_H_*/
diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c
index 68e9c9500..eb87f27bc 100644
--- a/src/libstrongswan/utils/host.c
+++ b/src/libstrongswan/utils/host.c
@@ -1,10 +1,3 @@
-/**
- * @file host.c
- *
- * @brief Implementation of host_t.
- *
- */
-
/*
* Copyright (C) 2006-2007 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
@@ -21,18 +14,23 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: host.c 4056 2008-06-11 07:44:23Z martin $
*/
+#define _GNU_SOURCE
+#include <netdb.h>
#include <string.h>
#include <printf.h>
#include "host.h"
+#include <debug.h>
typedef struct private_host_t private_host_t;
/**
- * @brief Private Data of a host object.
+ * Private Data of a host object.
*/
struct private_host_t {
/**
@@ -111,56 +109,79 @@ static int print(FILE *stream, const struct printf_info *info,
const void *const *args)
{
private_host_t *this = *((private_host_t**)(args[0]));
- char buffer[INET6_ADDRSTRLEN];
- void *address;
- u_int16_t port;
+ char buffer[INET6_ADDRSTRLEN + 16];
if (this == NULL)
{
- return fprintf(stream, "(null)");
+ snprintf(buffer, sizeof(buffer), "(null)");
}
-
- if (is_anyaddr(this))
+ else if (is_anyaddr(this))
{
- return fprintf(stream, "%%any");
+ snprintf(buffer, sizeof(buffer), "%%any");
}
-
- switch (this->address.sa_family)
+ else
{
- case AF_INET:
- address = &this->address4.sin_addr;
- port = this->address4.sin_port;
- break;
- case AF_INET6:
- address = &this->address6.sin6_addr;
- port = this->address6.sin6_port;
- break;
- default:
- return fprintf(stream, "(family not supported)");
- }
+ void *address;
+ u_int16_t port;
+ int len;
+
+ address = &this->address6.sin6_addr;
+ port = this->address6.sin6_port;
+
+ switch (this->address.sa_family)
+ {
+ case AF_INET:
+ address = &this->address4.sin_addr;
+ port = this->address4.sin_port;
+ /* fall */
+ case AF_INET6:
- if (inet_ntop(this->address.sa_family, address,
- buffer, sizeof(buffer)) == NULL)
- {
- return fprintf(stream, "(address conversion failed)");
+ if (inet_ntop(this->address.sa_family, address,
+ buffer, sizeof(buffer)) == NULL)
+ {
+ snprintf(buffer, sizeof(buffer),
+ "(address conversion failed)");
+ }
+ else if (info->alt)
+ {
+ len = strlen(buffer);
+ snprintf(buffer + len, sizeof(buffer) - len,
+ "[%d]", ntohs(port));
+ }
+ break;
+ default:
+ snprintf(buffer, sizeof(buffer), "(family not supported)");
+ break;
+ }
}
-
- if (info->alt)
+ if (info->left)
{
- return fprintf(stream, "%s[%d]", buffer, ntohs(port));
+ return fprintf(stream, "%-*s", info->width, buffer);
}
- else
+ return fprintf(stream, "%*s", info->width, buffer);
+}
+
+
+/**
+ * arginfo handler for printf() hosts
+ */
+int arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (n > 0)
{
- return fprintf(stream, "%s", buffer);
+ argtypes[0] = PA_POINTER;
}
+ return 1;
}
/**
- * register printf() handlers
+ * return printf hook functions for a host
*/
-static void __attribute__ ((constructor))print_register()
+printf_hook_functions_t host_get_printf_hooks()
{
- register_printf_function(PRINTF_HOST, print, arginfo_ptr);
+ printf_hook_functions_t hooks = {print, arginfo};
+
+ return hooks;
}
/**
@@ -433,6 +454,61 @@ host_t *host_create_from_string(char *string, u_int16_t port)
/*
* Described in header.
*/
+host_t *host_create_from_dns(char *string, int af, u_int16_t port)
+{
+ private_host_t *this;
+ struct hostent host, *ptr;
+ char buf[512];
+ int err, ret;
+
+ if (strchr(string, ':'))
+ { /* gethostbyname does not like IPv6 addresses, fallback */
+ return host_create_from_string(string, port);
+ }
+
+ if (af)
+ {
+ ret = gethostbyname2_r(string, af, &host, buf, sizeof(buf), &ptr, &err);
+ }
+ else
+ {
+ ret = gethostbyname_r(string, &host, buf, sizeof(buf), &ptr, &err);
+ }
+ if (ret != 0)
+ {
+ DBG1("resolving '%s' failed: %s", string, hstrerror(err));
+ return NULL;
+ }
+ if (ptr == NULL)
+ {
+ DBG1("resolving '%s' failed", string);
+ }
+ this = host_create_empty();
+ this->address.sa_family = host.h_addrtype;
+ switch (this->address.sa_family)
+ {
+ case AF_INET:
+ memcpy(&this->address4.sin_addr.s_addr,
+ host.h_addr_list[0], host.h_length);
+ this->address4.sin_port = htons(port);
+ this->socklen = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ memcpy(&this->address6.sin6_addr.s6_addr,
+ host.h_addr_list[0], host.h_length);
+ this->address6.sin6_port = htons(port);
+ this->socklen = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+/*
+ * Described in header.
+ */
host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port)
{
private_host_t *this = host_create_empty();
diff --git a/src/libstrongswan/utils/host.h b/src/libstrongswan/utils/host.h
index ee9aa457f..6a1d824c6 100644
--- a/src/libstrongswan/utils/host.h
+++ b/src/libstrongswan/utils/host.h
@@ -1,14 +1,7 @@
-/**
- * @file host.h
- *
- * @brief Interface of host_t.
- *
- */
-
/*
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2006-2007 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -23,6 +16,11 @@
* for more details.
*/
+/**
+ * @defgroup host host
+ * @{ @ingroup utils
+ */
+
#ifndef HOST_H_
#define HOST_H_
@@ -49,42 +47,31 @@ enum host_diff_t {
};
/**
- * @brief Representates a Host
+ * Representates a Host
*
* Host object, identifies a address:port pair and defines some
* useful functions on it.
- *
- * @b Constructors:
- * - host_create()
- * - host_create_from_chunk()
- * - host_create_from_sockaddr()
- *
- * @todo Add IPv6 support
- *
- * @ingroup utils
*/
struct host_t {
/**
- * @brief Build a clone of this host object.
+ * Build a clone of this host object.
*
- * @param this object to clone
- * @return cloned host
+ * @return cloned host
*/
host_t *(*clone) (host_t *this);
/**
- * @brief Get a pointer to the internal sockaddr struct.
+ * Get a pointer to the internal sockaddr struct.
*
* This is used for sending and receiving via sockets.
*
- * @param this object to clone
- * @return pointer to the internal sockaddr structure
+ * @return pointer to the internal sockaddr structure
*/
sockaddr_t *(*get_sockaddr) (host_t *this);
/**
- * @brief Get the length of the sockaddr struct.
+ * Get the length of the sockaddr struct.
*
* Depending on the family, the length of the sockaddr struct
* is different. Use this function to get the length of the sockaddr
@@ -92,140 +79,129 @@ struct host_t {
*
* This is used for sending and receiving via sockets.
*
- * @param this object to clone
- * @return length of the sockaddr struct
+ * @return length of the sockaddr struct
*/
socklen_t *(*get_sockaddr_len) (host_t *this);
/**
- * @brief Gets the family of the address
+ * Gets the family of the address
*
- * @param this calling object
- * @return family
+ * @return family
*/
int (*get_family) (host_t *this);
/**
- * @brief Checks if the ip address of host is set to default route.
+ * Checks if the ip address of host is set to default route.
*
- * @param this calling object
- * @return
- * - TRUE if host has IP 0.0.0.0 for default route
- * - FALSE otherwise
+ * @return TRUE if host is 0.0.0.0 or 0::0, FALSE otherwise
*/
bool (*is_anyaddr) (host_t *this);
/**
- * @brief get the address of this host as chunk_t
+ * Get the address of this host as chunk_t
*
* Returned chunk points to internal data.
*
- * @param this object
- * @return address string,
+ * @return address string,
*/
chunk_t (*get_address) (host_t *this);
/**
- * @brief get the port of this host
+ * Get the port of this host
*
- * @param this object to clone
- * @return port number
+ * @return port number
*/
u_int16_t (*get_port) (host_t *this);
/**
- * @brief set the port of this host
+ * Set the port of this host
*
- * @param this object to clone
- * @param port port numer
+ * @param port port numer
*/
void (*set_port) (host_t *this, u_int16_t port);
/**
- * @brief Compare the ips of two hosts hosts.
+ * Compare the ips of two hosts hosts.
*
- * @param this object to compare
- * @param other the other to compare
- * @return TRUE if addresses are equal.
+ * @param other the other to compare
+ * @return TRUE if addresses are equal.
*/
bool (*ip_equals) (host_t *this, host_t *other);
/**
- * @brief Compare two hosts, with port.
+ * Compare two hosts, with port.
*
- * @param this object to compare
- * @param other the other to compare
- * @return TRUE if addresses and ports are equal.
+ * @param other the other to compare
+ * @return TRUE if addresses and ports are equal.
*/
bool (*equals) (host_t *this, host_t *other);
/**
- * @brief Compare two hosts and return the differences.
+ * Compare two hosts and return the differences.
*
- * @param this object to compare
- * @param other the other to compare
- * @return differences in a combination of host_diff_t's
+ * @param other the other to compare
+ * @return differences in a combination of host_diff_t's
*/
host_diff_t (*get_differences) (host_t *this, host_t *other);
/**
- * @brief Destroy this host object
- *
- * @param this calling
- * @return SUCCESS in any case
+ * Destroy this host object.
*/
void (*destroy) (host_t *this);
};
/**
- * @brief Constructor to create a host_t object from an address string.
+ * Constructor to create a host_t object from an address string.
*
* @param string string of an address, such as "152.96.193.130"
* @param port port number
- * @return
- * - host_t object
- * - NULL, if string not an address.
- *
- * @ingroup network
+ * @return host_t, NULL if string not an address.
*/
host_t *host_create_from_string(char *string, u_int16_t port);
/**
- * @brief Constructor to create a host_t object from an address chunk
+ * Constructor to create a host_t from a DNS name.
*
- * @param family Address family to use for this object, such as AF_INET or AF_INET6
- * @param address address as 4 byte chunk_t in networ order
+ * @param string hostname to resolve
+ * @param family family to prefer, 0 for first match
* @param port port number
- * @return
- * - host_t object
- * - NULL, if family not supported or chunk_t length not 4 bytes.
- *
- * @ingroup network
+ * @return host_t, NULL lookup failed
+ */
+host_t *host_create_from_dns(char *string, int family, u_int16_t port);
+
+/**
+ * Constructor to create a host_t object from an address chunk
+ *
+ * @param family Address family, such as AF_INET or AF_INET6
+ * @param address address as chunk_t in networ order
+ * @param port port number
+ * @return host_t, NULL if family not supported/chunk invalid
*/
host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port);
/**
- * @brief Constructor to create a host_t object from a sockaddr struct
+ * Constructor to create a host_t object from a sockaddr struct
*
* @param sockaddr sockaddr struct which contains family, address and port
- * @return
- * - host_t object
- * - NULL, if family not supported.
- *
- * @ingroup network
+ * @return host_t, NULL if family not supported
*/
host_t *host_create_from_sockaddr(sockaddr_t *sockaddr);
/**
- * @brief Create a host without an address, a "any" host.
+ * Create a host without an address, a "any" host.
*
* @param family family of the any host
- * @return
- * - host_t object
- * - NULL, if family not supported.
- *
- * @ingroup network
+ * @return host_t, NULL if family not supported
*/
host_t *host_create_any(int family);
-#endif /*HOST_H_*/
+/**
+ * Get printf hooks for a host.
+ *
+ * Arguments are:
+ * host_t *host
+ * Use #-modifier to include port number
+ */
+printf_hook_functions_t host_get_printf_hooks();
+
+#endif /* HOST_H_ @}*/
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index 18f6d6824..39d49bf6c 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -1,12 +1,5 @@
-/**
- * @file identification.c
- *
- * @brief Implementation of identification_t.
- *
- */
-
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -20,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: identification.c 3256 2007-10-07 13:42:43Z andreas $
+ * $Id: identification.c 4064 2008-06-13 15:10:01Z martin $
*/
#define _GNU_SOURCE
@@ -34,8 +27,17 @@
#include "identification.h"
+#include <asn1/oid.h>
#include <asn1/asn1.h>
+ENUM_BEGIN(id_match_names, ID_MATCH_NONE, ID_MATCH_MAX_WILDCARDS,
+ "MATCH_NONE",
+ "MATCH_ANY",
+ "MATCH_MAX_WILDCARDS");
+ENUM_NEXT(id_match_names, ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_MAX_WILDCARDS,
+ "MATCH_PERFECT");
+ENUM_END(id_match_names, ID_MATCH_PERFECT);
+
ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID,
"ID_ANY",
"ID_IPV4_ADDR",
@@ -49,10 +51,12 @@ ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID,
"ID_DER_ASN1_DN",
"ID_DER_ASN1_GN",
"ID_KEY_ID");
-ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_DER_ASN1_GN_URI, ID_KEY_ID,
- "ID_DER_ASN1_GN_URI");
-ENUM_END(id_type_names, ID_DER_ASN1_GN_URI);
-
+ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_CERT_DER_SHA1, ID_KEY_ID,
+ "ID_DER_ASN1_GN_URI",
+ "ID_PUBKEY_INFO_SHA1",
+ "ID_PUBKEY_SHA1",
+ "ID_CERT_DER_SHA1");
+ENUM_END(id_type_names, ID_CERT_DER_SHA1);
/**
* X.501 acronyms for well known object identifiers (OIDs)
@@ -237,7 +241,7 @@ static chunk_t sanitize_chunk(chunk_t chunk)
/**
* Pointer is set to the first RDN in a DN
*/
-static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
+static bool init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
{
*rdn = chunk_empty;
*attribute = chunk_empty;
@@ -246,7 +250,7 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex
if (*dn.ptr != ASN1_SEQUENCE)
{
/* DN is not a SEQUENCE */
- return FAILED;
+ return FALSE;
}
rdn->len = asn1_length(&dn);
@@ -254,7 +258,7 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex
if (rdn->len == ASN1_INVALID_LENGTH)
{
/* Invalid RDN length */
- return FAILED;
+ return FALSE;
}
rdn->ptr = dn.ptr;
@@ -262,13 +266,13 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex
/* are there any RDNs ? */
*next = rdn->len > 0;
- return SUCCESS;
+ return TRUE;
}
/**
* Fetches the next RDN in a DN
*/
-static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value, asn1_t *type, bool *next)
+static bool get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value, asn1_t *type, bool *next)
{
chunk_t body;
@@ -283,13 +287,13 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (*rdn->ptr != ASN1_SET)
{
/* RDN is not a SET */
- return FAILED;
+ return FALSE;
}
attribute->len = asn1_length(rdn);
if (attribute->len == ASN1_INVALID_LENGTH)
{
/* Invalid attribute length */
- return FAILED;
+ return FALSE;
}
attribute->ptr = rdn->ptr;
/* advance to start of next RDN */
@@ -301,7 +305,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (*attribute->ptr != ASN1_SEQUENCE)
{
/* attributeTypeAndValue is not a SEQUENCE */
- return FAILED;
+ return FALSE;
}
/* extract the attribute body */
@@ -310,7 +314,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (body.len == ASN1_INVALID_LENGTH)
{
/* Invalid attribute body length */
- return FAILED;
+ return FALSE;
}
body.ptr = attribute->ptr;
@@ -323,7 +327,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (*body.ptr != ASN1_OID)
{
/* attributeType is not an OID */
- return FAILED;
+ return FALSE;
}
/* extract OID */
oid->len = asn1_length(&body);
@@ -331,7 +335,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (oid->len == ASN1_INVALID_LENGTH)
{
/* Invalid attribute OID length */
- return FAILED;
+ return FALSE;
}
oid->ptr = body.ptr;
@@ -348,19 +352,19 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
if (value->len == ASN1_INVALID_LENGTH)
{
/* Invalid attribute string length */
- return FAILED;
+ return FALSE;
}
value->ptr = body.ptr;
/* are there any RDNs left? */
*next = rdn->len > 0 || attribute->len > 0;
- return SUCCESS;
+ return TRUE;
}
/**
* Parses an ASN.1 distinguished name int its OID/value pairs
*/
-static status_t dntoa(chunk_t dn, chunk_t *str)
+static bool dntoa(chunk_t dn, chunk_t *str)
{
chunk_t rdn, oid, attribute, value, proper;
asn1_t type;
@@ -368,17 +372,17 @@ static status_t dntoa(chunk_t dn, chunk_t *str)
bool next;
bool first = TRUE;
- status_t status = init_rdn(dn, &rdn, &attribute, &next);
-
- if (status != SUCCESS)
- return status;
+ if (!init_rdn(dn, &rdn, &attribute, &next))
+ {
+ return FALSE;
+ }
while (next)
{
- status = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
-
- if (status != SUCCESS)
- return status;
+ if (!get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next))
+ {
+ return FALSE;
+ }
if (first)
{ /* first OID/value pair */
@@ -390,7 +394,7 @@ static status_t dntoa(chunk_t dn, chunk_t *str)
}
/* print OID */
- oid_code = known_oid(oid);
+ oid_code = asn1_known_oid(oid);
if (oid_code == OID_UNKNOWN)
{
update_chunk(str, snprintf(str->ptr,str->len,"0x#B", &oid));
@@ -404,7 +408,7 @@ static status_t dntoa(chunk_t dn, chunk_t *str)
update_chunk(str, snprintf(str->ptr,str->len,"=%.*s", (int)proper.len, proper.ptr));
chunk_free(&proper);
}
- return SUCCESS;
+ return TRUE;
}
/**
@@ -420,15 +424,17 @@ static bool same_dn(chunk_t a, chunk_t b)
/* same lengths for the DNs */
if (a.len != b.len)
+ {
return FALSE;
-
+ }
/* try a binary comparison first */
if (memeq(a.ptr, b.ptr, b.len))
+ {
return TRUE;
-
+ }
/* initialize DN parsing */
- if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != SUCCESS
- || init_rdn(b, &rdn_b, &attribute_b, &next_b) != SUCCESS)
+ if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) ||
+ !init_rdn(b, &rdn_b, &attribute_b, &next_b))
{
return FALSE;
}
@@ -437,23 +443,27 @@ static bool same_dn(chunk_t a, chunk_t b)
while (next_a && next_b)
{
/* parse next RDNs and check for errors */
- if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != SUCCESS
- || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != SUCCESS)
+ if (!get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) ||
+ !get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b))
{
return FALSE;
}
/* OIDs must agree */
- if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
+ if (oid_a.len != oid_b.len || !memeq(oid_a.ptr, oid_b.ptr, oid_b.len))
+ {
return FALSE;
+ }
/* same lengths for values */
if (value_a.len != value_b.len)
+ {
return FALSE;
+ }
/* printableStrings and email RDNs require uppercase comparison */
- if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING
- || (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
+ if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
+ (type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL)))
{
if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
{
@@ -470,8 +480,9 @@ static bool same_dn(chunk_t a, chunk_t b)
}
/* both DNs must have same number of RDNs */
if (next_a || next_b)
+ {
return FALSE;
-
+ }
/* the two DNs are equal! */
return TRUE;
}
@@ -490,14 +501,11 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
bool next_a, next_b;
/* initialize wildcard counter */
- if (wildcards)
- {
- *wildcards = 0;
- }
+ *wildcards = 0;
/* initialize DN parsing */
- if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != SUCCESS
- || init_rdn(b, &rdn_b, &attribute_b, &next_b) != SUCCESS)
+ if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) ||
+ !init_rdn(b, &rdn_b, &attribute_b, &next_b))
{
return FALSE;
}
@@ -506,31 +514,32 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
while (next_a && next_b)
{
/* parse next RDNs and check for errors */
- if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != SUCCESS
- || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != SUCCESS)
+ if (!get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) ||
+ !get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b))
{
return FALSE;
}
/* OIDs must agree */
if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
+ {
return FALSE;
+ }
/* does rdn_b contain a wildcard? */
if (value_b.len == 1 && *value_b.ptr == '*')
{
- if (wildcards)
- {
- (*wildcards)++;
- }
+ (*wildcards)++;
continue;
}
/* same lengths for values */
if (value_a.len != value_b.len)
+ {
return FALSE;
+ }
/* printableStrings and email RDNs require uppercase comparison */
- if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING
- || (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
+ if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
+ (type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL)))
{
if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
{
@@ -550,12 +559,8 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
{
return FALSE;
}
-
/* the two DNs match! */
- if (wildcards)
- {
- *wildcards = min(*wildcards, MAX_WILDCARDS);
- }
+ *wildcards = min(*wildcards, ID_MATCH_ONE_WILDCARD - ID_MATCH_MAX_WILDCARDS);
return TRUE;
}
@@ -645,7 +650,8 @@ static status_t atodn(char *src, chunk_t *dn)
{
name.len -= whitespace;
rdn_type = (x501rdns[i].type == ASN1_PRINTABLESTRING
- && !is_printablestring(name))? ASN1_T61STRING : x501rdns[i].type;
+ && !asn1_is_printablestring(name))
+ ? ASN1_T61STRING : x501rdns[i].type;
if (rdn_count < RDN_MAX)
{
@@ -675,7 +681,7 @@ static status_t atodn(char *src, chunk_t *dn)
/* build the distinguished name sequence */
{
int i;
- u_char *pos = build_asn1_object(dn, ASN1_SEQUENCE, dn_len);
+ u_char *pos = asn1_build_object(dn, ASN1_SEQUENCE, dn_len);
for (i = 0; i < rdn_count; i++)
{
@@ -776,198 +782,189 @@ static bool equals_strcasecmp(private_identification_t *this,
/**
* Default implementation of identification_t.matches.
*/
-static bool matches_binary(private_identification_t *this,
- private_identification_t *other, int *wildcards)
+static id_match_t matches_binary(private_identification_t *this,
+ private_identification_t *other)
{
if (other->type == ID_ANY)
{
- if (wildcards)
- {
- *wildcards = MAX_WILDCARDS;
- }
- return TRUE;
+ return ID_MATCH_ANY;
}
- if (wildcards)
+ if (this->type == other->type &&
+ chunk_equals(this->encoded, other->encoded))
{
- *wildcards = 0;
+ return ID_MATCH_PERFECT;
}
- return this->type == other->type &&
- chunk_equals(this->encoded, other->encoded);
+ return ID_MATCH_NONE;
}
/**
* Special implementation of identification_t.matches for ID_RFC822_ADDR/ID_FQDN.
* Checks for a wildcard in other-string, and compares it against this-string.
*/
-static bool matches_string(private_identification_t *this,
- private_identification_t *other, int *wildcards)
+static id_match_t matches_string(private_identification_t *this,
+ private_identification_t *other)
{
u_int len = other->encoded.len;
if (other->type == ID_ANY)
{
- if (wildcards)
- {
- *wildcards = MAX_WILDCARDS;
- }
- return TRUE;
+ return ID_MATCH_ANY;
}
-
if (this->type != other->type)
- return FALSE;
-
- /* try a binary comparison first */
- if (equals_binary(this, other))
{
- if (wildcards)
- {
- *wildcards = 0;
- }
- return TRUE;
+ return ID_MATCH_NONE;
+ }
+ /* try a equals check first */
+ if (equals_strcasecmp(this, other))
+ {
+ return ID_MATCH_PERFECT;
}
-
if (len == 0 || this->encoded.len < len)
- return FALSE;
+ {
+ return ID_MATCH_NONE;
+ }
/* check for single wildcard at the head of the string */
if (*other->encoded.ptr == '*')
{
- if (wildcards)
- {
- *wildcards = 1;
- }
-
/* single asterisk matches any string */
if (len-- == 1)
- return TRUE;
-
- if (memeq(this->encoded.ptr + this->encoded.len - len, other->encoded.ptr + 1, len))
- return TRUE;
+ { /* not better than ID_ANY */
+ return ID_MATCH_ANY;
+ }
+ if (strncasecmp(this->encoded.ptr + this->encoded.len - len,
+ other->encoded.ptr + 1, len) == 0)
+ {
+ return ID_MATCH_ONE_WILDCARD;
+ }
}
-
- return FALSE;
+ return ID_MATCH_NONE;
}
/**
* Special implementation of identification_t.matches for ID_ANY.
* ANY matches only another ANY, but nothing other
*/
-static bool matches_any(private_identification_t *this,
- private_identification_t *other, int *wildcards)
+static id_match_t matches_any(private_identification_t *this,
+ private_identification_t *other)
{
- if (wildcards)
+ if (other->type == ID_ANY)
{
- *wildcards = 0;
+ return ID_MATCH_ANY;
}
- return other->type == ID_ANY;
+ return ID_MATCH_NONE;
}
/**
- * Special implementation of identification_t.matches for ID_DER_ASN1_DN.
- * ANY matches any, even ANY, thats why its there...
+ * Special implementation of identification_t.matches for ID_DER_ASN1_DN
*/
-static bool matches_dn(private_identification_t *this,
- private_identification_t *other, int *wildcards)
+static id_match_t matches_dn(private_identification_t *this,
+ private_identification_t *other)
{
+ int wc;
+
if (other->type == ID_ANY)
{
- if (wildcards)
- {
- *wildcards = MAX_WILDCARDS;
- }
- return TRUE;
+ return ID_MATCH_ANY;
}
if (this->type == other->type)
{
- return match_dn(this->encoded, other->encoded, wildcards);
+ if (match_dn(this->encoded, other->encoded, &wc))
+ {
+ return ID_MATCH_PERFECT - wc;
+ }
}
- return FALSE;
+ return ID_MATCH_NONE;
}
/**
* output handler in printf()
*/
static int print(FILE *stream, const struct printf_info *info,
- const void *const *args)
+ const void *const *args)
{
private_identification_t *this = *((private_identification_t**)(args[0]));
char buf[BUF_LEN];
chunk_t proper, buf_chunk = chunk_from_buf(buf);
- int written;
if (this == NULL)
{
- return fprintf(stream, "(null)");
+ return fprintf(stream, "%*s", info->width, "(null)");
}
switch (this->type)
{
case ID_ANY:
- return fprintf(stream, "%%any");
+ snprintf(buf, sizeof(buf), "%%any");
+ break;
case ID_IPV4_ADDR:
if (this->encoded.len < sizeof(struct in_addr) ||
inet_ntop(AF_INET, this->encoded.ptr, buf, sizeof(buf)) == NULL)
{
- return fprintf(stream, "(invalid ID_IPV4_ADDR)");
- }
- else
- {
- return fprintf(stream, "%s", buf);
+ snprintf(buf, sizeof(buf), "(invalid ID_IPV4_ADDR)");
}
+ break;
case ID_IPV6_ADDR:
if (this->encoded.len < sizeof(struct in6_addr) ||
inet_ntop(AF_INET6, this->encoded.ptr, buf, INET6_ADDRSTRLEN) == NULL)
{
- return fprintf(stream, "(invalid ID_IPV6_ADDR)");
- }
- else
- {
- return fprintf(stream, "%s", buf);
+ snprintf(buf, sizeof(buf), "(invalid ID_IPV6_ADDR)");
}
+ break;
case ID_FQDN:
- {
- proper = sanitize_chunk(this->encoded);
- written = fprintf(stream, "%.*s", proper.len, proper.ptr);
- chunk_free(&proper);
- return written;
- }
case ID_RFC822_ADDR:
- {
+ case ID_DER_ASN1_GN_URI:
proper = sanitize_chunk(this->encoded);
- written = fprintf(stream, "%.*s", proper.len, proper.ptr);
+ snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr);
chunk_free(&proper);
- return written;
- }
+ break;
case ID_DER_ASN1_DN:
- {
- snprintf(buf, sizeof(buf), "%.*s", this->encoded.len, this->encoded.ptr);
- /* TODO: whats returned on failure?*/
- dntoa(this->encoded, &buf_chunk);
- return fprintf(stream, "%s", buf);
- }
+ if (!dntoa(this->encoded, &buf_chunk))
+ {
+ snprintf(buf, sizeof(buf), "(invalid ID_DER_ASN1_DN)");
+ }
+ break;
case ID_DER_ASN1_GN:
- return fprintf(stream, "(ASN.1 general Name");
+ snprintf(buf, sizeof(buf), "(ASN.1 general Name");
+ break;
case ID_KEY_ID:
- return fprintf(stream, "(KEY_ID)");
- case ID_DER_ASN1_GN_URI:
- {
- proper = sanitize_chunk(this->encoded);
- written = fprintf(stream, "%.*s", proper.len, proper.ptr);
- chunk_free(&proper);
- return written;
- }
+ case ID_PUBKEY_INFO_SHA1:
+ case ID_PUBKEY_SHA1:
+ case ID_CERT_DER_SHA1:
+ snprintf(buf, sizeof(buf), "%#B", &this->encoded);
+ break;
default:
- return fprintf(stream, "(unknown ID type: %d)", this->type);
+ snprintf(buf, sizeof(buf), "(unknown ID type: %d)", this->type);
+ break;
+ }
+ if (info->left)
+ {
+ return fprintf(stream, "%-*s", info->width, buf);
+ }
+ return fprintf(stream, "%*s", info->width, buf);
+}
+
+/**
+ * arginfo handler
+ */
+static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (n > 0)
+ {
+ argtypes[0] = PA_POINTER;
}
+ return 1;
}
/**
- * register printf() handlers
+ * Get printf hook functions
*/
-static void __attribute__ ((constructor))print_register()
+printf_hook_functions_t identification_get_printf_hooks()
{
- register_printf_function(PRINTF_IDENTIFICATION, print, arginfo_ptr);
+ printf_hook_functions_t hook = {print, arginfo};
+
+ return hook;
}
/**
@@ -1011,7 +1008,7 @@ static private_identification_t *identification_create(void)
this->public.destroy = (void (*) (identification_t*))destroy;
/* we use these as defaults, the may be overloaded for special ID types */
this->public.equals = (bool (*) (identification_t*,identification_t*))equals_binary;
- this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_binary;
+ this->public.matches = (id_match_t (*) (identification_t*,identification_t*))matches_binary;
this->encoded = chunk_empty;
@@ -1041,7 +1038,7 @@ identification_t *identification_create_from_string(char *string)
}
this->type = ID_DER_ASN1_DN;
this->public.equals = (bool (*) (identification_t*,identification_t*))equals_dn;
- this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_dn;
+ this->public.matches = (id_match_t (*) (identification_t*,identification_t*))matches_dn;
return &this->public;
}
else if (strchr(string, '@') == NULL)
@@ -1054,8 +1051,8 @@ identification_t *identification_create_from_string(char *string)
{
/* any ID will be accepted */
this->type = ID_ANY;
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_any;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_any;
return &this->public;
}
else
@@ -1072,8 +1069,8 @@ identification_t *identification_create_from_string(char *string)
this->type = ID_FQDN;
this->encoded.ptr = strdup(string);
this->encoded.len = strlen(string);
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_string;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_string;
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_strcasecmp;
return &(this->public);
@@ -1105,17 +1102,19 @@ identification_t *identification_create_from_string(char *string)
{
if (*(string + 1) == '#')
{
- /* TODO: Pluto handles '#' as hex encoded ID_KEY_ID. */
- free(this);
- return NULL;
+ string += 2;
+ this->type = ID_KEY_ID;
+ this->encoded = chunk_from_hex(
+ chunk_create(string, strlen(string)), NULL);
+ return &(this->public);
}
else
{
this->type = ID_FQDN;
this->encoded.ptr = strdup(string + 1);
this->encoded.len = strlen(string + 1);
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_string;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_string;
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_strcasecmp;
return &(this->public);
@@ -1126,8 +1125,8 @@ identification_t *identification_create_from_string(char *string)
this->type = ID_RFC822_ADDR;
this->encoded.ptr = strdup(string);
this->encoded.len = strlen(string);
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_string;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_string;
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_strcasecmp;
return &(this->public);
@@ -1146,27 +1145,30 @@ identification_t *identification_create_from_encoding(id_type_t type, chunk_t en
switch (type)
{
case ID_ANY:
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_any;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_any;
break;
case ID_FQDN:
case ID_RFC822_ADDR:
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_string;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_string;
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_strcasecmp;
break;
case ID_DER_ASN1_DN:
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_dn;
- this->public.matches = (bool (*)
- (identification_t*,identification_t*,int*))matches_dn;
+ this->public.matches = (id_match_t (*)
+ (identification_t*,identification_t*))matches_dn;
break;
case ID_IPV4_ADDR:
case ID_IPV6_ADDR:
case ID_DER_ASN1_GN:
case ID_KEY_ID:
case ID_DER_ASN1_GN_URI:
+ case ID_PUBKEY_INFO_SHA1:
+ case ID_PUBKEY_SHA1:
+ case ID_CERT_DER_SHA1:
default:
break;
}
diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h
index 59c568eaf..591909411 100644
--- a/src/libstrongswan/utils/identification.h
+++ b/src/libstrongswan/utils/identification.h
@@ -1,10 +1,3 @@
-/**
- * @file identification.h
- *
- * @brief Interface of identification_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: identification.h 3838 2008-04-18 11:24:45Z tobias $
+ */
+
+/**
+ * @defgroup identification identification
+ * @{ @ingroup utils
*/
@@ -27,15 +27,33 @@
typedef enum id_type_t id_type_t;
typedef struct identification_t identification_t;
+typedef enum id_match_t id_match_t;
#include <library.h>
-#define MAX_WILDCARDS 14
+/**
+ * Matches returned from identification_t.match
+ */
+enum id_match_t {
+ /* no match */
+ ID_MATCH_NONE = 0,
+ /* match to %any ID */
+ ID_MATCH_ANY = 1,
+ /* match with maximum allowed wildcards */
+ ID_MATCH_MAX_WILDCARDS = 2,
+ /* match with only one wildcard */
+ ID_MATCH_ONE_WILDCARD = 19,
+ /* perfect match, won't get better */
+ ID_MATCH_PERFECT = 20,
+};
/**
- * @brief ID Types in a ID payload.
- *
- * @ingroup utils
+ * enum names for id_match_t.
+ */
+extern enum_name_t *id_match_names;
+
+/**
+ * ID Types in a ID payload.
*/
enum id_type_t {
@@ -109,7 +127,21 @@ enum id_type_t {
* private type which represents a GeneralName of type URI
*/
ID_DER_ASN1_GN_URI = 201,
-
+
+ /**
+ * SHA1 hash over PKCS#1 subjectPublicKeyInfo
+ */
+ ID_PUBKEY_INFO_SHA1,
+
+ /**
+ * SHA1 hash over PKCS#1 subjectPublicKey
+ */
+ ID_PUBKEY_SHA1,
+
+ /**
+ * SHA1 hash of the binary DER encoding of a certificate
+ */
+ ID_CERT_DER_SHA1,
};
/**
@@ -118,110 +150,84 @@ enum id_type_t {
extern enum_name_t *id_type_names;
/**
- * @brief Generic identification, such as used in ID payload.
- *
- * The following types are possible:
- * - ID_IPV4_ADDR
- * - ID_FQDN
- * - ID_RFC822_ADDR
- * - ID_IPV6_ADDR
- * - ID_DER_ASN1_DN
- * - ID_DER_ASN1_GN
- * - ID_KEY_ID
- * - ID_DER_ASN1_GN_URI
- *
- * @b Constructors:
- * - identification_create_from_string()
- * - identification_create_from_encoding()
+ * Generic identification, such as used in ID payload.
*
* @todo Support for ID_DER_ASN1_GN is minimal right now. Comparison
* between them and ID_IPV4_ADDR/RFC822_ADDR would be nice.
- *
- * @ingroup utils
*/
struct identification_t {
/**
- * @brief Get the encoding of this id, to send over
+ * Get the encoding of this id, to send over
* the network.
*
- * @warning Result points to internal data, do NOT free!
+ * Result points to internal data, do not free.
*
- * @param this the identification_t object
* @return a chunk containing the encoded bytes
*/
chunk_t (*get_encoding) (identification_t *this);
/**
- * @brief Get the type of this identification.
+ * Get the type of this identification.
*
- * @param this the identification_t object
* @return id_type_t
*/
id_type_t (*get_type) (identification_t *this);
/**
- * @brief Check if two identification_t objects are equal.
+ * Check if two identification_t objects are equal.
*
- * @param this the identification_t object
* @param other other identification_t object
* @return TRUE if the IDs are equal
*/
bool (*equals) (identification_t *this, identification_t *other);
/**
- * @brief Check if an ID matches a wildcard ID.
+ * Check if an ID matches a wildcard ID.
*
* An identification_t may contain wildcards, such as
* *@strongswan.org. This call checks if a given ID
* (e.g. tester@strongswan.org) belongs to a such wildcard
- * ID. Returns TRUE if
+ * ID. Returns > 0 if
* - IDs are identical
* - other is of type ID_ANY
* - other contains a wildcard and matches this
+ *
+ * The larger the return value is, the better is the match. Zero means
+ * no match at all, 1 means a bad match, and 2 a slightly better match.
*
- * @param this the ID without wildcard
- * @param other the ID containing a wildcard
+ * @param other the ID containing one or more wildcards
* @param wildcards returns the number of wildcards, may be NULL
- * @return TRUE if match is found
+ * @return match value as described above
*/
- bool (*matches) (identification_t *this, identification_t *other, int *wildcards);
+ id_match_t (*matches) (identification_t *this, identification_t *other);
/**
- * @brief Check if an ID is a wildcard ID.
+ * Check if an ID is a wildcard ID.
*
* If the ID represents multiple IDs (with wildcards, or
* as the type ID_ANY), TRUE is returned. If it is unique,
* FALSE is returned.
*
- * @param this identification_t object
* @return TRUE if ID contains wildcards
*/
bool (*contains_wildcards) (identification_t *this);
/**
- * @brief Clone a identification_t instance.
+ * Clone a identification_t instance.
*
- * @param this the identification_t object to clone
* @return clone of this
*/
identification_t *(*clone) (identification_t *this);
/**
- * @brief Destroys a identification_t object.
- *
- * @param this identification_t object
+ * Destroys a identification_t object.
*/
void (*destroy) (identification_t *this);
};
/**
- * @brief Creates an identification_t object from a string.
- *
- * @param string input string, which will be converted
- * @return
- * - created identification_t object, or
- * - NULL if unsupported string supplied.
+ * Creates an identification_t object from a string.
*
* The input string may be e.g. one of the following:
* - ID_IPV4_ADDR: 192.168.0.1
@@ -239,23 +245,29 @@ struct identification_t {
* ND, UID, DC, CN, S, SN, serialNumber, C, L, ST, O, OU, T, D,
* N, G, I, ID, EN, EmployeeNumber, E, Email, emailAddress, UN,
* unstructuredName, TCGID.
- *
- * @ingroup utils
+ *
+ * @param string input string, which will be converted
+ * @return created identification_t, NULL if not supported.
*/
identification_t * identification_create_from_string(char *string);
/**
- * @brief Creates an identification_t object from an encoded chunk.
- *
- * @param type type of this id, such as ID_IPV4_ADDR
- * @param encoded encoded bytes, such as from identification_t.get_encoding
- * @return identification_t object
+ * Creates an identification_t object from an encoded chunk.
*
* In contrast to identification_create_from_string(), this constructor never
* returns NULL, even when the conversion to a string representation fails.
- *
- * @ingroup utils
+ *
+ * @param type type of this id, such as ID_IPV4_ADDR
+ * @param encoded encoded bytes, such as from identification_t.get_encoding
+ * @return identification_t
*/
identification_t * identification_create_from_encoding(id_type_t type, chunk_t encoded);
-#endif /* IDENTIFICATION_H_ */
+/**
+ * Get the printf hook functions.
+ *
+ * @return printf hook functions
+ */
+printf_hook_functions_t identification_get_printf_hooks();
+
+#endif /* IDENTIFICATION_H_ @} */
diff --git a/src/libstrongswan/utils/iterator.h b/src/libstrongswan/utils/iterator.h
index b4ff85bfb..a1bdad1d6 100644
--- a/src/libstrongswan/utils/iterator.h
+++ b/src/libstrongswan/utils/iterator.h
@@ -1,10 +1,3 @@
-/**
- * @file iterator.h
- *
- * @brief Interface iterator_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: iterator.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup iterator iterator
+ * @{ @ingroup utils
*/
#ifndef ITERATOR_H_
@@ -29,13 +29,11 @@
typedef enum hook_result_t hook_result_t;
/**
- * @brief Return value of an iterator hook.
+ * Return value of an iterator hook.
*
* Returning HOOK_AGAIN is useful to "inject" additional elements in an
* iteration, HOOK_NEXT is the normal iterator behavior, and HOOK_SKIP may
* be used to filter elements out.
- *
- * @ingroup utils
*/
enum hook_result_t {
@@ -56,14 +54,12 @@ enum hook_result_t {
};
/**
- * @brief Iterator hook function prototype.
+ * Iterator hook function prototype.
*
* @param param user supplied parameter
* @param in the value the hook receives from the iterator
* @param out the value supplied as a result to the iterator
* @return a hook_result_t
- *
- * @ingroup utils
*/
typedef hook_result_t (iterator_hook_t)(void *param, void *in, void **out);
@@ -71,44 +67,34 @@ typedef hook_result_t (iterator_hook_t)(void *param, void *in, void **out);
typedef struct iterator_t iterator_t;
/**
- * @brief Iterator interface, allows iteration over collections.
+ * Iterator interface, allows iteration over collections.
*
* iterator_t defines an interface for iterating over collections.
* It allows searching, deleting, updating and inserting.
*
- * @b Constructors:
- * - via linked_list_t.create_iterator, or
- * - any other class which supports the iterator_t interface
- *
- * @see linked_list_t
- *
- * @ingroup utils
+ * @deprecated Use enumerator instead.
*/
struct iterator_t {
/**
- * @brief Return number of list items.
+ * Return number of list items.
*
- * @param this calling object
* @return number of list items
*/
int (*get_count) (iterator_t *this);
/**
- * @brief Iterate over all items.
+ * Iterate over all items.
*
* The easy way to iterate over items.
*
- * @param this calling object
- * @param[out] value item
- * @return
- * - TRUE, if there was an element available,
- * - FALSE otherwise
+ * @param value item
+ * @return TRUE, if there was an element available, FALSE otherwise
*/
bool (*iterate) (iterator_t *this, void** value);
/**
- * @brief Hook a function into the iterator.
+ * Hook a function into the iterator.
*
* Sometimes it is useful to hook in an iterator. The hook function is
* called before any successful return of iterate(). It takes the
@@ -119,80 +105,67 @@ struct iterator_t {
* If an iterator is hooked, only the iterate() method is valid,
* all other methods behave undefined.
*
- * @param this calling object
- * @param hook iterator hook which manipulates the iterated value
- * @param param user supplied parameter to pass back to the hook
+ * @param hook iterator hook which manipulates the iterated value
+ * @param param user supplied parameter to pass back to the hook
*/
void (*set_iterator_hook) (iterator_t *this, iterator_hook_t *hook,
void *param);
/**
- * @brief Inserts a new item before the given iterator position.
+ * Inserts a new item before the given iterator position.
*
* The iterator position is not changed after inserting
*
- * @param this calling iterator
- * @param[in] item value to insert in list
+ * @param item value to insert in list
*/
void (*insert_before) (iterator_t *this, void *item);
/**
- * @brief Inserts a new item after the given iterator position.
+ * Inserts a new item after the given iterator position.
*
* The iterator position is not changed after inserting.
*
- * @param this calling iterator
- * @param[in] item value to insert in list
+ * @param this calling iterator
+ * @param item value to insert in list
*/
void (*insert_after) (iterator_t *this, void *item);
/**
- * @brief Replace the current item at current iterator position.
+ * Replace the current item at current iterator position.
*
* The iterator position is not changed after replacing.
*
- * @param this calling iterator
- * @param[out] old_item old value will be written here(can be NULL)
- * @param[in] new_item new value
- *
- * @return
- * - SUCCESS
- * - FAILED if iterator is on an invalid position
+ * @param this calling iterator
+ * @param old old value will be written here(can be NULL)
+ * @param new new value
+ * @return SUCCESS, FAILED if iterator is on an invalid position
*/
- status_t (*replace) (iterator_t *this, void **old_item, void *new_item);
+ status_t (*replace) (iterator_t *this, void **old, void *new);
/**
- * @brief Removes an element from list at the given iterator position.
+ * Removes an element from list at the given iterator position.
*
* The iterator is set the the following position:
* - to the item before, if available
* - it gets reseted, otherwise
*
- * @param this calling object
- * @return
- * - SUCCESS
- * - FAILED if iterator is on an invalid position
+ * @return SUCCESS, FAILED if iterator is on an invalid position
*/
status_t (*remove) (iterator_t *this);
/**
- * @brief Resets the iterator position.
+ * Resets the iterator position.
*
* After reset, the iterator_t objects doesn't point to an element.
* A call to iterator_t.has_next is necessary to do any other operations
* with the resetted iterator.
- *
- * @param this calling object
*/
void (*reset) (iterator_t *this);
/**
- * @brief Destroys an iterator.
- *
- * @param this iterator to destroy
- *
+ * Destroys an iterator.
*/
void (*destroy) (iterator_t *this);
};
-#endif /*ITERATOR_H_*/
+#endif /*ITERATOR_H_ @} */
diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c
index dab18fd5c..cff5a1c81 100644
--- a/src/libstrongswan/utils/leak_detective.c
+++ b/src/libstrongswan/utils/leak_detective.c
@@ -1,11 +1,5 @@
-/**
- * @file leak_detective.c
- *
- * @brief Allocation hooks to find memory leaks.
- */
-
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -17,8 +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: leak_detective.c 4044 2008-06-06 15:05:54Z martin $
*/
+#ifdef HAVE_DLADDR
+# define _GNU_SOURCE
+# include <dlfcn.h>
+#endif /* HAVE_DLADDR */
+
#include <stddef.h>
#include <string.h>
#include <stdio.h>
@@ -33,6 +34,7 @@
#include <pthread.h>
#include <netdb.h>
#include <printf.h>
+#include <locale.h>
#ifdef HAVE_BACKTRACE
# include <execinfo.h>
#endif /* HAVE_BACKTRACE */
@@ -42,7 +44,18 @@
#include <library.h>
#include <debug.h>
-#ifdef LEAK_DETECTIVE
+typedef struct private_leak_detective_t private_leak_detective_t;
+
+/**
+ * private data of leak_detective
+ */
+struct private_leak_detective_t {
+
+ /**
+ * public functions
+ */
+ leak_detective_t public;
+};
/**
* Magic value which helps to detect memory corruption. Yummy!
@@ -50,6 +63,11 @@
#define MEMORY_HEADER_MAGIC 0x7ac0be11
/**
+ * Magic written to tail of allocation
+ */
+#define MEMORY_TAIL_MAGIC 0xcafebabe
+
+/**
* Pattern which is filled in memory before freeing it
*/
#define MEMORY_FREE_PATTERN 0xFF
@@ -66,25 +84,26 @@ static void *malloc_hook(size_t, const void *);
static void *realloc_hook(void *, size_t, const void *);
static void free_hook(void*, const void *);
+void *(*old_malloc_hook)(size_t, const void *);
+void *(*old_realloc_hook)(void *, size_t, const void *);
+void (*old_free_hook)(void*, const void *);
+
static u_int count_malloc = 0;
static u_int count_free = 0;
static u_int count_realloc = 0;
typedef struct memory_header_t memory_header_t;
+typedef struct memory_tail_t memory_tail_t;
/**
* Header which is prepended to each allocated memory block
*/
struct memory_header_t {
- /**
- * Magci byte which must(!) hold MEMORY_HEADER_MAGIC
- */
- u_int32_t magic;
/**
* Number of bytes following after the header
*/
- size_t bytes;
+ u_int bytes;
/**
* Stack frames at the time of allocation
@@ -105,7 +124,25 @@ struct memory_header_t {
* Pointer to next entry in linked list
*/
memory_header_t *next;
-};
+
+ /**
+ * magic bytes to detect bad free or heap underflow, MEMORY_HEADER_MAGIC
+ */
+ u_int32_t magic;
+
+}__attribute__((__packed__));
+
+/**
+ * tail appended to each allocated memory block
+ */
+struct memory_tail_t {
+
+ /**
+ * Magic bytes to detect heap overflow, MEMORY_TAIL_MAGIC
+ */
+ u_int32_t magic;
+
+}__attribute__((__packed__));
/**
* first mem header is just a dummy to chain
@@ -120,22 +157,11 @@ static memory_header_t first_header = {
};
/**
- * standard hooks, used to temparily remove hooking
- */
-static void *old_malloc_hook, *old_realloc_hook, *old_free_hook;
-
-/**
* are the hooks currently installed?
*/
static bool installed = FALSE;
/**
- * Mutex to exclusivly uninstall hooks, access heap list
- */
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-
-/**
* log stack frames queried by backtrace()
* TODO: Dump symbols of static functions. This could be done with
* the addr2line utility or the GNU BFD Library...
@@ -143,80 +169,140 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static void log_stack_frames(void **stack_frames, int stack_frame_count)
{
#ifdef HAVE_BACKTRACE
- char **strings;
size_t i;
+ char **strings;
+
+ strings = backtrace_symbols(stack_frames, stack_frame_count);
- strings = backtrace_symbols (stack_frames, stack_frame_count);
-
- DBG1(" dumping %d stack frame addresses", stack_frame_count);
-
+ fprintf(stderr, " dumping %d stack frame addresses:\n", stack_frame_count);
for (i = 0; i < stack_frame_count; i++)
{
- DBG1(" %s", strings[i]);
+#ifdef HAVE_DLADDR
+ Dl_info info;
+
+ if (dladdr(stack_frames[i], &info))
+ {
+ char cmd[1024];
+ FILE *output;
+ char c;
+ void *ptr = stack_frames[i];
+
+ if (strstr(info.dli_fname, ".so"))
+ {
+ ptr = (void*)(stack_frames[i] - info.dli_fbase);
+ }
+ snprintf(cmd, sizeof(cmd), "addr2line -e %s %p", info.dli_fname, ptr);
+ if (info.dli_sname)
+ {
+ fprintf(stderr, " \e[33m%s\e[0m @ %p (\e[31m%s\e[0m+0x%x) [%p]\n",
+ info.dli_fname, info.dli_fbase, info.dli_sname,
+ stack_frames[i] - info.dli_saddr, stack_frames[i]);
+ }
+ else
+ {
+ fprintf(stderr, " \e[33m%s\e[0m @ %p [%p]\n", info.dli_fname,
+ info.dli_fbase, stack_frames[i]);
+ }
+ fprintf(stderr, " -> \e[32m");
+ output = popen(cmd, "r");
+ if (output)
+ {
+ while (TRUE)
+ {
+ c = getc(output);
+ if (c == '\n' || c == EOF)
+ {
+ break;
+ }
+ fputc(c, stderr);
+ }
+ }
+ else
+ {
+#endif /* HAVE_DLADDR */
+ fprintf(stderr, " %s\n", strings[i]);
+#ifdef HAVE_DLADDR
+ }
+ fprintf(stderr, "\n\e[0m");
+ }
+#endif /* HAVE_DLADDR */
}
free (strings);
#endif /* HAVE_BACKTRACE */
}
/**
- * Whitelist, which contains address ranges in stack frames ignored when leaking.
- *
- * This is necessary, as some function use allocation hacks (static buffers)
- * and so on, which we want to suppress on leak reports.
+ * Leak report white list
*
- * The range_size is calculated using the readelf utility, e.g.:
- * readelf -s /lib/glibc.so.6
- * The values are for glibc-2.4 and may or may not be correct on other systems.
+ * List of functions using static allocation buffers or should be suppressed
+ * otherwise on leak report.
*/
-typedef struct whitelist_t whitelist_t;
-
-struct whitelist_t {
- void* range_start;
- size_t range_size;
-};
-
-#ifdef LIBCURL
-/* dummy declaration for whitelisting */
-void *Curl_getaddrinfo(void);
-#endif /* LIBCURL */
-
-whitelist_t whitelist[] = {
- {pthread_create, 2542},
- {pthread_setspecific, 217},
- {mktime, 60},
- {tzset, 123},
- {inet_ntoa, 249},
- {strerror, 180},
- {getprotobynumber, 291},
- {getservbyport, 311},
- {register_printf_function, 159},
- {syslog, 44},
- {vsyslog, 41},
- {dlopen, 109},
-# ifdef LIBCURL
- /* from /usr/lib/libcurl.so.3 */
- {Curl_getaddrinfo, 480},
-# endif /* LIBCURL */
+char *whitelist[] = {
+ /* pthread stuff */
+ "pthread_create",
+ "pthread_setspecific",
+ /* glibc functions */
+ "mktime",
+ "__gmtime_r",
+ "tzset",
+ "inet_ntoa",
+ "strerror",
+ "getprotobynumber",
+ "getservbyport",
+ "getservbyname",
+ "gethostbyname_r",
+ "gethostbyname2_r",
+ "getpwnam_r",
+ "getgrnam_r",
+ "register_printf_function",
+ "syslog",
+ "vsyslog",
+ "getaddrinfo",
+ "setlocale",
+ /* ignore dlopen, as we do not dlclose to get proper leak reports */
+ "dlopen",
+ "dlerror",
+ /* mysql functions */
+ "mysql_init_character_set",
+ "init_client_errs",
+ "my_thread_init",
+ /* fastcgi library */
+ "FCGX_Init",
+ /* libxml */
+ "xmlInitCharEncodingHandlers",
+ "xmlInitParser",
+ "xmlInitParserCtxt",
+ /* ClearSilver */
+ "nerr_init",
+ /* OpenSSL */
+ "RSA_new_method",
+ "DH_new_method",
};
/**
- * Check if this stack frame is whitelisted.
+ * check if a stack frame contains functions listed above
*/
static bool is_whitelisted(void **stack_frames, int stack_frame_count)
{
int i, j;
+#ifdef HAVE_DLADDR
for (i=0; i< stack_frame_count; i++)
{
- for (j=0; j<sizeof(whitelist)/sizeof(whitelist_t); j++)
- {
- if (stack_frames[i] >= whitelist[j].range_start &&
- stack_frames[i] <= (whitelist[j].range_start + whitelist[j].range_size))
+ Dl_info info;
+
+ if (dladdr(stack_frames[i], &info) && info.dli_sname)
+ {
+ for (j = 0; j < sizeof(whitelist)/sizeof(char*); j++)
{
- return TRUE;
+ if (streq(info.dli_sname, whitelist[j]))
+ {
+ return TRUE;
+ }
}
}
}
+#endif /* HAVE_DLADDR */
return FALSE;
}
@@ -226,14 +312,19 @@ static bool is_whitelisted(void **stack_frames, int stack_frame_count)
void report_leaks()
{
memory_header_t *hdr;
- int leaks = 0;
+ int leaks = 0, whitelisted = 0;
for (hdr = first_header.next; hdr != NULL; hdr = hdr->next)
{
- if (!is_whitelisted(hdr->stack_frames, hdr->stack_frame_count))
+ if (is_whitelisted(hdr->stack_frames, hdr->stack_frame_count))
+ {
+ whitelisted++;
+ }
+ else
{
- DBG1("Leak (%d bytes at %p):", hdr->bytes, hdr + 1);
- log_stack_frames(hdr->stack_frames, hdr->stack_frame_count);
+ fprintf(stderr, "Leak (%d bytes at %p):\n", hdr->bytes, hdr + 1);
+ /* skip the first frame, contains leak detective logic */
+ log_stack_frames(hdr->stack_frames + 1, hdr->stack_frame_count - 1);
leaks++;
}
}
@@ -241,15 +332,16 @@ void report_leaks()
switch (leaks)
{
case 0:
- DBG1("No leaks detected");
+ fprintf(stderr, "No leaks detected");
break;
case 1:
- DBG1("One leak detected");
+ fprintf(stderr, "One leak detected");
break;
default:
- DBG1("%d leaks detected", leaks);
+ fprintf(stderr, "%d leaks detected", leaks);
break;
}
+ fprintf(stderr, ", %d suppressed by whitelist\n", whitelisted);
}
/**
@@ -289,17 +381,28 @@ static void uninstall_hooks()
void *malloc_hook(size_t bytes, const void *caller)
{
memory_header_t *hdr;
+ memory_tail_t *tail;
+ pthread_t thread_id = pthread_self();
+ int oldpolicy;
+ struct sched_param oldparams, params;
+
+ pthread_getschedparam(thread_id, &oldpolicy, &oldparams);
+
+ params.__sched_priority = sched_get_priority_max(SCHED_FIFO);
+ pthread_setschedparam(thread_id, SCHED_FIFO, &params);
- pthread_mutex_lock(&mutex);
count_malloc++;
uninstall_hooks();
- hdr = malloc(bytes + sizeof(memory_header_t));
+ hdr = malloc(sizeof(memory_header_t) + bytes + sizeof(memory_tail_t));
+ tail = ((void*)hdr) + bytes + sizeof(memory_header_t);
/* set to something which causes crashes */
- memset(hdr, MEMORY_ALLOC_PATTERN, bytes + sizeof(memory_header_t));
+ memset(hdr, MEMORY_ALLOC_PATTERN,
+ sizeof(memory_header_t) + bytes + sizeof(memory_tail_t));
hdr->magic = MEMORY_HEADER_MAGIC;
hdr->bytes = bytes;
hdr->stack_frame_count = backtrace(hdr->stack_frames, STACK_FRAMES_COUNT);
+ tail->magic = MEMORY_TAIL_MAGIC;
install_hooks();
/* insert at the beginning of the list */
@@ -310,7 +413,9 @@ void *malloc_hook(size_t bytes, const void *caller)
}
hdr->previous = &first_header;
first_header.next = hdr;
- pthread_mutex_unlock(&mutex);
+
+ pthread_setschedparam(thread_id, oldpolicy, &oldparams);
+
return hdr + 1;
}
@@ -321,41 +426,53 @@ void free_hook(void *ptr, const void *caller)
{
void *stack_frames[STACK_FRAMES_COUNT];
int stack_frame_count;
- memory_header_t *hdr = ptr - sizeof(memory_header_t);
-
+ memory_header_t *hdr;
+ memory_tail_t *tail;
+ pthread_t thread_id = pthread_self();
+ int oldpolicy;
+ struct sched_param oldparams, params;
+
/* allow freeing of NULL */
if (ptr == NULL)
{
return;
}
+ hdr = ptr - sizeof(memory_header_t);
+ tail = ptr + hdr->bytes;
+
+ pthread_getschedparam(thread_id, &oldpolicy, &oldparams);
+
+ params.__sched_priority = sched_get_priority_max(SCHED_FIFO);
+ pthread_setschedparam(thread_id, SCHED_FIFO, &params);
- pthread_mutex_lock(&mutex);
count_free++;
uninstall_hooks();
- if (hdr->magic != MEMORY_HEADER_MAGIC)
+ if (hdr->magic != MEMORY_HEADER_MAGIC ||
+ tail->magic != MEMORY_TAIL_MAGIC)
{
- DBG1("freeing of invalid memory (%p, MAGIC 0x%x != 0x%x):",
- ptr, hdr->magic, MEMORY_HEADER_MAGIC);
+ fprintf(stderr, "freeing invalid memory (%p): "
+ "header magic 0x%x, tail magic 0x%x:\n",
+ ptr, hdr->magic, tail->magic);
stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT);
log_stack_frames(stack_frames, stack_frame_count);
- install_hooks();
- pthread_mutex_unlock(&mutex);
- return;
}
-
- /* remove item from list */
- if (hdr->next)
+ else
{
- hdr->next->previous = hdr->previous;
- }
- hdr->previous->next = hdr->next;
+ /* remove item from list */
+ if (hdr->next)
+ {
+ hdr->next->previous = hdr->previous;
+ }
+ hdr->previous->next = hdr->next;
+
+ /* clear MAGIC, set mem to something remarkable */
+ memset(hdr, MEMORY_FREE_PATTERN, hdr->bytes + sizeof(memory_header_t));
- /* clear MAGIC, set mem to something remarkable */
- memset(hdr, MEMORY_FREE_PATTERN, hdr->bytes + sizeof(memory_header_t));
+ free(hdr);
+ }
- free(hdr);
install_hooks();
- pthread_mutex_unlock(&mutex);
+ pthread_setschedparam(thread_id, oldpolicy, &oldparams);
}
/**
@@ -366,7 +483,11 @@ void *realloc_hook(void *old, size_t bytes, const void *caller)
memory_header_t *hdr;
void *stack_frames[STACK_FRAMES_COUNT];
int stack_frame_count;
-
+ memory_tail_t *tail;
+ pthread_t thread_id = pthread_self();
+ int oldpolicy;
+ struct sched_param oldparams, params;
+
/* allow reallocation of NULL */
if (old == NULL)
{
@@ -374,27 +495,34 @@ void *realloc_hook(void *old, size_t bytes, const void *caller)
}
hdr = old - sizeof(memory_header_t);
+ tail = old + hdr->bytes;
+
+ pthread_getschedparam(thread_id, &oldpolicy, &oldparams);
+
+ params.__sched_priority = sched_get_priority_max(SCHED_FIFO);
+ pthread_setschedparam(thread_id, SCHED_FIFO, &params);
- pthread_mutex_lock(&mutex);
count_realloc++;
uninstall_hooks();
- if (hdr->magic != MEMORY_HEADER_MAGIC)
+ if (hdr->magic != MEMORY_HEADER_MAGIC ||
+ tail->magic != MEMORY_TAIL_MAGIC)
{
- DBG1("reallocation of invalid memory (%p):", old);
+ fprintf(stderr, "reallocating invalid memory (%p): "
+ "header magic 0x%x, tail magic 0x%x:\n",
+ old, hdr->magic, tail->magic);
stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT);
log_stack_frames(stack_frames, stack_frame_count);
- install_hooks();
- pthread_mutex_unlock(&mutex);
- raise(SIGKILL);
- return NULL;
}
-
- hdr = realloc(hdr, bytes + sizeof(memory_header_t));
-
+ /* clear tail magic, allocate, set tail magic */
+ memset(&tail->magic, MEMORY_ALLOC_PATTERN, sizeof(tail->magic));
+ hdr = realloc(hdr, sizeof(memory_header_t) + bytes + sizeof(memory_tail_t));
+ tail = ((void*)hdr) + bytes + sizeof(memory_header_t);
+ tail->magic = MEMORY_TAIL_MAGIC;
+
/* update statistics */
hdr->bytes = bytes;
hdr->stack_frame_count = backtrace(hdr->stack_frames, STACK_FRAMES_COUNT);
-
+
/* update header of linked list neighbours */
if (hdr->next)
{
@@ -402,70 +530,36 @@ void *realloc_hook(void *old, size_t bytes, const void *caller)
}
hdr->previous->next = hdr;
install_hooks();
- pthread_mutex_unlock(&mutex);
+ pthread_setschedparam(thread_id, oldpolicy, &oldparams);
return hdr + 1;
}
/**
- * Setup leak detective
- */
-void __attribute__ ((constructor)) leak_detective_init()
-{
- if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
- {
- install_hooks();
- }
-}
-
-/**
- * Clean up leak detective
+ * Implementation of leak_detective_t.destroy
*/
-void __attribute__ ((destructor)) leak_detective_cleanup()
+static void destroy(private_leak_detective_t *this)
{
- if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
+ if (installed)
{
uninstall_hooks();
report_leaks();
}
+ free(this);
}
-/**
- * Log memory allocation statistics
+/*
+ * see header file
*/
-void leak_detective_status(FILE *stream)
+leak_detective_t *leak_detective_create()
{
- u_int blocks = 0;
- size_t bytes = 0;
- memory_header_t *hdr = &first_header;
+ private_leak_detective_t *this = malloc_thing(private_leak_detective_t);
- if (getenv("LEAK_DETECTIVE_DISABLE"))
- {
- return;
- }
+ this->public.destroy = (void(*)(leak_detective_t*))destroy;
- pthread_mutex_lock(&mutex);
- while ((hdr = hdr->next))
+ if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
{
- blocks++;
- bytes += hdr->bytes;
+ install_hooks();
}
- pthread_mutex_unlock(&mutex);
-
- fprintf(stream, "allocation statistics:\n");
- fprintf(stream, " call stats: malloc: %d, free: %d, realloc: %d\n",
- count_malloc, count_free, count_realloc);
- fprintf(stream, " allocated %d blocks, total size %d bytes (avg. %d bytes)\n",
- blocks, bytes, bytes/blocks);
-}
-
-#else /* !LEAK_DETECTION */
-
-/**
- * Dummy when !using LEAK_DETECTIVE
- */
-void leak_detective_status(FILE *stream)
-{
-
+ return &this->public;
}
-#endif /* LEAK_DETECTION */
diff --git a/src/libstrongswan/utils/leak_detective.h b/src/libstrongswan/utils/leak_detective.h
index d4016b06e..763814726 100644
--- a/src/libstrongswan/utils/leak_detective.h
+++ b/src/libstrongswan/utils/leak_detective.h
@@ -1,11 +1,5 @@
-/**
- * @file leak_detective.h
- *
- * @brief malloc/free hooks to detect leaks.
- */
-
/*
- * 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
@@ -19,17 +13,41 @@
* for more details.
*/
+/**
+ * @defgroup leak_detective leak_detective
+ * @{ @ingroup utils
+ */
+
#ifndef LEAK_DETECTIVE_H_
#define LEAK_DETECTIVE_H_
/**
- * Log status information about allocation
+ * Maximum depth stack frames to register
*/
-void leak_detective_status(FILE *stream);
+#define STACK_FRAMES_COUNT 20
+
+typedef struct leak_detective_t leak_detective_t;
/**
- * Max number of stack frames to include in a backtrace.
+ * Leak detective finds leaks and bad frees using malloc hooks.
+ *
+ * Currently leaks are reported to stderr on destruction.
+ *
+ * @todo Build an API for leak detective, allowing leak enumeration, statistics
+ * and dynamic whitelisting.
+ */
+struct leak_detective_t {
+
+ /**
+ * Destroy a leak_detective instance.
+ */
+ void (*destroy)(leak_detective_t *this);
+};
+
+/**
+ * Create a leak_detective instance.
*/
-#define STACK_FRAMES_COUNT 30
+leak_detective_t *leak_detective_create();
+
+#endif /* LEAK_DETECTIVE_H_ @}*/
-#endif /* LEAK_DETECTIVE_H_ */
diff --git a/src/libstrongswan/utils/lexparser.c b/src/libstrongswan/utils/lexparser.c
index 7cc89fc90..8b7b3b547 100644
--- a/src/libstrongswan/utils/lexparser.c
+++ b/src/libstrongswan/utils/lexparser.c
@@ -1,12 +1,5 @@
-/**
- * @file lexparser.c
- *
- * @brief lexical parser for text-based configuration files
- *
- */
-
/*
- * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2001-2006 Andreas Steffen
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -18,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: lexparser.c 3353 2007-11-19 12:27:08Z martin $
+ * $Id: lexparser.c 3872 2008-04-25 07:04:59Z andreas $
*/
/* memrchr is a GNU extension */
@@ -55,6 +48,14 @@ bool extract_token(chunk_t *token, const char termination, chunk_t *src)
{
u_char *eot = memchr(src->ptr, termination, src->len);
+ if (termination == ' ')
+ {
+ u_char *eot_tab = memchr(src->ptr, '\t', src->len);
+
+ /* check if a tab instead of a space terminates the token */
+ eot = ( eot_tab == NULL || (eot && eot < eot_tab) ) ? eot : eot_tab;
+ }
+
/* initialize empty token */
*token = chunk_empty;
diff --git a/src/libstrongswan/utils/lexparser.h b/src/libstrongswan/utils/lexparser.h
index 775898139..7d54ca22e 100644
--- a/src/libstrongswan/utils/lexparser.h
+++ b/src/libstrongswan/utils/lexparser.h
@@ -1,12 +1,7 @@
-/**
- * @file lexparser.h
- *
- * @brief lexical parser for text-based configuration files
- *
- */
-
/*
- * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2001-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -18,47 +13,57 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: lexparser.h 3346 2007-11-16 20:23:29Z andreas $
+ * $Id: lexparser.h 3876 2008-04-26 09:24:14Z andreas $
+ */
+
+/**
+ * @defgroup lexparser lexparser
+ * @{ @ingroup utils
*/
+#ifndef LEXPARSER_H_
+#define LEXPARSER_H_
+
#include <library.h>
/**
- * @brief Eats whitespace
+ * Eats whitespace
*/
bool eat_whitespace(chunk_t *src);
/**
- * @brief Compare null-terminated pattern with chunk
+ * Compare null-terminated pattern with chunk
*/
bool match(const char *pattern, const chunk_t *ch);
/**
- * @brief Extracts a token ending with the first occurence a given termination symbol
+ * Extracts a token ending with the first occurence a given termination symbol
*/
bool extract_token(chunk_t *token, const char termination, chunk_t *src);
/**
- * @brief Extracts a token ending with the last occurence a given termination symbol
+ * Extracts a token ending with the last occurence a given termination symbol
*/
bool extract_last_token(chunk_t *token, const char termination, chunk_t *src);
/**
- * @brief Fetches a new text line terminated by \n or \r\n
+ * Fetches a new text line terminated by \n or \r\n
*/
bool fetchline(chunk_t *src, chunk_t *line);
/**
- * @brief Extracts a value that might be single or double quoted
+ * Extracts a value that might be single or double quoted
*/
err_t extract_value(chunk_t *value, chunk_t *line);
/**
- * @brief extracts a name: value pair from a text line
+ * extracts a name: value pair from a text line
*/
err_t extract_name_value(chunk_t *name, chunk_t *value, chunk_t *line);
/**
- * @brief extracts a parameter: value from a text line
+ * extracts a parameter: value from a text line
*/
err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line);
+
+#endif /* LEXPARSER_H_ @} */
diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c
index 63e1bcfbf..80c4e6f9f 100644
--- a/src/libstrongswan/utils/linked_list.c
+++ b/src/libstrongswan/utils/linked_list.c
@@ -1,12 +1,5 @@
-/**
- * @file linked_list.c
- *
- * @brief Implementation of linked_list_t.
- *
- */
-
/*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
* Copyright (C) 2005-2006 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: linked_list.c 3841 2008-04-18 11:48:53Z tobias $
*/
#include <stdlib.h>
@@ -154,9 +149,14 @@ struct private_enumerator_t {
enumerator_t enumerator;
/**
- * next item to enumerate
+ * associated linked list
*/
- element_t *next;
+ private_linked_list_t *list;
+
+ /**
+ * current item
+ */
+ element_t *current;
};
/**
@@ -164,12 +164,23 @@ struct private_enumerator_t {
*/
static bool enumerate(private_enumerator_t *this, void **item)
{
- if (this->next == NULL)
+ if (!this->current)
{
- return FALSE;
+ if (!this->list->first)
+ {
+ return FALSE;
+ }
+ this->current = this->list->first;
}
- *item = this->next->value;
- this->next = this->next->next;
+ else
+ {
+ if (!this->current->next)
+ {
+ return FALSE;
+ }
+ this->current = this->current->next;
+ }
+ *item = this->current->value;
return TRUE;
}
@@ -182,7 +193,8 @@ static enumerator_t* create_enumerator(private_linked_list_t *this)
enumerator->enumerator.enumerate = (void*)enumerate;
enumerator->enumerator.destroy = (void*)free;
- enumerator->next = this->first;
+ enumerator->list = this;
+ enumerator->current = NULL;
return &enumerator->enumerator;
}
@@ -459,34 +471,37 @@ static void insert_first(private_linked_list_t *this, void *item)
}
/**
- * Implementation of linked_list_t.remove_first.
+ * unlink an element form the list, returns following element
*/
-static status_t remove_first(private_linked_list_t *this, void **item)
+static element_t* remove_element(private_linked_list_t *this, element_t *element)
{
- element_t *element = this->first;
-
- if (element == NULL)
+ element_t *next, *previous;
+
+ next = element->next;
+ previous = element->previous;
+ free(element);
+ if (next)
{
- return NOT_FOUND;
+ next->previous = previous;
}
- if (element->next != NULL)
+ else
{
- element->next->previous = NULL;
+ this->last = previous;
}
- this->first = element->next;
-
- if (item != NULL)
+ if (previous)
+ {
+ previous->next = next;
+ }
+ else
{
- *item = element->value;
+ this->first = next;
}
if (--this->count == 0)
{
+ this->first = NULL;
this->last = NULL;
}
-
- free(element);
-
- return SUCCESS;
+ return next;
}
/**
@@ -503,6 +518,19 @@ static status_t get_first(private_linked_list_t *this, void **item)
}
/**
+ * Implementation of linked_list_t.remove_first.
+ */
+static status_t remove_first(private_linked_list_t *this, void **item)
+{
+ if (get_first(this, item) == SUCCESS)
+ {
+ remove_element(this, this->first);
+ return SUCCESS;
+ }
+ return NOT_FOUND;
+}
+
+/**
* Implementation of linked_list_t.insert_last.
*/
static void insert_last(private_linked_list_t *this, void *item)
@@ -529,151 +557,69 @@ static void insert_last(private_linked_list_t *this, void *item)
}
/**
- * Implementation of linked_list_t.remove_last.
+ * Implementation of linked_list_t.get_last.
*/
-static status_t remove_last(private_linked_list_t *this, void **item)
+static status_t get_last(private_linked_list_t *this, void **item)
{
- element_t *element = this->last;
-
- if (element == NULL)
+ if (this->count == 0)
{
return NOT_FOUND;
}
- if (element->previous != NULL)
- {
- element->previous->next = NULL;
- }
- this->last = element->previous;
-
- if (item != NULL)
- {
- *item = element->value;
- }
- if (--this->count == 0)
- {
- this->first = NULL;
- }
-
- free(element);
-
+ *item = this->last->value;
return SUCCESS;
}
/**
- * Implementation of linked_list_t.insert_at_position.
+ * Implementation of linked_list_t.remove_last.
*/
-static status_t insert_at_position (private_linked_list_t *this,size_t position, void *item)
+static status_t remove_last(private_linked_list_t *this, void **item)
{
- element_t *current_element;
- int i;
-
- if (this->count <= position)
+ if (get_last(this, item) == SUCCESS)
{
- return INVALID_ARG;
- }
-
- current_element = this->first;
-
- for (i = 0; i < position;i++)
- {
- current_element = current_element->next;
- }
-
- if (current_element == NULL)
- {
- this->public.insert_last(&(this->public),item);
+ remove_element(this, this->last);
return SUCCESS;
}
-
- element_t *element = element_create(item);
- if (current_element->previous == NULL)
- {
- current_element->previous = element;
- element->next = current_element;
- this->first = element;
- }
- else
- {
- current_element->previous->next = element;
- element->previous = current_element->previous;
- current_element->previous = element;
- element->next = current_element;
- }
-
-
- this->count++;
- return SUCCESS;
+ return NOT_FOUND;
}
/**
- * Implementation of linked_list_t.remove_at_position.
+ * Implementation of linked_list_t.remove.
*/
-static status_t remove_at_position(private_linked_list_t *this,size_t position, void **item)
+static int remove(private_linked_list_t *this, void *item,
+ bool (*compare)(void *,void*))
{
- iterator_t *iterator;
- int i;
-
- if (this->count <= position)
- {
- return INVALID_ARG;
- }
+ element_t *current = this->first;
+ int removed = 0;
- iterator = this->public.create_iterator(&(this->public),TRUE);
- iterator->iterate(iterator, item);
- for (i = 0; i < position; i++)
+ while (current)
{
- if (!iterator->iterate(iterator, item))
+ if ((compare && compare(current->value, item)) ||
+ (!compare && current->value == item))
{
- iterator->destroy(iterator);
- return INVALID_ARG;
+ removed++;
+ current = remove_element(this, current);
}
- }
- iterator->remove(iterator);
- iterator->destroy(iterator);
-
- return SUCCESS;
-}
-
-/**
- * Implementation of linked_list_t.get_at_position.
- */
-static status_t get_at_position(private_linked_list_t *this,size_t position, void **item)
-{
- int i;
- iterator_t *iterator;
-
- if (this->count <= position)
- {
- return INVALID_ARG;
- }
-
- iterator = this->public.create_iterator(&(this->public),TRUE);
- iterator->iterate(iterator, item);
- for (i = 0; i < position; i++)
- {
- if (!iterator->iterate(iterator, item))
+ else
{
- iterator->destroy(iterator);
- return INVALID_ARG;
+ current = current->next;
}
}
- iterator->destroy(iterator);
- return SUCCESS;
+ return removed;
}
/**
- * Implementation of linked_list_t.get_last.
+ * Implementation of linked_list_t.remove_at.
*/
-static status_t get_last(private_linked_list_t *this, void **item)
+static void remove_at(private_linked_list_t *this, private_enumerator_t *enumerator)
{
- if (this->count == 0)
+ element_t *current;
+
+ if (enumerator->current)
{
- return NOT_FOUND;
+ current = enumerator->current;
+ enumerator->current = current->previous;
+ remove_element(this, current);
}
-
- *item = this->last->value;
-
- return SUCCESS;
}
/**
@@ -725,14 +671,15 @@ static status_t find_last(private_linked_list_t *this, linked_list_match_t match
/**
* Implementation of linked_list_t.invoke_offset.
*/
-static void invoke_offset(private_linked_list_t *this, size_t offset)
+static void invoke_offset(private_linked_list_t *this, size_t offset,
+ void *d1, void *d2, void *d3, void *d4, void *d5)
{
element_t *current = this->first;
while (current)
{
- void (**method)(void*) = current->value + offset;
- (*method)(current->value);
+ linked_list_invoke_t *method = current->value + offset;
+ (*method)(current->value, d1, d2, d3, d4, d5);
current = current->next;
}
}
@@ -740,13 +687,14 @@ static void invoke_offset(private_linked_list_t *this, size_t offset)
/**
* Implementation of linked_list_t.invoke_function.
*/
-static void invoke_function(private_linked_list_t *this, void(*fn)(void*))
+static void invoke_function(private_linked_list_t *this, linked_list_invoke_t fn,
+ void *d1, void *d2, void *d3, void *d4, void *d5)
{
element_t *current = this->first;
while (current)
{
- fn(current->value);
+ fn(current->value, d1, d2, d3, d4, d5);
current = current->next;
}
}
@@ -895,11 +843,10 @@ linked_list_t *linked_list_create()
this->public.insert_last = (void (*) (linked_list_t *, void *item))insert_last;
this->public.remove_first = (status_t (*) (linked_list_t *, void **item))remove_first;
this->public.remove_last = (status_t (*) (linked_list_t *, void **item))remove_last;
- this->public.insert_at_position = (status_t (*) (linked_list_t *,size_t, void *))insert_at_position;
- this->public.remove_at_position = (status_t (*) (linked_list_t *,size_t, void **))remove_at_position;
- this->public.get_at_position = (status_t (*) (linked_list_t *,size_t, void **))get_at_position;
- this->public.invoke_offset = (void (*)(linked_list_t*,size_t))invoke_offset;
- this->public.invoke_function = (void (*)(linked_list_t*,void(*)(void*)))invoke_function;
+ this->public.remove = (int(*)(linked_list_t*, void *item, bool (*compare)(void *,void*)))remove;
+ this->public.remove_at = (void(*)(linked_list_t*, enumerator_t *enumerator))remove_at;
+ this->public.invoke_offset = (void (*)(linked_list_t*,size_t,...))invoke_offset;
+ this->public.invoke_function = (void (*)(linked_list_t*,linked_list_invoke_t,...))invoke_function;
this->public.clone_offset = (linked_list_t * (*)(linked_list_t*,size_t))clone_offset;
this->public.clone_function = (linked_list_t * (*)(linked_list_t*,void*(*)(void*)))clone_function;
this->public.destroy = (void (*) (linked_list_t *))destroy;
diff --git a/src/libstrongswan/utils/linked_list.h b/src/libstrongswan/utils/linked_list.h
index ac36ef46d..310e91e3c 100644
--- a/src/libstrongswan/utils/linked_list.h
+++ b/src/libstrongswan/utils/linked_list.h
@@ -1,12 +1,5 @@
-/**
- * @file linked_list.h
- *
- * @brief Interface of linked_list_t.
- *
- */
-
/*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -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: linked_list.h 3841 2008-04-18 11:48:53Z tobias $
+ */
+
+/**
+ * @defgroup linked_list linked_list
+ * @{ @ingroup utils
*/
#ifndef LINKED_LIST_H_
@@ -42,51 +42,50 @@ typedef struct linked_list_t linked_list_t;
* @return
* - TRUE, if the item matched
* - FALSE, otherwise
- * @ingroup utils
*/
typedef bool (*linked_list_match_t)(void *item, ...);
/**
- * @brief Class implementing a double linked list.
- *
- * General purpose linked list. This list is not synchronized.
+ * Method to be invoked on elements in a linked list (used in invoke_* functions)
*
- * @b Costructors:
- * - linked_list_create()
+ * @param item current list item
+ * @param ... user supplied data (only pointers, at most 5)
+ */
+typedef void (*linked_list_invoke_t)(void *item, ...);
+
+/**
+ * Class implementing a double linked list.
*
- * @ingroup utils
+ * General purpose linked list. This list is not synchronized.
*/
struct linked_list_t {
/**
- * @brief Gets the count of items in the list.
+ * Gets the count of items in the list.
*
- * @param this calling object
* @return number of items in list
*/
int (*get_count) (linked_list_t *this);
/**
- * @brief Creates a iterator for the given list.
+ * Creates a iterator for the given list.
*
* @warning Created iterator_t object has to get destroyed by the caller.
*
* @deprecated Iterator is obsolete and will disappear, it is too
* complicated to implement. Use enumerator instead.
*
- * @param this calling object
* @param forward iterator direction (TRUE: front to end)
* @return new iterator_t object
*/
iterator_t *(*create_iterator) (linked_list_t *this, bool forward);
/**
- * @brief Creates a iterator, locking a mutex.
+ * Creates a iterator, locking a mutex.
*
* The supplied mutex is acquired immediately, and released
* when the iterator gets destroyed.
*
- * @param this calling object
* @param mutex mutex to use for exclusive access
* @return new iterator_t object
*/
@@ -94,113 +93,86 @@ struct linked_list_t {
pthread_mutex_t *mutex);
/**
- * @brief Create an enumerator over the list.
+ * Create an enumerator over the list.
*
* The enumerator is a "lightweight" iterator. It only has two methods
* and should therefore be much easier to implement.
*
- * @param this calling object
* @return enumerator over list items
*/
enumerator_t* (*create_enumerator)(linked_list_t *this);
/**
- * @brief Inserts a new item at the beginning of the list.
+ * Inserts a new item at the beginning of the list.
*
- * @param this calling object
- * @param[in] item item value to insert in list
+ * @param item item value to insert in list
*/
void (*insert_first) (linked_list_t *this, void *item);
/**
- * @brief Removes the first item in the list and returns its value.
+ * Removes the first item in the list and returns its value.
*
- * @param this calling object
- * @param[out] item returned value of first item, or NULL
- * @return
- * - SUCCESS
- * - NOT_FOUND, if list is empty
+ * @param item returned value of first item, or NULL
+ * @return SUCCESS, or NOT_FOUND if list is empty
*/
status_t (*remove_first) (linked_list_t *this, void **item);
-
- /**
- * @brief Returns the value of the first list item without removing it.
- *
- * @param this calling object
- * @param[out] item returned value of first item
- * @return
- * - SUCCESS
- * - NOT_FOUND, if list is empty
- */
- status_t (*get_first) (linked_list_t *this, void **item);
-
+
/**
- * @brief Inserts a new item at the end of the list.
- *
- * @param this calling object
- * @param[in] item value to insert into list
+ * Remove an item from the list where the enumerator points to.
+ *
+ * @param enumerator enumerator with position
*/
- void (*insert_last) (linked_list_t *this, void *item);
+ void (*remove_at)(linked_list_t *this, enumerator_t *enumerator);
/**
- * @brief Inserts a new item at a given position in the list.
+ * Remove items from the list matching item.
*
- * @param this calling object
- * @param position position starting at 0 to insert new entry
- * @param[in] item value to insert into list
- * @return
- * - SUCCESS
- * - INVALID_ARG if position not existing
+ * If a compare function is given, it is called for each item, where
+ * the first parameter is the current list item and the second parameter
+ * is the supplied item parameter.
+ * If compare is NULL, compare is is done by pointer.
+ *
+ * @param item item to remove/pass to comparator
+ * @param compare compare function, or NULL
+ * @return number of removed items
*/
- status_t (*insert_at_position) (linked_list_t *this,size_t position, void *item);
+ int (*remove)(linked_list_t *this, void *item, bool (*compare)(void *,void*));
/**
- * @brief Removes an item from a given position in the list.
+ * Returns the value of the first list item without removing it.
*
* @param this calling object
- * @param position position starting at 0 to remove entry from
- * @param[out] item removed item will be stored at this location
- * @return
- * - SUCCESS
- * - INVALID_ARG if position not existing
+ * @param item returned value of first item
+ * @return SUCCESS, NOT_FOUND if list is empty
*/
- status_t (*remove_at_position) (linked_list_t *this, size_t position, void **item);
+ status_t (*get_first) (linked_list_t *this, void **item);
/**
- * @brief Get an item from a given position in the list.
+ * Inserts a new item at the end of the list.
*
- * @param this calling object
- * @param position position starting at 0 to get entry from
- * @param[out] item item will be stored at this location
- * @return
- * - SUCCESS
- * - INVALID_ARG if position not existing
+ * @param item value to insert into list
*/
- status_t (*get_at_position) (linked_list_t *this, size_t position, void **item);
+ void (*insert_last) (linked_list_t *this, void *item);
/**
- * @brief Removes the last item in the list and returns its value.
+ * Removes the last item in the list and returns its value.
*
* @param this calling object
- * @param[out] item returned value of last item, or NULL
- * @return
- * - SUCCESS
- * - NOT_FOUND if list is empty
+ * @param item returned value of last item, or NULL
+ * @return SUCCESS, NOT_FOUND if list is empty
*/
status_t (*remove_last) (linked_list_t *this, void **item);
/**
- * @brief Returns the value of the last list item without removing it.
+ * Returns the value of the last list item without removing it.
*
* @param this calling object
- * @param[out] item returned value of last item
- * @return
- * - SUCCESS
- * - NOT_FOUND if list is empty
+ * @param item returned value of last item
+ * @return SUCCESS, NOT_FOUND if list is empty
*/
status_t (*get_last) (linked_list_t *this, void **item);
- /** @brief Find the first matching element in the list.
+ /** Find the first matching element in the list.
*
* The first object passed to the match function is the current list item,
* followed by the user supplied data.
@@ -210,19 +182,15 @@ struct linked_list_t {
*
* @warning Only use pointers as user supplied data.
*
- * @param this calling object
* @param match comparison function to call on each object
- * @param[out] item
- * - the list item, if found
- * - NULL, otherwise
+ * @param item the list item, if found
* @param ... user data to supply to match function (limited to 5 arguments)
- * @return
- * - SUCCESS, if found
- * - NOT_FOUND, otherwise
+ * @return SUCCESS if found, NOT_FOUND otherwise
*/
- status_t (*find_first) (linked_list_t *this, linked_list_match_t match, void **item, ...);
+ status_t (*find_first) (linked_list_t *this, linked_list_match_t match,
+ void **item, ...);
- /** @brief Find the last matching element in the list.
+ /** Find the last matching element in the list.
*
* The first object passed to the match function is the current list item,
* followed by the user supplied data.
@@ -232,20 +200,16 @@ struct linked_list_t {
*
* @warning Only use pointers as user supplied data.
*
- * @param this calling object
* @param match comparison function to call on each object
- * @param[out] item
- * - the list item, if found
- * - NULL, otherwise
+ * @param item the list item, if found
* @param ... user data to supply to match function (limited to 5 arguments)
- * @return
- * - SUCCESS, if found
- * - NOT_FOUND, otherwise
+ * @return SUCCESS if found, NOT_FOUND otherwise
*/
- status_t (*find_last) (linked_list_t *this, linked_list_match_t match, void **item, ...);
+ status_t (*find_last) (linked_list_t *this, linked_list_match_t match,
+ void **item, ...);
/**
- * @brief Invoke a method on all of the contained objects.
+ * Invoke a method on all of the contained objects.
*
* If a linked list contains objects with function pointers,
* invoke() can call a method on each of the objects. The
@@ -253,79 +217,70 @@ struct linked_list_t {
* which can be evalutated at compile time using the offsetof
* macro, e.g.: list->invoke(list, offsetof(object_t, method));
*
- * @param this calling object
* @param offset offset of the method to invoke on objects
+ * @param ... user data to supply to called function (limited to 5 arguments)
*/
- void (*invoke_offset) (linked_list_t *this, size_t offset);
+ void (*invoke_offset) (linked_list_t *this, size_t offset, ...);
/**
- * @brief Invoke a function on all of the contained objects.
+ * Invoke a function on all of the contained objects.
*
- * @param this calling object
- * @param offset offset of the method to invoke on objects
+ * @param function offset of the method to invoke on objects
+ * @param ... user data to supply to called function (limited to 5 arguments)
*/
- void (*invoke_function) (linked_list_t *this, void (*)(void*));
+ void (*invoke_function) (linked_list_t *this, linked_list_invoke_t function, ...);
/**
- * @brief Clones a list and its objects using the objects' clone method.
+ * Clones a list and its objects using the objects' clone method.
*
- * @param this calling object
* @param offset offset ot the objects clone function
* @return cloned list
*/
linked_list_t *(*clone_offset) (linked_list_t *this, size_t offset);
/**
- * @brief Clones a list and its objects using a given function.
+ * Clones a list and its objects using a given function.
*
- * @param this calling object
* @param function function that clones an object
* @return cloned list
*/
linked_list_t *(*clone_function) (linked_list_t *this, void*(*)(void*));
/**
- * @brief Destroys a linked_list object.
- *
- * @param this calling object
+ * Destroys a linked_list object.
*/
void (*destroy) (linked_list_t *this);
/**
- * @brief Destroys a list and its objects using the destructor.
+ * Destroys a list and its objects using the destructor.
*
* If a linked list and the contained objects should be destroyed, use
* destroy_offset. The supplied offset specifies the destructor to
* call on each object. The offset may be calculated using the offsetof
* macro, e.g.: list->destroy_offset(list, offsetof(object_t, destroy));
*
- * @param this calling object
* @param offset offset of the objects destructor
*/
void (*destroy_offset) (linked_list_t *this, size_t offset);
/**
- * @brief Destroys a list and its contents using a a cleanup function.
+ * Destroys a list and its contents using a a cleanup function.
*
* If a linked list and its contents should get destroyed using a specific
* cleanup function, use destroy_function. This is useful when the
* list contains malloc()-ed blocks which should get freed,
* e.g.: list->destroy_function(list, free);
*
- * @param this calling object
* @param function function to call on each object
*/
void (*destroy_function) (linked_list_t *this, void (*)(void*));
};
/**
- * @brief Creates an empty linked list object.
+ * Creates an empty linked list object.
*
* @return linked_list_t object.
- *
- * @ingroup utils
*/
linked_list_t *linked_list_create(void);
-
-#endif /*LINKED_LIST_H_*/
+#endif /*LINKED_LIST_H_ @} */
diff --git a/src/libstrongswan/utils/mutex.c b/src/libstrongswan/utils/mutex.c
new file mode 100644
index 000000000..425389b4f
--- /dev/null
+++ b/src/libstrongswan/utils/mutex.c
@@ -0,0 +1,267 @@
+/*
+ * 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: mutex.c 3589 2008-03-13 14:14:44Z martin $
+ */
+
+#include "mutex.h"
+
+#include <library.h>
+#include <debug.h>
+
+#include <pthread.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+
+typedef struct private_mutex_t private_mutex_t;
+typedef struct private_n_mutex_t private_n_mutex_t;
+typedef struct private_r_mutex_t private_r_mutex_t;
+typedef struct private_condvar_t private_condvar_t;
+
+/**
+ * private data of mutex
+ */
+struct private_mutex_t {
+
+ /**
+ * public functions
+ */
+ mutex_t public;
+
+ /**
+ * wrapped pthread mutex
+ */
+ pthread_mutex_t mutex;
+};
+
+/**
+ * private data of mutex, extended by recursive locking information
+ */
+struct private_r_mutex_t {
+
+ /**
+ * public functions
+ */
+ private_mutex_t generic;
+
+ /**
+ * thread which currently owns mutex
+ */
+ pthread_t thread;
+
+ /**
+ * times we have locked the lock
+ */
+ int times;
+};
+
+/**
+ * private data of condvar
+ */
+struct private_condvar_t {
+
+ /**
+ * public functions
+ */
+ condvar_t public;
+
+ /**
+ * wrapped pthread condvar
+ */
+ pthread_cond_t condvar;
+};
+
+/**
+ * Implementation of mutex_t.lock.
+ */
+static void lock(private_mutex_t *this)
+{
+ if (pthread_mutex_lock(&this->mutex))
+ {
+ DBG1("!!!! MUTEX %sLOCK ERROR, your code is buggy !!!", "");
+ }
+}
+
+/**
+ * Implementation of mutex_t.unlock.
+ */
+static void unlock(private_mutex_t *this)
+{
+ if (pthread_mutex_unlock(&this->mutex))
+ {
+ DBG1("!!!! MUTEX %sLOCK ERROR, your code is buggy !!!", "UN");
+ }
+}
+
+/**
+ * Implementation of mutex_t.lock.
+ */
+static void lock_r(private_r_mutex_t *this)
+{
+ pthread_t self = pthread_self();
+
+ if (this->thread == self)
+ {
+ this->times++;
+ return;
+ }
+ lock(&this->generic);
+ this->thread = self;
+ this->times = 1;
+}
+
+/**
+ * Implementation of mutex_t.unlock.
+ */
+static void unlock_r(private_r_mutex_t *this)
+{
+ if (--this->times == 0)
+ {
+ this->thread = 0;
+ unlock(&this->generic);
+ }
+}
+
+/**
+ * Implementation of mutex_t.destroy
+ */
+static void mutex_destroy(private_mutex_t *this)
+{
+ pthread_mutex_destroy(&this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+mutex_t *mutex_create(mutex_type_t type)
+{
+ switch (type)
+ {
+ case MUTEX_RECURSIVE:
+ {
+ private_r_mutex_t *this = malloc_thing(private_r_mutex_t);
+
+ this->generic.public.lock = (void(*)(mutex_t*))lock_r;
+ this->generic.public.unlock = (void(*)(mutex_t*))unlock_r;
+ this->generic.public.destroy = (void(*)(mutex_t*))mutex_destroy;
+
+ pthread_mutex_init(&this->generic.mutex, NULL);
+ this->thread = 0;
+ this->times = 0;
+
+ return &this->generic.public;
+ }
+ case MUTEX_DEFAULT:
+ default:
+ {
+ private_mutex_t *this = malloc_thing(private_mutex_t);
+
+ this->public.lock = (void(*)(mutex_t*))lock;
+ this->public.unlock = (void(*)(mutex_t*))unlock;
+ this->public.destroy = (void(*)(mutex_t*))mutex_destroy;
+
+ pthread_mutex_init(&this->mutex, NULL);
+
+ return &this->public;
+ }
+ }
+}
+
+/**
+ * Implementation of condvar_t.wait.
+ */
+static void wait(private_condvar_t *this, private_mutex_t *mutex)
+{
+ pthread_cond_wait(&this->condvar, &mutex->mutex);
+}
+
+/**
+ * Implementation of condvar_t.timed_wait.
+ */
+static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex,
+ u_int timeout)
+{
+ struct timespec ts;
+ struct timeval tv;
+ u_int s, ms;
+
+ gettimeofday(&tv, NULL);
+
+ s = timeout / 1000;
+ ms = timeout % 1000;
+
+ ts.tv_sec = tv.tv_sec + s;
+ ts.tv_nsec = tv.tv_usec * 1000 + ms * 1000000;
+ if (ts.tv_nsec > 1000000000 /* 1s */)
+ {
+ ts.tv_nsec -= 1000000000;
+ ts.tv_sec++;
+ }
+ return (pthread_cond_timedwait(&this->condvar, &mutex->mutex,
+ &ts) == ETIMEDOUT);
+}
+
+/**
+ * Implementation of condvar_t.signal.
+ */
+static void signal(private_condvar_t *this)
+{
+ pthread_cond_signal(&this->condvar);
+}
+
+/**
+ * Implementation of condvar_t.broadcast.
+ */
+static void broadcast(private_condvar_t *this)
+{
+ pthread_cond_broadcast(&this->condvar);
+}
+
+/**
+ * Implementation of condvar_t.destroy
+ */
+static void condvar_destroy(private_condvar_t *this)
+{
+ pthread_cond_destroy(&this->condvar);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+condvar_t *condvar_create(condvar_type_t type)
+{
+ switch (type)
+ {
+ case CONDVAR_DEFAULT:
+ default:
+ {
+ private_condvar_t *this = malloc_thing(private_condvar_t);
+
+ this->public.wait = (void(*)(condvar_t*, mutex_t *mutex))wait;
+ this->public.timed_wait = (bool(*)(condvar_t*, mutex_t *mutex, u_int timeout))timed_wait;
+ this->public.signal = (void(*)(condvar_t*))signal;
+ this->public.broadcast = (void(*)(condvar_t*))broadcast;
+ this->public.destroy = (void(*)(condvar_t*))condvar_destroy;
+
+ pthread_cond_init(&this->condvar, NULL);
+
+ return &this->public;
+ }
+ }
+}
+
diff --git a/src/libstrongswan/utils/mutex.h b/src/libstrongswan/utils/mutex.h
new file mode 100644
index 000000000..cf557c35c
--- /dev/null
+++ b/src/libstrongswan/utils/mutex.h
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup mutex mutex
+ * @{ @ingroup utils
+ */
+
+#ifndef MUTEX_H_
+#define MUTEX_H_
+
+typedef struct mutex_t mutex_t;
+typedef struct condvar_t condvar_t;
+typedef enum mutex_type_t mutex_type_t;
+typedef enum condvar_type_t condvar_type_t;
+
+#include <library.h>
+
+/**
+ * Type of mutex.
+ */
+enum mutex_type_t {
+ /** default mutex */
+ MUTEX_DEFAULT = 0,
+ /** allow recursive locking of the mutex */
+ MUTEX_RECURSIVE = 1,
+};
+
+/**
+ * Type of condvar.
+ */
+enum condvar_type_t {
+ /** default condvar */
+ CONDVAR_DEFAULT = 0,
+};
+
+/**
+ * Mutex wrapper implements simple, portable and advanced mutex functions.
+ */
+struct mutex_t {
+
+ /**
+ * Acquire the lock to the mutex.
+ */
+ void (*lock)(mutex_t *this);
+
+ /**
+ * Release the lock on the mutex.
+ */
+ void (*unlock)(mutex_t *this);
+
+ /**
+ * Destroy a mutex instance.
+ */
+ void (*destroy)(mutex_t *this);
+};
+
+/**
+ * Condvar wrapper to use in conjunction with mutex_t.
+ */
+struct condvar_t {
+
+ /**
+ * Wait on a condvar until it gets signalized.
+ *
+ * @param mutex mutex to release while waiting
+ */
+ void (*wait)(condvar_t *this, mutex_t *mutex);
+
+ /**
+ * Wait on a condvar until it gets signalized, or times out.
+ *
+ * @param mutex mutex to release while waiting
+ * @param timeout timeout im ms
+ * @return TRUE if timed out, FALSE otherwise
+ */
+ bool (*timed_wait)(condvar_t *this, mutex_t *mutex, u_int timeout);
+
+ /**
+ * Wake up a single thread in a condvar.
+ */
+ void (*signal)(condvar_t *this);
+
+ /**
+ * Wake up all threads in a condvar.
+ */
+ void (*broadcast)(condvar_t *this);
+
+ /**
+ * Destroy a condvar and free its resources.
+ */
+ void (*destroy)(condvar_t *this);
+};
+
+/**
+ * Create a mutex instance.
+ *
+ * @param type type of mutex to create
+ * @return unlocked mutex instance
+ */
+mutex_t *mutex_create(mutex_type_t type);
+
+/**
+ * Create a condvar instance.
+ *
+ * @param type type of condvar to create
+ * @return condvar instance
+ */
+condvar_t *condvar_create(condvar_type_t type);
+
+#endif /* MUTEX_H_ @}*/
diff --git a/src/libstrongswan/utils/optionsfrom.c b/src/libstrongswan/utils/optionsfrom.c
index 39e38cc58..18427e197 100644
--- a/src/libstrongswan/utils/optionsfrom.c
+++ b/src/libstrongswan/utils/optionsfrom.c
@@ -1,13 +1,5 @@
-/**
- * @file optionsfrom.c
- *
- * @brief read command line options from a file
- *
- */
-
/*
* Copyright (C) 2007-2008 Andreas Steffen
- *
* Hochschule fuer Technik Rapperswil
*
* This library is free software; you can redistribute it and/or modify it
@@ -20,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
*
- * RCSID $Id$
+ * $Id: optionsfrom.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdio.h>
diff --git a/src/libstrongswan/utils/optionsfrom.h b/src/libstrongswan/utils/optionsfrom.h
index 0014cec36..424b9dc61 100644
--- a/src/libstrongswan/utils/optionsfrom.h
+++ b/src/libstrongswan/utils/optionsfrom.h
@@ -1,10 +1,3 @@
-/**
- * @file optionsfrom.h
- *
- * @brief Read command line options from a file
- *
- */
-
/*
* Copyright (C) 2007-2008 Andreas Steffen
*
@@ -20,7 +13,12 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id$
+ * $Id: optionsfrom.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup optionsfrom optionsfrom
+ * @{ @ingroup utils
*/
#ifndef OPTIONSFROM_H_
@@ -29,41 +27,33 @@
typedef struct options_t options_t;
/**
- * @brief options object.
- *
- * @b Constructors:
- * - options_create()
- *
- * @ingroup utils
+ * Reads additional command line arguments from a file
*/
struct options_t {
+
/**
- * @brief Check if the PKCS#7 contentType is data
+ * Check if the PKCS#7 contentType is data
*
- * @param this calling object
* @param filename file containing the options
* @param argcp pointer to argc
* @param argvp pointer to argv[]
* @param optind current optind, number of next argument
* @return TRUE if optionsfrom parsing successful
*/
- bool (*from) (options_t * this, char *filename, int *argcp, char **argvp[], int optind);
+ bool (*from) (options_t * this, char *filename,
+ int *argcp, char **argvp[], int optind);
/**
- * @brief Destroys the options_t object.
- *
- * @param this options_t object to destroy
+ * Destroys the options_t object.
*/
void (*destroy) (options_t *this);
};
/**
- * @brief Create an options object.
+ * Create an options object.
*
* @return created options_t object
- *
- * @ingroup utils
*/
options_t *options_create(void);
-#endif /*OPTIONSFROM_H_*/
+#endif /*OPTIONSFROM_H_ @} */
diff --git a/src/libstrongswan/utils/randomizer.c b/src/libstrongswan/utils/randomizer.c
deleted file mode 100644
index c15d108c7..000000000
--- a/src/libstrongswan/utils/randomizer.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * @file randomizer.c
- *
- * @brief Implementation of randomizer_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 <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "randomizer.h"
-
-
-typedef struct private_randomizer_t private_randomizer_t;
-
-/**
- * Private data of an randomizer_t object.
- */
-struct private_randomizer_t {
-
- /**
- * Public randomizer_t interface.
- */
- randomizer_t public;
-
- /**
- * @brief Reads a specific number of bytes from random or pseudo random device.
- *
- * @param this calling object
- * @param pseudo_random TRUE, if from pseudo random bytes should be read,
- * FALSE for true random bytes
- * @param bytes number of bytes to read
- * @param[out] buffer pointer to buffer where to write the data in.
- * Size of buffer has to be at least bytes.
- */
- status_t (*get_bytes_from_device) (private_randomizer_t *this,bool pseudo_random, size_t bytes, u_int8_t *buffer);
-};
-
-
-/**
- * Implementation of private_randomizer_t.get_bytes_from_device.
- */
-static status_t get_bytes_from_device(private_randomizer_t *this,bool pseudo_random, size_t bytes, u_int8_t *buffer)
-{
- size_t ndone;
- int device;
- size_t got;
- char * device_name;
-
- device_name = pseudo_random ? DEV_URANDOM : DEV_RANDOM;
-
- device = open(device_name, 0);
- if (device < 0) {
- return FAILED;
- }
- ndone = 0;
-
- /* read until nbytes are read */
- while (ndone < bytes)
- {
- got = read(device, buffer + ndone, bytes - ndone);
- if (got <= 0) {
- close(device);
- return FAILED;
- }
- ndone += got;
- }
- close(device);
- return SUCCESS;
-}
-
-/**
- * Implementation of randomizer_t.get_random_bytes.
- */
-static status_t get_random_bytes(private_randomizer_t *this,size_t bytes, u_int8_t *buffer)
-{
- return this->get_bytes_from_device(this, FALSE, bytes, buffer);
-}
-
-/**
- * Implementation of randomizer_t.allocate_random_bytes.
- */
-static status_t allocate_random_bytes(private_randomizer_t *this, size_t bytes, chunk_t *chunk)
-{
- status_t status;
- chunk->len = bytes;
- chunk->ptr = malloc(bytes);
- status = this->get_bytes_from_device(this, FALSE, bytes, chunk->ptr);
- if (status != SUCCESS)
- {
- free(chunk->ptr);
- }
- return status;
-}
-
-/**
- * Implementation of randomizer_t.get_pseudo_random_bytes.
- */
-static status_t get_pseudo_random_bytes(private_randomizer_t *this,size_t bytes, u_int8_t *buffer)
-{
- return (this->get_bytes_from_device(this, TRUE, bytes, buffer));
-}
-
-/**
- * Implementation of randomizer_t.allocate_pseudo_random_bytes.
- */
-static status_t allocate_pseudo_random_bytes(private_randomizer_t *this, size_t bytes, chunk_t *chunk)
-{
- status_t status;
- chunk->len = bytes;
- chunk->ptr = malloc(bytes);
- status = this->get_bytes_from_device(this, TRUE, bytes, chunk->ptr);
- if (status != SUCCESS)
- {
- free(chunk->ptr);
- }
- return status;
-}
-
-/**
- * Implementation of randomizer_t.destroy.
- */
-static void destroy(private_randomizer_t *this)
-{
- free(this);
-}
-
-/*
- * Described in header.
- */
-randomizer_t *randomizer_create(void)
-{
- private_randomizer_t *this = malloc_thing(private_randomizer_t);
-
- /* public functions */
- this->public.get_random_bytes = (status_t (*) (randomizer_t *,size_t, u_int8_t *)) get_random_bytes;
- this->public.allocate_random_bytes = (status_t (*) (randomizer_t *,size_t, chunk_t *)) allocate_random_bytes;
- this->public.get_pseudo_random_bytes = (status_t (*) (randomizer_t *,size_t, u_int8_t *)) get_pseudo_random_bytes;
- this->public.allocate_pseudo_random_bytes = (status_t (*) (randomizer_t *,size_t, chunk_t *)) allocate_pseudo_random_bytes;
- this->public.destroy = (void (*) (randomizer_t *))destroy;
-
- /* private functions */
- this->get_bytes_from_device = get_bytes_from_device;
-
- return &(this->public);
-}
diff --git a/src/libstrongswan/utils/randomizer.h b/src/libstrongswan/utils/randomizer.h
deleted file mode 100644
index afbade059..000000000
--- a/src/libstrongswan/utils/randomizer.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * @file randomizer.h
- *
- * @brief Interface of randomizer_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.
- */
-
-#ifndef RANDOMIZER_H_
-#define RANDOMIZER_H_
-
-typedef struct randomizer_t randomizer_t;
-
-#include <library.h>
-
-#ifndef DEV_RANDOM
-/**
- * Device to read real random bytes
- */
-# define DEV_RANDOM "/dev/random"
-#endif
-
-#ifndef DEV_URANDOM
-/**
- * Device to read pseudo random bytes
- */
-# define DEV_URANDOM "/dev/urandom"
-#endif
-
-/**
- * @brief Class used to get random and pseudo random values.
- *
- * @b Constructors:
- * - randomizer_create()
- *
- * @ingroup utils
- */
-struct randomizer_t {
-
- /**
- * @brief Reads a specific number of bytes from random device.
- *
- * @param this calling randomizer_t object
- * @param bytes number of bytes to read
- * @param[out] buffer pointer to buffer where to write the data in.
- * Size of buffer has to be at least bytes.
- * @return SUCCESS, or FAILED
- */
- status_t (*get_random_bytes) (randomizer_t *this, size_t bytes, u_int8_t *buffer);
-
- /**
- * @brief Allocates space and writes in random bytes.
- *
- * @param this calling randomizer_t object
- * @param bytes number of bytes to allocate
- * @param[out] chunk chunk which will hold the allocated random bytes
- * @return SUCCESS, or FAILED
- */
- status_t (*allocate_random_bytes) (randomizer_t *this, size_t bytes, chunk_t *chunk);
-
- /**
- * @brief Reads a specific number of bytes from pseudo random device.
- *
- * @param this calling randomizer_t object
- * @param bytes number of bytes to read
- * @param[out] buffer pointer to buffer where to write the data in.
- * size of buffer has to be at least bytes.
- * @return SUCCESS, or FAILED
- */
- status_t (*get_pseudo_random_bytes) (randomizer_t *this,size_t bytes, u_int8_t *buffer);
-
- /**
- * @brief Allocates space and writes in pseudo random bytes.
- *
- * @param this calling randomizer_t object
- * @param bytes number of bytes to allocate
- * @param[out] chunk chunk which will hold the allocated random bytes
- * @return SUCCESS, or FAILED
- */
- status_t (*allocate_pseudo_random_bytes) (randomizer_t *this, size_t bytes, chunk_t *chunk);
-
- /**
- * @brief Destroys a randomizer_t object.
- *
- * @param this randomizer_t object to destroy
- */
- void (*destroy) (randomizer_t *this);
-};
-
-/**
- * @brief Creates a randomizer_t object.
- *
- * @return created randomizer_t, or
- *
- * @ingroup utils
- */
-randomizer_t *randomizer_create(void);
-
-#endif /*RANDOMIZER_H_*/
diff --git a/src/manager/Makefile.am b/src/manager/Makefile.am
index 7f77d1dba..6c50f1563 100644
--- a/src/manager/Makefile.am
+++ b/src/manager/Makefile.am
@@ -1,52 +1,46 @@
-ipsec_PROGRAMS = manager.fcgi
+managerdir = ${ipsecdir}/manager
+
+manager_PROGRAMS = manager.fcgi
manager_fcgi_SOURCES = \
-main.c manager.c manager.h gateway.h gateway.c database.h database.c \
+main.c manager.c manager.h gateway.h gateway.c storage.h storage.c xml.h xml.c \
controller/auth_controller.c controller/auth_controller.h \
controller/ikesa_controller.c controller/ikesa_controller.h \
controller/control_controller.c controller/control_controller.h \
controller/config_controller.c controller/config_controller.h \
controller/gateway_controller.c controller/gateway_controller.h
-manager_fcgi_LDADD = $(top_builddir)/src/manager/libappserv.la -lsqlite3
-
-
-
-lib_LTLIBRARIES = libappserv.la
-
-libappserv_la_SOURCES = \
-lib/context.h lib/dispatcher.c lib/request.h lib/session.h \
-lib/controller.h lib/dispatcher.h lib/request.c lib/session.c \
-lib/xml.h lib/xml.c
-
-libappserv_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lfcgi -lpthread -lneo_cgi -lneo_cs -lneo_utl ${xml_LIBS}
-
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/manager/lib -I/usr/include/ClearSilver ${xml_CFLAGS}
-AM_CFLAGS = -rdynamic -DIPSECDIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
+manager_fcgi_LDADD = $(top_builddir)/src/libfast/libfast.la ${xml_LIBS}
-ipsec_DATA = manager.db
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libfast ${xml_CFLAGS}
+AM_CFLAGS = -rdynamic \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
+ -DIPSECDIR=\"${ipsecdir}\" \
+ -DIPSEC_PIDDIR=\"${piddir}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\"\
+ -DPLUGINS=\""${libstrongswan_plugins}\""
# Don't forget to add templates to EXTRA_DIST !!! How to automate?
-ipsec_templatesdir = ${ipsecdir}/templates
-ipsec_templates_DATA = templates/header.cs templates/footer.cs templates/error.cs
+manager_templatesdir = ${managerdir}/templates
+manager_templates_DATA = templates/header.cs templates/footer.cs templates/error.cs
-ipsec_templates_authdir = ${ipsec_templatesdir}/auth
-ipsec_templates_auth_DATA = templates/auth/login.cs
+manager_templates_authdir = ${manager_templatesdir}/auth
+manager_templates_auth_DATA = templates/auth/login.cs
-ipsec_templates_gatewaydir = ${ipsec_templatesdir}/gateway
-ipsec_templates_gateway_DATA = templates/gateway/list.cs
+manager_templates_gatewaydir = ${manager_templatesdir}/gateway
+manager_templates_gateway_DATA = templates/gateway/list.cs
-ipsec_templates_ikesadir = ${ipsec_templatesdir}/ikesa
-ipsec_templates_ikesa_DATA = templates/ikesa/list.cs
+manager_templates_ikesadir = ${manager_templatesdir}/ikesa
+manager_templates_ikesa_DATA = templates/ikesa/list.cs
-ipsec_templates_controldir = ${ipsec_templatesdir}/control
-ipsec_templates_control_DATA = templates/control/result.cs
+manager_templates_controldir = ${manager_templatesdir}/control
+manager_templates_control_DATA = templates/control/result.cs
-ipsec_templates_configdir = ${ipsec_templatesdir}/config
-ipsec_templates_config_DATA = templates/config/list.cs
+manager_templates_configdir = ${manager_templatesdir}/config
+manager_templates_config_DATA = templates/config/list.cs
-ipsec_templates_staticdir = ${ipsec_templatesdir}/static
-ipsec_templates_static_DATA = templates/static/style.css templates/static/script.js templates/static/jquery.js \
+manager_templates_staticdir = ${manager_templatesdir}/static
+manager_templates_static_DATA = templates/static/style.css templates/static/script.js templates/static/jquery.js \
templates/static/pipe.png templates/static/pipe-good.png templates/static/pipe-bad.png \
templates/static/pipe-thin.png templates/static/pipe-thin-left.png templates/static/pipe-thin-right.png \
templates/static/pipe-thin-green.png templates/static/pipe-thin-left-green.png templates/static/pipe-thin-right-green.png \
@@ -54,7 +48,7 @@ templates/static/gateway-left.png templates/static/client-left.png templates/sta
templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png \
templates/static/close.png templates/static/initiate.png
-EXTRA_DIST = manager.db templates/header.cs templates/footer.cs templates/error.cs \
+EXTRA_DIST = templates/header.cs templates/footer.cs templates/error.cs \
templates/auth/login.cs templates/gateway/list.cs templates/ikesa/list.cs \
templates/config/list.cs templates/control/result.cs \
templates/static/style.css templates/static/script.js templates/static/jquery.js \
diff --git a/src/manager/Makefile.in b/src/manager/Makefile.in
index d8cb38881..c79dce4d4 100644
--- a/src/manager/Makefile.in
+++ b/src/manager/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.
@@ -15,7 +15,6 @@
@SET_MAKE@
-
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -34,7 +33,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-ipsec_PROGRAMS = manager.fcgi$(EXEEXT)
+manager_PROGRAMS = manager.fcgi$(EXEEXT)
subdir = src/manager
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -43,36 +42,25 @@ 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)$(libdir)" "$(DESTDIR)$(ipsecdir)" \
- "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(ipsec_templatesdir)" \
- "$(DESTDIR)$(ipsec_templates_authdir)" \
- "$(DESTDIR)$(ipsec_templates_configdir)" \
- "$(DESTDIR)$(ipsec_templates_controldir)" \
- "$(DESTDIR)$(ipsec_templates_gatewaydir)" \
- "$(DESTDIR)$(ipsec_templates_ikesadir)" \
- "$(DESTDIR)$(ipsec_templates_staticdir)"
-libLTLIBRARIES_INSTALL = $(INSTALL)
-LTLIBRARIES = $(lib_LTLIBRARIES)
-am__DEPENDENCIES_1 =
-libappserv_la_DEPENDENCIES = \
- $(top_builddir)/src/libstrongswan/libstrongswan.la \
- $(am__DEPENDENCIES_1)
-am_libappserv_la_OBJECTS = dispatcher.lo request.lo session.lo xml.lo
-libappserv_la_OBJECTS = $(am_libappserv_la_OBJECTS)
-ipsecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
-PROGRAMS = $(ipsec_PROGRAMS)
+am__installdirs = "$(DESTDIR)$(managerdir)" \
+ "$(DESTDIR)$(manager_templatesdir)" \
+ "$(DESTDIR)$(manager_templates_authdir)" \
+ "$(DESTDIR)$(manager_templates_configdir)" \
+ "$(DESTDIR)$(manager_templates_controldir)" \
+ "$(DESTDIR)$(manager_templates_gatewaydir)" \
+ "$(DESTDIR)$(manager_templates_ikesadir)" \
+ "$(DESTDIR)$(manager_templates_staticdir)"
+managerPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(manager_PROGRAMS)
am_manager_fcgi_OBJECTS = main.$(OBJEXT) manager.$(OBJEXT) \
- gateway.$(OBJEXT) database.$(OBJEXT) auth_controller.$(OBJEXT) \
- ikesa_controller.$(OBJEXT) control_controller.$(OBJEXT) \
- config_controller.$(OBJEXT) gateway_controller.$(OBJEXT)
+ gateway.$(OBJEXT) storage.$(OBJEXT) xml.$(OBJEXT) \
+ auth_controller.$(OBJEXT) ikesa_controller.$(OBJEXT) \
+ control_controller.$(OBJEXT) config_controller.$(OBJEXT) \
+ gateway_controller.$(OBJEXT)
manager_fcgi_OBJECTS = $(am_manager_fcgi_OBJECTS)
-manager_fcgi_DEPENDENCIES = $(top_builddir)/src/manager/libappserv.la
+am__DEPENDENCIES_1 =
+manager_fcgi_DEPENDENCIES = $(top_builddir)/src/libfast/libfast.la \
+ $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -85,21 +73,27 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libappserv_la_SOURCES) $(manager_fcgi_SOURCES)
-DIST_SOURCES = $(libappserv_la_SOURCES) $(manager_fcgi_SOURCES)
-ipsecDATA_INSTALL = $(INSTALL_DATA)
-ipsec_templatesDATA_INSTALL = $(INSTALL_DATA)
-ipsec_templates_authDATA_INSTALL = $(INSTALL_DATA)
-ipsec_templates_configDATA_INSTALL = $(INSTALL_DATA)
-ipsec_templates_controlDATA_INSTALL = $(INSTALL_DATA)
-ipsec_templates_gatewayDATA_INSTALL = $(INSTALL_DATA)
-ipsec_templates_ikesaDATA_INSTALL = $(INSTALL_DATA)
-ipsec_templates_staticDATA_INSTALL = $(INSTALL_DATA)
-DATA = $(ipsec_DATA) $(ipsec_templates_DATA) \
- $(ipsec_templates_auth_DATA) $(ipsec_templates_config_DATA) \
- $(ipsec_templates_control_DATA) \
- $(ipsec_templates_gateway_DATA) $(ipsec_templates_ikesa_DATA) \
- $(ipsec_templates_static_DATA)
+SOURCES = $(manager_fcgi_SOURCES)
+DIST_SOURCES = $(manager_fcgi_SOURCES)
+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|^.*/||'`;
+manager_templatesDATA_INSTALL = $(INSTALL_DATA)
+manager_templates_authDATA_INSTALL = $(INSTALL_DATA)
+manager_templates_configDATA_INSTALL = $(INSTALL_DATA)
+manager_templates_controlDATA_INSTALL = $(INSTALL_DATA)
+manager_templates_gatewayDATA_INSTALL = $(INSTALL_DATA)
+manager_templates_ikesaDATA_INSTALL = $(INSTALL_DATA)
+manager_templates_staticDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(manager_templates_DATA) $(manager_templates_auth_DATA) \
+ $(manager_templates_config_DATA) \
+ $(manager_templates_control_DATA) \
+ $(manager_templates_gateway_DATA) \
+ $(manager_templates_ikesa_DATA) \
+ $(manager_templates_static_DATA)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -122,6 +116,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -151,6 +146,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -181,7 +177,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@
@@ -192,12 +187,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@
@@ -207,12 +201,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@
@@ -225,51 +219,52 @@ 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@
+managerdir = ${ipsecdir}/manager
manager_fcgi_SOURCES = \
-main.c manager.c manager.h gateway.h gateway.c database.h database.c \
+main.c manager.c manager.h gateway.h gateway.c storage.h storage.c xml.h xml.c \
controller/auth_controller.c controller/auth_controller.h \
controller/ikesa_controller.c controller/ikesa_controller.h \
controller/control_controller.c controller/control_controller.h \
controller/config_controller.c controller/config_controller.h \
controller/gateway_controller.c controller/gateway_controller.h
-manager_fcgi_LDADD = $(top_builddir)/src/manager/libappserv.la -lsqlite3
-lib_LTLIBRARIES = libappserv.la
-libappserv_la_SOURCES = \
-lib/context.h lib/dispatcher.c lib/request.h lib/session.h \
-lib/controller.h lib/dispatcher.h lib/request.c lib/session.c \
-lib/xml.h lib/xml.c
+manager_fcgi_LDADD = $(top_builddir)/src/libfast/libfast.la ${xml_LIBS}
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libfast ${xml_CFLAGS}
+AM_CFLAGS = -rdynamic \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
+ -DIPSECDIR=\"${ipsecdir}\" \
+ -DIPSEC_PIDDIR=\"${piddir}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\"\
+ -DPLUGINS=\""${libstrongswan_plugins}\""
-libappserv_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lfcgi -lpthread -lneo_cgi -lneo_cs -lneo_utl ${xml_LIBS}
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/manager/lib -I/usr/include/ClearSilver ${xml_CFLAGS}
-AM_CFLAGS = -rdynamic -DIPSECDIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
-ipsec_DATA = manager.db
# Don't forget to add templates to EXTRA_DIST !!! How to automate?
-ipsec_templatesdir = ${ipsecdir}/templates
-ipsec_templates_DATA = templates/header.cs templates/footer.cs templates/error.cs
-ipsec_templates_authdir = ${ipsec_templatesdir}/auth
-ipsec_templates_auth_DATA = templates/auth/login.cs
-ipsec_templates_gatewaydir = ${ipsec_templatesdir}/gateway
-ipsec_templates_gateway_DATA = templates/gateway/list.cs
-ipsec_templates_ikesadir = ${ipsec_templatesdir}/ikesa
-ipsec_templates_ikesa_DATA = templates/ikesa/list.cs
-ipsec_templates_controldir = ${ipsec_templatesdir}/control
-ipsec_templates_control_DATA = templates/control/result.cs
-ipsec_templates_configdir = ${ipsec_templatesdir}/config
-ipsec_templates_config_DATA = templates/config/list.cs
-ipsec_templates_staticdir = ${ipsec_templatesdir}/static
-ipsec_templates_static_DATA = templates/static/style.css templates/static/script.js templates/static/jquery.js \
+manager_templatesdir = ${managerdir}/templates
+manager_templates_DATA = templates/header.cs templates/footer.cs templates/error.cs
+manager_templates_authdir = ${manager_templatesdir}/auth
+manager_templates_auth_DATA = templates/auth/login.cs
+manager_templates_gatewaydir = ${manager_templatesdir}/gateway
+manager_templates_gateway_DATA = templates/gateway/list.cs
+manager_templates_ikesadir = ${manager_templatesdir}/ikesa
+manager_templates_ikesa_DATA = templates/ikesa/list.cs
+manager_templates_controldir = ${manager_templatesdir}/control
+manager_templates_control_DATA = templates/control/result.cs
+manager_templates_configdir = ${manager_templatesdir}/config
+manager_templates_config_DATA = templates/config/list.cs
+manager_templates_staticdir = ${manager_templatesdir}/static
+manager_templates_static_DATA = templates/static/style.css templates/static/script.js templates/static/jquery.js \
templates/static/pipe.png templates/static/pipe-good.png templates/static/pipe-bad.png \
templates/static/pipe-thin.png templates/static/pipe-thin-left.png templates/static/pipe-thin-right.png \
templates/static/pipe-thin-green.png templates/static/pipe-thin-left-green.png templates/static/pipe-thin-right-green.png \
@@ -277,7 +272,7 @@ templates/static/gateway-left.png templates/static/client-left.png templates/sta
templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png \
templates/static/close.png templates/static/initiate.png
-EXTRA_DIST = manager.db templates/header.cs templates/footer.cs templates/error.cs \
+EXTRA_DIST = templates/header.cs templates/footer.cs templates/error.cs \
templates/auth/login.cs templates/gateway/list.cs templates/ikesa/list.cs \
templates/config/list.cs templates/control/result.cs \
templates/static/style.css templates/static/script.js templates/static/jquery.js \
@@ -321,59 +316,30 @@ $(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-libLTLIBRARIES: $(lib_LTLIBRARIES)
- @$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- if test -f $$p; then \
- f=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
- else :; fi; \
- done
-
-uninstall-libLTLIBRARIES:
- @$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- p=$(am__strip_dir) \
- echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
- $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
- done
-
-clean-libLTLIBRARIES:
- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_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
-libappserv.la: $(libappserv_la_OBJECTS) $(libappserv_la_DEPENDENCIES)
- $(LINK) -rpath $(libdir) $(libappserv_la_OBJECTS) $(libappserv_la_LIBADD) $(LIBS)
-install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
+install-managerPROGRAMS: $(manager_PROGRAMS)
@$(NORMAL_INSTALL)
- test -z "$(ipsecdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsecdir)"
- @list='$(ipsec_PROGRAMS)'; for p in $$list; do \
+ test -z "$(managerdir)" || $(MKDIR_P) "$(DESTDIR)$(managerdir)"
+ @list='$(manager_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) --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 $(managerPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(managerdir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(managerPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(managerdir)/$$f" || exit 1; \
else :; fi; \
done
-uninstall-ipsecPROGRAMS:
+uninstall-managerPROGRAMS:
@$(NORMAL_UNINSTALL)
- @list='$(ipsec_PROGRAMS)'; for p in $$list; do \
+ @list='$(manager_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"; \
+ echo " rm -f '$(DESTDIR)$(managerdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(managerdir)/$$f"; \
done
-clean-ipsecPROGRAMS:
- @list='$(ipsec_PROGRAMS)'; for p in $$list; do \
+clean-managerPROGRAMS:
+ @list='$(manager_PROGRAMS)'; for p in $$list; do \
f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
echo " rm -f $$p $$f"; \
rm -f $$p $$f ; \
@@ -391,16 +357,13 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_controller.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config_controller.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control_controller.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/database.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dispatcher.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gateway.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gateway_controller.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ikesa_controller.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manager.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/request.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/storage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -423,34 +386,6 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-dispatcher.lo: lib/dispatcher.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dispatcher.lo -MD -MP -MF $(DEPDIR)/dispatcher.Tpo -c -o dispatcher.lo `test -f 'lib/dispatcher.c' || echo '$(srcdir)/'`lib/dispatcher.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/dispatcher.Tpo $(DEPDIR)/dispatcher.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lib/dispatcher.c' object='dispatcher.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 dispatcher.lo `test -f 'lib/dispatcher.c' || echo '$(srcdir)/'`lib/dispatcher.c
-
-request.lo: lib/request.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT request.lo -MD -MP -MF $(DEPDIR)/request.Tpo -c -o request.lo `test -f 'lib/request.c' || echo '$(srcdir)/'`lib/request.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/request.Tpo $(DEPDIR)/request.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lib/request.c' object='request.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 request.lo `test -f 'lib/request.c' || echo '$(srcdir)/'`lib/request.c
-
-session.lo: lib/session.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT session.lo -MD -MP -MF $(DEPDIR)/session.Tpo -c -o session.lo `test -f 'lib/session.c' || echo '$(srcdir)/'`lib/session.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/session.Tpo $(DEPDIR)/session.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lib/session.c' object='session.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 session.lo `test -f 'lib/session.c' || echo '$(srcdir)/'`lib/session.c
-
-xml.lo: lib/xml.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.lo -MD -MP -MF $(DEPDIR)/xml.Tpo -c -o xml.lo `test -f 'lib/xml.c' || echo '$(srcdir)/'`lib/xml.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/xml.Tpo $(DEPDIR)/xml.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lib/xml.c' object='xml.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.lo `test -f 'lib/xml.c' || echo '$(srcdir)/'`lib/xml.c
-
auth_controller.o: controller/auth_controller.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_controller.o -MD -MP -MF $(DEPDIR)/auth_controller.Tpo -c -o auth_controller.o `test -f 'controller/auth_controller.c' || echo '$(srcdir)/'`controller/auth_controller.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_controller.Tpo $(DEPDIR)/auth_controller.Po
@@ -526,141 +461,124 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
-install-ipsecDATA: $(ipsec_DATA)
- @$(NORMAL_INSTALL)
- test -z "$(ipsecdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsecdir)"
- @list='$(ipsec_DATA)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(ipsecDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsecdir)/$$f'"; \
- $(ipsecDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsecdir)/$$f"; \
- done
-
-uninstall-ipsecDATA:
- @$(NORMAL_UNINSTALL)
- @list='$(ipsec_DATA)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(ipsecdir)/$$f'"; \
- rm -f "$(DESTDIR)$(ipsecdir)/$$f"; \
- done
-install-ipsec_templatesDATA: $(ipsec_templates_DATA)
+install-manager_templatesDATA: $(manager_templates_DATA)
@$(NORMAL_INSTALL)
- test -z "$(ipsec_templatesdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templatesdir)"
- @list='$(ipsec_templates_DATA)'; for p in $$list; do \
+ test -z "$(manager_templatesdir)" || $(MKDIR_P) "$(DESTDIR)$(manager_templatesdir)"
+ @list='$(manager_templates_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
- echo " $(ipsec_templatesDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsec_templatesdir)/$$f'"; \
- $(ipsec_templatesDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsec_templatesdir)/$$f"; \
+ echo " $(manager_templatesDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(manager_templatesdir)/$$f'"; \
+ $(manager_templatesDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(manager_templatesdir)/$$f"; \
done
-uninstall-ipsec_templatesDATA:
+uninstall-manager_templatesDATA:
@$(NORMAL_UNINSTALL)
- @list='$(ipsec_templates_DATA)'; for p in $$list; do \
+ @list='$(manager_templates_DATA)'; for p in $$list; do \
f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(ipsec_templatesdir)/$$f'"; \
- rm -f "$(DESTDIR)$(ipsec_templatesdir)/$$f"; \
+ echo " rm -f '$(DESTDIR)$(manager_templatesdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(manager_templatesdir)/$$f"; \
done
-install-ipsec_templates_authDATA: $(ipsec_templates_auth_DATA)
+install-manager_templates_authDATA: $(manager_templates_auth_DATA)
@$(NORMAL_INSTALL)
- test -z "$(ipsec_templates_authdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_authdir)"
- @list='$(ipsec_templates_auth_DATA)'; for p in $$list; do \
+ test -z "$(manager_templates_authdir)" || $(MKDIR_P) "$(DESTDIR)$(manager_templates_authdir)"
+ @list='$(manager_templates_auth_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
- echo " $(ipsec_templates_authDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsec_templates_authdir)/$$f'"; \
- $(ipsec_templates_authDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsec_templates_authdir)/$$f"; \
+ echo " $(manager_templates_authDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(manager_templates_authdir)/$$f'"; \
+ $(manager_templates_authDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(manager_templates_authdir)/$$f"; \
done
-uninstall-ipsec_templates_authDATA:
+uninstall-manager_templates_authDATA:
@$(NORMAL_UNINSTALL)
- @list='$(ipsec_templates_auth_DATA)'; for p in $$list; do \
+ @list='$(manager_templates_auth_DATA)'; for p in $$list; do \
f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(ipsec_templates_authdir)/$$f'"; \
- rm -f "$(DESTDIR)$(ipsec_templates_authdir)/$$f"; \
+ echo " rm -f '$(DESTDIR)$(manager_templates_authdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(manager_templates_authdir)/$$f"; \
done
-install-ipsec_templates_configDATA: $(ipsec_templates_config_DATA)
+install-manager_templates_configDATA: $(manager_templates_config_DATA)
@$(NORMAL_INSTALL)
- test -z "$(ipsec_templates_configdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_configdir)"
- @list='$(ipsec_templates_config_DATA)'; for p in $$list; do \
+ test -z "$(manager_templates_configdir)" || $(MKDIR_P) "$(DESTDIR)$(manager_templates_configdir)"
+ @list='$(manager_templates_config_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
- echo " $(ipsec_templates_configDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsec_templates_configdir)/$$f'"; \
- $(ipsec_templates_configDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsec_templates_configdir)/$$f"; \
+ echo " $(manager_templates_configDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(manager_templates_configdir)/$$f'"; \
+ $(manager_templates_configDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(manager_templates_configdir)/$$f"; \
done
-uninstall-ipsec_templates_configDATA:
+uninstall-manager_templates_configDATA:
@$(NORMAL_UNINSTALL)
- @list='$(ipsec_templates_config_DATA)'; for p in $$list; do \
+ @list='$(manager_templates_config_DATA)'; for p in $$list; do \
f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(ipsec_templates_configdir)/$$f'"; \
- rm -f "$(DESTDIR)$(ipsec_templates_configdir)/$$f"; \
+ echo " rm -f '$(DESTDIR)$(manager_templates_configdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(manager_templates_configdir)/$$f"; \
done
-install-ipsec_templates_controlDATA: $(ipsec_templates_control_DATA)
+install-manager_templates_controlDATA: $(manager_templates_control_DATA)
@$(NORMAL_INSTALL)
- test -z "$(ipsec_templates_controldir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_controldir)"
- @list='$(ipsec_templates_control_DATA)'; for p in $$list; do \
+ test -z "$(manager_templates_controldir)" || $(MKDIR_P) "$(DESTDIR)$(manager_templates_controldir)"
+ @list='$(manager_templates_control_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
- echo " $(ipsec_templates_controlDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsec_templates_controldir)/$$f'"; \
- $(ipsec_templates_controlDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsec_templates_controldir)/$$f"; \
+ echo " $(manager_templates_controlDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(manager_templates_controldir)/$$f'"; \
+ $(manager_templates_controlDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(manager_templates_controldir)/$$f"; \
done
-uninstall-ipsec_templates_controlDATA:
+uninstall-manager_templates_controlDATA:
@$(NORMAL_UNINSTALL)
- @list='$(ipsec_templates_control_DATA)'; for p in $$list; do \
+ @list='$(manager_templates_control_DATA)'; for p in $$list; do \
f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(ipsec_templates_controldir)/$$f'"; \
- rm -f "$(DESTDIR)$(ipsec_templates_controldir)/$$f"; \
+ echo " rm -f '$(DESTDIR)$(manager_templates_controldir)/$$f'"; \
+ rm -f "$(DESTDIR)$(manager_templates_controldir)/$$f"; \
done
-install-ipsec_templates_gatewayDATA: $(ipsec_templates_gateway_DATA)
+install-manager_templates_gatewayDATA: $(manager_templates_gateway_DATA)
@$(NORMAL_INSTALL)
- test -z "$(ipsec_templates_gatewaydir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_gatewaydir)"
- @list='$(ipsec_templates_gateway_DATA)'; for p in $$list; do \
+ test -z "$(manager_templates_gatewaydir)" || $(MKDIR_P) "$(DESTDIR)$(manager_templates_gatewaydir)"
+ @list='$(manager_templates_gateway_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
- echo " $(ipsec_templates_gatewayDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsec_templates_gatewaydir)/$$f'"; \
- $(ipsec_templates_gatewayDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsec_templates_gatewaydir)/$$f"; \
+ echo " $(manager_templates_gatewayDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(manager_templates_gatewaydir)/$$f'"; \
+ $(manager_templates_gatewayDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(manager_templates_gatewaydir)/$$f"; \
done
-uninstall-ipsec_templates_gatewayDATA:
+uninstall-manager_templates_gatewayDATA:
@$(NORMAL_UNINSTALL)
- @list='$(ipsec_templates_gateway_DATA)'; for p in $$list; do \
+ @list='$(manager_templates_gateway_DATA)'; for p in $$list; do \
f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(ipsec_templates_gatewaydir)/$$f'"; \
- rm -f "$(DESTDIR)$(ipsec_templates_gatewaydir)/$$f"; \
+ echo " rm -f '$(DESTDIR)$(manager_templates_gatewaydir)/$$f'"; \
+ rm -f "$(DESTDIR)$(manager_templates_gatewaydir)/$$f"; \
done
-install-ipsec_templates_ikesaDATA: $(ipsec_templates_ikesa_DATA)
+install-manager_templates_ikesaDATA: $(manager_templates_ikesa_DATA)
@$(NORMAL_INSTALL)
- test -z "$(ipsec_templates_ikesadir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_ikesadir)"
- @list='$(ipsec_templates_ikesa_DATA)'; for p in $$list; do \
+ test -z "$(manager_templates_ikesadir)" || $(MKDIR_P) "$(DESTDIR)$(manager_templates_ikesadir)"
+ @list='$(manager_templates_ikesa_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
- echo " $(ipsec_templates_ikesaDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsec_templates_ikesadir)/$$f'"; \
- $(ipsec_templates_ikesaDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsec_templates_ikesadir)/$$f"; \
+ echo " $(manager_templates_ikesaDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(manager_templates_ikesadir)/$$f'"; \
+ $(manager_templates_ikesaDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(manager_templates_ikesadir)/$$f"; \
done
-uninstall-ipsec_templates_ikesaDATA:
+uninstall-manager_templates_ikesaDATA:
@$(NORMAL_UNINSTALL)
- @list='$(ipsec_templates_ikesa_DATA)'; for p in $$list; do \
+ @list='$(manager_templates_ikesa_DATA)'; for p in $$list; do \
f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(ipsec_templates_ikesadir)/$$f'"; \
- rm -f "$(DESTDIR)$(ipsec_templates_ikesadir)/$$f"; \
+ echo " rm -f '$(DESTDIR)$(manager_templates_ikesadir)/$$f'"; \
+ rm -f "$(DESTDIR)$(manager_templates_ikesadir)/$$f"; \
done
-install-ipsec_templates_staticDATA: $(ipsec_templates_static_DATA)
+install-manager_templates_staticDATA: $(manager_templates_static_DATA)
@$(NORMAL_INSTALL)
- test -z "$(ipsec_templates_staticdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_staticdir)"
- @list='$(ipsec_templates_static_DATA)'; for p in $$list; do \
+ test -z "$(manager_templates_staticdir)" || $(MKDIR_P) "$(DESTDIR)$(manager_templates_staticdir)"
+ @list='$(manager_templates_static_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
- echo " $(ipsec_templates_staticDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsec_templates_staticdir)/$$f'"; \
- $(ipsec_templates_staticDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsec_templates_staticdir)/$$f"; \
+ echo " $(manager_templates_staticDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(manager_templates_staticdir)/$$f'"; \
+ $(manager_templates_staticDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(manager_templates_staticdir)/$$f"; \
done
-uninstall-ipsec_templates_staticDATA:
+uninstall-manager_templates_staticDATA:
@$(NORMAL_UNINSTALL)
- @list='$(ipsec_templates_static_DATA)'; for p in $$list; do \
+ @list='$(manager_templates_static_DATA)'; for p in $$list; do \
f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(ipsec_templates_staticdir)/$$f'"; \
- rm -f "$(DESTDIR)$(ipsec_templates_staticdir)/$$f"; \
+ echo " rm -f '$(DESTDIR)$(manager_templates_staticdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(manager_templates_staticdir)/$$f"; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
@@ -668,8 +586,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -681,8 +599,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -692,13 +610,12 @@ ctags: CTAGS
CTAGS: $(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
@@ -739,9 +656,9 @@ distdir: $(DISTFILES)
done
check-am: all-am
check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA)
+all-am: Makefile $(PROGRAMS) $(DATA)
installdirs:
- for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(ipsec_templatesdir)" "$(DESTDIR)$(ipsec_templates_authdir)" "$(DESTDIR)$(ipsec_templates_configdir)" "$(DESTDIR)$(ipsec_templates_controldir)" "$(DESTDIR)$(ipsec_templates_gatewaydir)" "$(DESTDIR)$(ipsec_templates_ikesadir)" "$(DESTDIR)$(ipsec_templates_staticdir)"; do \
+ for dir in "$(DESTDIR)$(managerdir)" "$(DESTDIR)$(manager_templatesdir)" "$(DESTDIR)$(manager_templates_authdir)" "$(DESTDIR)$(manager_templates_configdir)" "$(DESTDIR)$(manager_templates_controldir)" "$(DESTDIR)$(manager_templates_gatewaydir)" "$(DESTDIR)$(manager_templates_ikesadir)" "$(DESTDIR)$(manager_templates_staticdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -770,8 +687,8 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-ipsecPROGRAMS clean-libLTLIBRARIES \
- clean-libtool mostlyclean-am
+clean-am: clean-generic clean-libtool clean-managerPROGRAMS \
+ mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
@@ -789,17 +706,17 @@ info: info-am
info-am:
-install-data-am: install-ipsecDATA install-ipsecPROGRAMS \
- install-ipsec_templatesDATA install-ipsec_templates_authDATA \
- install-ipsec_templates_configDATA \
- install-ipsec_templates_controlDATA \
- install-ipsec_templates_gatewayDATA \
- install-ipsec_templates_ikesaDATA \
- install-ipsec_templates_staticDATA
+install-data-am: install-managerPROGRAMS install-manager_templatesDATA \
+ install-manager_templates_authDATA \
+ install-manager_templates_configDATA \
+ install-manager_templates_controlDATA \
+ install-manager_templates_gatewayDATA \
+ install-manager_templates_ikesaDATA \
+ install-manager_templates_staticDATA
install-dvi: install-dvi-am
-install-exec-am: install-libLTLIBRARIES
+install-exec-am:
install-html: install-html-am
@@ -831,44 +748,43 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-ipsecDATA uninstall-ipsecPROGRAMS \
- uninstall-ipsec_templatesDATA \
- uninstall-ipsec_templates_authDATA \
- uninstall-ipsec_templates_configDATA \
- uninstall-ipsec_templates_controlDATA \
- uninstall-ipsec_templates_gatewayDATA \
- uninstall-ipsec_templates_ikesaDATA \
- uninstall-ipsec_templates_staticDATA uninstall-libLTLIBRARIES
+uninstall-am: uninstall-managerPROGRAMS \
+ uninstall-manager_templatesDATA \
+ uninstall-manager_templates_authDATA \
+ uninstall-manager_templates_configDATA \
+ uninstall-manager_templates_controlDATA \
+ uninstall-manager_templates_gatewayDATA \
+ uninstall-manager_templates_ikesaDATA \
+ uninstall-manager_templates_staticDATA
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-ipsecPROGRAMS clean-libLTLIBRARIES clean-libtool ctags \
- distclean distclean-compile distclean-generic \
- distclean-libtool distclean-tags distdir dvi dvi-am html \
- html-am info info-am install install-am install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-ipsecDATA install-ipsecPROGRAMS \
- install-ipsec_templatesDATA install-ipsec_templates_authDATA \
- install-ipsec_templates_configDATA \
- install-ipsec_templates_controlDATA \
- install-ipsec_templates_gatewayDATA \
- install-ipsec_templates_ikesaDATA \
- install-ipsec_templates_staticDATA install-libLTLIBRARIES \
- install-man install-pdf install-pdf-am install-ps \
- install-ps-am install-strip installcheck installcheck-am \
- installdirs maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
- uninstall-am uninstall-ipsecDATA uninstall-ipsecPROGRAMS \
- uninstall-ipsec_templatesDATA \
- uninstall-ipsec_templates_authDATA \
- uninstall-ipsec_templates_configDATA \
- uninstall-ipsec_templates_controlDATA \
- uninstall-ipsec_templates_gatewayDATA \
- uninstall-ipsec_templates_ikesaDATA \
- uninstall-ipsec_templates_staticDATA uninstall-libLTLIBRARIES
+ clean-libtool clean-managerPROGRAMS 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-managerPROGRAMS install-manager_templatesDATA \
+ install-manager_templates_authDATA \
+ install-manager_templates_configDATA \
+ install-manager_templates_controlDATA \
+ install-manager_templates_gatewayDATA \
+ install-manager_templates_ikesaDATA \
+ install-manager_templates_staticDATA install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-managerPROGRAMS \
+ uninstall-manager_templatesDATA \
+ uninstall-manager_templates_authDATA \
+ uninstall-manager_templates_configDATA \
+ uninstall-manager_templates_controlDATA \
+ uninstall-manager_templates_gatewayDATA \
+ uninstall-manager_templates_ikesaDATA \
+ uninstall-manager_templates_staticDATA
# 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/manager/controller/auth_controller.c b/src/manager/controller/auth_controller.c
index e9b86941a..13031198a 100644
--- a/src/manager/controller/auth_controller.c
+++ b/src/manager/controller/auth_controller.c
@@ -1,10 +1,3 @@
-/**
- * @file auth_controller.c
- *
- * @brief Implementation of auth_controller_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: auth_controller.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "auth_controller.h"
diff --git a/src/manager/controller/auth_controller.h b/src/manager/controller/auth_controller.h
index c90546a17..b17e5745d 100644
--- a/src/manager/controller/auth_controller.h
+++ b/src/manager/controller/auth_controller.h
@@ -1,10 +1,3 @@
-/**
- * @file auth_controller.h
- *
- * @brief Interface of auth_controller_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: auth_controller.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup auth_controller auth_controller
+ * @{ @ingroup controller
*/
#ifndef AUTH_CONTROLLER_H_
@@ -29,7 +29,7 @@
typedef struct auth_controller_t auth_controller_t;
/**
- * @brief Authentication controller.
+ * Authentication controller.
*/
struct auth_controller_t {
@@ -40,8 +40,8 @@ struct auth_controller_t {
};
/**
- * @brief Create a auth_controller controller instance.
+ * Create a auth_controller controller instance.
*/
controller_t *auth_controller_create(context_t *context, void *param);
-#endif /* AUTH_CONTROLLER_H_ */
+#endif /* AUTH_CONTROLLER_H_ @} */
diff --git a/src/manager/controller/config_controller.c b/src/manager/controller/config_controller.c
index e7941ada4..1f8289c71 100644
--- a/src/manager/controller/config_controller.c
+++ b/src/manager/controller/config_controller.c
@@ -1,10 +1,3 @@
-/**
- * @file config_controller.c
- *
- * @brief Implementation of config_controller_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: config_controller.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "config_controller.h"
diff --git a/src/manager/controller/config_controller.h b/src/manager/controller/config_controller.h
index fcf5f5c49..cde4efd1a 100644
--- a/src/manager/controller/config_controller.h
+++ b/src/manager/controller/config_controller.h
@@ -1,10 +1,3 @@
-/**
- * @file config_controller.h
- *
- * @brief Interface of config_controller_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: config_controller.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup config_controller config_controller
+ * @{ @ingroup controller
*/
#ifndef CONFIG_CONTROLLER_H_
@@ -29,7 +29,7 @@
typedef struct config_controller_t config_controller_t;
/**
- * @brief Status controller.
+ * Status controller.
*/
struct config_controller_t {
@@ -40,8 +40,8 @@ struct config_controller_t {
};
/**
- * @brief Create a config_controller controller instance.
+ * Create a config_controller controller instance.
*/
controller_t *config_controller_create(context_t *context, void *param);
-#endif /* CONFIG_CONTROLLER_H_ */
+#endif /* CONFIG_CONTROLLER_H_ @} */
diff --git a/src/manager/controller/control_controller.c b/src/manager/controller/control_controller.c
index 12cb5e907..b3149797f 100644
--- a/src/manager/controller/control_controller.c
+++ b/src/manager/controller/control_controller.c
@@ -1,10 +1,3 @@
-/**
- * @file control_controller.c
- *
- * @brief Implementation of control_controller_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: control_controller.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "control_controller.h"
diff --git a/src/manager/controller/control_controller.h b/src/manager/controller/control_controller.h
index 6a55170aa..1f2fbcb31 100644
--- a/src/manager/controller/control_controller.h
+++ b/src/manager/controller/control_controller.h
@@ -1,10 +1,3 @@
-/**
- * @file control_controller.h
- *
- * @brief Interface of control_controller_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: control_controller.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup control_controller control_controller
+ * @{ @ingroup controller
*/
#ifndef CONTROL_CONTROLLER_H_
@@ -29,7 +29,7 @@
typedef struct control_controller_t control_controller_t;
/**
- * @brief Status controller.
+ * Control controller.
*/
struct control_controller_t {
@@ -40,7 +40,7 @@ struct control_controller_t {
};
/**
- * @brief Create a control_controller controller instance.
+ * Create a control_controller controller instance.
*/
controller_t *control_controller_create(context_t *context, void *param);
diff --git a/src/manager/controller/gateway_controller.c b/src/manager/controller/gateway_controller.c
index dff1cf3cf..68fdb7021 100644
--- a/src/manager/controller/gateway_controller.c
+++ b/src/manager/controller/gateway_controller.c
@@ -1,10 +1,3 @@
-/**
- * @file gateway_controller.c
- *
- * @brief Implementation of gateway_controller_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: gateway_controller.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "gateway_controller.h"
diff --git a/src/manager/controller/gateway_controller.h b/src/manager/controller/gateway_controller.h
index 5872e20e2..cf314ce54 100644
--- a/src/manager/controller/gateway_controller.h
+++ b/src/manager/controller/gateway_controller.h
@@ -1,10 +1,3 @@
-/**
- * @file gateway_controller.h
- *
- * @brief Interface of gateway_controller_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: gateway_controller.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup gateway_controller gateway_controller
+ * @{ @ingroup controller
*/
#ifndef GATEWAY_CONTROLLER_H_
@@ -29,7 +29,7 @@
typedef struct gateway_controller_t gateway_controller_t;
/**
- * @brief Status controller.
+ * Status controller.
*/
struct gateway_controller_t {
@@ -40,8 +40,8 @@ struct gateway_controller_t {
};
/**
- * @brief Create a gateway_controller controller instance.
+ * Create a gateway_controller controller instance.
*/
controller_t *gateway_controller_create(context_t *context, void *param);
-#endif /* GATEWAY_CONTROLLER_H_ */
+#endif /* GATEWAY_CONTROLLER_H_ @} */
diff --git a/src/manager/controller/ikesa_controller.c b/src/manager/controller/ikesa_controller.c
index 2b282b79c..ab3a089f0 100644
--- a/src/manager/controller/ikesa_controller.c
+++ b/src/manager/controller/ikesa_controller.c
@@ -1,10 +1,3 @@
-/**
- * @file ikesa_controller.c
- *
- * @brief Implementation of ikesa_controller_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: ikesa_controller.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "ikesa_controller.h"
diff --git a/src/manager/controller/ikesa_controller.h b/src/manager/controller/ikesa_controller.h
index 753cccad1..1ff9d1749 100644
--- a/src/manager/controller/ikesa_controller.h
+++ b/src/manager/controller/ikesa_controller.h
@@ -1,10 +1,3 @@
-/**
- * @file ikesa_controller.h
- *
- * @brief Interface of ikesa_controller_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: ikesa_controller.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup ikesa_controller ikesa_controller
+ * @{ @ingroup controller
*/
#ifndef IKESA_CONTROLLER_H_
@@ -29,7 +29,7 @@
typedef struct ikesa_controller_t ikesa_controller_t;
/**
- * @brief Status controller.
+ * Status controller.
*/
struct ikesa_controller_t {
@@ -40,8 +40,8 @@ struct ikesa_controller_t {
};
/**
- * @brief Create a ikesa_controller controller instance.
+ * Create a ikesa_controller controller instance.
*/
controller_t *ikesa_controller_create(context_t *context, void *param);
-#endif /* IKESA_CONTROLLER_H_ */
+#endif /* IKESA_CONTROLLER_H_ @} */
diff --git a/src/manager/database.c b/src/manager/database.c
deleted file mode 100644
index a7776c81e..000000000
--- a/src/manager/database.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/**
- * @file database.c
- *
- * @brief Implementation of database_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.
- */
-
-#include "database.h"
-
-#include <sqlite3.h>
-#include <library.h>
-#include <crypto/hashers/hasher.h>
-
-
-typedef struct private_database_t private_database_t;
-
-/**
- * private data of database
- */
-struct private_database_t {
-
- /**
- * public functions
- */
- database_t public;
-
- /**
- * SQLite database handle
- */
- sqlite3 *db;
-};
-
-/**
- * database enumerator implements enumerator_t
- */
-typedef struct {
- enumerator_t enumerator;
- sqlite3_stmt *stmt;
-} db_enumerator_t;
-
-/**
- * destroy a database enumerator
- */
-static void db_enumerator_destroy(db_enumerator_t* this)
-{
- sqlite3_finalize(this->stmt);
- free(this);
-}
-
-/**
- * create a database enumerator
- */
-static enumerator_t *db_enumerator_create(bool(*enumerate)(db_enumerator_t*,void*,...),
- sqlite3_stmt *stmt)
-{
- db_enumerator_t *this = malloc_thing(db_enumerator_t);
- this->enumerator.enumerate = (void*)enumerate;
- this->enumerator.destroy = (void*)db_enumerator_destroy;
- this->stmt = stmt;
- return &this->enumerator;
-}
-
-/**
- * Implementation of database_t.login.
- */
-static int login(private_database_t *this, char *username, char *password)
-{
- sqlite3_stmt *stmt;
- hasher_t *hasher;
- chunk_t hash, data;
- size_t username_len, password_len;
- int uid = 0;
- char *str;
-
- /* hash = SHA1( username | password ) */
- hasher = hasher_create(HASH_SHA1);
- hash = chunk_alloca(hasher->get_hash_size(hasher));
- username_len = strlen(username);
- password_len = strlen(password);
- data = chunk_alloca(username_len + password_len);
- memcpy(data.ptr, username, username_len);
- memcpy(data.ptr + username_len, password, password_len);
- hasher->get_hash(hasher, data, hash.ptr);
- hasher->destroy(hasher);
- str = chunk_to_hex(hash, FALSE);
-
- if (sqlite3_prepare_v2(this->db,
- "SELECT oid FROM users WHERE username = ? AND password = ?;",
- -1, &stmt, NULL) == SQLITE_OK)
- {
- if (sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC) == SQLITE_OK &&
- sqlite3_bind_text(stmt, 2, str, -1, SQLITE_STATIC) == SQLITE_OK &&
- sqlite3_step(stmt) == SQLITE_ROW)
- {
- uid = sqlite3_column_int(stmt, 0);
- }
- sqlite3_finalize(stmt);
- }
- free(str);
- return uid;
-}
-
-/**
- * enumerate function for gateway enumrator
- */
-static bool gateway_enumerate(db_enumerator_t* e, int *id, const char **name,
- int *port, const char **address)
-{
- if (sqlite3_step(e->stmt) == SQLITE_ROW)
- {
- *id = sqlite3_column_int(e->stmt, 0);
- *name = sqlite3_column_text(e->stmt, 1);
- *port = sqlite3_column_int(e->stmt, 2);
- *address = sqlite3_column_text(e->stmt, 3);
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * Implementation of database_t.create_gateway_enumerator.
- */
-static enumerator_t* create_gateway_enumerator(private_database_t *this, int user)
-{
- sqlite3_stmt *stmt;
-
- if (sqlite3_prepare_v2(this->db,
- "SELECT gateways.oid AS gid, name, port, address FROM "
- "gateways, user_gateway AS ug ON gid = ug.gateway WHERE ug.user = ?;",
- -1, &stmt, NULL) == SQLITE_OK)
- {
- if (sqlite3_bind_int(stmt, 1, user) == SQLITE_OK)
- {
- return db_enumerator_create((void*)gateway_enumerate, stmt);
- }
- sqlite3_finalize(stmt);
- }
- return enumerator_create_empty();
-}
-
-/**
- * Implementation of database_t.destroy
- */
-static void destroy(private_database_t *this)
-{
- sqlite3_close(this->db);
- free(this);
-}
-
-/*
- * see header file
- */
-database_t *database_create(char *dbfile)
-{
- private_database_t *this = malloc_thing(private_database_t);
-
- this->public.login = (int(*)(database_t*, char *username, char *password))login;
- this->public.create_gateway_enumerator = (enumerator_t*(*)(database_t*,int))create_gateway_enumerator;
- this->public.destroy = (void(*)(database_t*))destroy;
-
- if (sqlite3_open(dbfile, &this->db) != SQLITE_OK)
- {
- destroy(this);
- return NULL;
- }
- return &this->public;
-}
-
diff --git a/src/manager/gateway.c b/src/manager/gateway.c
index d4eb5279e..e6c944873 100644
--- a/src/manager/gateway.c
+++ b/src/manager/gateway.c
@@ -1,10 +1,3 @@
-/**
- * @file gateway.c
- *
- * @brief Implementation of gateway_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: gateway.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "gateway.h"
@@ -29,7 +24,7 @@
#include <sys/socket.h>
#include <sys/un.h>
-#include <lib/xml.h>
+#include <xml.h>
typedef struct private_gateway_t private_gateway_t;
diff --git a/src/manager/gateway.h b/src/manager/gateway.h
index 81d8b9c3f..17df9763a 100644
--- a/src/manager/gateway.h
+++ b/src/manager/gateway.h
@@ -1,10 +1,3 @@
-/**
- * @file gateway.h
- *
- * @brief Interface of gateway_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: gateway.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup gateway gateway
+ * @{ @ingroup manager
*/
#ifndef GATEWAY_H_
@@ -29,12 +29,12 @@
typedef struct gateway_t gateway_t;
/**
- * @brief A connection to a gateway.
+ * A connection to a gateway.
*/
struct gateway_t {
/**
- * @brief Send an XML request to the gateway.
+ * Send an XML request to the gateway.
*
* @param xml xml request string
* @return allocated xml response string
@@ -42,21 +42,21 @@ struct gateway_t {
char* (*request)(gateway_t *this, char *xml);
/**
- * @brief Query the list of IKE_SAs and all its children.
+ * Query the list of IKE_SAs and all its children.
*
* @return enumerator over ikesa XML elements
*/
enumerator_t* (*query_ikesalist)(gateway_t *this);
/**
- * @brief Query the list of peer configs and its subconfigs.
+ * Query the list of peer configs and its subconfigs.
*
* @return enumerator over peerconfig XML elements
*/
enumerator_t* (*query_configlist)(gateway_t *this);
/**
- * @brief Terminate an IKE or a CHILD SA.
+ * Terminate an IKE or a CHILD SA.
*
* @param ike TRUE for IKE-, FALSE for a CHILD-SA
* @param id ID of the SA to terminate
@@ -65,7 +65,7 @@ struct gateway_t {
enumerator_t* (*terminate)(gateway_t *this, bool ike, u_int32_t id);
/**
- * @brief Initiate an IKE or a CHILD SA.
+ * Initiate an IKE or a CHILD SA.
*
* @param ike TRUE for IKE-, FALSE for CHILD-SA
* @param name name of the peer/child config
@@ -74,13 +74,13 @@ struct gateway_t {
enumerator_t* (*initiate)(gateway_t *this, bool ike, char *name);
/**
- * @brief Destroy a gateway instance.
+ * Destroy a gateway instance.
*/
void (*destroy)(gateway_t *this);
};
/**
- * @brief Create a gateway instance using a TCP connection.
+ * Create a gateway instance using a TCP connection.
*
* @param name name of the gateway
* @param host gateway connection endpoint
@@ -89,11 +89,11 @@ struct gateway_t {
gateway_t *gateway_create_tcp(char *name, host_t *host);
/**
- * @brief Create a gateway instance using a UNIX socket.
+ * Create a gateway instance using a UNIX socket.
*
* @param name name of the gateway
* @param
*/
gateway_t *gateway_create_unix(char *name);
-#endif /* GATEWAY_H_ */
+#endif /* GATEWAY_H_ @} */
diff --git a/src/manager/lib/dispatcher.h b/src/manager/lib/dispatcher.h
deleted file mode 100644
index 274837838..000000000
--- a/src/manager/lib/dispatcher.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file dispatcher.h
- *
- * @brief Interface of dispatcher_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 DISPATCHER_H_
-#define DISPATCHER_H_
-
-#include "controller.h"
-
-typedef struct dispatcher_t dispatcher_t;
-
-/**
- * @brief Dispatcher, accepts connections using multiple threads.
- *
- * The dispatcher creates a session for each client (using SID cookies). In
- * each session, a session context is created using the context constructor.
- * Each controller is instanciated in the session using the controller
- * constructor added with add_controller.
- */
-struct dispatcher_t {
-
- /**
- * @brief Register a controller to the dispatcher.
- *
- * The first controller added serves as default controller. Client's
- * get redirected to it if no other controller matches.
- *
- * @param constructor constructor function to the conntroller
- * @param param param to pass to constructor
- */
- void (*add_controller)(dispatcher_t *this,
- controller_constructor_t constructor, void *param);
-
- /**
- * @brief Start with dispatching.
- *
- * It may be necessary to call per-thread initialization functions.
- * If init is not NULL, the handler is called right after thread
- * creation (by the created thread) and the deinit function is called
- * before the thread gets destroyed (again by the thread itself).
- *
- * @param thread number of dispatching threads
- * @param init thread specific initialization function, or NULL
- * @param init_param param to pass to init function
- * @param deinit thread dpecific deinitialization function, or NULL
- * @param deinit_param param to pass to deinit function
- */
- void (*run)(dispatcher_t *this, int threads,
- void(*init)(void *param), void *init_param,
- void(*deinit)(void *param), void *deinit_param);
-
- /**
- * @brief Wait for a relevant signal action.
- */
- void (*waitsignal)(dispatcher_t *this);
-
- /**
- * @brief Destroy the dispatcher_t.
- */
- void (*destroy) (dispatcher_t *this);
-};
-
-/**
- * @brief Create a dispatcher.
- *
- * The context constructor is invoked to create a session context for
- * each session.
- *
- * @param socket FastCGI socket path, NULL for dynamic
- * @param timeout session timeout
- * @param constructor construction function for session context
- * @param param parameter to supply to context constructor
- */
-dispatcher_t *dispatcher_create(char *socket, int timeout,
- context_constructor_t constructor, void *param);
-
-#endif /* DISPATCHER_H_ */
diff --git a/src/manager/main.c b/src/manager/main.c
index eb4654ced..59d534e30 100644
--- a/src/manager/main.c
+++ b/src/manager/main.c
@@ -1,10 +1,3 @@
-/**
- * @file main.c
- *
- * @brief Implementation of dispatcher_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,54 +11,68 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: main.c 3967 2008-05-16 08:52:32Z martin $
*/
#include <dispatcher.h>
+#include <debug.h>
#include <stdio.h>
#include "manager.h"
-#include "database.h"
+#include "storage.h"
#include "controller/auth_controller.h"
#include "controller/ikesa_controller.h"
#include "controller/gateway_controller.h"
#include "controller/control_controller.h"
#include "controller/config_controller.h"
-#define DBFILE IPSECDIR "/manager.db"
-#define SESSION_TIMEOUT 900
-#define THREADS 10
-
int main (int arc, char *argv[])
{
dispatcher_t *dispatcher;
- database_t *database;
- char *socket = NULL;
+ storage_t *storage;
+ char *socket;
+ char *database;
+ bool debug;
+ int threads, timeout;
+
+ library_init(STRONGSWAN_CONF);
+ lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
+ lib->settings->get_str(lib->settings, "manager.load", PLUGINS));
-#ifdef FCGI_SOCKET
- socket = FCGI_SOCKET;
-#endif /* FCGI_SOCKET */
+ socket = lib->settings->get_str(lib->settings, "manager.socket", NULL);
+ debug = lib->settings->get_bool(lib->settings, "manager.debug", FALSE);
+ timeout = lib->settings->get_int(lib->settings, "manager.timeout", 900);
+ threads = lib->settings->get_int(lib->settings, "manager.threads", 10);
+ database = lib->settings->get_str(lib->settings, "manager.database", NULL);
+ if (!database)
+ {
+ DBG1("database URI undefined, set manager.database in strongswan.conf");
+ return 1;
+ }
- database = database_create(DBFILE);
- if (database == NULL)
+ storage = storage_create(database);
+ if (storage == NULL)
{
- fprintf(stderr, "opening database '%s' failed.\n", DBFILE);
return 1;
}
- dispatcher = dispatcher_create(socket, SESSION_TIMEOUT,
- (context_constructor_t)manager_create, database);
+ dispatcher = dispatcher_create(socket, debug, timeout,
+ (context_constructor_t)manager_create, storage);
dispatcher->add_controller(dispatcher, ikesa_controller_create, NULL);
dispatcher->add_controller(dispatcher, gateway_controller_create, NULL);
dispatcher->add_controller(dispatcher, auth_controller_create, NULL);
dispatcher->add_controller(dispatcher, control_controller_create, NULL);
dispatcher->add_controller(dispatcher, config_controller_create, NULL);
- dispatcher->run(dispatcher, THREADS, NULL, NULL, NULL, NULL);
+ dispatcher->run(dispatcher, threads);
dispatcher->waitsignal(dispatcher);
dispatcher->destroy(dispatcher);
- database->destroy(database);
+ storage->destroy(storage);
+
+ library_deinit();
return 0;
}
diff --git a/src/manager/manager.c b/src/manager/manager.c
index 39c8d995a..7d1b2adba 100644
--- a/src/manager/manager.c
+++ b/src/manager/manager.c
@@ -1,10 +1,3 @@
-/**
- * @file manager.c
- *
- * @brief Implementation of manager_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: manager.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "manager.h"
@@ -39,9 +34,9 @@ struct private_manager_t {
manager_t public;
/**
- * underlying database
+ * underlying storage database
*/
- database_t *db;
+ storage_t *store;
/**
* user id, if we are logged in
@@ -59,7 +54,7 @@ struct private_manager_t {
*/
static enumerator_t* create_gateway_enumerator(private_manager_t *this)
{
- return this->db->create_gateway_enumerator(this->db, this->user);
+ return this->store->create_gateway_enumerator(this->store, this->user);
}
/**
@@ -77,7 +72,7 @@ static gateway_t* select_gateway(private_manager_t *this, int select_id)
if (this->gateway) this->gateway->destroy(this->gateway);
this->gateway = NULL;
- enumerator = this->db->create_gateway_enumerator(this->db, this->user);
+ enumerator = this->store->create_gateway_enumerator(this->store, this->user);
while (enumerator->enumerate(enumerator, &id, &name, &port, &address))
{
if (select_id == id)
@@ -117,7 +112,7 @@ static bool login(private_manager_t *this, char *username, char *password)
{
if (!this->user)
{
- this->user = this->db->login(this->db, username, password);
+ this->user = this->store->login(this->store, username, password);
}
return this->user != 0;
}
@@ -147,7 +142,7 @@ static void destroy(private_manager_t *this)
/*
* see header file
*/
-manager_t *manager_create(database_t *database)
+manager_t *manager_create(storage_t *storage)
{
private_manager_t *this = malloc_thing(private_manager_t);
@@ -159,7 +154,7 @@ manager_t *manager_create(database_t *database)
this->public.context.destroy = (void(*)(context_t*))destroy;
this->user = 0;
- this->db = database;
+ this->store = storage;
this->gateway = NULL;
return &this->public;
diff --git a/src/manager/manager.db b/src/manager/manager.db
deleted file mode 100644
index 23b6ed2e0..000000000
--- a/src/manager/manager.db
+++ /dev/null
Binary files differ
diff --git a/src/manager/manager.h b/src/manager/manager.h
index 4235618cd..669e413ac 100644
--- a/src/manager/manager.h
+++ b/src/manager/manager.h
@@ -1,10 +1,3 @@
-/**
- * @file manager.h
- *
- * @brief Interface of manager_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,12 +11,24 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
+ *
+ * $Id: manager.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup manager manager
+ *
+ * @defgroup controller controller
+ * @ingroup manager
+ *
+ * @defgroup manager_i manager
+ * @{ @ingroup manager
*/
#ifndef MANAGER_H_
#define MANAGER_H_
-#include "database.h"
+#include "storage.h"
#include "gateway.h"
#include <context.h>
@@ -33,7 +38,7 @@
typedef struct manager_t manager_t;
/**
- * @brief The manager, manages multiple gateways.
+ * The manager, manages multiple gateways.
*/
struct manager_t {
@@ -43,7 +48,7 @@ struct manager_t {
context_t context;
/**
- * @brief Create an iterator over all configured gateways.
+ * Create an iterator over all configured gateways.
*
* enumerate() arguments: int id, char *name, int port, char *address
* If port is 0, address is a Unix socket address.
@@ -53,7 +58,7 @@ struct manager_t {
enumerator_t* (*create_gateway_enumerator)(manager_t *this);
/**
- * @brief Select a gateway.
+ * Select a gateway.
*
* If id is 0, the previously selected gateway is returned. If none has
* been selected yet, NULL is returned.
@@ -64,7 +69,7 @@ struct manager_t {
gateway_t* (*select_gateway)(manager_t *this, int id);
/**
- * @brief Try to log in.
+ * Try to log in.
*
* @param username username
* @param password cleartext password
@@ -73,21 +78,21 @@ struct manager_t {
bool (*login)(manager_t *this, char *username, char *password);
/**
- * @brief Check if user logged in.
+ * Check if user logged in.
*
* @return TRUE if logged in
*/
bool (*logged_in)(manager_t *this);
/**
- * @brief Log out.
+ * Log out.
*/
void (*logout)(manager_t *this);
};
/**
- * @brief Create a manager instance.
+ * Create a manager instance.
*/
-manager_t *manager_create(database_t *database);
+manager_t *manager_create(storage_t *storage);
-#endif /* MANAGER_H_ */
+#endif /* MANAGER_H_ @} */
diff --git a/src/manager/storage.c b/src/manager/storage.c
new file mode 100644
index 000000000..fee4c216e
--- /dev/null
+++ b/src/manager/storage.c
@@ -0,0 +1,129 @@
+/*
+ * 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: storage.c 3917 2008-05-08 13:12:43Z martin $
+ */
+
+#include "storage.h"
+
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
+
+typedef struct private_storage_t private_storage_t;
+
+/**
+ * private data of storage
+ */
+struct private_storage_t {
+
+ /**
+ * public functions
+ */
+ storage_t public;
+
+ /**
+ * database connection
+ */
+ database_t *db;
+};
+
+/**
+ * Implementation of storage_t.login.
+ */
+static int login(private_storage_t *this, char *username, char *password)
+{
+ hasher_t *hasher;
+ chunk_t hash, data, hex_str;
+ size_t username_len, password_len;
+ int uid = 0;
+ enumerator_t *enumerator;
+
+ /* hash = SHA1( username | password ) */
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher == NULL)
+ {
+ return 0;
+ }
+ hash = chunk_alloca(hasher->get_hash_size(hasher));
+ username_len = strlen(username);
+ password_len = strlen(password);
+ data = chunk_alloca(username_len + password_len);
+ memcpy(data.ptr, username, username_len);
+ memcpy(data.ptr + username_len, password, password_len);
+ hasher->get_hash(hasher, data, hash.ptr);
+ hasher->destroy(hasher);
+ hex_str = chunk_to_hex(hash, NULL, FALSE);
+
+ enumerator = this->db->query(this->db,
+ "SELECT oid FROM users WHERE username = ? AND password = ?;",
+ DB_TEXT, username, DB_TEXT, hex_str.ptr,
+ DB_INT);
+ if (enumerator)
+ {
+ enumerator->enumerate(enumerator, &uid);
+ enumerator->destroy(enumerator);
+ }
+ free(hex_str.ptr);
+ return uid;
+}
+
+/**
+ * Implementation of storage_t.create_gateway_enumerator.
+ */
+static enumerator_t* create_gateway_enumerator(private_storage_t *this, int user)
+{
+ enumerator_t *enumerator;
+
+ enumerator = this->db->query(this->db,
+ "SELECT gateways.oid AS gid, name, port, address FROM "
+ "gateways, user_gateway AS ug ON gid = ug.gateway WHERE ug.user = ?;",
+ DB_INT, user,
+ DB_INT, DB_TEXT, DB_INT, DB_TEXT);
+ if (!enumerator)
+ {
+ enumerator = enumerator_create_empty();
+ }
+ return enumerator;
+}
+
+/**
+ * Implementation of storage_t.destroy
+ */
+static void destroy(private_storage_t *this)
+{
+ this->db->destroy(this->db);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+storage_t *storage_create(char *uri)
+{
+ private_storage_t *this = malloc_thing(private_storage_t);
+
+ this->public.login = (int(*)(storage_t*, char *username, char *password))login;
+ this->public.create_gateway_enumerator = (enumerator_t*(*)(storage_t*,int))create_gateway_enumerator;
+ this->public.destroy = (void(*)(storage_t*))destroy;
+
+ this->db = lib->db->create(lib->db, uri);
+ if (this->db == NULL)
+ {
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
diff --git a/src/manager/database.h b/src/manager/storage.h
index 228d1cb22..f732eca72 100644
--- a/src/manager/database.h
+++ b/src/manager/storage.h
@@ -1,10 +1,3 @@
-/**
- * @file database.h
- *
- * @brief Interface of database_t.
- *
- */
-
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,32 +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: storage.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup storage storage
+ * @{ @ingroup manager
*/
-#ifndef DATABASE_H_
-#define DATABASE_H_
+#ifndef STORAGE_H_
+#define STORAGE_H_
#include <utils/enumerator.h>
-typedef struct database_t database_t;
+typedef struct storage_t storage_t;
/**
- * @brief Persistent database.
+ * Persistent database storage.
*/
-struct database_t {
+struct storage_t {
/**
- * @brief Try to log in using specified credentials.
+ * Try to log in using specified credentials.
*
* @param username username
* @param password plaintext password
* @return user ID if login good, 0 otherwise
*/
- int (*login)(database_t *this, char *username, char *password);
+ int (*login)(storage_t *this, char *username, char *password);
/**
- * @brief Create an iterator over the gateways.
+ * Create an iterator over the gateways.
*
* enumerate() arguments: int id, char *name, int port, char *address
* If port is 0, address is a Unix socket address.
@@ -51,19 +51,19 @@ struct database_t {
* @param user user Id
* @return enumerator
*/
- enumerator_t* (*create_gateway_enumerator)(database_t *this, int user);
+ enumerator_t* (*create_gateway_enumerator)(storage_t *this, int user);
/**
- * @brief Destroy a database instance.
+ * Destroy a storage instance.
*/
- void (*destroy)(database_t *this);
+ void (*destroy)(storage_t *this);
};
/**
- * @brief Create a database instance.
+ * Create a storage instance.
*
- * @param dbfile SQLite database file
+ * @param uri database connection URI
*/
-database_t *database_create(char *dbfile);
+storage_t *storage_create(char *uri);
-#endif /* DATABASE_H_ */
+#endif /* STORAGE_H_ @} */
diff --git a/src/manager/templates/header.cs b/src/manager/templates/header.cs
index bacd833e0..ee46dbb3c 100644
--- a/src/manager/templates/header.cs
+++ b/src/manager/templates/header.cs
@@ -4,8 +4,8 @@
<head>
<title><?cs var:title ?> - strongSwan Manager</title>
<link rel="stylesheet" type="text/css" href="<?cs var:base ?>/static/style.css" />
- <script type="text/javascript" src="<?cs var:base ?>/static/jquery.js" />
- <script type="text/javascript" src="<?cs var:base ?>/static/script.js" />
+ <script type="text/javascript" src="<?cs var:base ?>/static/jquery.js"></script>
+ <script type="text/javascript" src="<?cs var:base ?>/static/script.js"></script>
</head>
<body>
<div class="fleft">
@@ -18,7 +18,7 @@
<div class="menu">
| <a href="<?cs var:base ?>/ikesa/list">IKE SAs</a>
| <a href="<?cs var:base ?>/config/list">Config</a>
- | <a href="<?cs var:base ?>/gateway/list">Select Gateway</a>
+ | <a href="<?cs var:base ?>/gateway/list">Gateway</a>
| <a href="<?cs var:base ?>/auth/logout">Logout</a>
</div>
<hr class="cleft"/>
diff --git a/src/manager/lib/xml.c b/src/manager/xml.c
index 008235b69..1e9731cc2 100644
--- a/src/manager/lib/xml.c
+++ b/src/manager/xml.c
@@ -1,10 +1,3 @@
-/**
- * @file xml.c
- *
- * @brief Implementation of xml_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: xml.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "xml.h"
diff --git a/src/manager/lib/xml.h b/src/manager/xml.h
index 738a8e1b3..73964307d 100644
--- a/src/manager/lib/xml.h
+++ b/src/manager/xml.h
@@ -1,10 +1,3 @@
-/**
- * @file xml.h
- *
- * @brief Interface of xml_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: xml.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup xml xml
+ * @{ @ingroup manager
*/
#ifndef XML_H_
@@ -28,7 +28,7 @@
typedef struct xml_t xml_t;
/**
- * @brief Simple enumerator based XML parser.
+ * Simple enumerator based XML parser.
*
* An xml_t is a single node of the XML tree, but also serves as root node
* and therefore the document.
@@ -38,7 +38,7 @@ typedef struct xml_t xml_t;
struct xml_t {
/**
- * @brief Create an enumerator over all children.
+ * Create an enumerator over all children.
*
* Enumerated values must not be manipulated or freed.
*
@@ -47,7 +47,7 @@ struct xml_t {
enumerator_t* (*children)(xml_t *this);
/**
- * @brief Get an attribute value by its name.
+ * Get an attribute value by its name.
*
* @param name name of the attribute
* @return attribute value, NULL if not found
@@ -56,8 +56,8 @@ struct xml_t {
};
/**
- * @brief Create a xml instance.
+ * Create a xml instance.
*/
xml_t *xml_create(char *xml);
-#endif /* XML_H_ */
+#endif /* XML_H_ @} */
diff --git a/src/medsrv/Makefile.am b/src/medsrv/Makefile.am
new file mode 100644
index 000000000..8da1cfcc4
--- /dev/null
+++ b/src/medsrv/Makefile.am
@@ -0,0 +1,42 @@
+medsrvdir = ${ipsecdir}/medsrv
+
+medsrv_PROGRAMS = medsrv.fcgi
+
+medsrv_fcgi_SOURCES = user.h user.c \
+main.c filter/auth_filter.c filter/auth_filter.h \
+controller/user_controller.c controller/user_controller.h \
+controller/peer_controller.c controller/peer_controller.h
+
+medsrv_fcgi_LDADD = $(top_builddir)/src/libfast/libfast.la
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libfast
+AM_CFLAGS = -rdynamic \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
+ -DIPSECDIR=\"${ipsecdir}\" \
+ -DIPSEC_PIDDIR=\"${piddir}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\"\
+ -DPLUGINS=\""${libstrongswan_plugins}\""
+
+# Don't forget to add templates to EXTRA_DIST !!! How to automate?
+medsrv_templatesdir = ${medsrvdir}/templates
+medsrv_templates_DATA = templates/header.cs templates/footer.cs
+
+medsrv_templates_userdir = ${medsrv_templatesdir}/user
+medsrv_templates_user_DATA = templates/user/add.cs templates/user/edit.cs \
+templates/user/login.cs templates/user/help.cs
+
+medsrv_templates_peerdir = ${medsrv_templatesdir}/peer
+medsrv_templates_peer_DATA = templates/peer/add.cs templates/peer/edit.cs \
+templates/peer/list.cs
+
+medsrv_templates_staticdir = ${medsrv_templatesdir}/static
+medsrv_templates_static_DATA = templates/header.cs templates/footer.cs \
+templates/static/style.css templates/static/strongswan.png \
+templates/static/favicon.ico templates/static/mootools.js templates/static/script.js
+
+EXTRA_DIST = templates/header.cs templates/footer.cs \
+templates/static/style.css templates/static/strongswan.png \
+templates/static/favicon.ico templates/static/mootools.js templates/static/script.js \
+templates/peer/add.cs templates/peer/edit.cs templates/peer/list.cs \
+templates/user/login.cs templates/user/add.cs templates/user/edit.cs \
+templates/user/help.cs
diff --git a/src/medsrv/Makefile.in b/src/medsrv/Makefile.in
new file mode 100644
index 000000000..4c2ced763
--- /dev/null
+++ b/src/medsrv/Makefile.in
@@ -0,0 +1,667 @@
+# 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@
+medsrv_PROGRAMS = medsrv.fcgi$(EXEEXT)
+subdir = src/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__installdirs = "$(DESTDIR)$(medsrvdir)" \
+ "$(DESTDIR)$(medsrv_templatesdir)" \
+ "$(DESTDIR)$(medsrv_templates_peerdir)" \
+ "$(DESTDIR)$(medsrv_templates_staticdir)" \
+ "$(DESTDIR)$(medsrv_templates_userdir)"
+medsrvPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(medsrv_PROGRAMS)
+am_medsrv_fcgi_OBJECTS = user.$(OBJEXT) main.$(OBJEXT) \
+ auth_filter.$(OBJEXT) user_controller.$(OBJEXT) \
+ peer_controller.$(OBJEXT)
+medsrv_fcgi_OBJECTS = $(am_medsrv_fcgi_OBJECTS)
+medsrv_fcgi_DEPENDENCIES = $(top_builddir)/src/libfast/libfast.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 = $(medsrv_fcgi_SOURCES)
+DIST_SOURCES = $(medsrv_fcgi_SOURCES)
+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|^.*/||'`;
+medsrv_templatesDATA_INSTALL = $(INSTALL_DATA)
+medsrv_templates_peerDATA_INSTALL = $(INSTALL_DATA)
+medsrv_templates_staticDATA_INSTALL = $(INSTALL_DATA)
+medsrv_templates_userDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(medsrv_templates_DATA) $(medsrv_templates_peer_DATA) \
+ $(medsrv_templates_static_DATA) $(medsrv_templates_user_DATA)
+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@
+medsrvdir = ${ipsecdir}/medsrv
+medsrv_fcgi_SOURCES = user.h user.c \
+main.c filter/auth_filter.c filter/auth_filter.h \
+controller/user_controller.c controller/user_controller.h \
+controller/peer_controller.c controller/peer_controller.h
+
+medsrv_fcgi_LDADD = $(top_builddir)/src/libfast/libfast.la
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libfast
+AM_CFLAGS = -rdynamic \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
+ -DIPSECDIR=\"${ipsecdir}\" \
+ -DIPSEC_PIDDIR=\"${piddir}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\"\
+ -DPLUGINS=\""${libstrongswan_plugins}\""
+
+
+# Don't forget to add templates to EXTRA_DIST !!! How to automate?
+medsrv_templatesdir = ${medsrvdir}/templates
+medsrv_templates_DATA = templates/header.cs templates/footer.cs
+medsrv_templates_userdir = ${medsrv_templatesdir}/user
+medsrv_templates_user_DATA = templates/user/add.cs templates/user/edit.cs \
+templates/user/login.cs templates/user/help.cs
+
+medsrv_templates_peerdir = ${medsrv_templatesdir}/peer
+medsrv_templates_peer_DATA = templates/peer/add.cs templates/peer/edit.cs \
+templates/peer/list.cs
+
+medsrv_templates_staticdir = ${medsrv_templatesdir}/static
+medsrv_templates_static_DATA = templates/header.cs templates/footer.cs \
+templates/static/style.css templates/static/strongswan.png \
+templates/static/favicon.ico templates/static/mootools.js templates/static/script.js
+
+EXTRA_DIST = templates/header.cs templates/footer.cs \
+templates/static/style.css templates/static/strongswan.png \
+templates/static/favicon.ico templates/static/mootools.js templates/static/script.js \
+templates/peer/add.cs templates/peer/edit.cs templates/peer/list.cs \
+templates/user/login.cs templates/user/add.cs templates/user/edit.cs \
+templates/user/help.cs
+
+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/medsrv/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/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-medsrvPROGRAMS: $(medsrv_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(medsrvdir)" || $(MKDIR_P) "$(DESTDIR)$(medsrvdir)"
+ @list='$(medsrv_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 $(medsrvPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(medsrvdir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(medsrvPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(medsrvdir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-medsrvPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(medsrv_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(medsrvdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(medsrvdir)/$$f"; \
+ done
+
+clean-medsrvPROGRAMS:
+ @list='$(medsrv_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+medsrv.fcgi$(EXEEXT): $(medsrv_fcgi_OBJECTS) $(medsrv_fcgi_DEPENDENCIES)
+ @rm -f medsrv.fcgi$(EXEEXT)
+ $(LINK) $(medsrv_fcgi_OBJECTS) $(medsrv_fcgi_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_filter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peer_controller.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/user.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/user_controller.Po@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 $@ $<
+
+auth_filter.o: filter/auth_filter.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_filter.o -MD -MP -MF $(DEPDIR)/auth_filter.Tpo -c -o auth_filter.o `test -f 'filter/auth_filter.c' || echo '$(srcdir)/'`filter/auth_filter.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_filter.Tpo $(DEPDIR)/auth_filter.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='filter/auth_filter.c' object='auth_filter.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_filter.o `test -f 'filter/auth_filter.c' || echo '$(srcdir)/'`filter/auth_filter.c
+
+auth_filter.obj: filter/auth_filter.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_filter.obj -MD -MP -MF $(DEPDIR)/auth_filter.Tpo -c -o auth_filter.obj `if test -f 'filter/auth_filter.c'; then $(CYGPATH_W) 'filter/auth_filter.c'; else $(CYGPATH_W) '$(srcdir)/filter/auth_filter.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_filter.Tpo $(DEPDIR)/auth_filter.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='filter/auth_filter.c' object='auth_filter.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_filter.obj `if test -f 'filter/auth_filter.c'; then $(CYGPATH_W) 'filter/auth_filter.c'; else $(CYGPATH_W) '$(srcdir)/filter/auth_filter.c'; fi`
+
+user_controller.o: controller/user_controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT user_controller.o -MD -MP -MF $(DEPDIR)/user_controller.Tpo -c -o user_controller.o `test -f 'controller/user_controller.c' || echo '$(srcdir)/'`controller/user_controller.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/user_controller.Tpo $(DEPDIR)/user_controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/user_controller.c' object='user_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 user_controller.o `test -f 'controller/user_controller.c' || echo '$(srcdir)/'`controller/user_controller.c
+
+user_controller.obj: controller/user_controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT user_controller.obj -MD -MP -MF $(DEPDIR)/user_controller.Tpo -c -o user_controller.obj `if test -f 'controller/user_controller.c'; then $(CYGPATH_W) 'controller/user_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/user_controller.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/user_controller.Tpo $(DEPDIR)/user_controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/user_controller.c' object='user_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 user_controller.obj `if test -f 'controller/user_controller.c'; then $(CYGPATH_W) 'controller/user_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/user_controller.c'; fi`
+
+peer_controller.o: controller/peer_controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT peer_controller.o -MD -MP -MF $(DEPDIR)/peer_controller.Tpo -c -o peer_controller.o `test -f 'controller/peer_controller.c' || echo '$(srcdir)/'`controller/peer_controller.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/peer_controller.Tpo $(DEPDIR)/peer_controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/peer_controller.c' object='peer_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 peer_controller.o `test -f 'controller/peer_controller.c' || echo '$(srcdir)/'`controller/peer_controller.c
+
+peer_controller.obj: controller/peer_controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT peer_controller.obj -MD -MP -MF $(DEPDIR)/peer_controller.Tpo -c -o peer_controller.obj `if test -f 'controller/peer_controller.c'; then $(CYGPATH_W) 'controller/peer_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/peer_controller.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/peer_controller.Tpo $(DEPDIR)/peer_controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/peer_controller.c' object='peer_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 peer_controller.obj `if test -f 'controller/peer_controller.c'; then $(CYGPATH_W) 'controller/peer_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/peer_controller.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-medsrv_templatesDATA: $(medsrv_templates_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(medsrv_templatesdir)" || $(MKDIR_P) "$(DESTDIR)$(medsrv_templatesdir)"
+ @list='$(medsrv_templates_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(medsrv_templatesDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(medsrv_templatesdir)/$$f'"; \
+ $(medsrv_templatesDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(medsrv_templatesdir)/$$f"; \
+ done
+
+uninstall-medsrv_templatesDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(medsrv_templates_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(medsrv_templatesdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(medsrv_templatesdir)/$$f"; \
+ done
+install-medsrv_templates_peerDATA: $(medsrv_templates_peer_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(medsrv_templates_peerdir)" || $(MKDIR_P) "$(DESTDIR)$(medsrv_templates_peerdir)"
+ @list='$(medsrv_templates_peer_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(medsrv_templates_peerDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(medsrv_templates_peerdir)/$$f'"; \
+ $(medsrv_templates_peerDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(medsrv_templates_peerdir)/$$f"; \
+ done
+
+uninstall-medsrv_templates_peerDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(medsrv_templates_peer_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(medsrv_templates_peerdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(medsrv_templates_peerdir)/$$f"; \
+ done
+install-medsrv_templates_staticDATA: $(medsrv_templates_static_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(medsrv_templates_staticdir)" || $(MKDIR_P) "$(DESTDIR)$(medsrv_templates_staticdir)"
+ @list='$(medsrv_templates_static_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(medsrv_templates_staticDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(medsrv_templates_staticdir)/$$f'"; \
+ $(medsrv_templates_staticDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(medsrv_templates_staticdir)/$$f"; \
+ done
+
+uninstall-medsrv_templates_staticDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(medsrv_templates_static_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(medsrv_templates_staticdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(medsrv_templates_staticdir)/$$f"; \
+ done
+install-medsrv_templates_userDATA: $(medsrv_templates_user_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(medsrv_templates_userdir)" || $(MKDIR_P) "$(DESTDIR)$(medsrv_templates_userdir)"
+ @list='$(medsrv_templates_user_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(medsrv_templates_userDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(medsrv_templates_userdir)/$$f'"; \
+ $(medsrv_templates_userDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(medsrv_templates_userdir)/$$f"; \
+ done
+
+uninstall-medsrv_templates_userDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(medsrv_templates_user_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(medsrv_templates_userdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(medsrv_templates_userdir)/$$f"; \
+ 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; 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 $(PROGRAMS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(medsrvdir)" "$(DESTDIR)$(medsrv_templatesdir)" "$(DESTDIR)$(medsrv_templates_peerdir)" "$(DESTDIR)$(medsrv_templates_staticdir)" "$(DESTDIR)$(medsrv_templates_userdir)"; 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-medsrvPROGRAMS \
+ 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-medsrvPROGRAMS install-medsrv_templatesDATA \
+ install-medsrv_templates_peerDATA \
+ install-medsrv_templates_staticDATA \
+ install-medsrv_templates_userDATA
+
+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-medsrvPROGRAMS uninstall-medsrv_templatesDATA \
+ uninstall-medsrv_templates_peerDATA \
+ uninstall-medsrv_templates_staticDATA \
+ uninstall-medsrv_templates_userDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-medsrvPROGRAMS 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-medsrvPROGRAMS install-medsrv_templatesDATA \
+ install-medsrv_templates_peerDATA \
+ install-medsrv_templates_staticDATA \
+ install-medsrv_templates_userDATA install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-medsrvPROGRAMS \
+ uninstall-medsrv_templatesDATA \
+ uninstall-medsrv_templates_peerDATA \
+ uninstall-medsrv_templates_staticDATA \
+ uninstall-medsrv_templates_userDATA
+
+# 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/medsrv/controller/peer_controller.c b/src/medsrv/controller/peer_controller.c
new file mode 100755
index 000000000..22fc6df2f
--- /dev/null
+++ b/src/medsrv/controller/peer_controller.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+
+#include "peer_controller.h"
+
+#include <library.h>
+#include <debug.h>
+#include <asn1/asn1.h>
+#include <asn1/oid.h>
+
+typedef struct private_peer_controller_t private_peer_controller_t;
+
+/**
+ * private data of the peer_controller
+ */
+struct private_peer_controller_t {
+
+ /**
+ * public functions
+ */
+ peer_controller_t public;
+
+ /**
+ * active user session
+ */
+ user_t *user;
+
+ /**
+ * underlying database
+ */
+ database_t *db;
+};
+
+/**
+ * list the configured peer configs
+ */
+static void list(private_peer_controller_t *this, request_t *request)
+{
+ enumerator_t *query;
+
+ query = this->db->query(this->db,
+ "SELECT id, alias, keyid FROM peer WHERE user = ? ORDER BY alias",
+ DB_UINT, this->user->get_user(this->user),
+ DB_UINT, DB_TEXT, DB_BLOB);
+
+ if (query)
+ {
+ u_int id;
+ char *alias;
+ chunk_t keyid;
+ identification_t *identifier;
+
+ while (query->enumerate(query, &id, &alias, &keyid))
+ {
+ request->setf(request, "peers.%d.alias=%s", id, alias);
+ identifier = identification_create_from_encoding(ID_KEY_ID, keyid);
+ request->setf(request, "peers.%d.identifier=%D", id, identifier);
+ identifier->destroy(identifier);
+ }
+ query->destroy(query);
+ }
+ request->render(request, "templates/peer/list.cs");
+}
+
+/**
+ * verify a peer alias
+ */
+static bool verify_alias(private_peer_controller_t *this, request_t *request,
+ char *alias)
+{
+ if (!alias || *alias == '\0')
+ {
+ request->setf(request, "error=Alias is missing.");
+ return FALSE;
+ }
+ while (*alias != '\0')
+ {
+ switch (*alias)
+ {
+ case 'a' ... 'z':
+ case 'A' ... 'Z':
+ case '0' ... '9':
+ case '-':
+ case '_':
+ case '@':
+ case '.':
+ alias++;
+ continue;
+ default:
+ request->setf(request, "error=Alias invalid, "
+ "valid characters: A-Z a-z 0-9 - _ @ .");
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * parse and verify a public key
+ */
+static bool parse_public_key(private_peer_controller_t *this,
+ request_t *request, char *public_key,
+ chunk_t *encoding, chunk_t *keyid)
+{
+ public_key_t *public;
+ identification_t *id;
+
+ if (!public_key || *public_key == '\0')
+ {
+ request->setf(request, "error=Public key is missing.");
+ return FALSE;
+ }
+ public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+ BUILD_BLOB_ASN1_PEM, public_key,
+ BUILD_END);
+ if (!public)
+ {
+ request->setf(request, "error=Parsing public key failed.");
+ return FALSE;
+ }
+ /* TODO: use get_encoding() with an encoding type */
+ *encoding = asn1_wrap(ASN1_SEQUENCE, "cm",
+ asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
+ asn1_bitstring("m", public->get_encoding(public)));
+ id = public->get_id(public, ID_PUBKEY_SHA1);
+ *keyid = chunk_clone(id->get_encoding(id));
+ public->destroy(public);
+ return TRUE;
+}
+
+/**
+ * register a new peer
+ */
+static void add(private_peer_controller_t *this, request_t *request)
+{
+ char *alias = "", *public_key = "";
+
+ if (request->get_query_data(request, "back"))
+ {
+ return request->redirect(request, "peer/list");
+ }
+ while (request->get_query_data(request, "add"))
+ {
+ chunk_t encoding, keyid;
+
+ alias = request->get_query_data(request, "alias");
+ public_key = request->get_query_data(request, "public_key");
+
+ if (!verify_alias(this, request, alias))
+ {
+ break;
+ }
+ if (!parse_public_key(this, request, public_key, &encoding, &keyid))
+ {
+ break;
+ }
+ if (this->db->execute(this->db, NULL,
+ "INSERT INTO peer (user, alias, public_key, keyid) "
+ "VALUES (?, ?, ?, ?)",
+ DB_UINT, this->user->get_user(this->user),
+ DB_TEXT, alias, DB_BLOB, encoding,
+ DB_BLOB, keyid) <= 0)
+ {
+ request->setf(request, "error=Peer already exists.");
+ free(keyid.ptr);
+ free(encoding.ptr);
+ break;
+ }
+ free(keyid.ptr);
+ free(encoding.ptr);
+ return request->redirect(request, "peer/list");
+ }
+ request->set(request, "alias", alias);
+ request->set(request, "public_key", public_key);
+
+ return request->render(request, "templates/peer/add.cs");
+}
+
+/**
+ * pem encode a public key into an allocated string
+ */
+char* pem_encode(chunk_t der)
+{
+ static const char *begin = "-----BEGIN PUBLIC KEY-----\n";
+ static const char *end = "-----END PUBLIC KEY-----";
+ size_t len;
+ char *pem;
+ chunk_t base64;
+ int i = 0;
+
+ base64 = chunk_to_base64(der, NULL);
+ len = strlen(begin) + base64.len + base64.len/64 + strlen(end) + 2;
+ pem = malloc(len + 1);
+
+ strcpy(pem, begin);
+ do
+ {
+ strncat(pem, base64.ptr + i, 64);
+ strcat(pem, "\n");
+ i += 64;
+ }
+ while (i < base64.len - 2);
+ strcat(pem, end);
+
+ free(base64.ptr);
+ return pem;
+}
+
+/**
+ * edit a peer
+ */
+static void edit(private_peer_controller_t *this, request_t *request, int id)
+{
+ char *alias = "", *public_key = "", *pem;
+ chunk_t encoding, keyid;
+
+ if (request->get_query_data(request, "back"))
+ {
+ return request->redirect(request, "peer/list");
+ }
+ if (request->get_query_data(request, "delete"))
+ {
+ this->db->execute(this->db, NULL,
+ "DELETE FROM peer WHERE id = ? AND user = ?",
+ DB_INT, id, DB_UINT, this->user->get_user(this->user));
+ return request->redirect(request, "peer/list");
+ }
+ if (request->get_query_data(request, "save"))
+ {
+ while (TRUE)
+ {
+ alias = request->get_query_data(request, "alias");
+ public_key = request->get_query_data(request, "public_key");
+
+ if (!verify_alias(this, request, alias))
+ {
+ break;
+ }
+ if (!parse_public_key(this, request, public_key, &encoding, &keyid))
+ {
+ break;
+ }
+ if (this->db->execute(this->db, NULL,
+ "UPDATE peer SET alias = ?, public_key = ?, keyid = ? "
+ "WHERE id = ? AND user = ?",
+ DB_TEXT, alias, DB_BLOB, encoding, DB_BLOB, keyid,
+ DB_INT, id, DB_UINT, this->user->get_user(this->user)) < 0)
+ {
+ request->setf(request, "error=Peer already exists.");
+ free(keyid.ptr);
+ free(encoding.ptr);
+ break;
+ }
+ free(keyid.ptr);
+ free(encoding.ptr);
+ return request->redirect(request, "peer/list");
+ }
+ }
+ else
+ {
+ enumerator_t *query = this->db->query(this->db,
+ "SELECT alias, public_key FROM peer WHERE id = ? AND user = ?",
+ DB_INT, id, DB_UINT, this->user->get_user(this->user),
+ DB_TEXT, DB_BLOB);
+ if (query && query->enumerate(query, &alias, &encoding))
+ {
+ alias = strdupa(alias);
+ pem = pem_encode(encoding);
+ public_key = strdupa(pem);
+ free(pem);
+ }
+ else
+ {
+ return request->redirect(request, "peer/list");
+ }
+ DESTROY_IF(query);
+ }
+ request->set(request, "alias", alias);
+ request->set(request, "public_key", public_key);
+ return request->render(request, "templates/peer/edit.cs");
+}
+
+/**
+ * delete a peer from the database
+ */
+static void delete(private_peer_controller_t *this, request_t *request, int id)
+{
+ this->db->execute(this->db, NULL,
+ "DELETE FROM peer WHERE id = ? AND user = ?",
+ DB_INT, id, DB_UINT, this->user->get_user(this->user));
+}
+
+/**
+ * Implementation of controller_t.get_name
+ */
+static char* get_name(private_peer_controller_t *this)
+{
+ return "peer";
+}
+
+/**
+ * Implementation of controller_t.handle
+ */
+static void handle(private_peer_controller_t *this, request_t *request,
+ char *action, char *idstr)
+{
+ if (action)
+ {
+ int id = 0;
+ if (idstr)
+ {
+ id = atoi(idstr);
+ }
+
+ if (streq(action, "list"))
+ {
+ return list(this, request);
+ }
+ else if (streq(action, "add"))
+ {
+ return add(this, request);
+ }
+ else if (streq(action, "edit") && id)
+ {
+ return edit(this, request, id);
+ }
+ else if (streq(action, "delete") && id)
+ {
+ delete(this, request, id);
+ }
+ }
+ request->redirect(request, "peer/list");
+}
+
+/**
+ * Implementation of controller_t.destroy
+ */
+static void destroy(private_peer_controller_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+controller_t *peer_controller_create(user_t *user, database_t *db)
+{
+ private_peer_controller_t *this= malloc_thing(private_peer_controller_t);
+
+ this->public.controller.get_name = (char*(*)(controller_t*))get_name;
+ this->public.controller.handle = (void(*)(controller_t*, request_t*, char*, char*, char*, char*, char*))handle;
+ this->public.controller.destroy = (void(*)(controller_t*))destroy;
+
+ this->user = user;
+ this->db = db;
+
+ return &this->public.controller;
+}
+
diff --git a/src/medsrv/controller/peer_controller.h b/src/medsrv/controller/peer_controller.h
new file mode 100755
index 000000000..511265487
--- /dev/null
+++ b/src/medsrv/controller/peer_controller.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup peer_controller_server peer_controller
+ * @{ @ingroup controller_server
+ */
+
+#ifndef PEER_CONTROLLER_H_
+#define PEER_CONTROLLER_H_
+
+#include <user.h>
+
+#include <controller.h>
+#include <database/database.h>
+
+typedef struct peer_controller_t peer_controller_t;
+
+/**
+ * Peer controller. Manages peers associated to a user.
+ */
+struct peer_controller_t {
+
+ /**
+ * Implements controller_t interface.
+ */
+ controller_t controller;
+};
+
+/**
+ * Create a peer_controller controller instance.
+ */
+controller_t *peer_controller_create(user_t *user, database_t *db);
+
+#endif /* PEER_CONTROLLER_H_ @} */
diff --git a/src/medsrv/controller/user_controller.c b/src/medsrv/controller/user_controller.c
new file mode 100755
index 000000000..9e6d12340
--- /dev/null
+++ b/src/medsrv/controller/user_controller.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+
+#include "user_controller.h"
+
+#include <library.h>
+
+typedef struct private_user_controller_t private_user_controller_t;
+
+/**
+ * private data of the user_controller
+ */
+struct private_user_controller_t {
+
+ /**
+ * public functions
+ */
+ user_controller_t public;
+
+ /**
+ * database connection
+ */
+ database_t *db;
+
+ /**
+ * user session
+ */
+ user_t *user;
+
+ /**
+ * minimum required password lenght
+ */
+ u_int password_length;
+};
+
+/**
+ * hash the password for database storage
+ */
+static chunk_t hash_password(char *login, char *password)
+{
+ hasher_t *hasher;
+ chunk_t hash, data;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (!hasher)
+ {
+ return chunk_empty;
+ }
+ data = chunk_cata("cc", chunk_create(login, strlen(login)),
+ chunk_create(password, strlen(password)));
+ hasher->allocate_hash(hasher, data, &hash);
+ hasher->destroy(hasher);
+ return hash;
+}
+
+/**
+ * Login a user.
+ */
+static void login(private_user_controller_t *this, request_t *request)
+{
+ if (request->get_query_data(request, "submit"))
+ {
+ char *login, *password;
+
+ login = request->get_query_data(request, "login");
+ password = request->get_query_data(request, "password");
+
+ if (login && password)
+ {
+ enumerator_t *query;
+ u_int id = 0;
+ chunk_t hash;
+
+ hash = hash_password(login, password);
+ query = this->db->query(this->db,
+ "SELECT id FROM user WHERE login = ? AND password = ?",
+ DB_TEXT, login, DB_BLOB, hash, DB_UINT);
+ if (query)
+ {
+ query->enumerate(query, &id);
+ query->destroy(query);
+ }
+ free(hash.ptr);
+ if (id)
+ {
+ this->user->set_user(this->user, id);
+ return request->redirect(request, "peer/list");
+ }
+ }
+ request->setf(request, "error=Invalid username or password.");
+ }
+ request->render(request, "templates/user/login.cs");
+}
+
+/**
+ * Logout a user.
+ */
+static void logout(private_user_controller_t *this, request_t *request)
+{
+ request->redirect(request, "user/login");
+ request->close_session(request);
+}
+
+/**
+ * verify a user entered username for validity
+ */
+static bool verify_login(private_user_controller_t *this, request_t *request,
+ char *login)
+{
+ if (!login || *login == '\0')
+ {
+ request->setf(request, "error=Username is missing.");
+ return FALSE;
+ }
+ while (*login != '\0')
+ {
+ switch (*login)
+ {
+ case 'a' ... 'z':
+ case 'A' ... 'Z':
+ case '0' ... '9':
+ case '-':
+ case '_':
+ case '@':
+ case '.':
+ login++;
+ continue;
+ default:
+ request->setf(request, "error=Username invalid, "
+ "valid characters: A-Z a-z 0-9 - _ @ .");
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * verify a user entered password for validity
+ */
+static bool verify_password(private_user_controller_t *this, request_t *request,
+ char *password, char *confirm)
+{
+ if (!password || *password == '\0')
+ {
+ request->setf(request, "error=Password is missing.");
+ return FALSE;
+ }
+ if (strlen(password) < this->password_length)
+ {
+ request->setf(request, "error=Password requires at least %d characters.",
+ this->password_length);
+ return FALSE;
+ }
+ if (!confirm || !streq(password, confirm))
+ {
+ request->setf(request, "error=Password not confirmed.");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Register a user.
+ */
+static void add(private_user_controller_t *this, request_t *request)
+{
+ char *login = "";
+
+ while (request->get_query_data(request, "register"))
+ {
+ char *password, *confirm;
+ chunk_t hash;
+ u_int id;
+
+ login = request->get_query_data(request, "new_login");
+ password = request->get_query_data(request, "new_password");
+ confirm = request->get_query_data(request, "confirm_password");
+
+ if (!verify_login(this, request, login) ||
+ !verify_password(this, request, password, confirm))
+ {
+ break;
+ }
+
+ hash = hash_password(login, password);
+ if (!hash.ptr || this->db->execute(this->db, &id,
+ "INSERT INTO user (login, password) VALUES (?, ?)",
+ DB_TEXT, login, DB_BLOB, hash) < 0)
+ {
+ request->setf(request, "error=Username already exists.");
+ free(hash.ptr);
+ break;
+ }
+ free(hash.ptr);
+ this->user->set_user(this->user, id);
+ return request->redirect(request, "peer/list");
+ }
+ request->set(request, "new_login", login);
+ request->setf(request, "password_length=%d", this->password_length);
+ request->render(request, "templates/user/add.cs");
+}
+
+/**
+ * Edit the logged in user
+ */
+static void edit(private_user_controller_t *this, request_t *request)
+{
+ enumerator_t *query;
+ char *old_login;
+
+ /* lookup old login */
+ query = this->db->query(this->db, "SELECT login FROM user WHERE id = ?",
+ DB_INT, this->user->get_user(this->user),
+ DB_TEXT);
+ if (!query || !query->enumerate(query, &old_login))
+ {
+ DESTROY_IF(query);
+ request->close_session(request);
+ return request->redirect(request, "user/login");
+ }
+ old_login = strdupa(old_login);
+ query->destroy(query);
+
+ /* back pressed */
+ if (request->get_query_data(request, "back"))
+ {
+ return request->redirect(request, "peer/list");
+ }
+ /* delete pressed */
+ if (request->get_query_data(request, "delete"))
+ {
+ this->db->execute(this->db, NULL, "DELETE FROM user WHERE id = ?",
+ DB_UINT, this->user->get_user(this->user));
+ this->db->execute(this->db, NULL,
+ "DELETE FROM peer WHERE user = ?",
+ DB_UINT, this->user->get_user(this->user));
+ return logout(this, request);
+ }
+ /* save pressed */
+ while (request->get_query_data(request, "save"))
+ {
+ char *new_login, *old_pass, *new_pass, *confirm;
+ chunk_t old_hash, new_hash;
+
+ new_login = request->get_query_data(request, "old_login");
+ old_pass = request->get_query_data(request, "old_password");
+ new_pass = request->get_query_data(request, "new_password");
+ confirm = request->get_query_data(request, "confirm_password");
+
+ if (!verify_login(this, request, new_login) ||
+ !verify_password(this, request, new_pass, confirm))
+ {
+ old_login = new_login;
+ break;
+ }
+ old_hash = hash_password(old_login, old_pass);
+ new_hash = hash_password(new_login, new_pass);
+
+ if (this->db->execute(this->db, NULL,
+ "UPDATE user SET login = ?, password = ? "
+ "WHERE id = ? AND password = ?",
+ DB_TEXT, new_login, DB_BLOB, new_hash,
+ DB_UINT, this->user->get_user(this->user), DB_BLOB, old_hash) <= 0)
+ {
+ free(new_hash.ptr);
+ free(old_hash.ptr);
+ old_login = new_login;
+ request->setf(request, "error=Password verification failed.");
+ break;
+ }
+ free(new_hash.ptr);
+ free(old_hash.ptr);
+ return request->redirect(request, "peer/list");
+ }
+ /* on error/template rendering */
+ request->set(request, "old_login", old_login);
+ request->setf(request, "password_length=%d", this->password_length);
+ request->render(request, "templates/user/edit.cs");
+}
+
+/**
+ * Implementation of controller_t.get_name
+ */
+static char* get_name(private_user_controller_t *this)
+{
+ return "user";
+}
+
+/**
+ * Implementation of controller_t.handle
+ */
+static void handle(private_user_controller_t *this, request_t *request, char *action)
+{
+ if (action)
+ {
+ if (streq(action, "add"))
+ {
+ return add(this, request);
+ }
+ if (streq(action, "login"))
+ {
+ return login(this, request);
+ }
+ else if (streq(action, "logout"))
+ {
+ return logout(this, request);
+ }
+ else if (streq(action, "edit"))
+ {
+ return edit(this, request);
+ }
+ else if (streq(action, "help"))
+ {
+ return request->render(request, "templates/user/help.cs");
+ }
+ }
+ request->redirect(request, "user/login");
+}
+
+/**
+ * Implementation of controller_t.destroy
+ */
+static void destroy(private_user_controller_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+controller_t *user_controller_create(user_t *user, database_t *db)
+{
+ private_user_controller_t *this= malloc_thing(private_user_controller_t);
+
+ this->public.controller.get_name = (char*(*)(controller_t*))get_name;
+ this->public.controller.handle = (void(*)(controller_t*, request_t*, char*, char*, char*, char*, char*))handle;
+ this->public.controller.destroy = (void(*)(controller_t*))destroy;
+
+ this->user = user;
+ this->db = db;
+ this->password_length = lib->settings->get_int(lib->settings,
+ "medsrv.password_length", 6);
+
+ return &this->public.controller;
+}
+
diff --git a/src/medsrv/controller/user_controller.h b/src/medsrv/controller/user_controller.h
new file mode 100755
index 000000000..897e28362
--- /dev/null
+++ b/src/medsrv/controller/user_controller.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup user_controller_server user_controller
+ * @{ @ingroup controller_server
+ */
+
+#ifndef USER_CONTROLLER_H_
+#define USER_CONTROLLER_H_
+
+#include <user.h>
+
+#include <controller.h>
+#include <database/database.h>
+
+typedef struct user_controller_t user_controller_t;
+
+/**
+ * User controller. Register, Login and user management.
+ */
+struct user_controller_t {
+
+ /**
+ * Implements controller_t interface.
+ */
+ controller_t controller;
+};
+
+/**
+ * Create a user_controller controller instance.
+ */
+controller_t *user_controller_create(user_t *user, database_t *db);
+
+#endif /* USER_CONTROLLER_H_ @} */
diff --git a/src/medsrv/filter/auth_filter.c b/src/medsrv/filter/auth_filter.c
new file mode 100755
index 000000000..5036d26f1
--- /dev/null
+++ b/src/medsrv/filter/auth_filter.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "auth_filter.h"
+
+#include <debug.h>
+
+typedef struct private_auth_filter_t private_auth_filter_t;
+
+/**
+ * private data of auth_filter
+ */
+struct private_auth_filter_t {
+ /**
+ * public functions
+ */
+ auth_filter_t public;
+
+ /**
+ * user session
+ */
+ user_t *user;
+
+ /**
+ * database connection
+ */
+ database_t *db;
+};
+
+/**
+ * Implementation of filter_t.run
+ */
+static bool run(private_auth_filter_t *this, request_t *request,
+ char *controller, char *action)
+{
+ if (this->user->get_user(this->user))
+ {
+ enumerator_t *query;
+ char *login;
+
+ query = this->db->query(this->db, "SELECT login FROM user WHERE id = ?",
+ DB_INT, this->user->get_user(this->user),
+ DB_TEXT);
+ if (query && query->enumerate(query, &login))
+ {
+ request->set(request, "login", login);
+ query->destroy(query);
+ return TRUE;
+ }
+ DESTROY_IF(query);
+ this->user->set_user(this->user, 0);
+ }
+ if (controller && streq(controller, "user") && action &&
+ (streq(action, "add") || streq(action, "login") || streq(action, "help")))
+ { /* add/login allowed */
+ return TRUE;
+ }
+ request->redirect(request, "user/login");
+ return FALSE;
+}
+
+/**
+ * Implementation of filter_t.destroy
+ */
+static void destroy(private_auth_filter_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+filter_t *auth_filter_create(user_t *user, database_t *db)
+{
+ private_auth_filter_t *this= malloc_thing(private_auth_filter_t);
+
+ this->public.filter.destroy = (void(*)(filter_t*))destroy;
+ this->public.filter.run = (bool(*)(filter_t*, request_t*,char*,char*,char*,char*,char*,char*))run;
+
+ this->user = user;
+ this->db = db;
+
+ return &this->public.filter;
+}
+
diff --git a/src/medsrv/filter/auth_filter.h b/src/medsrv/filter/auth_filter.h
new file mode 100755
index 000000000..5ba270e72
--- /dev/null
+++ b/src/medsrv/filter/auth_filter.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup auth_filter_server auth_filter
+ * @{ @ingroup filter_server
+ */
+
+#ifndef AUTH_FILTER_H_
+#define AUTH_FILTER_H_
+
+#include <library.h>
+#include <filter.h>
+
+#include "user.h"
+
+typedef struct auth_filter_t auth_filter_t;
+
+/**
+ * Authentication/Authorization filter.
+ */
+struct auth_filter_t {
+
+ /**
+ * Implements filter_t interface.
+ */
+ filter_t filter;
+};
+
+/**
+ * Create a auth_filter instance.
+ */
+filter_t *auth_filter_create(user_t *user, database_t *db);
+
+#endif /* AUTH_FILTER_H_ @}*/
diff --git a/src/medsrv/main.c b/src/medsrv/main.c
new file mode 100644
index 000000000..00975e93a
--- /dev/null
+++ b/src/medsrv/main.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include <stdio.h>
+
+#include <dispatcher.h>
+#include <debug.h>
+#include <database/database.h>
+
+#include "filter/auth_filter.h"
+#include "controller/user_controller.h"
+#include "controller/peer_controller.h"
+
+int main(int arc, char *argv[])
+{
+ dispatcher_t *dispatcher;
+ database_t *db;
+ char *socket;
+ bool debug;
+ char *uri;
+ int timeout, threads;
+
+ library_init(STRONGSWAN_CONF);
+ lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
+ lib->settings->get_str(lib->settings, "medsrv.load", PLUGINS));
+
+ socket = lib->settings->get_str(lib->settings, "medsrv.socket", NULL);
+ debug = lib->settings->get_bool(lib->settings, "medsrv.debug", FALSE);
+ timeout = lib->settings->get_int(lib->settings, "medsrv.timeout", 900);
+ threads = lib->settings->get_int(lib->settings, "medsrv.threads", 5);
+ uri = lib->settings->get_str(lib->settings, "medsrv.database", NULL);
+ if (uri == NULL)
+ {
+ fprintf(stderr, "database URI medsrv.database not defined.\n");
+ return 1;
+ }
+
+ db = lib->db->create(lib->db, uri);
+ if (db == NULL)
+ {
+ fprintf(stderr, "opening database failed.\n");
+ return 1;
+ }
+
+ dispatcher = dispatcher_create(socket, debug, timeout,
+ (context_constructor_t)user_create, db);
+ dispatcher->add_filter(dispatcher,
+ (filter_constructor_t)auth_filter_create, db);
+ dispatcher->add_controller(dispatcher,
+ (controller_constructor_t)user_controller_create, db);
+ dispatcher->add_controller(dispatcher,
+ (controller_constructor_t)peer_controller_create, db);
+
+ dispatcher->run(dispatcher, threads);
+
+ dispatcher->waitsignal(dispatcher);
+ dispatcher->destroy(dispatcher);
+ db->destroy(db);
+
+ library_deinit();
+ return 0;
+}
+
diff --git a/src/medsrv/templates/footer.cs b/src/medsrv/templates/footer.cs
new file mode 100755
index 000000000..db3601961
--- /dev/null
+++ b/src/medsrv/templates/footer.cs
@@ -0,0 +1,4 @@
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/src/medsrv/templates/header.cs b/src/medsrv/templates/header.cs
new file mode 100755
index 000000000..4ab4afd1e
--- /dev/null
+++ b/src/medsrv/templates/header.cs
@@ -0,0 +1,31 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2002/REC-xhtml1-20020801/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>strongSwan Mediation Service</title>
+ <link rel="stylesheet" type="text/css" href="<?cs var:base ?>/static/style.css"/>
+ <link rel="icon" href="<?cs var:base ?>/static/favicon.ico" type="image/x-icon" />
+ <script type="text/javascript" src="<?cs var:base ?>/static/mootools.js"></script>
+ <script type="text/javascript" src="<?cs var:base ?>/static/script.js"></script>
+ </head>
+ <body>
+ <div class="fleft">
+ <a href="<?cs var:base ?>/peer/list">
+ <img class="fleft" src="<?cs var:base ?>/static/strongswan.png"/>
+ </a>
+ <h1>Mediation Service</h1>
+ </div>
+ <div class="menu">
+ <?cs if:?login ?>
+ Logged in as <i><?cs var:login ?></i>
+ | <a href="<?cs var:base ?>/user/edit">Edit</a>
+ | <a href="<?cs var:base ?>/user/logout">Logout</a>
+ | <a href="<?cs var:base ?>/user/help">Help</a>
+ <?cs else ?>
+ | <a href="<?cs var:base ?>/user/help">Help</a>
+ | <a href="<?cs var:base ?>/user/login">Login</a>
+ | <a href="<?cs var:base ?>/user/add">Register</a>
+ <?cs /if ?>
+ </div>
+ <hr class="cleft"/>
+ <div class="center">
+ <div class="content">
diff --git a/src/medsrv/templates/peer/add.cs b/src/medsrv/templates/peer/add.cs
new file mode 100755
index 000000000..28a994f7f
--- /dev/null
+++ b/src/medsrv/templates/peer/add.cs
@@ -0,0 +1,24 @@
+<?cs include:"templates/header.cs" ?>
+<form method="post">
+<?cs if:?error ?>
+ <div class="error"><?cs var:error ?></div>
+<?cs /if ?>
+ <table class="peer">
+ <tr>
+ <td><label for="alias">Alias</label></td>
+ <td><input type="text" id="alias" name="alias" class="focus" maxlength="30" value="<?cs var:alias ?>";"/></td>
+ </tr>
+ <tr>
+ <td valign="top"><label for="public_key">Public Key</label></td>
+ <td><textarea id="public_key" name="public_key"><?cs var:public_key ?></textarea></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="right">
+ <input type="submit" value="Back" name="back"/>
+ <input type="submit" value="Add" name="add"/>
+ </td>
+ </tr>
+</table>
+</form>
+<?cs include:"templates/footer.cs" ?>
diff --git a/src/medsrv/templates/peer/edit.cs b/src/medsrv/templates/peer/edit.cs
new file mode 100755
index 000000000..76fb9dafc
--- /dev/null
+++ b/src/medsrv/templates/peer/edit.cs
@@ -0,0 +1,25 @@
+<?cs include:"templates/header.cs" ?>
+<form method="post" name="form">
+<?cs if:?error ?>
+ <div class="error"><?cs var:error ?></div>
+<?cs /if ?>
+ <table class="peer">
+ <tr>
+ <td><label for="alias">Alias</label></td>
+ <td><input type="text" id="alias" name="alias" maxlength="30" class="focus" value="<?cs var:alias ?>"/></td>
+ </tr>
+ <tr>
+ <td valign="top"><label for="public_key">Public Key</label></td>
+ <td><textarea id="public_key" name="public_key"><?cs var:public_key ?></textarea></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td align="right">
+ <input type="submit" value="Back" name="back"/>
+ <input type="submit" value="Delete" name="delete" onclick="return confirm('Permanently delete this peer?')"/>
+ <input type="submit" value="Save" name="save"/>
+ </td>
+ </tr>
+</table>
+</form>
+<?cs include:"templates/footer.cs" ?>
diff --git a/src/medsrv/templates/peer/list.cs b/src/medsrv/templates/peer/list.cs
new file mode 100755
index 000000000..205452641
--- /dev/null
+++ b/src/medsrv/templates/peer/list.cs
@@ -0,0 +1,28 @@
+<?cs include:"templates/header.cs" ?>
+<div>
+<?cs if subcount(peers) > 0 ?>
+<table class="list">
+ <tr>
+ <th>Alias</th>
+ <th>Key Identifier</th>
+ </tr>
+<?cs each:peer = peers ?>
+ <tr>
+ <td>
+ <a href="<?cs var:base ?>/peer/edit/<?cs name:peer?>"><?cs var:peer.alias ?></a>
+ </td>
+ <td>
+ <a href="<?cs var:base ?>/peer/edit/<?cs name:peer?>"><?cs var:peer.identifier ?></a>
+ </td>
+ </tr>
+<?cs /each ?>
+</table>
+<?cs else ?>
+No peers defined.
+<?cs /if ?>
+<div class="right">
+<form action="<?cs var:base ?>/peer/add" method="get">
+ <input type="submit" value="Add Peer"/></td>
+</form>
+</div>
+<?cs include:"templates/footer.cs" ?>
diff --git a/src/medsrv/templates/static/favicon.ico b/src/medsrv/templates/static/favicon.ico
new file mode 100755
index 000000000..d00459196
--- /dev/null
+++ b/src/medsrv/templates/static/favicon.ico
Binary files differ
diff --git a/src/medsrv/templates/static/mootools.js b/src/medsrv/templates/static/mootools.js
new file mode 100644
index 000000000..d953a1c06
--- /dev/null
+++ b/src/medsrv/templates/static/mootools.js
@@ -0,0 +1,341 @@
+//MooTools, <http://mootools.net>, My Object Oriented (JavaScript) Tools. Copyright (c) 2006-2008 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
+
+var MooTools={version:"1.2dev",build:""};var Native=function(J){J=J||{};var F=J.afterImplement||function(){};var G=J.generics;G=(G!==false);var H=J.legacy;
+var E=J.initialize;var B=J.protect;var A=J.name;var C=E||H;C.constructor=Native;C.$family={name:"native"};if(H&&E){C.prototype=H.prototype;}C.prototype.constructor=C;
+if(A){var D=A.toLowerCase();C.prototype.$family={name:D};Native.typize(C,D);}var I=function(M,K,N,L){if(!B||L||!M.prototype[K]){M.prototype[K]=N;}if(G){Native.genericize(M,K,B);
+}F.call(M,K,N);return M;};C.implement=function(L,K,N){if(typeof L=="string"){return I(this,L,K,N);}for(var M in L){I(this,M,L[M],K);}return this;};C.alias=function(M,K,N){if(typeof M=="string"){M=this.prototype[M];
+if(M){I(this,K,M,N);}}else{for(var L in M){this.alias(L,M[L],K);}}return this;};return C;};Native.implement=function(D,C){for(var B=0,A=D.length;B<A;B++){D[B].implement(C);
+}};Native.genericize=function(B,C,A){if((!A||!B[C])&&typeof B.prototype[C]=="function"){B[C]=function(){var D=Array.prototype.slice.call(arguments);return B.prototype[C].apply(D.shift(),D);
+};}};Native.typize=function(A,B){if(!A.type){A.type=function(C){return($type(C)===B);};}};Native.alias=function(E,B,A,F){for(var D=0,C=E.length;D<C;D++){E[D].alias(B,A,F);
+}};(function(B){for(var A in B){Native.typize(B[A],A);}})({"boolean":Boolean,"native":Native,object:Object});(function(B){for(var A in B){new Native({name:A,initialize:B[A],protect:true});
+}})({String:String,Function:Function,Number:Number,Array:Array,RegExp:RegExp,Date:Date});(function(B,A){for(var C=A.length;C--;C){Native.genericize(B,A[C],true);
+}return arguments.callee;})(Array,["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice","toString","valueOf","indexOf","lastIndexOf"])(String,["charAt","charCodeAt","concat","indexOf","lastIndexOf","match","replace","search","slice","split","substr","substring","toLowerCase","toUpperCase","valueOf"]);
+function $chk(A){return !!(A||A===0);}function $clear(A){clearTimeout(A);clearInterval(A);return null;}function $defined(A){return(A!=undefined);}function $empty(){}function $arguments(A){return function(){return arguments[A];
+};}function $lambda(A){return(typeof A=="function")?A:function(){return A;};}function $extend(C,A){for(var B in (A||{})){C[B]=A[B];}return C;}function $unlink(C){var B;
+switch($type(C)){case"object":B={};for(var E in C){B[E]=$unlink(C[E]);}break;case"hash":B=$unlink(C.getClean());break;case"array":B=[];for(var D=0,A=C.length;
+D<A;D++){B[D]=$unlink(C[D]);}break;default:return C;}return B;}function $merge(){var E={};for(var D=0,A=arguments.length;D<A;D++){var B=arguments[D];if($type(B)!="object"){continue;
+}for(var C in B){var G=B[C],F=E[C];E[C]=(F&&$type(G)=="object"&&$type(F)=="object")?$merge(F,G):$unlink(G);}}return E;}function $pick(){for(var B=0,A=arguments.length;
+B<A;B++){if(arguments[B]!=undefined){return arguments[B];}}return null;}function $random(B,A){return Math.floor(Math.random()*(A-B+1)+B);}function $splat(B){var A=$type(B);
+return(A)?((A!="array"&&A!="arguments")?[B]:B):[];}var $time=Date.now||function(){return new Date().getTime();};function $try(){for(var B=0,A=arguments.length;
+B<A;B++){try{return arguments[B]();}catch(C){}}return null;}function $type(A){if(A==undefined){return false;}if(A.$family){return(A.$family.name=="number"&&!isFinite(A))?false:A.$family.name;
+}if(A.nodeName){switch(A.nodeType){case 1:return"element";case 3:return(/\S/).test(A.nodeValue)?"textnode":"whitespace";}}else{if(typeof A.length=="number"){if(A.callee){return"arguments";
+}else{if(A.item){return"collection";}}}}return typeof A;}var Hash=new Native({name:"Hash",initialize:function(A){if($type(A)=="hash"){A=$unlink(A.getClean());
+}for(var B in A){this[B]=A[B];}return this;}});Hash.implement({getLength:function(){var B=0;for(var A in this){if(this.hasOwnProperty(A)){B++;}}return B;
+},forEach:function(B,C){for(var A in this){if(this.hasOwnProperty(A)){B.call(C,this[A],A,this);}}},getClean:function(){var B={};for(var A in this){if(this.hasOwnProperty(A)){B[A]=this[A];
+}}return B;}});Hash.alias("forEach","each");function $H(A){return new Hash(A);}Array.implement({forEach:function(C,D){for(var B=0,A=this.length;B<A;B++){C.call(D,this[B],B,this);
+}}});Array.alias("forEach","each");function $A(C){if(C.item){var D=[];for(var B=0,A=C.length;B<A;B++){D[B]=C[B];}return D;}return Array.prototype.slice.call(C);
+}function $each(C,B,D){var A=$type(C);((A=="arguments"||A=="collection"||A=="array")?Array:Hash).each(C,B,D);}var Browser=new Hash({Engine:{name:"unknown",version:""},Platform:{name:(navigator.platform.match(/mac|win|linux/i)||["other"])[0].toLowerCase()},Features:{xpath:!!(document.evaluate),air:!!(window.runtime)},Plugins:{}});
+if(window.opera){Browser.Engine={name:"presto",version:(document.getElementsByClassName)?950:925};}else{if(window.ActiveXObject){Browser.Engine={name:"trident",version:(window.XMLHttpRequest)?5:4};
+}else{if(!navigator.taintEnabled){Browser.Engine={name:"webkit",version:(Browser.Features.xpath)?420:419};}else{if(document.getBoxObjectFor!=null){Browser.Engine={name:"gecko",version:(document.getElementsByClassName)?19:18};
+}}}}Browser.Engine[Browser.Engine.name]=Browser.Engine[Browser.Engine.name+Browser.Engine.version]=true;if(window.orientation!=undefined){Browser.Platform.name="ipod";
+}Browser.Platform[Browser.Platform.name]=true;Browser.Request=function(){return $try(function(){return new XMLHttpRequest();},function(){return new ActiveXObject("MSXML2.XMLHTTP");
+});};Browser.Features.xhr=!!(Browser.Request());Browser.Plugins.Flash=(function(){var A=($try(function(){return navigator.plugins["Shockwave Flash"].description;
+},function(){return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version");})||"0 r0").match(/\d+/g);return{version:parseInt(A[0]||0+"."+A[1]||0),build:parseInt(A[2]||0)};
+})();function $exec(B){if(!B){return B;}if(window.execScript){window.execScript(B);}else{var A=document.createElement("script");A.setAttribute("type","text/javascript");
+A.text=B;document.head.appendChild(A);document.head.removeChild(A);}return B;}Native.UID=1;var $uid=(Browser.Engine.trident)?function(A){return(A.uid||(A.uid=[Native.UID++]))[0];
+}:function(A){return A.uid||(A.uid=Native.UID++);};var Window=new Native({name:"Window",legacy:(Browser.Engine.trident)?null:window.Window,initialize:function(A){$uid(A);
+if(!A.Element){A.Element=$empty;if(Browser.Engine.webkit){A.document.createElement("iframe");}A.Element.prototype=(Browser.Engine.webkit)?window["[[DOMElement.prototype]]"]:{};
+}return $extend(A,Window.Prototype);},afterImplement:function(B,A){window[B]=Window.Prototype[B]=A;}});Window.Prototype={$family:{name:"window"}};new Window(window);
+var Document=new Native({name:"Document",legacy:(Browser.Engine.trident)?null:window.Document,initialize:function(A){$uid(A);A.head=A.getElementsByTagName("head")[0];
+A.html=A.getElementsByTagName("html")[0];A.window=A.defaultView||A.parentWindow;if(Browser.Engine.trident4){$try(function(){A.execCommand("BackgroundImageCache",false,true);
+});}return $extend(A,Document.Prototype);},afterImplement:function(B,A){document[B]=Document.Prototype[B]=A;}});Document.Prototype={$family:{name:"document"}};
+new Document(document);Array.implement({every:function(C,D){for(var B=0,A=this.length;B<A;B++){if(!C.call(D,this[B],B,this)){return false;}}return true;
+},filter:function(D,E){var C=[];for(var B=0,A=this.length;B<A;B++){if(D.call(E,this[B],B,this)){C.push(this[B]);}}return C;},clean:function(){return this.filter($defined);
+},indexOf:function(C,D){var A=this.length;for(var B=(D<0)?Math.max(0,A+D):D||0;B<A;B++){if(this[B]===C){return B;}}return -1;},map:function(D,E){var C=[];
+for(var B=0,A=this.length;B<A;B++){C[B]=D.call(E,this[B],B,this);}return C;},some:function(C,D){for(var B=0,A=this.length;B<A;B++){if(C.call(D,this[B],B,this)){return true;
+}}return false;},associate:function(C){var D={},B=Math.min(this.length,C.length);for(var A=0;A<B;A++){D[C[A]]=this[A];}return D;},link:function(C){var A={};
+for(var E=0,B=this.length;E<B;E++){for(var D in C){if(C[D](this[E])){A[D]=this[E];delete C[D];break;}}}return A;},contains:function(A,B){return this.indexOf(A,B)!=-1;
+},extend:function(C){for(var B=0,A=C.length;B<A;B++){this.push(C[B]);}return this;},getLast:function(){return(this.length)?this[this.length-1]:null;},getRandom:function(){return(this.length)?this[$random(0,this.length-1)]:null;
+},include:function(A){if(!this.contains(A)){this.push(A);}return this;},combine:function(C){for(var B=0,A=C.length;B<A;B++){this.include(C[B]);}return this;
+},erase:function(B){for(var A=this.length;A--;A){if(this[A]===B){this.splice(A,1);}}return this;},empty:function(){this.length=0;return this;},flatten:function(){var D=[];
+for(var B=0,A=this.length;B<A;B++){var C=$type(this[B]);if(!C){continue;}D=D.concat((C=="array"||C=="collection"||C=="arguments")?Array.flatten(this[B]):this[B]);
+}return D;},hexToRgb:function(B){if(this.length!=3){return null;}var A=this.map(function(C){if(C.length==1){C+=C;}return C.toInt(16);});return(B)?A:"rgb("+A+")";
+},rgbToHex:function(D){if(this.length<3){return null;}if(this.length==4&&this[3]==0&&!D){return"transparent";}var B=[];for(var A=0;A<3;A++){var C=(this[A]-0).toString(16);
+B.push((C.length==1)?"0"+C:C);}return(D)?B:"#"+B.join("");}});Function.implement({extend:function(A){for(var B in A){this[B]=A[B];}return this;},create:function(B){var A=this;
+B=B||{};return function(D){var C=B.arguments;C=(C!=undefined)?$splat(C):Array.slice(arguments,(B.event)?1:0);if(B.event){C=[D||window.event].extend(C);
+}var E=function(){return A.apply(B.bind||null,C);};if(B.delay){return setTimeout(E,B.delay);}if(B.periodical){return setInterval(E,B.periodical);}if(B.attempt){return $try(E);
+}return E();};},pass:function(A,B){return this.create({arguments:A,bind:B});},attempt:function(A,B){return this.create({arguments:A,bind:B,attempt:true})();
+},bind:function(B,A){return this.create({bind:B,arguments:A});},bindWithEvent:function(B,A){return this.create({bind:B,event:true,arguments:A});},delay:function(B,C,A){return this.create({delay:B,bind:C,arguments:A})();
+},periodical:function(A,C,B){return this.create({periodical:A,bind:C,arguments:B})();},run:function(A,B){return this.apply(B,$splat(A));}});Number.implement({limit:function(B,A){return Math.min(A,Math.max(B,this));
+},round:function(A){A=Math.pow(10,A||0);return Math.round(this*A)/A;},times:function(B,C){for(var A=0;A<this;A++){B.call(C,A,this);}},toFloat:function(){return parseFloat(this);
+},toInt:function(A){return parseInt(this,A||10);}});Number.alias("times","each");(function(B){var A={};B.each(function(C){if(!Number[C]){A[C]=function(){return Math[C].apply(null,[this].concat($A(arguments)));
+};}});Number.implement(A);})(["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","max","min","pow","sin","sqrt","tan"]);String.implement({test:function(A,B){return((typeof A=="string")?new RegExp(A,B):A).test(this);
+},contains:function(A,B){return(B)?(B+this+B).indexOf(B+A+B)>-1:this.indexOf(A)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim();
+},camelCase:function(){return this.replace(/-\D/g,function(A){return A.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(A){return("-"+A.charAt(0).toLowerCase());
+});},capitalize:function(){return this.replace(/\b[a-z]/g,function(A){return A.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");
+},toInt:function(A){return parseInt(this,A||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(B){var A=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
+return(A)?A.slice(1).hexToRgb(B):null;},rgbToHex:function(B){var A=this.match(/\d{1,3}/g);return(A)?A.rgbToHex(B):null;},stripScripts:function(B){var A="";
+var C=this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi,function(){A+=arguments[1]+"\n";return"";});if(B===true){$exec(A);}else{if($type(B)=="function"){B(A,C);
+}}return C;},substitute:function(A,B){return this.replace(B||(/\\?\{([^}]+)\}/g),function(D,C){if(D.charAt(0)=="\\"){return D.slice(1);}return(A[C]!=undefined)?A[C]:"";
+});}});Hash.implement({has:Object.prototype.hasOwnProperty,keyOf:function(B){for(var A in this){if(this.hasOwnProperty(A)&&this[A]===B){return A;}}return null;
+},hasValue:function(A){return(Hash.keyOf(this,A)!==null);},extend:function(A){Hash.each(A,function(C,B){Hash.set(this,B,C);},this);return this;},combine:function(A){Hash.each(A,function(C,B){Hash.include(this,B,C);
+},this);return this;},erase:function(A){if(this.hasOwnProperty(A)){delete this[A];}return this;},get:function(A){return(this.hasOwnProperty(A))?this[A]:null;
+},set:function(A,B){if(!this[A]||this.hasOwnProperty(A)){this[A]=B;}return this;},empty:function(){Hash.each(this,function(B,A){delete this[A];},this);
+return this;},include:function(B,C){var A=this[B];if(A==undefined){this[B]=C;}return this;},map:function(B,C){var A=new Hash;Hash.each(this,function(E,D){A.set(D,B.call(C,E,D,this));
+},this);return A;},filter:function(B,C){var A=new Hash;Hash.each(this,function(E,D){if(B.call(C,E,D,this)){A.set(D,E);}},this);return A;},every:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&!B.call(C,this[A],A)){return false;
+}}return true;},some:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&B.call(C,this[A],A)){return true;}}return false;},getKeys:function(){var A=[];
+Hash.each(this,function(C,B){A.push(B);});return A;},getValues:function(){var A=[];Hash.each(this,function(B){A.push(B);});return A;},toQueryString:function(A){var B=[];
+Hash.each(this,function(F,E){if(A){E=A+"["+E+"]";}var D;switch($type(F)){case"object":D=Hash.toQueryString(F,E);break;case"array":var C={};F.each(function(H,G){C[G]=H;
+});D=Hash.toQueryString(C,E);break;default:D=E+"="+encodeURIComponent(F);}if(F!=undefined){B.push(D);}});return B.join("&");}});Hash.alias({keyOf:"indexOf",hasValue:"contains"});
+var Event=new Native({name:"Event",initialize:function(A,F){F=F||window;var K=F.document;A=A||F.event;if(A.$extended){return A;}this.$extended=true;var J=A.type;
+var G=A.target||A.srcElement;while(G&&G.nodeType==3){G=G.parentNode;}if(J.test(/key/)){var B=A.which||A.keyCode;var M=Event.Keys.keyOf(B);if(J=="keydown"){var D=B-111;
+if(D>0&&D<13){M="f"+D;}}M=M||String.fromCharCode(B).toLowerCase();}else{if(J.match(/(click|mouse|menu)/i)){K=(!K.compatMode||K.compatMode=="CSS1Compat")?K.html:K.body;
+var I={x:A.pageX||A.clientX+K.scrollLeft,y:A.pageY||A.clientY+K.scrollTop};var C={x:(A.pageX)?A.pageX-F.pageXOffset:A.clientX,y:(A.pageY)?A.pageY-F.pageYOffset:A.clientY};
+if(J.match(/DOMMouseScroll|mousewheel/)){var H=(A.wheelDelta)?A.wheelDelta/120:-(A.detail||0)/3;}var E=(A.which==3)||(A.button==2);var L=null;if(J.match(/over|out/)){switch(J){case"mouseover":L=A.relatedTarget||A.fromElement;
+break;case"mouseout":L=A.relatedTarget||A.toElement;}if(!(function(){while(L&&L.nodeType==3){L=L.parentNode;}return true;}).create({attempt:Browser.Engine.gecko})()){L=false;
+}}}}return $extend(this,{event:A,type:J,page:I,client:C,rightClick:E,wheel:H,relatedTarget:L,target:G,code:B,key:M,shift:A.shiftKey,control:A.ctrlKey,alt:A.altKey,meta:A.metaKey});
+}});Event.Keys=new Hash({enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46});Event.implement({stop:function(){return this.stopPropagation().preventDefault();
+},stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation();}else{this.event.cancelBubble=true;}return this;},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault();
+}else{this.event.returnValue=false;}return this;}});var Class=new Native({name:"Class",initialize:function(B){B=B||{};var A=function(E){for(var D in this){this[D]=$unlink(this[D]);
+}for(var F in Class.Mutators){if(!this[F]){continue;}Class.Mutators[F](this,this[F]);delete this[F];}this.constructor=A;if(E===$empty){return this;}var C=(this.initialize)?this.initialize.apply(this,arguments):this;
+if(this.options&&this.options.initialize){this.options.initialize.call(this);}return C;};$extend(A,this);A.constructor=Class;A.prototype=B;return A;}});
+Class.implement({implement:function(){Class.Mutators.Implements(this.prototype,Array.slice(arguments));return this;}});Class.Mutators={Implements:function(A,B){$splat(B).each(function(C){$extend(A,($type(C)=="class")?new C($empty):C);
+});},Extends:function(self,klass){var instance=new klass($empty);delete instance.parent;delete instance.parentOf;for(var key in instance){var current=self[key],previous=instance[key];
+if(current==undefined){self[key]=previous;continue;}var ctype=$type(current),ptype=$type(previous);if(ctype!=ptype){continue;}switch(ctype){case"function":if(!arguments.callee.caller){self[key]=eval("("+String(current).replace(/\bthis\.parent\(\s*(\))?/g,function(full,close){return"arguments.callee._parent_.call(this"+(close||", ");
+})+")");}self[key]._parent_=previous;break;case"object":self[key]=$merge(previous,current);}}self.parent=function(){return arguments.callee.caller._parent_.apply(this,arguments);
+};self.parentOf=function(descendant){return descendant._parent_.apply(this,Array.slice(arguments,1));};}};var Chain=new Class({chain:function(){this.$chain=(this.$chain||[]).extend(arguments);
+return this;},callChain:function(){return(this.$chain&&this.$chain.length)?this.$chain.shift().apply(this,arguments):false;},clearChain:function(){if(this.$chain){this.$chain.empty();
+}return this;}});var Events=new Class({addEvent:function(C,B,A){C=Events.removeOn(C);if(B!=$empty){this.$events=this.$events||{};this.$events[C]=this.$events[C]||[];
+this.$events[C].include(B);if(A){B.internal=true;}}return this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);}return this;},fireEvent:function(C,B,A){C=Events.removeOn(C);
+if(!this.$events||!this.$events[C]){return this;}this.$events[C].each(function(D){D.create({bind:this,delay:A,"arguments":B})();},this);return this;},removeEvent:function(B,A){B=Events.removeOn(B);
+if(!this.$events||!this.$events[B]){return this;}if(!A.internal){this.$events[B].erase(A);}return this;},removeEvents:function(C){for(var D in this.$events){if(C&&C!=D){continue;
+}var B=this.$events[D];for(var A=B.length;A--;A){this.removeEvent(D,B[A]);}}return this;}});Events.removeOn=function(A){return A.replace(/^on([A-Z])/,function(B,C){return C.toLowerCase();
+});};var Options=new Class({setOptions:function(){this.options=$merge.run([this.options].extend(arguments));if(!this.addEvent){return this;}for(var A in this.options){if($type(this.options[A])!="function"||!(/^on[A-Z]/).test(A)){continue;
+}this.addEvent(A,this.options[A]);delete this.options[A];}return this;}});Document.implement({newElement:function(A,B){if(Browser.Engine.trident&&B){["name","type","checked"].each(function(C){if(!B[C]){return ;
+}A+=" "+C+'="'+B[C]+'"';if(C!="checked"){delete B[C];}});A="<"+A+">";}return $.element(this.createElement(A)).set(B);},newTextNode:function(A){return this.createTextNode(A);
+},getDocument:function(){return this;},getWindow:function(){return this.defaultView||this.parentWindow;},purge:function(){var C=this.getElementsByTagName("*");
+for(var B=0,A=C.length;B<A;B++){Browser.freeMem(C[B]);}}});var Element=new Native({name:"Element",legacy:window.Element,initialize:function(A,B){var C=Element.Constructors.get(A);
+if(C){return C(B);}if(typeof A=="string"){return document.newElement(A,B);}return $(A).set(B);},afterImplement:function(A,B){if(!Array[A]){Elements.implement(A,Elements.multi(A));
+}Element.Prototype[A]=B;}});Element.Prototype={$family:{name:"element"}};Element.Constructors=new Hash;var IFrame=new Native({name:"IFrame",generics:false,initialize:function(){var E=Array.link(arguments,{properties:Object.type,iframe:$defined});
+var C=E.properties||{};var B=$(E.iframe)||false;var D=C.onload||$empty;delete C.onload;C.id=C.name=$pick(C.id,C.name,B.id,B.name,"IFrame_"+$time());B=new Element(B||"iframe",C);
+var A=function(){var F=$try(function(){return B.contentWindow.location.host;});if(F&&F==window.location.host){var H=new Window(B.contentWindow);var G=new Document(B.contentWindow.document);
+$extend(H.Element.prototype,Element.Prototype);}D.call(B.contentWindow,B.contentWindow.document);};(!window.frames[C.id])?B.addListener("load",A):A();return B;
+}});var Elements=new Native({initialize:function(F,B){B=$extend({ddup:true,cash:true},B);F=F||[];if(B.ddup||B.cash){var G={},E=[];for(var C=0,A=F.length;
+C<A;C++){var D=$.element(F[C],!B.cash);if(B.ddup){if(G[D.uid]){continue;}G[D.uid]=true;}E.push(D);}F=E;}return(B.cash)?$extend(F,this):F;}});Elements.implement({filter:function(A,B){if(!A){return this;
+}return new Elements(Array.filter(this,(typeof A=="string")?function(C){return C.match(A);}:A,B));}});Elements.multi=function(A){return function(){var B=[];
+var F=true;for(var D=0,C=this.length;D<C;D++){var E=this[D][A].apply(this[D],arguments);B.push(E);if(F){F=($type(E)=="element");}}return(F)?new Elements(B):B;
+};};Window.implement({$:function(B,C){if(B&&B.$family&&B.uid){return B;}var A=$type(B);return($[A])?$[A](B,C,this.document):null;},$$:function(A){if(arguments.length==1&&typeof A=="string"){return this.document.getElements(A);
+}var F=[];var C=Array.flatten(arguments);for(var D=0,B=C.length;D<B;D++){var E=C[D];switch($type(E)){case"element":E=[E];break;case"string":E=this.document.getElements(E,true);
+break;default:E=false;}if(E){F.extend(E);}}return new Elements(F);},getDocument:function(){return this.document;},getWindow:function(){return this;}});
+$.string=function(C,B,A){C=A.getElementById(C);return(C)?$.element(C,B):null;};$.element=function(A,D){$uid(A);if(!D&&!A.$family&&!(/^object|embed$/i).test(A.tagName)){var B=Element.Prototype;
+for(var C in B){A[C]=B[C];}}return A;};$.object=function(B,C,A){if(B.toElement){return $.element(B.toElement(A),C);}return null;};$.textnode=$.whitespace=$.window=$.document=$arguments(0);
+Native.implement([Element,Document],{getElement:function(A,B){return $(this.getElements(A,true)[0]||null,B);},getElements:function(A,D){A=A.split(",");
+var C=[];var B=(A.length>1);A.each(function(E){var F=this.getElementsByTagName(E.trim());(B)?C.extend(F):C=F;},this);return new Elements(C,{ddup:B,cash:!D});
+}});Element.Storage={get:function(A){return(this[A]||(this[A]={}));}};Element.Inserters=new Hash({before:function(B,A){if(A.parentNode){A.parentNode.insertBefore(B,A);
+}},after:function(B,A){if(!A.parentNode){return ;}var C=A.nextSibling;(C)?A.parentNode.insertBefore(B,C):A.parentNode.appendChild(B);},bottom:function(B,A){A.appendChild(B);
+},top:function(B,A){var C=A.firstChild;(C)?A.insertBefore(B,C):A.appendChild(B);}});Element.Inserters.inside=Element.Inserters.bottom;Element.Inserters.each(function(C,B){var A=B.capitalize();
+Element.implement("inject"+A,function(D){C(this,$(D,true));return this;});Element.implement("grab"+A,function(D){C($(D,true),this);return this;});});Element.implement({getDocument:function(){return this.ownerDocument;
+},getWindow:function(){return this.ownerDocument.getWindow();},getElementById:function(D,C){var B=this.ownerDocument.getElementById(D);if(!B){return null;
+}for(var A=B.parentNode;A!=this;A=A.parentNode){if(!A){return null;}}return $.element(B,C);},set:function(D,B){switch($type(D)){case"object":for(var C in D){this.set(C,D[C]);
+}break;case"string":var A=Element.Properties.get(D);(A&&A.set)?A.set.apply(this,Array.slice(arguments,1)):this.setProperty(D,B);}return this;},get:function(B){var A=Element.Properties.get(B);
+return(A&&A.get)?A.get.apply(this,Array.slice(arguments,1)):this.getProperty(B);},erase:function(B){var A=Element.Properties.get(B);(A&&A.erase)?A.erase.apply(this,Array.slice(arguments,1)):this.removeProperty(B);
+return this;},match:function(A){return(!A||Element.get(this,"tag")==A);},inject:function(B,A){Element.Inserters.get(A||"bottom")(this,$(B,true));return this;
+},wraps:function(B,A){B=$(B,true);return this.replaces(B).grab(B,A);},grab:function(B,A){Element.Inserters.get(A||"bottom")($(B,true),this);return this;
+},appendText:function(B,A){return this.grab(this.getDocument().newTextNode(B),A);},adopt:function(){Array.flatten(arguments).each(function(A){A=$(A,true);
+if(A){this.appendChild(A);}},this);return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this;},clone:function(D,C){switch($type(this)){case"element":var H={};
+for(var G=0,E=this.attributes.length;G<E;G++){var B=this.attributes[G],L=B.nodeName.toLowerCase();if(Browser.Engine.trident&&(/input/i).test(this.tagName)&&(/width|height/).test(L)){continue;
+}var K=(L=="style"&&this.style)?this.style.cssText:B.nodeValue;if(!$chk(K)||L=="uid"||(L=="id"&&!C)){continue;}if(K!="inherit"&&["string","number"].contains($type(K))){H[L]=K;
+}}var J=new Element(this.nodeName.toLowerCase(),H);if(D!==false){for(var I=0,F=this.childNodes.length;I<F;I++){var A=Element.clone(this.childNodes[I],true,C);
+if(A){J.grab(A);}}}return J;case"textnode":return document.newTextNode(this.nodeValue);}return null;},replaces:function(A){A=$(A,true);A.parentNode.replaceChild(this,A);
+return this;},hasClass:function(A){return this.className.contains(A," ");},addClass:function(A){if(!this.hasClass(A)){this.className=(this.className+" "+A).clean();
+}return this;},removeClass:function(A){this.className=this.className.replace(new RegExp("(^|\\s)"+A+"(?:\\s|$)"),"$1").clean();return this;},toggleClass:function(A){return this.hasClass(A)?this.removeClass(A):this.addClass(A);
+},getComputedStyle:function(B){if(this.currentStyle){return this.currentStyle[B.camelCase()];}var A=this.getWindow().getComputedStyle(this,null);return(A)?A.getPropertyValue([B.hyphenate()]):null;
+},empty:function(){$A(this.childNodes).each(function(A){Browser.freeMem(A);Element.empty(A);Element.dispose(A);},this);return this;},destroy:function(){Browser.freeMem(this.empty().dispose());
+return null;},getSelected:function(){return new Elements($A(this.options).filter(function(A){return A.selected;}));},toQueryString:function(){var A=[];
+this.getElements("input, select, textarea").each(function(B){if(!B.name||B.disabled){return ;}var C=(B.tagName.toLowerCase()=="select")?Element.getSelected(B).map(function(D){return D.value;
+}):((B.type=="radio"||B.type=="checkbox")&&!B.checked)?null:B.value;$splat(C).each(function(D){if(D){A.push(B.name+"="+encodeURIComponent(D));}});});return A.join("&");
+},getProperty:function(C){var B=Element.Attributes,A=B.Props[C];var D=(A)?this[A]:this.getAttribute(C,2);return(B.Bools[C])?!!D:(A)?D:D||null;},getProperties:function(){var A=$A(arguments);
+return A.map(function(B){return this.getProperty(B);},this).associate(A);},setProperty:function(D,E){var C=Element.Attributes,B=C.Props[D],A=$defined(E);
+if(B&&C.Bools[D]){E=(E||!A)?true:false;}else{if(!A){return this.removeProperty(D);}}(B)?this[B]=E:this.setAttribute(D,E);return this;},setProperties:function(A){for(var B in A){this.setProperty(B,A[B]);
+}return this;},removeProperty:function(D){var C=Element.Attributes,B=C.Props[D],A=(B&&C.Bools[D]);(B)?this[B]=(A)?false:"":this.removeAttribute(D);return this;
+},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this;}});(function(){var A=function(D,B,I,C,F,H){var E=D[I||B];var G=[];
+while(E){if(E.nodeType==1&&(!C||Element.match(E,C))){G.push(E);if(!F){break;}}E=E[B];}return(F)?new Elements(G,{ddup:false,cash:!H}):$(G[0],H);};Element.implement({getPrevious:function(B,C){return A(this,"previousSibling",null,B,false,C);
+},getAllPrevious:function(B,C){return A(this,"previousSibling",null,B,true,C);},getNext:function(B,C){return A(this,"nextSibling",null,B,false,C);},getAllNext:function(B,C){return A(this,"nextSibling",null,B,true,C);
+},getFirst:function(B,C){return A(this,"nextSibling","firstChild",B,false,C);},getLast:function(B,C){return A(this,"previousSibling","lastChild",B,false,C);
+},getParent:function(B,C){return A(this,"parentNode",null,B,false,C);},getParents:function(B,C){return A(this,"parentNode",null,B,true,C);},getChildren:function(B,C){return A(this,"nextSibling","firstChild",B,true,C);
+},hasChild:function(B){B=$(B,true);return(!!B&&$A(this.getElementsByTagName(B.tagName)).contains(B));}});})();Element.Properties=new Hash;Element.Properties.style={set:function(A){this.style.cssText=A;
+},get:function(){return this.style.cssText;},erase:function(){this.style.cssText="";}};Element.Properties.tag={get:function(){return this.tagName.toLowerCase();
+}};Element.Properties.href={get:function(){return(!this.href)?null:this.href.replace(new RegExp("^"+document.location.protocol+"//"+document.location.host),"");
+}};Element.Properties.html={set:function(){return this.innerHTML=Array.flatten(arguments).join("");}};Native.implement([Element,Window,Document],{addListener:function(B,A){if(this.addEventListener){this.addEventListener(B,A,false);
+}else{this.attachEvent("on"+B,A);}return this;},removeListener:function(B,A){if(this.removeEventListener){this.removeEventListener(B,A,false);}else{this.detachEvent("on"+B,A);
+}return this;},retrieve:function(B,A){var D=Element.Storage.get(this.uid);var C=D[B];if($defined(A)&&!$defined(C)){C=D[B]=A;}return $pick(C);},store:function(B,A){var C=Element.Storage.get(this.uid);
+C[B]=A;return this;},eliminate:function(A){var B=Element.Storage.get(this.uid);delete B[A];return this;}});Element.Attributes=new Hash({Props:{html:"innerHTML","class":"className","for":"htmlFor",text:(Browser.Engine.trident)?"innerText":"textContent"},Bools:["compact","nowrap","ismap","declare","noshade","checked","disabled","readonly","multiple","selected","noresize","defer"],Camels:["value","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"]});
+Browser.freeMem=function(A){if(!A){return ;}if(Browser.Engine.trident&&(/object/i).test(A.tagName)){for(var B in A){if(typeof A[B]=="function"){A[B]=$empty;
+}}Element.dispose(A);}if(A.uid&&A.removeEvents){A.removeEvents();}};(function(B){var C=B.Bools,A=B.Camels;B.Bools=C=C.associate(C);Hash.extend(Hash.combine(B.Props,C),A.associate(A.map(function(D){return D.toLowerCase();
+})));B.erase("Camels");})(Element.Attributes);window.addListener("unload",function(){window.removeListener("unload",arguments.callee);document.purge();
+if(Browser.Engine.trident){CollectGarbage();}});Element.Properties.events={set:function(A){this.addEvents(A);}};Native.implement([Element,Window,Document],{addEvent:function(E,G){var H=this.retrieve("events",{});
+H[E]=H[E]||{keys:[],values:[]};if(H[E].keys.contains(G)){return this;}H[E].keys.push(G);var F=E,A=Element.Events.get(E),C=G,I=this;if(A){if(A.onAdd){A.onAdd.call(this,G);
+}if(A.condition){C=function(J){if(A.condition.call(this,J)){return G.call(this,J);}return false;};}F=A.base||F;}var D=function(){return G.call(I);};var B=Element.NativeEvents[F]||0;
+if(B){if(B==2){D=function(J){J=new Event(J,I.getWindow());if(C.call(I,J)===false){J.stop();}};}this.addListener(F,D);}H[E].values.push(D);return this;},removeEvent:function(D,C){var B=this.retrieve("events");
+if(!B||!B[D]){return this;}var G=B[D].keys.indexOf(C);if(G==-1){return this;}var A=B[D].keys.splice(G,1)[0];var F=B[D].values.splice(G,1)[0];var E=Element.Events.get(D);
+if(E){if(E.onRemove){E.onRemove.call(this,C);}D=E.base||D;}return(Element.NativeEvents[D])?this.removeListener(D,F):this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);
+}return this;},removeEvents:function(B){var A=this.retrieve("events");if(!A){return this;}if(!B){for(var C in A){this.removeEvents(C);}A=null;}else{if(A[B]){while(A[B].keys[0]){this.removeEvent(B,A[B].keys[0]);
+}A[B]=null;}}return this;},fireEvent:function(D,B,A){var C=this.retrieve("events");if(!C||!C[D]){return this;}C[D].keys.each(function(E){E.create({bind:this,delay:A,"arguments":B})();
+},this);return this;},cloneEvents:function(D,A){D=$(D);var C=D.retrieve("events");if(!C){return this;}if(!A){for(var B in C){this.cloneEvents(D,B);}}else{if(C[A]){C[A].keys.each(function(E){this.addEvent(A,E);
+},this);}}return this;}});Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:1,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1};
+(function(){var A=function(B){var C=B.relatedTarget;if(C==undefined){return true;}if(C===false){return false;}return($type(this)!="document"&&C!=this&&C.prefix!="xul"&&!this.hasChild(C));
+};Element.Events=new Hash({mouseenter:{base:"mouseover",condition:A},mouseleave:{base:"mouseout",condition:A},mousewheel:{base:(Browser.Engine.gecko)?"DOMMouseScroll":"mousewheel"}});
+})();Element.Properties.styles={set:function(A){this.setStyles(A);}};Element.Properties.opacity={set:function(A,B){if(!B){if(A==0){if(this.style.visibility!="hidden"){this.style.visibility="hidden";
+}}else{if(this.style.visibility!="visible"){this.style.visibility="visible";}}}if(!this.currentStyle||!this.currentStyle.hasLayout){this.style.zoom=1;}if(Browser.Engine.trident){this.style.filter=(A==1)?"":"alpha(opacity="+A*100+")";
+}this.style.opacity=A;this.store("opacity",A);},get:function(){return this.retrieve("opacity",1);}};Element.implement({setOpacity:function(A){return this.set("opacity",A,true);
+},getOpacity:function(){return this.get("opacity");},setStyle:function(B,A){switch(B){case"opacity":return this.set("opacity",parseFloat(A));case"float":B=(Browser.Engine.trident)?"styleFloat":"cssFloat";
+}B=B.camelCase();if($type(A)!="string"){var C=(Element.Styles.get(B)||"@").split(" ");A=$splat(A).map(function(E,D){if(!C[D]){return"";}return($type(E)=="number")?C[D].replace("@",Math.round(E)):E;
+}).join(" ");}else{if(A==String(Number(A))){A=Math.round(A);}}this.style[B]=A;return this;},getStyle:function(G){switch(G){case"opacity":return this.get("opacity");
+case"float":G=(Browser.Engine.trident)?"styleFloat":"cssFloat";}G=G.camelCase();var A=this.style[G];if(!$chk(A)){A=[];for(var F in Element.ShortStyles){if(G!=F){continue;
+}for(var E in Element.ShortStyles[F]){A.push(this.getStyle(E));}return A.join(" ");}A=this.getComputedStyle(G);}if(A){A=String(A);var C=A.match(/rgba?\([\d\s,]+\)/);
+if(C){A=A.replace(C[0],C[0].rgbToHex());}}if(Browser.Engine.presto||(Browser.Engine.trident&&!$chk(parseInt(A)))){if(G.test(/^(height|width)$/)){var B=(G=="width")?["left","right"]:["top","bottom"],D=0;
+B.each(function(H){D+=this.getStyle("border-"+H+"-width").toInt()+this.getStyle("padding-"+H).toInt();},this);return this["offset"+G.capitalize()]-D+"px";
+}if(Browser.Engine.presto&&String(A).test("px")){return A;}if(G.test(/(border(.+)Width|margin|padding)/)){return"0px";}}return A;},setStyles:function(B){for(var A in B){this.setStyle(A,B[A]);
+}return this;},getStyles:function(){var A={};Array.each(arguments,function(B){A[B]=this.getStyle(B);},this);return A;}});Element.Styles=new Hash({left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"});
+Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(G){var F=Element.ShortStyles;
+var B=Element.Styles;["margin","padding"].each(function(H){var I=H+G;F[H][I]=B[I]="@px";});var E="border"+G;F.border[E]=B[E]="@px @ rgb(@, @, @)";var D=E+"Width",A=E+"Style",C=E+"Color";
+F[E]={};F.borderWidth[D]=F[E][D]=B[D]="@px";F.borderStyle[A]=F[E][A]=B[A]="@";F.borderColor[C]=F[E][C]=B[C]="rgb(@, @, @)";});(function(){Element.implement({scrollTo:function(H,I){if(B(this)){this.getWindow().scrollTo(H,I);
+}else{this.scrollLeft=H;this.scrollTop=I;}return this;},getSize:function(){if(B(this)){return this.getWindow().getSize();}return{x:this.offsetWidth,y:this.offsetHeight};
+},getScrollSize:function(){if(B(this)){return this.getWindow().getScrollSize();}return{x:this.scrollWidth,y:this.scrollHeight};},getScroll:function(){if(B(this)){return this.getWindow().getScroll();
+}return{x:this.scrollLeft,y:this.scrollTop};},getScrolls:function(){var I=this,H={x:0,y:0};while(I&&!B(I)){H.x+=I.scrollLeft;H.y+=I.scrollTop;I=I.parentNode;
+}return H;},getOffsetParent:function(){var H=this;if(B(H)){return null;}if(!Browser.Engine.trident){return H.offsetParent;}while((H=H.parentNode)&&!B(H)){if(D(H,"position")!="static"){return H;
+}}return null;},getOffsets:function(){var I=this,H={x:0,y:0};if(B(this)){return H;}while(I&&!B(I)){H.x+=I.offsetLeft;H.y+=I.offsetTop;if(Browser.Engine.gecko){if(!F(I)){H.x+=C(I);
+H.y+=G(I);}var J=I.parentNode;if(J&&D(J,"overflow")!="visible"){H.x+=C(J);H.y+=G(J);}}else{if(I!=this&&(Browser.Engine.trident||Browser.Engine.webkit)){H.x+=C(I);
+H.y+=G(I);}}I=I.offsetParent;if(Browser.Engine.trident){while(I&&!I.currentStyle.hasLayout){I=I.offsetParent;}}}if(Browser.Engine.gecko&&!F(this)){H.x-=C(this);
+H.y-=G(this);}return H;},getPosition:function(K){if(B(this)){return{x:0,y:0};}var L=this.getOffsets(),I=this.getScrolls();var H={x:L.x-I.x,y:L.y-I.y};var J=(K&&(K=$(K)))?K.getPosition():{x:0,y:0};
+return{x:H.x-J.x,y:H.y-J.y};},getCoordinates:function(J){if(B(this)){return this.getWindow().getCoordinates();}var H=this.getPosition(J),I=this.getSize();
+var K={left:H.x,top:H.y,width:I.x,height:I.y};K.right=K.left+K.width;K.bottom=K.top+K.height;return K;},computePosition:function(H){return{left:H.x-E(this,"margin-left"),top:H.y-E(this,"margin-top")};
+},position:function(H){return this.setStyles(this.computePosition(H));}});Native.implement([Document,Window],{getSize:function(){var I=this.getWindow();
+if(Browser.Engine.presto||Browser.Engine.webkit){return{x:I.innerWidth,y:I.innerHeight};}var H=A(this);return{x:H.clientWidth,y:H.clientHeight};},getScroll:function(){var I=this.getWindow();
+var H=A(this);return{x:I.pageXOffset||H.scrollLeft,y:I.pageYOffset||H.scrollTop};},getScrollSize:function(){var I=A(this);var H=this.getSize();return{x:Math.max(I.scrollWidth,H.x),y:Math.max(I.scrollHeight,H.y)};
+},getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var H=this.getSize();return{top:0,left:0,bottom:H.y,right:H.x,height:H.y,width:H.x};
+}});var D=Element.getComputedStyle;function E(H,I){return D(H,I).toInt()||0;}function F(H){return D(H,"-moz-box-sizing")=="border-box";}function G(H){return E(H,"border-top-width");
+}function C(H){return E(H,"border-left-width");}function B(H){return(/^(?:body|html)$/i).test(H.tagName);}function A(H){var I=H.getDocument();return(!I.compatMode||I.compatMode=="CSS1Compat")?I.html:I.body;
+}})();Native.implement([Window,Document,Element],{getHeight:function(){return this.getSize().y;},getWidth:function(){return this.getSize().x;},getScrollTop:function(){return this.getScroll().y;
+},getScrollLeft:function(){return this.getScroll().x;},getScrollHeight:function(){return this.getScrollSize().y;},getScrollWidth:function(){return this.getScrollSize().x;
+},getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x;}});Native.implement([Document,Element],{getElements:function(H,G){H=H.split(",");
+var C,E={};for(var D=0,B=H.length;D<B;D++){var A=H[D],F=Selectors.Utils.search(this,A,E);if(D!=0&&F.item){F=$A(F);}C=(D==0)?F:(C.item)?$A(C).concat(F):C.concat(F);
+}return new Elements(C,{ddup:(H.length>1),cash:!G});}});Element.implement({match:function(B){if(!B){return true;}var D=Selectors.Utils.parseTagAndID(B);
+var A=D[0],E=D[1];if(!Selectors.Filters.byID(this,E)||!Selectors.Filters.byTag(this,A)){return false;}var C=Selectors.Utils.parseSelector(B);return(C)?Selectors.Utils.filter(this,C,{}):true;
+}});var Selectors={Cache:{nth:{},parsed:{}}};Selectors.RegExps={id:(/#([\w-]+)/),tag:(/^(\w+|\*)/),quick:(/^(\w+|\*)$/),splitter:(/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g),combined:(/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)["']?(.*?)["']?)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g)};
+Selectors.Utils={chk:function(B,C){if(!C){return true;}var A=$uid(B);if(!C[A]){return C[A]=true;}return false;},parseNthArgument:function(F){if(Selectors.Cache.nth[F]){return Selectors.Cache.nth[F];
+}var C=F.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/);if(!C){return false;}var E=parseInt(C[1]);var B=(E||E===0)?E:1;var D=C[2]||false;var A=parseInt(C[3])||0;
+if(B!=0){A--;while(A<1){A+=B;}while(A>=B){A-=B;}}else{B=A;D="index";}switch(D){case"n":C={a:B,b:A,special:"n"};break;case"odd":C={a:2,b:0,special:"n"};
+break;case"even":C={a:2,b:1,special:"n"};break;case"first":C={a:0,special:"index"};break;case"last":C={special:"last-child"};break;case"only":C={special:"only-child"};
+break;default:C={a:(B-1),special:"index"};}return Selectors.Cache.nth[F]=C;},parseSelector:function(E){if(Selectors.Cache.parsed[E]){return Selectors.Cache.parsed[E];
+}var D,H={classes:[],pseudos:[],attributes:[]};while((D=Selectors.RegExps.combined.exec(E))){var I=D[1],G=D[2],F=D[3],B=D[4],C=D[5],J=D[6];if(I){H.classes.push(I);
+}else{if(C){var A=Selectors.Pseudo.get(C);if(A){H.pseudos.push({parser:A,argument:J});}else{H.attributes.push({name:C,operator:"=",value:J});}}else{if(G){H.attributes.push({name:G,operator:F,value:B});
+}}}}if(!H.classes.length){delete H.classes;}if(!H.attributes.length){delete H.attributes;}if(!H.pseudos.length){delete H.pseudos;}if(!H.classes&&!H.attributes&&!H.pseudos){H=null;
+}return Selectors.Cache.parsed[E]=H;},parseTagAndID:function(B){var A=B.match(Selectors.RegExps.tag);var C=B.match(Selectors.RegExps.id);return[(A)?A[1]:"*",(C)?C[1]:false];
+},filter:function(F,C,E){var D;if(C.classes){for(D=C.classes.length;D--;D){var G=C.classes[D];if(!Selectors.Filters.byClass(F,G)){return false;}}}if(C.attributes){for(D=C.attributes.length;
+D--;D){var B=C.attributes[D];if(!Selectors.Filters.byAttribute(F,B.name,B.operator,B.value)){return false;}}}if(C.pseudos){for(D=C.pseudos.length;D--;D){var A=C.pseudos[D];
+if(!Selectors.Filters.byPseudo(F,A.parser,A.argument,E)){return false;}}}return true;},getByTagAndID:function(B,A,D){if(D){var C=(B.getElementById)?B.getElementById(D,true):Element.getElementById(B,D,true);
+return(C&&Selectors.Filters.byTag(C,A))?[C]:[];}else{return B.getElementsByTagName(A);}},search:function(J,I,O){var B=[];var C=I.trim().replace(Selectors.RegExps.splitter,function(Z,Y,X){B.push(Y);
+return":)"+X;}).split(":)");var K,F,E,V;for(var U=0,Q=C.length;U<Q;U++){var T=C[U];if(U==0&&Selectors.RegExps.quick.test(T)){K=J.getElementsByTagName(T);
+continue;}var A=B[U-1];var L=Selectors.Utils.parseTagAndID(T);var W=L[0],M=L[1];if(U==0){K=Selectors.Utils.getByTagAndID(J,W,M);}else{var D={},H=[];for(var S=0,R=K.length;
+S<R;S++){H=Selectors.Getters[A](H,K[S],W,M,D);}K=H;}var G=Selectors.Utils.parseSelector(T);if(G){E=[];for(var P=0,N=K.length;P<N;P++){V=K[P];if(Selectors.Utils.filter(V,G,O)){E.push(V);
+}}K=E;}}return K;}};Selectors.Getters={" ":function(H,G,I,A,E){var D=Selectors.Utils.getByTagAndID(G,I,A);for(var C=0,B=D.length;C<B;C++){var F=D[C];if(Selectors.Utils.chk(F,E)){H.push(F);
+}}return H;},">":function(H,G,I,A,F){var C=Selectors.Utils.getByTagAndID(G,I,A);for(var E=0,D=C.length;E<D;E++){var B=C[E];if(B.parentNode==G&&Selectors.Utils.chk(B,F)){H.push(B);
+}}return H;},"+":function(C,B,A,E,D){while((B=B.nextSibling)){if(B.nodeType==1){if(Selectors.Utils.chk(B,D)&&Selectors.Filters.byTag(B,A)&&Selectors.Filters.byID(B,E)){C.push(B);
+}break;}}return C;},"~":function(C,B,A,E,D){while((B=B.nextSibling)){if(B.nodeType==1){if(!Selectors.Utils.chk(B,D)){break;}if(Selectors.Filters.byTag(B,A)&&Selectors.Filters.byID(B,E)){C.push(B);
+}}}return C;}};Selectors.Filters={byTag:function(B,A){return(A=="*"||(B.tagName&&B.tagName.toLowerCase()==A));},byID:function(A,B){return(!B||(A.id&&A.id==B));
+},byClass:function(B,A){return(B.className&&B.className.contains(A," "));},byPseudo:function(A,D,C,B){return D.call(A,C,B);},byAttribute:function(C,D,B,E){var A=Element.prototype.getProperty.call(C,D);
+if(!A){return false;}if(!B||E==undefined){return true;}switch(B){case"=":return(A==E);case"*=":return(A.contains(E));case"^=":return(A.substr(0,E.length)==E);
+case"$=":return(A.substr(A.length-E.length)==E);case"!=":return(A!=E);case"~=":return A.contains(E," ");case"|=":return A.contains(E,"-");}return false;
+}};Selectors.Pseudo=new Hash({empty:function(){return !(this.innerText||this.textContent||"").length;},not:function(A){return !Element.match(this,A);},contains:function(A){return(this.innerText||this.textContent||"").contains(A);
+},"first-child":function(){return Selectors.Pseudo.index.call(this,0);},"last-child":function(){var A=this;while((A=A.nextSibling)){if(A.nodeType==1){return false;
+}}return true;},"only-child":function(){var B=this;while((B=B.previousSibling)){if(B.nodeType==1){return false;}}var A=this;while((A=A.nextSibling)){if(A.nodeType==1){return false;
+}}return true;},"nth-child":function(G,E){G=(G==undefined)?"n":G;var C=Selectors.Utils.parseNthArgument(G);if(C.special!="n"){return Selectors.Pseudo[C.special].call(this,C.a,E);
+}var F=0;E.positions=E.positions||{};var D=$uid(this);if(!E.positions[D]){var B=this;while((B=B.previousSibling)){if(B.nodeType!=1){continue;}F++;var A=E.positions[$uid(B)];
+if(A!=undefined){F=A+F;break;}}E.positions[D]=F;}return(E.positions[D]%C.a==C.b);},index:function(A){var B=this,C=0;while((B=B.previousSibling)){if(B.nodeType==1&&++C>A){return false;
+}}return(C==A);},even:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n+1",A);},odd:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n",A);
+}});Element.Events.domready={onAdd:function(A){if(Browser.loaded){A.call(this);}}};(function(){var B=function(){if(Browser.loaded){return ;}Browser.loaded=true;
+window.fireEvent("domready");document.fireEvent("domready");};switch(Browser.Engine.name){case"webkit":(function(){(["loaded","complete"].contains(document.readyState))?B():arguments.callee.delay(50);
+})();break;case"trident":var A=document.createElement("div");(function(){($try(function(){A.doScroll("left");return $(A).inject(document.body).set("html","temp").dispose();
+}))?B():arguments.callee.delay(50);})();break;default:window.addEvent("load",B);document.addEvent("DOMContentLoaded",B);}})();var JSON=new Hash({encode:function(B){switch($type(B)){case"string":return'"'+B.replace(/[\x00-\x1f\\"]/g,JSON.$replaceChars)+'"';
+case"array":return"["+String(B.map(JSON.encode).filter($defined))+"]";case"object":case"hash":var A=[];Hash.each(B,function(E,D){var C=JSON.encode(E);if(C){A.push(JSON.encode(D)+":"+C);
+}});return"{"+A+"}";case"number":case"boolean":return String(B);case false:return"null";}return null;},$specialChars:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},$replaceChars:function(A){return JSON.$specialChars[A]||"\\u00"+Math.floor(A.charCodeAt()/16).toString(16)+(A.charCodeAt()%16).toString(16);
+},decode:function(string,secure){if($type(string)!="string"||!string.length){return null;}if(secure&&!(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,""))){return null;
+}return eval("("+string+")");}});Native.implement([Hash,Array,String,Number],{toJSON:function(){return JSON.encode(this);}});var Cookie=new Class({Implements:Options,options:{path:false,domain:false,duration:false,secure:false,document:document},initialize:function(B,A){this.key=B;
+this.setOptions(A);},write:function(B){B=encodeURIComponent(B);if(this.options.domain){B+="; domain="+this.options.domain;}if(this.options.path){B+="; path="+this.options.path;
+}if(this.options.duration){var A=new Date();A.setTime(A.getTime()+this.options.duration*24*60*60*1000);B+="; expires="+A.toGMTString();}if(this.options.secure){B+="; secure";
+}this.options.document.cookie=this.key+"="+B;return this;},read:function(){var A=this.options.document.cookie.match("(?:^|;)\\s*"+this.key.escapeRegExp()+"=([^;]*)");
+return(A)?decodeURIComponent(A[1]):null;},dispose:function(){new Cookie(this.key,$merge(this.options,{duration:-1})).write("");return this;}});Cookie.write=function(B,C,A){return new Cookie(B,A).write(C);
+};Cookie.read=function(A){return new Cookie(A).read();};Cookie.dispose=function(B,A){return new Cookie(B,A).dispose();};var Swiff=new Class({Implements:[Options],options:{id:null,height:1,width:1,container:null,properties:{},params:{quality:"high",allowScriptAccess:"always",wMode:"transparent",swLiveConnect:true},callBacks:{},vars:{}},toElement:function(){return this.object;
+},initialize:function(L,M){this.instance="Swiff_"+$time();this.setOptions(M);M=this.options;var B=this.id=M.id||this.instance;var A=$(M.container);Swiff.CallBacks[this.instance]={};
+var E=M.params,G=M.vars,F=M.callBacks;var H=$extend({height:M.height,width:M.width},M.properties);var K=this;for(var D in F){Swiff.CallBacks[this.instance][D]=(function(N){return function(){return N.apply(K.object,arguments);
+};})(F[D]);G[D]="Swiff.CallBacks."+this.instance+"."+D;}E.flashVars=Hash.toQueryString(G);if(Browser.Engine.trident){H.classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
+E.movie=L;}else{H.type="application/x-shockwave-flash";H.data=L;}var J='<object id="'+B+'"';for(var I in H){J+=" "+I+'="'+H[I]+'"';}J+=">";for(var C in E){if(E[C]){J+='<param name="'+C+'" value="'+E[C]+'" />';
+}}J+="</object>";this.object=((A)?A.empty():new Element("div")).set("html",J).firstChild;},replaces:function(A){A=$(A,true);A.parentNode.replaceChild(this.toElement(),A);
+return this;},inject:function(A){$(A,true).appendChild(this.toElement());return this;},remote:function(){return Swiff.remote.apply(Swiff,[this.toElement()].extend(arguments));
+}});Swiff.CallBacks={};Swiff.remote=function(obj,fn){var rs=obj.CallFunction('<invoke name="'+fn+'" returntype="javascript">'+__flash__argumentsToXML(arguments,2)+"</invoke>");
+return eval(rs);};var Fx=new Class({Implements:[Chain,Events,Options],options:{fps:50,unit:false,duration:500,link:"ignore",transition:function(A){return -(Math.cos(Math.PI*A)-1)/2;
+}},initialize:function(A){this.subject=this.subject||this;this.setOptions(A);this.options.duration=Fx.Durations[this.options.duration]||this.options.duration.toInt();
+var B=this.options.wait;if(B===false){this.options.link="cancel";}},step:function(){var A=$time();if(A<this.time+this.options.duration){var B=this.options.transition((A-this.time)/this.options.duration);
+this.set(this.compute(this.from,this.to,B));}else{this.set(this.compute(this.from,this.to,1));this.complete();}},set:function(A){return A;},compute:function(C,B,A){return Fx.compute(C,B,A);
+},check:function(A){if(!this.timer){return true;}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(A.bind(this,Array.slice(arguments,1)));
+return false;}return false;},start:function(B,A){if(!this.check(arguments.callee,B,A)){return this;}this.from=B;this.to=A;this.time=0;this.startTimer();
+this.onStart();return this;},complete:function(){if(this.stopTimer()){this.onComplete();}return this;},cancel:function(){if(this.stopTimer()){this.onCancel();
+}return this;},onStart:function(){this.fireEvent("start",this.subject);},onComplete:function(){this.fireEvent("complete",this.subject);if(!this.callChain()){this.fireEvent("chainComplete",this.subject);
+}},onCancel:function(){this.fireEvent("cancel",this.subject).clearChain();},pause:function(){this.stopTimer();return this;},resume:function(){this.startTimer();
+return this;},stopTimer:function(){if(!this.timer){return false;}this.time=$time()-this.time;this.timer=$clear(this.timer);return true;},startTimer:function(){if(this.timer){return false;
+}this.time=$time()-this.time;this.timer=this.step.periodical(Math.round(1000/this.options.fps),this);return true;}});Fx.compute=function(C,B,A){return(B-C)*A+C;
+};Fx.Durations={"short":250,normal:500,"long":1000};Fx.CSS=new Class({Extends:Fx,prepare:function(D,E,B){B=$splat(B);var C=B[1];if(!$chk(C)){B[1]=B[0];
+B[0]=D.getStyle(E);}var A=B.map(this.parse);return{from:A[0],to:A[1]};},parse:function(A){A=$lambda(A)();A=(typeof A=="string")?A.split(" "):$splat(A);
+return A.map(function(C){C=String(C);var B=false;Fx.CSS.Parsers.each(function(F,E){if(B){return ;}var D=F.parse(C);if($chk(D)){B={value:D,parser:F};}});
+B=B||{value:C,parser:Fx.CSS.Parsers.String};return B;});},compute:function(D,C,B){var A=[];(Math.min(D.length,C.length)).times(function(E){A.push({value:D[E].parser.compute(D[E].value,C[E].value,B),parser:D[E].parser});
+});A.$family={name:"fx:css:value"};return A;},serve:function(C,B){if($type(C)!="fx:css:value"){C=this.parse(C);}var A=[];C.each(function(D){A=A.concat(D.parser.serve(D.value,B));
+});return A;},render:function(A,D,C,B){A.setStyle(D,this.serve(C,B));},search:function(A){if(Fx.CSS.Cache[A]){return Fx.CSS.Cache[A];}var B={};Array.each(document.styleSheets,function(E,D){var C=E.href;
+if(C&&C.contains("://")&&!C.contains(document.domain)){return ;}var F=E.rules||E.cssRules;Array.each(F,function(I,G){if(!I.style){return ;}var H=(I.selectorText)?I.selectorText.replace(/^\w+/,function(J){return J.toLowerCase();
+}):null;if(!H||!H.test("^"+A+"$")){return ;}Element.Styles.each(function(K,J){if(!I.style[J]||Element.ShortStyles[J]){return ;}K=String(I.style[J]);B[J]=(K.test(/^rgb/))?K.rgbToHex():K;
+});});});return Fx.CSS.Cache[A]=B;}});Fx.CSS.Cache={};Fx.CSS.Parsers=new Hash({Color:{parse:function(A){if(A.match(/^#[0-9a-f]{3,6}$/i)){return A.hexToRgb(true);
+}return((A=A.match(/(\d+),\s*(\d+),\s*(\d+)/)))?[A[1],A[2],A[3]]:false;},compute:function(C,B,A){return C.map(function(E,D){return Math.round(Fx.compute(C[D],B[D],A));
+});},serve:function(A){return A.map(Number);}},Number:{parse:parseFloat,compute:Fx.compute,serve:function(B,A){return(A)?B+A:B;}},String:{parse:$lambda(false),compute:$arguments(1),serve:$arguments(0)}});
+Fx.Tween=new Class({Extends:Fx.CSS,initialize:function(B,A){this.element=this.subject=$(B);this.parent(A);},set:function(B,A){if(arguments.length==1){A=B;
+B=this.property||this.options.property;}this.render(this.element,B,A,this.options.unit);return this;},start:function(C,E,D){if(!this.check(arguments.callee,C,E,D)){return this;
+}var B=Array.flatten(arguments);this.property=this.options.property||B.shift();var A=this.prepare(this.element,this.property,B);return this.parent(A.from,A.to);
+}});Element.Properties.tween={set:function(A){var B=this.retrieve("tween");if(B){B.cancel();}return this.eliminate("tween").store("tween:options",$extend({link:"cancel"},A));
+},get:function(A){if(A||!this.retrieve("tween")){if(A||!this.retrieve("tween:options")){this.set("tween",A);}this.store("tween",new Fx.Tween(this,this.retrieve("tween:options")));
+}return this.retrieve("tween");}};Element.implement({tween:function(A,C,B){this.get("tween").start(arguments);return this;},fade:function(C){var E=this.get("tween"),D="opacity",A;
+C=$pick(C,"toggle");switch(C){case"in":E.start(D,1);break;case"out":E.start(D,0);break;case"show":E.set(D,1);break;case"hide":E.set(D,0);break;case"toggle":var B=this.retrieve("fade:flag",this.get("opacity")==1);
+E.start(D,(B)?0:1);this.store("fade:flag",!B);A=true;break;default:E.start(D,arguments);}if(!A){this.eliminate("fade:flag");}return this;},highlight:function(C,A){if(!A){A=this.retrieve("highlight:original",this.getStyle("background-color"));
+A=(A=="transparent")?"#fff":A;}var B=this.get("tween");B.start("background-color",C||"#ffff88",A).chain(function(){this.setStyle("background-color",this.retrieve("highlight:original"));
+B.callChain();}.bind(this));return this;}});Fx.Morph=new Class({Extends:Fx.CSS,initialize:function(B,A){this.element=this.subject=$(B);this.parent(A);},set:function(A){if(typeof A=="string"){A=this.search(A);
+}for(var B in A){this.render(this.element,B,A[B],this.options.unit);}return this;},compute:function(E,D,C){var A={};for(var B in E){A[B]=this.parent(E[B],D[B],C);
+}return A;},start:function(B){if(!this.check(arguments.callee,B)){return this;}if(typeof B=="string"){B=this.search(B);}var E={},D={};for(var C in B){var A=this.prepare(this.element,C,B[C]);
+E[C]=A.from;D[C]=A.to;}return this.parent(E,D);}});Element.Properties.morph={set:function(A){var B=this.retrieve("morph");if(B){B.cancel();}return this.eliminate("morph").store("morph:options",$extend({link:"cancel"},A));
+},get:function(A){if(A||!this.retrieve("morph")){if(A||!this.retrieve("morph:options")){this.set("morph",A);}this.store("morph",new Fx.Morph(this,this.retrieve("morph:options")));
+}return this.retrieve("morph");}};Element.implement({morph:function(A){this.get("morph").start(A);return this;}});(function(){var A=Fx.prototype.initialize;
+Fx.prototype.initialize=function(B){A.call(this,B);var C=this.options.transition;if(typeof C=="string"&&(C=C.split(":"))){var D=Fx.Transitions;D=D[C[0]]||D[C[0].capitalize()];
+if(C[1]){D=D["ease"+C[1].capitalize()+(C[2]?C[2].capitalize():"")];}this.options.transition=D;}};})();Fx.Transition=function(B,A){A=$splat(A);return $extend(B,{easeIn:function(C){return B(C,A);
+},easeOut:function(C){return 1-B(1-C,A);},easeInOut:function(C){return(C<=0.5)?B(2*C,A)/2:(2-B(2*(1-C),A))/2;}});};Fx.Transitions=new Hash({linear:$arguments(0)});
+Fx.Transitions.extend=function(A){for(var B in A){Fx.Transitions[B]=new Fx.Transition(A[B]);}};Fx.Transitions.extend({Pow:function(B,A){return Math.pow(B,A[0]||6);
+},Expo:function(A){return Math.pow(2,8*(A-1));},Circ:function(A){return 1-Math.sin(Math.acos(A));},Sine:function(A){return 1-Math.sin((1-A)*Math.PI/2);
+},Back:function(B,A){A=A[0]||1.618;return Math.pow(B,2)*((A+1)*B-A);},Bounce:function(D){var C;for(var B=0,A=1;1;B+=A,A/=2){if(D>=(7-4*B)/11){C=-Math.pow((11-6*B-11*D)/4,2)+A*A;
+break;}}return C;},Elastic:function(B,A){return Math.pow(2,10*--B)*Math.cos(20*B*Math.PI*(A[0]||1)/3);}});["Quad","Cubic","Quart","Quint"].each(function(B,A){Fx.Transitions[B]=new Fx.Transition(function(C){return Math.pow(C,[A+2]);
+});});var Request=new Class({Implements:[Chain,Events,Options],options:{url:"",data:"",headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/javascript, text/html, application/xml, text/xml, */*"},async:true,format:false,method:"post",link:"ignore",isSuccess:null,emulation:true,urlEncoded:true,encoding:"utf-8",evalScripts:false,evalResponse:false},initialize:function(A){this.xhr=new Browser.Request();
+this.setOptions(A);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers=new Hash(this.options.headers);},onStateChange:function(){if(this.xhr.readyState!=4||!this.running){return ;
+}this.running=false;this.status=0;$try(function(){this.status=this.xhr.status;}.bind(this));if(this.options.isSuccess.call(this,this.status)){this.response={text:this.xhr.responseText,xml:this.xhr.responseXML};
+this.success(this.response.text,this.response.xml);}else{this.response={text:null,xml:null};this.failure();}this.xhr.onreadystatechange=$empty;},isSuccess:function(){return((this.status>=200)&&(this.status<300));
+},processScripts:function(A){if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){return $exec(A);}return A.stripScripts(this.options.evalScripts);
+},success:function(B,A){this.onSuccess(this.processScripts(B),A);},onSuccess:function(){this.fireEvent("complete",arguments).fireEvent("success",arguments).callChain();
+},failure:function(){this.onFailure();},onFailure:function(){this.fireEvent("complete").fireEvent("failure",this.xhr);},setHeader:function(A,B){this.headers.set(A,B);
+return this;},getHeader:function(A){return $try(function(){return this.xhr.getResponseHeader(A);}.bind(this));},check:function(A){if(!this.running){return true;
+}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(A.bind(this,Array.slice(arguments,1)));return false;}return false;
+},send:function(I){if(!this.check(arguments.callee,I)){return this;}this.running=true;var G=$type(I);if(G=="string"||G=="element"){I={data:I};}var D=this.options;
+I=$extend({data:D.data,url:D.url,method:D.method},I);var E=I.data,B=I.url,A=I.method;switch($type(E)){case"element":E=$(E).toQueryString();break;case"object":case"hash":E=Hash.toQueryString(E);
+}if(this.options.format){var H="format="+this.options.format;E=(E)?H+"&"+E:H;}if(this.options.emulation&&["put","delete"].contains(A)){var F="_method="+A;
+E=(E)?F+"&"+E:F;A="post";}if(this.options.urlEncoded&&A=="post"){var C=(this.options.encoding)?"; charset="+this.options.encoding:"";this.headers.set("Content-type","application/x-www-form-urlencoded"+C);
+}if(E&&A=="get"){B=B+(B.contains("?")?"&":"?")+E;E=null;}this.xhr.open(A.toUpperCase(),B,this.options.async);this.xhr.onreadystatechange=this.onStateChange.bind(this);
+this.headers.each(function(K,J){if(!$try(function(){this.xhr.setRequestHeader(J,K);return true;}.bind(this))){this.fireEvent("exception",[J,K]);}},this);
+this.fireEvent("request");this.xhr.send(E);if(!this.options.async){this.onStateChange();}return this;},cancel:function(){if(!this.running){return this;
+}this.running=false;this.xhr.abort();this.xhr.onreadystatechange=$empty;this.xhr=new Browser.Request();this.fireEvent("cancel");return this;}});(function(){var A={};
+["get","post","put","delete","GET","POST","PUT","DELETE"].each(function(B){A[B]=function(){var C=Array.link(arguments,{url:String.type,data:$defined});
+return this.send($extend(C,{method:B.toLowerCase()}));};});Request.implement(A);})();Element.Properties.send={set:function(A){var B=this.retrieve("send");
+if(B){B.cancel();}return this.eliminate("send").store("send:options",$extend({data:this,link:"cancel",method:this.get("method")||"post",url:this.get("action")},A));
+},get:function(A){if(A||!this.retrieve("send")){if(A||!this.retrieve("send:options")){this.set("send",A);}this.store("send",new Request(this.retrieve("send:options")));
+}return this.retrieve("send");}};Element.implement({send:function(A){var B=this.get("send");B.send({data:this,url:A||B.options.url});return this;}});Request.HTML=new Class({Extends:Request,options:{update:false,evalScripts:true,filter:false},processHTML:function(C){var B=C.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
+C=(B)?B[1]:C;var A=new Element("div");return $try(function(){var D="<root>"+C+"</root>",G;if(Browser.Engine.trident){G=new ActiveXObject("Microsoft.XMLDOM");
+G.async=false;G.loadXML(D);}else{G=new DOMParser().parseFromString(D,"text/xml");}D=G.getElementsByTagName("root")[0];for(var F=0,E=D.childNodes.length;
+F<E;F++){var H=Element.clone(D.childNodes[F],true,true);if(H){A.grab(H);}}return A;})||A.set("html",C);},success:function(D){var C=this.options,B=this.response;
+B.html=D.stripScripts(function(E){B.javascript=E;});var A=this.processHTML(B.html);B.tree=A.childNodes;B.elements=A.getElements("*");if(C.filter){B.tree=B.elements.filter(C.filter);
+}if(C.update){$(C.update).empty().adopt(B.tree);}if(C.evalScripts){$exec(B.javascript);}this.onSuccess(B.tree,B.elements,B.html,B.javascript);}});Element.Properties.load={set:function(A){var B=this.retrieve("load");
+if(B){send.cancel();}return this.eliminate("load").store("load:options",$extend({data:this,link:"cancel",update:this,method:"get"},A));},get:function(A){if(A||!this.retrieve("load")){if(A||!this.retrieve("load:options")){this.set("load",A);
+}this.store("load",new Request.HTML(this.retrieve("load:options")));}return this.retrieve("load");}};Element.implement({load:function(){this.get("load").send(Array.link(arguments,{data:Object.type,url:String.type}));
+return this;}});Request.JSON=new Class({Extends:Request,options:{secure:true},initialize:function(A){this.parent(A);this.headers.extend({Accept:"application/json","X-Request":"JSON"});
+},success:function(A){this.response.json=JSON.decode(A,this.options.secure);this.onSuccess(this.response.json,A);}});
diff --git a/src/medsrv/templates/static/script.js b/src/medsrv/templates/static/script.js
new file mode 100644
index 000000000..f2ab1e009
--- /dev/null
+++ b/src/medsrv/templates/static/script.js
@@ -0,0 +1,13 @@
+window.addEvent('domready', function() {
+ $$('.focus').each(function(e){e.focus();});
+ $$('table.list tr:nth-child(2n) td').each(function(e){e.set('class', 'even');});
+ $$('table.list tr:nth-child(2n+1) td').each(function(e){e.set('class', 'odd');});
+ $$('table.list tr th').each(function(e){e.set('class', 'head');});
+ $$('table.list tr td').each(function(e){e.addEvents({
+ 'click': function(){
+ location.href = this.getChildren('a')[0].get('href');
+ }
+ })});
+});
+
+
diff --git a/src/medsrv/templates/static/strongswan.png b/src/medsrv/templates/static/strongswan.png
new file mode 100755
index 000000000..869188cdf
--- /dev/null
+++ b/src/medsrv/templates/static/strongswan.png
Binary files differ
diff --git a/src/medsrv/templates/static/style.css b/src/medsrv/templates/static/style.css
new file mode 100755
index 000000000..e109ce278
--- /dev/null
+++ b/src/medsrv/templates/static/style.css
@@ -0,0 +1,132 @@
+
+body {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ color: #230100;
+ background-color: #f7f4d3;
+ margin: 0;
+}
+
+.content {
+}
+
+.content > * {
+ background-color: #e5bf5e;
+ border: solid 2px;
+ padding: 1em 1em 1em 1em;
+ margin: 1em;
+ text-align: left;
+}
+
+textarea, select, input {
+ background-color: #ffec9e;
+ border: 1px solid;
+ padding: 1px 3px 1px 3px;
+}
+
+table.user input[type="text"], table.user input[type="password"] {
+ width: 15em;
+}
+
+table.peer textarea {
+ height: 20em;
+ width: 42.3em;
+
+}
+
+table.peer input[type="text"] {
+ width: 38em;
+}
+
+.menu {
+ text-align: right;
+ background-color: #e5bf5e;
+ padding: 3px;
+ border-bottom: solid 2px;
+}
+
+a {
+ color: black;
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+h1 {
+ margin-top: 1.5em;
+ font-size: 2.1em;
+ white-space: nowrap;
+}
+
+hr {
+ border: solid 1px;
+}
+
+a img {
+ border: none;
+}
+
+.center {
+ text-align: center;
+}
+
+.left {
+ text-align: left;
+}
+
+.right {
+ text-align: right;
+}
+
+.fleft {
+ margin-right: 2em;
+ float: left;
+}
+
+.fright {
+ float: left;
+}
+
+.cleft {
+ clear:left;
+}
+
+.cright {
+ clear:right;
+}
+
+.both {
+ clear:both;
+}
+
+.error {
+ color: #dd0000;
+}
+
+.even {
+ cursor : pointer;
+}
+
+.even a, .odd a {
+ text-decoration: none;
+}
+
+.odd {
+ background-color: #f2cd6f;
+ cursor : pointer;
+}
+
+.head {
+ background-color: #ffec9e;
+}
+
+table.list * {
+ padding: 0px 1em 0px 0.2em;
+}
+
+table.list tr td, table.list tr th {
+ border: solid 1px;
+ border-color: black;
+}
+
diff --git a/src/medsrv/templates/user/add.cs b/src/medsrv/templates/user/add.cs
new file mode 100755
index 000000000..8ba4e5c96
--- /dev/null
+++ b/src/medsrv/templates/user/add.cs
@@ -0,0 +1,28 @@
+<?cs include:"templates/header.cs" ?>
+<form method="post">
+<?cs if:?error ?>
+ <div class="error"><?cs var:error ?></div>
+<?cs /if ?>
+ <table class="user">
+ <tr>
+ <td><label for="new_login">Username</label></td>
+ <td><input type="text" id="new_login" name="new_login" class="focus" maxlength="30" value="<?cs var:new_login ?>"/></td>
+ </tr>
+ <tr>
+ <td><label for="new_password">Password</label></td>
+ <td><input type="password" id="new_password" name="new_password"/></td>
+ <td><small>min. <?cs var:password_length ?> characters</small></td>
+ </tr>
+ <tr>
+ <td><label for="confirm_password">Confirm password</label></td>
+ <td><input type="password" id="confirm_password" name="confirm_password"/></td>
+ </tr>
+ <tr>
+ <td/>
+ <td class="right">
+ <input type="submit" value="Register" name="register"/>
+ </td>
+ </tr>
+</table>
+</form>
+<?cs include:"templates/footer.cs" ?>
diff --git a/src/medsrv/templates/user/edit.cs b/src/medsrv/templates/user/edit.cs
new file mode 100755
index 000000000..1f168498b
--- /dev/null
+++ b/src/medsrv/templates/user/edit.cs
@@ -0,0 +1,35 @@
+<?cs include:"templates/header.cs" ?>
+<form method="post">
+<?cs if:?error ?>
+ <div class="error"><?cs var:error ?></div>
+<?cs /if ?>
+ <table class="user">
+ <tr>
+ <td><label for="old_login">Username</label></td>
+ <td><input type="text" id="old_login" name="old_login" maxlength="30" value="<?cs var:old_login ?>" /></td>
+ </tr>
+ <tr>
+ <td><label for="old_password">Old password</label></td>
+ <td><input type="password" id="old_password" name="old_password"/></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><label for="new_password">New password</label></td>
+ <td><input type="password" id="new_password" name="new_password"/></td>
+ <td><small>min. <?cs var:password_length ?> characters</small></td>
+ </tr>
+ <tr>
+ <td><label for="confirm_password">Confirm new password</label></td>
+ <td><input type="password" id="confirm_password" name="confirm_password"/></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="right">
+ <input type="submit" value="Back" name="back"/>
+ <input type="submit" value="Delete" name="delete" onclick="return confirm('Permanently delete your account?')"/>
+ <input type="submit" value="Save" name="save"/>
+ </td>
+ </tr>
+ </table>
+</form>
+<?cs include:"templates/footer.cs" ?>
diff --git a/src/medsrv/templates/user/help.cs b/src/medsrv/templates/user/help.cs
new file mode 100644
index 000000000..58615c14a
--- /dev/null
+++ b/src/medsrv/templates/user/help.cs
@@ -0,0 +1,34 @@
+<?cs include:"templates/header.cs" ?>
+<div>
+<h3>strongSwan Mediation Service web frontend</h3>
+<p>This web application builds the end user front end for a Mediation Service
+as defined in the <i>
+<a href="http://www.ietf.org/internet-drafts/draft-brunner-ikev2-mediation-00.txt">
+IKEv2 Mediation Extension draft</a></i>.</p>
+<h4>Mediation connection</h4>
+<p>The authentication between Mediation Server and connecting clients is based
+on RSA public keys. The identities used for IKEv2 are the public key identifier
+of each clients key, encapsulated in a ID_KEY_ID identity.</p>
+<p>The public key of this Mediation Server is:</p>
+<pre>-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzZRsIp99UrIdoctThOfc
+r2Up92BTSlY1Xv1J6Hqcbx3dX/MDvX60nCPeA63Eh0VvQetfkpR73I/42+RD+NES
+4NosmBRefE0c0Vzd0IV39NTz0KLh2jwIyUzYGXWHUZMeepckzEPXOhG44XaiaLTN
+u/OZXLCXI6vJv8R3wl5xSkZhqEwHi+dATYmGvlXyBDfjprJ4o8yJrsCFlB8aGq+v
+SyKuFG/kaE1VZ9wwZYoyCH0BuYUVBwyxZTMRy2EC+CqDxjjCp5mF27lgB1Lpy8Jy
+AUpcVHtKtZEww6lIZYv/eUtvICz5WTn/pzsQUh8FwGDOyxX4WX7ZXXK55AXuMfG1
+2QIDAQAB
+-----END PUBLIC KEY-----</pre>
+<p>The Mediation Server is reachable at <i>mediation.strongswan.org</i>.</p>
+The mediation server allows connections from all registered peers.</p>
+<h4>Mediated connections</h4>
+<p>The authentication between mediated clients is done between clients, they
+can use own keys or the same keys as defined for authentication of the
+mediation connection.
+<form action="<?cs var:base ?>/peer/list" method="get">
+ <div class="right">
+ <input type="submit" value="Back"/></td>
+ </div>
+</form>
+</div>
+<?cs include:"templates/footer.cs" ?>
diff --git a/src/medsrv/templates/user/login.cs b/src/medsrv/templates/user/login.cs
new file mode 100755
index 000000000..1d6eadbbc
--- /dev/null
+++ b/src/medsrv/templates/user/login.cs
@@ -0,0 +1,23 @@
+<?cs include:"templates/header.cs" ?>
+<form method="post">
+<?cs if:?error ?>
+ <div class="error"><?cs var:error ?></div>
+<?cs /if ?>
+ <table class="user">
+ <tr>
+ <td><label for="login">Username</label></td>
+ <td><input type="text" id="login" name="login" size="30" maxlength="30" class="focus"/></td>
+ </tr>
+ <tr>
+ <td><label for="password">Password</label></td>
+ <td><input type="password" id="password" name="password" size="30"/></td>
+ </tr>
+ <tr>
+ <td/>
+ <td class="right">
+ <input type="submit" value="Login" name="submit"/>
+ </td>
+ </tr>
+</table>
+</form>
+<?cs include:"templates/footer.cs" ?>
diff --git a/src/medsrv/user.c b/src/medsrv/user.c
new file mode 100644
index 000000000..032859e2e
--- /dev/null
+++ b/src/medsrv/user.c
@@ -0,0 +1,77 @@
+/*
+ * 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 "user.h"
+
+typedef struct private_user_t private_user_t;
+
+/**
+ * private data of user
+ */
+struct private_user_t {
+
+ /**
+ * public functions
+ */
+ user_t public;
+
+ /**
+ * user id, if we are logged in; otherwise 0
+ */
+ u_int user;
+};
+
+/**
+ * Implementation of user_t.set_user
+ */
+static void set_user(private_user_t *this, u_int id)
+{
+ this->user = id;
+}
+
+/**
+ * Implementation of user_t.get_user
+ */
+static u_int get_user(private_user_t *this)
+{
+ return this->user;
+}
+
+/**
+ * Implementation of context_t.destroy
+ */
+static void destroy(private_user_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+user_t *user_create(void *param)
+{
+ private_user_t *this= malloc_thing(private_user_t);
+
+ this->public.set_user = (void(*)(user_t*,u_int id))set_user;
+ this->public.get_user = (u_int(*)(user_t*))get_user;
+ this->public.context.destroy = (void(*)(context_t*))destroy;
+
+ this->user = 0;
+
+ return &this->public;
+}
+
diff --git a/src/medsrv/user.h b/src/medsrv/user.h
new file mode 100644
index 000000000..b411f7c6f
--- /dev/null
+++ b/src/medsrv/user.h
@@ -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$
+ */
+
+#ifndef USER_H_
+#define USER_H_
+
+#include <context.h>
+#include <library.h>
+
+typedef struct user_t user_t;
+
+/**
+ * Per session context. Contains user user state and data.
+ */
+struct user_t {
+
+ /**
+ * implements context_t interface
+ */
+ context_t context;
+
+ /**
+ * Set the user ID of the logged in user.
+ */
+ void (*set_user)(user_t *this, u_int id);
+
+ /**
+ * Get the user ID of the logged in user.
+ */
+ u_int (*get_user)(user_t *this);
+};
+
+/**
+ * Create a user instance.
+ */
+user_t *user_create(void *param);
+
+#endif /* USER_H_ @} */
diff --git a/src/openac/Makefile.am b/src/openac/Makefile.am
index 4b88d8b2d..005486779 100644
--- a/src/openac/Makefile.am
+++ b/src/openac/Makefile.am
@@ -1,8 +1,12 @@
ipsec_PROGRAMS = openac
-openac_SOURCES = openac.c build.c build.h
+openac_SOURCES = openac.c
dist_man_MANS = openac.8
INCLUDES = -I$(top_srcdir)/src/libstrongswan
-AM_CFLAGS = -DIPSEC_CONFDIR=\"${confdir}\"
+AM_CFLAGS = \
+ -DIPSEC_CONFDIR=\"${confdir}\" \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\" \
+ -DPLUGINS=\""${libstrongswan_plugins}\""
openac_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lgmp
diff --git a/src/openac/Makefile.in b/src/openac/Makefile.in
index 3cca270a7..00977e038 100644
--- a/src/openac/Makefile.in
+++ b/src/openac/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.
@@ -45,7 +45,7 @@ CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"
ipsecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(ipsec_PROGRAMS)
-am_openac_OBJECTS = openac.$(OBJEXT) build.$(OBJEXT)
+am_openac_OBJECTS = openac.$(OBJEXT)
openac_OBJECTS = $(am_openac_OBJECTS)
openac_DEPENDENCIES = \
$(top_builddir)/src/libstrongswan/libstrongswan.la
@@ -88,6 +88,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -117,6 +118,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -147,7 +149,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@
@@ -158,12 +159,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@
@@ -173,12 +173,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@
@@ -191,20 +191,27 @@ 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@
-openac_SOURCES = openac.c build.c build.h
+openac_SOURCES = openac.c
dist_man_MANS = openac.8
INCLUDES = -I$(top_srcdir)/src/libstrongswan
-AM_CFLAGS = -DIPSEC_CONFDIR=\"${confdir}\"
+AM_CFLAGS = \
+ -DIPSEC_CONFDIR=\"${confdir}\" \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\" \
+ -DPLUGINS=\""${libstrongswan_plugins}\""
+
openac_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lgmp
all: all-am
@@ -248,8 +255,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
@@ -277,7 +284,6 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/build.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openac.Po@am__quote@
.c.o:
@@ -357,8 +363,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -370,8 +376,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -381,13 +387,12 @@ ctags: CTAGS
CTAGS: $(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
diff --git a/src/openac/build.c b/src/openac/build.c
deleted file mode 100644
index 40c8b7964..000000000
--- a/src/openac/build.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* Build a X.509 attribute certificate
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2004,2007 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT 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: build.c 3424 2008-01-22 10:34:44Z andreas $
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <asn1/oid.h>
-#include <asn1/asn1.h>
-#include <crypto/ietf_attr_list.h>
-#include <utils/identification.h>
-
-#include "build.h"
-
-static u_char ASN1_group_oid_str[] = {
- 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
-};
-
-static const chunk_t ASN1_group_oid = chunk_from_buf(ASN1_group_oid_str);
-
-static u_char ASN1_authorityKeyIdentifier_oid_str[] = {
- 0x06, 0x03,
- 0x55, 0x1d, 0x23
-};
-
-static const chunk_t ASN1_authorityKeyIdentifier_oid =
- chunk_from_buf(ASN1_authorityKeyIdentifier_oid_str);
-
-static u_char ASN1_noRevAvail_ext_str[] = {
- 0x30, 0x09,
- 0x06, 0x03,
- 0x55, 0x1d, 0x38,
- 0x04, 0x02,
- 0x05, 0x00
-};
-
-static const chunk_t ASN1_noRevAvail_ext = chunk_from_buf(ASN1_noRevAvail_ext_str);
-
-/**
- * build directoryName
- */
-static chunk_t build_directoryName(asn1_t tag, chunk_t name)
-{
- return asn1_wrap(tag, "m",
- asn1_simple_object(ASN1_CONTEXT_C_4, name));
-}
-
-/**
- * build holder
- */
-static chunk_t build_holder(void)
-{
- identification_t *issuer = usercert->get_issuer(usercert);
- identification_t *subject = usercert->get_subject(usercert);
-
- return asn1_wrap(ASN1_SEQUENCE, "mm",
- asn1_wrap(ASN1_CONTEXT_C_0, "mm",
- build_directoryName(ASN1_SEQUENCE, issuer->get_encoding(issuer)),
- asn1_simple_object(ASN1_INTEGER, usercert->get_serialNumber(usercert))
- ),
- build_directoryName(ASN1_CONTEXT_C_1, subject->get_encoding(subject)));
-}
-
-/**
- * build v2Form
- */
-static chunk_t build_v2_form(void)
-{
- identification_t *subject = signercert->get_subject(signercert);
-
- return asn1_wrap(ASN1_CONTEXT_C_0, "m",
- build_directoryName(ASN1_SEQUENCE, subject->get_encoding(subject)));
-}
-
-/**
- * build attrCertValidityPeriod
- */
-static chunk_t build_attr_cert_validity(void)
-{
- return asn1_wrap(ASN1_SEQUENCE, "mm",
- timetoasn1(&notBefore, ASN1_GENERALIZEDTIME),
- timetoasn1(&notAfter, ASN1_GENERALIZEDTIME));
-}
-
-
-/**
- * build attribute type
- */
-static chunk_t build_attribute_type(const chunk_t type, chunk_t content)
-{
- return asn1_wrap(ASN1_SEQUENCE, "cm",
- type,
- asn1_wrap(ASN1_SET, "m", content));
-}
-
-/**
- * build attributes
- */
-static chunk_t build_attributes(void)
-{
- return asn1_wrap(ASN1_SEQUENCE, "m",
- build_attribute_type(ASN1_group_oid, ietfAttr_list_encode(groups)));
-}
-
-/**
- * build authorityKeyIdentifier
- */
-static chunk_t build_authorityKeyID(x509_t *signer)
-{
- identification_t *issuer = signer->get_issuer(signer);
- chunk_t subjectKeyID = signer->get_subjectKeyID(signer);
-
- chunk_t keyIdentifier = (subjectKeyID.ptr == NULL)
- ? chunk_empty
- : asn1_simple_object(ASN1_CONTEXT_S_0, subjectKeyID);
-
- chunk_t authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1,
- issuer->get_encoding(issuer));
-
- chunk_t authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2,
- signer->get_serialNumber(signer));
-
- return asn1_wrap(ASN1_SEQUENCE, "cm",
- ASN1_authorityKeyIdentifier_oid,
- asn1_wrap(ASN1_OCTET_STRING, "m",
- asn1_wrap(ASN1_SEQUENCE, "mmm",
- keyIdentifier,
- authorityCertIssuer,
- authorityCertSerialNumber
- )
- )
- );
-}
-
-/**
- * build extensions
- */
-static chunk_t build_extensions(void)
-{
- return asn1_wrap(ASN1_SEQUENCE, "mc",
- build_authorityKeyID(signercert),
- ASN1_noRevAvail_ext);
-}
-
-/**
- * build attributeCertificateInfo
- */
-static chunk_t build_attr_cert_info(void)
-{
- return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
- ASN1_INTEGER_1,
- build_holder(),
- build_v2_form(),
- asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
- asn1_simple_object(ASN1_INTEGER, serial),
- build_attr_cert_validity(),
- build_attributes(),
- build_extensions());
-}
-
-
-/**
- * build an X.509 attribute certificate
- */
-chunk_t build_attr_cert(void)
-{
- chunk_t signatureValue;
- chunk_t attributeCertificateInfo = build_attr_cert_info();
-
- signerkey->build_emsa_pkcs1_signature(signerkey, HASH_SHA1,
- attributeCertificateInfo, &signatureValue);
-
- return asn1_wrap(ASN1_SEQUENCE, "mcm",
- attributeCertificateInfo,
- asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
- asn1_bitstring("m", signatureValue));
-}
diff --git a/src/openac/build.h b/src/openac/build.h
deleted file mode 100644
index c873c4479..000000000
--- a/src/openac/build.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Build a X.509 attribute certificate
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2004,2007 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT 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: build.h 3270 2007-10-08 20:09:57Z andreas $
- */
-
-#ifndef _BUILD_H
-#define _BUILD_H
-
-#include <time.h>
-
-#include <library.h>
-#include <crypto/x509.h>
-#include <crypto/rsa/rsa_private_key.h>
-#include <utils/linked_list.h>
-
-/*
- * global variables accessible by both main() and build.c
- */
-extern x509_t *usercert;
-extern x509_t *signercert;
-extern rsa_private_key_t *signerkey;
-extern linked_list_t *groups;
-extern time_t notBefore;
-extern time_t notAfter;
-extern chunk_t serial;
-
-/*
- * exported functions
- */
-extern chunk_t build_attr_cert(void);
-
-#endif /* _BUILD_H */
diff --git a/src/openac/openac.c b/src/openac/openac.c
index 3d82940c2..48dc57ece 100755
--- a/src/openac/openac.c
+++ b/src/openac/openac.c
@@ -20,7 +20,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: openac.c 3442 2008-02-04 14:46:43Z andreas $
+ * RCSID $Id: openac.c 3967 2008-05-16 08:52:32Z martin $
*/
#include <stdio.h>
@@ -33,11 +33,12 @@
#include <time.h>
#include <gmp.h>
+#include <library.h>
#include <debug.h>
#include <asn1/asn1.h>
-#include <asn1/ttodata.h>
-#include <crypto/ac.h>
-#include <crypto/ietf_attr_list.h>
+#include <asn1/pem.h>
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/ac.h>
#include <utils/optionsfrom.h>
#ifdef INTEGRITY_TEST
@@ -45,10 +46,10 @@
#include <fips_signature.h>
#endif /* INTEGRITY_TEST */
-#include "build.h"
+#define OPENAC_PATH IPSEC_CONFDIR "/openac"
+#define OPENAC_SERIAL IPSEC_CONFDIR "/openac/serial"
-#define OPENAC_PATH IPSEC_CONFDIR "/openac"
-#define OPENAC_SERIAL IPSEC_CONFDIR "/openac/serial"
+#define DEFAULT_VALIDITY 24*3600 /* seconds */
/**
* @brief prints the usage of the program to the stderr
@@ -113,7 +114,8 @@ static chunk_t read_serial(void)
mpz_t number;
char buf[BUF_LEN], buf1[BUF_LEN];
- chunk_t last_serial = { buf1, BUF_LEN};
+ chunk_t hex_serial = { buf, BUF_LEN };
+ chunk_t last_serial = { buf1, BUF_LEN };
chunk_t serial;
FILE *fd = fopen(OPENAC_SERIAL, "r");
@@ -124,15 +126,10 @@ static chunk_t read_serial(void)
if (fd)
{
- if (fscanf(fd, "%s", buf))
+ if (fscanf(fd, "%s", hex_serial.ptr))
{
- err_t ugh = ttodata(buf, 0, 16, last_serial.ptr, BUF_LEN, &last_serial.len);
-
- if (ugh != NULL)
- {
- DBG1(" error reading serial number from %s: %s",
- OPENAC_SERIAL, ugh);
- }
+ hex_serial.len = strlen(hex_serial.ptr);
+ last_serial = chunk_from_hex(hex_serial, last_serial.ptr);
}
fclose(fd);
}
@@ -164,9 +161,13 @@ static void write_serial(chunk_t serial)
if (fd)
{
+ chunk_t hex_serial;
+
DBG1(" serial number is %#B", &serial);
- fprintf(fd, "%#B\n", &serial);
+ hex_serial = chunk_to_hex(serial, NULL, FALSE);
+ fprintf(fd, "%.*s\n", hex_serial.len, hex_serial.ptr);
fclose(fd);
+ free(hex_serial.ptr);
}
else
{
@@ -175,18 +176,33 @@ static void write_serial(chunk_t serial)
}
/**
- * global variables accessible by both main() and build.c
+ * Load and parse a private key file
*/
-x509_t *usercert = NULL;
-x509_t *signercert = NULL;
-
-linked_list_t *groups = NULL;
-rsa_private_key_t *signerkey = NULL;
+static private_key_t* private_key_create_from_file(char *path, chunk_t *secret)
+{
+ bool pgp = FALSE;
+ chunk_t chunk = chunk_empty;
+ private_key_t *key = NULL;
-time_t notBefore = UNDEFINED_TIME;
-time_t notAfter = UNDEFINED_TIME;
+ if (!pem_asn1_load_file(path, secret, &chunk, &pgp))
+ {
+ DBG1(" could not load private key file '%s'", path);
+ return NULL;
+ }
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+ if (key == NULL)
+ {
+ DBG1(" could not parse loaded private key file '%s'", path);
+ return NULL;
+ }
+ DBG1(" loaded private key file '%s'", path);
+ return key;
+}
-chunk_t serial;
+/**
+ * global variables accessible by both main() and build.c
+ */
static int debug_level = 1;
static bool stderr_quiet = FALSE;
@@ -220,30 +236,43 @@ static void openac_dbg(int level, char *fmt, ...)
*/
int main(int argc, char **argv)
{
+ certificate_t *attr_cert = NULL;
+ certificate_t *userCert = NULL;
+ certificate_t *signerCert = NULL;
+ private_key_t *signerKey = NULL;
+
+ time_t notBefore = UNDEFINED_TIME;
+ time_t notAfter = UNDEFINED_TIME;
+ time_t validity = 0;
+
char *keyfile = NULL;
char *certfile = NULL;
char *usercertfile = NULL;
char *outfile = NULL;
+ char *groups = "";
char buf[BUF_LEN];
chunk_t passphrase = { buf, 0 };
- chunk_t attr_cert = chunk_empty;
- x509ac_t *ac = NULL;
+ chunk_t serial = chunk_empty;
+ chunk_t attr_chunk = chunk_empty;
- const time_t default_validity = 24*3600; /* 24 hours */
- time_t validity = 0;
int status = 1;
- options_t *options = options_create();
-
/* enable openac debugging hook */
dbg = openac_dbg;
passphrase.ptr[0] = '\0';
- groups = linked_list_create();
openlog("openac", 0, LOG_AUTHPRIV);
+ /* initialize library */
+ library_init(STRONGSWAN_CONF);
+ lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
+ lib->settings->get_str(lib->settings, "openac.load", PLUGINS));
+
+ /* initialize optionsfrom */
+ options_t *options = options_create();
+
/* handle arguments */
for (;;)
{
@@ -337,7 +366,7 @@ int main(int argc, char **argv)
continue;
case 'g': /* --groups */
- ietfAttr_list_create_from_string(optarg, groups);
+ groups = optarg;
continue;
case 'D': /* --days */
@@ -390,7 +419,7 @@ int main(int argc, char **argv)
{
chunk_t date = { optarg, 15 };
- notBefore = asn1totime(&date, ASN1_GENERALIZEDTIME);
+ notBefore = asn1_to_time(&date, ASN1_GENERALIZEDTIME);
}
continue;
@@ -403,7 +432,7 @@ int main(int argc, char **argv)
else
{
chunk_t date = { optarg, 15 };
- notAfter = asn1totime(&date, ASN1_GENERALIZEDTIME);
+ notAfter = asn1_to_time(&date, ASN1_GENERALIZEDTIME);
}
continue;
@@ -449,9 +478,9 @@ int main(int argc, char **argv)
/* load the signer's RSA private key */
if (keyfile != NULL)
{
- signerkey = rsa_private_key_create_from_file(keyfile, &passphrase);
+ signerKey = private_key_create_from_file(keyfile, &passphrase);
- if (signerkey == NULL)
+ if (signerKey == NULL)
{
goto end;
}
@@ -460,9 +489,12 @@ int main(int argc, char **argv)
/* load the signer's X.509 certificate */
if (certfile != NULL)
{
- signercert = x509_create_from_file(certfile, "signer cert");
-
- if (signercert == NULL)
+ signerCert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, certfile,
+ BUILD_X509_FLAG, 0,
+ BUILD_END);
+ if (signerCert == NULL)
{
goto end;
}
@@ -471,46 +503,69 @@ int main(int argc, char **argv)
/* load the users's X.509 certificate */
if (usercertfile != NULL)
{
- usercert = x509_create_from_file(usercertfile, "user cert");
-
- if (usercert == NULL)
+ userCert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, usercertfile,
+ BUILD_X509_FLAG, 0,
+ BUILD_END);
+ if (userCert == NULL)
{
goto end;
}
}
/* compute validity interval */
- validity = (validity)? validity : default_validity;
+ validity = (validity)? validity : DEFAULT_VALIDITY;
notBefore = (notBefore == UNDEFINED_TIME) ? time(NULL) : notBefore;
notAfter = (notAfter == UNDEFINED_TIME) ? time(NULL) + validity : notAfter;
/* build and parse attribute certificate */
- if (usercert != NULL && signercert != NULL && signerkey != NULL)
+ if (userCert != NULL && signerCert != NULL && signerKey != NULL)
{
/* read the serial number and increment it by one */
serial = read_serial();
- attr_cert = build_attr_cert();
- ac = x509ac_create_from_chunk(attr_cert);
+ attr_cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509_AC,
+ BUILD_CERT, userCert->get_ref(userCert),
+ BUILD_NOT_BEFORE_TIME, notBefore,
+ BUILD_NOT_AFTER_TIME, notAfter,
+ BUILD_SERIAL, serial,
+ BUILD_IETF_GROUP_ATTR, groups,
+ BUILD_SIGNING_CERT, signerCert->get_ref(signerCert),
+ BUILD_SIGNING_KEY, signerKey->get_ref(signerKey),
+ BUILD_END);
+ if (!attr_cert)
+ {
+ goto end;
+ }
/* write the attribute certificate to file */
- if (chunk_write(attr_cert, outfile, "attribute cert", 0022, TRUE))
+ attr_chunk = attr_cert->get_encoding(attr_cert);
+ if (chunk_write(attr_chunk, outfile, 0022, TRUE))
{
+ DBG1(" wrote attribute cert file '%s' (%u bytes)", outfile, attr_chunk.len);
write_serial(serial);
status = 0;
}
}
+ else
+ {
+ usage("some of the mandatory parameters --usercert --cert --key "
+ "are missing");
+ }
end:
/* delete all dynamically allocated objects */
- DESTROY_IF(signerkey);
- DESTROY_IF(signercert);
- DESTROY_IF(usercert);
- DESTROY_IF(ac);
- ietfAttr_list_destroy(groups);
+ DESTROY_IF(signerKey);
+ DESTROY_IF(signerCert);
+ DESTROY_IF(userCert);
+ DESTROY_IF(attr_cert);
+ free(attr_chunk.ptr);
free(serial.ptr);
closelog();
dbg = dbg_default;
options->destroy(options);
+ library_deinit();
exit(status);
}
diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am
index 69902ad8f..156b81018 100644
--- a/src/pluto/Makefile.am
+++ b/src/pluto/Makefile.am
@@ -123,12 +123,19 @@ if USE_NAT_TRANSPORT
endif
# This compile option activates dynamic URL fetching using libcurl
-if USE_LIBCURL
+if USE_CURL
pluto_LDADD += -lcurl
+ AM_CFLAGS += -DLIBCURL
endif
# This compile option activates dynamic LDAP CRL fetching
-if USE_LIBLDAP
+if USE_LDAP
pluto_LDADD += -lldap -llber
+ AM_CFLAGS += -DLIBLDAP
+endif
+
+# This compile option activates smartcard support
+if USE_SMARTCARD
+ AM_CFLAGS += -DSMARTCARD
endif
diff --git a/src/pluto/Makefile.in b/src/pluto/Makefile.in
index a9ae01d65..42017641c 100644
--- a/src/pluto/Makefile.in
+++ b/src/pluto/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.
@@ -51,10 +51,15 @@ ipsec_PROGRAMS = pluto$(EXEEXT) _pluto_adns$(EXEEXT)
@USE_NAT_TRANSPORT_TRUE@am__append_4 = -DI_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
# This compile option activates dynamic URL fetching using libcurl
-@USE_LIBCURL_TRUE@am__append_5 = -lcurl
+@USE_CURL_TRUE@am__append_5 = -lcurl
+@USE_CURL_TRUE@am__append_6 = -DLIBCURL
# This compile option activates dynamic LDAP CRL fetching
-@USE_LIBLDAP_TRUE@am__append_6 = -lldap -llber
+@USE_LDAP_TRUE@am__append_7 = -lldap -llber
+@USE_LDAP_TRUE@am__append_8 = -DLIBLDAP
+
+# This compile option activates smartcard support
+@USE_SMARTCARD_TRUE@am__append_9 = -DSMARTCARD
subdir = src/pluto
DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in TODO
@@ -138,6 +143,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -167,6 +173,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -197,7 +204,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@
@@ -208,12 +214,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@
@@ -223,12 +228,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@
@@ -241,10 +246,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@
@@ -328,10 +335,11 @@ AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_CONFDIR=\"${confdir}\" \
-DSHARED_SECRETS_FILE=\"${confdir}/ipsec.secrets\" \
-DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES -DPLUTO \
-DKLIPS -DDEBUG -DTHREADS $(am__append_1) $(am__append_2) \
- $(am__append_3) $(am__append_4)
+ $(am__append_3) $(am__append_4) $(am__append_6) \
+ $(am__append_8) $(am__append_9)
pluto_LDADD = oid.o $(LIBFREESWANDIR)/libfreeswan.a \
$(LIBCRYPTODIR)/libcrypto.a -lgmp -lresolv -lpthread -ldl \
- $(am__append_5) $(am__append_6)
+ $(am__append_5) $(am__append_7)
_pluto_adns_LDADD = \
$(LIBFREESWANDIR)/libfreeswan.a \
-lresolv -ldl
@@ -379,8 +387,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
@@ -681,8 +689,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -694,8 +702,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -705,13 +713,12 @@ ctags: CTAGS
CTAGS: $(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
diff --git a/src/pluto/ac.c b/src/pluto/ac.c
index 43ebf91d9..77e0b40bb 100644
--- a/src/pluto/ac.c
+++ b/src/pluto/ac.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: ac.c 3253 2007-10-06 21:39:00Z andreas $
+ * RCSID $Id: ac.c 3686 2008-03-28 11:48:14Z martin $
*/
#include <stdlib.h>
@@ -599,16 +599,6 @@ parse_ac(chunk_t blob, x509acert_t *ac)
}
/*
- * compare two X.509 attribute certificates by comparing their signatures
- */
-static bool
-same_x509acert(x509acert_t *a, x509acert_t *b)
-{
- return a->signature.len == b->signature.len &&
- memcmp(a->signature.ptr, b->signature.ptr, b->signature.len) == 0;
-}
-
-/*
* release an ietfAttribute, free it if count reaches zero
*/
static void
diff --git a/src/pluto/alg/ike_alg_aes.c b/src/pluto/alg/ike_alg_aes.c
index 44de09b4c..c635af723 100644
--- a/src/pluto/alg/ike_alg_aes.c
+++ b/src/pluto/alg/ike_alg_aes.c
@@ -34,7 +34,7 @@ do_aes(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *
memcpy(new_iv=iv_bak, (char*) buf + buf_len - AES_CBC_BLOCK_SIZE
, AES_CBC_BLOCK_SIZE);
- AES_cbc_encrypt(&aes_ctx, buf, buf, buf_len, iv, enc);
+ SS_AES_cbc_encrypt(&aes_ctx, buf, buf, buf_len, iv, enc);
if (enc)
new_iv = (char*) buf + buf_len-AES_CBC_BLOCK_SIZE;
diff --git a/src/pluto/alg_info.c b/src/pluto/alg_info.c
index 145e492d4..cd02d2358 100644
--- a/src/pluto/alg_info.c
+++ b/src/pluto/alg_info.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: alg_info.c 3253 2007-10-06 21:39:00Z andreas $
+ * RCSID $Id: alg_info.c 3846 2008-04-18 17:01:45Z andreas $
*/
#include <stddef.h>
@@ -96,8 +96,8 @@ alg_info_esp_sadb2aa(int sadb_aalg)
int auth = 0;
switch(sadb_aalg) {
- case SADB_AALG_MD5_HMAC:
- case SADB_AALG_SHA1_HMAC:
+ case SADB_AALG_MD5HMAC:
+ case SADB_AALG_SHA1HMAC:
auth = sadb_aalg - 1;
break;
/* since they are the same ... :) */
@@ -195,7 +195,11 @@ aalg_getbyname_esp(const char *const str, int len)
/* interpret 'SHA' as 'SHA1' */
if (strncasecmp("SHA", str, len) == 0)
- return enum_search(&auth_alg_names, "AUTH_ALGORITHM_HMAC_SHA1");
+ return AUTH_ALGORITHM_HMAC_SHA1;
+
+ /* interpret 'AESXCBC' as 'AES_XCBC_MAC' */
+ if (strncasecmp("AESXCBC", str, len) == 0)
+ return AUTH_ALGORITHM_AES_XCBC_MAC;
ret = enum_search_prefix(&auth_alg_names,"AUTH_ALGORITHM_HMAC_", str ,len);
if (ret >= 0)
diff --git a/src/pluto/connections.c b/src/pluto/connections.c
index 8fbf969b6..13a004794 100644
--- a/src/pluto/connections.c
+++ b/src/pluto/connections.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: connections.c 3361 2007-11-21 23:42:27Z andreas $
+ * RCSID $Id: connections.c 3686 2008-03-28 11:48:14Z martin $
*/
#include <string.h>
@@ -2354,7 +2354,7 @@ initiate_opportunistic_body(struct find_oppo_bundle *b
* DNS query (if any). It also selects the kind of the next step.
* The second chunk initiates the next DNS query (if any).
*/
- enum find_oppo_step next_step;
+ enum find_oppo_step next_step = fos_myid_ip_txt;
err_t ugh = ac_ugh;
char mycredentialstr[BUF_LEN];
char cib[CONN_INST_BUF];
@@ -3279,7 +3279,7 @@ refine_host_connection(const struct state *st, const struct id *peer_id
struct connection *d;
struct connection *best_found = NULL;
u_int16_t auth = st->st_oakley.auth;
- lset_t auth_policy;
+ lset_t auth_policy = POLICY_PSK;
const chunk_t *psk = NULL;
bool wcpip; /* wildcard Peer IP? */
int best_prio = PRIO_NO_MATCH_FOUND;
diff --git a/src/pluto/connections.h b/src/pluto/connections.h
index 3000f888a..b11565296 100644
--- a/src/pluto/connections.h
+++ b/src/pluto/connections.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: connections.h 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: connections.h 4024 2008-05-29 07:49:47Z andreas $
*/
#ifndef _CONNECTIONS_H
@@ -186,7 +186,7 @@ struct connection {
char *log_file_name; /* name of log file */
FILE *log_file; /* possibly open FILE */
- CIRCLEQ_ENTRY(connection) log_link; /* linked list of open conns */
+ TAILQ_ENTRY(connection) log_link; /* linked list of open conns */
bool log_file_err; /* only bitch once */
struct spd_route spd;
diff --git a/src/pluto/constants.c b/src/pluto/constants.c
index 93e430957..ca548afab 100644
--- a/src/pluto/constants.c
+++ b/src/pluto/constants.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: constants.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: constants.c 3839 2008-04-18 11:25:37Z andreas $
*/
/*
@@ -377,11 +377,13 @@ static const char *const ah_transform_name[] = {
"AH_SHA2_256",
"AH_SHA2_384",
"AH_SHA2_512",
- "AH_RIPEMD"
+ "AH_RIPEMD",
+ "AH_AES_XCBC_MAC",
+ "AH_RSA"
};
enum_names ah_transformid_names =
- { AH_MD5, AH_RIPEMD, ah_transform_name, NULL };
+ { AH_MD5, AH_RSA, ah_transform_name, NULL };
/* IPsec ESP transform values */
@@ -401,7 +403,13 @@ static const char *const esp_transform_name[] = {
"ESP_AES-CTR",
"ESP_AES-CCM_8",
"ESP_AES-CCM_12",
- "ESP_AES-CCM_16"
+ "ESP_AES-CCM_16",
+ "ESP_UNASSIGNED_17",
+ "ESP_AES_GCM_8",
+ "ESP_AES_GCM_12",
+ "ESP_AES_GCM_16",
+ "ESP_SEED_CBC",
+ "ESP_CAMELLIA"
};
/*
@@ -417,7 +425,7 @@ enum_names esp_transformid_names_high =
{ ESP_SERPENT, ESP_TWOFISH, esp_transform_name_high, NULL };
enum_names esp_transformid_names =
- { ESP_DES_IV64, ESP_AES_CCM_16, esp_transform_name, &esp_transformid_names_high };
+ { ESP_DES_IV64, ESP_CAMELLIA, esp_transform_name, &esp_transformid_names_high };
/* IPCOMP transform values */
@@ -684,6 +692,8 @@ static const char *const auth_alg_name[] = {
"AUTH_ALGORITHM_HMAC_SHA2_384",
"AUTH_ALGORITHM_HMAC_SHA2_512",
"AUTH_ALGORITHM_HMAC_RIPEMD",
+ "AUTH_ALGORITHM_AES_XCBC_MAC",
+ "AUTH_ALGORITHM_SIG_RSA"
};
static const char *const extended_auth_alg_name[] = {
@@ -694,7 +704,7 @@ enum_names extended_auth_alg_names =
{ AUTH_ALGORITHM_NULL, AUTH_ALGORITHM_NULL, extended_auth_alg_name, NULL };
enum_names auth_alg_names =
- { AUTH_ALGORITHM_HMAC_MD5, AUTH_ALGORITHM_HMAC_RIPEMD, auth_alg_name
+ { AUTH_ALGORITHM_HMAC_MD5, AUTH_ALGORITHM_SIG_RSA, auth_alg_name
, &extended_auth_alg_names };
/* From draft-beaulieu-ike-xauth */
diff --git a/src/pluto/constants.h b/src/pluto/constants.h
index ddfe76293..e6357164f 100644
--- a/src/pluto/constants.h
+++ b/src/pluto/constants.h
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: constants.h 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: constants.h 4051 2008-06-10 09:08:27Z tobias $
*/
#ifndef _CONSTANTS_H
@@ -877,6 +877,7 @@ extern const char *prettypolicy(lset_t policy);
#define POLICY_BEET LELEM(22) /* bound end2end tunnel, IKEv2 */
#define POLICY_MOBIKE LELEM(23) /* enable MOBIKE for IKEv2 */
#define POLICY_FORCE_ENCAP LELEM(24) /* force UDP encapsulation (IKEv2) */
+#define POLICY_ECDSASIG LELEM(25) /* ecdsa signature (IKEv2) */
/* Any IPsec policy? If not, a connection description
* is only for ISAKMP SA, not IPSEC SA. (A pun, I admit.)
@@ -992,6 +993,8 @@ extern enum_names auth_alg_names, extended_auth_alg_names;
#define AUTH_ALGORITHM_HMAC_SHA2_384 6
#define AUTH_ALGORITHM_HMAC_SHA2_512 7
#define AUTH_ALGORITHM_HMAC_RIPEMD 8
+#define AUTH_ALGORITHM_AES_XCBC_MAC 9
+#define AUTH_ALGORITHM_SIG_RSA 10
#define AUTH_ALGORITHM_NULL 251
/* Oakley Lifetime Type attribute
diff --git a/src/pluto/crl.c b/src/pluto/crl.c
index 8998207c2..6e1093661 100644
--- a/src/pluto/crl.c
+++ b/src/pluto/crl.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: crl.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: crl.c 3686 2008-03-28 11:48:14Z martin $
*/
#include <stdlib.h>
@@ -406,7 +406,7 @@ parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
asn1_ctx_t ctx;
bool critical;
chunk_t extnID;
- chunk_t userCertificate;
+ chunk_t userCertificate = empty_chunk;
chunk_t object;
u_int level;
int objectID = 0;
diff --git a/src/pluto/demux.c b/src/pluto/demux.c
index 9bc889b4b..04728a4a8 100644
--- a/src/pluto/demux.c
+++ b/src/pluto/demux.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: demux.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: demux.c 3686 2008-03-28 11:48:14Z martin $
*/
/* Ordering Constraints on Payloads
@@ -2167,7 +2167,7 @@ complete_state_transition(struct msg_digest **mdp, stf_status result)
/* Schedule for whatever timeout is specified */
{
- time_t delay;
+ time_t delay = UNDEFINED_TIME;
enum event_type kind = smc->timeout_event;
bool agreed_time = FALSE;
struct connection *c = st->st_connection;
diff --git a/src/pluto/fetch.c b/src/pluto/fetch.c
index c0bf3fed6..cd8b58df2 100644
--- a/src/pluto/fetch.c
+++ b/src/pluto/fetch.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: fetch.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: fetch.c 3686 2008-03-28 11:48:14Z martin $
*/
#include <stdlib.h>
@@ -825,7 +825,9 @@ fetch_thread(void *arg)
void
init_fetch(void)
{
+#if defined(LIBCURL) || defined (THREADS)
int status;
+#endif
#ifdef LIBCURL
/* init curl */
diff --git a/src/pluto/ike_alg.c b/src/pluto/ike_alg.c
index 52f2c5c80..6759059fa 100644
--- a/src/pluto/ike_alg.c
+++ b/src/pluto/ike_alg.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: ike_alg.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: ike_alg.c 3686 2008-03-28 11:48:14Z martin $
*/
#include <stdio.h>
@@ -521,9 +521,6 @@ ike_alg_test(void)
for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
{
-
- struct encrypt_desc *desc = (struct encrypt_desc*)a;
-
plog(" %s self-test not available", enum_name(&oakley_enc_names, a->algo_id));
}
diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c
index 852b2e73e..88536e6d6 100644
--- a/src/pluto/ipsec_doi.c
+++ b/src/pluto/ipsec_doi.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: ipsec_doi.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: ipsec_doi.c 3686 2008-03-28 11:48:14Z martin $
*/
#include <stdio.h>
@@ -952,7 +952,6 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
/* SA out */
{
u_char *sa_start = rbody.cur;
- lset_t auth_policy = policy & POLICY_ID_AUTH_MASK;
if (!out_sa(&rbody, &oakley_sadb, st, TRUE
, vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
@@ -2800,7 +2799,7 @@ compute_proto_keymat(struct state *st
, u_int8_t protoid
, struct ipsec_proto_info *pi)
{
- size_t needed_len; /* bytes of keying material needed */
+ size_t needed_len = 0; /* bytes of keying material needed */
/* Add up the requirements for keying material
* (It probably doesn't matter if we produce too much!)
@@ -3754,7 +3753,7 @@ main_id_and_auth(struct msg_digest *md
struct key_continuation *nkc
= alloc_thing(struct key_continuation, "key continuation");
enum key_oppo_step step_done = kc == NULL? kos_null : kc->step;
- err_t ugh;
+ err_t ugh = NULL;
/* Record that state is used by a suspended md */
passert(st->st_suspended_md == NULL);
@@ -4308,7 +4307,7 @@ report_verify_failure(struct verify_oppo_bundle *b, err_t ugh)
char fgwb[ADDRTOT_BUF]
, cb[ADDRTOT_BUF];
ip_address client;
- err_t which;
+ err_t which = NULL;
switch (b->step)
{
@@ -4384,7 +4383,7 @@ quick_inI1_outR1_start_query(struct verify_oppo_bundle *b
, *our_id /* needed for myid playing */
, our_id_space; /* ephemeral: no need for unshare_id_content */
ip_address client;
- err_t ugh;
+ err_t ugh = NULL;
/* Record that state is used by a suspended md */
b->step = next_step; /* not just vc->b.step */
@@ -4495,7 +4494,7 @@ quick_inI1_outR1_process_answer(struct verify_oppo_bundle *b
, struct state *p1st)
{
struct connection *c = p1st->st_connection;
- enum verify_oppo_step next_step;
+ enum verify_oppo_step next_step = vos_our_client;
err_t ugh = NULL;
DBG(DBG_CONTROL,
diff --git a/src/pluto/kernel.c b/src/pluto/kernel.c
index 5f31d5ca3..d42ac3372 100644
--- a/src/pluto/kernel.c
+++ b/src/pluto/kernel.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: kernel.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: kernel.c 3846 2008-04-18 17:01:45Z andreas $
*/
#include <stddef.h>
@@ -1827,30 +1827,30 @@ setup_half_ipsec_sa(struct state *st, bool inbound)
static const struct esp_info esp_info[] = {
{ ESP_NULL, AUTH_ALGORITHM_HMAC_MD5,
0, HMAC_MD5_KEY_LEN,
- SADB_EALG_NULL, SADB_AALG_MD5_HMAC },
+ SADB_EALG_NULL, SADB_AALG_MD5HMAC },
{ ESP_NULL, AUTH_ALGORITHM_HMAC_SHA1,
0, HMAC_SHA1_KEY_LEN,
- SADB_EALG_NULL, SADB_AALG_SHA1_HMAC },
+ SADB_EALG_NULL, SADB_AALG_SHA1HMAC },
{ ESP_DES, AUTH_ALGORITHM_NONE,
DES_CBC_BLOCK_SIZE, 0,
- SADB_EALG_DES_CBC, SADB_AALG_NONE },
+ SADB_EALG_DESCBC, SADB_AALG_NONE },
{ ESP_DES, AUTH_ALGORITHM_HMAC_MD5,
DES_CBC_BLOCK_SIZE, HMAC_MD5_KEY_LEN,
- SADB_EALG_DES_CBC, SADB_AALG_MD5_HMAC },
+ SADB_EALG_DESCBC, SADB_AALG_MD5HMAC },
{ ESP_DES, AUTH_ALGORITHM_HMAC_SHA1,
DES_CBC_BLOCK_SIZE,
- HMAC_SHA1_KEY_LEN, SADB_EALG_DES_CBC, SADB_AALG_SHA1_HMAC },
+ HMAC_SHA1_KEY_LEN, SADB_EALG_DESCBC, SADB_AALG_SHA1HMAC },
{ ESP_3DES, AUTH_ALGORITHM_NONE,
DES_CBC_BLOCK_SIZE * 3, 0,
- SADB_EALG_3DES_CBC, SADB_AALG_NONE },
+ SADB_EALG_3DESCBC, SADB_AALG_NONE },
{ ESP_3DES, AUTH_ALGORITHM_HMAC_MD5,
DES_CBC_BLOCK_SIZE * 3, HMAC_MD5_KEY_LEN,
- SADB_EALG_3DES_CBC, SADB_AALG_MD5_HMAC },
+ SADB_EALG_3DESCBC, SADB_AALG_MD5HMAC },
{ ESP_3DES, AUTH_ALGORITHM_HMAC_SHA1,
DES_CBC_BLOCK_SIZE * 3, HMAC_SHA1_KEY_LEN,
- SADB_EALG_3DES_CBC, SADB_AALG_SHA1_HMAC },
+ SADB_EALG_3DESCBC, SADB_AALG_SHA1HMAC },
};
u_int8_t natt_type = 0;
@@ -1976,11 +1976,11 @@ setup_half_ipsec_sa(struct state *st, bool inbound)
switch (st->st_ah.attrs.auth)
{
case AUTH_ALGORITHM_HMAC_MD5:
- authalg = SADB_AALG_MD5_HMAC;
+ authalg = SADB_AALG_MD5HMAC;
break;
case AUTH_ALGORITHM_HMAC_SHA1:
- authalg = SADB_AALG_SHA1_HMAC;
+ authalg = SADB_AALG_SHA1HMAC;
break;
default:
diff --git a/src/pluto/kernel_netlink.c b/src/pluto/kernel_netlink.c
index abdb603de..4269de66e 100644
--- a/src/pluto/kernel_netlink.c
+++ b/src/pluto/kernel_netlink.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: kernel_netlink.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: kernel_netlink.c 3850 2008-04-18 20:01:49Z andreas $
*/
#if defined(linux) && defined(KERNEL26_SUPPORT)
@@ -83,12 +83,13 @@ static sparse_names xfrm_type_names = {
/* Authentication algorithms */
static sparse_names aalg_list = {
{ SADB_X_AALG_NULL, "digest_null" },
- { SADB_AALG_MD5_HMAC, "md5" },
- { SADB_AALG_SHA1_HMAC, "sha1" },
- { SADB_AALG_SHA2_256_HMAC, "sha256" },
- { SADB_AALG_SHA2_384_HMAC, "sha384" },
- { SADB_AALG_SHA2_512_HMAC, "sha512" },
- { SADB_AALG_RIPEMD_160_HMAC, "ripemd160" },
+ { SADB_AALG_MD5HMAC, "md5" },
+ { SADB_AALG_SHA1HMAC, "sha1" },
+ { SADB_X_AALG_SHA2_256HMAC, "sha256" },
+ { SADB_X_AALG_SHA2_384HMAC, "sha384" },
+ { SADB_X_AALG_SHA2_512HMAC, "sha512" },
+ { SADB_X_AALG_RIPEMD160HMAC, "ripemd160" },
+ { SADB_X_AALG_AES_XCBC_MAC, "xcbc(aes)"},
{ SADB_X_AALG_NULL, "null" },
{ 0, sparse_end }
};
@@ -96,14 +97,14 @@ static sparse_names aalg_list = {
/* Encryption algorithms */
static sparse_names ealg_list = {
{ SADB_EALG_NULL, "cipher_null" },
- { SADB_EALG_DES_CBC, "des" },
- { SADB_EALG_3DES_CBC, "des3_ede" },
- { SADB_EALG_IDEA_CBC, "idea" },
- { SADB_EALG_CAST_CBC, "cast128" },
- { SADB_EALG_BLOWFISH_CBC, "blowfish" },
- { SADB_EALG_AES_CBC, "aes" },
- { SADB_X_EALG_SERPENT_CBC, "serpent" },
- { SADB_X_EALG_TWOFISH_CBC, "twofish" },
+ { SADB_EALG_DESCBC, "des" },
+ { SADB_EALG_3DESCBC, "des3_ede" },
+ { SADB_X_EALG_CASTCBC, "cast128" },
+ { SADB_X_EALG_BLOWFISHCBC, "blowfish" },
+ { SADB_X_EALG_AESCBC, "aes" },
+ { SADB_X_EALG_CAMELLIACBC, "cbc(camellia)" },
+ { SADB_X_EALG_SERPENTCBC, "serpent" },
+ { SADB_X_EALG_TWOFISHCBC, "twofish" },
{ 0, sparse_end }
};
diff --git a/src/pluto/keys.c b/src/pluto/keys.c
index eab9dfc4a..1aed7a63f 100644
--- a/src/pluto/keys.c
+++ b/src/pluto/keys.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keys.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: keys.c 3738 2008-04-02 19:04:45Z andreas $
*/
#include <stddef.h>
@@ -83,7 +83,7 @@ static pubkey_t*
allocate_RSA_public_key(const cert_t cert)
{
pubkey_t *pk = alloc_thing(pubkey_t, "pubkey");
- chunk_t e, n;
+ chunk_t e = empty_chunk, n = empty_chunk;
switch (cert.type)
{
@@ -335,7 +335,7 @@ get_x509_private_key(const x509cert_t *cert)
{
secret_t *s;
const RSA_private_key_t *pri = NULL;
- const cert_t c = {CERT_X509_SIGNATURE, {cert}};
+ const cert_t c = {CERT_X509_SIGNATURE, {(x509cert_t*)cert}};
pubkey_t *pubkey = allocate_RSA_public_key(c);
@@ -647,7 +647,7 @@ xauth_get_secret(xauth_t *xauth_secret)
* find a matching secret
*/
static bool
-xauth_verify_secret(const char *conn_name, const xauth_t *xauth_secret)
+xauth_verify_secret(const xauth_peer_t *peer, const xauth_t *xauth_secret)
{
bool found = FALSE;
secret_t *s;
@@ -1473,7 +1473,7 @@ add_pgp_public_key(pgpcert_t *cert , time_t until
void
remove_x509_public_key(const x509cert_t *cert)
{
- const cert_t c = {CERT_X509_SIGNATURE, {cert}};
+ const cert_t c = {CERT_X509_SIGNATURE, {(x509cert_t*)cert}};
pubkey_list_t *p, **pp;
pubkey_t *revoked_pk;
diff --git a/src/pluto/log.c b/src/pluto/log.c
index ca0576b69..0fb5f1d25 100644
--- a/src/pluto/log.c
+++ b/src/pluto/log.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: log.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: log.c 4024 2008-05-29 07:49:47Z andreas $
*/
#include <stdio.h>
@@ -65,7 +65,7 @@ const char *base_perpeer_logdir = PERPEERLOGDIR;
static int perpeer_count = 0;
/* from sys/queue.h */
-static CIRCLEQ_HEAD(,connection) perpeer_list;
+static TAILQ_HEAD(perpeer, connection) perpeer_list;
/* Context for logging.
@@ -88,19 +88,19 @@ init_log(const char *program)
if (log_to_syslog)
openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
- CIRCLEQ_INIT(&perpeer_list);
+ TAILQ_INIT(&perpeer_list);
}
void
close_peerlog(void)
{
- /* end of circular queue is given by pointer to "HEAD"
- * BUT if the queue is not initialized, this won't be true
- * so we must guard by test perpeer_list.cqh_first != NULL
- */
- if (perpeer_list.cqh_first != NULL)
- while (perpeer_list.cqh_first != (void *)&perpeer_list)
- perpeer_logclose(perpeer_list.cqh_first);
+ /* exit if the queue has not been initialized */
+ if (TAILQ_LAST(&perpeer_list, perpeer) == NULL)
+ return;
+
+ /* end of queue is given by pointer to "HEAD" */
+ while (TAILQ_LAST(&perpeer_list, perpeer) != (void *)&perpeer_list)
+ perpeer_logclose(TAILQ_LAST(&perpeer_list, perpeer));
}
void
@@ -231,7 +231,7 @@ perpeer_logclose(struct connection *c)
{
passert(perpeer_count > 0);
- CIRCLEQ_REMOVE(&perpeer_list, c, log_link);
+ TAILQ_REMOVE(&perpeer_list, c, log_link);
perpeer_count--;
fclose(c->log_file);
c->log_file=NULL;
@@ -366,13 +366,13 @@ open_peerlog(struct connection *c)
while (perpeer_count >= MAX_PEERLOG_COUNT)
{
/* can not be NULL because perpeer_count > 0 */
- passert(perpeer_list.cqh_last != (void *)&perpeer_list);
+ passert(TAILQ_LAST(&perpeer_list, perpeer) != (void *)&perpeer_list);
- perpeer_logclose(perpeer_list.cqh_last);
+ perpeer_logclose(TAILQ_LAST(&perpeer_list, perpeer));
}
/* insert this into the list */
- CIRCLEQ_INSERT_HEAD(&perpeer_list, c, log_link);
+ TAILQ_INSERT_HEAD(&perpeer_list, c, log_link);
passert(c->log_file != NULL);
perpeer_count++;
}
@@ -406,8 +406,8 @@ peerlog(const char *prefix, const char *m)
fprintf(cur_connection->log_file, "%s %s%s\n", datebuf, prefix, m);
/* now move it to the front of the list */
- CIRCLEQ_REMOVE(&perpeer_list, cur_connection, log_link);
- CIRCLEQ_INSERT_HEAD(&perpeer_list, cur_connection, log_link);
+ TAILQ_REMOVE(&perpeer_list, cur_connection, log_link);
+ TAILQ_INSERT_HEAD(&perpeer_list, cur_connection, log_link);
}
}
diff --git a/src/pluto/modecfg.c b/src/pluto/modecfg.c
index b7f8aef93..93624588a 100644
--- a/src/pluto/modecfg.c
+++ b/src/pluto/modecfg.c
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: modecfg.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: modecfg.c 3738 2008-04-02 19:04:45Z andreas $
*
* This code originally written by Colubris Networks, Inc.
* Extraction of patch and porting to 1.99 codebases by Xelerance Corporation
@@ -967,6 +967,12 @@ xauth_inR1(struct msg_digest *md)
}
else
{
+ xauth_peer_t peer;
+
+ peer.conn_name = st->st_connection->name;
+ addrtot(&md->sender, 0, peer.ip_address, sizeof(peer.ip_address));
+ idtoa(&md->st->st_connection->spd.that.id, peer.id, sizeof(peer.id));
+
DBG(DBG_CONTROL,
DBG_log("peer xauth user name is '%.*s'"
, ia.xauth_secret.user_name.len
@@ -977,9 +983,8 @@ xauth_inR1(struct msg_digest *md)
, ia.xauth_secret.user_password.len
, ia.xauth_secret.user_password.ptr)
)
- /* verify the user credentials using a plugn function */
- st->st_xauth.status = xauth_module.verify_secret(st->st_connection->name
- , &ia.xauth_secret);
+ /* verify the user credentials using a plugin function */
+ st->st_xauth.status = xauth_module.verify_secret(&peer, &ia.xauth_secret);
plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
}
diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c
index fccd2e461..5662c5c41 100644
--- a/src/pluto/plutomain.c
+++ b/src/pluto/plutomain.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: plutomain.c 3253 2007-10-06 21:39:00Z andreas $
+ * RCSID $Id: plutomain.c 3914 2008-05-08 10:58:04Z martin $
*/
#include <stdio.h>
@@ -31,6 +31,8 @@
#include <sys/queue.h>
#include <linux/capability.h>
#include <sys/prctl.h>
+#include <pwd.h>
+#include <grp.h>
#include <freeswan.h>
@@ -617,19 +619,43 @@ main(int argc, char **argv)
init_fetch();
/* drop unneeded capabilities and change UID/GID */
+#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 =
1<<CAP_NET_ADMIN | 1<<CAP_NET_BIND_SERVICE;
prctl(PR_SET_KEEPCAPS, 1);
+
+#ifdef IPSEC_GROUP
+ {
+ struct group group, *grp;
+ char buf[1024];
-# if IPSEC_GID
- setgid(IPSEC_GID);
-# endif
-# if IPSEC_UID
- setuid(IPSEC_UID);
-# endif
+ if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
+ grp == NULL || setgid(grp->gr_gid) != 0)
+ {
+ plog("unable to change daemon group");
+ abort();
+ }
+ }
+#endif
+#ifdef IPSEC_USER
+ {
+ struct passwd passwd, *pwp;
+ char buf[1024];
+
+ if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
+ pwp == NULL || setuid(pwp->pw_uid) != 0)
+ {
+ plog("unable to change daemon user");
+ abort();
+ }
+ }
+#endif
if (capset(&hdr, &data))
{
plog("unable to drop root privileges");
diff --git a/src/pluto/smartcard.c b/src/pluto/smartcard.c
index c46e3cf9a..937c3f93a 100644
--- a/src/pluto/smartcard.c
+++ b/src/pluto/smartcard.c
@@ -18,7 +18,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: smartcard.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: smartcard.c 3686 2008-03-28 11:48:14Z martin $
*/
#include <stdio.h>
@@ -701,7 +701,7 @@ void
scx_init(const char* module, const char *init_args)
{
#ifdef SMARTCARD
- CK_C_INITIALIZE_ARGS args = { .pReserved = init_args, };
+ CK_C_INITIALIZE_ARGS args = { .pReserved = (char *)init_args, };
CK_RV rv;
if (scx_initialized)
@@ -1442,7 +1442,7 @@ scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
if (rv == CKR_FUNCTION_NOT_SUPPORTED)
{
RSA_public_key_t rsa;
- chunk_t plain_text = {in, inlen};
+ chunk_t plain_text = {(u_char*)in, inlen};
chunk_t cipher_text;
DBG(DBG_CONTROL,
@@ -1496,7 +1496,7 @@ scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
DBG(DBG_CONTROL,
DBG_log("doing RSA encryption on smartcard")
)
- rv = pkcs11_functions->C_Encrypt(sc->session, in, inlen
+ rv = pkcs11_functions->C_Encrypt(sc->session, (u_char*)in, inlen
, out, &len);
if (rv != CKR_OK)
{
@@ -1570,7 +1570,7 @@ scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen
return FALSE;
}
- rv = pkcs11_functions->C_Decrypt(sc->session, in, inlen
+ rv = pkcs11_functions->C_Decrypt(sc->session, (u_char*)in, inlen
, out, &len);
if (rv != CKR_OK)
{
diff --git a/src/pluto/spdb.c b/src/pluto/spdb.c
index 7003b127a..9d1bf8843 100644
--- a/src/pluto/spdb.c
+++ b/src/pluto/spdb.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: spdb.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: spdb.c 3845 2008-04-18 17:00:30Z andreas $
*/
#include <stdio.h>
@@ -296,9 +296,9 @@ out_sa(pb_stream *outs
struct db_prop *p = &pc->props[pn];
pb_stream proposal_pbs;
struct isakmp_proposal proposal;
- struct_desc *trans_desc;
- struct_desc *attr_desc;
- enum_names **attr_val_descs;
+ struct_desc *trans_desc = NULL;
+ struct_desc *attr_desc = NULL;
+ enum_names **attr_val_descs = NULL;
int tn;
bool tunnel_mode;
@@ -1166,6 +1166,8 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit
case OAKLEY_GROUP_ORDER | ISAKMP_ATTR_AF_TLV:
#endif
default:
+ /* fix compiler warning */
+ memset(&ta, 0, sizeof(ta));
ugh = "unsupported OAKLEY attribute";
break;
}
@@ -1761,7 +1763,9 @@ parse_ipsec_sa_body(
{
int propno = next_proposal.isap_proposal;
pb_stream ah_prop_pbs, esp_prop_pbs, ipcomp_prop_pbs;
- struct isakmp_proposal ah_proposal, esp_proposal, ipcomp_proposal;
+ struct isakmp_proposal ah_proposal = {0, 0, 0, 0, 0, 0, 0};
+ struct isakmp_proposal esp_proposal = {0, 0, 0, 0, 0, 0, 0};
+ struct isakmp_proposal ipcomp_proposal = {0, 0, 0, 0, 0, 0, 0};
ipsec_spi_t ah_spi = 0;
ipsec_spi_t esp_spi = 0;
ipsec_spi_t ipcomp_cpi = 0;
@@ -2054,7 +2058,7 @@ parse_ipsec_sa_body(
/* set default key length for AES encryption */
if (!esp_attrs.key_len && esp_attrs.transid == ESP_AES)
{
- esp_attrs.key_len = 128 / BITS_PER_BYTE;
+ esp_attrs.key_len = 128; /* bits */
}
if (!kernel_alg_esp_enc_ok(esp_attrs.transid, esp_attrs.key_len
diff --git a/src/pluto/vendor.c b/src/pluto/vendor.c
index c31a4195b..3b779ed24 100644
--- a/src/pluto/vendor.c
+++ b/src/pluto/vendor.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: vendor.c 3472 2008-02-14 21:26:21Z andreas $
+ * RCSID $Id: vendor.c 4016 2008-05-25 10:35:39Z andreas $
*/
#include <stdlib.h>
@@ -206,7 +206,12 @@ static struct vid_struct _vid_tab[] = {
/*
* strongSwan
*/
- DEC_MD5_VID(STRONGSWAN, "strongSwan 4.1.11")
+ DEC_MD5_VID(STRONGSWAN, "strongSwan 4.2.4")
+ DEC_MD5_VID(STRONGSWAN_4_2_3, "strongSwan 4.2.3")
+ DEC_MD5_VID(STRONGSWAN_4_2_2, "strongSwan 4.2.2")
+ DEC_MD5_VID(STRONGSWAN_4_2_1, "strongSwan 4.2.1")
+ DEC_MD5_VID(STRONGSWAN_4_2_0, "strongSwan 4.2.0")
+ DEC_MD5_VID(STRONGSWAN_4_1_11,"strongSwan 4.1.11")
DEC_MD5_VID(STRONGSWAN_4_1_10,"strongSwan 4.1.10")
DEC_MD5_VID(STRONGSWAN_4_1_9, "strongSwan 4.1.9")
DEC_MD5_VID(STRONGSWAN_4_1_8, "strongSwan 4.1.8")
diff --git a/src/pluto/vendor.h b/src/pluto/vendor.h
index 03d2fde77..c1d8870bc 100644
--- a/src/pluto/vendor.h
+++ b/src/pluto/vendor.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: vendor.h 3413 2007-12-24 18:07:55Z andreas $
+ * RCSID $Id: vendor.h 4016 2008-05-25 10:35:39Z andreas $
*/
#ifndef _VENDOR_H_
@@ -114,17 +114,23 @@ enum known_vendorid {
VID_STRONGSWAN_4_1_8 = 96,
VID_STRONGSWAN_4_1_9 = 97,
VID_STRONGSWAN_4_1_10 = 98,
+ VID_STRONGSWAN_4_1_11 = 99,
+
+ VID_STRONGSWAN_4_2_0 =100,
+ VID_STRONGSWAN_4_2_1 =101,
+ VID_STRONGSWAN_4_2_2 =102,
+ VID_STRONGSWAN_4_2_3 =103,
/* 101 - 200 : NAT-Traversal */
- VID_NATT_STENBERG_01 =101,
- VID_NATT_STENBERG_02 =102,
- VID_NATT_HUTTUNEN =103,
- VID_NATT_HUTTUNEN_ESPINUDP =104,
- VID_NATT_IETF_00 =105,
- VID_NATT_IETF_02_N =106,
- VID_NATT_IETF_02 =107,
- VID_NATT_IETF_03 =108,
- VID_NATT_RFC =109,
+ VID_NATT_STENBERG_01 =151,
+ VID_NATT_STENBERG_02 =152,
+ VID_NATT_HUTTUNEN =153,
+ VID_NATT_HUTTUNEN_ESPINUDP =154,
+ VID_NATT_IETF_00 =155,
+ VID_NATT_IETF_02_N =156,
+ VID_NATT_IETF_02 =157,
+ VID_NATT_IETF_03 =158,
+ VID_NATT_RFC =159,
/* 201 - 300 : Misc */
VID_MISC_XAUTH =201,
diff --git a/src/pluto/xauth.c b/src/pluto/xauth.c
index 0188b1950..8f4dc2460 100644
--- a/src/pluto/xauth.c
+++ b/src/pluto/xauth.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: xauth.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: xauth.c 3738 2008-04-02 19:04:45Z andreas $
*/
#include <dlfcn.h>
@@ -44,7 +44,7 @@ xauth_init(void)
DBG_log("xauth module: found get_secret() function");
}
)
- xauth_module.verify_secret = (bool (*) (const char*, const xauth_t*))
+ xauth_module.verify_secret = (bool (*) (const xauth_peer_t*, const xauth_t*))
dlsym(xauth_module.handle, "verify_secret");
DBG(DBG_CONTROL,
if (xauth_module.verify_secret != NULL)
diff --git a/src/pluto/xauth.h b/src/pluto/xauth.h
index 277340ab0..fd7e5399f 100644
--- a/src/pluto/xauth.h
+++ b/src/pluto/xauth.h
@@ -12,17 +12,26 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: xauth.h 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: xauth.h 3738 2008-04-02 19:04:45Z andreas $
*/
#ifndef _XAUTH_H
#define _XAUTH_H
+#include <freeswan.h>
+#include "defs.h"
+
/* XAUTH credentials */
struct chunk_t;
typedef struct {
+ char *conn_name;
+ char id[BUF_LEN];
+ char ip_address[ADDRTOT_BUF];
+} xauth_peer_t;
+
+typedef struct {
chunk_t user_name;
chunk_t user_password;
} xauth_t;
@@ -30,7 +39,7 @@ typedef struct {
typedef struct {
void *handle;
bool (*get_secret) (xauth_t *xauth_secret);
- bool (*verify_secret) (const char *conn_name, const xauth_t *xauth_secret);
+ bool (*verify_secret) (const xauth_peer_t *peer, const xauth_t *xauth_secret);
} xauth_module_t;
extern xauth_module_t xauth_module;
diff --git a/src/scepclient/Makefile.am b/src/scepclient/Makefile.am
index 3a5f9839f..57b20dfb5 100644
--- a/src/scepclient/Makefile.am
+++ b/src/scepclient/Makefile.am
@@ -23,16 +23,18 @@ scepclient_LDADD = asn1.o ca.o crl.o certs.o constants.o defs.o fetch.o id.o \
$(LIBFREESWANDIR)/libfreeswan.a $(LIBCRYPTODIR)/libcrypto.a \
-lgmp
-# This compile option activates dynamic URL fetching using libcurl
-if USE_LIBCURL
- scepclient_LDADD += -lcurl
-endif
-
# This compile option activates smartcard support
if USE_SMARTCARD
+ AM_CFLAGS += -DSMARTCARD
scepclient_LDADD += -ldl
endif
+# This compile option activates dynamic URL fetching using libcurl
+if USE_CURL
+ AM_CFLAGS += -DLIBCURL
+ scepclient_LDADD += -lcurl
+endif
+
dist_man_MANS = scepclient.8
asn1.o : $(PLUTODIR)/asn1.c $(PLUTODIR)/asn1.h
diff --git a/src/scepclient/Makefile.in b/src/scepclient/Makefile.in
index 1f0cbf48f..9198ab229 100644
--- a/src/scepclient/Makefile.in
+++ b/src/scepclient/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.
@@ -34,11 +34,13 @@ build_triplet = @build@
host_triplet = @host@
ipsec_PROGRAMS = scepclient$(EXEEXT)
-# This compile option activates dynamic URL fetching using libcurl
-@USE_LIBCURL_TRUE@am__append_1 = -lcurl
-
# This compile option activates smartcard support
+@USE_SMARTCARD_TRUE@am__append_1 = -DSMARTCARD
@USE_SMARTCARD_TRUE@am__append_2 = -ldl
+
+# This compile option activates dynamic URL fetching using libcurl
+@USE_CURL_TRUE@am__append_3 = -DLIBCURL
+@USE_CURL_TRUE@am__append_4 = -lcurl
subdir = src/scepclient
DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
@@ -99,6 +101,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -128,6 +131,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -158,7 +162,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@
@@ -169,12 +172,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@
@@ -184,12 +186,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@
@@ -202,10 +204,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@
@@ -226,12 +230,13 @@ INCLUDES = \
-I$(LIBCRYPTODIR) \
-I$(WHACKDIR)
-AM_CFLAGS = -DDEBUG -DNO_PLUTO -DIPSEC_CONFDIR=\"${confdir}\"
+AM_CFLAGS = -DDEBUG -DNO_PLUTO -DIPSEC_CONFDIR=\"${confdir}\" \
+ $(am__append_1) $(am__append_3)
scepclient_LDADD = asn1.o ca.o crl.o certs.o constants.o defs.o \
fetch.o id.o keys.o lex.o md2.o md5.o mp_defs.o ocsp.o oid.o \
pem.o pgp.o pkcs1.o pkcs7.o rnd.o sha1.o smartcard.o x509.o \
$(LIBFREESWANDIR)/libfreeswan.a $(LIBCRYPTODIR)/libcrypto.a \
- -lgmp $(am__append_1) $(am__append_2)
+ -lgmp $(am__append_2) $(am__append_4)
dist_man_MANS = scepclient.8
all: all-am
@@ -275,8 +280,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
@@ -387,8 +392,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -400,8 +405,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -411,13 +416,12 @@ ctags: CTAGS
CTAGS: $(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
diff --git a/src/scepclient/scep.c b/src/scepclient/scep.c
index 9e05561ed..0c1265918 100644
--- a/src/scepclient/scep.c
+++ b/src/scepclient/scep.c
@@ -340,7 +340,7 @@ chunk_t
scep_messageType_attribute(scep_msg_t m)
{
chunk_t msgType = {
- msgType_values[m],
+ (u_char*)msgType_values[m],
strlen(msgType_values[m])
};
diff --git a/src/starter/Makefile.am b/src/starter/Makefile.am
index 40725a996..e6346a585 100644
--- a/src/starter/Makefile.am
+++ b/src/starter/Makefile.am
@@ -16,7 +16,7 @@ PLUTODIR=$(top_srcdir)/src/pluto
SCEPCLIENTDIR=$(top_srcdir)/src/scepclient
lex.yy.c: y.tab.c parser.l parser.y parser.h
- $(LEX) parser.l
+ $(LEX) --nounput parser.l
y.tab.c: parser.l parser.y parser.h
$(YACC) -v -d parser.y
@@ -30,5 +30,15 @@ keywords.c: keywords.txt keywords.h
defs.o: $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h
$(COMPILE) -c -o $@ $<
-install-exec-local :
- test -e "$(DESTDIR)$(sysconfdir)/ipsec.conf" || $(INSTALL) ipsec.conf $(DESTDIR)$(sysconfdir)/ipsec.conf
+install-exec-local :
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/cacerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/cacerts" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/ocspcerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/ocspcerts" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/certs" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/certs" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/acerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/acerts" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/aacerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/aacerts" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/crls" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/crls" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/reqs" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/reqs" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/private" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d -m 750 "$(DESTDIR)$(sysconfdir)/ipsec.d/private" || true
+ test -e "$(DESTDIR)$(sysconfdir)/ipsec.conf" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -m 644 ipsec.conf $(DESTDIR)$(sysconfdir)/ipsec.conf || true
+
diff --git a/src/starter/Makefile.in b/src/starter/Makefile.in
index a9e86fab0..03bb318a5 100644
--- a/src/starter/Makefile.in
+++ b/src/starter/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.
@@ -95,6 +95,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -124,6 +125,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -154,7 +156,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@
@@ -165,12 +166,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@
@@ -180,12 +180,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@
@@ -198,10 +198,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@
@@ -264,8 +266,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
@@ -431,8 +433,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -444,8 +446,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -455,13 +457,12 @@ ctags: CTAGS
CTAGS: $(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
@@ -613,7 +614,7 @@ uninstall-man: uninstall-man5 uninstall-man8
lex.yy.c: y.tab.c parser.l parser.y parser.h
- $(LEX) parser.l
+ $(LEX) --nounput parser.l
y.tab.c: parser.l parser.y parser.h
$(YACC) -v -d parser.y
@@ -627,8 +628,17 @@ keywords.c: keywords.txt keywords.h
defs.o: $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h
$(COMPILE) -c -o $@ $<
-install-exec-local :
- test -e "$(DESTDIR)$(sysconfdir)/ipsec.conf" || $(INSTALL) ipsec.conf $(DESTDIR)$(sysconfdir)/ipsec.conf
+install-exec-local :
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/cacerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/cacerts" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/ocspcerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/ocspcerts" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/certs" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/certs" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/acerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/acerts" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/aacerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/aacerts" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/crls" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/crls" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/reqs" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/reqs" || true
+ test -e "$(DESTDIR)${sysconfdir}/ipsec.d/private" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d -m 750 "$(DESTDIR)$(sysconfdir)/ipsec.d/private" || true
+ test -e "$(DESTDIR)$(sysconfdir)/ipsec.conf" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -m 644 ipsec.conf $(DESTDIR)$(sysconfdir)/ipsec.conf || true
# 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/starter/args.c b/src/starter/args.c
index 8539f209b..8a0262d8d 100644
--- a/src/starter/args.c
+++ b/src/starter/args.c
@@ -1,5 +1,4 @@
/* automatic handling of confread struct arguments
- * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2006 Andreas Steffen
* Hochschule fuer Technik Rapperswil, Switzerland
*
@@ -13,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: args.c 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: args.c 3932 2008-05-12 10:05:49Z andreas $
*/
#include <stddef.h>
@@ -62,6 +61,14 @@ static const char *LST_sendcert[] = {
NULL
};
+static const char *LST_unique[] = {
+ "no",
+ "yes",
+ "replace",
+ "keep",
+ NULL
+};
+
static const char *LST_strict[] = {
"no",
"yes",
@@ -163,7 +170,8 @@ static const token_info_t token_info[] =
{ ARG_STR, offsetof(starter_config_t, setup.charondebug), NULL },
{ ARG_STR, offsetof(starter_config_t, setup.prepluto), NULL },
{ ARG_STR, offsetof(starter_config_t, setup.postpluto), NULL },
- { ARG_ENUM, offsetof(starter_config_t, setup.uniqueids), LST_bool },
+ { ARG_STR, offsetof(starter_config_t, setup.plutostderrlog), NULL },
+ { ARG_ENUM, offsetof(starter_config_t, setup.uniqueids), LST_unique },
{ ARG_UINT, offsetof(starter_config_t, setup.overridemtu), NULL },
{ ARG_TIME, offsetof(starter_config_t, setup.crlcheckinterval), NULL },
{ ARG_ENUM, offsetof(starter_config_t, setup.cachecrls), LST_bool },
@@ -171,8 +179,8 @@ static const token_info_t token_info[] =
{ ARG_ENUM, offsetof(starter_config_t, setup.nocrsend), LST_bool },
{ ARG_ENUM, offsetof(starter_config_t, setup.nat_traversal), LST_bool },
{ ARG_TIME, offsetof(starter_config_t, setup.keep_alive), NULL },
+ { ARG_ENUM, offsetof(starter_config_t, setup.force_keepalive), LST_bool },
{ ARG_STR, offsetof(starter_config_t, setup.virtual_private), NULL },
- { ARG_STR, offsetof(starter_config_t, setup.eapdir), NULL },
{ ARG_STR, offsetof(starter_config_t, setup.pkcs11module), NULL },
{ ARG_STR, offsetof(starter_config_t, setup.pkcs11initargs), NULL },
{ ARG_ENUM, offsetof(starter_config_t, setup.pkcs11keepstate), LST_bool },
@@ -211,9 +219,9 @@ static const token_info_t token_info[] =
{ ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action },
{ ARG_MISC, 0, NULL /* KW_MODECONFIG */ },
{ ARG_MISC, 0, NULL /* KW_XAUTH */ },
- { ARG_ENUM, offsetof(starter_conn_t, p2p_mediation), LST_bool },
- { ARG_STR, offsetof(starter_conn_t, p2p_mediated_by), NULL },
- { ARG_STR, offsetof(starter_conn_t, p2p_peerid), NULL },
+ { ARG_ENUM, offsetof(starter_conn_t, me_mediation), LST_bool },
+ { ARG_STR, offsetof(starter_conn_t, me_mediated_by), NULL },
+ { ARG_STR, offsetof(starter_conn_t, me_peerid), NULL },
/* ca section keywords */
{ ARG_STR, offsetof(starter_ca_t, name), NULL },
@@ -225,14 +233,15 @@ static const token_info_t token_info[] =
{ ARG_STR, offsetof(starter_ca_t, crluri2), NULL },
{ ARG_STR, offsetof(starter_ca_t, ocspuri), NULL },
{ ARG_STR, offsetof(starter_ca_t, ocspuri2), NULL },
+ { ARG_STR, offsetof(starter_ca_t, certuribase), NULL },
/* end keywords */
{ ARG_MISC, 0, NULL /* KW_HOST */ },
{ ARG_MISC, 0, NULL /* KW_NEXTHOP */ },
- { ARG_MISC, 0, NULL /* KW_SUBNET */ },
+ { ARG_STR, offsetof(starter_end_t, subnet), NULL },
{ ARG_MISC, 0, NULL /* KW_SUBNETWITHIN */ },
{ ARG_MISC, 0, NULL /* KW_PROTOPORT */ },
- { ARG_MISC, 0, NULL /* KW_SOURCEIP */ },
+ { ARG_STR, offsetof(starter_end_t, srcip), NULL },
{ ARG_MISC, 0, NULL /* KW_NATIP */ },
{ ARG_ENUM, offsetof(starter_end_t, firewall), LST_bool },
{ ARG_ENUM, offsetof(starter_end_t, hostaccess), LST_bool },
diff --git a/src/starter/cmp.c b/src/starter/cmp.c
index a4198ce41..5abb8399b 100644
--- a/src/starter/cmp.c
+++ b/src/starter/cmp.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: cmp.c 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: cmp.c 3881 2008-04-27 11:04:13Z andreas $
*/
#include <string.h>
@@ -29,6 +29,7 @@
#define VARCMP(obj) if (c1->obj != c2->obj) return FALSE
#define ADDCMP(obj) if (!sameaddr(&c1->obj,&c2->obj)) return FALSE
#define SUBCMP(obj) if (!samesubnet(&c1->obj,&c2->obj)) return FALSE
+#define STRCMP(obj) if (strcmp(c1->obj,c2->obj)) return FALSE
static bool
starter_cmp_end(starter_end_t *c1, starter_end_t *c2)
@@ -45,12 +46,11 @@ starter_cmp_end(starter_end_t *c1, starter_end_t *c2)
ADDCMP(addr);
}
ADDCMP(nexthop);
- ADDCMP(srcip);
- SUBCMP(subnet);
VARCMP(has_client);
VARCMP(has_client_wildcard);
VARCMP(has_port_wildcard);
- VARCMP(has_srcip);
+ VARCMP(has_natip);
+ VARCMP(has_virt);
VARCMP(modecfg);
VARCMP(port);
VARCMP(protocol);
diff --git a/src/starter/confread.c b/src/starter/confread.c
index 7a312d893..df9be43bb 100644
--- a/src/starter/confread.c
+++ b/src/starter/confread.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: confread.c 3405 2007-12-19 00:49:32Z andreas $
+ * RCSID $Id: confread.c 4051 2008-06-10 09:08:27Z tobias $
*/
#include <stddef.h>
@@ -32,7 +32,7 @@
#include "interfaces.h"
/* strings containing a colon are interpreted as an IPv6 address */
-#define ip_version(string) (strchr(string, ':') != NULL)? AF_INET6 : AF_INET;
+#define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
static const char ike_defaults[] = "aes128-sha-modp2048";
static const char esp_defaults[] = "aes128-sha1, 3des-md5";
@@ -79,6 +79,8 @@ static void default_values(starter_config_t *cfg)
cfg->conn_default.sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT;
cfg->conn_default.addr_family = AF_INET;
cfg->conn_default.tunnel_addr_family = AF_INET;
+ cfg->conn_default.dpd_delay = 30; /* seconds */
+ cfg->conn_default.dpd_timeout = 150; /* seconds */
cfg->conn_default.left.seen = LEMPTY;
cfg->conn_default.right.seen = LEMPTY;
@@ -88,10 +90,8 @@ static void default_values(starter_config_t *cfg)
anyaddr(AF_INET, &cfg->conn_default.left.addr);
anyaddr(AF_INET, &cfg->conn_default.left.nexthop);
- anyaddr(AF_INET, &cfg->conn_default.left.srcip);
anyaddr(AF_INET, &cfg->conn_default.right.addr);
anyaddr(AF_INET, &cfg->conn_default.right.nexthop);
- anyaddr(AF_INET, &cfg->conn_default.right.srcip);
cfg->ca_default.seen = LEMPTY;
}
@@ -146,17 +146,91 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
if (!assign_arg(token, KW_END_FIRST, kw, (char *)end, &assigned))
goto err;
- if (token == KW_SENDCERT)
+ /* post processing of some keywords that were assigned automatically */
+ switch (token)
{
+ case KW_SUBNET:
+ if ((strlen(value) >= 6 && strncmp(value,"vhost:",6) == 0)
+ || (strlen(value) >= 5 && strncmp(value,"vnet:",5) == 0))
+ {
+ /* used by pluto only */
+ end->has_virt = TRUE;
+ }
+ else
+ {
+ ip_subnet net;
+ char *pos;
+ int len = 0;
+
+ end->has_client = TRUE;
+ conn->tunnel_addr_family = ip_version(value);
+
+ pos = strchr(value, ',');
+ if (pos)
+ {
+ len = pos - value;
+ }
+ ugh = ttosubnet(value, len, ip_version(value), &net);
+ if (ugh != NULL)
+ {
+ plog("# bad subnet: %s=%s [%s]", name, value, ugh);
+ goto err;
+ }
+ }
+ break;
+ case KW_SOURCEIP:
+ if (end->has_natip)
+ {
+ plog("# natip and sourceip cannot be defined at the same time");
+ goto err;
+ }
+ if (streq(value, "%modeconfig") || streq(value, "%modecfg") ||
+ streq(value, "%config") || streq(value, "%cfg"))
+ {
+ pfree(end->srcip);
+ end->srcip = NULL;
+ end->modecfg = TRUE;
+ }
+ else
+ {
+ ip_address addr;
+ ip_subnet net;
+
+ conn->tunnel_addr_family = ip_version(value);
+ if (strchr(value, '/'))
+ { /* CIDR notation, address pool */
+ ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &net);
+ }
+ else if (value[0] != '%')
+ { /* old style fixed srcip, a %poolname otherwise */
+ ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &addr);
+ }
+ if (ugh != NULL)
+ {
+ plog("# bad addr: %s=%s [%s]", name, value, ugh);
+ goto err;
+ }
+ }
+ conn->policy |= POLICY_TUNNEL;
+ break;
+ case KW_SENDCERT:
if (end->sendcert == CERT_YES_SEND)
+ {
end->sendcert = CERT_ALWAYS_SEND;
+ }
else if (end->sendcert == CERT_NO_SEND)
+ {
end->sendcert = CERT_NEVER_SEND;
+ }
+ break;
+ default:
+ break;
}
if (assigned)
return;
+ /* individual processing of keywords that were not assigned automatically */
switch (token)
{
case KW_HOST:
@@ -189,7 +263,6 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
conn->policy |= POLICY_GROUP | POLICY_TUNNEL;
anyaddr(conn->addr_family, &end->addr);
anyaddr(conn->tunnel_addr_family, &any);
- initsubnet(&any, 0, '0', &end->subnet);
end->has_client = TRUE;
}
else
@@ -243,69 +316,41 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
goto err;
}
break;
- case KW_SUBNET:
- if ((strlen(value) >= 6 && strncmp(value,"vhost:",6) == 0)
- || (strlen(value) >= 5 && strncmp(value,"vnet:",5) == 0))
- {
- end->virt = clone_str(value, "virt");
- }
- else
- {
- end->has_client = TRUE;
- conn->tunnel_addr_family = ip_version(value);
- ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &end->subnet);
- if (ugh != NULL)
- {
- plog("# bad subnet: %s=%s [%s]", name, value, ugh);
- goto err;
- }
- }
- break;
case KW_SUBNETWITHIN:
+ {
+ ip_subnet net;
+
end->has_client = TRUE;
end->has_client_wildcard = TRUE;
conn->tunnel_addr_family = ip_version(value);
- ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &end->subnet);
+
+ ugh = ttosubnet(value, 0, ip_version(value), &net);
+ if (ugh != NULL)
+ {
+ plog("# bad subnet: %s=%s [%s]", name, value, ugh);
+ goto err;
+ }
+ end->subnet = clone_str(value, "subnetwithin");
break;
+ }
case KW_PROTOPORT:
ugh = ttoprotoport(value, 0, &end->protocol, &end->port, &has_port_wildcard);
end->has_port_wildcard = has_port_wildcard;
break;
- case KW_SOURCEIP:
- if (end->has_natip)
- {
- plog("# natip and sourceip cannot be defined at the same time");
- goto err;
- }
- if (streq(value, "%modeconfig") || streq(value, "%modecfg") ||
- streq(value, "%config") || streq(value, "%cfg"))
- {
- end->modecfg = TRUE;
- }
- else
- {
- conn->tunnel_addr_family = ip_version(value);
- ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &end->srcip);
- if (ugh != NULL)
- {
- plog("# bad addr: %s=%s [%s]", name, value, ugh);
- goto err;
- }
- end->has_srcip = TRUE;
- }
- conn->policy |= POLICY_TUNNEL;
- break;
case KW_NATIP:
- if (end->has_srcip)
+ if (end->srcip)
{
plog("# natip and sourceip cannot be defined at the same time");
goto err;
}
if (streq(value, "%defaultroute"))
{
+ char buf[64];
+
if (cfg->defaultroute.defined)
{
- end->srcip = cfg->defaultroute.addr;
+ addrtot(&cfg->defaultroute.addr, 0, buf, sizeof(buf));
+ end->srcip = clone_str(buf, "natip");
}
else
{
@@ -315,13 +360,16 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
}
else
{
+ ip_address addr;
+
conn->tunnel_addr_family = ip_version(value);
- ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &end->srcip);
+ ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &addr);
if (ugh != NULL)
{
plog("# bad addr: %s=%s [%s]", name, value, ugh);
goto err;
}
+ end->srcip = clone_str(value, "srcip");
}
end->has_natip = TRUE;
conn->policy |= POLICY_TUNNEL;
@@ -487,10 +535,12 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
/* also handles the cases secret|rsasig and rsasig|secret */
for (;;)
{
- if (streq(value, "rsasig"))
+ if (streq(value, "rsa") || streq(value, "rsasig"))
conn->policy |= POLICY_RSASIG | POLICY_ENCRYPT;
else if (streq(value, "secret") || streq(value, "psk"))
conn->policy |= POLICY_PSK | POLICY_ENCRYPT;
+ else if (streq(value, "ecdsa") || streq(value, "ecdsasig"))
+ conn->policy |= POLICY_ECDSASIG | POLICY_ENCRYPT;
else if (streq(value, "xauthrsasig"))
conn->policy |= POLICY_XAUTH_RSASIG | POLICY_ENCRYPT;
else if (streq(value, "xauthpsk"))
diff --git a/src/starter/confread.h b/src/starter/confread.h
index a32e7116d..41f02476f 100644
--- a/src/starter/confread.h
+++ b/src/starter/confread.h
@@ -1,6 +1,4 @@
/* strongSwan IPsec config file parser
- * Copyright (C) 2007 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
* Copyright (C) 2001-2002 Mathieu Lafon
* Arkoon Network Security
*
@@ -14,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: confread.h 3394 2007-12-13 17:31:21Z martin $
+ * RCSID $Id: confread.h 3932 2008-05-12 10:05:49Z andreas $
*/
#ifndef _IPSEC_CONFREAD_H_
@@ -67,13 +65,12 @@ struct starter_end {
char *iface;
ip_address addr;
ip_address nexthop;
- ip_address srcip;
- ip_subnet subnet;
+ char *subnet;
bool has_client;
bool has_client_wildcard;
bool has_port_wildcard;
- bool has_srcip;
bool has_natip;
+ bool has_virt;
bool modecfg;
certpolicy_t sendcert;
bool firewall;
@@ -83,7 +80,7 @@ struct starter_end {
char *updown;
u_int16_t port;
u_int8_t protocol;
- char *virt;
+ char *srcip;
};
typedef struct also also_t;
@@ -130,9 +127,9 @@ struct starter_conn {
dpd_action_t dpd_action;
int dpd_count;
- bool p2p_mediation;
- char *p2p_mediated_by;
- char *p2p_peerid;
+ bool me_mediation;
+ char *me_mediated_by;
+ char *me_peerid;
starter_conn_t *next;
};
@@ -155,6 +152,7 @@ struct starter_ca {
char *crluri2;
char *ocspuri;
char *ocspuri2;
+ char *certuribase;
bool strict;
@@ -176,6 +174,7 @@ struct starter_config {
char *charondebug;
char *prepluto;
char *postpluto;
+ char *plutostderrlog;
bool uniqueids;
u_int overridemtu;
u_int crlcheckinterval;
@@ -184,8 +183,8 @@ struct starter_config {
bool nocrsend;
bool nat_traversal;
u_int keep_alive;
+ u_int force_keepalive;
char *virtual_private;
- char *eapdir;
char *pkcs11module;
char *pkcs11initargs;
bool pkcs11keepstate;
diff --git a/src/starter/invokecharon.c b/src/starter/invokecharon.c
index 111bb9c6f..849a0af32 100644
--- a/src/starter/invokecharon.c
+++ b/src/starter/invokecharon.c
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: invokecharon.c 3344 2007-11-15 18:34:05Z martin $
+ * RCSID $Id: invokecharon.c 3928 2008-05-11 07:59:00Z andreas $
*/
#include <sys/types.h>
@@ -101,11 +101,11 @@ starter_stop_charon (void)
int
-starter_start_charon (starter_config_t *cfg, bool debug)
+starter_start_charon (starter_config_t *cfg, bool no_fork)
{
- int pid, i;
struct stat stb;
- char buffer[BUF_LEN], buffer1[BUF_LEN];
+ int pid, i;
+ char buffer[BUF_LEN];
int argc = 1;
char *arg[] = {
CHARON_CMD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -114,30 +114,10 @@ starter_start_charon (starter_config_t *cfg, bool debug)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
- if (!debug)
+ if (!no_fork)
{
arg[argc++] = "--use-syslog";
}
- if (cfg->setup.strictcrlpolicy)
- {
- arg[argc++] = "--strictcrlpolicy";
- arg[argc++] = cfg->setup.strictcrlpolicy == STRICT_IFURI ? "2":"1";
- }
- if (cfg->setup.cachecrls)
- {
- arg[argc++] = "--cachecrls";
- }
- if (cfg->setup.crlcheckinterval > 0)
- {
- snprintf(buffer1, BUF_LEN, "%u", cfg->setup.crlcheckinterval);
- arg[argc++] = "--crlcheckinterval";
- arg[argc++] = buffer1;
- }
- if (cfg->setup.eapdir)
- {
- arg[argc++] = "--eapdir";
- arg[argc++] = cfg->setup.eapdir;
- }
{ /* parse debug string */
char *pos, *level, *buf_pos, type[4];
@@ -179,34 +159,6 @@ starter_start_charon (starter_config_t *cfg, bool debug)
unlink(CHARON_CTL_FILE);
_stop_requested = 0;
- /* if ipsec.secrets file is missing then generate RSA default key pair */
- if (stat(SECRETS_FILE, &stb) != 0)
- {
- mode_t oldmask;
- FILE *f;
-
- plog("no %s file, generating RSA key", SECRETS_FILE);
- seteuid(IPSEC_UID);
- setegid(IPSEC_GID);
- system("ipsec scepclient --out pkcs1 --out cert-self --quiet");
- seteuid(0);
- setegid(0);
-
- /* ipsec.secrets is root readable only */
- oldmask = umask(0066);
-
- f = fopen(SECRETS_FILE, "w");
- if (f)
- {
- fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n");
- fprintf(f, "\n");
- fprintf(f, ": RSA myKey.der\n");
- fclose(f);
- }
- chown(SECRETS_FILE, IPSEC_UID, IPSEC_GID);
- umask(oldmask);
- }
-
pid = fork();
switch (pid)
{
diff --git a/src/starter/invokepluto.c b/src/starter/invokepluto.c
index 5234722be..a3cf3a786 100644
--- a/src/starter/invokepluto.c
+++ b/src/starter/invokepluto.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: invokepluto.c 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: invokepluto.c 3942 2008-05-13 07:37:08Z martin $
*/
#include <sys/types.h>
@@ -21,6 +21,7 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
+#include <fcntl.h>
#include <freeswan.h>
@@ -104,10 +105,10 @@ starter_stop_pluto (void)
}
int
-starter_start_pluto (starter_config_t *cfg, bool debug)
+starter_start_pluto (starter_config_t *cfg, bool no_fork)
{
- int i;
struct stat stb;
+ int i;
pid_t pid;
char **l;
int argc = 2;
@@ -121,7 +122,7 @@ starter_start_pluto (starter_config_t *cfg, bool debug)
printf ("starter_start_pluto entered\n");
- if (debug)
+ if (cfg->setup.plutostderrlog || no_fork)
{
arg[argc++] = "--stderrlog";
}
@@ -167,6 +168,10 @@ starter_start_pluto (starter_config_t *cfg, bool debug)
{
arg[argc++] = "--nat_traversal";
}
+ if (cfg->setup.force_keepalive)
+ {
+ arg[argc++] = "--force_keepalive";
+ }
if (cfg->setup.keep_alive)
{
static char buf2[15];
@@ -175,13 +180,11 @@ starter_start_pluto (starter_config_t *cfg, bool debug)
snprintf(buf2, sizeof(buf2), "%u", cfg->setup.keep_alive);
arg[argc++] = buf2;
}
-#ifdef VIRTUAL_IP
if (cfg->setup.virtual_private)
{
arg[argc++] = "--virtual_private";
arg[argc++] = cfg->setup.virtual_private;
}
-#endif
if (cfg->setup.pkcs11module)
{
arg[argc++] = "--pkcs11module";
@@ -214,34 +217,6 @@ starter_start_pluto (starter_config_t *cfg, bool debug)
if (cfg->setup.prepluto)
system(cfg->setup.prepluto);
- /* if ipsec.secrets file is missing then generate RSA default key pair */
- if (stat(SECRETS_FILE, &stb) != 0)
- {
- mode_t oldmask;
- FILE *f;
-
- plog("no %s file, generating RSA key", SECRETS_FILE);
- seteuid(IPSEC_UID);
- setegid(IPSEC_GID);
- system("ipsec scepclient --out pkcs1 --out cert-self --quiet");
- seteuid(0);
- setegid(0);
-
- /* ipsec.secrets is root readable only */
- oldmask = umask(0066);
-
- f = fopen(SECRETS_FILE, "w");
- if (f)
- {
- fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n");
- fprintf(f, "\n");
- fprintf(f, ": RSA myKey.der\n");
- fclose(f);
- }
- chown(SECRETS_FILE, IPSEC_UID, IPSEC_GID);
- umask(oldmask);
- }
-
pid = fork();
switch (pid)
{
@@ -250,6 +225,21 @@ starter_start_pluto (starter_config_t *cfg, bool debug)
return -1;
case 0:
/* child */
+ if (cfg->setup.plutostderrlog)
+ {
+ int f = creat(cfg->setup.plutostderrlog, 00644);
+
+ /* redirect stderr to file */
+ if (f < 0)
+ {
+ plog("couldn't open stderr redirection file '%s'",
+ cfg->setup.plutostderrlog);
+ }
+ else
+ {
+ dup2(f, 2);
+ }
+ }
setsid();
sigprocmask(SIG_SETMASK, 0, NULL);
execv(arg[0], arg);
diff --git a/src/starter/ipsec.conf.5 b/src/starter/ipsec.conf.5
index d542af555..bf8bcc0d2 100644
--- a/src/starter/ipsec.conf.5
+++ b/src/starter/ipsec.conf.5
@@ -1,5 +1,5 @@
.TH IPSEC.CONF 5 "27 Jun 2007"
-.\" RCSID $Id: ipsec.conf.5 3394 2007-12-13 17:31:21Z martin $
+.\" RCSID $Id: ipsec.conf.5 3934 2008-05-12 12:46:30Z andreas $
.SH NAME
ipsec.conf \- IPsec configuration and connections
.SH DESCRIPTION
@@ -373,7 +373,7 @@ for the connection, e.g.
(encryption-integrity-[dh-group]). If dh-group is specified, CHILD_SA setup
and rekeying include a separate diffe hellman exchange (IKEv2 only).
.TP
-.B force_encap
+.B forceencaps
Force UDP encapsulation for ESP packets even if no NAT situation is detected.
This may help to hurdle restrictive firewalls. To enforce the peer to
encapsulate packets, NAT detection payloads are faked (IKEv2 only).
@@ -633,7 +633,10 @@ The internal source IP to use in a tunnel for the remote peer. If the
value is
.B %config
on the responder side, the initiator must propose a address which is then echoed
-back.
+back. The IKEv2 daemon also supports address pools expressed as
+\fInetwork\fB/\fInetmask\fR
+or the use of an external IP address pool using %\fIpoolname\fR
+, where \fIpoolname\fR is the name of the IP address pool used for the lookup.
.TP
.B leftsubnet
private subnet behind the left participant, expressed as
@@ -643,7 +646,9 @@ private subnet behind the left participant, expressed as
if omitted, essentially assumed to be \fIleft\fB/32\fR,
signifying that the left end of the connection goes to the left participant
only. When using IKEv2, the configured subnet of the peers may differ, the
-protocol narrows it to the greates common subnet.
+protocol narrows it to the greatest common subnet. Further, IKEv2 supports
+multiple subnets separated by commas. IKEv1 only interprets the first subnet
+of such a definition.
.TP
.B leftsubnetwithin
the peer can propose any subnet or single IP address that fits within the
@@ -788,31 +793,31 @@ and
.B client
(the default).
-.SS "CONN PARAMETERS: PEER-TO-PEER"
-The following parameters are relevant to Peer-to-Peer NAT-T operation
-only.
+.SS "CONN PARAMETERS: IKEv2 MEDIATION EXTENSION"
+The following parameters are relevant to IKEv2 Mediation Extension
+operation only.
.TP 14
-.B p2p_mediation
-whether this connection is a P2P mediation connection, ie. whether this
+.B mediation
+whether this connection is a mediation connection, ie. whether this
connection is used to mediate other connections. Mediation connections
create no child SA. Acceptable values are
.B no
(the default) and
.BR yes .
.TP
-.B p2p_mediated_by
+.B mediated_by
the name of the connection to mediate this connection through. If given,
the connection will be mediated through the named mediation connection.
The mediation connection must set
-.BR p2p_mediation=yes .
+.BR mediation=yes .
.TP
-.B p2p_peerid
+.B me_peerid
ID as which the peer is known to the mediation server, ie. which the other
end of this connection uses as its
.B leftid
on its connection to the mediation server. This is the ID we request the
mediation server to mediate us with. If
-.B p2p_peerid
+.B me_peerid
is not given, the
.B rightid
of this connection will be used as peer ID.
@@ -855,6 +860,11 @@ synonym for
.TP
.B ocspuri2
defines an alternative OCSP URI. Currently used by IKEv2 only.
+.B certuribase
+defines the base URI for the Hash and URL feature supported by IKEv2.
+Instead of exchanging complete certificates, IKEv2 allows to send an URI
+that resolves to the DER encoded certificate. The certificate URIs are built
+by appending the SHA1 hash of the DER encoded certificates to this base URI.
.SH "CONFIG SECTIONS"
At present, the only
.B config
@@ -882,7 +892,7 @@ The currently-accepted
names in a
.B config
.B setup
-section are:
+section affecting both daemons are:
.TP 14
.B cachecrls
certificate revocation lists (CRLs) fetched via http or ldap will be cached in
@@ -902,11 +912,6 @@ Accepted values are
or
.BR no .
.TP
-.B crlcheckinterval
-interval in seconds. CRL fetching is enabled if the value is greater than zero.
-Asynchronous, periodic checking for fresh CRLs is currently done by the
-IKEv1 Pluto daemon only.
-.TP
.B dumpdir
in what directory should things started by \fBipsec starter\fR
(notably the Pluto and Charon daemons) be allowed to dump core?
@@ -937,11 +942,37 @@ which reverts to
if at least one CRL URI is defined and to
.B no
if no URI is known.
+.TP
+.B uniqueids
+whether a particular participant ID should be kept unique,
+with any new (automatically keyed)
+connection using an ID from a different IP address
+deemed to replace all old ones using that ID;
+acceptable values are
+.B yes
+(the default)
+and
+.BR no .
+Participant IDs normally \fIare\fR unique,
+so a new (automatically-keyed) connection using the same ID is
+almost invariably intended to replace an old one.
+The IKEv2 daemon also accepts the value
+.B replace
+wich is identical to
+.B yes
+and the value
+.B keep
+to reject new IKE_SA setups and keep the duplicate established earlier.
.PP
The following
.B config section
parameters are used by the IKEv1 Pluto daemon only:
.TP
+.B crlcheckinterval
+interval in seconds. CRL fetching is enabled if the value is greater than zero.
+Asynchronous, periodic checking for fresh CRLs is currently done by the
+IKEv1 Pluto daemon only.
+.TP
.B keep_alive
interval in seconds between NAT keep alive packets, the default being 20 seconds.
.TP
@@ -1004,6 +1035,10 @@ separated by white space) are enabled;
for details on available debugging types, see
.IR pluto (8).
.TP
+.B plutostderrlog
+Pluto will not use syslog, but rather log to stderr, and redirect stderr
+to the argument file.
+.TP
.B postpluto
shell command to run after starting Pluto
(e.g., to remove a decrypted copy of the
@@ -1032,20 +1067,6 @@ Default is none.
.TP
.B virtual_private
defines private networks using a wildcard notation.
-.TP
-.B uniqueids
-whether a particular participant ID should be kept unique,
-with any new (automatically keyed)
-connection using an ID from a different IP address
-deemed to replace all old ones using that ID;
-acceptable values are
-.B yes
-(the default)
-and
-.BR no .
-Participant IDs normally \fIare\fR unique,
-so a new (automatically-keyed) connection using the same ID is
-almost invariably intended to replace an old one.
.PP
The following
.B config section
diff --git a/src/starter/keywords.c b/src/starter/keywords.c
index 0d3e850bb..b96019d83 100644
--- a/src/starter/keywords.c
+++ b/src/starter/keywords.c
@@ -1,4 +1,4 @@
-/* C code produced by gperf version 3.0.1 */
+/* C code produced by gperf version 3.0.3 */
/* Command-line: /usr/bin/gperf -C -G -t */
/* Computed positions: -k'1-2,$' */
@@ -31,7 +31,6 @@ error "gperf generated tables don't work with this execution character set. Plea
/* strongSwan keywords
- * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005 Andreas Steffen
* Hochschule fuer Technik Rapperswil, Switzerland
*
@@ -45,7 +44,7 @@ error "gperf generated tables don't work with this execution character set. Plea
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keywords.txt 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: keywords.txt 3928 2008-05-11 07:59:00Z andreas $
*/
#include <string.h>
@@ -57,12 +56,12 @@ struct kw_entry {
kw_token_t token;
};
-#define TOTAL_KEYWORDS 98
+#define TOTAL_KEYWORDS 100
#define MIN_WORD_LENGTH 3
#define MAX_WORD_LENGTH 17
-#define MIN_HASH_VALUE 15
-#define MAX_HASH_VALUE 236
-/* maximum key range = 222, duplicates = 0 */
+#define MIN_HASH_VALUE 6
+#define MAX_HASH_VALUE 263
+/* maximum key range = 258, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -76,191 +75,194 @@ hash (str, len)
register const char *str;
register unsigned int len;
{
- static const unsigned char asso_values[] =
+ static const unsigned short asso_values[] =
{
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 40,
- 5, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 90, 237, 25,
- 75, 5, 85, 0, 95, 0, 237, 55, 0, 45,
- 0, 70, 20, 237, 15, 70, 40, 20, 5, 237,
- 5, 65, 0, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, 237, 237, 237
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 10,
+ 0, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 15, 264, 0,
+ 100, 5, 90, 85, 60, 0, 264, 60, 10, 55,
+ 80, 75, 15, 264, 0, 50, 35, 5, 25, 264,
+ 10, 75, 0, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 264, 264, 264
};
return len + asso_values[(unsigned char)str[1]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
}
static const struct kw_entry wordlist[] =
{
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
{""}, {""}, {""}, {""}, {""}, {""},
- {"leftupdown", KW_LEFTUPDOWN},
- {""},
- {"leftfirewall", KW_LEFTFIREWALL},
- {""}, {""}, {""},
- {"leftsubnetwithin", KW_LEFTSUBNETWITHIN},
+ {"crluri", KW_CRLURI},
+ {"crluri2", KW_CRLURI2},
+ {""}, {""}, {""}, {""}, {""}, {""},
+ {"rekeyfuzz", KW_REKEYFUZZ},
+ {""}, {""},
+ {"crluri1", KW_CRLURI},
{""}, {""}, {""},
- {"virtual_private", KW_VIRTUAL_PRIVATE},
- {"rightupdown", KW_RIGHTUPDOWN},
- {""},
+ {"certuribase", KW_CERTURIBASE},
+ {"rightca", KW_RIGHTCA},
{"rightfirewall", KW_RIGHTFIREWALL},
- {"rekeyfuzz", KW_REKEYFUZZ},
- {"plutodebug", KW_PLUTODEBUG},
- {"rekeymargin", KW_REKEYMARGIN},
- {"rightsubnetwithin", KW_RIGHTSUBNETWITHIN},
- {""},
- {"leftnatip", KW_LEFTNATIP},
{""},
- {"leftnexthop", KW_LEFTNEXTHOP},
- {"leftsourceip", KW_LEFTSOURCEIP},
- {"p2p_mediation", KW_P2P_MEDIATION},
- {""}, {""}, {""}, {""}, {""}, {""},
{"rightnatip", KW_RIGHTNATIP},
- {"crluri", KW_CRLURI},
+ {"crlcheckinterval", KW_CRLCHECKINTERVAL},
{"rightnexthop", KW_RIGHTNEXTHOP},
{"rightsourceip", KW_RIGHTSOURCEIP},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {"leftca", KW_LEFTCA},
+ {"leftfirewall", KW_LEFTFIREWALL},
+ {"eap", KW_EAP},
+ {"leftnatip", KW_LEFTNATIP},
+ {"right", KW_RIGHT},
+ {"leftnexthop", KW_LEFTNEXTHOP},
+ {"leftsourceip", KW_LEFTSOURCEIP},
+ {""},
+ {"rightcert", KW_RIGHTCERT},
+ {"virtual_private", KW_VIRTUAL_PRIVATE},
+ {"rightsubnet", KW_RIGHTSUBNET},
+ {""},
+ {"rightsendcert", KW_RIGHTSENDCERT},
+ {"rightprotoport", KW_RIGHTPROTOPORT},
+ {""}, {""}, {""}, {""},
{"left", KW_LEFT},
- {""}, {""},
- {"crluri2", KW_CRLURI2},
+ {""},
+ {"cacert", KW_CACERT},
+ {""},
{"leftcert", KW_LEFTCERT,},
{""},
{"leftsubnet", KW_LEFTSUBNET},
- {"crlcheckinterval", KW_CRLCHECKINTERVAL},
+ {"rightgroups", KW_RIGHTGROUPS},
{"leftsendcert", KW_LEFTSENDCERT},
{"leftprotoport", KW_LEFTPROTOPORT},
{""},
- {"right", KW_RIGHT},
+ {"righthostaccess", KW_RIGHTHOSTACCESS},
{""}, {""},
{"ike", KW_IKE},
- {"rightcert", KW_RIGHTCERT},
- {"klipsdebug", KW_KLIPSDEBUG},
- {"rightsubnet", KW_RIGHTSUBNET},
{""},
- {"rightsendcert", KW_RIGHTSENDCERT},
- {"rightprotoport", KW_RIGHTPROTOPORT},
{"plutostart", KW_PLUTOSTART},
+ {"reauth", KW_REAUTH},
+ {""},
+ {"esp", KW_ESP},
+ {"cachecrls", KW_CACHECRLS},
+ {"leftgroups", KW_LEFTGROUPS},
{"ikelifetime", KW_IKELIFETIME},
{"keylife", KW_KEYLIFE},
- {""}, {""},
+ {"packetdefault", KW_PACKETDEFAULT},
+ {"lefthostaccess", KW_LEFTHOSTACCESS},
{"keep_alive", KW_KEEP_ALIVE},
{"keyexchange", KW_KEYEXCHANGE},
- {""}, {""}, {""},
- {"interfaces", KW_INTERFACES},
- {""},
- {"leftallowany", KW_LEFTALLOWANY},
- {"leftrsasigkey", KW_LEFTRSASIGKEY},
- {""},
- {"leftgroups", KW_LEFTGROUPS},
- {"leftid", KW_LEFTID},
- {"crluri1", KW_CRLURI},
- {"ldapbase", KW_LDAPBASE},
- {"lefthostaccess", KW_LEFTHOSTACCESS},
+ {"ocspuri", KW_OCSPURI},
+ {"ocspuri2", KW_OCSPURI2},
+ {"auth", KW_AUTH},
{"rekey", KW_REKEY},
- {""},
- {"pkcs11module", KW_PKCS11MODULE},
+ {""}, {""},
{"rightallowany", KW_RIGHTALLOWANY},
{"rightrsasigkey", KW_RIGHTRSASIGKEY},
- {"pkcs11keepstate", KW_PKCS11KEEPSTATE},
- {"rightgroups", KW_RIGHTGROUPS},
- {"rightid", KW_RIGHTID},
- {"esp", KW_ESP},
- {"uniqueids", KW_UNIQUEIDS},
- {"righthostaccess", KW_RIGHTHOSTACCESS},
- {"leftca", KW_LEFTCA},
- {"ocspuri", KW_OCSPURI},
- {"nat_traversal", KW_NAT_TRAVERSAL},
- {"dpdaction", KW_DPDACTION},
- {"p2p_mediated_by", KW_P2P_MEDIATED_BY},
- {"overridemtu", KW_OVERRIDEMTU},
- {""},
- {"ocspuri2", KW_OCSPURI2},
- {""},
- {"p2p_peerid", KW_P2P_PEERID},
+ {"xauth", KW_XAUTH},
+ {"rightupdown", KW_RIGHTUPDOWN},
+ {"pkcs11module", KW_PKCS11MODULE},
+ {"ocspuri1", KW_OCSPURI},
{""},
- {"rightca", KW_RIGHTCA},
+ {"pkcs11keepstate", KW_PKCS11KEEPSTATE},
+ {"rekeymargin", KW_REKEYMARGIN},
+ {"rightsubnetwithin", KW_RIGHTSUBNETWITHIN},
{"prepluto", KW_PREPLUTO},
- {"type", KW_TYPE},
+ {"auto", KW_AUTO},
{""},
- {"eapdir", KW_EAPDIR},
+ {"authby", KW_AUTHBY},
+ {"leftallowany", KW_LEFTALLOWANY},
+ {"leftrsasigkey", KW_LEFTRSASIGKEY},
+ {"also", KW_ALSO},
+ {"leftupdown", KW_LEFTUPDOWN},
+ {"charonstart", KW_CHARONSTART},
+ {"rightid", KW_RIGHTID},
+ {""}, {""}, {""},
+ {"leftsubnetwithin", KW_LEFTSUBNETWITHIN},
{"dumpdir", KW_DUMPDIR},
- {"eap", KW_EAP},
+ {"fragicmp", KW_FRAGICMP},
{""}, {""},
- {"reauth", KW_REAUTH},
+ {"overridemtu", KW_OVERRIDEMTU},
+ {"hidetos", KW_HIDETOS},
+ {"nat_traversal", KW_NAT_TRAVERSAL},
+ {"type", KW_TYPE},
+ {"plutodebug", KW_PLUTODEBUG},
+ {"leftid", KW_LEFTID},
{""},
- {"ldaphost", KW_LDAPHOST},
+ {"ldapbase", KW_LDAPBASE},
+ {"plutostderrlog", KW_PLUTOSTDERRLOG},
{""},
- {"modeconfig", KW_MODECONFIG},
+ {"keyingtries", KW_KEYINGTRIES},
+ {""},
+ {"pfsgroup", KW_PFSGROUP},
+ {""}, {""}, {""}, {""},
+ {"compress", KW_COMPRESS},
+ {""}, {""}, {""}, {""}, {""},
+ {"pkcs11initargs", KW_PKCS11INITARGS},
+ {"interfaces", KW_INTERFACES},
{"mobike", KW_MOBIKE},
+ {""}, {""},
+ {"uniqueids", KW_UNIQUEIDS},
{""},
- {"fragicmp", KW_FRAGICMP},
+ {"mediated_by", KW_MEDIATED_BY},
+ {""}, {""},
+ {"mediation", KW_MEDIATION},
+ {""}, {""}, {""},
+ {"ldaphost", KW_LDAPHOST},
{""}, {""},
{"charondebug", KW_CHARONDEBUG},
{""},
- {"pfsgroup", KW_PFSGROUP},
- {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {"keyingtries", KW_KEYINGTRIES},
- {""},
- {"ocspuri1", KW_OCSPURI},
+ {"pfs", KW_PFS},
{""},
{"dpdtimeout", KW_DPDTIMEOUT},
- {""}, {""}, {""}, {""}, {""},
{"pkcs11proxy", KW_PKCS11PROXY},
- {""},
- {"nocrsend", KW_NOCRSEND},
- {""}, {""}, {""}, {""}, {""},
- {"pkcs11initargs", KW_PKCS11INITARGS},
- {""},
- {"cacert", KW_CACERT},
- {""},
- {"packetdefault", KW_PACKETDEFAULT},
- {"also", KW_ALSO},
{""}, {""}, {""},
- {"dpddelay", KW_DPDDELAY},
- {"postpluto", KW_POSTPLUTO},
- {""},
- {"charonstart", KW_CHARONSTART},
- {"hidetos", KW_HIDETOS},
- {"compress", KW_COMPRESS},
+ {"klipsdebug", KW_KLIPSDEBUG},
+ {""}, {""}, {""},
+ {"me_peerid", KW_ME_PEERID},
{""}, {""}, {""}, {""},
- {"pfs", KW_PFS},
- {""}, {""},
- {"authby", KW_AUTHBY},
- {""}, {""},
- {"auto", KW_AUTO},
- {""}, {""}, {""}, {""}, {""},
+ {"postpluto", KW_POSTPLUTO},
{"strictcrlpolicy", KW_STRICTCRLPOLICY},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {"force_keepalive", KW_FORCE_KEEPALIVE},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
{""}, {""}, {""},
- {"cachecrls", KW_CACHECRLS},
- {"xauth", KW_XAUTH},
+ {"dpddelay", KW_DPDDELAY},
+ {""}, {""}, {""}, {""}, {""},
+ {"dpdaction", KW_DPDACTION},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {""}, {""},
+ {"modeconfig", KW_MODECONFIG},
+ {"forceencaps", KW_FORCEENCAPS},
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {""}, {""}, {""}, {""},
- {"auth", KW_AUTH},
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {"forceencaps", KW_FORCEENCAPS}
+ {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+ {"nocrsend", KW_NOCRSEND}
};
#ifdef __GNUC__
__inline
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
#endif
const struct kw_entry *
in_word_set (str, len)
diff --git a/src/starter/keywords.h b/src/starter/keywords.h
index 7973dfae7..39b544267 100644
--- a/src/starter/keywords.h
+++ b/src/starter/keywords.h
@@ -1,5 +1,4 @@
/* strongSwan keywords
- * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005 Andreas Steffen
* Hochschule fuer Technik Rapperswil, Switzerland
*
@@ -13,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keywords.h 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: keywords.h 3928 2008-05-11 07:59:00Z andreas $
*/
#ifndef _KEYWORDS_H_
@@ -31,6 +30,7 @@ typedef enum {
KW_CHARONDEBUG,
KW_PREPLUTO,
KW_POSTPLUTO,
+ KW_PLUTOSTDERRLOG,
KW_UNIQUEIDS,
KW_OVERRIDEMTU,
KW_CRLCHECKINTERVAL,
@@ -39,8 +39,8 @@ typedef enum {
KW_NOCRSEND,
KW_NAT_TRAVERSAL,
KW_KEEP_ALIVE,
+ KW_FORCE_KEEPALIVE,
KW_VIRTUAL_PRIVATE,
- KW_EAPDIR,
KW_PKCS11MODULE,
KW_PKCS11INITARGS,
KW_PKCS11KEEPSTATE,
@@ -88,12 +88,12 @@ typedef enum {
KW_DPDACTION,
KW_MODECONFIG,
KW_XAUTH,
- KW_P2P_MEDIATION,
- KW_P2P_MEDIATED_BY,
- KW_P2P_PEERID,
+ KW_MEDIATION,
+ KW_MEDIATED_BY,
+ KW_ME_PEERID,
#define KW_CONN_FIRST KW_CONN_SETUP
-#define KW_CONN_LAST KW_P2P_PEERID
+#define KW_CONN_LAST KW_ME_PEERID
/* ca section keywords */
KW_CA_NAME,
@@ -105,9 +105,10 @@ typedef enum {
KW_CRLURI2,
KW_OCSPURI,
KW_OCSPURI2,
+ KW_CERTURIBASE,
#define KW_CA_FIRST KW_CA_SETUP
-#define KW_CA_LAST KW_OCSPURI2
+#define KW_CA_LAST KW_CERTURIBASE
/* end keywords */
KW_HOST,
diff --git a/src/starter/keywords.txt b/src/starter/keywords.txt
index 5f7422d0d..d0435d1c7 100644
--- a/src/starter/keywords.txt
+++ b/src/starter/keywords.txt
@@ -1,6 +1,5 @@
%{
/* strongSwan keywords
- * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005 Andreas Steffen
* Hochschule fuer Technik Rapperswil, Switzerland
*
@@ -14,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: keywords.txt 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: keywords.txt 3928 2008-05-11 07:59:00Z andreas $
*/
#include <string.h>
@@ -36,6 +35,7 @@ plutodebug, KW_PLUTODEBUG
charondebug, KW_CHARONDEBUG
prepluto, KW_PREPLUTO
postpluto, KW_POSTPLUTO
+plutostderrlog, KW_PLUTOSTDERRLOG
fragicmp, KW_FRAGICMP
packetdefault, KW_PACKETDEFAULT
hidetos, KW_HIDETOS
@@ -47,9 +47,9 @@ strictcrlpolicy, KW_STRICTCRLPOLICY
nocrsend, KW_NOCRSEND
nat_traversal, KW_NAT_TRAVERSAL
keep_alive, KW_KEEP_ALIVE
+force_keepalive, KW_FORCE_KEEPALIVE
virtual_private, KW_VIRTUAL_PRIVATE
eap, KW_EAP
-eapdir, KW_EAPDIR
mobike, KW_MOBIKE
forceencaps, KW_FORCEENCAPS
pkcs11module, KW_PKCS11MODULE
@@ -77,9 +77,9 @@ dpdtimeout, KW_DPDTIMEOUT
dpdaction, KW_DPDACTION
modeconfig, KW_MODECONFIG
xauth, KW_XAUTH
-p2p_mediation, KW_P2P_MEDIATION
-p2p_mediated_by, KW_P2P_MEDIATED_BY
-p2p_peerid, KW_P2P_PEERID
+mediation, KW_MEDIATION
+mediated_by, KW_MEDIATED_BY
+me_peerid, KW_ME_PEERID
cacert, KW_CACERT
ldaphost, KW_LDAPHOST
ldapbase, KW_LDAPBASE
@@ -89,6 +89,7 @@ crluri2, KW_CRLURI2
ocspuri, KW_OCSPURI
ocspuri1, KW_OCSPURI
ocspuri2, KW_OCSPURI2
+certuribase, KW_CERTURIBASE
left, KW_LEFT
leftnexthop, KW_LEFTNEXTHOP
leftsubnet, KW_LEFTSUBNET
diff --git a/src/starter/lex.yy.c b/src/starter/lex.yy.c
index 3e55a4530..cd3535318 100644
--- a/src/starter/lex.yy.c
+++ b/src/starter/lex.yy.c
@@ -8,7 +8,7 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 33
+#define YY_FLEX_SUBMINOR_VERSION 34
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@@ -30,7 +30,7 @@
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-#if __STDC_VERSION__ >= 199901L
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
* if you want the limit (max/min) macros for int types.
@@ -93,11 +93,12 @@ typedef unsigned int flex_uint32_t;
#else /* ! __cplusplus */
-#if __STDC__
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
#define YY_USE_CONST
-#endif /* __STDC__ */
+#endif /* defined (__STDC__) */
#endif /* ! __cplusplus */
#ifdef YY_USE_CONST
@@ -180,11 +181,13 @@ extern FILE *yyin, *yyout;
/* The following is because we cannot portably get our hands on size_t
* (without autoconf's help, which isn't available because we want
* flex-generated scanners to compile on their own).
+ * Given that the standard has decreed that size_t exists since 1989,
+ * I guess we can afford to depend on it. Manoj.
*/
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
+typedef size_t yy_size_t;
#endif
#ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -614,7 +617,7 @@ int _parser_y_include (const char *filename)
return 0;
}
-#line 618 "lex.yy.c"
+#line 621 "lex.yy.c"
#define INITIAL 0
@@ -644,8 +647,6 @@ extern int yywrap (void );
#endif
#endif
- static void yyunput (int c,char *buf_ptr );
-
#ifndef yytext_ptr
static void yy_flex_strncpy (char *,yyconst char *,int );
#endif
@@ -674,7 +675,7 @@ static int input (void );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -685,7 +686,7 @@ static int input (void );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- size_t n; \
+ int n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -773,7 +774,7 @@ YY_DECL
#line 134 "parser.l"
-#line 777 "lex.yy.c"
+#line 778 "lex.yy.c"
if ( !(yy_init) )
{
@@ -957,7 +958,7 @@ YY_RULE_SETUP
#line 184 "parser.l"
ECHO;
YY_BREAK
-#line 961 "lex.yy.c"
+#line 962 "lex.yy.c"
case YY_END_OF_BUFFER:
{
@@ -1186,7 +1187,7 @@ static int yy_get_next_buffer (void)
/* Read in more data. */
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- (yy_n_chars), num_to_read );
+ (yy_n_chars), (size_t) num_to_read );
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
}
@@ -1210,6 +1211,14 @@ static int yy_get_next_buffer (void)
else
ret_val = EOB_ACT_CONTINUE_SCAN;
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
(yy_n_chars) += number_to_move;
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
@@ -1277,43 +1286,6 @@ static int yy_get_next_buffer (void)
return yy_is_jam ? 0 : yy_current_state;
}
- static void yyunput (int c, register char * yy_bp )
-{
- register char *yy_cp;
-
- yy_cp = (yy_c_buf_p);
-
- /* undo effects of setting up yytext */
- *yy_cp = (yy_hold_char);
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- register int number_to_move = (yy_n_chars) + 2;
- register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
- register char *source =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
- (yytext_ptr) = yy_bp;
- (yy_hold_char) = *yy_cp;
- (yy_c_buf_p) = yy_cp;
-}
-
#ifndef YY_NO_INPUT
#ifdef __cplusplus
static int yyinput (void)
@@ -1500,19 +1472,9 @@ static void yy_load_buffer_state (void)
yyfree((void *) b );
}
-#ifndef _UNISTD_H /* assume unistd.h has isatty() for us */
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __THROW /* this is a gnuism */
-extern int isatty (int ) __THROW;
-#else
+#ifndef __cplusplus
extern int isatty (int );
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
+#endif /* __cplusplus */
/* Initializes or reinitializes a buffer.
* This function is sometimes called more than once on the same buffer,
@@ -1638,7 +1600,9 @@ static void yyensure_buffer_stack (void)
(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
);
-
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
(yy_buffer_stack_max) = num_to_alloc;
@@ -1656,6 +1620,8 @@ static void yyensure_buffer_stack (void)
((yy_buffer_stack),
num_to_alloc * sizeof(struct yy_buffer_state*)
);
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
/* zero only the new slots.*/
memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -1700,7 +1666,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
/** Setup the input buffer state to scan a string. The next call to yylex() will
* scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
+ * @param yystr a NUL-terminated string to scan
*
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
diff --git a/src/starter/starter.c b/src/starter/starter.c
index bc2e8f1df..6ff0ac29c 100644
--- a/src/starter/starter.c
+++ b/src/starter/starter.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: starter.c 3369 2007-11-28 17:02:12Z andreas $
+ * RCSID $Id: starter.c 3914 2008-05-08 10:58:04Z martin $
*/
#include <sys/types.h>
@@ -26,6 +26,8 @@
#include <string.h>
#include <errno.h>
#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
#include <freeswan.h>
@@ -139,6 +141,64 @@ fsig(int signal)
}
}
+static void generate_selfcert()
+{
+ struct stat stb;
+
+ /* if ipsec.secrets file is missing then generate RSA default key pair */
+ if (stat(SECRETS_FILE, &stb) != 0)
+ {
+ mode_t oldmask;
+ FILE *f;
+ uid_t uid = 0;
+ gid_t gid = 0;
+
+#ifdef IPSEC_GROUP
+ {
+ char buf[1024];
+ struct group group, *grp;
+
+ if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) == 0 &&
+ grp)
+ {
+ gid = grp->gr_gid;
+ }
+ }
+#endif
+#ifdef IPSEC_USER
+ {
+ char buf[1024];
+ struct passwd passwd, *pwp;
+
+ if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) == 0 &&
+ pwp)
+ {
+ uid = pwp->pw_uid;
+ }
+ }
+#endif
+ setegid(gid);
+ seteuid(uid);
+ system("ipsec scepclient --out pkcs1 --out cert-self --quiet");
+ seteuid(0);
+ setegid(0);
+
+ /* ipsec.secrets is root readable only */
+ oldmask = umask(0066);
+
+ f = fopen(SECRETS_FILE, "w");
+ if (f)
+ {
+ fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n");
+ fprintf(f, "\n");
+ fprintf(f, ": RSA myKey.der\n");
+ fclose(f);
+ }
+ chown(SECRETS_FILE, uid, gid);
+ umask(oldmask);
+ }
+}
+
static void
usage(char *name)
{
@@ -274,6 +334,8 @@ int main (int argc, char **argv)
plog("starter is already running (%s exists) -- no fork done", STARTER_PID_FILE);
exit(LSB_RC_SUCCESS);
}
+
+ generate_selfcert();
/* fork if we're not debugging stuff */
if (!no_fork)
@@ -541,6 +603,7 @@ int main (int argc, char **argv)
/* schedule next try */
alarm(PLUTO_RESTART_DELAY);
}
+ starter_stroke_configure(cfg);
}
_action_ &= ~FLAG_ACTION_START_CHARON;
}
@@ -589,7 +652,7 @@ int main (int argc, char **argv)
}
if (starter_charon_pid())
{
- starter_stroke_add_conn(conn);
+ starter_stroke_add_conn(cfg, conn);
}
if (starter_pluto_pid())
{
diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c
index fae895ba0..ffd5d28a6 100644
--- a/src/starter/starterstroke.c
+++ b/src/starter/starterstroke.c
@@ -1,5 +1,4 @@
/* Stroke for charon is the counterpart to whack from pluto
- * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -13,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: starterstroke.c 3394 2007-12-13 17:31:21Z martin $
+ * RCSID $Id: starterstroke.c 4100 2008-06-24 13:36:10Z martin $
*/
#include <sys/types.h>
@@ -32,20 +31,19 @@
#include <defs.h>
#include <log.h>
-#include <stroke.h>
+#include <stroke_msg.h>
#include "starterstroke.h"
#include "confread.h"
#include "files.h"
/**
- * Authentication mehtods, must be the same values as in charon
+ * Authentication methods, must be the same as in charons authenticator.h
*/
enum auth_method_t {
- AUTH_RSA = 1,
- AUTH_PSK = 2,
- AUTH_DSS = 3,
- AUTH_EAP = 201,
+ AUTH_PUBKEY = 1,
+ AUTH_PSK = 2,
+ AUTH_EAP = 3
};
static char* push_string(stroke_msg_t *msg, char *string)
@@ -162,32 +160,62 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
msg_end->updown = push_string(msg, conn_end->updown);
ip_address2string(&conn_end->addr, buffer, sizeof(buffer));
msg_end->address = push_string(msg, buffer);
- ip_address2string(&conn_end->subnet.addr, buffer, sizeof(buffer));
- msg_end->subnet = push_string(msg, buffer);
- msg_end->subnet_mask = conn_end->subnet.maskbits;
+ msg_end->subnets = push_string(msg, conn_end->subnet);
msg_end->sendcert = conn_end->sendcert;
msg_end->hostaccess = conn_end->hostaccess;
msg_end->tohost = !conn_end->has_client;
msg_end->protocol = conn_end->protocol;
msg_end->port = conn_end->port;
- msg_end->virtual_ip = conn_end->modecfg || conn_end->has_srcip;
- ip_address2string(&conn_end->srcip, buffer, sizeof(buffer));
- msg_end->sourceip = push_string(msg, buffer);
+ if (conn_end->srcip)
+ {
+ if (conn_end->srcip[0] == '%')
+ { /* %poolname, strip % */
+ msg_end->sourceip_size = 0;
+ msg_end->sourceip = push_string(msg, conn_end->srcip + 1);
+ }
+ else
+ {
+ char *pos = strchr(conn_end->srcip, '/');
+ if (pos)
+ { /* CIDR subnet definition */
+ snprintf(buffer, pos - conn_end->srcip + 1, "%s", conn_end->srcip);
+ msg_end->sourceip = push_string(msg, buffer);
+ msg_end->sourceip_size = atoi(pos + 1);
+ }
+ else
+ { /* a single address */
+ msg_end->sourceip = push_string(msg, conn_end->srcip);
+ if (strchr(conn_end->srcip, ':'))
+ { /* IPv6 */
+ msg_end->sourceip_size = 128;
+ }
+ else
+ { /* IPv4 */
+ msg_end->sourceip_size = 32;
+ }
+ }
+ }
+ }
+ else if (conn_end->modecfg)
+ {
+ msg_end->sourceip_size = 1;
+ }
}
-int starter_stroke_add_conn(starter_conn_t *conn)
+int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
{
stroke_msg_t msg;
+ memset(&msg, 0, sizeof(msg));
msg.type = STR_ADD_CONN;
msg.length = offsetof(stroke_msg_t, buffer);
msg.add_conn.ikev2 = conn->keyexchange == KEY_EXCHANGE_IKEV2;
msg.add_conn.name = push_string(&msg, connection_name(conn));
- /* RSA is preferred before PSK and EAP */
- if (conn->policy & POLICY_RSASIG)
+ /* PUBKEY is preferred to PSK and EAP */
+ if (conn->policy & POLICY_RSASIG || conn->policy & POLICY_ECDSASIG)
{
- msg.add_conn.auth_method = AUTH_RSA;
+ msg.add_conn.auth_method = AUTH_PUBKEY;
}
else if (conn->policy & POLICY_PSK)
{
@@ -213,15 +241,7 @@ int starter_stroke_add_conn(starter_conn_t *conn)
msg.add_conn.mode = 0; /* XFRM_MODE_TUNNEL */
}
- if (conn->policy & POLICY_DONT_REKEY)
- {
- msg.add_conn.rekey.ipsec_lifetime = 0;
- msg.add_conn.rekey.ike_lifetime = 0;
- msg.add_conn.rekey.margin = 0;
- msg.add_conn.rekey.tries = 0;
- msg.add_conn.rekey.fuzz = 0;
- }
- else
+ if (!(conn->policy & POLICY_DONT_REKEY))
{
msg.add_conn.rekey.reauth = (conn->policy & POLICY_DONT_REAUTH) == LEMPTY;
msg.add_conn.rekey.ipsec_lifetime = conn->sa_ipsec_life_seconds;
@@ -232,13 +252,16 @@ int starter_stroke_add_conn(starter_conn_t *conn)
}
msg.add_conn.mobike = conn->policy & POLICY_MOBIKE;
msg.add_conn.force_encap = conn->policy & POLICY_FORCE_ENCAP;
+ msg.add_conn.ipcomp = conn->policy & POLICY_COMPRESS;
+ msg.add_conn.crl_policy = cfg->setup.strictcrlpolicy;
+ msg.add_conn.unique = cfg->setup.uniqueids;
msg.add_conn.algorithms.ike = push_string(&msg, conn->ike);
msg.add_conn.algorithms.esp = push_string(&msg, conn->esp);
msg.add_conn.dpd.delay = conn->dpd_delay;
msg.add_conn.dpd.action = conn->dpd_action;
- msg.add_conn.p2p.mediation = conn->p2p_mediation;
- msg.add_conn.p2p.mediated_by = push_string(&msg, conn->p2p_mediated_by);
- msg.add_conn.p2p.peerid = push_string(&msg, conn->p2p_peerid);
+ msg.add_conn.ikeme.mediation = conn->me_mediation;
+ msg.add_conn.ikeme.mediated_by = push_string(&msg, conn->me_mediated_by);
+ msg.add_conn.ikeme.peerid = push_string(&msg, conn->me_peerid);
starter_stroke_add_end(&msg, &msg.add_conn.me, &conn->left);
starter_stroke_add_end(&msg, &msg.add_conn.other, &conn->right);
@@ -282,12 +305,13 @@ int starter_stroke_add_ca(starter_ca_t *ca)
msg.type = STR_ADD_CA;
msg.length = offsetof(stroke_msg_t, buffer);
- msg.add_ca.name = push_string(&msg, ca->name);
- msg.add_ca.cacert = push_string(&msg, ca->cacert);
- msg.add_ca.crluri = push_string(&msg, ca->crluri);
- msg.add_ca.crluri2 = push_string(&msg, ca->crluri2);
- msg.add_ca.ocspuri = push_string(&msg, ca->ocspuri);
- msg.add_ca.ocspuri2 = push_string(&msg, ca->ocspuri2);
+ msg.add_ca.name = push_string(&msg, ca->name);
+ msg.add_ca.cacert = push_string(&msg, ca->cacert);
+ msg.add_ca.crluri = push_string(&msg, ca->crluri);
+ msg.add_ca.crluri2 = push_string(&msg, ca->crluri2);
+ msg.add_ca.ocspuri = push_string(&msg, ca->ocspuri);
+ msg.add_ca.ocspuri2 = push_string(&msg, ca->ocspuri2);
+ msg.add_ca.certuribase = push_string(&msg, ca->certuribase);
return send_stroke_msg(&msg);
}
@@ -301,4 +325,17 @@ int starter_stroke_del_ca(starter_ca_t *ca)
return send_stroke_msg(&msg);
}
+int starter_stroke_configure(starter_config_t *cfg)
+{
+ stroke_msg_t msg;
+
+ if (cfg->setup.cachecrls)
+ {
+ msg.type = STR_CONFIG;
+ msg.length = offsetof(stroke_msg_t, buffer);
+ msg.config.cachecrl = 1;
+ return send_stroke_msg(&msg);
+ }
+ return 0;
+}
diff --git a/src/starter/starterstroke.h b/src/starter/starterstroke.h
index fbcf51eed..e6b9e5504 100644
--- a/src/starter/starterstroke.h
+++ b/src/starter/starterstroke.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: starterstroke.h 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: starterstroke.h 3825 2008-04-17 15:01:57Z martin $
*/
#ifndef _STARTER_STROKE_H_
@@ -19,11 +19,12 @@
#include "confread.h"
-extern int starter_stroke_add_conn(starter_conn_t *conn);
+extern int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn);
extern int starter_stroke_del_conn(starter_conn_t *conn);
extern int starter_stroke_route_conn(starter_conn_t *conn);
extern int starter_stroke_initiate_conn(starter_conn_t *conn);
extern int starter_stroke_add_ca(starter_ca_t *ca);
extern int starter_stroke_del_ca(starter_ca_t *ca);
+extern int starter_stroke_configure(starter_config_t *cfg);
#endif /* _STARTER_STROKE_H_ */
diff --git a/src/starter/starterwhack.c b/src/starter/starterwhack.c
index d29b87873..8b7d500b8 100644
--- a/src/starter/starterwhack.c
+++ b/src/starter/starterwhack.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: starterwhack.c 3405 2007-12-19 00:49:32Z andreas $
+ * RCSID $Id: starterwhack.c 3880 2008-04-27 10:49:31Z andreas $
*/
#include <sys/types.h>
@@ -32,6 +32,8 @@
#include "confread.h"
#include "files.h"
+#define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
+
static int
pack_str (char **p, char **next, char **roof)
{
@@ -149,13 +151,31 @@ connection_name(starter_conn_t *conn)
static void
set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
-{
+{
+ if (end->srcip && end->srcip[0] != '%')
+ {
+ int len = 0;
+ char *pos;
+
+ pos = strchr(end->srcip, '/');
+ if (pos)
+ {
+ /* use first address only for pluto */
+ len = pos - end->srcip;
+ }
+ w->has_srcip = !end->has_natip;
+ ttoaddr(end->srcip, len, ip_version(end->srcip), &w->host_srcip);
+ }
+ else
+ {
+ anyaddr(AF_INET, &w->host_srcip);
+ }
+
w->id = end->id;
w->cert = end->cert;
w->ca = end->ca;
w->groups = end->groups;
w->host_addr = end->addr;
- w->host_srcip = end->srcip;
w->has_client = end->has_client;
if (family == AF_INET6 && isanyaddr(&end->nexthop))
@@ -165,13 +185,28 @@ set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
w->host_nexthop = end->nexthop;
if (w->has_client)
- w->client = end->subnet;
+ {
+ char *pos;
+ int len = 0;
+
+ pos = strchr(end->subnet, ',');
+ if (pos)
+ {
+ len = pos - end->subnet;
+ }
+ ttosubnet(end->subnet, len, ip_version(end->subnet), &w->client);
+ }
else
+ {
+ if (end->has_virt)
+ {
+ w->virt = end->subnet;
+ }
w->client.addr.u.v4.sin_family = addrtypeof(&w->host_addr);
+ }
w->has_client_wildcard = end->has_client_wildcard;
w->has_port_wildcard = end->has_port_wildcard;
- w->has_srcip = end->has_srcip;
w->has_natip = end->has_natip;
w->allow_any = end->allow_any && !end->dns_failed;
w->modecfg = end->modecfg;
@@ -181,7 +216,6 @@ set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
w->host_port = IKE_UDP_PORT;
w->port = end->port;
w->protocol = end->protocol;
- w->virt = end->virt;
if (w->port != 0)
{
@@ -251,6 +285,14 @@ starter_whack_add_conn(starter_conn_t *conn)
msg.sa_keying_tries = conn->sa_keying_tries;
msg.policy = conn->policy;
+ /*
+ * Make sure the IKEv2-only policy bits are unset for IKEv1 connections
+ */
+ msg.policy &= ~POLICY_DONT_REAUTH;
+ msg.policy &= ~POLICY_BEET;
+ msg.policy &= ~POLICY_MOBIKE;
+ msg.policy &= ~POLICY_FORCE_ENCAP;
+
set_whack_end(&msg.left, &conn->left, conn->addr_family);
set_whack_end(&msg.right, &conn->right, conn->addr_family);
diff --git a/src/stroke/Makefile.am b/src/stroke/Makefile.am
index 6ea64753c..aaedfc787 100644
--- a/src/stroke/Makefile.am
+++ b/src/stroke/Makefile.am
@@ -1,9 +1,10 @@
ipsec_PROGRAMS = stroke
-stroke_SOURCES = stroke.c stroke.h stroke_keywords.c stroke_keywords.h
+stroke_SOURCES = stroke.c stroke_msg.h stroke_keywords.c stroke_keywords.h
INCLUDES = -I$(top_srcdir)/src/libstrongswan
EXTRA_DIST = stroke_keywords.txt
MAINTAINERCLEANFILES = stroke_keywords.c
+AM_CFLAGS = -DIPSEC_PIDDIR=\"${piddir}\"
stroke_keywords.c: stroke_keywords.txt stroke_keywords.h
$(GPERF) -C -G -t < stroke_keywords.txt > stroke_keywords.c
diff --git a/src/stroke/Makefile.in b/src/stroke/Makefile.in
index ad3df98d5..4f3373d23 100644
--- a/src/stroke/Makefile.in
+++ b/src/stroke/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.
@@ -83,6 +83,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -112,6 +113,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -142,7 +144,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@
@@ -153,12 +154,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@
@@ -168,12 +168,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@
@@ -186,20 +186,23 @@ 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@
-stroke_SOURCES = stroke.c stroke.h stroke_keywords.c stroke_keywords.h
+stroke_SOURCES = stroke.c stroke_msg.h stroke_keywords.c stroke_keywords.h
INCLUDES = -I$(top_srcdir)/src/libstrongswan
EXTRA_DIST = stroke_keywords.txt
MAINTAINERCLEANFILES = stroke_keywords.c
+AM_CFLAGS = -DIPSEC_PIDDIR=\"${piddir}\"
all: all-am
.SUFFIXES:
@@ -242,8 +245,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
@@ -306,8 +309,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -319,8 +322,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -330,13 +333,12 @@ ctags: CTAGS
CTAGS: $(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
diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c
index af06c8890..55f98f751 100644
--- a/src/stroke/stroke.c
+++ b/src/stroke/stroke.c
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: stroke.c 3271 2007-10-08 20:12:25Z andreas $
+ * RCSID $Id: stroke.c 3875 2008-04-25 12:41:37Z martin $
*/
#include <stdlib.h>
@@ -28,7 +28,7 @@
#include <stdio.h>
#include <stddef.h>
-#include "stroke.h"
+#include "stroke_msg.h"
#include "stroke_keywords.h"
struct stroke_token {
@@ -100,66 +100,30 @@ static int send_stroke_msg (stroke_msg_t *msg)
static int add_connection(char *name,
char *my_id, char *other_id,
char *my_addr, char *other_addr,
- char *my_net, char *other_net,
- u_int my_netmask, u_int other_netmask)
+ char *my_nets, char *other_nets)
{
stroke_msg_t msg;
+ memset(&msg, 0, sizeof(msg));
msg.length = offsetof(stroke_msg_t, buffer);
msg.type = STR_ADD_CONN;
msg.add_conn.name = push_string(&msg, name);
msg.add_conn.ikev2 = 1;
msg.add_conn.auth_method = 2;
- msg.add_conn.eap_type = 0;
msg.add_conn.mode = 1;
msg.add_conn.mobike = 1;
- msg.add_conn.force_encap = 0;
-
- msg.add_conn.rekey.reauth = 0;
- msg.add_conn.rekey.ipsec_lifetime = 0;
- msg.add_conn.rekey.ike_lifetime = 0;
- msg.add_conn.rekey.margin = 0;
- msg.add_conn.rekey.tries = 0;
- msg.add_conn.rekey.fuzz = 0;
-
- msg.add_conn.algorithms.ike = NULL;
- msg.add_conn.algorithms.esp = NULL;
-
- msg.add_conn.dpd.delay = 0;
msg.add_conn.dpd.action = 1;
- msg.add_conn.p2p.mediation = 0;
- msg.add_conn.p2p.mediated_by = NULL;
- msg.add_conn.p2p.peerid = NULL;
-
msg.add_conn.me.id = push_string(&msg, my_id);
msg.add_conn.me.address = push_string(&msg, my_addr);
- msg.add_conn.me.subnet = push_string(&msg, my_net);
- msg.add_conn.me.subnet_mask = my_netmask;
- msg.add_conn.me.sourceip = NULL;
- msg.add_conn.me.virtual_ip = 0;
- msg.add_conn.me.cert = NULL;
- msg.add_conn.me.ca = NULL;
+ msg.add_conn.me.subnets = push_string(&msg, my_nets);
msg.add_conn.me.sendcert = 1;
- msg.add_conn.me.hostaccess = 0;
- msg.add_conn.me.tohost = 0;
- msg.add_conn.me.protocol = 0;
- msg.add_conn.me.port = 0;
msg.add_conn.other.id = push_string(&msg, other_id);
msg.add_conn.other.address = push_string(&msg, other_addr);
- msg.add_conn.other.subnet = push_string(&msg, other_net);
- msg.add_conn.other.subnet_mask = other_netmask;
- msg.add_conn.other.sourceip = NULL;
- msg.add_conn.other.virtual_ip = 0;
- msg.add_conn.other.cert = NULL;
- msg.add_conn.other.ca = NULL;
+ msg.add_conn.other.subnets = push_string(&msg, other_nets);
msg.add_conn.other.sendcert = 1;
- msg.add_conn.other.hostaccess = 0;
- msg.add_conn.other.tohost = 0;
- msg.add_conn.other.protocol = 0;
- msg.add_conn.other.port = 0;
return send_stroke_msg(&msg);
}
@@ -310,8 +274,7 @@ static void exit_usage(char *error)
printf(" MY_NET OTHER_NET MY_NETBITS OTHER_NETBITS\n");
printf(" where: ID is any IKEv2 ID \n");
printf(" ADDR is a IPv4 address\n");
- printf(" NET is a IPv4 address of the subnet to tunnel\n");
- printf(" NETBITS is the size of the subnet, as the \"24\" in 192.168.0.0/24\n");
+ printf(" NET is a IPv4 subnet in CIDR notation\n");
printf(" Delete a connection:\n");
printf(" stroke delete NAME\n");
printf(" where: NAME is a connection name added with \"stroke add\"\n");
@@ -367,8 +330,7 @@ int main(int argc, char *argv[])
res = add_connection(argv[2],
argv[3], argv[4],
argv[5], argv[6],
- argv[7], argv[8],
- atoi(argv[9]), atoi(argv[10]));
+ argv[7], argv[8]);
break;
case STROKE_DELETE:
case STROKE_DEL:
diff --git a/src/stroke/stroke_keywords.c b/src/stroke/stroke_keywords.c
index 5143cba2e..ad37732fa 100644
--- a/src/stroke/stroke_keywords.c
+++ b/src/stroke/stroke_keywords.c
@@ -1,4 +1,4 @@
-/* C code produced by gperf version 3.0.1 */
+/* C code produced by gperf version 3.0.3 */
/* Command-line: /usr/bin/gperf -C -G -t */
/* Computed positions: -k'1,5,7' */
@@ -169,6 +169,9 @@ static const struct stroke_token wordlist[] =
#ifdef __GNUC__
__inline
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
#endif
const struct stroke_token *
in_word_set (str, len)
diff --git a/src/stroke/stroke.h b/src/stroke/stroke_msg.h
index ca4e397e4..6aa5d8a49 100644
--- a/src/stroke/stroke.h
+++ b/src/stroke/stroke_msg.h
@@ -1,5 +1,5 @@
/**
- * @file stroke.h
+ * @file stroke_msg.h
*
* @brief Definition of stroke_msg_t.
*
@@ -19,18 +19,18 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: stroke.h 3394 2007-12-13 17:31:21Z martin $
+ * RCSID $Id: stroke_msg.h 3920 2008-05-08 16:19:11Z tobias $
*/
-#ifndef STROKE_H_
-#define STROKE_H_
+#ifndef STROKE_MSG_H_
+#define STROKE_MSG_H_
#include <sys/types.h>
/**
* Socket which is used to communicate between charon and stroke
*/
-#define STROKE_SOCKET "/var/run/charon.ctl"
+#define STROKE_SOCKET IPSEC_PIDDIR "/charon.ctl"
#define STROKE_BUF_LEN 2048
@@ -103,6 +103,16 @@ enum purge_flag_t {
PURGE_OCSP = 0x0001,
};
+/**
+ * CRL certificate validation policy
+ */
+typedef enum {
+ CRL_STRICT_NO,
+ CRL_STRICT_YES,
+ CRL_STRICT_IFURI,
+} crl_policy_t;
+
+
typedef struct stroke_end_t stroke_end_t;
/**
@@ -116,9 +126,8 @@ struct stroke_end_t {
char *updown;
char *address;
char *sourceip;
- u_int8_t virtual_ip;
- char *subnet;
- int subnet_mask;
+ int sourceip_size;
+ char *subnets;
int sendcert;
int hostaccess;
int tohost;
@@ -159,6 +168,8 @@ struct stroke_msg_t {
STR_DEL_CA,
/* set a log type to log/not log */
STR_LOGLEVEL,
+ /* configure global options for stroke */
+ STR_CONFIG,
/* list various objects */
STR_LIST,
/* reread various objects */
@@ -187,6 +198,9 @@ struct stroke_msg_t {
int mode;
int mobike;
int force_encap;
+ int ipcomp;
+ crl_policy_t crl_policy;
+ int unique;
struct {
char *ike;
char *esp;
@@ -207,7 +221,7 @@ struct stroke_msg_t {
int mediation;
char *mediated_by;
char *peerid;
- } p2p;
+ } ikeme;
stroke_end_t me, other;
} add_conn;
@@ -219,6 +233,7 @@ struct stroke_msg_t {
char *crluri2;
char *ocspuri;
char *ocspuri2;
+ char *certuribase;
} add_ca;
/* data for STR_LOGLEVEL */
@@ -226,6 +241,11 @@ struct stroke_msg_t {
char *type;
int level;
} loglevel;
+
+ /* data for STR_CONFIG */
+ struct {
+ int cachecrl;
+ } config;
/* data for STR_LIST */
struct {
@@ -246,4 +266,4 @@ struct stroke_msg_t {
char buffer[STROKE_BUF_LEN];
};
-#endif /* STROKE_H_ */
+#endif /* STROKE_MSG_H_ */
diff --git a/src/strongswan.conf b/src/strongswan.conf
new file mode 100644
index 000000000..661792a67
--- /dev/null
+++ b/src/strongswan.conf
@@ -0,0 +1,25 @@
+# strongswan.conf - strongSwan configuration file
+
+charon {
+
+ # number of worker threads in charon
+ threads = 16
+
+ # plugins to load in charon
+ # load = aes des gmp hmac md5 random sha1 sha2 pubkey xcbc x509 stroke
+
+ plugins {
+
+ sql {
+
+ # loglevel to log into sql database
+ loglevel = -1
+
+ # URI to the database
+ # database = sqlite:///path/to/file.db
+ # database = mysql://user:password@localhost/database
+ }
+ }
+
+ # ...
+}
diff --git a/src/whack/Makefile.in b/src/whack/Makefile.in
index 258102021..86f92790a 100644
--- a/src/whack/Makefile.in
+++ b/src/whack/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.
@@ -83,6 +83,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
@@ -112,6 +113,7 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -142,7 +144,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@
@@ -153,12 +154,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@
@@ -168,12 +168,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@
@@ -186,10 +186,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@
@@ -242,8 +244,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
@@ -305,8 +307,8 @@ ID: $(HEADERS) $(SOURCES) $(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
@@ -318,8 +320,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
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) \
@@ -329,13 +331,12 @@ ctags: CTAGS
CTAGS: $(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