From e0fe7651524d96abb5a7109d17bd8bd9da2e25fa Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Tue, 10 Apr 2007 06:01:03 +0000 Subject: [PATCH] restructured file layout new configuration structure: peer_cfg: configuration related to a peer (authenitcation, ...= ike_cfg: config to use for IKE setup (proposals) child_Cfg: config for CHILD_SA (proposals, traffic selectors) a peer_cfg has one ike_cfg and multiple child_cfg's stroke now uses fixed count of threads --- TODO | 1 + {src/charon/doc => doc}/Known-bugs.txt | 0 {src/charon/doc => doc}/architecture.h | 0 ...t-eronen-ipsec-ikev2-clarifications-09.txt | 0 .../draft-eronen-ipsec-ikev2-eap-auth-05.txt | 0 .../standards/draft-hoffman-ikev2-1-00.txt | 0 .../standards/draft-hoffman-ikev2bis-00.txt | 0 .../standards/draft-myers-ikev2-ocsp-03.txt | 0 {src/charon/doc => doc}/standards/rfc3748.txt | 0 {src/charon/doc => doc}/standards/rfc4186.txt | 0 {src/charon/doc => doc}/standards/rfc4301.txt | 0 {src/charon/doc => doc}/standards/rfc4306.txt | 0 {src/charon/doc => doc}/standards/rfc4307.txt | 0 {src/charon/doc => doc}/standards/rfc4478.txt | 0 {src/charon/doc => doc}/standards/rfc4718.txt | 0 {src/charon/doc => doc}/standards/rfc4739.txt | 0 scripts/cfg-leak | 4 +- src/charon/Makefile.am | 131 ++-- src/charon/config/backends/backend.h | 77 +++ src/charon/config/backends/local_backend.c | 231 +++++++ src/charon/config/backends/local_backend.h | 82 +++ src/charon/config/cfg_store.c | 164 +++++ src/charon/config/cfg_store.h | 135 ++++ src/charon/config/child_cfg.c | 397 +++++++++++ src/charon/config/child_cfg.h | 239 +++++++ src/charon/config/connections/connection.c | 404 ----------- src/charon/config/connections/connection.h | 292 -------- .../config/connections/connection_store.h | 118 ---- .../connections/local_connection_store.c | 237 ------- .../connections/local_connection_store.h | 62 -- src/charon/config/ike_cfg.c | 259 +++++++ src/charon/config/ike_cfg.h | 160 +++++ src/charon/config/peer_cfg.c | 470 +++++++++++++ src/charon/config/peer_cfg.h | 345 ++++++++++ .../config/policies/local_policy_store.c | 282 -------- .../config/policies/local_policy_store.h | 60 -- src/charon/config/policies/policy.c | 635 ------------------ src/charon/config/policies/policy.h | 413 ------------ src/charon/config/policies/policy_store.h | 119 ---- src/charon/config/traffic_selector.c | 20 + src/charon/control/controller.c | 0 src/charon/control/controller.h | 0 .../{threads => control}/stroke_interface.c | 570 +++++++++------- .../{threads => control}/stroke_interface.h | 10 +- src/charon/daemon.c | 19 +- src/charon/daemon.h | 27 +- .../{threads => kernel}/kernel_interface.c | 6 +- .../{threads => kernel}/kernel_interface.h | 0 src/charon/{threads => network}/receiver.c | 6 +- src/charon/{threads => network}/receiver.h | 0 src/charon/{threads => network}/sender.c | 0 src/charon/{threads => network}/sender.h | 0 .../{queues => processing}/event_queue.c | 0 .../{queues => processing}/event_queue.h | 2 +- src/charon/{queues => processing}/job_queue.c | 0 src/charon/{queues => processing}/job_queue.h | 2 +- .../{queues => processing}/jobs/acquire_job.c | 0 .../{queues => processing}/jobs/acquire_job.h | 2 +- .../jobs/delete_child_sa_job.c | 0 .../jobs/delete_child_sa_job.h | 2 +- .../jobs/delete_ike_sa_job.c | 0 .../jobs/delete_ike_sa_job.h | 2 +- .../jobs/initiate_job.c | 36 +- .../jobs/initiate_job.h | 22 +- src/charon/{queues => processing}/jobs/job.c | 0 src/charon/{queues => processing}/jobs/job.h | 0 .../jobs/process_message_job.c | 0 .../jobs/process_message_job.h | 2 +- .../jobs/rekey_child_sa_job.c | 0 .../jobs/rekey_child_sa_job.h | 2 +- .../jobs/rekey_ike_sa_job.c | 0 .../jobs/rekey_ike_sa_job.h | 2 +- .../jobs/retransmit_job.c | 0 .../jobs/retransmit_job.h | 2 +- .../{queues => processing}/jobs/route_job.c | 40 +- .../{queues => processing}/jobs/route_job.h | 14 +- .../jobs/send_dpd_job.c | 0 .../jobs/send_dpd_job.h | 3 +- .../jobs/send_keepalive_job.c | 0 .../jobs/send_keepalive_job.h | 3 +- .../{threads => processing}/scheduler.c | 2 +- .../{threads => processing}/scheduler.h | 0 .../{threads => processing}/thread_pool.c | 2 +- .../{threads => processing}/thread_pool.h | 0 .../sa/authenticators/eap_authenticator.c | 2 +- .../sa/authenticators/psk_authenticator.c | 1 - .../sa/authenticators/rsa_authenticator.c | 1 - src/charon/sa/child_sa.c | 63 +- src/charon/sa/child_sa.h | 25 +- src/charon/sa/ike_sa.c | 388 +++++------ src/charon/sa/ike_sa.h | 55 +- src/charon/sa/ike_sa_manager.c | 1 + src/charon/sa/task_manager.c | 4 +- src/charon/sa/tasks/child_create.c | 107 ++- src/charon/sa/tasks/child_create.h | 6 +- src/charon/sa/tasks/child_rekey.c | 8 +- src/charon/sa/tasks/ike_auth.c | 47 +- src/charon/sa/tasks/ike_cert.c | 26 +- src/charon/sa/tasks/ike_config.c | 23 +- src/charon/sa/tasks/ike_config.h | 5 +- src/charon/sa/tasks/ike_delete.c | 2 +- src/charon/sa/tasks/ike_init.c | 30 +- src/charon/sa/tasks/ike_rekey.c | 25 +- src/libstrongswan/utils/host.c | 2 +- 104 files changed, 3466 insertions(+), 3470 deletions(-) rename {src/charon/doc => doc}/Known-bugs.txt (100%) rename {src/charon/doc => doc}/architecture.h (100%) rename {src/charon/doc => doc}/standards/draft-eronen-ipsec-ikev2-clarifications-09.txt (100%) rename {src/charon/doc => doc}/standards/draft-eronen-ipsec-ikev2-eap-auth-05.txt (100%) rename {src/charon/doc => doc}/standards/draft-hoffman-ikev2-1-00.txt (100%) rename {src/charon/doc => doc}/standards/draft-hoffman-ikev2bis-00.txt (100%) rename {src/charon/doc => doc}/standards/draft-myers-ikev2-ocsp-03.txt (100%) rename {src/charon/doc => doc}/standards/rfc3748.txt (100%) rename {src/charon/doc => doc}/standards/rfc4186.txt (100%) rename {src/charon/doc => doc}/standards/rfc4301.txt (100%) rename {src/charon/doc => doc}/standards/rfc4306.txt (100%) rename {src/charon/doc => doc}/standards/rfc4307.txt (100%) rename {src/charon/doc => doc}/standards/rfc4478.txt (100%) rename {src/charon/doc => doc}/standards/rfc4718.txt (100%) rename {src/charon/doc => doc}/standards/rfc4739.txt (100%) create mode 100644 src/charon/config/backends/backend.h create mode 100644 src/charon/config/backends/local_backend.c create mode 100644 src/charon/config/backends/local_backend.h create mode 100644 src/charon/config/cfg_store.c create mode 100644 src/charon/config/cfg_store.h create mode 100644 src/charon/config/child_cfg.c create mode 100644 src/charon/config/child_cfg.h delete mode 100644 src/charon/config/connections/connection.c delete mode 100644 src/charon/config/connections/connection.h delete mode 100755 src/charon/config/connections/connection_store.h delete mode 100644 src/charon/config/connections/local_connection_store.c delete mode 100644 src/charon/config/connections/local_connection_store.h create mode 100644 src/charon/config/ike_cfg.c create mode 100644 src/charon/config/ike_cfg.h create mode 100644 src/charon/config/peer_cfg.c create mode 100644 src/charon/config/peer_cfg.h delete mode 100644 src/charon/config/policies/local_policy_store.c delete mode 100644 src/charon/config/policies/local_policy_store.h delete mode 100644 src/charon/config/policies/policy.c delete mode 100644 src/charon/config/policies/policy.h delete mode 100755 src/charon/config/policies/policy_store.h create mode 100644 src/charon/control/controller.c create mode 100644 src/charon/control/controller.h rename src/charon/{threads => control}/stroke_interface.c (69%) rename src/charon/{threads => control}/stroke_interface.h (80%) rename src/charon/{threads => kernel}/kernel_interface.c (99%) rename src/charon/{threads => kernel}/kernel_interface.h (100%) rename src/charon/{threads => network}/receiver.c (98%) rename src/charon/{threads => network}/receiver.h (100%) rename src/charon/{threads => network}/sender.c (100%) rename src/charon/{threads => network}/sender.h (100%) rename src/charon/{queues => processing}/event_queue.c (100%) rename src/charon/{queues => processing}/event_queue.h (99%) rename src/charon/{queues => processing}/job_queue.c (100%) rename src/charon/{queues => processing}/job_queue.h (98%) rename src/charon/{queues => processing}/jobs/acquire_job.c (100%) rename src/charon/{queues => processing}/jobs/acquire_job.h (97%) rename src/charon/{queues => processing}/jobs/delete_child_sa_job.c (100%) rename src/charon/{queues => processing}/jobs/delete_child_sa_job.h (98%) rename src/charon/{queues => processing}/jobs/delete_ike_sa_job.c (100%) rename src/charon/{queues => processing}/jobs/delete_ike_sa_job.h (98%) rename src/charon/{queues => processing}/jobs/initiate_job.c (72%) rename src/charon/{queues => processing}/jobs/initiate_job.h (71%) rename src/charon/{queues => processing}/jobs/job.c (100%) rename src/charon/{queues => processing}/jobs/job.h (100%) rename src/charon/{queues => processing}/jobs/process_message_job.c (100%) rename src/charon/{queues => processing}/jobs/process_message_job.h (97%) rename src/charon/{queues => processing}/jobs/rekey_child_sa_job.c (100%) rename src/charon/{queues => processing}/jobs/rekey_child_sa_job.h (98%) rename src/charon/{queues => processing}/jobs/rekey_ike_sa_job.c (100%) rename src/charon/{queues => processing}/jobs/rekey_ike_sa_job.h (97%) rename src/charon/{queues => processing}/jobs/retransmit_job.c (100%) rename src/charon/{queues => processing}/jobs/retransmit_job.h (98%) rename src/charon/{queues => processing}/jobs/route_job.c (72%) rename src/charon/{queues => processing}/jobs/route_job.h (78%) rename src/charon/{queues => processing}/jobs/send_dpd_job.c (100%) rename src/charon/{queues => processing}/jobs/send_dpd_job.h (95%) rename src/charon/{queues => processing}/jobs/send_keepalive_job.c (100%) rename src/charon/{queues => processing}/jobs/send_keepalive_job.h (96%) rename src/charon/{threads => processing}/scheduler.c (98%) rename src/charon/{threads => processing}/scheduler.h (100%) rename src/charon/{threads => processing}/thread_pool.c (99%) rename src/charon/{threads => processing}/thread_pool.h (100%) diff --git a/TODO b/TODO index 91363e38b..f63d0d594 100644 --- a/TODO +++ b/TODO @@ -47,6 +47,7 @@ Build system ------------ - configure flag which allows to ommit vendor id in pluto - reduce printf handlers count to 10, as uClibc does not support more +- remove %m printf handlers, as error may have changed until it reaches fprintf() Certificate support ------------------- diff --git a/src/charon/doc/Known-bugs.txt b/doc/Known-bugs.txt similarity index 100% rename from src/charon/doc/Known-bugs.txt rename to doc/Known-bugs.txt diff --git a/src/charon/doc/architecture.h b/doc/architecture.h similarity index 100% rename from src/charon/doc/architecture.h rename to doc/architecture.h diff --git a/src/charon/doc/standards/draft-eronen-ipsec-ikev2-clarifications-09.txt b/doc/standards/draft-eronen-ipsec-ikev2-clarifications-09.txt similarity index 100% rename from src/charon/doc/standards/draft-eronen-ipsec-ikev2-clarifications-09.txt rename to doc/standards/draft-eronen-ipsec-ikev2-clarifications-09.txt diff --git a/src/charon/doc/standards/draft-eronen-ipsec-ikev2-eap-auth-05.txt b/doc/standards/draft-eronen-ipsec-ikev2-eap-auth-05.txt similarity index 100% rename from src/charon/doc/standards/draft-eronen-ipsec-ikev2-eap-auth-05.txt rename to doc/standards/draft-eronen-ipsec-ikev2-eap-auth-05.txt diff --git a/src/charon/doc/standards/draft-hoffman-ikev2-1-00.txt b/doc/standards/draft-hoffman-ikev2-1-00.txt similarity index 100% rename from src/charon/doc/standards/draft-hoffman-ikev2-1-00.txt rename to doc/standards/draft-hoffman-ikev2-1-00.txt diff --git a/src/charon/doc/standards/draft-hoffman-ikev2bis-00.txt b/doc/standards/draft-hoffman-ikev2bis-00.txt similarity index 100% rename from src/charon/doc/standards/draft-hoffman-ikev2bis-00.txt rename to doc/standards/draft-hoffman-ikev2bis-00.txt diff --git a/src/charon/doc/standards/draft-myers-ikev2-ocsp-03.txt b/doc/standards/draft-myers-ikev2-ocsp-03.txt similarity index 100% rename from src/charon/doc/standards/draft-myers-ikev2-ocsp-03.txt rename to doc/standards/draft-myers-ikev2-ocsp-03.txt diff --git a/src/charon/doc/standards/rfc3748.txt b/doc/standards/rfc3748.txt similarity index 100% rename from src/charon/doc/standards/rfc3748.txt rename to doc/standards/rfc3748.txt diff --git a/src/charon/doc/standards/rfc4186.txt b/doc/standards/rfc4186.txt similarity index 100% rename from src/charon/doc/standards/rfc4186.txt rename to doc/standards/rfc4186.txt diff --git a/src/charon/doc/standards/rfc4301.txt b/doc/standards/rfc4301.txt similarity index 100% rename from src/charon/doc/standards/rfc4301.txt rename to doc/standards/rfc4301.txt diff --git a/src/charon/doc/standards/rfc4306.txt b/doc/standards/rfc4306.txt similarity index 100% rename from src/charon/doc/standards/rfc4306.txt rename to doc/standards/rfc4306.txt diff --git a/src/charon/doc/standards/rfc4307.txt b/doc/standards/rfc4307.txt similarity index 100% rename from src/charon/doc/standards/rfc4307.txt rename to doc/standards/rfc4307.txt diff --git a/src/charon/doc/standards/rfc4478.txt b/doc/standards/rfc4478.txt similarity index 100% rename from src/charon/doc/standards/rfc4478.txt rename to doc/standards/rfc4478.txt diff --git a/src/charon/doc/standards/rfc4718.txt b/doc/standards/rfc4718.txt similarity index 100% rename from src/charon/doc/standards/rfc4718.txt rename to doc/standards/rfc4718.txt diff --git a/src/charon/doc/standards/rfc4739.txt b/doc/standards/rfc4739.txt similarity index 100% rename from src/charon/doc/standards/rfc4739.txt rename to doc/standards/rfc4739.txt diff --git a/scripts/cfg-leak b/scripts/cfg-leak index 44c3ec8b6..22df652d3 100755 --- a/scripts/cfg-leak +++ b/scripts/cfg-leak @@ -1,4 +1,4 @@ #!/bin/bash CFLAGS="-Wall -Wno-format -Wno-pointer-sign -Wno-strict-aliasing -g -O2" ./configure \ ---sysconfdir=/etc --with-random-device=/dev/urandom --enable-ldap --enable-http \ ---enable-leak-detective +--sysconfdir=/etc --with-random-device=/dev/urandom \ +--enable-leak-detective --enable-eap-sim --with-sim-reader=/home/martin/strongswan/trunk/src/charon/sa/authenticators/eap/sim_reader/sim_api.so diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am index 9522b6e6d..b66f23773 100644 --- a/src/charon/Makefile.am +++ b/src/charon/Makefile.am @@ -17,65 +17,90 @@ ipsec_PROGRAMS = charon charon_SOURCES = \ bus/bus.c bus/bus.h \ -bus/listeners/sys_logger.c bus/listeners/sys_logger.h \ bus/listeners/file_logger.c bus/listeners/file_logger.h \ -config/connections/connection.c config/connections/connection.h \ -config/connections/local_connection_store.c config/connections/local_connection_store.h config/connections/connection_store.h \ -config/policies/policy.c config/policies/policy.h \ -config/policies/local_policy_store.c config/policies/policy_store.h config/policies/local_policy_store.h \ +bus/listeners/sys_logger.c bus/listeners/sys_logger.h \ +config/backends/backend.h \ +config/backends/local_backend.c config/backends/local_backend.h \ +config/cfg_store.c config/cfg_store.h \ +config/child_cfg.c config/child_cfg.h \ +config/configuration.c config/configuration.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 \ -config/proposal.c config/proposal.h config/configuration.c config/configuration.h \ -sa/authenticators/eap_authenticator.h sa/authenticators/eap_authenticator.c \ -sa/authenticators/eap/eap_method.h sa/authenticators/eap/eap_method.c \ -sa/child_sa.c sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_manager.c sa/ike_sa_manager.h \ -sa/ike_sa_id.c sa/ike_sa_id.h sa/tasks/task.c sa/tasks/task.h \ -sa/tasks/ike_init.c sa/tasks/ike_init.h \ -sa/tasks/ike_natd.c sa/tasks/ike_natd.h \ -sa/tasks/ike_auth.c sa/tasks/ike_auth.h \ -sa/tasks/ike_config.c sa/tasks/ike_config.h \ -sa/tasks/ike_cert.c sa/tasks/ike_cert.h \ -sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \ -sa/tasks/ike_delete.c sa/tasks/ike_delete.h \ -sa/tasks/ike_dpd.c sa/tasks/ike_dpd.h \ +control/controller.c control/controller.h \ +control/stroke_interface.c control/stroke_interface.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 \ +encoding/payloads/certreq_payload.c encoding/payloads/certreq_payload.h \ +encoding/payloads/configuration_attribute.c encoding/payloads/configuration_attribute.h \ +encoding/payloads/cp_payload.c encoding/payloads/cp_payload.h \ +encoding/payloads/delete_payload.c encoding/payloads/delete_payload.h \ +encoding/payloads/eap_payload.c encoding/payloads/eap_payload.h \ +encoding/payloads/encodings.c encoding/payloads/encodings.h \ +encoding/payloads/encryption_payload.c encoding/payloads/encryption_payload.h \ +encoding/payloads/id_payload.c encoding/payloads/id_payload.h \ +encoding/payloads/ike_header.c encoding/payloads/ike_header.h \ +encoding/payloads/ke_payload.c encoding/payloads/ke_payload.h \ +encoding/payloads/nonce_payload.c encoding/payloads/nonce_payload.h \ +encoding/payloads/notify_payload.c encoding/payloads/notify_payload.h \ +encoding/payloads/payload.c encoding/payloads/payload.h \ +encoding/payloads/proposal_substructure.c encoding/payloads/proposal_substructure.h \ +encoding/payloads/sa_payload.c encoding/payloads/sa_payload.h \ +encoding/payloads/traffic_selector_substructure.c encoding/payloads/traffic_selector_substructure.h \ +encoding/payloads/transform_attribute.c encoding/payloads/transform_attribute.h \ +encoding/payloads/transform_substructure.c encoding/payloads/transform_substructure.h \ +encoding/payloads/ts_payload.c encoding/payloads/ts_payload.h \ +encoding/payloads/unknown_payload.c encoding/payloads/unknown_payload.h \ +encoding/payloads/vendor_id_payload.c encoding/payloads/vendor_id_payload.h \ +kernel/kernel_interface.c kernel/kernel_interface.h \ +network/packet.c network/packet.h \ +network/receiver.c network/receiver.h \ +network/sender.c network/sender.h \ +network/socket.c network/socket.h \ +processing/event_queue.c processing/event_queue.h \ +processing/job_queue.c processing/job_queue.h \ +processing/jobs/acquire_job.c processing/jobs/acquire_job.h \ +processing/jobs/delete_child_sa_job.c processing/jobs/delete_child_sa_job.h \ +processing/jobs/delete_ike_sa_job.c processing/jobs/delete_ike_sa_job.h \ +processing/jobs/initiate_job.c processing/jobs/initiate_job.h \ +processing/jobs/job.c processing/jobs/job.h \ +processing/jobs/process_message_job.c processing/jobs/process_message_job.h \ +processing/jobs/rekey_child_sa_job.c processing/jobs/rekey_child_sa_job.h \ +processing/jobs/rekey_ike_sa_job.c processing/jobs/rekey_ike_sa_job.h \ +processing/jobs/retransmit_job.c processing/jobs/retransmit_job.h \ +processing/jobs/route_job.c processing/jobs/route_job.h \ +processing/jobs/send_dpd_job.c processing/jobs/send_dpd_job.h \ +processing/jobs/send_keepalive_job.c processing/jobs/send_keepalive_job.h \ +processing/scheduler.c processing/scheduler.h \ +processing/thread_pool.c processing/thread_pool.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/psk_authenticator.c sa/authenticators/psk_authenticator.h \ +sa/authenticators/rsa_authenticator.c sa/authenticators/rsa_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/authenticators/authenticator.c sa/authenticators/authenticator.h \ -sa/authenticators/rsa_authenticator.c sa/authenticators/rsa_authenticator.h \ -sa/authenticators/psk_authenticator.c sa/authenticators/psk_authenticator.h \ -sa/task_manager.c sa/task_manager.h encoding/payloads/encryption_payload.c \ -encoding/payloads/cert_payload.c encoding/payloads/payload.h encoding/payloads/traffic_selector_substructure.c \ -encoding/payloads/configuration_attribute.h encoding/payloads/proposal_substructure.h \ -encoding/payloads/transform_attribute.c encoding/payloads/transform_attribute.h \ -encoding/payloads/configuration_attribute.c encoding/payloads/transform_substructure.c \ -encoding/payloads/encryption_payload.h encoding/payloads/auth_payload.c encoding/payloads/ike_header.c \ -encoding/payloads/transform_substructure.h encoding/payloads/nonce_payload.c encoding/payloads/cert_payload.h \ -encoding/payloads/eap_payload.c encoding/payloads/ike_header.h encoding/payloads/auth_payload.h \ -encoding/payloads/ts_payload.c encoding/payloads/traffic_selector_substructure.h encoding/payloads/nonce_payload.h \ -encoding/payloads/notify_payload.c encoding/payloads/eap_payload.h encoding/payloads/notify_payload.h \ -encoding/payloads/ts_payload.h encoding/payloads/id_payload.c encoding/payloads/ke_payload.c \ -encoding/payloads/unknown_payload.c encoding/payloads/encodings.c encoding/payloads/id_payload.h \ -encoding/payloads/cp_payload.c encoding/payloads/delete_payload.c encoding/payloads/sa_payload.c \ -encoding/payloads/ke_payload.h encoding/payloads/unknown_payload.h encoding/payloads/encodings.h \ -encoding/payloads/certreq_payload.c encoding/payloads/cp_payload.h encoding/payloads/delete_payload.h \ -encoding/payloads/sa_payload.h encoding/payloads/vendor_id_payload.c encoding/payloads/certreq_payload.h \ -encoding/payloads/vendor_id_payload.h encoding/payloads/proposal_substructure.c encoding/payloads/payload.c \ -encoding/parser.h encoding/message.c encoding/generator.c encoding/message.h encoding/generator.h \ -encoding/parser.c daemon.c daemon.h network/packet.c \ -network/socket.c network/packet.h network/socket.h queues/jobs/job.h queues/jobs/job.c \ -queues/jobs/retransmit_job.h queues/jobs/initiate_job.h \ -queues/jobs/process_message_job.h queues/jobs/process_message_job.c \ -queues/jobs/delete_ike_sa_job.c queues/jobs/delete_ike_sa_job.h \ -queues/jobs/retransmit_job.c queues/jobs/initiate_job.c \ -queues/jobs/send_keepalive_job.c queues/jobs/send_keepalive_job.h \ -queues/jobs/rekey_child_sa_job.c queues/jobs/rekey_child_sa_job.h queues/jobs/delete_child_sa_job.c queues/jobs/delete_child_sa_job.h \ -queues/jobs/send_dpd_job.c queues/jobs/send_dpd_job.h queues/jobs/route_job.c queues/jobs/route_job.h \ -queues/jobs/acquire_job.c queues/jobs/acquire_job.h queues/jobs/rekey_ike_sa_job.c queues/jobs/rekey_ike_sa_job.h \ -queues/job_queue.c queues/event_queue.c queues/job_queue.h queues/event_queue.h \ -threads/kernel_interface.c threads/thread_pool.c threads/scheduler.c threads/sender.c \ -threads/sender.h threads/kernel_interface.h threads/scheduler.h threads/receiver.c threads/stroke_interface.c \ -threads/thread_pool.h threads/receiver.h threads/stroke_interface.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_rekey.c sa/tasks/ike_rekey.h \ +sa/tasks/task.c sa/tasks/task.h 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}\" -DIPSEC_EAPDIR=\"${eapdir}\" diff --git a/src/charon/config/backends/backend.h b/src/charon/config/backends/backend.h new file mode 100644 index 000000000..a054a7221 --- /dev/null +++ b/src/charon/config/backends/backend.h @@ -0,0 +1,77 @@ +/** + * @file backend.h + * + * @brief Interface 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 . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 +#include +#include +#include + + +/** + * @brief The interface for a configuration backend. + * + * @b Constructors: + * - implementations constructor, such as local_backend_create() + * + * @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. + * + * @param this calling object + * @param my_id own ID + * @param other_id peers ID + * @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); + + /** + * @brief Get a peer_cfg identified by its name. + * + * @param this calling object + * @param name configs name + * @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/backends/local_backend.c b/src/charon/config/backends/local_backend.c new file mode 100644 index 000000000..534c71c97 --- /dev/null +++ b/src/charon/config/backends/local_backend.c @@ -0,0 +1,231 @@ +/** + * @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 . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 + +#include "local_backend.h" + +#include +#include + + +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 cfg_store_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; +} + +/** + * implements cfg_store_t.get_peer. + */ +static peer_cfg_t *get_peer_cfg(private_local_backend_t *this, + identification_t *my_id, + identification_t *other_id) +{ + peer_cfg_t *current, *found = NULL; + iterator_t *iterator; + identification_t *my_candidate, *other_candidate; + int wc1, wc2, total, best = MAX_WILDCARDS; + + 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**)¤t)) + { + 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)) + { + total = wc1 + wc2; + + DBG2(DBG_CFG, " candidate '%s': %D...%D, wildcards %d", + current->get_name(current), my_candidate, other_candidate, + total); + + if (total < best) + { + found = current; + best = total; + } + } + } + if (found) + { + found->get_ref(found); + } + iterator->destroy(iterator); + return found; +} + +/** + * implements cfg_store_t.get_peer_by_name. + */ +static peer_cfg_t *get_peer_cfg_by_name(private_local_backend_t *this, + char *name) +{ + iterator_t *iterator; + peer_cfg_t *current, *found = NULL; + + iterator = this->cfgs->create_iterator(this->cfgs, TRUE); + while (iterator->iterate(iterator, (void**)¤t)) + { + if (streq(current->get_name(current), name)) + { + found = current; + found->get_ref(found); + break; + } + } + iterator->destroy(iterator); + return found; +} + +/** + * Implementation of local_backend_t.create_peer_cfg_iterator. + */ +static iterator_t* create_peer_cfg_iterator(private_local_backend_t *this) +{ + return this->cfgs->create_iterator_locked(this->cfgs, &this->mutex); +} + +/** + * Implementation of local_backend_t.add_peer_cfg. + */ +static void add_peer_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 local_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. + */ +local_backend_t *local_backend_create(void) +{ + private_local_backend_t *this = malloc_thing(private_local_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 *))get_peer_cfg; + this->public.backend.get_peer_cfg_by_name = (peer_cfg_t*(*)(backend_t*, char *))get_peer_cfg_by_name; + this->public.create_peer_cfg_iterator = (iterator_t*(*)(local_backend_t*))create_peer_cfg_iterator; + this->public.add_peer_cfg = (void(*)(local_backend_t*, peer_cfg_t *))add_peer_cfg; + this->public.destroy = (void(*)(local_backend_t*))destroy; + + /* private variables */ + this->cfgs = linked_list_create(); + pthread_mutex_init(&this->mutex, NULL); + + return (&this->public); +} diff --git a/src/charon/config/backends/local_backend.h b/src/charon/config/backends/local_backend.h new file mode 100644 index 000000000..041725ae4 --- /dev/null +++ b/src/charon/config/backends/local_backend.h @@ -0,0 +1,82 @@ +/** + * @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 . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 +#include + +/** + * @brief An in-memory backend to store configuration information. + * + * The local_backend_t stores the configuration in a simple list. Additional + * to the backend_t functionality, it adds the modification (add/remove). + * + * @b Constructors: + * - local_backend_create() + * + * @ingroup backends + */ +struct local_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_peer_cfg)(local_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_peer_cfg_iterator)(local_backend_t *this); + + /** + * @brief Destroy a local backend. + * + * @param this calling object + */ + void (*destroy)(local_backend_t *this); +}; + +/** + * @brief Creates a local_backend_t instance. + * + * @return local_backend instance. + * + * @ingroup config + */ +local_backend_t *local_backend_create(void); + +#endif /* LOCAL_BACKEND_H_ */ diff --git a/src/charon/config/cfg_store.c b/src/charon/config/cfg_store.c new file mode 100644 index 000000000..e06780a94 --- /dev/null +++ b/src/charon/config/cfg_store.c @@ -0,0 +1,164 @@ +/** + * @file cfg_store.c + * + * @brief Implementation of cfg_store_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 . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 + +#include "cfg_store.h" + +#include +#include + + +typedef struct private_cfg_store_t private_cfg_store_t; + +/** + * Private data of an cfg_store_t object. + */ +struct private_cfg_store_t { + + /** + * Public part of cfg_store_t object. + */ + cfg_store_t public; + + /** + * list of registered backends + */ + linked_list_t *backends; + + /** + * mutex to lock backend list + */ + pthread_mutex_t mutex; +}; + +/** + * implements cfg_store_t.get_ike. + */ +static ike_cfg_t *get_ike_cfg(private_cfg_store_t *this, + host_t *my_host, host_t *other_host) +{ + backend_t *backend; + ike_cfg_t *config = NULL; + iterator_t *iterator = this->backends->create_iterator_locked( + this->backends, &this->mutex); + while (config == NULL && iterator->iterate(iterator, (void**)&backend)) + { + config = backend->get_ike_cfg(backend, my_host, other_host); + } + iterator->destroy(iterator); + return config; +} + +/** + * implements cfg_store_t.get_peer. + */ +static peer_cfg_t *get_peer_cfg(private_cfg_store_t *this, + identification_t *my_id, + identification_t *other_id) +{ + backend_t *backend; + peer_cfg_t *config = NULL; + iterator_t *iterator = this->backends->create_iterator_locked( + this->backends, &this->mutex); + while (config == NULL && iterator->iterate(iterator, (void**)&backend)) + { + config = backend->get_peer_cfg(backend, my_id, other_id); + } + iterator->destroy(iterator); + return config; +} + +/** + * implements cfg_store_t.get_peer_by_name. + */ +static peer_cfg_t *get_peer_cfg_by_name(private_cfg_store_t *this, char *name) +{ + backend_t *backend; + peer_cfg_t *config = NULL; + iterator_t *iterator = this->backends->create_iterator_locked( + this->backends, &this->mutex); + while (config == NULL && iterator->iterate(iterator, (void**)&backend)) + { + config = backend->get_peer_cfg_by_name(backend, name); + } + iterator->destroy(iterator); + return config; +} + +/** + * implements cfg_store_t.register_backend. + */ +static void register_backend(private_cfg_store_t *this, backend_t *backend) +{ + pthread_mutex_lock(&this->mutex); + this->backends->insert_last(this->backends, backend); + pthread_mutex_unlock(&this->mutex); +} + +/** + * implements cfg_store_t.unregister_backend. + */ +static void unregister_backend(private_cfg_store_t *this, backend_t *backend) +{ + backend_t *current; + iterator_t *iterator = this->backends->create_iterator_locked( + this->backends, &this->mutex); + while (iterator->iterate(iterator, (void**)¤t)) + { + if (backend == current) + { + iterator->remove(iterator); + break; + } + } + iterator->destroy(iterator); +} + +/** + * Implementation of cfg_store_t.destroy. + */ +static void destroy(private_cfg_store_t *this) +{ + this->backends->destroy(this->backends); + free(this); +} + +/* + * Described in header-file + */ +cfg_store_t *cfg_store_create() +{ + private_cfg_store_t *this = malloc_thing(private_cfg_store_t); + + this->public.get_ike_cfg = (ike_cfg_t*(*)(cfg_store_t*, host_t *, host_t *))get_ike_cfg; + this->public.get_peer_cfg = (peer_cfg_t*(*)(cfg_store_t*, identification_t *, identification_t *))get_peer_cfg; + this->public.get_peer_cfg_by_name = (peer_cfg_t*(*)(cfg_store_t*, char *name))get_peer_cfg_by_name; + this->public.register_backend = (void(*)(cfg_store_t*, backend_t *))register_backend; + this->public.unregister_backend = (void(*)(cfg_store_t*, backend_t *))unregister_backend; + this->public.destroy = (void(*)(cfg_store_t*))destroy; + + this->backends = linked_list_create(); + pthread_mutex_init(&this->mutex, NULL); + + return &this->public; +} diff --git a/src/charon/config/cfg_store.h b/src/charon/config/cfg_store.h new file mode 100644 index 000000000..0a0b5f3e1 --- /dev/null +++ b/src/charon/config/cfg_store.h @@ -0,0 +1,135 @@ +/** + * @file cfg_store.h + * + * @brief Interface cfg_store_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 . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 CFG_STORE_H_ +#define CFG_STORE_H_ + +typedef struct cfg_store_t cfg_store_t; + +#include +#include +#include +#include +#include +#include + + +/** + * @brief A multiplexer to use multiple cfg_store backends. + * + * Charon allows the use of multiple cfg_store backends simultaneously. To + * access all this backends by a single call, this class wraps multiple + * backends behind a single object. + * Backends may be registered and unregister at runtime dynamically. + * + * +---------+ +---------+ +--------------+ | + * | | | | +--------------+ | | + * | |----->| config | +--------------+ |-+ <==|==> IPC + * | | | |------>| backends |-+ | + * | daemon |----->| | +--------------+ | + * | core | +---------+ | + * | | | + * | | +---------+ +--------------+ | + * | |<-----| | +--------------+ | | + * | | | control-| +--------------+ |-+ <==|==> IPC + * | |<-----| ler |------>| controllers |-+ | + * | | | | +--------------+ | + * +---------+ +---------+ | + * + * The daemon core only knows the simple and single cfg_store interface. + * The cfg_store wraps two kind of objects, backends and trustchains. + * If the daemon needs something, it asks the cfg_store. cfg_store + * asks all of its backends if they can fullfil the request. + * + * + * @b Constructors: + * - stroke_create() + * + * @ingroup config + */ +struct cfg_store_t { + + /** + * @brief 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 + */ + ike_cfg_t *(*get_ike_cfg)(cfg_store_t *this, + host_t *my_host, host_t *other_host); + + /** + * @brief Get a peer_config identified by two IDs. + * + * @param this calling object + * @param my_id own ID + * @param other_id peers ID + * @return matching peer_config, or NULL if none found + */ + peer_cfg_t *(*get_peer_cfg)(cfg_store_t *this, identification_t *my_id, + identification_t *other_id); + + /** + * @brief Get a peer_config identified by its 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)(cfg_store_t *this, char *name); + + /** + * @brief Register a backend to be queried by the calls above. + * + * The backend first added is the most preferred. + * + * @param this calling object + */ + void (*register_backend) (cfg_store_t *this, backend_t *backend); + + /** + * @brief Unregister a backend. + * + * @param this calling object + */ + void (*unregister_backend) (cfg_store_t *this, backend_t *backend); + + /** + * @brief Destroys a cfg_store_t object. + * + * @param this calling object + */ + void (*destroy) (cfg_store_t *this); +}; + +/** + * @brief Create a new instance of the store. + * + * @return cfg_store instance + * + * @ingroup config + */ +cfg_store_t *cfg_store_create(void); + +#endif /*CFG_STORE_H_*/ diff --git a/src/charon/config/child_cfg.c b/src/charon/config/child_cfg.c new file mode 100644 index 000000000..2f5376753 --- /dev/null +++ b/src/charon/config/child_cfg.c @@ -0,0 +1,397 @@ +/** + * @file child_cfg.c + * + * @brief Implementation of child_cfg_t. + * + */ + +/* + * 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 . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 "child_cfg.h" + +#include + +ENUM(mode_names, MODE_TRANSPORT, MODE_BEET, + "TRANSPORT", + "TUNNEL", + "2", + "3", + "BEET", +); + +typedef struct private_child_cfg_t private_child_cfg_t; + +/** + * Private data of an child_cfg_t object + */ +struct private_child_cfg_t { + + /** + * Public part + */ + child_cfg_t public; + + /** + * Number of references hold by others to this child_cfg + */ + refcount_t refcount; + + /** + * Name of the child_cfg, used to query it + */ + char *name; + + /** + * list for all proposals + */ + linked_list_t *proposals; + + /** + * list for traffic selectors for my site + */ + linked_list_t *my_ts; + + /** + * list for traffic selectors for others site + */ + linked_list_t *other_ts; + + /** + * updown script + */ + char *updown; + + /** + * allow host access + */ + bool hostaccess; + + /** + * Mode to propose for a initiated CHILD: tunnel/transport + */ + mode_t mode; + + /** + * Time before an SA gets invalid + */ + u_int32_t lifetime; + + /** + * Time before an SA gets rekeyed + */ + u_int32_t rekeytime; + + /** + * Time, which specifies the range of a random value + * substracted from rekeytime. + */ + u_int32_t jitter; +}; + +/** + * Implementation of child_cfg_t.get_name + */ +static char *get_name(private_child_cfg_t *this) +{ + return this->name; +} + +/** + * Implementation of child_cfg_t.add_proposal + */ +static void add_proposal(private_child_cfg_t *this, proposal_t *proposal) +{ + this->proposals->insert_last(this->proposals, proposal); +} + +/** + * Implementation of child_cfg_t.get_proposals + */ +static linked_list_t* get_proposals(private_child_cfg_t *this) +{ + iterator_t *iterator; + proposal_t *current; + linked_list_t *proposals = linked_list_create(); + + iterator = this->proposals->create_iterator(this->proposals, TRUE); + while (iterator->iterate(iterator, (void**)¤t)) + { + current = current->clone(current); + proposals->insert_last(proposals, current); + } + iterator->destroy(iterator); + + return proposals; +} + +/** + * Implementation of child_cfg_t.get_name + */ +static proposal_t* select_proposal(private_child_cfg_t*this, linked_list_t *proposals) +{ + iterator_t *stored_iter, *supplied_iter; + proposal_t *stored, *supplied, *selected = NULL; + + 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)) + { + supplied_iter->reset(supplied_iter); + while (supplied_iter->iterate(supplied_iter, (void**)&supplied)) + { + selected = stored->select(stored, supplied); + if (selected) + { + break; + } + } + if (selected) + { + break; + } + } + stored_iter->destroy(stored_iter); + supplied_iter->destroy(supplied_iter); + return selected; +} + +/** + * Implementation of child_cfg_t.get_name + */ +static void add_traffic_selector(private_child_cfg_t *this, bool local, + traffic_selector_t *ts) +{ + if (local) + { + this->my_ts->insert_last(this->my_ts, ts); + } + else + { + this->other_ts->insert_last(this->other_ts, ts); + } +} + +/** + * Implementation of child_cfg_t.get_name + */ +static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool local, + linked_list_t *supplied, + host_t *host) +{ + iterator_t *i1, *i2; + 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); + } + else + { + i1 = this->other_ts->create_iterator(this->other_ts, FALSE); + } + + /* no list supplied, just fetch the stored traffic selectors */ + if (supplied == NULL) + { + while (i1->iterate(i1, (void**)&ts1)) + { + /* we make a copy of the TS, this allows us to update dynamic TS' */ + ts1 = ts1->clone(ts1); + if (host) + { + ts1->set_address(ts1, host); + } + result->insert_last(result, ts1); + } + i1->destroy(i1); + } + else + { + DBG2(DBG_CFG, "selecting traffic selectors"); + i2 = supplied->create_iterator(supplied, TRUE); + /* iterate over all stored selectors */ + while (i1->iterate(i1, (void**)&ts1)) + { + /* we make a copy of the TS, as we have to update dynamic TS' */ + ts1 = ts1->clone(ts1); + if (host) + { + ts1->set_address(ts1, host); + } + + i2->reset(i2); + /* iterate over all supplied traffic selectors */ + while (i2->iterate(i2, (void**)&ts2)) + { + DBG2(DBG_CFG, "stored %R <=> %R received", ts1, ts2); + selected = ts1->get_subset(ts1, ts2); + if (selected) + { + result->insert_last(result, selected); + DBG2(DBG_CFG, "found traffic selector for %s: %R", + local ? "us" : "other", selected); + } + } + ts1->destroy(ts1); + } + i1->destroy(i1); + i2->destroy(i2); + } + + /* 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)) + { + while (i2->iterate(i2, (void**)&ts2)) + { + if (ts1 != ts2) + { + if (ts2->is_contained_in(ts2, ts1)) + { + i2->remove(i2); + ts2->destroy(ts2); + i1->reset(i1); + break; + } + if (ts1->is_contained_in(ts1, ts2)) + { + i1->remove(i1); + ts1->destroy(ts1); + i2->reset(i2); + break; + } + } + } + } + i1->destroy(i1); + i2->destroy(i2); + + return result; +} + +/** + * Implementation of child_cfg_t.get_name + */ +static char* get_updown(private_child_cfg_t *this) +{ + return this->updown; +} + +/** + * Implementation of child_cfg_t.get_name + */ +static bool get_hostaccess(private_child_cfg_t *this) +{ + return this->hostaccess; +} + +/** + * Implementation of child_cfg_t.get_name + */ +static u_int32_t get_lifetime(private_child_cfg_t *this, bool rekey) +{ + if (rekey) + { + if (this->jitter == 0) + { + return this->rekeytime; + } + return this->rekeytime - (random() % this->jitter); + } + return this->lifetime; +} + +/** + * Implementation of child_cfg_t.get_name + */ +static mode_t get_mode(private_child_cfg_t *this) +{ + return this->mode; +} + +/** + * Implementation of child_cfg_t.get_name + */ +static void get_ref(private_child_cfg_t *this) +{ + ref_get(&this->refcount); +} + +/** + * Implements child_cfg_t.destroy. + */ +static void destroy(private_child_cfg_t *this) +{ + if (ref_put(&this->refcount)) + { + this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy)); + this->my_ts->destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy)); + this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy)); + if (this->updown) + { + free(this->updown); + } + free(this->name); + free(this); + } +} + +/* + * Described in header-file + */ +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) +{ + 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; + this->public.add_proposal = (void (*) (child_cfg_t*,proposal_t*))add_proposal; + this->public.get_proposals = (linked_list_t* (*) (child_cfg_t*))get_proposals; + this->public.select_proposal = (proposal_t* (*) (child_cfg_t*,linked_list_t*))select_proposal; + 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_lifetime = (u_int32_t (*) (child_cfg_t *,bool))get_lifetime; + this->public.get_ref = (void (*) (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; + this->jitter = jitter; + this->updown = updown ? strdup(updown) : NULL; + this->hostaccess = hostaccess; + this->mode = mode; + + /* initialize private members*/ + this->refcount = 1; + this->proposals = linked_list_create(); + this->my_ts = linked_list_create(); + this->other_ts = linked_list_create(); + + return &this->public; +} diff --git a/src/charon/config/child_cfg.h b/src/charon/config/child_cfg.h new file mode 100644 index 000000000..eab30122a --- /dev/null +++ b/src/charon/config/child_cfg.h @@ -0,0 +1,239 @@ +/** + * @file child_cfg.h + * + * @brief Interface of child_cfg_t. + * + */ + +/* + * 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 . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 CHILD_CFG_H_ +#define CHILD_CFG_H_ + +typedef enum mode_t mode_t; +typedef struct child_cfg_t child_cfg_t; + +#include +#include +#include + +/** + * @brief Mode of an CHILD_SA. + * + * These are equal to those defined in XFRM, so don't change. + * + * @ingroup child_cfg + */ +enum mode_t { + /** transport mode, no inner address */ + MODE_TRANSPORT = 0, + /** tunnel mode, inner and outer addresses */ + MODE_TUNNEL = 1, + /** BEET mode, tunnel mode but fixed, bound inner addresses */ + MODE_BEET = 4, +}; + +/** + * enum names for mode_t. + */ +extern enum_name_t *mode_names; + +/** + * @brief 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. + * Reading from the object is save, adding things is not allowed when other + * threads may access the object. + * A reference counter handles the number of references hold to this config. + * + * @b Constructors: + * - child_cfg_create() + * + * @ingroup child_cfg + */ +struct child_cfg_t { + + /** + * @brief 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. + * + * 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. + * + * Resulting list and all of its proposals must be freed after use. + * + * @param this calling object + * @return list of proposals + */ + linked_list_t* (*get_proposals)(child_cfg_t *this); + + /** + * @brief 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 + * @return selected proposal, or NULL if nothing matches + */ + proposal_t* (*select_proposal)(child_cfg_t*this, linked_list_t *proposals); + + /** + * @brief 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 + */ + void (*add_traffic_selector)(child_cfg_t *this, bool local, + traffic_selector_t *ts); + + /** + * @brief 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. + * If a list with traffic selectors is supplied, these are used to narrow + * down the traffic selector list to the greatest common divisor. + * Some traffic selector may be "dymamic", meaning they are narrowed down + * to a specific address (host-to-host or virtual-IP setups). Use + * 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 + * @return list containing the traffic selectors + */ + linked_list_t *(*get_traffic_selectors)(child_cfg_t *this, bool local, + linked_list_t *supplied, + host_t *host); + + /** + * @brief 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)? + * + * @param this calling object + * @return value of hostaccess flag + */ + bool (*get_hostaccess) (child_cfg_t *this); + + /** + * @brief 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 + * returned when the CHILD_SA must be deleted. + * 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. + * + * 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 + */ + mode_t (*get_mode) (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(), + * + * @param this calling object + */ + void (*get_ref) (child_cfg_t *this); + + /** + * @brief 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. + * + * The "name" string gets cloned. + * Lifetimes are in seconds. To prevent to peers to start rekeying at the + * same time, a jitter may be specified. Rekeying of an SA starts at + * (rekeytime - random(0, jitter)). You should specify + * lifetime > rekeytime > jitter. + * After a call to create, a reference is obtained (refcount = 1). + * + * @param name name of the child_cfg + * @param lifetime lifetime after CHILD_SA expires and gets deleted + * @param rekeytime time when rekeying should be initiated + * @param jitter range of randomization time to remove from rekeytime + * @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 + * @return child_cfg_t object + * + * @ingroup child_cfg + */ +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); + +#endif /* CHILD_CFG_H_ */ diff --git a/src/charon/config/connections/connection.c b/src/charon/config/connections/connection.c deleted file mode 100644 index ffe508992..000000000 --- a/src/charon/config/connections/connection.c +++ /dev/null @@ -1,404 +0,0 @@ -/** - * @file connection.c - * - * @brief Implementation of connection_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 . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT 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 - -#include -#include - -ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND, - "CERT_ALWAYS_SEND", - "CERT_SEND_IF_ASKED", - "CERT_NEVER_SEND" -); - -typedef struct private_connection_t private_connection_t; - -/** - * Private data of an connection_t object - */ -struct private_connection_t { - - /** - * Public part - */ - connection_t public; - - /** - * Number of references hold by others to this connection - */ - refcount_t refcount; - - /** - * Name of the connection - */ - char *name; - - /** - * Does charon handle this connection? Or can he ignore it? - */ - bool ikev2; - - /** - * should we send a certificate request? - */ - cert_policy_t certreq_policy; - - /** - * should we send a certificates? - */ - cert_policy_t cert_policy; - - /** - * ID of us - */ - identification_t *my_id; - - /** - * Host information of my host. - */ - host_t *my_host; - - /** - * Host information of other host. - */ - host_t *other_host; - - /** - * Interval to send DPD liveness checks on inactivity - */ - u_int32_t dpd_delay; - - /** - * Number of retransmission sequences to send bevore giving up - */ - u_int32_t keyingtries; - - /** - * Supported proposals - */ - linked_list_t *proposals; - - /** - * Time before an SA gets invalid - */ - u_int32_t soft_lifetime; - - /** - * Time before an SA gets rekeyed - */ - u_int32_t hard_lifetime; - - /** - * Use full reauthentication instead of rekeying - */ - bool reauth; - - /** - * Time, which specifies the range of a random value - * substracted from soft_lifetime. - */ - u_int32_t jitter; -}; - -/** - * Implementation of connection_t.get_name. - */ -static char *get_name (private_connection_t *this) -{ - return this->name; -} - -/** - * Implementation of connection_t.is_ikev2. - */ -static bool is_ikev2 (private_connection_t *this) -{ - return this->ikev2; -} - -/** - * Implementation of connection_t.get_certreq_policy. - */ -static cert_policy_t get_certreq_policy (private_connection_t *this) -{ - return this->certreq_policy; -} - -/** - * Implementation of connection_t.get_cert_policy. - */ -static cert_policy_t get_cert_policy (private_connection_t *this) -{ - return this->cert_policy; -} - -/** - * Implementation of connection_t.get_my_host. - */ -static host_t *get_my_host (private_connection_t *this) -{ - return this->my_host; -} - -/** - * Implementation of connection_t.get_other_host. - */ -static host_t *get_other_host (private_connection_t *this) -{ - return this->other_host; -} - -/** - * Implementation of connection_t.get_proposals. - */ -static linked_list_t* get_proposals(private_connection_t *this) -{ - iterator_t *iterator; - proposal_t *current; - linked_list_t *proposals = linked_list_create(); - - iterator = this->proposals->create_iterator(this->proposals, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - current = current->clone(current); - proposals->insert_last(proposals, (void*)current); - } - iterator->destroy(iterator); - - return proposals; -} - -/** - * Implementation of connection_t.select_proposal. - */ -static proposal_t *select_proposal(private_connection_t *this, linked_list_t *proposals) -{ - iterator_t *stored_iter, *supplied_iter; - proposal_t *stored, *supplied, *selected; - - 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)) - { - supplied_iter->reset(supplied_iter); - - while (supplied_iter->iterate(supplied_iter, (void**)&supplied)) - { - selected = stored->select(stored, supplied); - if (selected) - { - /* they match, return */ - stored_iter->destroy(stored_iter); - supplied_iter->destroy(supplied_iter); - return selected; - } - } - } - /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */ - stored_iter->destroy(stored_iter); - supplied_iter->destroy(supplied_iter); - - return NULL; -} - -/** - * Implementation of connection_t.add_proposal. - */ -static void add_proposal(private_connection_t *this, proposal_t *proposal) -{ - this->proposals->insert_last(this->proposals, proposal); -} - -/** - * Implementation of connection_t.get_dpd_delay. - */ -static u_int32_t get_dpd_delay(private_connection_t *this) -{ - return this->dpd_delay; -} - -/** - * Implementation of connection_t.get_keyingtries. - */ -static u_int32_t get_keyingtries(private_connection_t *this) -{ - return this->keyingtries; -} - -/** - * Implementation of connection_t.get_dh_group. - */ -static diffie_hellman_group_t get_dh_group(private_connection_t *this) -{ - iterator_t *iterator; - proposal_t *proposal; - algorithm_t *algo; - diffie_hellman_group_t dh_group = MODP_NONE; - - iterator = this->proposals->create_iterator(this->proposals, TRUE); - while (iterator->iterate(iterator, (void**)&proposal)) - { - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &algo)) - { - dh_group = algo->algorithm; - break; - } - } - iterator->destroy(iterator); - return dh_group; -} - -/** - * Implementation of connection_t.check_dh_group. - */ -static bool check_dh_group(private_connection_t *this, diffie_hellman_group_t dh_group) -{ - iterator_t *prop_iter, *alg_iter; - proposal_t *proposal; - algorithm_t *algo; - - prop_iter = this->proposals->create_iterator(this->proposals, TRUE); - while (prop_iter->iterate(prop_iter, (void**)&proposal)) - { - alg_iter = proposal->create_algorithm_iterator(proposal, DIFFIE_HELLMAN_GROUP); - while (alg_iter->iterate(alg_iter, (void**)&algo)) - { - if (algo->algorithm == dh_group) - { - prop_iter->destroy(prop_iter); - alg_iter->destroy(alg_iter); - return TRUE; - } - } - alg_iter->destroy(alg_iter); - } - prop_iter->destroy(prop_iter); - return FALSE; -} -/** - * Implementation of connection_t.get_soft_lifetime - */ -static u_int32_t get_soft_lifetime(private_connection_t *this) -{ - if (this->jitter == 0) - { - return this->soft_lifetime ; - } - return this->soft_lifetime - (random() % this->jitter); -} - -/** - * Implementation of connection_t.get_hard_lifetime. - */ -static u_int32_t get_hard_lifetime(private_connection_t *this) -{ - return this->hard_lifetime; -} - -/** - * Implementation of connection_t.get_reauth. - */ -static bool get_reauth(private_connection_t *this) -{ - return this->reauth; -} - -/** - * Implementation of connection_t.get_ref. - */ -static void get_ref(private_connection_t *this) -{ - ref_get(&this->refcount); -} - -/** - * Implementation of connection_t.destroy. - */ -static void destroy(private_connection_t *this) -{ - if (ref_put(&this->refcount)) - { - 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->name); - free(this); - } -} - -/** - * Described in header. - */ -connection_t * connection_create(char *name, bool ikev2, - cert_policy_t cert_policy, - cert_policy_t certreq_policy, - host_t *my_host, host_t *other_host, - u_int32_t dpd_delay, bool reauth, - u_int32_t keyingtries, - u_int32_t hard_lifetime, - u_int32_t soft_lifetime, u_int32_t jitter) -{ - private_connection_t *this = malloc_thing(private_connection_t); - - /* public functions */ - this->public.get_name = (char*(*)(connection_t*))get_name; - this->public.is_ikev2 = (bool(*)(connection_t*))is_ikev2; - this->public.get_cert_policy = (cert_policy_t(*)(connection_t*))get_cert_policy; - this->public.get_certreq_policy = (cert_policy_t(*)(connection_t*))get_certreq_policy; - this->public.get_my_host = (host_t*(*)(connection_t*))get_my_host; - this->public.get_other_host = (host_t*(*)(connection_t*))get_other_host; - this->public.get_proposals = (linked_list_t*(*)(connection_t*))get_proposals; - this->public.select_proposal = (proposal_t*(*)(connection_t*,linked_list_t*))select_proposal; - this->public.add_proposal = (void(*)(connection_t*, proposal_t*)) add_proposal; - this->public.get_dpd_delay = (u_int32_t(*)(connection_t*)) get_dpd_delay; - this->public.get_reauth = (bool(*)(connection_t*)) get_reauth; - this->public.get_keyingtries = (u_int32_t(*)(connection_t*)) get_keyingtries; - this->public.get_dh_group = (diffie_hellman_group_t(*)(connection_t*)) get_dh_group; - this->public.check_dh_group = (bool(*)(connection_t*,diffie_hellman_group_t)) check_dh_group; - this->public.get_soft_lifetime = (u_int32_t (*) (connection_t *))get_soft_lifetime; - this->public.get_hard_lifetime = (u_int32_t (*) (connection_t *))get_hard_lifetime; - this->public.get_ref = (void(*)(connection_t*))get_ref; - this->public.destroy = (void(*)(connection_t*))destroy; - - /* private variables */ - this->refcount = 1; - this->name = strdup(name); - this->ikev2 = ikev2; - this->cert_policy = cert_policy; - this->certreq_policy = certreq_policy; - this->my_host = my_host; - this->other_host = other_host; - this->dpd_delay = dpd_delay; - this->reauth = reauth; - this->keyingtries = keyingtries; - this->hard_lifetime = hard_lifetime; - this->soft_lifetime = soft_lifetime; - this->jitter = jitter; - - this->proposals = linked_list_create(); - - return &this->public; -} diff --git a/src/charon/config/connections/connection.h b/src/charon/config/connections/connection.h deleted file mode 100644 index d0788876f..000000000 --- a/src/charon/config/connections/connection.h +++ /dev/null @@ -1,292 +0,0 @@ -/** - * @file connection.h - * - * @brief Interface of connection_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 . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT 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 CONNECTION_H_ -#define CONNECTION_H_ - -typedef enum cert_policy_t cert_policy_t; -typedef struct connection_t connection_t; - -#include -#include -#include -#include -#include -#include - - -/** - * 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. - */ -enum cert_policy_t { - /** always send certificates, even when not requested */ - CERT_ALWAYS_SEND = 0, - /** send certificate upon cert request */ - CERT_SEND_IF_ASKED = 1, - /** never send a certificate, even when requested */ - CERT_NEVER_SEND = 2, -}; - -/** - * enum strings for cert_policy_t - * - * @ingroup config - */ -extern enum_name_t *cert_policy_names; - -/** - * @brief A connection_t defines the rules to set up an IKE_SA. - * - * @b Constructors: - * - connection_create() - * - * @ingroup config - */ -struct connection_t { - - /** - * @brief Get my address as host_t object. - * - * Object is NOT getting cloned. - * - * @param this calling object - * @return host information as host_t object - */ - host_t *(*get_my_host) (connection_t *this); - - /** - * @brief Get others address as host_t object. - * - * Object is NOT getting cloned. - * - * @param this calling object - * @return host information as host_t object - */ - host_t *(*get_other_host) (connection_t *this); - - /** - * @brief Returns a list of all supported proposals. - * - * Returned list and its proposals must be destroyed after usage. - * - * @param this calling object - * @return list containing all the proposals - */ - linked_list_t *(*get_proposals) (connection_t *this); - - /** - * @brief 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) (connection_t *this, proposal_t *proposal); - - /** - * @brief Select a proposed from suggested proposals. - * - * Returned proposal must be destroyed after usage. - * - * @param this calling object - * @param proposals list of proposals to select from - * @return selected proposal, or NULL if none matches. - */ - proposal_t *(*select_proposal) (connection_t *this, linked_list_t *proposals); - - /** - * @brief Get the DPD check interval. - * - * @param this calling object - * @return dpd_delay in seconds - */ - u_int32_t (*get_dpd_delay) (connection_t *this); - - /** - * @brief Should a full reauthentication be done instead of rekeying? - * - * @param this calling object - * @return TRUE to use full reauthentication - */ - bool (*get_reauth) (connection_t *this); - - /** - * @brief Get the max number of retransmission sequences. - * - * @param this calling object - * @return max number of retransmission sequences - */ - u_int32_t (*get_keyingtries) (connection_t *this); - - /** - * @brief Get the connection name. - * - * Name must not be freed, since it points to - * internal data. - * - * @param this calling object - * @return name of the connection - */ - char* (*get_name) (connection_t *this); - - /** - * @brief Check if the connection is marked as an IKEv2 connection. - * - * Since all connections (IKEv1+2) are loaded, but charon handles - * only those marked with IKEv2, this flag can tell us if we must - * ignore a connection on initiaton. Then pluto will do it for us. - * - * @param this calling object - * @return - TRUE, if this is an IKEv2 connection - */ - bool (*is_ikev2) (connection_t *this); - - /** - * @brief Should be sent a certificate request for this connection? - * - * A certificate request contains serials of our trusted CA certificates. - * This flag says if such a request is sent on connection setup to - * the peer. It should be omitted when CERT_SEND_NEVER, sended otherwise. - * - * @param this calling object - * @return certificate request sending policy - */ - cert_policy_t (*get_certreq_policy) (connection_t *this); - - /** - * @brief Should be sent a certificate for this connection? - * - * Return the policy used to send the certificate. - * - * @param this calling object - * @return certificate sending policy - */ - cert_policy_t (*get_cert_policy) (connection_t *this); - - /** - * @brief Get the DH group to use for connection initialization. - * - * @param this calling object - * @return dh group to use for initialization - */ - diffie_hellman_group_t (*get_dh_group) (connection_t *this); - - /** - * @brief Check if a suggested dh group is acceptable. - * - * If we guess a wrong DH group for IKE_SA_INIT, the other - * peer will send us a offer. But is this acceptable for us? - * - * @param this calling object - * @return TRUE if group acceptable - */ - bool (*check_dh_group) (connection_t *this, diffie_hellman_group_t dh_group); - - /** - * @brief Get the lifetime of a connection, before IKE_SA rekeying starts. - * - * A call to this function automatically adds a jitter to - * avoid simultanous rekeying. - * - * @param this calling object - * @return lifetime in seconds - */ - u_int32_t (*get_soft_lifetime) (connection_t *this); - - /** - * @brief Get the lifetime of a connection, before IKE_SA gets deleted. - * - * @param this calling object - * @return lifetime in seconds - */ - u_int32_t (*get_hard_lifetime) (connection_t *this); - - /** - * @brief Get a new reference to this connection. - * - * Get a new reference to this connection 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 - */ - void (*get_ref) (connection_t *this); - - /** - * @brief Destroys a connection_t object. - * - * Decrements the internal reference counter and - * destroys the connection when it reaches zero. - * - * @param this calling object - */ - void (*destroy) (connection_t *this); -}; - -/** - * @brief Creates a connection_t object. - * - * Supplied hosts become owned by connection, so - * do not modify or destroy them after a call to - * connection_create(). Name gets cloned internally. - * The retrasmit sequence number says how fast we give up when the peer - * does not respond. A high value may bridge-over temporary connection - * problems, a small value can detect dead peers faster. - * - * @param name connection identifier - * @param ikev2 TRUE if this is an IKEv2 connection - * @param cert_policy certificate send policy - * @param cert_req_policy certificate request send policy - * @param my_host host_t representing local address - * @param other_host host_t representing remote address - * @param dpd_delay interval of DPD liveness checks - * @param reauth use full reauthentication instead of rekeying - * @param keyingtries number of retransmit sequences to use - * @param hard_lifetime lifetime before deleting an IKE_SA - * @param soft_lifetime lifetime before rekeying an IKE_SA - * @param jitter range of randomization time - * @return connection_t object. - * - * @ingroup config - */ -connection_t * connection_create(char *name, bool ikev2, - cert_policy_t cert_pol, cert_policy_t req_pol, - host_t *my_host, host_t *other_host, - u_int32_t dpd_delay, bool reauth, - u_int32_t keyingtries, - u_int32_t hard_lifetime, u_int32_t soft_lifetime, - u_int32_t jitter); - -#endif /* CONNECTION_H_ */ diff --git a/src/charon/config/connections/connection_store.h b/src/charon/config/connections/connection_store.h deleted file mode 100755 index 70f209d3b..000000000 --- a/src/charon/config/connections/connection_store.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file connection_store.h - * - * @brief Interface connection_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 . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT 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 CONNECTION_STORE_H_ -#define CONNECTION_STORE_H_ - -typedef struct connection_store_t connection_store_t; - -#include -#include -#include - -/** - * @brief The interface for a store of connection_t's. - * - * @b Constructors: - * - stroke_create() - * - * @ingroup config - */ -struct connection_store_t { - - /** - * @brief Returns a connection definition identified by two hosts. - * - * This call is usefull to get a connection identified by addresses. - * It may be used after kernel request for traffic protection. - * The returned connection gets created/cloned and therefore must - * be destroyed after usage. - * - * @param this calling object - * @param my_id own address of connection - * @param other_id others address of connection - * @return - * - connection_t, if found - * - NULL otherwise - */ - connection_t *(*get_connection_by_hosts)(connection_store_t *this, - host_t *my_host, host_t *other_host); - - /** - * @brief Returns a connection identified by its name. - * - * This call is usefull to get a connection identified its - * name, as on an connection setup. - * - * @param this calling object - * @param name name of the connection to get - * @return - * - connection_t, if found - * - NULL otherwise - */ - connection_t *(*get_connection_by_name) (connection_store_t *this, char *name); - - /** - * @brief Add a connection to the store. - * - * After a successful call, the connection is owned by the store and may - * not be manipulated nor destroyed. - * - * @param this calling object - * @param connection connection to add - * @return - * - SUCCESS, or - * - FAILED - */ - status_t (*add_connection) (connection_store_t *this, connection_t *connection); - - /** - * @brief Delete a connection from the store. - * - * Remove a connection from the connection store, identified - * by the connections name. - * - * @param this calling object - * @param name name of the connection to delete - * @return - * - SUCCESS, or - * - NOT_FOUND - */ - status_t (*delete_connection) (connection_store_t *this, char *name); - - /** - * @brief Get an iterator for the stored connections. - * - * @param this calling object - * @return iterator over all stored connections - */ - iterator_t* (*create_iterator) (connection_store_t *this); - - /** - * @brief Destroys a connection_store_t object. - * - * @param this calling object - */ - void (*destroy) (connection_store_t *this); -}; - -#endif /* CONNECTION_STORE_H_ */ diff --git a/src/charon/config/connections/local_connection_store.c b/src/charon/config/connections/local_connection_store.c deleted file mode 100644 index df4ec230a..000000000 --- a/src/charon/config/connections/local_connection_store.c +++ /dev/null @@ -1,237 +0,0 @@ -/** - * @file local_connection_store.c - * - * @brief Implementation of local_connection_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 . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT 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 - -#include "local_connection_store.h" - -#include -#include - - -typedef struct private_local_connection_store_t private_local_connection_store_t; - -/** - * Private data of an local_connection_store_t object - */ -struct private_local_connection_store_t { - - /** - * Public part - */ - local_connection_store_t public; - - /** - * stored connection - */ - linked_list_t *connections; - - /** - * Mutex to exclusivly access connection list - */ - pthread_mutex_t mutex; -}; - - -/** - * Implementation of connection_store_t.get_connection_by_hosts. - */ -static connection_t *get_connection_by_hosts(private_local_connection_store_t *this, host_t *my_host, host_t *other_host) -{ - typedef enum { - PRIO_UNDEFINED= 0x00, - PRIO_ADDR_ANY= 0x01, - PRIO_ADDR_MATCH= 0x02 - } prio_t; - - prio_t best_prio = PRIO_UNDEFINED; - - iterator_t *iterator; - connection_t *candidate; - connection_t *found = NULL; - - DBG2(DBG_CFG, "looking for connection for host pair %H...%H", - my_host, other_host); - - pthread_mutex_lock(&(this->mutex)); - iterator = this->connections->create_iterator(this->connections, TRUE); - /* determine closest matching connection */ - while (iterator->iterate(iterator, (void**)&candidate)) - { - host_t *candidate_my_host; - host_t *candidate_other_host; - - candidate_my_host = candidate->get_my_host(candidate); - candidate_other_host = candidate->get_other_host(candidate); - - /* my_host addresses must match*/ - if (my_host->ip_equals(my_host, candidate_my_host)) - { - prio_t prio = PRIO_UNDEFINED; - - /* exact match of peer host address or wildcard address? */ - if (other_host->ip_equals(other_host, candidate_other_host)) - { - prio |= PRIO_ADDR_MATCH; - } - else if (candidate_other_host->is_anyaddr(candidate_other_host)) - { - prio |= PRIO_ADDR_ANY; - } - - DBG2(DBG_CFG, "candidate connection \"%s\": %H...%H (prio=%d)", - candidate->get_name(candidate), - candidate_my_host, candidate_other_host, prio); - - if (prio > best_prio) - { - found = candidate; - best_prio = prio; - } - } - } - iterator->destroy(iterator); - - if (found) - { - DBG2(DBG_CFG, "found matching connection \"%s\": %H...%H (prio=%d)", - found->get_name(found), found->get_my_host(found), - found->get_other_host(found), best_prio); - - /* give out a new reference to it */ - found->get_ref(found); - } - pthread_mutex_unlock(&(this->mutex)); - return found; -} - -/** - * Implementation of connection_store_t.get_connection_by_name. - */ -static connection_t *get_connection_by_name(private_local_connection_store_t *this, char *name) -{ - iterator_t *iterator; - connection_t *current, *found = NULL; - - pthread_mutex_lock(&(this->mutex)); - iterator = this->connections->create_iterator(this->connections, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - if (strcmp(name, current->get_name(current)) == 0) - { - found = current; - break; - } - } - iterator->destroy(iterator); - pthread_mutex_unlock(&(this->mutex)); - - if (found) - { - /* get a new reference for it */ - found->get_ref(found); - } - return found; -} - -/** - * Implementation of connection_store_t.delete_connection. - */ -static status_t delete_connection(private_local_connection_store_t *this, char *name) -{ - iterator_t *iterator; - connection_t *current; - bool found = FALSE; - - pthread_mutex_lock(&(this->mutex)); - iterator = this->connections->create_iterator(this->connections, TRUE); - while (iterator->iterate(iterator, (void **)¤t)) - { - if (strcmp(current->get_name(current), name) == 0) - { - /* remove connection from list, and destroy it */ - iterator->remove(iterator); - current->destroy(current); - found = TRUE; - break; - } - } - iterator->destroy(iterator); - pthread_mutex_unlock(&(this->mutex)); - if (found) - { - return SUCCESS; - } - return NOT_FOUND; -} - -/** - * Implementation of connection_store_t.add_connection. - */ -static status_t add_connection(private_local_connection_store_t *this, connection_t *connection) -{ - pthread_mutex_lock(&(this->mutex)); - this->connections->insert_last(this->connections, connection); - pthread_mutex_unlock(&(this->mutex)); - return SUCCESS; -} - -/** - * Implementation of connection_store_t.create_iterator. - */ -static iterator_t* create_iterator(private_local_connection_store_t *this) -{ - return this->connections->create_iterator_locked(this->connections, - &this->mutex); -} - -/** - * Implementation of connection_store_t.destroy. - */ -static void destroy (private_local_connection_store_t *this) -{ - pthread_mutex_lock(&(this->mutex)); - this->connections->destroy_offset(this->connections, offsetof(connection_t, destroy)); - pthread_mutex_unlock(&(this->mutex)); - free(this); -} - -/** - * Described in header. - */ -local_connection_store_t * local_connection_store_create(void) -{ - private_local_connection_store_t *this = malloc_thing(private_local_connection_store_t); - - this->public.connection_store.get_connection_by_hosts = (connection_t*(*)(connection_store_t*,host_t*,host_t*))get_connection_by_hosts; - this->public.connection_store.get_connection_by_name = (connection_t*(*)(connection_store_t*,char*))get_connection_by_name; - this->public.connection_store.delete_connection = (status_t(*)(connection_store_t*,char*))delete_connection; - this->public.connection_store.add_connection = (status_t(*)(connection_store_t*,connection_t*))add_connection; - this->public.connection_store.create_iterator = (iterator_t*(*)(connection_store_t*))create_iterator; - this->public.connection_store.destroy = (void(*)(connection_store_t*))destroy; - - /* private variables */ - this->connections = linked_list_create(); - pthread_mutex_init(&(this->mutex), NULL); - - return (&this->public); -} diff --git a/src/charon/config/connections/local_connection_store.h b/src/charon/config/connections/local_connection_store.h deleted file mode 100644 index e78ed809a..000000000 --- a/src/charon/config/connections/local_connection_store.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @file local_connection_store.h - * - * @brief Interface of local_connection_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 . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT 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_CONNECTION_H_ -#define LOCAL_CONNECTION_H_ - -typedef struct local_connection_store_t local_connection_store_t; - -#include -#include - -/** - * @brief A connection_store_t implementation using a simple connection list. - * - * The local_connection_store_t class implements the connection_store_t interface - * as simple as possible. connection_t's are stored in an in-memory list. - * - * @b Constructors: - * - local_connection_store_create() - * - * @todo Make thread-save first - * @todo Add remove_connection method - * - * @ingroup config - */ -struct local_connection_store_t { - - /** - * Implements connection_store_t interface - */ - connection_store_t connection_store; -}; - -/** - * @brief Creates a local_connection_store_t instance. - * - * @return connection store instance. - * - * @ingroup config - */ -local_connection_store_t * local_connection_store_create(void); - -#endif /* LOCAL_CONNECTION_H_ */ diff --git a/src/charon/config/ike_cfg.c b/src/charon/config/ike_cfg.c new file mode 100644 index 000000000..61e62115d --- /dev/null +++ b/src/charon/config/ike_cfg.c @@ -0,0 +1,259 @@ +/** + * @file ike_cfg.c + * + * @brief Implementation of ike_cfg_t. + * + */ + +/* + * 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 . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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_cfg.h" + +#include + + +typedef struct private_ike_cfg_t private_ike_cfg_t; + +/** + * Private data of an ike_cfg_t object + */ +struct private_ike_cfg_t { + + /** + * Public part + */ + ike_cfg_t public; + + /** + * Number of references hold by others to this ike_cfg + */ + refcount_t refcount; + + /** + * Address of local host + */ + host_t *my_host; + + /** + * Address of remote host + */ + host_t *other_host; + + /** + * should we send a certificate request? + */ + bool certreq; + + /** + * List of proposals to use + */ + linked_list_t *proposals; +}; + +/** + * Implementation of ike_cfg_t.certreq. + */ +static bool send_certreq(private_ike_cfg_t *this) +{ + return this->certreq; +} + +/** + * Implementation of ike_cfg_t.get_my_host. + */ +static host_t *get_my_host (private_ike_cfg_t *this) +{ + return this->my_host; +} + +/** + * Implementation of ike_cfg_t.get_other_host. + */ +static host_t *get_other_host (private_ike_cfg_t *this) +{ + return this->other_host; +} + +/** + * Implementation of ike_cfg_t.add_proposal. + */ +static void add_proposal(private_ike_cfg_t *this, proposal_t *proposal) +{ + this->proposals->insert_last(this->proposals, proposal); +} + +/** + * Implementation of ike_cfg_t.get_proposals. + */ +static linked_list_t* get_proposals(private_ike_cfg_t *this) +{ + iterator_t *iterator; + proposal_t *current; + linked_list_t *proposals = linked_list_create(); + + iterator = this->proposals->create_iterator(this->proposals, TRUE); + while (iterator->iterate(iterator, (void**)¤t)) + { + current = current->clone(current); + proposals->insert_last(proposals, (void*)current); + } + iterator->destroy(iterator); + + return proposals; +} + +/** + * Implementation of ike_cfg_t.select_proposal. + */ +static proposal_t *select_proposal(private_ike_cfg_t *this, + linked_list_t *proposals) +{ + iterator_t *stored_iter, *supplied_iter; + proposal_t *stored, *supplied, *selected; + + 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)) + { + supplied_iter->reset(supplied_iter); + + while (supplied_iter->iterate(supplied_iter, (void**)&supplied)) + { + selected = stored->select(stored, supplied); + if (selected) + { + /* they match, return */ + stored_iter->destroy(stored_iter); + supplied_iter->destroy(supplied_iter); + return selected; + } + } + } + /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */ + stored_iter->destroy(stored_iter); + supplied_iter->destroy(supplied_iter); + + return NULL; +} + +/** + * Implementation of ike_cfg_t.get_dh_group. + */ +static diffie_hellman_group_t get_dh_group(private_ike_cfg_t *this) +{ + iterator_t *iterator; + proposal_t *proposal; + algorithm_t *algo; + diffie_hellman_group_t dh_group = MODP_NONE; + + iterator = this->proposals->create_iterator(this->proposals, TRUE); + while (iterator->iterate(iterator, (void**)&proposal)) + { + if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &algo)) + { + dh_group = algo->algorithm; + break; + } + } + iterator->destroy(iterator); + return dh_group; +} + +/** + * Implementation of ike_cfg_t.check_dh_group. + */ +static bool check_dh_group(private_ike_cfg_t *this, + diffie_hellman_group_t dh_group) +{ + iterator_t *prop_iter, *alg_iter; + proposal_t *proposal; + algorithm_t *algo; + + prop_iter = this->proposals->create_iterator(this->proposals, TRUE); + while (prop_iter->iterate(prop_iter, (void**)&proposal)) + { + alg_iter = proposal->create_algorithm_iterator(proposal, + DIFFIE_HELLMAN_GROUP); + while (alg_iter->iterate(alg_iter, (void**)&algo)) + { + if (algo->algorithm == dh_group) + { + prop_iter->destroy(prop_iter); + alg_iter->destroy(alg_iter); + return TRUE; + } + } + alg_iter->destroy(alg_iter); + } + prop_iter->destroy(prop_iter); + return FALSE; +} + +/** + * Implementation of ike_cfg_t.get_ref. + */ +static void get_ref(private_ike_cfg_t *this) +{ + ref_get(&this->refcount); +} + +/** + * Implementation of ike_cfg_t.destroy. + */ +static void destroy(private_ike_cfg_t *this) +{ + if (ref_put(&this->refcount)) + { + 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); + } +} + +/** + * Described in header. + */ +ike_cfg_t *ike_cfg_create(bool certreq, host_t *my_host, host_t *other_host) +{ + 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.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.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.check_dh_group = (bool(*)(ike_cfg_t*,diffie_hellman_group_t)) check_dh_group; + this->public.get_ref = (void(*)(ike_cfg_t*))get_ref; + this->public.destroy = (void(*)(ike_cfg_t*))destroy; + + /* private variables */ + this->refcount = 1; + this->certreq = certreq; + this->my_host = my_host; + this->other_host = other_host; + + this->proposals = linked_list_create(); + + return &this->public; +} diff --git a/src/charon/config/ike_cfg.h b/src/charon/config/ike_cfg.h new file mode 100644 index 000000000..f8f5a3500 --- /dev/null +++ b/src/charon/config/ike_cfg.h @@ -0,0 +1,160 @@ +/** + * @file ike_cfg.h + * + * @brief Interface of ike_cfg_t. + * + */ + +/* + * 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 . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 IKE_CFG_H_ +#define IKE_CFG_H_ + +typedef struct ike_cfg_t ike_cfg_t; + +#include +#include +#include +#include +#include +#include + +/** + * @brief An ike_cfg_t defines the rules to set up an IKE_SA. + * + * @b Constructors: + * - ike_cfg_create() + * + * @ingroup ike_cfg + */ +struct ike_cfg_t { + + /** + * @brief Get own address. + * + * @param this calling object + * @return host information as host_t object + */ + host_t* (*get_my_host) (ike_cfg_t *this); + + /** + * @brief Get peers address. + * + * @param this calling object + * @return host information as host_t object + */ + host_t* (*get_other_host) (ike_cfg_t *this); + + /** + * @brief 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. + * + * 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. + * + * 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? + * + * @param this calling object + * @return certificate request sending policy + */ + bool (*send_certreq) (ike_cfg_t *this); + + /** + * @brief 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 Check if a suggested DH group is acceptable. + * + * If we guess a wrong DH group for IKE_SA_INIT, the other + * peer will send us a offer. But is this acceptable for us? + * + * @param this calling object + * @return TRUE if group acceptable + */ + bool (*check_dh_group) (ike_cfg_t *this, diffie_hellman_group_t dh_group); + + /** + * @brief Get a new reference to this ike_cfg. + * + * 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 this calling object + */ + void (*get_ref) (ike_cfg_t *this); + + /** + * @brief 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. + * + * 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 my_host host_t representing local address + * @param other_host host_t representing remote address + * @return ike_cfg_t object. + * + * @ingroup config + */ +ike_cfg_t *ike_cfg_create(bool certreq, host_t *my_host, host_t *other_host); + +#endif /* IKE_CFG_H_ */ diff --git a/src/charon/config/peer_cfg.c b/src/charon/config/peer_cfg.c new file mode 100644 index 000000000..453fce555 --- /dev/null +++ b/src/charon/config/peer_cfg.c @@ -0,0 +1,470 @@ +/** + * @file peer_cfg.c + * + * @brief Implementation of peer_cfg_t. + * + */ + +/* + * 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 . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 +#include + +#include "peer_cfg.h" + +#include +#include + +ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND, + "CERT_ALWAYS_SEND", + "CERT_SEND_IF_ASKED", + "CERT_NEVER_SEND" +); + +ENUM(dpd_action_names, DPD_NONE, DPD_RESTART, + "DPD_NONE", + "DPD_CLEAR", + "DPD_ROUTE", + "DPD_RESTART" +); + +typedef struct private_peer_cfg_t private_peer_cfg_t; + +/** + * Private data of an peer_cfg_t object + */ +struct private_peer_cfg_t { + + /** + * Public part + */ + peer_cfg_t public; + + /** + * Number of references hold by others to this peer_cfg + */ + refcount_t refcount; + + /** + * Name of the peer_cfg, used to query it + */ + char *name; + + /** + * IKE version to use for initiation + */ + u_int ike_version; + + /** + * IKE config associated to this peer config + */ + ike_cfg_t *ike_cfg; + + /** + * list of child configs associated to this peer config + */ + linked_list_t *child_cfgs; + + /** + * mutex to lock access to list of child_cfgs + */ + pthread_mutex_t mutex; + + /** + * id to use to identify us + */ + identification_t *my_id; + + /** + * allowed id for other + */ + 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; + + /** + * should we send a certificate + */ + cert_policy_t cert_policy; + + /** + * Method to use for own authentication data + */ + auth_method_t auth_method; + + /** + * EAP type to use for peer authentication + */ + eap_type_t eap_type; + + /** + * number of tries after giving up if peer does not respond + */ + u_int32_t keyingtries; + + /** + * user reauthentication instead of rekeying + */ + bool use_reauth; + + /** + * Time before an SA gets invalid + */ + u_int32_t lifetime; + + /** + * Time before an SA gets rekeyed + */ + u_int32_t rekeytime; + + /** + * Time, which specifies the range of a random value + * substracted from lifetime. + */ + u_int32_t jitter; + + /** + * What to do with an SA when other peer seams to be dead? + */ + bool dpd_delay; + + /** + * What to do with CHILDren when other peer seams to be dead? + */ + bool dpd_action; + + /** + * virtual IP to use locally + */ + host_t *my_virtual_ip; + + /** + * virtual IP to use remotly + */ + host_t *other_virtual_ip; +}; + +/** + * Implementation of peer_cfg_t.get_name + */ +static char *get_name(private_peer_cfg_t *this) +{ + return this->name; +} + +/** + * Implementation of peer_cfg_t.get_ike_version + */ +static u_int get_ike_version(private_peer_cfg_t *this) +{ + return this->ike_version; +} + +/** + * Implementation of peer_cfg_t.get_ike_cfg + */ +static ike_cfg_t* get_ike_cfg(private_peer_cfg_t *this) +{ + return this->ike_cfg; +} + +/** + * Implementation of peer_cfg_t.add_child_cfg. + */ +static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg) +{ + pthread_mutex_lock(&this->mutex); + this->child_cfgs->insert_last(this->child_cfgs, child_cfg); + pthread_mutex_unlock(&this->mutex); +} + +/** + * Implementation of peer_cfg_t.create_child_cfg_iterator. + */ +static iterator_t* create_child_cfg_iterator(private_peer_cfg_t *this) +{ + return this->child_cfgs->create_iterator_locked(this->child_cfgs, + &this->mutex); +} + +/** + * Check if child_cfg contains traffic selectors + */ +static bool contains_ts(child_cfg_t *child, bool mine, linked_list_t *ts, + host_t *host) +{ + linked_list_t *selected; + bool contains = FALSE; + + selected = child->get_traffic_selectors(child, mine, ts, host); + contains = selected->get_count(selected); + selected->destroy_offset(selected, offsetof(traffic_selector_t, destroy)); + return contains; +} + +/** + * Implementation of peer_cfg_t.select_child_cfg + */ +static child_cfg_t* select_child_cfg(private_peer_cfg_t *this, + linked_list_t *my_ts, + linked_list_t *other_ts, + host_t *my_host, host_t *other_host) +{ + child_cfg_t *current, *found = NULL; + iterator_t *iterator; + + iterator = create_child_cfg_iterator(this); + while (iterator->iterate(iterator, (void**)¤t)) + { + if (contains_ts(current, TRUE, my_ts, my_host) && + contains_ts(current, FALSE, other_ts, other_host)) + { + found = current; + found->get_ref(found); + break; + } + } + iterator->destroy(iterator); + return found; +} + +/** + * Implementation of peer_cfg_t.get_my_id + */ +static identification_t *get_my_id(private_peer_cfg_t *this) +{ + return this->my_id; +} + +/** + * Implementation of peer_cfg_t.get_other_id + */ +static identification_t *get_other_id(private_peer_cfg_t *this) +{ + return this->other_id; +} + +/** + * Implementation of peer_cfg_t.get_my_ca + */ +static identification_t *get_my_ca(private_peer_cfg_t *this) +{ + return this->my_ca; +} + +static identification_t *get_other_ca(private_peer_cfg_t *this) +{ + return this->other_ca; +} + +/** + * Implementation of peer_cfg_t.get_cert_policy. + */ +static cert_policy_t get_cert_policy(private_peer_cfg_t *this) +{ + return this->cert_policy; +} + +/** + * Implementation of connection_t.auth_method_t. + */ +static auth_method_t get_auth_method(private_peer_cfg_t *this) +{ + return this->auth_method; +} + +/** + * Implementation of connection_t.get_eap_type. + */ +static eap_type_t get_eap_type(private_peer_cfg_t *this) +{ + return this->eap_type; +} + +/** + * Implementation of connection_t.get_keyingtries. + */ +static u_int32_t get_keyingtries(private_peer_cfg_t *this) +{ + return this->keyingtries; +} + +/** + * Implementation of peer_cfg_t.get_soft_lifetime + */ +static u_int32_t get_lifetime(private_peer_cfg_t *this, bool rekey) +{ + if (rekey) + { + if (this->jitter == 0) + { + return this->rekeytime; + } + return this->rekeytime - (random() % this->jitter); + } + return this->lifetime; +} + +/** + * Implementation of peer_cfg_t.use_reauth. + */ +static bool use_reauth(private_peer_cfg_t *this, bool rekey) +{ + return this->use_reauth; +} + +/** + * Implements peer_cfg_t.get_dpd_delay + */ +static u_int32_t get_dpd_delay(private_peer_cfg_t *this) +{ + return this->dpd_action; +} + +/** + * Implements peer_cfg_t.get_dpd_action + */ +static dpd_action_t get_dpd_action(private_peer_cfg_t *this) +{ + return this->dpd_action; +} + +/** + * Implementation of peer_cfg_t.get_virtual_ip. + */ +static host_t* get_virtual_ip(private_peer_cfg_t *this, host_t *suggestion) +{ + if (suggestion == NULL) + { + if (this->my_virtual_ip) + { + return this->my_virtual_ip->clone(this->my_virtual_ip); + } + return NULL; + } + if (this->other_virtual_ip) + { + return this->other_virtual_ip->clone(this->other_virtual_ip); + } + if (suggestion->is_anyaddr(suggestion)) + { + return NULL; + } + return suggestion->clone(suggestion); +} + +/** + * Implements peer_cfg_t.get_ref. + */ +static void get_ref(private_peer_cfg_t *this) +{ + ref_get(&this->refcount); +} + +/** + * Implements peer_cfg_t.destroy. + */ +static void destroy(private_peer_cfg_t *this) +{ + if (ref_put(&this->refcount)) + { + this->ike_cfg->destroy(this->ike_cfg); + 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); + free(this->name); + free(this); + } +} + +/* + * Described in header-file + */ +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, + cert_policy_t cert_policy, auth_method_t auth_method, + eap_type_t eap_type, u_int32_t keyingtries, + u_int32_t lifetime, u_int32_t rekeytime, + u_int32_t jitter, bool reauth, + u_int32_t dpd_delay, dpd_action_t dpd_action, + host_t *my_virtual_ip, host_t *other_virtual_ip) +{ + private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t); + + /* public functions */ + this->public.get_name = (char* (*) (peer_cfg_t *))get_name; + this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version; + this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg; + this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg; + this->public.create_child_cfg_iterator = (iterator_t* (*) (peer_cfg_t *))create_child_cfg_iterator; + 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_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_eap_type = (eap_type_t (*) (peer_cfg_t *))get_eap_type; + this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries; + this->public.get_lifetime = (u_int32_t (*) (peer_cfg_t *, bool rekey))get_lifetime; + this->public.use_reauth = (bool (*) (peer_cfg_t *))use_reauth; + 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_virtual_ip = (host_t* (*) (peer_cfg_t *, host_t *))get_virtual_ip; + this->public.get_ref = (void(*)(peer_cfg_t *))get_ref; + this->public.destroy = (void(*)(peer_cfg_t *))destroy; + + /* apply init values */ + this->name = strdup(name); + this->ike_version = ike_version; + this->ike_cfg = ike_cfg; + this->child_cfgs = linked_list_create(); + 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->cert_policy = cert_policy; + this->auth_method = auth_method; + this->eap_type = eap_type; + this->keyingtries = keyingtries; + this->lifetime = lifetime; + this->rekeytime = rekeytime; + this->jitter = jitter; + this->use_reauth = reauth; + 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->refcount = 1; + + return &this->public; +} diff --git a/src/charon/config/peer_cfg.h b/src/charon/config/peer_cfg.h new file mode 100644 index 000000000..b0e3c8a3a --- /dev/null +++ b/src/charon/config/peer_cfg.h @@ -0,0 +1,345 @@ +/** + * @file peer_cfg.h + * + * @brief Interface of peer_cfg_t. + * + */ + +/* + * 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 . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 PEER_CFG_H_ +#define PEER_CFG_H_ + +typedef enum dpd_action_t dpd_action_t; +typedef enum cert_policy_t cert_policy_t; +typedef struct peer_cfg_t peer_cfg_t; + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * 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. + */ +enum cert_policy_t { + /** always send certificates, even when not requested */ + CERT_ALWAYS_SEND = 0, + /** send certificate upon cert request */ + CERT_SEND_IF_ASKED = 1, + /** never send a certificate, even when requested */ + CERT_NEVER_SEND = 2, +}; + +/** + * 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 peer_cfg + */ +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 names for dpd_action_t. + */ +extern enum_name_t *dpd_action_names; + +/** + * @brief Configuration of a peer, specified by IDs. + * + * @b Constructors: + * - peer_cfg_create() + * + * @ingroup peer_cfg + */ +struct peer_cfg_t { + + /** + * @brief 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. + * + * @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. + * + * @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. + * + * @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. + * + * @param this calling object + * @return an iterator over all CHILD configs. + */ + iterator_t* (*create_child_cfg_iterator) (peer_cfg_t *this); + + /** + * @brief 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 + * @param other_host host to narrow down dynamic TS for remote side + * @return selected CHILD config, or NULL if no match found + */ + child_cfg_t* (*select_child_cfg) (peer_cfg_t *this, linked_list_t *my_ts, + linked_list_t *other_ts, host_t *my_host, + host_t *other_host); + + /** + * @brief Get own ID. + * + * @param this calling object + * @return own id + */ + identification_t* (*get_my_id)(peer_cfg_t *this); + + /** + * @brief 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 peers CA. + * + * @param this calling object + * @return other ca + */ + identification_t* (*get_other_ca)(peer_cfg_t *this); + + /** + * @brief Should be sent a certificate for this connection? + * + * @param this calling object + * @return certificate sending policy + */ + cert_policy_t (*get_cert_policy) (peer_cfg_t *this); + + /** + * @brief 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); + + /** + * @brief Get the EAP type to use for peer authentication. + * + * @param this calling object + * @return authentication method + */ + eap_type_t (*get_eap_type) (peer_cfg_t *this); + + /** + * @brief 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 the lifetime of a IKE_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 + * returned when the IKE_SA must be deleted. + * The rekey time automatically contains a jitter to avoid simlutaneous + * rekeying. + * + * @param this child_config + * @param rekey TRUE to get rekey time + * @return lifetime in seconds + */ + u_int32_t (*get_lifetime) (peer_cfg_t *this, bool rekey); + + /** + * @brief Should a full reauthentication be done instead of rekeying? + * + * @param this calling object + * @return TRUE to use full reauthentication + */ + bool (*use_reauth) (peer_cfg_t *this); + + /** + * @brief Get the DPD check interval. + * + * @param this calling object + * @return dpd_delay in seconds + */ + u_int32_t (*get_dpd_delay) (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 or the remote host. + * + * By supplying NULL as IP, an IP for the local host is requested. It + * may be %any or specific. + * By supplying %any as host, an IP from the pool is selected to be + * served to the peer. + * If a specified host is supplied, it is checked if this address + * is acceptable to serve to the peer. If so, it is returned. Otherwise, + * an alternative IP is returned. + * In any mode, this call may return NULL indicating virtual IP should + * not be used. + * + * @param this peer_cfg + * @param suggestion NULL, %any or specific, see description + * @return clone of an IP to use, or NULL + */ + host_t* (*get_virtual_ip) (peer_cfg_t *this, host_t *suggestion); + + /** + * @brief Get a new reference. + * + * 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 + */ + void (*get_ref) (peer_cfg_t *this); + + /** + * @brief 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. + * + * name-string gets cloned, ID's not. + * Virtual IPs are used if they are != NULL. A %any host means the virtual + * IP should be obtained from the other peer. + * Lifetimes are in seconds. To prevent to peers to start rekeying at the + * same time, a jitter may be specified. Rekeying of an SA starts at + * (rekeylifetime - random(0, jitter)). + * + * @param name name of the peer_cfg + * @param ike_version which IKE version we sould use for this peer + * @param ike_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 cert_policy should we send a certificate payload? + * @param auth_method auth method to use to authenticate us + * @param eap_type EAP type to use for peer authentication + * @param keyingtries how many keying tries should be done before giving up + * @param lifetime lifetime before deleting an SA + * @param rekeytime lifetime before rekeying an SA + * @param jitter range of random to substract from rekeytime + * @param use_reauth sould be done reauthentication instead of rekeying? + * @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 + * @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, + cert_policy_t cert_policy, auth_method_t auth_method, + eap_type_t eap_type, u_int32_t keyingtries, + u_int32_t lifetime, u_int32_t rekeytime, + u_int32_t jitter, bool use_reauth, + u_int32_t dpd_delay, dpd_action_t dpd_action, + host_t *my_virtual_ip, host_t *other_virtual_ip); + +#endif /* PEER_CFG_H_ */ diff --git a/src/charon/config/policies/local_policy_store.c b/src/charon/config/policies/local_policy_store.c deleted file mode 100644 index dd22b43a0..000000000 --- a/src/charon/config/policies/local_policy_store.c +++ /dev/null @@ -1,282 +0,0 @@ -/** - * @file local_policy_store.c - * - * @brief Implementation of local_policy_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 . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT 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 - -#include "local_policy_store.h" - -#include -#include - - -typedef struct private_local_policy_store_t private_local_policy_store_t; - -/** - * Private data of an local_policy_store_t object - */ -struct private_local_policy_store_t { - - /** - * Public part - */ - local_policy_store_t public; - - /** - * list of policy_t's - */ - linked_list_t *policies; - - /** - * Mutex to exclusivly access list - */ - pthread_mutex_t mutex; -}; - -/** - * Implementation of policy_store_t.add_policy. - */ -static void add_policy(private_local_policy_store_t *this, policy_t *policy) -{ - pthread_mutex_lock(&(this->mutex)); - this->policies->insert_last(this->policies, (void*)policy); - pthread_mutex_unlock(&(this->mutex)); -} - -/** - * Check if a policy contains traffic selectors - */ -static bool contains_traffic_selectors(policy_t *policy, bool mine, - linked_list_t *ts, host_t *host) -{ - linked_list_t *selected; - bool contains = FALSE; - - if (mine) - { - selected = policy->select_my_traffic_selectors(policy, ts, host); - } - else - { - selected = policy->select_other_traffic_selectors(policy, ts, host); - } - if (selected->get_count(selected)) - { - contains = TRUE; - } - selected->destroy_offset(selected, offsetof(traffic_selector_t, destroy)); - return contains; -} - -/** - * Implementation of policy_store_t.get_policy. - */ -static policy_t *get_policy(private_local_policy_store_t *this, - identification_t *my_id, identification_t *other_id, - linked_list_t *my_ts, linked_list_t *other_ts, - host_t *my_host, host_t *other_host) -{ - typedef enum { - PRIO_UNDEFINED = 0x00, - PRIO_TS_MISMATCH = 0x01, - PRIO_ID_ANY = 0x02, - PRIO_ID_MATCH = PRIO_ID_ANY + MAX_WILDCARDS, - } prio_t; - - prio_t best_prio = PRIO_UNDEFINED; - - iterator_t *iterator; - policy_t *candidate; - policy_t *found = NULL; - traffic_selector_t *ts; - - DBG1(DBG_CFG, "searching policy for '%D'...'%D'", my_id, other_id); - iterator = my_ts->create_iterator(my_ts, TRUE); - while (iterator->iterate(iterator, (void**)&ts)) - { - DBG1(DBG_CFG, " local TS: %R", ts); - } - iterator->destroy(iterator); - iterator = other_ts->create_iterator(other_ts, TRUE); - while (iterator->iterate(iterator, (void**)&ts)) - { - DBG1(DBG_CFG, " remote TS: %R", ts); - } - iterator->destroy(iterator); - - pthread_mutex_lock(&(this->mutex)); - iterator = this->policies->create_iterator(this->policies, TRUE); - - /* determine closest matching policy */ - while (iterator->iterate(iterator, (void**)&candidate)) - { - identification_t *candidate_my_id; - identification_t *candidate_other_id; - int wildcards; - - candidate_my_id = candidate->get_my_id(candidate); - candidate_other_id = candidate->get_other_id(candidate); - - /* my_id is either %any or if set must match exactly */ - if (candidate_my_id->matches(candidate_my_id, my_id, &wildcards)) - { - prio_t prio = PRIO_UNDEFINED; - - /* wildcard match for other_id */ - if (!other_id->matches(other_id, candidate_other_id, &wildcards)) - { - continue; - } - prio = PRIO_ID_MATCH - wildcards; - - /* only accept if traffic selectors match */ - if (!contains_traffic_selectors(candidate, TRUE, my_ts, my_host) || - !contains_traffic_selectors(candidate, FALSE, other_ts, other_host)) - { - DBG2(DBG_CFG, "candidate '%s' inacceptable due traffic " - "selector mismatch", candidate->get_name(candidate)); - prio = PRIO_TS_MISMATCH; - } - - DBG2(DBG_CFG, "candidate policy '%s': '%D'...'%D' (prio=%d)", - candidate->get_name(candidate), - candidate_my_id, candidate_other_id, prio); - - if (prio > best_prio) - { - found = candidate; - best_prio = prio; - } - } - } - iterator->destroy(iterator); - - if (found) - { - DBG1(DBG_CFG, "found matching policy '%s': '%D'...'%D' (prio=%d)", - found->get_name(found), found->get_my_id(found), - found->get_other_id(found), best_prio); - /* give out a new reference to it */ - found->get_ref(found); - } - pthread_mutex_unlock(&(this->mutex)); - return found; -} - -/** - * Implementation of policy_store_t.get_policy_by_name. - */ -static policy_t *get_policy_by_name(private_local_policy_store_t *this, char *name) -{ - iterator_t *iterator; - policy_t *current, *found = NULL; - - DBG2(DBG_CFG, "looking for policy '%s'", name); - - pthread_mutex_lock(&(this->mutex)); - iterator = this->policies->create_iterator(this->policies, TRUE); - while (iterator->iterate(iterator, (void **)¤t)) - { - if (strcmp(current->get_name(current), name) == 0) - { - found = current; - } - } - iterator->destroy(iterator); - pthread_mutex_unlock(&(this->mutex)); - - /* give out a new reference */ - found->get_ref(found); - return found; -} - -/** - * Implementation of policy_store_t.delete_policy. - */ -static status_t delete_policy(private_local_policy_store_t *this, char *name) -{ - iterator_t *iterator; - policy_t *current; - bool found = FALSE; - - pthread_mutex_lock(&(this->mutex)); - iterator = this->policies->create_iterator(this->policies, TRUE); - while (iterator->iterate(iterator, (void **)¤t)) - { - if (strcmp(current->get_name(current), name) == 0) - { - /* remove policy from list, and destroy it */ - iterator->remove(iterator); - current->destroy(current); - found = TRUE; - /* we do not break here, as there may be multipe policies */ - } - } - iterator->destroy(iterator); - pthread_mutex_unlock(&(this->mutex)); - if (found) - { - return SUCCESS; - } - return NOT_FOUND; -} - -/** - * Implementation of policy_store_t.create_iterator. - */ -static iterator_t* create_iterator(private_local_policy_store_t *this) -{ - return this->policies->create_iterator_locked(this->policies, - &this->mutex); -} - -/** - * Implementation of policy_store_t.destroy. - */ -static void destroy(private_local_policy_store_t *this) -{ - pthread_mutex_lock(&(this->mutex)); - this->policies->destroy_offset(this->policies, offsetof(policy_t, destroy)); - pthread_mutex_unlock(&(this->mutex)); - free(this); -} - -/** - * Described in header. - */ -local_policy_store_t *local_policy_store_create(void) -{ - private_local_policy_store_t *this = malloc_thing(private_local_policy_store_t); - - this->public.policy_store.add_policy = (void (*) (policy_store_t*,policy_t*))add_policy; - this->public.policy_store.get_policy = (policy_t* (*) (policy_store_t*,identification_t*,identification_t*, - linked_list_t*,linked_list_t*,host_t*,host_t*))get_policy; - this->public.policy_store.get_policy_by_name = (policy_t* (*) (policy_store_t*,char*))get_policy_by_name; - this->public.policy_store.delete_policy = (status_t (*) (policy_store_t*,char*))delete_policy; - this->public.policy_store.create_iterator = (iterator_t* (*) (policy_store_t*))create_iterator; - this->public.policy_store.destroy = (void (*) (policy_store_t*))destroy; - - /* private variables */ - this->policies = linked_list_create(); - pthread_mutex_init(&(this->mutex), NULL); - - return (&this->public); -} diff --git a/src/charon/config/policies/local_policy_store.h b/src/charon/config/policies/local_policy_store.h deleted file mode 100644 index 01d5d2d60..000000000 --- a/src/charon/config/policies/local_policy_store.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file local_policy_store.h - * - * @brief Interface of local_policy_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 . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT 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_POLICY_STORE_H_ -#define LOCAL_POLICY_STORE_H_ - -typedef struct local_policy_store_t local_policy_store_t; - -#include -#include - - -/** - * @brief A policy_store_t implementation using a simple policy lists. - * - * The local_policy_store_t class implements the policy_store_t interface - * as simple as possible. The policies are stored in a in-memory list. - * - * @b Constructors: - * - local_policy_store_create() - * - * @ingroup config - */ -struct local_policy_store_t { - - /** - * Implements policy_store_t interface - */ - policy_store_t policy_store; -}; - -/** - * @brief Creates a local_policy_store_t instance. - * - * @return policy store instance. - * - * @ingroup config - */ -local_policy_store_t *local_policy_store_create(void); - -#endif /* LOCAL_POLICY_STORE_H_ */ diff --git a/src/charon/config/policies/policy.c b/src/charon/config/policies/policy.c deleted file mode 100644 index 363d1609f..000000000 --- a/src/charon/config/policies/policy.c +++ /dev/null @@ -1,635 +0,0 @@ -/** - * @file policy.c - * - * @brief Implementation of policy_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 . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT 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 -#include -#include - -#include "policy.h" - -#include -#include -#include - -ENUM(dpd_action_names, DPD_NONE, DPD_RESTART, - "DPD_NONE", - "DPD_CLEAR", - "DPD_ROUTE", - "DPD_RESTART" -); - -ENUM(mode_names, MODE_TRANSPORT, MODE_BEET, - "TRANSPORT", - "TUNNEL", - "2", - "3", - "BEET" -); - -typedef struct private_policy_t private_policy_t; - -/** - * Private data of an policy_t object - */ -struct private_policy_t { - - /** - * Public part - */ - policy_t public; - - /** - * Number of references hold by others to this policy - */ - refcount_t refcount; - - /** - * Name of the policy, used to query it - */ - char *name; - - /** - * id to use to identify us - */ - identification_t *my_id; - - /** - * allowed id for other - */ - identification_t *other_id; - - /** - * virtual IP to use locally - */ - host_t *my_virtual_ip; - - /** - * virtual IP to use remotly - */ - host_t *other_virtual_ip; - - /** - * Method to use for own authentication data - */ - auth_method_t auth_method; - - /** - * EAP type to use for peer authentication - */ - eap_type_t eap_type; - - /** - * 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; - - /** - * updown script - */ - char *updown; - - /** - * allow host access - */ - bool hostaccess; - - /** - * list for all proposals - */ - linked_list_t *proposals; - - /** - * list for traffic selectors for my site - */ - linked_list_t *my_ts; - - /** - * list for traffic selectors for others site - */ - linked_list_t *other_ts; - - /** - * Time before an SA gets invalid - */ - u_int32_t soft_lifetime; - - /** - * Time before an SA gets rekeyed - */ - u_int32_t hard_lifetime; - - /** - * Time, which specifies the range of a random value - * substracted from soft_lifetime. - */ - u_int32_t jitter; - - /** - * What to do with an SA when other peer seams to be dead? - */ - bool dpd_action; - - /** - * Mode to propose for a initiated CHILD: tunnel/transport - */ - mode_t mode; -}; - -/** - * Implementation of policy_t.get_name - */ -static char *get_name(private_policy_t *this) -{ - return this->name; -} - -/** - * Implementation of policy_t.get_my_id - */ -static identification_t *get_my_id(private_policy_t *this) -{ - return this->my_id; -} - -/** - * Implementation of policy_t.get_other_id - */ -static identification_t *get_other_id(private_policy_t *this) -{ - return this->other_id; -} - -/** - * Implementation of policy_t.get_my_ca - */ -static identification_t *get_my_ca(private_policy_t *this) -{ - return this->my_ca; -} - -/** - * Implementation of policy_t.get_other_ca - */ -static identification_t *get_other_ca(private_policy_t *this) -{ - return this->other_ca; -} - -/** - * Implementation of connection_t.auth_method_t. - */ -static auth_method_t get_auth_method(private_policy_t *this) -{ - return this->auth_method; -} - -/** - * Implementation of connection_t.get_eap_type. - */ -static eap_type_t get_eap_type(private_policy_t *this) -{ - return this->eap_type; -} - -/** - * Get traffic selectors, with wildcard-address update - */ -static linked_list_t *get_traffic_selectors(private_policy_t *this, - linked_list_t *list, host_t *host) -{ - iterator_t *iterator; - traffic_selector_t *current; - linked_list_t *result = linked_list_create(); - - iterator = list->create_iterator(list, TRUE); - - while (iterator->iterate(iterator, (void**)¤t)) - { - /* we make a copy of the TS, this allows us to update wildcard - * addresses in it. We won't pollute the shared policy. */ - current = current->clone(current); - if (host) - { - current->set_address(current, host); - } - - result->insert_last(result, (void*)current); - } - iterator->destroy(iterator); - return result; -} - -/** - * Implementation of policy_t.get_my_traffic_selectors - */ -static linked_list_t *get_my_traffic_selectors(private_policy_t *this, host_t *me) -{ - return get_traffic_selectors(this, this->my_ts, me); -} - -/** - * Implementation of policy_t.get_other_traffic_selectors - */ -static linked_list_t *get_other_traffic_selectors(private_policy_t *this, host_t *other) -{ - return get_traffic_selectors(this, this->other_ts, other); -} - -/** - * Narrow traffic selectors, with wildcard-address update in "stored". - */ -static linked_list_t *select_traffic_selectors(private_policy_t *this, - linked_list_t *stored, - linked_list_t *supplied, - host_t *host) -{ - iterator_t *supplied_iter, *stored_iter, *i1, *i2; - traffic_selector_t *supplied_ts, *stored_ts, *selected_ts, *ts1, *ts2; - linked_list_t *selected = linked_list_create(); - - DBG2(DBG_CFG, "selecting traffic selectors"); - - stored_iter = stored->create_iterator(stored, TRUE); - supplied_iter = supplied->create_iterator(supplied, TRUE); - - /* iterate over all stored selectors */ - while (stored_iter->iterate(stored_iter, (void**)&stored_ts)) - { - /* we make a copy of the TS, this allows us to update wildcard - * addresses in it. We won't pollute the shared policy. */ - stored_ts = stored_ts->clone(stored_ts); - if (host) - { - stored_ts->set_address(stored_ts, host); - } - - supplied_iter->reset(supplied_iter); - /* iterate over all supplied traffic selectors */ - while (supplied_iter->iterate(supplied_iter, (void**)&supplied_ts)) - { - DBG2(DBG_CFG, "stored %R <=> %R received", - stored_ts, supplied_ts); - - selected_ts = stored_ts->get_subset(stored_ts, supplied_ts); - if (selected_ts) - { - /* got a match, add to list */ - selected->insert_last(selected, (void*)selected_ts); - - DBG2(DBG_CFG, "found traffic selector for %s: %R", - stored == this->my_ts ? "us" : "other", selected_ts); - } - } - stored_ts->destroy(stored_ts); - } - stored_iter->destroy(stored_iter); - supplied_iter->destroy(supplied_iter); - - /* remove any redundant traffic selectors in the list */ - i1 = selected->create_iterator(selected, TRUE); - i2 = selected->create_iterator(selected, TRUE); - while (i1->iterate(i1, (void**)&ts1)) - { - while (i2->iterate(i2, (void**)&ts2)) - { - if (ts1 != ts2) - { - if (ts2->is_contained_in(ts2, ts1)) - { - i2->remove(i2); - ts2->destroy(ts2); - i1->reset(i1); - break; - } - if (ts1->is_contained_in(ts1, ts2)) - { - i1->remove(i1); - ts1->destroy(ts1); - i2->reset(i2); - break; - } - } - } - } - i1->destroy(i1); - i2->destroy(i2); - - return selected; -} - -/** - * Implementation of private_policy_t.select_my_traffic_selectors - */ -static linked_list_t *select_my_traffic_selectors(private_policy_t *this, - linked_list_t *supplied, - host_t *me) -{ - return select_traffic_selectors(this, this->my_ts, supplied, me); -} - -/** - * Implementation of private_policy_t.select_other_traffic_selectors - */ -static linked_list_t *select_other_traffic_selectors(private_policy_t *this, - linked_list_t *supplied, - host_t* other) -{ - return select_traffic_selectors(this, this->other_ts, supplied, other); -} - -/** - * Implementation of policy_t.get_proposal_iterator - */ -static linked_list_t *get_proposals(private_policy_t *this) -{ - iterator_t *iterator; - proposal_t *current; - linked_list_t *proposals = linked_list_create(); - - iterator = this->proposals->create_iterator(this->proposals, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - current = current->clone(current); - proposals->insert_last(proposals, (void*)current); - } - iterator->destroy(iterator); - - return proposals; -} - -/** - * Implementation of policy_t.select_proposal - */ -static proposal_t *select_proposal(private_policy_t *this, linked_list_t *proposals) -{ - iterator_t *stored_iter, *supplied_iter; - proposal_t *stored, *supplied, *selected; - - 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)) - { - supplied_iter->reset(supplied_iter); - while (supplied_iter->iterate(supplied_iter, (void**)&supplied)) - { - selected = stored->select(stored, supplied); - if (selected) - { - /* they match, return */ - stored_iter->destroy(stored_iter); - supplied_iter->destroy(supplied_iter); - return selected; - } - } - } - - /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */ - stored_iter->destroy(stored_iter); - supplied_iter->destroy(supplied_iter); - - return NULL; -} - -/** - * Implementation of policy_t.add_authorities - */ -static void add_authorities(private_policy_t *this, identification_t *my_ca, identification_t *other_ca) -{ - this->my_ca = my_ca; - this->other_ca = other_ca; -} - -/** - * Implementation of policy_t.get_updown - */ -static char* get_updown(private_policy_t *this) -{ - return this->updown; -} - -/** - * Implementation of policy_t.get_hostaccess - */ -static bool get_hostaccess(private_policy_t *this) -{ - return this->hostaccess; -} - -/** - * Implements policy_t.get_dpd_action - */ -static dpd_action_t get_dpd_action(private_policy_t *this) -{ - return this->dpd_action; -} - -/** - * Implementation of policy_t.add_my_traffic_selector - */ -static void add_my_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector) -{ - this->my_ts->insert_last(this->my_ts, (void*)traffic_selector); -} - -/** - * Implementation of policy_t.add_other_traffic_selector - */ -static void add_other_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector) -{ - this->other_ts->insert_last(this->other_ts, (void*)traffic_selector); -} - -/** - * Implementation of policy_t.add_proposal - */ -static void add_proposal(private_policy_t *this, proposal_t *proposal) -{ - this->proposals->insert_last(this->proposals, (void*)proposal); -} - -/** - * Implementation of policy_t.get_soft_lifetime - */ -static u_int32_t get_soft_lifetime(private_policy_t *this) -{ - if (this->jitter == 0) - { - return this->soft_lifetime ; - } - return this->soft_lifetime - (random() % this->jitter); -} - -/** - * Implementation of policy_t.get_hard_lifetime - */ -static u_int32_t get_hard_lifetime(private_policy_t *this) -{ - return this->hard_lifetime; -} - -/** - * Implementation of policy_t.get_mode. - */ -static mode_t get_mode(private_policy_t *this) -{ - return this->mode; -} - -/** - * Implementation of policy_t.get_virtual_ip. - */ -static host_t* get_virtual_ip(private_policy_t *this, host_t *suggestion) -{ - if (suggestion == NULL) - { - if (this->my_virtual_ip) - { - return this->my_virtual_ip->clone(this->my_virtual_ip); - } - return NULL; - } - if (this->other_virtual_ip) - { - return this->other_virtual_ip->clone(this->other_virtual_ip); - } - if (suggestion->is_anyaddr(suggestion)) - { - return NULL; - } - return suggestion->clone(suggestion); -} - -/** - * Implements policy_t.get_ref. - */ -static void get_ref(private_policy_t *this) -{ - ref_get(&this->refcount); -} - -/** - * Implements policy_t.destroy. - */ -static void destroy(private_policy_t *this) -{ - if (ref_put(&this->refcount)) - { - - this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy)); - this->my_ts->destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy)); - this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy)); - - /* delete certification authorities */ - DESTROY_IF(this->my_ca); - DESTROY_IF(this->other_ca); - - /* delete updown script */ - if (this->updown) - { - free(this->updown); - } - - /* delete ids */ - this->my_id->destroy(this->my_id); - this->other_id->destroy(this->other_id); - DESTROY_IF(this->my_virtual_ip); - DESTROY_IF(this->other_virtual_ip); - - free(this->name); - free(this); - } -} - -/* - * Described in header-file - */ -policy_t *policy_create(char *name, identification_t *my_id, identification_t *other_id, - host_t *my_virtual_ip, host_t *other_virtual_ip, - auth_method_t auth_method, eap_type_t eap_type, - u_int32_t hard_lifetime, u_int32_t soft_lifetime, - u_int32_t jitter, char *updown, bool hostaccess, - mode_t mode, dpd_action_t dpd_action) -{ - private_policy_t *this = malloc_thing(private_policy_t); - - /* public functions */ - this->public.get_name = (char* (*) (policy_t*))get_name; - this->public.get_my_id = (identification_t* (*) (policy_t*))get_my_id; - this->public.get_other_id = (identification_t* (*) (policy_t*))get_other_id; - this->public.get_my_ca = (identification_t* (*) (policy_t*))get_my_ca; - this->public.get_other_ca = (identification_t* (*) (policy_t*))get_other_ca; - this->public.get_auth_method = (auth_method_t (*) (policy_t*)) get_auth_method; - this->public.get_eap_type = (eap_type_t (*) (policy_t*)) get_eap_type; - this->public.get_my_traffic_selectors = (linked_list_t* (*) (policy_t*,host_t*))get_my_traffic_selectors; - this->public.get_other_traffic_selectors = (linked_list_t* (*) (policy_t*,host_t*))get_other_traffic_selectors; - this->public.select_my_traffic_selectors = (linked_list_t* (*) (policy_t*,linked_list_t*,host_t*))select_my_traffic_selectors; - this->public.select_other_traffic_selectors = (linked_list_t* (*) (policy_t*,linked_list_t*,host_t*))select_other_traffic_selectors; - this->public.get_proposals = (linked_list_t* (*) (policy_t*))get_proposals; - this->public.select_proposal = (proposal_t* (*) (policy_t*,linked_list_t*))select_proposal; - this->public.add_my_traffic_selector = (void (*) (policy_t*,traffic_selector_t*))add_my_traffic_selector; - this->public.add_other_traffic_selector = (void (*) (policy_t*,traffic_selector_t*))add_other_traffic_selector; - this->public.add_proposal = (void (*) (policy_t*,proposal_t*))add_proposal; - this->public.add_authorities = (void (*) (policy_t*,identification_t*,identification_t*))add_authorities; - this->public.get_updown = (char* (*) (policy_t*))get_updown; - this->public.get_hostaccess = (bool (*) (policy_t*))get_hostaccess; - this->public.get_dpd_action = (dpd_action_t (*) (policy_t*))get_dpd_action; - this->public.get_soft_lifetime = (u_int32_t (*) (policy_t *))get_soft_lifetime; - this->public.get_hard_lifetime = (u_int32_t (*) (policy_t *))get_hard_lifetime; - this->public.get_mode = (mode_t (*) (policy_t *))get_mode; - this->public.get_virtual_ip = (host_t* (*)(policy_t*,host_t*))get_virtual_ip; - this->public.get_ref = (void (*) (policy_t*))get_ref; - this->public.destroy = (void (*) (policy_t*))destroy; - - /* apply init values */ - this->name = strdup(name); - this->my_id = my_id; - this->other_id = other_id; - this->my_virtual_ip = my_virtual_ip; - this->other_virtual_ip = other_virtual_ip; - this->auth_method = auth_method; - this->eap_type = eap_type; - this->hard_lifetime = hard_lifetime; - this->soft_lifetime = soft_lifetime; - this->jitter = jitter; - this->updown = (updown == NULL) ? NULL : strdup(updown); - this->hostaccess = hostaccess; - this->dpd_action = dpd_action; - this->mode = mode; - - /* initialize private members*/ - this->refcount = 1; - this->my_ca = NULL; - this->other_ca = NULL; - this->proposals = linked_list_create(); - this->my_ts = linked_list_create(); - this->other_ts = linked_list_create(); - - return &this->public; -} diff --git a/src/charon/config/policies/policy.h b/src/charon/config/policies/policy.h deleted file mode 100644 index d8916b29e..000000000 --- a/src/charon/config/policies/policy.h +++ /dev/null @@ -1,413 +0,0 @@ -/** - * @file policy.h - * - * @brief Interface of policy_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 . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT 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 POLICY_H_ -#define POLICY_H_ - -typedef enum dpd_action_t dpd_action_t; -typedef struct policy_t policy_t; - -#include -#include -#include -#include -#include -#include - - -/** - * @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 - */ -enum dpd_action_t { - /** DPD disabled */ - DPD_NONE, - /** remove CHILD_SA without replacement */ - DPD_CLEAR, - /** route the CHILD_SA to resetup when needed */ - DPD_ROUTE, - /** restart CHILD_SA in a new IKE_SA, immediately */ - DPD_RESTART, -}; - -/** - * enum names for dpd_action_t. - */ -extern enum_name_t *dpd_action_names; - -/** - * @brief Mode of an IPsec SA. - * - * These are equal to those defined in XFRM, so don't change. - * - * @ingroup config - */ -enum mode_t { - /** transport mode, no inner address */ - MODE_TRANSPORT = 0, - /** tunnel mode, inner and outer addresses */ - MODE_TUNNEL = 1, - /** BEET mode, tunnel mode but fixed, bound inner addresses */ - MODE_BEET = 4, -}; - -/** - * enum names for mode_t. - */ -extern enum_name_t *mode_names; - -/** - * @brief A policy_t defines the policies to apply to CHILD_SAs. - * - * The given two IDs identify a policy. These rules define how - * child SAs may be set up and which traffic may be IPsec'ed. - * - * @b Constructors: - * - policy_create() - * - * @ingroup config - */ -struct policy_t { - - /** - * @brief Get the name of the policy. - * - * Returned object is not getting cloned. - * - * @param this calling object - * @return policy's name - */ - char *(*get_name) (policy_t *this); - - /** - * @brief Get own id. - * - * Returned object is not getting cloned. - * - * @param this calling object - * @return own id - */ - identification_t *(*get_my_id) (policy_t *this); - - /** - * @brief Get peer id. - * - * Returned object is not getting cloned. - * - * @param this calling object - * @return other id - */ - identification_t *(*get_other_id) (policy_t *this); - - /** - * @brief Get own ca. - * - * Returned object is not getting cloned. - * - * @param this calling object - * @return own ca - */ - identification_t *(*get_my_ca) (policy_t *this); - - /** - * @brief Get peer ca. - * - * Returned object is not getting cloned. - * - * @param this calling object - * @return other ca - */ - identification_t *(*get_other_ca) (policy_t *this); - - /** - * @brief Get the authentication method to use. - * - * @param this calling object - * @return authentication method - */ - auth_method_t (*get_auth_method) (policy_t *this); - - /** - * @brief Get the EAP type to use for peer authentication. - * - * @param this calling object - * @return authentication method - */ - eap_type_t (*get_eap_type) (policy_t *this); - - /** - * @brief Get configured traffic selectors for our site. - * - * Returns a list with all traffic selectors for the local - * site. List and items must be destroyed after usage. - * - * @param this calling object - * @return list with traffic selectors - */ - linked_list_t *(*get_my_traffic_selectors) (policy_t *this, host_t *me); - - /** - * @brief Get configured traffic selectors for others site. - * - * Returns a list with all traffic selectors for the remote - * site. List and items must be destroyed after usage. - * - * @param this calling object - * @return list with traffic selectors - */ - linked_list_t *(*get_other_traffic_selectors) (policy_t *this, host_t* other); - - /** - * @brief Select traffic selectors from a supplied list for local site. - * - * Resulted list and traffic selectors must be destroyed after usage. - * As the traffic selectors may contain a wildcard address (0.0.0.0) for - * addresses we don't know in previous, an address may be supplied to - * replace these 0.0.0.0 addresses on-the-fly. - * - * @param this calling object - * @param supplied linked list with traffic selectors - * @param me host address used by us - * @return list containing the selected traffic selectors - */ - linked_list_t *(*select_my_traffic_selectors) (policy_t *this, - linked_list_t *supplied, - host_t *me); - - /** - * @brief Select traffic selectors from a supplied list for remote site. - * - * Resulted list and traffic selectors must be destroyed after usage. - * As the traffic selectors may contain a wildcard address (0.0.0.0) for - * addresses we don't know in previous, an address may be supplied to - * replace these 0.0.0.0 addresses on-the-fly. - * - * @param this calling object - * @param supplied linked list with traffic selectors - * @return list containing the selected traffic selectors - */ - linked_list_t *(*select_other_traffic_selectors) (policy_t *this, - linked_list_t *supplied, - host_t *other); - - /** - * @brief Get the list of internally stored proposals. - * - * policy_t does store proposals for AH/ESP, IKE proposals are in - * the connection_t. - * Resulting list and all of its proposals must be freed after usage. - * - * @param this calling object - * @return lists with proposals - */ - linked_list_t *(*get_proposals) (policy_t *this); - - /** - * @brief 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 - * @return selected proposal, or NULL if nothing matches - */ - proposal_t *(*select_proposal) (policy_t *this, linked_list_t *proposals); - - /** - * @brief Add a traffic selector to the list for local site. - * - * After add, traffic selector is owned by policy. - * - * @param this calling object - * @param traffic_selector traffic_selector to add - */ - void (*add_my_traffic_selector) (policy_t *this, traffic_selector_t *traffic_selector); - - /** - * @brief Add a traffic selector to the list for remote site. - * - * After add, traffic selector is owned by policy. - * - * @param this calling object - * @param traffic_selector traffic_selector to add - */ - void (*add_other_traffic_selector) (policy_t *this, traffic_selector_t *traffic_selector); - - /** - * @brief Add a proposal to the list. - * - * The proposals are stored by priority, first added - * is the most prefered. - * After add, proposal is owned by policy. - * - * @param this calling object - * @param proposal proposal to add - */ - void (*add_proposal) (policy_t *this, proposal_t *proposal); - - /** - * @brief Add certification authorities. - * - * @param this calling object - * @param my_ca issuer of my certificate - * @param other_ca required issuer of the peer's certificate - */ - void (*add_authorities) (policy_t *this, identification_t *my_ca, identification_t *other_ca); - - /** - * @brief Get updown script - * - * @param this calling object - * @return path to updown script - */ - char* (*get_updown) (policy_t *this); - - /** - * @brief Get hostaccess flag - * - * @param this calling object - * @return value of hostaccess flag - */ - bool (*get_hostaccess) (policy_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) (policy_t *this); - - /** - * @brief Get the lifetime of a policy, before rekeying starts. - * - * A call to this function automatically adds a jitter to - * avoid simultanous rekeying. - * - * @param this policy - * @return lifetime in seconds - */ - u_int32_t (*get_soft_lifetime) (policy_t *this); - - /** - * @brief Get the lifetime of a policy, before SA gets deleted. - * - * @param this policy - * @return lifetime in seconds - */ - u_int32_t (*get_hard_lifetime) (policy_t *this); - - /** - * @brief Get the mode to use for the CHILD_SA, tunnel, transport or BEET. - * - * @param this policy - * @return lifetime in seconds - */ - mode_t (*get_mode) (policy_t *this); - - /** - * @brief Get a virtual IP for the local or the remote host. - * - * By supplying NULL as IP, an IP for the local host is requested. It - * may be %any or specific. - * By supplying %any as host, an IP from the pool is selected to be - * served to the peer. - * If a specified host is supplied, it is checked if this address - * is acceptable to serve to the peer. If so, it is returned. Otherwise, - * an alternative IP is returned. - * In any mode, this call may return NULL indicating virtual IP should - * not be used. - * - * @param this policy - * @param suggestion NULL, %any or specific, see description - * @return clone of an IP to use, or NULL - */ - host_t* (*get_virtual_ip) (policy_t *this, host_t *suggestion); - - /** - * @brief Get a new reference. - * - * Get a new reference to this policy 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 - */ - void (*get_ref) (policy_t *this); - - /** - * @brief Destroys the policy object. - * - * Decrements the internal reference counter and - * destroys the policy when it reaches zero. - * - * @param this calling object - */ - void (*destroy) (policy_t *this); -}; - -/** - * @brief 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 - * IP should be obtained from the other peer. - * Lifetimes are in seconds. To prevent to peers to start rekeying at the - * same time, a jitter may be specified. Rekeying of an SA starts at - * (soft_lifetime - random(0, jitter)). After a successful rekeying, - * the hard_lifetime limit counter is reset. You should specify - * hard_lifetime > soft_lifetime > jitter. - * After a call to create, a reference is obtained (refcount = 1). - * - * @param name name of the policy - * @param my_id identification_t for ourselves - * @param other_id identification_t for the remote guy - * @param my_virtual_ip virtual IP for local host, or NULL - * @param other_virtual_ip virtual IP for remote host, or NULL - * @param auth_method Authentication method to use for our(!) auth data - * @param eap_type EAP type to use for peer authentication - * @param hard_lifetime lifetime before deleting an SA - * @param soft_lifetime lifetime before rekeying an SA - * @param jitter range of randomization time - * @param updown updown script to execute on up/down event - * @param hostaccess allow access to the host itself (used by the updown script) - * @param mode mode to propose for CHILD_SA, transport, tunnel or BEET - * @param dpd_action what to to with a CHILD_SA when other peer does not respond - * @return policy_t object - * - * @ingroup config - */ -policy_t *policy_create(char *name, - identification_t *my_id, identification_t *other_id, - host_t *my_virtual_ip, host_t *other_virtual_ip, - auth_method_t auth_method, eap_type_t eap_type, - u_int32_t hard_lifetime, u_int32_t soft_lifetime, - u_int32_t jitter, char *updown, bool hostaccess, - mode_t mode, dpd_action_t dpd_action); - -#endif /* POLICY_H_ */ diff --git a/src/charon/config/policies/policy_store.h b/src/charon/config/policies/policy_store.h deleted file mode 100755 index cd8870953..000000000 --- a/src/charon/config/policies/policy_store.h +++ /dev/null @@ -1,119 +0,0 @@ -/** - * @file policy_store.h - * - * @brief Interface policy_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 . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT 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 POLICY_STORE_H_ -#define POLICY_STORE_H_ - -typedef struct policy_store_t policy_store_t; - -#include -#include -#include - - -/** - * @brief The interface for a store of policy_t's. - * - * The store uses reference counting to manage their lifetime. Call - * destroy() for a policy which is returned from the store after usage. - * - * @b Constructors: - * - stroke_create() - * - * @ingroup config - */ -struct policy_store_t { - - /** - * @brief Returns a policy identified by two IDs and a set of traffic selectors. - * - * other_id must be fully qualified. my_id may be %any, as the - * other peer may not include an IDr Request. - * - * @param this calling object - * @param my_id own ID of the policy - * @param other_id others ID of the policy - * @param my_ts traffic selectors requested for local host - * @param other_ts traffic selectors requested for remote host - * @param my_host host to use for wilcards in TS compare - * @param other_host host to use for wildcards in TS compare - * @return - * - matching policy_t, if found - * - NULL otherwise - */ - policy_t *(*get_policy) (policy_store_t *this, - identification_t *my_id, identification_t *other_id, - linked_list_t *my_ts, linked_list_t *other_ts, - host_t *my_host, host_t* other_host); - - /** - * @brief Returns a policy identified by a connection name. - * - * @param this calling object - * @param name name of the policy - * @return - * - matching policy_t, if found - * - NULL otherwise - */ - policy_t *(*get_policy_by_name) (policy_store_t *this, char *name); - - /** - * @brief Add a policy to the list. - * - * The policy is owned by the store after the call. Do - * not modify nor free. - * - * @param this calling object - * @param policy policy to add - */ - void (*add_policy) (policy_store_t *this, policy_t *policy); - - /** - * @brief Delete a policy from the store. - * - * Remove a policy from the store identified by its name. - * - * @param this calling object - * @param policy policy to add - * @return - * - SUCCESS, or - * - NOT_FOUND - */ - status_t (*delete_policy) (policy_store_t *this, char *name); - - /** - * @brief Get an iterator for the stored policies. - * - * @param this calling object - * @return iterator over all stored policies - */ - iterator_t* (*create_iterator) (policy_store_t *this); - - /** - * @brief Destroys a policy_store_t object. - * - * @param this calling object - */ - void (*destroy) (policy_store_t *this); -}; - -#endif /*POLICY_STORE_H_*/ diff --git a/src/charon/config/traffic_selector.c b/src/charon/config/traffic_selector.c index 2fb012e16..b399074d1 100644 --- a/src/charon/config/traffic_selector.c +++ b/src/charon/config/traffic_selector.c @@ -167,6 +167,8 @@ static int print(FILE *stream, const struct printf_info *info, const void *const *args) { private_traffic_selector_t *this = *((private_traffic_selector_t**)(args[0])); + linked_list_t *list = *((linked_list_t**)(args[0])); + iterator_t *iterator; char addr_str[INET6_ADDRSTRLEN] = ""; char *serv_proto = NULL; u_int8_t mask; @@ -179,6 +181,24 @@ static int print(FILE *stream, const struct printf_info *info, return fprintf(stream, "(null)"); } + if (info->alt) + { + iterator = list->create_iterator(list, TRUE); + while (iterator->iterate(iterator, (void**)&this)) + { + /* call recursivly */ + written += fprintf(stream, "%R ", this); + } + iterator->destroy(iterator); + return written; + } + + if (this->dynamic) + { + return fprintf(stream, "dynamic/%d", + this->type == TS_IPV4_ADDR_RANGE ? 32 : 128); + } + if (this->type == TS_IPV4_ADDR_RANGE) { inet_ntop(AF_INET, &this->from4, addr_str, sizeof(addr_str)); diff --git a/src/charon/control/controller.c b/src/charon/control/controller.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/charon/control/controller.h b/src/charon/control/controller.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/charon/threads/stroke_interface.c b/src/charon/control/stroke_interface.c similarity index 69% rename from src/charon/threads/stroke_interface.c rename to src/charon/control/stroke_interface.c index a9074debb..ef9238658 100755 --- a/src/charon/threads/stroke_interface.c +++ b/src/charon/control/stroke_interface.c @@ -1,12 +1,12 @@ /** - * @file stroke.c + * @file stroke_interface.c * - * @brief Implementation of stroke_t. + * @brief Implementation of stroke_interface_t. * */ /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2006-2007 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -40,23 +40,23 @@ #include #include #include -#include -#include +#include +#include #include #define IKE_PORT 500 #define PATH_BUF 256 - +#define STROKE_THREADS 3 struct sockaddr_un socket_addr = { AF_UNIX, STROKE_SOCKET}; -typedef struct private_stroke_t private_stroke_t; +typedef struct private_stroke_interface_t private_stroke_interface_t; /** * Private data of an stroke_t object. */ -struct private_stroke_t { +struct private_stroke_interface_t { /** * Public part of stroke_t object. @@ -64,9 +64,9 @@ struct private_stroke_t { stroke_t public; /** - * Output stream (stroke console) + * backend to store configurations */ - FILE *out; + local_backend_t *backend; /** * Unix socket to listen for strokes @@ -76,7 +76,7 @@ struct private_stroke_t { /** * Thread which reads from the Socket */ - pthread_t assigned_thread; + pthread_t threads[STROKE_THREADS]; }; /** @@ -187,10 +187,12 @@ static x509_t* load_ca_certificate(const char *filename) /** * Add a connection to the configuration list */ -static void stroke_add_conn(stroke_msg_t *msg, FILE *out) +static void stroke_add_conn(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { - connection_t *connection; - policy_t *policy; + ike_cfg_t *ike_cfg; + peer_cfg_t *peer_cfg; + child_cfg_t *child_cfg; identification_t *my_id, *other_id; identification_t *my_ca = NULL; identification_t *other_ca = NULL; @@ -201,6 +203,8 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out) proposal_t *proposal; traffic_selector_t *my_ts, *other_ts; char *interface; + bool use_existing = FALSE; + iterator_t *iterator; pop_string(msg, &msg->add_conn.name); pop_string(msg, &msg->add_conn.me.address); @@ -421,67 +425,102 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out) DBG2(DBG_CFG, " other ca:'%D'", other_ca); DBG2(DBG_CFG, " updown: '%s'", msg->add_conn.me.updown); - connection = connection_create(msg->add_conn.name, - msg->add_conn.ikev2, - msg->add_conn.me.sendcert, - msg->add_conn.other.sendcert, - my_host, other_host, - msg->add_conn.dpd.delay, - msg->add_conn.rekey.reauth, - msg->add_conn.rekey.tries, - msg->add_conn.rekey.ike_lifetime, - msg->add_conn.rekey.ike_lifetime - msg->add_conn.rekey.margin, - msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100); - - if (msg->add_conn.algorithms.ike) + /* have a look for an (almost) identical peer config to reuse */ + iterator = this->backend->create_peer_cfg_iterator(this->backend); + while (iterator->iterate(iterator, (void**)&peer_cfg)) { - 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, ","))) + 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)) && + 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) == msg->add_conn.eap_type) { - 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); - connection->destroy(connection); - return; - } - connection->add_proposal(connection, proposal); - } - if (!strict) - { - proposal = proposal_create_default(PROTO_IKE); - connection->add_proposal(connection, proposal); + DBG1(DBG_CFG, "reusing existing configuration '%s'", + peer_cfg->get_name(peer_cfg)); + use_existing = TRUE; + break; } } + iterator->destroy(iterator); + + if (use_existing) + { + 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); + } else { - proposal = proposal_create_default(PROTO_IKE); - connection->add_proposal(connection, proposal); + ike_cfg = ike_cfg_create(msg->add_conn.other.sendcert != CERT_NEVER_SEND, + 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); + } + + + 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, msg->add_conn.me.sendcert, + msg->add_conn.auth_method, msg->add_conn.eap_type, + msg->add_conn.rekey.tries, msg->add_conn.rekey.ike_lifetime, + msg->add_conn.rekey.ike_lifetime - msg->add_conn.rekey.margin, + msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100, + msg->add_conn.rekey.reauth, msg->add_conn.dpd.delay, + msg->add_conn.dpd.action,my_vip, other_vip); } - policy = policy_create(msg->add_conn.name, my_id, other_id, my_vip, other_vip, - msg->add_conn.auth_method, msg->add_conn.eap_type, - 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, msg->add_conn.dpd.action); - policy->add_my_traffic_selector(policy, my_ts); - policy->add_other_traffic_selector(policy, other_ts); - policy->add_authorities(policy, my_ca, other_ca); + 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) { @@ -499,31 +538,30 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out) if (proposal == NULL) { DBG1(DBG_CFG, "invalid ESP proposal string: %s", proposal_string); - policy->destroy(policy); - connection->destroy(connection); + peer_cfg->destroy(peer_cfg); return; } - policy->add_proposal(policy, proposal); + child_cfg->add_proposal(child_cfg, proposal); } if (!strict) { proposal = proposal_create_default(PROTO_ESP); - policy->add_proposal(policy, proposal); + child_cfg->add_proposal(child_cfg, proposal); } } else { proposal = proposal_create_default(PROTO_ESP); - policy->add_proposal(policy, proposal); + child_cfg->add_proposal(child_cfg, proposal); } - /* add to global connection list */ - charon->connections->add_connection(charon->connections, connection); - DBG1(DBG_CFG, "added connection '%s': %H[%D]...%H[%D]", - msg->add_conn.name, my_host, my_id, other_host, other_id); - /* add to global policy list */ - charon->policies->add_policy(charon->policies, policy); - + if (!use_existing) + { + /* add config to backend */ + this->backend->add_peer_cfg(this->backend, 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 */ @@ -540,69 +578,109 @@ destroy_hosts: /** * Delete a connection from the list */ -static void stroke_del_conn(stroke_msg_t *msg, FILE *out) +static void stroke_del_conn(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { - status_t status; + iterator_t *peer_iter, *child_iter; + peer_cfg_t *peer, *child; pop_string(msg, &(msg->del_conn.name)); DBG1(DBG_CFG, "received stroke: delete connection '%s'", msg->del_conn.name); - status = charon->connections->delete_connection(charon->connections, - msg->del_conn.name); - charon->policies->delete_policy(charon->policies, msg->del_conn.name); - if (status == SUCCESS) + peer_iter = this->backend->create_peer_cfg_iterator(this->backend); + while (peer_iter->iterate(peer_iter, (void**)&peer)) { - fprintf(out, "deleted connection '%s'\n", msg->del_conn.name); + /* 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); } - else + 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) +{ + child_cfg_t *current, *found = NULL; + iterator_t *iterator; + + iterator = peer_cfg->create_child_cfg_iterator(peer_cfg); + while (iterator->iterate(iterator, (void**)¤t)) { - fprintf(out, "no connection named '%s'\n", msg->del_conn.name); + if (streq(current->get_name(current), peer_cfg->get_name(peer_cfg))) + { + found = current; + found->get_ref(found); + break; + } } + iterator->destroy(iterator); + return found; } /** * initiate a connection by name */ -static void stroke_initiate(stroke_msg_t *msg, FILE *out) +static void stroke_initiate(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { initiate_job_t *job; - connection_t *connection; - policy_t *policy; + peer_cfg_t *peer_cfg; + child_cfg_t *child_cfg; ike_sa_t *init_ike_sa = NULL; signal_t signal; pop_string(msg, &(msg->initiate.name)); DBG1(DBG_CFG, "received stroke: initiate '%s'", msg->initiate.name); - connection = charon->connections->get_connection_by_name(charon->connections, - msg->initiate.name); - if (connection == NULL) + peer_cfg = charon->cfg_store->get_peer_cfg_by_name(charon->cfg_store, + msg->initiate.name); + if (peer_cfg == NULL) { if (msg->output_verbosity >= 0) { - fprintf(out, "no connection named '%s'\n", msg->initiate.name); + fprintf(out, "no config named '%s'\n", msg->initiate.name); } return; } - if (!connection->is_ikev2(connection)) + if (peer_cfg->get_ike_version(peer_cfg) != 2) { - connection->destroy(connection); + DBG1(DBG_CFG, "ignoring initiation request for IKEv%d config", + peer_cfg->get_ike_version(peer_cfg)); + peer_cfg->destroy(peer_cfg); return; } - policy = charon->policies->get_policy_by_name(charon->policies, - msg->initiate.name); - if (policy == NULL) + child_cfg = get_child_from_peer(peer_cfg); + if (child_cfg == NULL) { if (msg->output_verbosity >= 0) { - fprintf(out, "no policy named '%s'\n", msg->initiate.name); + fprintf(out, "no child config named '%s'\n", msg->initiate.name); } - connection->destroy(connection); + peer_cfg->destroy(peer_cfg); return; } - job = initiate_job_create(connection, policy); + job = initiate_job_create(peer_cfg, child_cfg); charon->bus->set_listen_state(charon->bus, TRUE); charon->job_queue->add(charon->job_queue, (job_t*)job); while (TRUE) @@ -654,49 +732,48 @@ static void stroke_initiate(stroke_msg_t *msg, FILE *out) /** * route/unroute a policy (install SPD entries) */ -static void stroke_route(stroke_msg_t *msg, FILE *out, bool route) +static void stroke_route(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out, bool route) { route_job_t *job; - connection_t *connection; - policy_t *policy; + peer_cfg_t *peer_cfg; + child_cfg_t *child_cfg; pop_string(msg, &(msg->route.name)); DBG1(DBG_CFG, "received stroke: %s '%s'", route ? "route" : "unroute", msg->route.name); - /* we wouldn't need a connection, but we only want to route policies - * whose connections are keyexchange=ikev2. */ - connection = charon->connections->get_connection_by_name(charon->connections, - msg->route.name); - if (connection == NULL) + peer_cfg = charon->cfg_store->get_peer_cfg_by_name(charon->cfg_store, + msg->route.name); + if (peer_cfg == NULL) { - fprintf(out, "no connection named '%s'\n", msg->route.name); + fprintf(out, "no config named '%s'\n", msg->route.name); return; } - if (!connection->is_ikev2(connection)) + if (peer_cfg->get_ike_version(peer_cfg) != 2) { - connection->destroy(connection); + peer_cfg->destroy(peer_cfg); return; } - - policy = charon->policies->get_policy_by_name(charon->policies, - msg->route.name); - if (policy == NULL) + + child_cfg = get_child_from_peer(peer_cfg); + if (child_cfg == NULL) { - fprintf(out, "no policy named '%s'\n", msg->route.name); - connection->destroy(connection); + fprintf(out, "no child config named '%s'\n", msg->route.name); + peer_cfg->destroy(peer_cfg); return; } fprintf(out, "%s policy '%s'\n", route ? "routing" : "unrouting", msg->route.name); - job = route_job_create(connection, policy, route); + job = route_job_create(peer_cfg, child_cfg, route); charon->job_queue->add(charon->job_queue, (job_t*)job); } /** * terminate a connection by name */ -static void stroke_terminate(stroke_msg_t *msg, FILE *out) +static void stroke_terminate(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { char *string, *pos = NULL, *name = NULL; u_int32_t id = 0; @@ -797,7 +874,8 @@ static void stroke_terminate(stroke_msg_t *msg, FILE *out) /** * Add a ca information record to the cainfo list */ -static void stroke_add_ca(stroke_msg_t *msg, FILE *out) +static void stroke_add_ca(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { x509_t *cacert; ca_info_t *ca_info; @@ -864,7 +942,8 @@ static void stroke_add_ca(stroke_msg_t *msg, FILE *out) /** * Delete a ca information record from the cainfo list */ -static void stroke_del_ca(stroke_msg_t *msg, FILE *out) +static void stroke_del_ca(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { status_t status; @@ -887,13 +966,15 @@ static void stroke_del_ca(stroke_msg_t *msg, FILE *out) /** * show status of daemon */ -static void stroke_statusall(stroke_msg_t *msg, FILE *out) +static void stroke_statusall(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { - iterator_t *iterator; + iterator_t *iterator, *children; linked_list_t *list; host_t *host; - connection_t *connection; - policy_t *policy; + peer_cfg_t *peer_cfg; + ike_cfg_t *ike_cfg; + child_cfg_t *child_cfg; ike_sa_t *ike_sa; char *name = NULL; @@ -923,40 +1004,35 @@ static void stroke_statusall(stroke_msg_t *msg, FILE *out) name = msg->status.name; } - iterator = charon->connections->create_iterator(charon->connections); - if (iterator->get_count(iterator) > 0) + fprintf(out, "Connections:\n"); + iterator = this->backend->create_peer_cfg_iterator(this->backend); + while (iterator->iterate(iterator, (void**)&peer_cfg)) { - fprintf(out, "Connections:\n"); - } - while (iterator->iterate(iterator, (void**)&connection)) - { - if (connection->is_ikev2(connection) - && (name == NULL || streq(name, connection->get_name(connection)))) + if (peer_cfg->get_ike_version(peer_cfg) != 2 || + (name && !streq(name, peer_cfg->get_name(peer_cfg)))) { - fprintf(out, "%12s: %H...%H\n", - connection->get_name(connection), - connection->get_my_host(connection), - connection->get_other_host(connection)); - } - } - iterator->destroy(iterator); - - iterator = charon->policies->create_iterator(charon->policies); - if (iterator->get_count(iterator) > 0) - { - fprintf(out, "Policies:\n"); - } - while (iterator->iterate(iterator, (void**)&policy)) - { - if (name == NULL || streq(name, policy->get_name(policy))) - { - fprintf(out, "%12s: '%D'...'%D'\n", - policy->get_name(policy), - policy->get_my_id(policy), - policy->get_other_id(policy)); + 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)); + 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 (iterator->get_count(iterator) > 0) @@ -970,7 +1046,7 @@ static void stroke_statusall(stroke_msg_t *msg, FILE *out) iterator_t *children = ike_sa->create_child_sa_iterator(ike_sa); /* print IKE_SA */ - if (name == NULL || strncmp(name, ike_sa->get_name(ike_sa), strlen(name)) == 0) + if (name == NULL || strcmp(name, ike_sa->get_name(ike_sa)) == 0) { fprintf(out, "%#K\n", ike_sa); ike_sa_printed = TRUE; @@ -979,7 +1055,7 @@ static void stroke_statusall(stroke_msg_t *msg, FILE *out) while (children->iterate(children, (void**)&child_sa)) { bool child_sa_match = name == NULL || - strncmp(name, child_sa->get_name(child_sa), strlen(name)) == 0; + strcmp(name, child_sa->get_name(child_sa)) == 0; /* print IKE_SA if its name differs from the CHILD_SA's name */ if (!ike_sa_printed && child_sa_match) @@ -1002,7 +1078,8 @@ static void stroke_statusall(stroke_msg_t *msg, FILE *out) /** * show status of daemon */ -static void stroke_status(stroke_msg_t *msg, FILE *out) +static void stroke_status(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { iterator_t *iterator; ike_sa_t *ike_sa; @@ -1022,7 +1099,7 @@ static void stroke_status(stroke_msg_t *msg, FILE *out) iterator_t *children = ike_sa->create_child_sa_iterator(ike_sa); /* print IKE_SA */ - if (name == NULL || strncmp(name, ike_sa->get_name(ike_sa), strlen(name)) == 0) + if (name == NULL || strcmp(name, ike_sa->get_name(ike_sa)) == 0) { fprintf(out, "%K\n", ike_sa); ike_sa_printed = TRUE; @@ -1031,7 +1108,7 @@ static void stroke_status(stroke_msg_t *msg, FILE *out) while (children->iterate(children, (void**)&child_sa)) { bool child_sa_match = name == NULL || - strncmp(name, child_sa->get_name(child_sa), strlen(name)) == 0; + strcmp(name, child_sa->get_name(child_sa)) == 0; /* print IKE_SA if its name differs from the CHILD_SA's name */ if (!ike_sa_printed && child_sa_match) @@ -1054,7 +1131,8 @@ static void stroke_status(stroke_msg_t *msg, FILE *out) /** * list all authority certificates matching a specified flag */ -static void list_auth_certificates(u_int flag, const char *label, bool utc, FILE *out) +static void list_auth_certificates(private_stroke_interface_t *this, u_int flag, + const char *label, bool utc, FILE *out) { bool first = TRUE; x509_t *cert; @@ -1081,7 +1159,8 @@ static void list_auth_certificates(u_int flag, const char *label, bool utc, FILE /** * list various information */ -static void stroke_list(stroke_msg_t *msg, FILE *out) +static void stroke_list(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { iterator_t *iterator; @@ -1111,7 +1190,7 @@ static void stroke_list(stroke_msg_t *msg, FILE *out) } if (msg->list.flags & LIST_CACERTS) { - list_auth_certificates(AUTH_CA, "CA", msg->list.utc, out); + list_auth_certificates(this, AUTH_CA, "CA", msg->list.utc, out); } if (msg->list.flags & LIST_CAINFOS) { @@ -1132,60 +1211,59 @@ static void stroke_list(stroke_msg_t *msg, FILE *out) } 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->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); + 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->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_OCSPCERTS) { - list_auth_certificates(AUTH_OCSP, "OCSP", msg->list.utc, out); + list_auth_certificates(this, AUTH_OCSP, "OCSP", msg->list.utc, out); } 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->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); + iterator = charon->credentials->create_cainfo_iterator(charon->credentials); + while (iterator->iterate(iterator, (void **)&ca_info)) + { + if (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) +static void stroke_reread(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { if (msg->reread.flags & REREAD_CACERTS) { @@ -1204,7 +1282,8 @@ static void stroke_reread(stroke_msg_t *msg, FILE *out) /** * purge various information */ -static void stroke_purge(stroke_msg_t *msg, FILE *out) +static void stroke_purge(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { if (msg->purge.flags & PURGE_OCSP) { @@ -1237,7 +1316,8 @@ signal_t get_signal_from_logtype(char *type) /** * set the verbosity debug output */ -static void stroke_loglevel(stroke_msg_t *msg, FILE *out) +static void stroke_loglevel(private_stroke_interface_t *this, + stroke_msg_t *msg, FILE *out) { signal_t signal; @@ -1259,13 +1339,12 @@ static void stroke_loglevel(stroke_msg_t *msg, FILE *out) /** * process a stroke request from the socket pointed by "fd" */ -static void stroke_process(int *fd) +static void stroke_process(private_stroke_interface_t *this, int strokefd) { stroke_msg_t *msg; u_int16_t msg_length; ssize_t bytes_read; FILE *out; - int strokefd = *fd; /* peek the length */ bytes_read = recv(strokefd, &msg_length, sizeof(msg_length), MSG_PEEK); @@ -1300,46 +1379,46 @@ static void stroke_process(int *fd) switch (msg->type) { case STR_INITIATE: - stroke_initiate(msg, out); + stroke_initiate(this, msg, out); break; case STR_ROUTE: - stroke_route(msg, out, TRUE); + stroke_route(this, msg, out, TRUE); break; case STR_UNROUTE: - stroke_route(msg, out, FALSE); + stroke_route(this, msg, out, FALSE); break; case STR_TERMINATE: - stroke_terminate(msg, out); + stroke_terminate(this, msg, out); break; case STR_STATUS: - stroke_status(msg, out); + stroke_status(this, msg, out); break; case STR_STATUS_ALL: - stroke_statusall(msg, out); + stroke_statusall(this, msg, out); break; case STR_ADD_CONN: - stroke_add_conn(msg, out); + stroke_add_conn(this, msg, out); break; case STR_DEL_CONN: - stroke_del_conn(msg, out); + stroke_del_conn(this, msg, out); break; case STR_ADD_CA: - stroke_add_ca(msg, out); + stroke_add_ca(this, msg, out); break; case STR_DEL_CA: - stroke_del_ca(msg, out); + stroke_del_ca(this, msg, out); break; case STR_LOGLEVEL: - stroke_loglevel(msg, out); + stroke_loglevel(this, msg, out); break; case STR_LIST: - stroke_list(msg, out); + stroke_list(this, msg, out); break; case STR_REREAD: - stroke_reread(msg, out); + stroke_reread(this, msg, out); break; case STR_PURGE: - stroke_purge(msg, out); + stroke_purge(this, msg, out); break; default: DBG1(DBG_CFG, "received unknown stroke"); @@ -1350,15 +1429,14 @@ static void stroke_process(int *fd) } /** - * Implementation of private_stroke_t.stroke_receive. + * Implementation of private_stroke_interface_t.stroke_receive. */ -static void stroke_receive(private_stroke_t *this) +static void stroke_receive(private_stroke_interface_t *this) { struct sockaddr_un strokeaddr; int strokeaddrlen = sizeof(strokeaddr); - int strokefd; int oldstate; - pthread_t thread; + int strokefd; /* ignore sigpipe. writing over the pipe back to the console * only fails if SIGPIPE is ignored. */ @@ -1379,24 +1457,22 @@ static void stroke_receive(private_stroke_t *this) DBG1(DBG_CFG, "accepting stroke connection failed: %m"); continue; } - - /* handle request asynchronously */ - if (pthread_create(&thread, NULL, (void*(*)(void*))stroke_process, (void*)&strokefd) != 0) - { - DBG1(DBG_CFG, "failed to spawn stroke thread: %m"); - } - /* detach so the thread terminates cleanly */ - pthread_detach(thread); + stroke_process(this, strokefd); } } /** * Implementation of stroke_t.destroy. */ -static void destroy(private_stroke_t *this) +static void destroy(private_stroke_interface_t *this) { - pthread_cancel(this->assigned_thread); - pthread_join(this->assigned_thread, NULL); + int i; + + for (i = 0; i < STROKE_THREADS; i++) + { + pthread_cancel(this->threads[i]); + pthread_join(this->threads[i], NULL); + } close(this->socket); unlink(socket_addr.sun_path); @@ -1406,14 +1482,17 @@ static void destroy(private_stroke_t *this) /* * Described in header-file */ -stroke_t *stroke_create() +stroke_t *stroke_create(local_backend_t *backend) { - private_stroke_t *this = malloc_thing(private_stroke_t); + private_stroke_interface_t *this = malloc_thing(private_stroke_interface_t); mode_t old; + int i; /* public functions */ this->public.destroy = (void (*)(stroke_t*))destroy; + this->backend = backend; + /* set up unix socket */ this->socket = socket(AF_UNIX, SOCK_STREAM, 0); if (this->socket == -1) @@ -1442,14 +1521,13 @@ stroke_t *stroke_create() return NULL; } - /* start a thread reading from the socket */ - if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))stroke_receive, this) != 0) + /* start threads reading from the socket */ + for (i = 0; i < STROKE_THREADS; i++) { - DBG1(DBG_CFG, "could not spawn stroke thread"); - close(this->socket); - unlink(socket_addr.sun_path); - free(this); - return NULL; + if (pthread_create(&this->threads[i], NULL, (void*(*)(void*))stroke_receive, this) != 0) + { + charon->kill(charon, "unable to create stroke thread"); + } } return (&this->public); diff --git a/src/charon/threads/stroke_interface.h b/src/charon/control/stroke_interface.h similarity index 80% rename from src/charon/threads/stroke_interface.h rename to src/charon/control/stroke_interface.h index 0def5167e..8ba81ad70 100644 --- a/src/charon/threads/stroke_interface.h +++ b/src/charon/control/stroke_interface.h @@ -25,11 +25,14 @@ typedef struct stroke_t stroke_t; +#include + /** * @brief Stroke is a configuration and control interface which * allows other processes to modify charons behavior. * - * stroke_t allows config manipulation (as whack in pluto). + * stroke_t allows config manipulation (as whack in pluto). Configurations + * are stored in a special backend, the in-memory local_backend_t. * Messages of type stroke_msg_t's are sent over a unix socket * (/var/run/charon.ctl). * @@ -52,10 +55,11 @@ struct stroke_t { /** * @brief Create the stroke interface and listen on the socket. * - * @return stroke_t object + * @param backend backend to store received configurations + * @return stroke_t object * * @ingroup threads */ -stroke_t *stroke_create(void); +stroke_t *stroke_create(local_backend_t *backend); #endif /* STROKE_INTERFACE_H_ */ diff --git a/src/charon/daemon.c b/src/charon/daemon.c index 7671aea86..ef07d6531 100644 --- a/src/charon/daemon.c +++ b/src/charon/daemon.c @@ -42,8 +42,7 @@ #include #include #include -#include -#include +#include #include @@ -179,8 +178,8 @@ static void destroy(private_daemon_t *this) DESTROY_IF(this->public.event_queue); DESTROY_IF(this->public.configuration); DESTROY_IF(this->public.credentials); - DESTROY_IF(this->public.connections); - DESTROY_IF(this->public.policies); + DESTROY_IF(this->public.cfg_store); + DESTROY_IF(this->public.local_backend); sched_yield(); /* we hope the sender could send the outstanding deletes, but * we shut down here at any cost */ @@ -264,9 +263,11 @@ static void initialize(private_daemon_t *this, bool strict, bool syslog, this->public.ike_sa_manager = ike_sa_manager_create(); this->public.job_queue = job_queue_create(); this->public.event_queue = event_queue_create(); - this->public.connections = (connection_store_t*)local_connection_store_create(); - this->public.policies = (policy_store_t*)local_policy_store_create(); this->public.credentials = (credential_store_t*)local_credential_store_create(strict); + this->public.cfg_store = cfg_store_create(); + this->public.local_backend = local_backend_create(); + this->public.cfg_store->register_backend(this->public.cfg_store, + &this->public.local_backend->backend); /* initialize fetcher_t class */ fetcher_initialize(); @@ -279,7 +280,7 @@ static void initialize(private_daemon_t *this, bool strict, bool syslog, credentials->load_secrets(credentials); /* start building threads, we are multi-threaded NOW */ - this->public.stroke = stroke_create(); + this->public.stroke = stroke_create(this->public.local_backend); this->public.sender = sender_create(); this->public.receiver = receiver_create(); this->public.scheduler = scheduler_create(); @@ -335,8 +336,8 @@ private_daemon_t *daemon_create(void) this->public.event_queue = NULL; this->public.configuration = NULL; this->public.credentials = NULL; - this->public.connections = NULL; - this->public.policies = NULL; + this->public.cfg_store = NULL; + this->public.local_backend = NULL; this->public.sender= NULL; this->public.receiver = NULL; this->public.scheduler = NULL; diff --git a/src/charon/daemon.h b/src/charon/daemon.h index 420262474..6ba676812 100644 --- a/src/charon/daemon.h +++ b/src/charon/daemon.h @@ -29,22 +29,21 @@ typedef struct daemon_t daemon_t; #include -#include -#include -#include -#include -#include -#include +#include +#include #include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include +#include +#include /** * @defgroup charon charon @@ -324,12 +323,12 @@ struct daemon_t { /** * A connection_store_t instance. */ - connection_store_t *connections; + cfg_store_t *cfg_store; /** - * A policy_store_t instance. + * A backend for cfg_store using in-memory lists */ - policy_store_t *policies; + local_backend_t *local_backend; /** * A credential_store_t instance. diff --git a/src/charon/threads/kernel_interface.c b/src/charon/kernel/kernel_interface.c similarity index 99% rename from src/charon/threads/kernel_interface.c rename to src/charon/kernel/kernel_interface.c index 4a70d2ecf..e9cddccb4 100644 --- a/src/charon/threads/kernel_interface.c +++ b/src/charon/kernel/kernel_interface.c @@ -45,9 +45,9 @@ #include #include -#include -#include -#include +#include +#include +#include /** kernel level protocol identifiers */ #define KERNEL_ESP 50 diff --git a/src/charon/threads/kernel_interface.h b/src/charon/kernel/kernel_interface.h similarity index 100% rename from src/charon/threads/kernel_interface.h rename to src/charon/kernel/kernel_interface.h diff --git a/src/charon/threads/receiver.c b/src/charon/network/receiver.c similarity index 98% rename from src/charon/threads/receiver.c rename to src/charon/network/receiver.c index 7195c162d..640339cc9 100644 --- a/src/charon/threads/receiver.c +++ b/src/charon/network/receiver.c @@ -29,9 +29,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include /** length of the full cookie, including time (u_int32_t + SHA1()) */ #define COOKIE_LENGTH 24 diff --git a/src/charon/threads/receiver.h b/src/charon/network/receiver.h similarity index 100% rename from src/charon/threads/receiver.h rename to src/charon/network/receiver.h diff --git a/src/charon/threads/sender.c b/src/charon/network/sender.c similarity index 100% rename from src/charon/threads/sender.c rename to src/charon/network/sender.c diff --git a/src/charon/threads/sender.h b/src/charon/network/sender.h similarity index 100% rename from src/charon/threads/sender.h rename to src/charon/network/sender.h diff --git a/src/charon/queues/event_queue.c b/src/charon/processing/event_queue.c similarity index 100% rename from src/charon/queues/event_queue.c rename to src/charon/processing/event_queue.c diff --git a/src/charon/queues/event_queue.h b/src/charon/processing/event_queue.h similarity index 99% rename from src/charon/queues/event_queue.h rename to src/charon/processing/event_queue.h index cd275123b..3258b254f 100644 --- a/src/charon/queues/event_queue.h +++ b/src/charon/processing/event_queue.h @@ -29,7 +29,7 @@ typedef struct event_queue_t event_queue_t; #include #include -#include +#include /** * @brief Event-Queue used to store timed events. diff --git a/src/charon/queues/job_queue.c b/src/charon/processing/job_queue.c similarity index 100% rename from src/charon/queues/job_queue.c rename to src/charon/processing/job_queue.c diff --git a/src/charon/queues/job_queue.h b/src/charon/processing/job_queue.h similarity index 98% rename from src/charon/queues/job_queue.h rename to src/charon/processing/job_queue.h index c971ba514..26e1492d8 100644 --- a/src/charon/queues/job_queue.h +++ b/src/charon/processing/job_queue.h @@ -27,7 +27,7 @@ typedef struct job_queue_t job_queue_t; #include -#include +#include /** * @brief The job queue stores jobs, which will be processed by the thread_pool_t. diff --git a/src/charon/queues/jobs/acquire_job.c b/src/charon/processing/jobs/acquire_job.c similarity index 100% rename from src/charon/queues/jobs/acquire_job.c rename to src/charon/processing/jobs/acquire_job.c diff --git a/src/charon/queues/jobs/acquire_job.h b/src/charon/processing/jobs/acquire_job.h similarity index 97% rename from src/charon/queues/jobs/acquire_job.h rename to src/charon/processing/jobs/acquire_job.h index 54f1b9b5b..226966215 100644 --- a/src/charon/queues/jobs/acquire_job.h +++ b/src/charon/processing/jobs/acquire_job.h @@ -26,7 +26,7 @@ typedef struct acquire_job_t acquire_job_t; #include -#include +#include /** * @brief Class representing an ACQUIRE Job. diff --git a/src/charon/queues/jobs/delete_child_sa_job.c b/src/charon/processing/jobs/delete_child_sa_job.c similarity index 100% rename from src/charon/queues/jobs/delete_child_sa_job.c rename to src/charon/processing/jobs/delete_child_sa_job.c diff --git a/src/charon/queues/jobs/delete_child_sa_job.h b/src/charon/processing/jobs/delete_child_sa_job.h similarity index 98% rename from src/charon/queues/jobs/delete_child_sa_job.h rename to src/charon/processing/jobs/delete_child_sa_job.h index 9c2e4fa4d..0b90e008d 100644 --- a/src/charon/queues/jobs/delete_child_sa_job.h +++ b/src/charon/processing/jobs/delete_child_sa_job.h @@ -27,7 +27,7 @@ typedef struct delete_child_sa_job_t delete_child_sa_job_t; #include #include -#include +#include #include diff --git a/src/charon/queues/jobs/delete_ike_sa_job.c b/src/charon/processing/jobs/delete_ike_sa_job.c similarity index 100% rename from src/charon/queues/jobs/delete_ike_sa_job.c rename to src/charon/processing/jobs/delete_ike_sa_job.c diff --git a/src/charon/queues/jobs/delete_ike_sa_job.h b/src/charon/processing/jobs/delete_ike_sa_job.h similarity index 98% rename from src/charon/queues/jobs/delete_ike_sa_job.h rename to src/charon/processing/jobs/delete_ike_sa_job.h index 43701a354..11bb46e73 100644 --- a/src/charon/queues/jobs/delete_ike_sa_job.h +++ b/src/charon/processing/jobs/delete_ike_sa_job.h @@ -28,7 +28,7 @@ typedef struct delete_ike_sa_job_t delete_ike_sa_job_t; #include #include -#include +#include /** diff --git a/src/charon/queues/jobs/initiate_job.c b/src/charon/processing/jobs/initiate_job.c similarity index 72% rename from src/charon/queues/jobs/initiate_job.c rename to src/charon/processing/jobs/initiate_job.c index af50663d6..68ca17258 100644 --- a/src/charon/queues/jobs/initiate_job.c +++ b/src/charon/processing/jobs/initiate_job.c @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -40,14 +40,14 @@ struct private_initiate_job_t { initiate_job_t public; /** - * associated connection to initiate + * associated peer config to use for IKE_SA setup */ - connection_t *connection; + peer_cfg_t *peer_cfg; /** - * associated policy to initiate + * child config to use for CHILD_SA */ - policy_t *policy; + child_cfg_t *child_cfg; }; /** @@ -64,14 +64,20 @@ static job_type_t get_type(private_initiate_job_t *this) static status_t execute(private_initiate_job_t *this) { ike_sa_t *ike_sa; + ike_cfg_t *ike_cfg = this->peer_cfg->get_ike_cfg(this->peer_cfg); ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager, - this->connection->get_my_host(this->connection), - this->connection->get_other_host(this->connection), - this->policy->get_my_id(this->policy), - this->policy->get_other_id(this->policy)); + ike_cfg->get_my_host(ike_cfg), + ike_cfg->get_other_host(ike_cfg), + this->peer_cfg->get_my_id(this->peer_cfg), + this->peer_cfg->get_other_id(this->peer_cfg)); - if (ike_sa->initiate(ike_sa, this->connection, this->policy) != SUCCESS) + if (ike_sa->get_peer_cfg(ike_sa) == NULL) + { + ike_sa->set_peer_cfg(ike_sa, this->peer_cfg); + } + + if (ike_sa->initiate(ike_sa, this->child_cfg) != SUCCESS) { DBG1(DBG_JOB, "initiation failed, going to delete IKE_SA"); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); @@ -87,15 +93,15 @@ static status_t execute(private_initiate_job_t *this) */ static void destroy(private_initiate_job_t *this) { - this->connection->destroy(this->connection); - this->policy->destroy(this->policy); + this->peer_cfg->destroy(this->peer_cfg); + this->child_cfg->destroy(this->child_cfg); free(this); } /* * Described in header */ -initiate_job_t *initiate_job_create(connection_t *connection, policy_t *policy) +initiate_job_t *initiate_job_create(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg) { private_initiate_job_t *this = malloc_thing(private_initiate_job_t); @@ -105,8 +111,8 @@ initiate_job_t *initiate_job_create(connection_t *connection, policy_t *policy) this->public.job_interface.destroy = (void (*) (job_t *)) destroy; /* private variables */ - this->connection = connection; - this->policy = policy; + this->peer_cfg = peer_cfg; + this->child_cfg = child_cfg; return &this->public; } diff --git a/src/charon/queues/jobs/initiate_job.h b/src/charon/processing/jobs/initiate_job.h similarity index 71% rename from src/charon/queues/jobs/initiate_job.h rename to src/charon/processing/jobs/initiate_job.h index af1dd9ece..15b46a74c 100644 --- a/src/charon/queues/jobs/initiate_job.h +++ b/src/charon/processing/jobs/initiate_job.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -20,15 +20,15 @@ * for more details. */ -#ifndef INITIATE_IKE_SA_JOB_H_ -#define INITIATE_IKE_SA_JOB_H_ +#ifndef INITIATE_JOB_H_ +#define INITIATE_JOB_H_ typedef struct initiate_job_t initiate_job_t; #include -#include -#include -#include +#include +#include +#include /** * @brief Class representing an INITIATE_IKE_SA Job. @@ -48,14 +48,14 @@ struct initiate_job_t { }; /** - * @brief Creates a job of type INITIATE_IKE_SA. + * @brief Creates a job of type INITIATE. * - * @param connection connection_t to initialize - * @param policy policy to set up + * @param peer_cfg peer configuration to use (if not yet established) + * @param child_cfg config to create a CHILD from * @return initiate_job_t object * * @ingroup jobs */ -initiate_job_t *initiate_job_create(connection_t *connection, policy_t *policy); +initiate_job_t *initiate_job_create(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg); -#endif /*INITIATE_IKE_SA_JOB_H_*/ +#endif /*INITIATE_JOB_H_*/ diff --git a/src/charon/queues/jobs/job.c b/src/charon/processing/jobs/job.c similarity index 100% rename from src/charon/queues/jobs/job.c rename to src/charon/processing/jobs/job.c diff --git a/src/charon/queues/jobs/job.h b/src/charon/processing/jobs/job.h similarity index 100% rename from src/charon/queues/jobs/job.h rename to src/charon/processing/jobs/job.h diff --git a/src/charon/queues/jobs/process_message_job.c b/src/charon/processing/jobs/process_message_job.c similarity index 100% rename from src/charon/queues/jobs/process_message_job.c rename to src/charon/processing/jobs/process_message_job.c diff --git a/src/charon/queues/jobs/process_message_job.h b/src/charon/processing/jobs/process_message_job.h similarity index 97% rename from src/charon/queues/jobs/process_message_job.h rename to src/charon/processing/jobs/process_message_job.h index 2e60a298c..5bb18155a 100644 --- a/src/charon/queues/jobs/process_message_job.h +++ b/src/charon/processing/jobs/process_message_job.h @@ -28,7 +28,7 @@ typedef struct process_message_job_t process_message_job_t; #include #include -#include +#include /** * @brief Class representing an PROCESS_MESSAGE job. diff --git a/src/charon/queues/jobs/rekey_child_sa_job.c b/src/charon/processing/jobs/rekey_child_sa_job.c similarity index 100% rename from src/charon/queues/jobs/rekey_child_sa_job.c rename to src/charon/processing/jobs/rekey_child_sa_job.c diff --git a/src/charon/queues/jobs/rekey_child_sa_job.h b/src/charon/processing/jobs/rekey_child_sa_job.h similarity index 98% rename from src/charon/queues/jobs/rekey_child_sa_job.h rename to src/charon/processing/jobs/rekey_child_sa_job.h index 19e1b5d32..df86070bc 100644 --- a/src/charon/queues/jobs/rekey_child_sa_job.h +++ b/src/charon/processing/jobs/rekey_child_sa_job.h @@ -27,7 +27,7 @@ typedef struct rekey_child_sa_job_t rekey_child_sa_job_t; #include #include -#include +#include #include /** diff --git a/src/charon/queues/jobs/rekey_ike_sa_job.c b/src/charon/processing/jobs/rekey_ike_sa_job.c similarity index 100% rename from src/charon/queues/jobs/rekey_ike_sa_job.c rename to src/charon/processing/jobs/rekey_ike_sa_job.c diff --git a/src/charon/queues/jobs/rekey_ike_sa_job.h b/src/charon/processing/jobs/rekey_ike_sa_job.h similarity index 97% rename from src/charon/queues/jobs/rekey_ike_sa_job.h rename to src/charon/processing/jobs/rekey_ike_sa_job.h index f3e336fb3..4031b3813 100644 --- a/src/charon/queues/jobs/rekey_ike_sa_job.h +++ b/src/charon/processing/jobs/rekey_ike_sa_job.h @@ -27,7 +27,7 @@ typedef struct rekey_ike_sa_job_t rekey_ike_sa_job_t; #include #include -#include +#include /** * @brief Class representing an REKEY_IKE_SA Job. diff --git a/src/charon/queues/jobs/retransmit_job.c b/src/charon/processing/jobs/retransmit_job.c similarity index 100% rename from src/charon/queues/jobs/retransmit_job.c rename to src/charon/processing/jobs/retransmit_job.c diff --git a/src/charon/queues/jobs/retransmit_job.h b/src/charon/processing/jobs/retransmit_job.h similarity index 98% rename from src/charon/queues/jobs/retransmit_job.h rename to src/charon/processing/jobs/retransmit_job.h index 19e29b909..93bb548e7 100644 --- a/src/charon/queues/jobs/retransmit_job.h +++ b/src/charon/processing/jobs/retransmit_job.h @@ -27,7 +27,7 @@ typedef struct retransmit_job_t retransmit_job_t; #include -#include +#include #include /** diff --git a/src/charon/queues/jobs/route_job.c b/src/charon/processing/jobs/route_job.c similarity index 72% rename from src/charon/queues/jobs/route_job.c rename to src/charon/processing/jobs/route_job.c index bb6281dcc..36afa5513 100644 --- a/src/charon/queues/jobs/route_job.c +++ b/src/charon/processing/jobs/route_job.c @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2007 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -39,14 +39,14 @@ struct private_route_job_t { route_job_t public; /** - * associated connection to route + * peer config for route */ - connection_t *connection; + peer_cfg_t *peer_cfg; /** - * associated policy to route + * child config to route */ - policy_t *policy; + child_cfg_t *child_cfg; /** * route or unroute? @@ -68,22 +68,29 @@ static job_type_t get_type(private_route_job_t *this) static status_t execute(private_route_job_t *this) { ike_sa_t *ike_sa; + ike_cfg_t *ike_cfg = this->peer_cfg->get_ike_cfg(this->peer_cfg); ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager, - this->connection->get_my_host(this->connection), - this->connection->get_other_host(this->connection), - this->policy->get_my_id(this->policy), - this->policy->get_other_id(this->policy)); + ike_cfg->get_my_host(ike_cfg), + ike_cfg->get_other_host(ike_cfg), + this->peer_cfg->get_my_id(this->peer_cfg), + this->peer_cfg->get_other_id(this->peer_cfg)); + + if (ike_sa->get_peer_cfg(ike_sa) == NULL) + { + ike_sa->set_peer_cfg(ike_sa, this->peer_cfg); + } + if (this->route) { - if (ike_sa->route(ike_sa, this->connection, this->policy) != SUCCESS) + if (ike_sa->route(ike_sa, this->child_cfg) != SUCCESS) { DBG1(DBG_JOB, "routing failed"); } } else { - if (ike_sa->unroute(ike_sa, this->policy) == DESTROY_ME) + if (ike_sa->unroute(ike_sa, this->child_cfg) == DESTROY_ME) { DBG1(DBG_JOB, "removing IKE_SA, as last routed CHILD_SA unrouted"); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); @@ -99,15 +106,16 @@ static status_t execute(private_route_job_t *this) */ static void destroy(private_route_job_t *this) { - this->connection->destroy(this->connection); - this->policy->destroy(this->policy); + this->peer_cfg->destroy(this->peer_cfg); + this->child_cfg->destroy(this->child_cfg); free(this); } /* * Described in header */ -route_job_t *route_job_create(connection_t *connection, policy_t *policy, bool route) +route_job_t *route_job_create(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, + bool route) { private_route_job_t *this = malloc_thing(private_route_job_t); @@ -117,8 +125,8 @@ route_job_t *route_job_create(connection_t *connection, policy_t *policy, bool r this->public.job_interface.destroy = (void (*) (job_t *)) destroy; /* private variables */ - this->connection = connection; - this->policy = policy; + this->peer_cfg = peer_cfg; + this->child_cfg = child_cfg; this->route = route; return &this->public; diff --git a/src/charon/queues/jobs/route_job.h b/src/charon/processing/jobs/route_job.h similarity index 78% rename from src/charon/queues/jobs/route_job.h rename to src/charon/processing/jobs/route_job.h index 2743a70ab..840fcc92a 100644 --- a/src/charon/queues/jobs/route_job.h +++ b/src/charon/processing/jobs/route_job.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2007 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -25,9 +25,8 @@ typedef struct route_job_t route_job_t; #include -#include -#include -#include +#include +#include /** * @brief Class representing an ROUTE Job. @@ -47,13 +46,14 @@ struct route_job_t { /** * @brief Creates a job of type ROUTE. * - * @param connection connection used for routing - * @param policy policy to set up + * @param peer_cfg peer config to use for acquire + * @param child_cfg route to install * @param route TRUE to route, FALSE to unroute * @return route_job_t object * * @ingroup jobs */ -route_job_t *route_job_create(connection_t *connection, policy_t *policy, bool route); +route_job_t *route_job_create(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, + bool route); #endif /*ROUTE_JOB_H_*/ diff --git a/src/charon/queues/jobs/send_dpd_job.c b/src/charon/processing/jobs/send_dpd_job.c similarity index 100% rename from src/charon/queues/jobs/send_dpd_job.c rename to src/charon/processing/jobs/send_dpd_job.c diff --git a/src/charon/queues/jobs/send_dpd_job.h b/src/charon/processing/jobs/send_dpd_job.h similarity index 95% rename from src/charon/queues/jobs/send_dpd_job.h rename to src/charon/processing/jobs/send_dpd_job.h index f3900f9a2..26c9e2e81 100644 --- a/src/charon/queues/jobs/send_dpd_job.h +++ b/src/charon/processing/jobs/send_dpd_job.h @@ -25,8 +25,7 @@ typedef struct send_dpd_job_t send_dpd_job_t; #include -#include -#include +#include #include /** diff --git a/src/charon/queues/jobs/send_keepalive_job.c b/src/charon/processing/jobs/send_keepalive_job.c similarity index 100% rename from src/charon/queues/jobs/send_keepalive_job.c rename to src/charon/processing/jobs/send_keepalive_job.c diff --git a/src/charon/queues/jobs/send_keepalive_job.h b/src/charon/processing/jobs/send_keepalive_job.h similarity index 96% rename from src/charon/queues/jobs/send_keepalive_job.h rename to src/charon/processing/jobs/send_keepalive_job.h index c7d05be65..f7b38337e 100644 --- a/src/charon/queues/jobs/send_keepalive_job.h +++ b/src/charon/processing/jobs/send_keepalive_job.h @@ -25,8 +25,7 @@ typedef struct send_keepalive_job_t send_keepalive_job_t; #include -#include -#include +#include #include /** diff --git a/src/charon/threads/scheduler.c b/src/charon/processing/scheduler.c similarity index 98% rename from src/charon/threads/scheduler.c rename to src/charon/processing/scheduler.c index 74091e3a3..156c1e240 100644 --- a/src/charon/threads/scheduler.c +++ b/src/charon/processing/scheduler.c @@ -27,7 +27,7 @@ #include "scheduler.h" #include -#include +#include typedef struct private_scheduler_t private_scheduler_t; diff --git a/src/charon/threads/scheduler.h b/src/charon/processing/scheduler.h similarity index 100% rename from src/charon/threads/scheduler.h rename to src/charon/processing/scheduler.h diff --git a/src/charon/threads/thread_pool.c b/src/charon/processing/thread_pool.c similarity index 99% rename from src/charon/threads/thread_pool.c rename to src/charon/processing/thread_pool.c index 052b5aab9..effa30a2d 100644 --- a/src/charon/threads/thread_pool.c +++ b/src/charon/processing/thread_pool.c @@ -29,7 +29,7 @@ #include "thread_pool.h" #include -#include +#include typedef struct private_thread_pool_t private_thread_pool_t; diff --git a/src/charon/threads/thread_pool.h b/src/charon/processing/thread_pool.h similarity index 100% rename from src/charon/threads/thread_pool.h rename to src/charon/processing/thread_pool.h diff --git a/src/charon/sa/authenticators/eap_authenticator.c b/src/charon/sa/authenticators/eap_authenticator.c index 6c8ca8d8f..08edd80e8 100644 --- a/src/charon/sa/authenticators/eap_authenticator.c +++ b/src/charon/sa/authenticators/eap_authenticator.c @@ -25,7 +25,7 @@ #include "eap_authenticator.h" #include -#include +#include #include typedef struct private_eap_authenticator_t private_eap_authenticator_t; diff --git a/src/charon/sa/authenticators/psk_authenticator.c b/src/charon/sa/authenticators/psk_authenticator.c index 43aec0971..1831b2ded 100644 --- a/src/charon/sa/authenticators/psk_authenticator.c +++ b/src/charon/sa/authenticators/psk_authenticator.c @@ -25,7 +25,6 @@ #include "psk_authenticator.h" -#include #include /** diff --git a/src/charon/sa/authenticators/rsa_authenticator.c b/src/charon/sa/authenticators/rsa_authenticator.c index dfa01e332..42d861ef6 100644 --- a/src/charon/sa/authenticators/rsa_authenticator.c +++ b/src/charon/sa/authenticators/rsa_authenticator.c @@ -25,7 +25,6 @@ #include "rsa_authenticator.h" -#include #include diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c index 19131389d..7ce8ca2fd 100644 --- a/src/charon/sa/child_sa.c +++ b/src/charon/sa/child_sa.c @@ -154,9 +154,9 @@ struct private_child_sa_t { host_t *virtual_ip; /** - * policy used to create this child + * config used to create this child */ - policy_t *policy; + child_cfg_t *config; }; /** @@ -164,7 +164,7 @@ struct private_child_sa_t { */ static char *get_name(private_child_sa_t *this) { - return this->policy->get_name(this->policy);; + return this->config->get_name(this->config); } /** @@ -204,11 +204,11 @@ static child_sa_state_t get_state(private_child_sa_t *this) } /** - * Implements child_sa_t.get_policy + * Implements child_sa_t.get_config */ -static policy_t* get_policy(private_child_sa_t *this) +static child_cfg_t* get_config(private_child_sa_t *this) { - return this->policy; + return this->config; } /** @@ -220,7 +220,7 @@ static void updown(private_child_sa_t *this, bool up) iterator_t *iterator; char *script; - script = this->policy->get_updown(this->policy); + script = this->config->get_updown(this->config); if (script == NULL) { @@ -300,7 +300,7 @@ static void updown(private_child_sa_t *this, bool up) policy->my_ts->is_host(policy->my_ts, this->me.addr) ? "-host" : "-client", this->me.addr->get_family(this->me.addr) == AF_INET ? "" : "-ipv6", - this->policy->get_name(this->policy), + this->config->get_name(this->config), ifname ? ifname : "(unknown)", this->reqid, this->me.addr, @@ -316,7 +316,7 @@ static void updown(private_child_sa_t *this, bool up) policy->other_ts->get_from_port(policy->other_ts), policy->other_ts->get_protocol(policy->other_ts), virtual_ip, - this->policy->get_hostaccess(this->policy) ? + this->config->get_hostaccess(this->config) ? "PLUTO_HOST_ACCESS='1' " : "", script); free(ifname); @@ -528,8 +528,8 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, natt = NULL; } - soft = this->policy->get_soft_lifetime(this->policy); - hard = this->policy->get_hard_lifetime(this->policy); + 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); @@ -665,10 +665,10 @@ static status_t add_policies(private_child_sa_t *this, policy = malloc_thing(sa_policy_t); policy->my_ts = my_ts->clone(my_ts); policy->other_ts = other_ts->clone(other_ts); - this->policies->insert_last(this->policies, (void*)policy); + this->policies->insert_last(this->policies, policy); /* add to separate list to query them via get_*_traffic_selectors() */ - this->my_ts->insert_last(this->my_ts, (void*)policy->my_ts); - this->other_ts->insert_last(this->other_ts, (void*)policy->other_ts); + this->my_ts->insert_last(this->my_ts, policy->my_ts); + this->other_ts->insert_last(this->other_ts, policy->other_ts); } } my_iter->destroy(my_iter); @@ -685,18 +685,14 @@ static status_t add_policies(private_child_sa_t *this, } /** - * Implementation of child_sa_t.get_my_traffic_selectors. + * Implementation of child_sa_t.get_traffic_selectors. */ -static linked_list_t *get_my_traffic_selectors(private_child_sa_t *this) -{ - return this->my_ts; -} - -/** - * Implementation of child_sa_t.get_my_traffic_selectors. - */ -static linked_list_t *get_other_traffic_selectors(private_child_sa_t *this) +static linked_list_t *get_traffic_selectors(private_child_sa_t *this, bool local) { + if (local) + { + return this->my_ts; + } return this->other_ts; } @@ -762,7 +758,7 @@ static int print(FILE *stream, const struct printf_info *info, now = time(NULL); written += fprintf(stream, "%12s{%d}: %N, %N", - this->policy->get_name(this->policy), this->reqid, + this->config->get_name(this->config), this->reqid, child_sa_state_names, this->state, mode_names, this->mode); @@ -775,7 +771,7 @@ static int print(FILE *stream, const struct printf_info *info, if (info->alt) { written += fprintf(stream, "\n%12s{%d}: ", - this->policy->get_name(this->policy), + this->config->get_name(this->config), this->reqid); if (this->protocol == PROTO_ESP) @@ -814,7 +810,7 @@ static int print(FILE *stream, const struct printf_info *info, while (iterator->iterate(iterator, (void**)&policy)) { written += fprintf(stream, "\n%12s{%d}: %R===%R, last use: ", - this->policy->get_name(this->policy), this->reqid, + this->config->get_name(this->config), this->reqid, policy->my_ts, policy->other_ts); /* query time of last policy use */ @@ -1066,7 +1062,7 @@ static void destroy(private_child_sa_t *this) this->other.addr->destroy(this->other.addr); this->me.id->destroy(this->me.id); this->other.id->destroy(this->other.id); - this->policy->destroy(this->policy); + this->config->destroy(this->config); DESTROY_IF(this->virtual_ip); free(this); } @@ -1076,7 +1072,7 @@ static void destroy(private_child_sa_t *this) */ child_sa_t * child_sa_create(host_t *me, host_t* other, identification_t *my_id, identification_t *other_id, - policy_t *policy, u_int32_t rekey, bool use_natt) + child_cfg_t *config, u_int32_t rekey, bool use_natt) { static u_int32_t reqid = 0; private_child_sa_t *this = malloc_thing(private_child_sa_t); @@ -1091,12 +1087,11 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, this->public.update = (status_t(*)(child_sa_t*,proposal_t*,mode_t,prf_plus_t*))update; this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,host_diff_t,host_diff_t))update_hosts; this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*,mode_t))add_policies; - this->public.get_my_traffic_selectors = (linked_list_t*(*)(child_sa_t*))get_my_traffic_selectors; - this->public.get_other_traffic_selectors = (linked_list_t*(*)(child_sa_t*))get_other_traffic_selectors; + this->public.get_traffic_selectors = (linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors; this->public.get_use_time = (status_t (*)(child_sa_t*,bool,time_t*))get_use_time; 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_policy = (policy_t*(*)(child_sa_t*))get_policy; + this->public.get_config = (child_cfg_t*(*)(child_sa_t*))get_config; this->public.set_virtual_ip = (void(*)(child_sa_t*,host_t*))set_virtual_ip; this->public.destroy = (void(*)(child_sa_t*))destroy; @@ -1123,8 +1118,8 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, this->protocol = PROTO_NONE; this->mode = MODE_TUNNEL; this->virtual_ip = NULL; - this->policy = policy; - policy->get_ref(policy); + this->config = config; + config->get_ref(config); return &this->public; } diff --git a/src/charon/sa/child_sa.h b/src/charon/sa/child_sa.h index 216e56659..3169b975a 100644 --- a/src/charon/sa/child_sa.h +++ b/src/charon/sa/child_sa.h @@ -32,7 +32,7 @@ typedef struct child_sa_t child_sa_t; #include #include #include -#include +#include /** * Where we should start with reqid enumeration @@ -101,7 +101,7 @@ extern enum_name_t *child_sa_state_names; struct child_sa_t { /** - * @brief Get the name of the policy this CHILD_SA uses. + * @brief Get the name of the config this CHILD_SA uses. * * @param this calling object * @return name @@ -214,17 +214,10 @@ struct child_sa_t { * @brief 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_my_traffic_selectors) (child_sa_t *this); - - /** - * @brief Get the traffic selectors of added policies of remote host. - * - * @param this calling object - * @return list of traffic selectors - */ - linked_list_t* (*get_other_traffic_selectors) (child_sa_t *this); + 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) @@ -251,12 +244,12 @@ struct child_sa_t { void (*set_state) (child_sa_t *this, child_sa_state_t state); /** - * @brief Get the policy used to set up this child sa. + * @brief Get the config used to set up this child sa. * * @param this calling object - * @return policy + * @return child_cfg */ - policy_t* (*get_policy) (child_sa_t *this); + child_cfg_t* (*get_config) (child_sa_t *this); /** * @brief Set the virtual IP used received from IRAS. @@ -284,7 +277,7 @@ struct child_sa_t { * @param other remote address * @param my_id id of own peer * @param other_id id of remote peer - * @param policy policy this CHILD_SA instantiates + * @param config config to use for this CHILD_SA * @param reqid reqid of old CHILD_SA when rekeying, 0 otherwise * @param use_natt TRUE if NAT traversal is used * @return child_sa_t object @@ -293,6 +286,6 @@ struct child_sa_t { */ child_sa_t * child_sa_create(host_t *me, host_t *other, identification_t *my_id, identification_t* other_id, - policy_t *policy, u_int32_t reqid, bool use_natt); + child_cfg_t *config, u_int32_t reqid, bool use_natt); #endif /*CHILD_SA_H_*/ diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c index 68aba3064..ec69f619d 100644 --- a/src/charon/sa/ike_sa.c +++ b/src/charon/sa/ike_sa.c @@ -56,13 +56,13 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #ifndef RESOLV_CONF @@ -105,14 +105,14 @@ struct private_ike_sa_t { ike_sa_state_t state; /** - * connection used to establish this IKE_SA. + * IKE configuration used to set up this IKE_SA */ - connection_t *connection; + ike_cfg_t *ike_cfg; /** * Peer and authentication information to establish IKE_SA. */ - policy_t *policy; + peer_cfg_t *peer_cfg; /** * Juggles tasks to process messages @@ -273,47 +273,13 @@ static u_int32_t get_unique_id(private_ike_sa_t *this) */ static char *get_name(private_ike_sa_t *this) { - if (this->connection) + if (this->peer_cfg) { - return this->connection->get_name(this->connection); + return this->peer_cfg->get_name(this->peer_cfg); } return "(unnamed)"; } -/** - * Implementation of ike_sa_t.get_connection - */ -static connection_t* get_connection(private_ike_sa_t *this) -{ - return this->connection; -} - -/** - * Implementation of ike_sa_t.set_connection - */ -static void set_connection(private_ike_sa_t *this, connection_t *connection) -{ - this->connection = connection; - connection->get_ref(connection); -} - -/** - * Implementation of ike_sa_t.get_policy - */ -static policy_t *get_policy(private_ike_sa_t *this) -{ - return this->policy; -} - -/** - * Implementation of ike_sa_t.set_policy - */ -static void set_policy(private_ike_sa_t *this, policy_t *policy) -{ - policy->get_ref(policy); - this->policy = policy; -} - /** * Implementation of ike_sa_t.get_my_host. */ @@ -348,6 +314,66 @@ static void set_other_host(private_ike_sa_t *this, host_t *other) this->other_host = other; } +/** + * Implementation of ike_sa_t.get_peer_cfg + */ +static peer_cfg_t* get_peer_cfg(private_ike_sa_t *this) +{ + return this->peer_cfg; +} + +/** + * Implementation of ike_sa_t.set_peer_cfg + */ +static void set_peer_cfg(private_ike_sa_t *this, peer_cfg_t *peer_cfg) +{ + host_t *me, *other; + identification_t *my_id, *other_id; + + peer_cfg->get_ref(peer_cfg); + this->peer_cfg = peer_cfg; + if (this->ike_cfg == NULL) + { + 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)) + { + 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)) + { + other = this->ike_cfg->get_other_host(this->ike_cfg); + set_other_host(this, other->clone(other)); + } + my_id = this->peer_cfg->get_my_id(this->peer_cfg); + other_id = this->peer_cfg->get_other_id(this->peer_cfg); + DESTROY_IF(this->my_id); + DESTROY_IF(this->other_id); + this->my_id = my_id->clone(my_id); + this->other_id = other_id->clone(other_id); +} + +/** + * Implementation of ike_sa_t.get_ike_cfg + */ +static ike_cfg_t *get_ike_cfg(private_ike_sa_t *this) +{ + return this->ike_cfg; +} + +/** + * Implementation of ike_sa_t.set_ike_cfg + */ +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.send_dpd */ @@ -356,7 +382,7 @@ static status_t send_dpd(private_ike_sa_t *this) send_dpd_job_t *job; time_t diff, delay; - delay = this->connection->get_dpd_delay(this->connection); + delay = this->peer_cfg->get_dpd_delay(this->peer_cfg); if (delay == 0) { @@ -464,9 +490,9 @@ static void set_state(private_ike_sa_t *this, ike_sa_state_t state) send_dpd(this); /* schedule rekeying/reauthentication */ - soft = this->connection->get_soft_lifetime(this->connection); - hard = this->connection->get_hard_lifetime(this->connection); - reauth = this->connection->get_reauth(this->connection); + soft = this->peer_cfg->get_lifetime(this->peer_cfg, TRUE); + hard = this->peer_cfg->get_lifetime(this->peer_cfg, FALSE); + reauth = this->peer_cfg->use_reauth(this->peer_cfg); DBG1(DBG_IKE, "scheduling %s in %ds, maximum lifetime %ds", reauth ? "reauthentication": "rekeying", soft, hard); @@ -521,7 +547,7 @@ static void reset(private_ike_sa_t *this) } /** - * Update connection host, as addresses may change (NAT) + * Update hosts, as addresses may change (NAT) */ static void update_hosts(private_ike_sa_t *this, host_t *me, host_t *other) { @@ -696,16 +722,16 @@ static status_t process_message(private_ike_sa_t *this, message_t *message) me = message->get_destination(message); other = message->get_source(message); - /* if this IKE_SA is virgin, we check for a connection */ - if (this->connection == NULL) + /* if this IKE_SA is virgin, we check for a config */ + if (this->ike_cfg == NULL) { job_t *job; - this->connection = charon->connections->get_connection_by_hosts( - charon->connections, me, other); - if (this->connection == NULL) + this->ike_cfg = charon->cfg_store->get_ike_cfg(charon->cfg_store, + me, other); + if (this->ike_cfg == NULL) { - /* no connection found for these hosts, destroy */ - DBG1(DBG_IKE, "no connection found for %H...%H, sending %N", + /* no config found for these hosts, destroy */ + DBG1(DBG_IKE, "no IKE config found for %H...%H, sending %N", me, other, notify_type_names, NO_PROPOSAL_CHOSEN); send_notify_response(this, message, NO_PROPOSAL_CHOSEN); return DESTROY_ME; @@ -717,7 +743,7 @@ static status_t process_message(private_ike_sa_t *this, message_t *message) charon->configuration)); } - /* check if message is trustworthy, and update connection information */ + /* check if message is trustworthy, and update host information */ if (this->state == IKE_CREATED || message->get_exchange_type(message) != IKE_SA_INIT) { @@ -728,47 +754,15 @@ static status_t process_message(private_ike_sa_t *this, message_t *message) } } -/** - * apply the connection/policy information to this IKE_SA - */ -static void apply_config(private_ike_sa_t *this, - connection_t *connection, policy_t *policy) -{ - host_t *me, *other; - identification_t *my_id, *other_id; - - if (this->connection == NULL && this->policy == NULL) - { - this->connection = connection; - connection->get_ref(connection); - this->policy = policy; - policy->get_ref(policy); - - me = connection->get_my_host(connection); - other = connection->get_other_host(connection); - my_id = policy->get_my_id(policy); - other_id = policy->get_other_id(policy); - set_my_host(this, me->clone(me)); - set_other_host(this, other->clone(other)); - DESTROY_IF(this->my_id); - DESTROY_IF(this->other_id); - this->my_id = my_id->clone(my_id); - this->other_id = other_id->clone(other_id); - } -} - /** * Implementation of ike_sa_t.initiate. */ -static status_t initiate(private_ike_sa_t *this, - connection_t *connection, policy_t *policy) +static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg) { task_t *task; if (this->state == IKE_CREATED) { - /* if we aren't established/establishing, do so */ - apply_config(this, connection, policy); if (this->other_host->is_anyaddr(this->other_host)) { @@ -785,11 +779,11 @@ static status_t initiate(private_ike_sa_t *this, 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, policy); + task = (task_t*)ike_config_create(&this->public, TRUE); this->task_manager->queue_task(this->task_manager, task); } - task = (task_t*)child_create_create(&this->public, policy); + task = (task_t*)child_create_create(&this->public, child_cfg); this->task_manager->queue_task(this->task_manager, task); return this->task_manager->initiate(this->task_manager); @@ -800,7 +794,7 @@ static status_t initiate(private_ike_sa_t *this, */ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid) { - policy_t *policy; + child_cfg_t *child_cfg; iterator_t *iterator; child_sa_t *current, *child_sa = NULL; task_t *task; @@ -833,7 +827,6 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid) return FAILED; } - policy = child_sa->get_policy(child_sa); if (this->state == IKE_CREATED) { @@ -845,52 +838,24 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid) 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, policy); + task = (task_t*)ike_config_create(&this->public, TRUE); this->task_manager->queue_task(this->task_manager, task); } - child_create = child_create_create(&this->public, policy); + 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); return this->task_manager->initiate(this->task_manager); } -/** - * compare two lists of traffic selectors for equality - */ -static bool ts_list_equals(linked_list_t *l1, linked_list_t *l2) -{ - bool equals = TRUE; - iterator_t *i1, *i2; - traffic_selector_t *t1, *t2; - - if (l1->get_count(l1) != l2->get_count(l2)) - { - return FALSE; - } - - i1 = l1->create_iterator(l1, TRUE); - i2 = l2->create_iterator(l2, TRUE); - while (i1->iterate(i1, (void**)&t1) && i2->iterate(i2, (void**)&t2)) - { - if (!t1->equals(t1, t2)) - { - equals = FALSE; - break; - } - } - i1->destroy(i1); - i2->destroy(i2); - return equals; -} - /** * Implementation of ike_sa_t.route. */ -static status_t route(private_ike_sa_t *this, connection_t *connection, policy_t *policy) +static status_t route(private_ike_sa_t *this, child_cfg_t *child_cfg) { - child_sa_t *child_sa = NULL; + child_sa_t *child_sa; iterator_t *iterator; linked_list_t *my_ts, *other_ts; status_t status; @@ -901,27 +866,12 @@ static status_t route(private_ike_sa_t *this, connection_t *connection, policy_t iterator = this->child_sas->create_iterator(this->child_sas, TRUE); while (iterator->iterate(iterator, (void**)&child_sa)) { - if (child_sa->get_state(child_sa) == CHILD_ROUTED) + if (child_sa->get_state(child_sa) == CHILD_ROUTED && + streq(child_sa->get_name(child_sa), child_cfg->get_name(child_cfg))) { - linked_list_t *my_ts_conf, *other_ts_conf; - - my_ts = child_sa->get_my_traffic_selectors(child_sa); - other_ts = child_sa->get_other_traffic_selectors(child_sa); - - my_ts_conf = policy->get_my_traffic_selectors(policy, this->my_host); - other_ts_conf = policy->get_other_traffic_selectors(policy, this->other_host); - - if (ts_list_equals(my_ts, my_ts_conf) && - ts_list_equals(other_ts, other_ts_conf)) - { - iterator->destroy(iterator); - my_ts_conf->destroy_offset(my_ts_conf, offsetof(traffic_selector_t, destroy)); - other_ts_conf->destroy_offset(other_ts_conf, offsetof(traffic_selector_t, destroy)); - SIG(CHILD_ROUTE_FAILED, "CHILD_SA with such a policy already routed"); - return FAILED; - } - my_ts_conf->destroy_offset(my_ts_conf, offsetof(traffic_selector_t, destroy)); - other_ts_conf->destroy_offset(other_ts_conf, offsetof(traffic_selector_t, destroy)); + iterator->destroy(iterator); + SIG(CHILD_ROUTE_FAILED, "CHILD_SA with such a config already routed"); + return FAILED; } } iterator->destroy(iterator); @@ -934,9 +884,6 @@ static status_t route(private_ike_sa_t *this, connection_t *connection, policy_t "unable to route CHILD_SA, as its IKE_SA gets deleted"); return FAILED; case IKE_CREATED: - /* apply connection information, we need it to acquire */ - apply_config(this, connection, policy); - break; case IKE_CONNECTING: case IKE_ESTABLISHED: default: @@ -944,29 +891,37 @@ static status_t route(private_ike_sa_t *this, connection_t *connection, policy_t } /* install kernel policies */ - child_sa = child_sa_create(this->my_host, this->other_host, - this->my_id, this->other_id, policy, FALSE, 0); + child_sa = child_sa_create(this->my_host, this->other_host, this->my_id, + this->other_id, child_cfg, FALSE, 0); - my_ts = policy->get_my_traffic_selectors(policy, this->my_host); - other_ts = policy->get_other_traffic_selectors(policy, this->other_host); + my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, + this->my_host); + other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, + this->other_host); status = child_sa->add_policies(child_sa, my_ts, other_ts, - policy->get_mode(policy)); + child_cfg->get_mode(child_cfg)); my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); - this->child_sas->insert_last(this->child_sas, child_sa); - SIG(CHILD_ROUTE_SUCCESS, "CHILD_SA routed"); + if (status == SUCCESS) + { + this->child_sas->insert_last(this->child_sas, child_sa); + SIG(CHILD_ROUTE_SUCCESS, "CHILD_SA routed"); + } + else + { + SIG(CHILD_ROUTE_FAILED, "routing CHILD_SA failed"); + } return status; } /** * Implementation of ike_sa_t.unroute. */ -static status_t unroute(private_ike_sa_t *this, policy_t *policy) +static status_t unroute(private_ike_sa_t *this, child_cfg_t *child_cfg) { iterator_t *iterator; - child_sa_t *child_sa = NULL; + child_sa_t *child_sa; bool found = FALSE; - linked_list_t *my_ts, *other_ts, *my_ts_conf, *other_ts_conf; SIG(CHILD_UNROUTE_START, "unrouting CHILD_SA"); @@ -974,27 +929,14 @@ static status_t unroute(private_ike_sa_t *this, policy_t *policy) iterator = this->child_sas->create_iterator(this->child_sas, TRUE); while (iterator->iterate(iterator, (void**)&child_sa)) { - if (child_sa->get_state(child_sa) == CHILD_ROUTED) + if (child_sa->get_state(child_sa) == CHILD_ROUTED && + streq(child_sa->get_name(child_sa), child_cfg->get_name(child_cfg))) { - my_ts = child_sa->get_my_traffic_selectors(child_sa); - other_ts = child_sa->get_other_traffic_selectors(child_sa); - - my_ts_conf = policy->get_my_traffic_selectors(policy, this->my_host); - other_ts_conf = policy->get_other_traffic_selectors(policy, this->other_host); - - if (ts_list_equals(my_ts, my_ts_conf) && - ts_list_equals(other_ts, other_ts_conf)) - { - iterator->remove(iterator); - SIG(CHILD_UNROUTE_SUCCESS, "CHILD_SA unrouted"); - child_sa->destroy(child_sa); - my_ts_conf->destroy_offset(my_ts_conf, offsetof(traffic_selector_t, destroy)); - other_ts_conf->destroy_offset(other_ts_conf, offsetof(traffic_selector_t, destroy)); - found = TRUE; - break; - } - my_ts_conf->destroy_offset(my_ts_conf, offsetof(traffic_selector_t, destroy)); - other_ts_conf->destroy_offset(other_ts_conf, offsetof(traffic_selector_t, destroy)); + iterator->remove(iterator); + SIG(CHILD_UNROUTE_SUCCESS, "CHILD_SA unrouted"); + child_sa->destroy(child_sa); + found = TRUE; + break; } } iterator->destroy(iterator); @@ -1021,7 +963,7 @@ 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) { - policy_t *policy; + child_cfg_t *child_cfg; child_sa_t* child_sa; linked_list_t *to_route, *to_restart; iterator_t *iterator; @@ -1032,7 +974,7 @@ static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id) case IKE_CONNECTING: { /* retry IKE_SA_INIT if we have multiple keyingtries */ - u_int32_t tries = this->connection->get_keyingtries(this->connection); + u_int32_t tries = this->peer_cfg->get_keyingtries(this->peer_cfg); this->keyingtry++; if (tries == 0 || tries > this->keyingtry) { @@ -1060,23 +1002,23 @@ static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id) iterator = this->child_sas->create_iterator(this->child_sas, TRUE); while (iterator->iterate(iterator, (void**)&child_sa)) { - policy = child_sa->get_policy(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, policy); + to_route->insert_last(to_route, child_cfg); } else { /* use DPD action for established CHILD_SAs */ - switch (policy->get_dpd_action(policy)) + switch (this->peer_cfg->get_dpd_action(this->peer_cfg)) { case DPD_ROUTE: - to_route->insert_last(to_route, policy); + to_route->insert_last(to_route, child_cfg); break; case DPD_RESTART: - to_restart->insert_last(to_restart, policy); + to_restart->insert_last(to_restart, child_cfg); break; default: break; @@ -1094,15 +1036,15 @@ static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id) new = (private_ike_sa_t*)charon->ike_sa_manager->checkout_new( charon->ike_sa_manager, TRUE); - apply_config(new, this->connection, this->policy); - /* use actual used host, not the wildcarded one in connection */ + 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); /* install routes */ - while (to_route->remove_last(to_route, (void**)&policy) == SUCCESS) + while (to_route->remove_last(to_route, (void**)&child_cfg) == SUCCESS) { - route(new, new->connection, policy); + route(new, child_cfg); } /* restart children */ @@ -1114,14 +1056,14 @@ static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id) 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, new->policy); + 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**)&policy) == SUCCESS) + while (to_restart->remove_last(to_restart, (void**)&child_cfg) == SUCCESS) { - task = (task_t*)child_create_create(&new->public, policy); + task = (task_t*)child_create_create(&new->public, child_cfg); new->task_manager->queue_task(new->task_manager, task); } new->task_manager->initiate(new->task_manager); @@ -1542,14 +1484,14 @@ static void reestablish(private_ike_sa_t *this) private_ike_sa_t *other; iterator_t *iterator; child_sa_t *child_sa; - policy_t *policy; + child_cfg_t *child_cfg; task_t *task; job_t *job; other = (private_ike_sa_t*)charon->ike_sa_manager->checkout_new( charon->ike_sa_manager, TRUE); - apply_config(other, this->connection, this->policy); + set_peer_cfg(other, this->peer_cfg); other->other_host->destroy(other->other_host); other->other_host = this->other_host->clone(this->other_host); @@ -1561,7 +1503,7 @@ static void reestablish(private_ike_sa_t *this) other->task_manager->queue_task(other->task_manager, task); task = (task_t*)ike_cert_create(&other->public, TRUE); other->task_manager->queue_task(other->task_manager, task); - task = (task_t*)ike_config_create(&other->public, other->policy); + task = (task_t*)ike_config_create(&other->public, TRUE); other->task_manager->queue_task(other->task_manager, task); task = (task_t*)ike_auth_create(&other->public, TRUE); other->task_manager->queue_task(other->task_manager, task); @@ -1583,8 +1525,8 @@ static void reestablish(private_ike_sa_t *this) } default: { - policy = child_sa->get_policy(child_sa); - task = (task_t*)child_create_create(&other->public, policy); + child_cfg = child_sa->get_config(child_sa); + task = (task_t*)child_create_create(&other->public, child_cfg); other->task_manager->queue_task(other->task_manager, task); break; } @@ -1865,9 +1807,9 @@ static int print(FILE *stream, const struct printf_info *info, bool reauth = FALSE; private_ike_sa_t *this = *((private_ike_sa_t**)(args[0])); - if (this->connection) + if (this->peer_cfg) { - reauth = this->connection->get_reauth(this->connection); + reauth = this->peer_cfg->use_reauth(this->peer_cfg); } if (this == NULL) @@ -1879,15 +1821,19 @@ static int print(FILE *stream, const struct printf_info *info, this->unique_id, ike_sa_state_names, this->state, this->my_host, this->my_id, this->other_host, this->other_id); - written += fprintf(stream, "\n%12s[%d]: IKE SPIs: %J, %s in %ds", - get_name(this), this->unique_id, this->ike_sa_id, - this->connection && reauth? "reauthentication":"rekeying", - this->time.rekey - time(NULL)); - - if (info->alt) + if (this->time.rekey) { - + written += fprintf(stream, "\n%12s[%d]: IKE SPIs: %J, %s in %ds", + get_name(this), this->unique_id, this->ike_sa_id, + reauth ? "reauthentication" : "rekeying", + this->time.rekey - time(NULL)); } + else + { + written += fprintf(stream, "\n%12s[%d]: IKE SPIs: %J, rekeying disabled", + get_name(this), this->unique_id, this->ike_sa_id); + } + return written; } @@ -1931,8 +1877,8 @@ static void destroy(private_ike_sa_t *this) DESTROY_IF(this->my_id); DESTROY_IF(this->other_id); - DESTROY_IF(this->connection); - DESTROY_IF(this->policy); + DESTROY_IF(this->ike_cfg); + DESTROY_IF(this->peer_cfg); this->ike_sa_id->destroy(this->ike_sa_id); this->task_manager->destroy(this->task_manager); @@ -1952,14 +1898,14 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->public.set_state = (void(*)(ike_sa_t*,ike_sa_state_t)) set_state; this->public.get_name = (char*(*)(ike_sa_t*))get_name; this->public.process_message = (status_t(*)(ike_sa_t*, message_t*)) process_message; - this->public.initiate = (status_t(*)(ike_sa_t*,connection_t*,policy_t*)) initiate; - this->public.route = (status_t(*)(ike_sa_t*,connection_t*,policy_t*)) route; - this->public.unroute = (status_t(*)(ike_sa_t*,policy_t*)) unroute; + this->public.initiate = (status_t(*)(ike_sa_t*,child_cfg_t*)) initiate; + this->public.route = (status_t(*)(ike_sa_t*,child_cfg_t*)) route; + this->public.unroute = (status_t(*)(ike_sa_t*,child_cfg_t*)) unroute; this->public.acquire = (status_t(*)(ike_sa_t*,u_int32_t)) acquire; - this->public.get_connection = (connection_t*(*)(ike_sa_t*))get_connection; - this->public.set_connection = (void(*)(ike_sa_t*,connection_t*))set_connection; - this->public.get_policy = (policy_t*(*)(ike_sa_t*))get_policy; - this->public.set_policy = (void(*)(ike_sa_t*,policy_t*))set_policy; + this->public.get_ike_cfg = (ike_cfg_t*(*)(ike_sa_t*))get_ike_cfg; + 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_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; @@ -2019,8 +1965,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->time.established = 0; this->time.rekey = 0; this->time.delete = 0; - this->connection = NULL; - this->policy = NULL; + this->ike_cfg = NULL; + this->peer_cfg = NULL; this->task_manager = task_manager_create(&this->public); this->unique_id = ++unique_id; this->my_virtual_ip = NULL; diff --git a/src/charon/sa/ike_sa.h b/src/charon/sa/ike_sa.h index 604ec94a9..c386f92eb 100644 --- a/src/charon/sa/ike_sa.h +++ b/src/charon/sa/ike_sa.h @@ -39,9 +39,8 @@ typedef struct ike_sa_t ike_sa_t; #include #include #include -#include -#include -#include +#include +#include /** * @brief State of an IKE_SA. @@ -237,51 +236,49 @@ struct ike_sa_t { void (*set_other_id) (ike_sa_t *this, identification_t *other); /** - * @brief Get the connection used by this IKE_SA. + * @brief Get the config used to setup this IKE_SA. * * @param this calling object - * @return connection + * @return ike_config */ - connection_t* (*get_connection) (ike_sa_t *this); + ike_cfg_t* (*get_ike_cfg) (ike_sa_t *this); /** - * @brief Set the connection to use with this IKE_SA. + * @brief Set the config to setup this IKE_SA. * * @param this calling object - * @param connection connection to use + * @param config ike_config to use */ - void (*set_connection) (ike_sa_t *this, connection_t* connection); + void (*set_ike_cfg) (ike_sa_t *this, ike_cfg_t* config); /** - * @brief Get the policy used by this IKE_SA. + * @brief Get the peer config used by this IKE_SA. * * @param this calling object - * @return policy + * @return peer_config */ - policy_t* (*get_policy) (ike_sa_t *this); + peer_cfg_t* (*get_peer_cfg) (ike_sa_t *this); /** - * @brief Set the policy to use with this IKE_SA. + * @brief Set the peer config to use with this IKE_SA. * * @param this calling object - * @param policy policy to use + * @param config peer_config to use */ - void (*set_policy) (ike_sa_t *this, policy_t *policy); + void (*set_peer_cfg) (ike_sa_t *this, peer_cfg_t *config); /** * @brief Initiate a new connection. * - * The policy/connection is owned by the IKE_SA after the call, so - * do not modify or destroy it. + * The configs are owned by the IKE_SA after the call. * * @param this calling object - * @param connection connection to initiate - * @param policy policy to set up + * @param child_cfg child config to create CHILD from * @return * - SUCCESS if initialization started - * - DESTROY_ME if initialization failed and IKE_SA MUST be deleted + * - DESTROY_ME if initialization failed */ - status_t (*initiate) (ike_sa_t *this, connection_t *connection, policy_t *policy); + status_t (*initiate) (ike_sa_t *this, child_cfg_t *child_cfg); /** * @brief Route a policy in the kernel. @@ -290,28 +287,26 @@ struct ike_sa_t { * the kernel requests connection setup from the IKE_SA via acquire(). * * @param this calling object - * @param connection connection definition used for routing - * @param policy policy to route + * @param child_cfg child config to route * @return * - SUCCESS if routed successfully * - FAILED if routing failed */ - status_t (*route) (ike_sa_t *this, connection_t *connection, policy_t *policy); + status_t (*route) (ike_sa_t *this, child_cfg_t *child_cfg); /** * @brief Unroute a policy in the kernel previously routed. * * @param this calling object - * @param policy policy to route + * @param child_cfg child config to unroute * @return * - SUCCESS if route removed - * - DESTROY_ME if last route was removed from - * an IKE_SA which was not established + * - DESTROY_ME if last CHILD_SA was unrouted */ - status_t (*unroute) (ike_sa_t *this, policy_t *policy); + status_t (*unroute) (ike_sa_t *this, child_cfg_t *child_cfg); /** - * @brief Acquire connection setup for a policy. + * @brief 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). @@ -320,7 +315,7 @@ struct ike_sa_t { * @param reqid reqid of the CHILD_SA the policy belongs to. * @return * - SUCCESS if initialization started - * - DESTROY_ME if initialization failed and IKE_SA MUST be deleted + * - DESTROY_ME if initialization failed */ status_t (*acquire) (ike_sa_t *this, u_int32_t reqid); diff --git a/src/charon/sa/ike_sa_manager.c b/src/charon/sa/ike_sa_manager.c index 791ef805e..287f049d3 100644 --- a/src/charon/sa/ike_sa_manager.c +++ b/src/charon/sa/ike_sa_manager.c @@ -363,6 +363,7 @@ static ike_sa_t *checkout_new(private_ike_sa_manager_t* this, bool initiator) pthread_mutex_unlock(&this->mutex); DBG2(DBG_MGR, "created IKE_SA: %J, %d IKE_SAs in manager", id, this->ike_sa_list->get_count(this->ike_sa_list)); + id->destroy(id); return entry->ike_sa; } diff --git a/src/charon/sa/task_manager.c b/src/charon/sa/task_manager.c index 844300735..cbdc67837 100644 --- a/src/charon/sa/task_manager.c +++ b/src/charon/sa/task_manager.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include typedef struct exchange_t exchange_t; @@ -577,7 +577,7 @@ static status_t process_request(private_task_manager_t *this, this->passive_tasks->insert_last(this->passive_tasks, task); task = (task_t*)ike_auth_create(this->ike_sa, FALSE); this->passive_tasks->insert_last(this->passive_tasks, task); - task = (task_t*)ike_config_create(this->ike_sa, NULL); + 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); this->passive_tasks->insert_last(this->passive_tasks, task); diff --git a/src/charon/sa/tasks/child_create.c b/src/charon/sa/tasks/child_create.c index 781d679f2..5ed9791ab 100644 --- a/src/charon/sa/tasks/child_create.c +++ b/src/charon/sa/tasks/child_create.c @@ -64,9 +64,9 @@ struct private_child_create_t { chunk_t other_nonce; /** - * policy to create the CHILD_SA from + * config to create the CHILD_SA from */ - policy_t *policy; + child_cfg_t *config; /** * list of proposal candidates @@ -198,7 +198,7 @@ static status_t select_and_install(private_child_create_t *this) my_vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE); other_vip = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE); - this->proposal = this->policy->select_proposal(this->policy, this->proposals); + this->proposal = this->config->select_proposal(this->config, this->proposals); if (this->proposal == NULL) { @@ -206,28 +206,31 @@ static status_t select_and_install(private_child_create_t *this) return FAILED; } - if (this->initiator && my_vip) - { /* if we have a virtual IP, shorten our TS to the minimum */ - my_ts = this->policy->select_my_traffic_selectors(this->policy, my_ts, - my_vip); + if (my_vip == NULL) + { + my_vip = me; + } + else if (this->initiator) + { /* to setup firewall rules correctly, CHILD_SA needs the virtual IP */ this->child_sa->set_virtual_ip(this->child_sa, my_vip); } - else - { /* shorten in the host2host case only */ - my_ts = this->policy->select_my_traffic_selectors(this->policy, - my_ts, me); + if (other_vip == NULL) + { + other_vip = other; } - if (other_vip) - { /* if other has a virtual IP, shorten it's traffic selectors to it */ - other_ts = this->policy->select_other_traffic_selectors(this->policy, - other_ts, other_vip); - } - else - { /* use his host for the host2host case */ - other_ts = this->policy->select_other_traffic_selectors(this->policy, - other_ts, other); + + my_ts = this->config->get_traffic_selectors(this->config, TRUE, my_ts, + my_vip); + other_ts = this->config->get_traffic_selectors(this->config, FALSE, other_ts, + other_vip); + + if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0) + { + SIG(CHILD_UP_FAILED, "no acceptable traffic selectors found"); + return FAILED; } + this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy)); this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy)); if (this->initiator) @@ -241,13 +244,6 @@ static status_t select_and_install(private_child_create_t *this) this->tsi = other_ts; } - if (this->tsi->get_count(this->tsi) == 0 || - this->tsr->get_count(this->tsr) == 0) - { - SIG(CHILD_UP_FAILED, "no acceptable traffic selectors found"); - return FAILED; - } - if (!this->initiator) { /* check if requested mode is acceptable, downgrade if required */ @@ -421,6 +417,7 @@ static void process_payloads(private_child_create_t *this, message_t *message) static status_t build_i(private_child_create_t *this, message_t *message) { host_t *me, *other, *vip; + peer_cfg_t *peer_cfg; switch (message->get_exchange_type(message)) { @@ -448,25 +445,29 @@ static status_t build_i(private_child_create_t *this, message_t *message) me = this->ike_sa->get_my_host(this->ike_sa); other = this->ike_sa->get_other_host(this->ike_sa); - vip = this->policy->get_virtual_ip(this->policy, NULL); + peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); + vip = peer_cfg->get_virtual_ip(peer_cfg, NULL); if (vip) { /* propose a 0.0.0.0/0 subnet when we use virtual ip */ - this->tsi = this->policy->get_my_traffic_selectors(this->policy, NULL); + this->tsi = this->config->get_traffic_selectors(this->config, TRUE, + NULL, NULL); vip->destroy(vip); } else { /* but shorten a 0.0.0.0/0 subnet to the actual address if host2host */ - this->tsi = this->policy->get_my_traffic_selectors(this->policy, me); + this->tsi = this->config->get_traffic_selectors(this->config, TRUE, + NULL, me); } - this->tsr = this->policy->get_other_traffic_selectors(this->policy, other); - this->proposals = this->policy->get_proposals(this->policy); - this->mode = this->policy->get_mode(this->policy); + this->tsr = this->config->get_traffic_selectors(this->config, FALSE, + NULL, other); + this->proposals = this->config->get_proposals(this->config); + this->mode = this->config->get_mode(this->config); this->child_sa = child_sa_create(me, other, this->ike_sa->get_my_id(this->ike_sa), this->ike_sa->get_other_id(this->ike_sa), - this->policy, this->reqid, + this->config, this->reqid, this->ike_sa->is_natt_enabled(this->ike_sa)); if (this->child_sa->alloc(this->child_sa, this->proposals) != SUCCESS) @@ -492,6 +493,8 @@ static status_t build_i(private_child_create_t *this, message_t *message) */ static status_t process_r(private_child_create_t *this, message_t *message) { + peer_cfg_t *peer_cfg; + switch (message->get_exchange_type(message)) { case IKE_SA_INIT: @@ -517,18 +520,13 @@ static status_t process_r(private_child_create_t *this, message_t *message) return NEED_MORE; } - this->policy = charon->policies->get_policy(charon->policies, - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa), - this->tsr, this->tsi, - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa)); - - if (this->policy && this->ike_sa->get_policy(this->ike_sa) == NULL) + peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); + if (peer_cfg) { - this->ike_sa->set_policy(this->ike_sa, this->policy); + this->config = peer_cfg->select_child_cfg(peer_cfg, this->tsr, this->tsi, + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa)); } - return NEED_MORE; } @@ -565,10 +563,11 @@ static status_t build_r(private_child_create_t *this, message_t *message) return SUCCESS; } - if (this->policy == NULL) + if (this->config == NULL) { - SIG(CHILD_UP_FAILED, "no acceptable policy found"); - message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty); + SIG(CHILD_UP_FAILED, "traffic selectors %#R=== %#R inacceptable", + this->tsr, this->tsi); + message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty); return SUCCESS; } @@ -576,12 +575,12 @@ static status_t build_r(private_child_create_t *this, message_t *message) this->ike_sa->get_other_host(this->ike_sa), this->ike_sa->get_my_id(this->ike_sa), this->ike_sa->get_other_id(this->ike_sa), - this->policy, this->reqid, + this->config, this->reqid, this->ike_sa->is_natt_enabled(this->ike_sa)); if (select_and_install(this) != SUCCESS) { - message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty); + message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty); return SUCCESS; } @@ -756,14 +755,14 @@ static void destroy(private_child_create_t *this) this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy)); } - DESTROY_IF(this->policy); + DESTROY_IF(this->config); free(this); } /* * Described in header. */ -child_create_t *child_create_create(ike_sa_t *ike_sa, policy_t *policy) +child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config) { private_child_create_t *this = malloc_thing(private_child_create_t); @@ -773,12 +772,12 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, policy_t *policy) 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 (policy) + if (config) { this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; this->initiator = TRUE; - policy->get_ref(policy); + config->get_ref(config); } else { @@ -788,7 +787,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, policy_t *policy) } this->ike_sa = ike_sa; - this->policy = policy; + this->config = config; this->my_nonce = chunk_empty; this->other_nonce = chunk_empty; this->proposals = NULL; diff --git a/src/charon/sa/tasks/child_create.h b/src/charon/sa/tasks/child_create.h index 200d37457..9f4815215 100644 --- a/src/charon/sa/tasks/child_create.h +++ b/src/charon/sa/tasks/child_create.h @@ -28,7 +28,7 @@ typedef struct child_create_t child_create_t; #include #include #include -#include +#include /** * @brief Task of type CHILD_CREATE, established a new CHILD_SA. @@ -80,9 +80,9 @@ struct child_create_t { * @brief Create a new child_create task. * * @param ike_sa IKE_SA this task works for - * @param policy policy if task initiator, NULL if responder + * @param config child_cfg if task initiator, NULL if responder * @return child_create task to handle by the task_manager */ -child_create_t *child_create_create(ike_sa_t *ike_sa, policy_t *policy); +child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config); #endif /* CHILD_CREATE_H_ */ diff --git a/src/charon/sa/tasks/child_rekey.c b/src/charon/sa/tasks/child_rekey.c index 745895dbb..af0e4d3b5 100644 --- a/src/charon/sa/tasks/child_rekey.c +++ b/src/charon/sa/tasks/child_rekey.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include typedef struct private_child_rekey_t private_child_rekey_t; @@ -315,8 +315,8 @@ static void destroy(private_child_rekey_t *this) */ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, child_sa_t *child_sa) { + child_cfg_t *config; private_child_rekey_t *this = malloc_thing(private_child_rekey_t); - policy_t *policy; this->public.collide = (void (*)(child_rekey_t*,task_t*))collide; this->public.task.get_type = (task_type_t(*)(task_t*))get_type; @@ -327,8 +327,8 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, child_sa_t *child_sa) this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; this->initiator = TRUE; - policy = child_sa->get_policy(child_sa); - this->child_create = child_create_create(ike_sa, policy); + config = child_sa->get_config(child_sa); + this->child_create = child_create_create(ike_sa, config); } else { diff --git a/src/charon/sa/tasks/ike_auth.c b/src/charon/sa/tasks/ike_auth.c index 541e1bb37..fa4b6a45e 100644 --- a/src/charon/sa/tasks/ike_auth.c +++ b/src/charon/sa/tasks/ike_auth.c @@ -100,18 +100,18 @@ static status_t build_auth(private_ike_auth_t *this, message_t *message) { authenticator_t *auth; auth_payload_t *auth_payload; - policy_t *policy; + peer_cfg_t *config; auth_method_t method; status_t status; /* create own authenticator and add auth payload */ - policy = this->ike_sa->get_policy(this->ike_sa); - if (!policy) + config = this->ike_sa->get_peer_cfg(this->ike_sa); + if (!config) { - SIG(IKE_UP_FAILED, "unable to authenticate, no policy found"); + SIG(IKE_UP_FAILED, "unable to authenticate, no peer config found"); return FAILED; } - method = policy->get_auth_method(policy); + method = config->get_auth_method(config); auth = authenticator_create(this->ike_sa, method); if (auth == NULL) @@ -140,15 +140,15 @@ static status_t build_id(private_ike_auth_t *this, message_t *message) { identification_t *me, *other; id_payload_t *id; - policy_t *policy; + peer_cfg_t *config; me = this->ike_sa->get_my_id(this->ike_sa); other = this->ike_sa->get_other_id(this->ike_sa); - policy = this->ike_sa->get_policy(this->ike_sa); + config = this->ike_sa->get_peer_cfg(this->ike_sa); if (me->contains_wildcards(me)) { - me = policy->get_my_id(policy); + me = config->get_my_id(config); if (me->contains_wildcards(me)) { SIG(IKE_UP_FAILED, "negotiation of own ID failed"); @@ -459,7 +459,7 @@ static status_t build_eap_r(private_ike_auth_t *this, message_t *message) */ static status_t build_i(private_ike_auth_t *this, message_t *message) { - policy_t *policy; + peer_cfg_t *config; if (message->get_exchange_type(message) == IKE_SA_INIT) { @@ -471,8 +471,8 @@ static status_t build_i(private_ike_auth_t *this, message_t *message) return FAILED; } - policy = this->ike_sa->get_policy(this->ike_sa); - if (policy->get_auth_method(policy) == AUTH_EAP) + config = this->ike_sa->get_peer_cfg(this->ike_sa); + if (config->get_auth_method(config) == AUTH_EAP) { this->eap_auth = eap_authenticator_create(this->ike_sa); } @@ -491,7 +491,9 @@ static status_t build_i(private_ike_auth_t *this, message_t *message) * Implementation of task_t.process for initiator */ static status_t process_r(private_ike_auth_t *this, message_t *message) -{ +{ + peer_cfg_t *config; + if (message->get_exchange_type(message) == IKE_SA_INIT) { return collect_other_init_data(this, message); @@ -502,6 +504,15 @@ static status_t process_r(private_ike_auth_t *this, message_t *message) return NEED_MORE; } + config = charon->cfg_store->get_peer_cfg(charon->cfg_store, + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa)); + if (config) + { + this->ike_sa->set_peer_cfg(this->ike_sa, config); + config->destroy(config); + } + switch (process_auth(this, message)) { case SUCCESS: @@ -522,7 +533,7 @@ static status_t process_r(private_ike_auth_t *this, message_t *message) */ static status_t build_r(private_ike_auth_t *this, message_t *message) { - policy_t *policy; + peer_cfg_t *config; eap_type_t eap_type; eap_payload_t *eap_payload; status_t status; @@ -532,10 +543,12 @@ static status_t build_r(private_ike_auth_t *this, message_t *message) return collect_my_init_data(this, message); } - policy = this->ike_sa->get_policy(this->ike_sa); - if (policy == NULL) + config = this->ike_sa->get_peer_cfg(this->ike_sa); + if (config == NULL) { - SIG(IKE_UP_FAILED, "no acceptable policy found"); + SIG(IKE_UP_FAILED, "no acceptable peer 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); return FAILED; } @@ -567,7 +580,7 @@ static status_t build_r(private_ike_auth_t *this, message_t *message) } /* initiate EAP authenitcation */ - eap_type = policy->get_eap_type(policy); + eap_type = config->get_eap_type(config); status = this->eap_auth->initiate(this->eap_auth, eap_type, &eap_payload); message->add_payload(message, (payload_t*)eap_payload); if (status != NEED_MORE) diff --git a/src/charon/sa/tasks/ike_cert.c b/src/charon/sa/tasks/ike_cert.c index 160600742..ff1143e50 100644 --- a/src/charon/sa/tasks/ike_cert.c +++ b/src/charon/sa/tasks/ike_cert.c @@ -171,20 +171,20 @@ static void process_certs(private_ike_cert_t *this, message_t *message) */ static void build_certreqs(private_ike_cert_t *this, message_t *message) { - connection_t *connection; - policy_t *policy; + ike_cfg_t *ike_cfg; + peer_cfg_t *peer_cfg; identification_t *ca; certreq_payload_t *certreq; - connection = this->ike_sa->get_connection(this->ike_sa); + ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa); - if (connection->get_certreq_policy(connection) != CERT_NEVER_SEND) + if (ike_cfg->send_certreq(ike_cfg) != CERT_NEVER_SEND) { - policy = this->ike_sa->get_policy(this->ike_sa); + peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); - if (policy) + if (peer_cfg) { - ca = policy->get_other_ca(policy); + ca = peer_cfg->get_other_ca(peer_cfg); if (ca && ca->get_type(ca) != ID_ANY) { @@ -212,17 +212,15 @@ static void build_certreqs(private_ike_cert_t *this, message_t *message) */ static void build_certs(private_ike_cert_t *this, message_t *message) { - policy_t *policy; - connection_t *connection; + peer_cfg_t *peer_cfg; x509_t *cert; cert_payload_t *payload; - policy = this->ike_sa->get_policy(this->ike_sa); - connection = this->ike_sa->get_connection(this->ike_sa); + peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); - if (policy && policy->get_auth_method(policy) == AUTH_RSA) + if (peer_cfg && peer_cfg->get_auth_method(peer_cfg) == AUTH_RSA) { - switch (connection->get_cert_policy(connection)) + switch (peer_cfg->get_cert_policy(peer_cfg)) { case CERT_NEVER_SEND: break; @@ -236,7 +234,7 @@ static void build_certs(private_ike_cert_t *this, message_t *message) { /* TODO: respect CA cert request */ cert = charon->credentials->get_certificate(charon->credentials, - policy->get_my_id(policy)); + peer_cfg->get_my_id(peer_cfg)); if (cert) { payload = cert_payload_create_from_x509(cert); diff --git a/src/charon/sa/tasks/ike_config.c b/src/charon/sa/tasks/ike_config.c index ce29b9220..0fc35013b 100644 --- a/src/charon/sa/tasks/ike_config.c +++ b/src/charon/sa/tasks/ike_config.c @@ -48,11 +48,6 @@ struct private_ike_config_t { */ bool initiator; - /** - * associated policy with virtual IP configuration - */ - policy_t *policy; - /** * virtual ip */ @@ -266,7 +261,8 @@ static status_t build_i(private_ike_config_t *this, message_t *message) if (message->get_exchange_type(message) == IKE_AUTH && message->get_payload(message, ID_INITIATOR)) { - this->virtual_ip = this->policy->get_virtual_ip(this->policy, NULL); + peer_cfg_t *config = this->ike_sa->get_peer_cfg(this->ike_sa); + this->virtual_ip = config->get_virtual_ip(config, NULL); build_payloads(this, message, CFG_REQUEST); } @@ -295,14 +291,14 @@ static status_t build_r(private_ike_config_t *this, message_t *message) if (message->get_exchange_type(message) == IKE_AUTH && message->get_payload(message, EXTENSIBLE_AUTHENTICATION) == NULL) { - this->policy = this->ike_sa->get_policy(this->ike_sa); + peer_cfg_t *config = this->ike_sa->get_peer_cfg(this->ike_sa); - if (this->policy && this->virtual_ip) + if (config && this->virtual_ip) { host_t *ip; DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip); - ip = this->policy->get_virtual_ip(this->policy, this->virtual_ip); + ip = config->get_virtual_ip(config, this->virtual_ip); if (ip == NULL || ip->is_anyaddr(ip)) { DBG1(DBG_IKE, "not assigning a virtual IP to peer"); @@ -398,7 +394,7 @@ static void destroy(private_ike_config_t *this) /* * Described in header. */ -ike_config_t *ike_config_create(ike_sa_t *ike_sa, policy_t *policy) +ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator) { private_ike_config_t *this = malloc_thing(private_ike_config_t); @@ -406,21 +402,18 @@ ike_config_t *ike_config_create(ike_sa_t *ike_sa, policy_t *policy) this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; this->public.task.destroy = (void(*)(task_t*))destroy; - if (policy) + if (initiator) { this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; - this->initiator = TRUE; } else { this->public.task.build = (status_t(*)(task_t*,message_t*))build_r; this->public.task.process = (status_t(*)(task_t*,message_t*))process_r; - this->initiator = FALSE; } - + this->initiator = initiator; this->ike_sa = ike_sa; - this->policy = policy; this->virtual_ip = NULL; this->dns = linked_list_create(); diff --git a/src/charon/sa/tasks/ike_config.h b/src/charon/sa/tasks/ike_config.h index 0c9b961b4..a7cfddff0 100644 --- a/src/charon/sa/tasks/ike_config.h +++ b/src/charon/sa/tasks/ike_config.h @@ -28,7 +28,6 @@ typedef struct ike_config_t ike_config_t; #include #include #include -#include /** * @brief Task of type IKE_CONFIG, sets up a virtual IP and other @@ -51,9 +50,9 @@ struct ike_config_t { * @brief Create a new ike_config task. * * @param ike_sa IKE_SA this task works for - * @param policy policy for the initiator, NULL for the responder + * @param initiator TRUE for initiator * @return ike_config task to handle by the task_manager */ -ike_config_t *ike_config_create(ike_sa_t *ike_sa, policy_t *policy); +ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator); #endif /* IKE_CONFIG_H_ */ diff --git a/src/charon/sa/tasks/ike_delete.c b/src/charon/sa/tasks/ike_delete.c index 9c4fdac0e..68fdb7bd9 100644 --- a/src/charon/sa/tasks/ike_delete.c +++ b/src/charon/sa/tasks/ike_delete.c @@ -28,7 +28,7 @@ typedef struct private_ike_delete_t private_ike_delete_t; -/** +/**file * Private members of a ike_delete_t task. */ struct private_ike_delete_t { diff --git a/src/charon/sa/tasks/ike_init.c b/src/charon/sa/tasks/ike_init.c index 0b493666a..8165a01a2 100644 --- a/src/charon/sa/tasks/ike_init.c +++ b/src/charon/sa/tasks/ike_init.c @@ -57,9 +57,9 @@ struct private_ike_init_t { bool initiator; /** - * Connection established by this IKE_SA + * IKE config to establish */ - connection_t *connection; + ike_cfg_t *config; /** * diffie hellman group to use @@ -117,11 +117,11 @@ static void build_payloads(private_ike_init_t *this, message_t *message) id = this->ike_sa->get_id(this->ike_sa); - this->connection = this->ike_sa->get_connection(this->ike_sa); + this->config = this->ike_sa->get_ike_cfg(this->ike_sa); if (this->initiator) { - proposal_list = this->connection->get_proposals(this->connection); + proposal_list = this->config->get_proposals(this->config); if (this->old_sa) { /* include SPI of new IKE_SA when we are rekeying */ @@ -174,8 +174,8 @@ static void process_payloads(private_ike_init_t *this, message_t *message) linked_list_t *proposal_list; proposal_list = sa_payload->get_proposals(sa_payload); - this->proposal = this->connection->select_proposal( - this->connection, proposal_list); + this->proposal = this->config->select_proposal(this->config, + proposal_list); proposal_list->destroy_offset(proposal_list, offsetof(proposal_t, destroy)); break; @@ -200,8 +200,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message) else { this->dh_group = dh_group; - if (!this->connection->check_dh_group(this->connection, - dh_group)) + if (!this->config->check_dh_group(this->config, dh_group)) { break; } @@ -235,9 +234,9 @@ static status_t build_i(private_ike_init_t *this, message_t *message) randomizer_t *randomizer; status_t status; - this->connection = this->ike_sa->get_connection(this->ike_sa); + this->config = this->ike_sa->get_ike_cfg(this->ike_sa); SIG(IKE_UP_START, "initiating IKE_SA to %H", - this->connection->get_other_host(this->connection)); + this->config->get_other_host(this->config)); this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING); if (this->retry++ >= MAX_RETRIES) @@ -249,7 +248,7 @@ static status_t build_i(private_ike_init_t *this, message_t *message) /* if the DH group is set via use_dh_group(), we already have a DH object */ if (!this->diffie_hellman) { - this->dh_group = this->connection->get_dh_group(this->connection); + this->dh_group = this->config->get_dh_group(this->config); this->diffie_hellman = diffie_hellman_create(this->dh_group); if (this->diffie_hellman == NULL) { @@ -291,7 +290,7 @@ static status_t process_r(private_ike_init_t *this, message_t *message) { randomizer_t *randomizer; - this->connection = this->ike_sa->get_connection(this->ike_sa); + this->config = this->ike_sa->get_ike_cfg(this->ike_sa); SIG(IKE_UP_FAILED, "%H is initiating an IKE_SA", message->get_source(message)); this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING); @@ -335,7 +334,7 @@ static status_t build_r(private_ike_init_t *this, message_t *message) SIG(IKE_UP_FAILED, "received inacceptable DH group (%N)", diffie_hellman_group_names, this->dh_group); - this->dh_group = this->connection->get_dh_group(this->connection); + this->dh_group = this->config->get_dh_group(this->config); dh_enc = htons(this->dh_group); chunk.ptr = (u_int8_t*)&dh_enc; chunk.len = sizeof(dh_enc); @@ -414,8 +413,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message) DBG1(DBG_IKE, "peer didn't accept DH group %N, it requested" " %N", diffie_hellman_group_names, old_dh_group, diffie_hellman_group_names, this->dh_group); - if (!this->connection->check_dh_group(this->connection, - this->dh_group)) + if (!this->config->check_dh_group(this->config, this->dh_group)) { DBG1(DBG_IKE, "requested DH group %N not acceptable, " "giving up", diffie_hellman_group_names, @@ -590,7 +588,7 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa) this->other_nonce = chunk_empty; this->cookie = chunk_empty; this->proposal = NULL; - this->connection = NULL; + this->config = NULL; this->old_sa = old_sa; this->retry = 0; diff --git a/src/charon/sa/tasks/ike_rekey.c b/src/charon/sa/tasks/ike_rekey.c index a33e7ee34..04dd229ea 100644 --- a/src/charon/sa/tasks/ike_rekey.c +++ b/src/charon/sa/tasks/ike_rekey.c @@ -26,8 +26,8 @@ #include #include #include -#include -#include +#include +#include typedef struct private_ike_rekey_t private_ike_rekey_t; @@ -73,20 +73,15 @@ struct private_ike_rekey_t { */ static status_t build_i(private_ike_rekey_t *this, message_t *message) { - connection_t *connection; - policy_t *policy; + peer_cfg_t *peer_cfg; this->new_sa = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, TRUE); - connection = this->ike_sa->get_connection(this->ike_sa); - policy = this->ike_sa->get_policy(this->ike_sa); - this->new_sa->set_connection(this->new_sa, connection); - this->new_sa->set_policy(this->new_sa, policy); - + peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); + this->new_sa->set_peer_cfg(this->new_sa, peer_cfg); this->ike_init = ike_init_create(this->new_sa, TRUE, this->ike_sa); this->ike_init->task.build(&this->ike_init->task, message); - this->ike_sa->set_state(this->ike_sa, IKE_REKEYING); return NEED_MORE; @@ -97,8 +92,7 @@ static status_t build_i(private_ike_rekey_t *this, message_t *message) */ static status_t process_r(private_ike_rekey_t *this, message_t *message) { - connection_t *connection; - policy_t *policy; + peer_cfg_t *peer_cfg; iterator_t *iterator; child_sa_t *child_sa; @@ -129,11 +123,8 @@ static status_t process_r(private_ike_rekey_t *this, message_t *message) this->new_sa = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, FALSE); - connection = this->ike_sa->get_connection(this->ike_sa); - policy = this->ike_sa->get_policy(this->ike_sa); - this->new_sa->set_connection(this->new_sa, connection); - this->new_sa->set_policy(this->new_sa, policy); - + peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); + this->new_sa->set_peer_cfg(this->new_sa, peer_cfg); this->ike_init = ike_init_create(this->new_sa, FALSE, this->ike_sa); this->ike_init->task.process(&this->ike_init->task, message); diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c index 8cbfd6ab8..68e9c9500 100644 --- a/src/libstrongswan/utils/host.c +++ b/src/libstrongswan/utils/host.c @@ -325,7 +325,7 @@ static bool equals(private_host_t *this, private_host_t *other) { if (!ip_equals(this, other)) { - return FAILED; + return FALSE; } switch (this->address.sa_family)