diff options
Diffstat (limited to 'src/charon/sa/transactions/ike_auth.c')
-rw-r--r-- | src/charon/sa/transactions/ike_auth.c | 1562 |
1 files changed, 0 insertions, 1562 deletions
diff --git a/src/charon/sa/transactions/ike_auth.c b/src/charon/sa/transactions/ike_auth.c deleted file mode 100644 index bf7fd6d12..000000000 --- a/src/charon/sa/transactions/ike_auth.c +++ /dev/null @@ -1,1562 +0,0 @@ -/** - * @file ike_auth.c - * - * @brief Implementation of ike_auth_t transaction. - * - */ - -/* - * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include "ike_auth.h" - -#include <string.h> - -#include <daemon.h> -#include <encoding/payloads/sa_payload.h> -#include <encoding/payloads/id_payload.h> -#include <encoding/payloads/cert_payload.h> -#include <encoding/payloads/certreq_payload.h> -#include <encoding/payloads/auth_payload.h> -#include <encoding/payloads/ts_payload.h> -#include <sa/authenticators/authenticator.h> -#include <sa/authenticators/eap_authenticator.h> -#include <sa/child_sa.h> - - -typedef struct private_ike_auth_t private_ike_auth_t; - -/** - * Private members of a ike_auth_t object.. - */ -struct private_ike_auth_t { - - /** - * Public methods and transaction_t interface. - */ - ike_auth_t public; - - /** - * Assigned IKE_SA. - */ - ike_sa_t *ike_sa; - - /** - * Message sent by our peer, if already generated - */ - message_t *message; - - /** - * Message ID this transaction uses - */ - u_int32_t message_id; - - /** - * Times we did send the request - */ - u_int32_t requested; - - /** - * initiator chosen nonce - */ - chunk_t nonce_i; - - /** - * responder chosen nonce - */ - chunk_t nonce_r; - - /** - * encoded request message of ike_sa_init transaction - */ - chunk_t init_request; - - /** - * encoded response message of ike_sa_init transaction - */ - chunk_t init_response; - - /** - * connection definition used for IKE_SA setup - */ - connection_t *connection; - - /** - * policy definition used CHILD_SA creation - */ - policy_t *policy; - - /** - * Negotiated proposal used for CHILD_SA - */ - proposal_t *proposal; - - /** - * Negotiated traffic selectors for initiator - */ - linked_list_t *tsi; - - /** - * Negotiated traffic selectors for responder - */ - linked_list_t *tsr; - - /** - * CHILD_SA created along with IKE_AUTH - */ - child_sa_t *child_sa; - - /** - * did other peer create a CHILD_SA? - */ - bool build_child; - - /** - * reqid to use for CHILD_SA setup - */ - u_int32_t reqid; - - /** - * List of CA certificates the other peer trusts - */ - linked_list_t *cacerts; - - /** - * EAP uses this authentication, which is passed along multiple ike_auths - */ - eap_authenticator_t *eap_auth; - - /** - * if the client receives a EAP request, it is stored here for later use - */ - eap_payload_t *eap_next; - - /** - * set to TRUE if authentication should be done with EAP only - */ - bool eap_only; - - /** - * has the other peer been authenticated yet? - */ - bool peer_authenticated; - - /** - * mode the CHILD_SA uses: tranport, tunnel, BEET - */ - mode_t mode; -}; - -/** - * Implementation of transaction_t.get_message_id. - */ -static u_int32_t get_message_id(private_ike_auth_t *this) -{ - return this->message_id; -} - -/** - * Implementation of transaction_t.requested. - */ -static u_int32_t requested(private_ike_auth_t *this) -{ - return this->requested++; -} - -/** - * Implementation of transaction_t.set_config. - */ -static void set_config(private_ike_auth_t *this, - connection_t *connection, policy_t *policy) -{ - this->connection = connection; - this->policy = policy; -} - -/** - * Implementation of transaction_t.set_reqid. - */ -static void set_reqid(private_ike_auth_t *this, u_int32_t reqid) -{ - this->reqid = reqid; -} - -/** - * Implementation of transaction_t.set_nonces. - */ -static void set_nonces(private_ike_auth_t *this, chunk_t nonce_i, chunk_t nonce_r) -{ - this->nonce_i = nonce_i; - this->nonce_r = nonce_r; -} - -/** - * Implementation of transaction_t.set_init_messages. - */ -static void set_init_messages(private_ike_auth_t *this, chunk_t init_request, chunk_t init_response) -{ - this->init_request = init_request; - this->init_response = init_response; -} - -/** - * Build a notify message. - */ -static void build_notify(notify_type_t type, message_t *message, bool flush_message) -{ - notify_payload_t *notify; - - if (flush_message) - { - payload_t *payload; - iterator_t *iterator = message->get_payload_iterator(message); - while (iterator->iterate(iterator, (void**)&payload)) - { - payload->destroy(payload); - iterator->remove(iterator); - } - iterator->destroy(iterator); - } - - notify = notify_payload_create(); - notify->set_notify_type(notify, type); - message->add_payload(message, (payload_t*)notify); -} - -/** - * Implementation of transaction_t.get_request. - */ -static status_t get_request(private_ike_auth_t *this, message_t **result) -{ - message_t *request; - host_t *me, *other; - identification_t *my_id, *other_id; - id_payload_t *my_id_payload; - - /* check if we already have built a message (retransmission) */ - if (this->message) - { - *result = this->message; - return SUCCESS; - } - - me = this->ike_sa->get_my_host(this->ike_sa); - other = this->ike_sa->get_other_host(this->ike_sa); - my_id = this->policy->get_my_id(this->policy); - other_id = this->policy->get_other_id(this->policy); - - /* build the request */ - request = message_create(); - request->set_source(request, me->clone(me)); - request->set_destination(request, other->clone(other)); - request->set_exchange_type(request, IKE_AUTH); - request->set_request(request, TRUE); - request->set_ike_sa_id(request, this->ike_sa->get_id(this->ike_sa)); - /* apply for caller */ - *result = request; - /* store for retransmission */ - this->message = request; - - this->message_id = this->ike_sa->get_next_message_id(this->ike_sa); - request->set_message_id(request, this->message_id); - - if (this->eap_auth) - { - /* we already sent ID, SA, TS in an earlier ike_auth, we now - * continiue EAP processing */ - if (this->eap_next) - { - /* if we have another outstanding EAP response, send it */ - request->add_payload(request, (payload_t*)this->eap_next); - this->eap_next = NULL; - return SUCCESS; - } - else - { - /* if not, we have received an EAP_SUCCESS, send AUTH payload. - * we only send our data if: - * a) The peer has been authenticated using RSA/PSK, or - * b) The EAP method is mutual and gives us enough security - */ - if (this->eap_auth->is_mutual(this->eap_auth) || - this->peer_authenticated) - { - auth_payload_t *auth_payload; - authenticator_t *authenticator = (authenticator_t*)this->eap_auth; - - if (authenticator->build(authenticator, this->init_request, - this->nonce_r, &auth_payload) != SUCCESS) - { - SIG(IKE_UP_FAILED, - "EAP authentication data generation failed, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, - "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - request->add_payload(request, (payload_t*)auth_payload); - return SUCCESS; - } - else - { - SIG(IKE_UP_FAILED, - "peer didn't send authentication data, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, - "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - } - } - /* otherwise we do a normal ike_auth request... */ - - { /* build ID payload */ - my_id_payload = id_payload_create_from_identification(TRUE, my_id); - request->add_payload(request, (payload_t*)my_id_payload); - } - - /* build certificate request payload */ - if (this->connection->get_certreq_policy(this->connection) != CERT_NEVER_SEND) - { - certreq_payload_t *certreq_payload; - identification_t *other_ca = this->policy->get_other_ca(this->policy); - - if (other_ca) - { - if (other_ca->get_type(other_ca) == ID_ANY) - { - certreq_payload = certreq_payload_create_from_cacerts(); - } - else - { - certreq_payload = certreq_payload_create_from_cacert(other_ca); - } - if (certreq_payload != NULL) - { - request->add_payload(request, (payload_t*)certreq_payload); - } - } - } - - /* build certificate payload. TODO: Handle certreq from init_ike_sa. */ - if (this->policy->get_auth_method(this->policy) == AUTH_RSA && - this->connection->get_cert_policy(this->connection) != CERT_NEVER_SEND) - { - cert_payload_t *cert_payload; - - x509_t *cert = charon->credentials->get_certificate(charon->credentials, my_id); - - if (cert) - { - cert_payload = cert_payload_create_from_x509(cert); - request->add_payload(request, (payload_t*)cert_payload); - } - else - { - DBG1(DBG_IKE, "could not find my certificate, certificate payload omitted"); - } - } - - { /* build IDr payload, if other_id defined */ - id_payload_t *id_payload; - if (!other_id->contains_wildcards(other_id)) - { - id_payload = id_payload_create_from_identification(FALSE, other_id); - request->add_payload(request, (payload_t*)id_payload); - } - } - - if (this->policy->get_auth_method(this->policy) != AUTH_EAP) - { /* build auth payload */ - authenticator_t *authenticator; - auth_payload_t *auth_payload; - auth_method_t auth_method; - status_t status; - - auth_method = this->policy->get_auth_method(this->policy); - authenticator = authenticator_create(this->ike_sa, auth_method); - if (authenticator == NULL) - { - SIG(IKE_UP_FAILED, "auth method %N not supported, deleting IKE_SA", - auth_method_names, auth_method); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - status = authenticator->build(authenticator, this->init_request, - this->nonce_r, &auth_payload); - authenticator->destroy(authenticator); - if (status != SUCCESS) - { - SIG(IKE_UP_FAILED, "could not generate AUTH data, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - request->add_payload(request, (payload_t*)auth_payload); - } - else - { - this->eap_auth = eap_authenticator_create(this->ike_sa); - /* include notify that we support EAP only authentication */ - build_notify(EAP_ONLY_AUTHENTICATION, request, FALSE); - } - - { /* build SA payload for CHILD_SA */ - linked_list_t *proposal_list; - sa_payload_t *sa_payload; - u_int32_t soft_lifetime, hard_lifetime; - bool enable_natt; - - proposal_list = this->policy->get_proposals(this->policy); - soft_lifetime = this->policy->get_soft_lifetime(this->policy); - hard_lifetime = this->policy->get_hard_lifetime(this->policy); - enable_natt = this->ike_sa->is_natt_enabled(this->ike_sa); - this->child_sa = child_sa_create(this->reqid, me, other, my_id, other_id, - soft_lifetime, hard_lifetime, - this->policy->get_updown(this->policy), - this->policy->get_hostaccess(this->policy), - enable_natt); - this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy)); - if (this->child_sa->alloc(this->child_sa, proposal_list) != SUCCESS) - { - SIG(IKE_UP_FAILED, "could not install CHILD_SA, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - sa_payload = sa_payload_create_from_proposal_list(proposal_list); - proposal_list->destroy_offset(proposal_list, offsetof(proposal_t, destroy)); - request->add_payload(request, (payload_t*)sa_payload); - } - - /* notify for transport/BEET mode, we propose it - * independent of the traffic selectors */ - switch (this->policy->get_mode(this->policy)) - { - case MODE_TUNNEL: - /* is the default */ - break; - case MODE_TRANSPORT: - if (this->ike_sa->is_natt_enabled(this->ike_sa)) - { - DBG1(DBG_IKE, "not using tranport mode, as connection NATed"); - } - else - { - build_notify(USE_TRANSPORT_MODE, request, FALSE); - } - break; - case MODE_BEET: - build_notify(USE_BEET_MODE, request, FALSE); - break; - } - - { /* build TSi payload */ - linked_list_t *ts_list; - ts_payload_t *ts_payload; - - ts_list = this->policy->get_my_traffic_selectors(this->policy, me); - ts_payload = ts_payload_create_from_traffic_selectors(TRUE, ts_list); - ts_list->destroy_offset(ts_list, offsetof(traffic_selector_t, destroy)); - - request->add_payload(request, (payload_t*)ts_payload); - } - - { /* build TSr payload */ - linked_list_t *ts_list; - ts_payload_t *ts_payload; - - ts_list = this->policy->get_other_traffic_selectors(this->policy, other); - ts_payload = ts_payload_create_from_traffic_selectors(FALSE, ts_list); - ts_list->destroy_offset(ts_list, offsetof(traffic_selector_t, destroy)); - - request->add_payload(request, (payload_t*)ts_payload); - } - - return SUCCESS; -} - -/** - * Handle all kind of notifies - */ -static status_t process_notifies(private_ike_auth_t *this, notify_payload_t *notify_payload) -{ - notify_type_t notify_type = notify_payload->get_notify_type(notify_payload); - - DBG2(DBG_IKE, "process notify type %N", notify_type_names, notify_type); - - switch (notify_type) - { - /* these notifies are not critical. no child_sa is built, but IKE stays alive */ - case SINGLE_PAIR_REQUIRED: - { - SIG(CHILD_UP_FAILED, "received a SINGLE_PAIR_REQUIRED notify"); - this->build_child = FALSE; - return SUCCESS; - } - case TS_UNACCEPTABLE: - { - SIG(CHILD_UP_FAILED, "received TS_UNACCEPTABLE notify"); - this->build_child = FALSE; - return SUCCESS; - } - case NO_PROPOSAL_CHOSEN: - { - SIG(CHILD_UP_FAILED, "received NO_PROPOSAL_CHOSEN notify"); - this->build_child = FALSE; - return SUCCESS; - } - case EAP_ONLY_AUTHENTICATION: - { - DBG1(DBG_IKE, "peer requested EAP_ONLY_AUTHENTICATION"); - this->eap_only = TRUE; - return SUCCESS; - } - case USE_TRANSPORT_MODE: - { - this->mode = MODE_TRANSPORT; - return SUCCESS; - } - case USE_BEET_MODE: - { - this->mode = MODE_BEET; - return SUCCESS; - } - default: - { - if (notify_type < 16383) - { - SIG(IKE_UP_FAILED, "received %N notify error, deleting IKE_SA", - notify_type_names, notify_type); - return DESTROY_ME; - } - else - { - DBG1(DBG_IKE, "received %N notify, ignored", - notify_type_names, notify_type); - return SUCCESS; - } - } - } -} - -/** - * Import certificate requests from a certreq payload - */ -static void process_certificate_request(private_ike_auth_t *this, - certreq_payload_t *certreq_payload) -{ - chunk_t keyids; - cert_encoding_t encoding = certreq_payload->get_cert_encoding(certreq_payload); - - if (encoding != CERT_X509_SIGNATURE) - { - DBG1(DBG_IKE, "certreq payload %N not supported, ignored", - cert_encoding_names, encoding); - return; - } - - keyids = certreq_payload->get_data(certreq_payload); - while (keyids.len >= HASH_SIZE_SHA1) - { - chunk_t keyid = { keyids.ptr, HASH_SIZE_SHA1}; - x509_t *cacert = charon->credentials->get_ca_certificate_by_keyid( - charon->credentials, keyid); - if (cacert) - { - DBG2(DBG_IKE, "request for certificate issued by ca '%D'", - cacert->get_subject(cacert)); - this->cacerts->insert_last(this->cacerts, cacert); - } - else - { - DBG2(DBG_IKE, "request for certificate issued by unknown ca"); - } - DBG2(DBG_IKE, " with keyid %#B", &keyid); - - keyids.ptr += HASH_SIZE_SHA1; - keyids.len -= HASH_SIZE_SHA1; - } -} - -/** - * Import a certificate from a cert payload - */ -static void import_certificate(cert_payload_t *cert_payload) -{ - bool found; - x509_t *cert; - cert_encoding_t encoding; - - encoding = cert_payload->get_cert_encoding(cert_payload); - if (encoding != CERT_X509_SIGNATURE) - { - DBG1(DBG_IKE, "certificate payload %N not supported, ignored", - cert_encoding_names, encoding); - return; - } - cert = x509_create_from_chunk(cert_payload->get_data_clone(cert_payload)); - if (cert) - { - if (charon->credentials->verify(charon->credentials, cert, &found)) - { - DBG2(DBG_IKE, "received end entity certificate is trusted, added to store"); - if (!found) - { - charon->credentials->add_end_certificate(charon->credentials, cert); - } - else - { - cert->destroy(cert); - } - } - else - { - DBG1(DBG_IKE, "received end entity certificate is not trusted, discarded"); - cert->destroy(cert); - } - } - else - { - DBG1(DBG_IKE, "parsing of received certificate failed, discarded"); - } -} - -/** - * Check a list of traffic selectors if any selector belongs to host - */ -static bool ts_list_is_host(linked_list_t *list, host_t *host) -{ - traffic_selector_t *ts; - bool is_host = TRUE; - iterator_t *iterator = list->create_iterator(list, TRUE); - - while (is_host && iterator->iterate(iterator, (void**)&ts)) - { - is_host = is_host && ts->is_host(ts, host); - } - iterator->destroy(iterator); - return is_host; -} - -/** - * Install a CHILD_SA for usage - */ -static status_t install_child_sa(private_ike_auth_t *this, bool initiator) -{ - prf_plus_t *prf_plus; - chunk_t seed; - status_t status; - - seed = chunk_alloc(this->nonce_i.len + this->nonce_r.len); - memcpy(seed.ptr, this->nonce_i.ptr, this->nonce_i.len); - memcpy(seed.ptr + this->nonce_i.len, this->nonce_r.ptr, this->nonce_r.len); - prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed); - chunk_free(&seed); - - if (initiator) - { - status = this->child_sa->update(this->child_sa, this->proposal, - this->mode, prf_plus); - } - else - { - status = this->child_sa->add(this->child_sa, this->proposal, - this->mode, prf_plus); - } - prf_plus->destroy(prf_plus); - if (status != SUCCESS) - { - return DESTROY_ME; - } - if (initiator) - { - status = this->child_sa->add_policies(this->child_sa, this->tsi, - this->tsr, this->mode); - } - else - { - status = this->child_sa->add_policies(this->child_sa, this->tsr, - this->tsi, this->mode); - } - if (status != SUCCESS) - { - return DESTROY_ME; - } - - /* add to IKE_SA, and remove from transaction */ - this->child_sa->set_state(this->child_sa, CHILD_INSTALLED); - this->ike_sa->add_child_sa(this->ike_sa, this->child_sa); - this->child_sa = NULL; - return SUCCESS; -} - -/** - * create a CHILD SA, install it, and build response message - */ -static void setup_child_sa(private_ike_auth_t *this, message_t *response) -{ - bool use_natt; - u_int32_t soft_lifetime, hard_lifetime; - host_t *me, *other; - identification_t *my_id, *other_id; - - me = this->ike_sa->get_my_host(this->ike_sa); - other = this->ike_sa->get_other_host(this->ike_sa); - my_id = this->ike_sa->get_my_id(this->ike_sa); - other_id = this->ike_sa->get_other_id(this->ike_sa); - - soft_lifetime = this->policy->get_soft_lifetime(this->policy); - hard_lifetime = this->policy->get_hard_lifetime(this->policy); - use_natt = this->ike_sa->is_natt_enabled(this->ike_sa); - this->child_sa = child_sa_create(this->reqid, me, other, my_id, other_id, - soft_lifetime, hard_lifetime, - this->policy->get_updown(this->policy), - this->policy->get_hostaccess(this->policy), - use_natt); - this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy)); - /* check mode, and include notify into reply */ - switch (this->mode) - { - case MODE_TUNNEL: - /* is the default */ - break; - case MODE_TRANSPORT: - if (!ts_list_is_host(this->tsi, other) || - !ts_list_is_host(this->tsr, me)) - { - this->mode = MODE_TUNNEL; - DBG1(DBG_IKE, "not using tranport mode, not host-to-host"); - } - else if (this->ike_sa->is_natt_enabled(this->ike_sa)) - { - this->mode = MODE_TUNNEL; - DBG1(DBG_IKE, "not using tranport mode, as connection NATed"); - } - else - { - build_notify(USE_TRANSPORT_MODE, response, FALSE); - } - break; - case MODE_BEET: - if (!ts_list_is_host(this->tsi, NULL) || - !ts_list_is_host(this->tsr, NULL)) - { - this->mode = MODE_TUNNEL; - DBG1(DBG_IKE, "not using BEET mode, not host-to-host"); - } - else - { - build_notify(USE_BEET_MODE, response, FALSE); - } - break; - } - - if (install_child_sa(this, FALSE) != SUCCESS) - { - SIG(CHILD_UP_FAILED, "installing CHILD_SA %s failed, no CHILD_SA created", - this->policy->get_name(this->policy)); - DBG1(DBG_IKE, "adding NO_PROPOSAL_CHOSEN notify to response"); - build_notify(NO_PROPOSAL_CHOSEN, response, FALSE); - } - else - { - /* build SA and TS payloads */ - SIG(CHILD_UP_SUCCESS, "CHILD_SA created"); - ts_payload_t *ts_response; - sa_payload_t *sa_response = sa_payload_create(); - sa_response->add_proposal(sa_response, this->proposal); - response->add_payload(response, (payload_t*)sa_response); - ts_response = ts_payload_create_from_traffic_selectors(TRUE, this->tsi); - response->add_payload(response, (payload_t*)ts_response); - ts_response = ts_payload_create_from_traffic_selectors(FALSE, this->tsr); - response->add_payload(response, (payload_t*)ts_response); - } -} - -/** - * clone the transaction to requeue it for EAP handling - */ -static private_ike_auth_t *clone_for_eap(private_ike_auth_t *this) -{ - private_ike_auth_t *clone; - clone = (private_ike_auth_t*)ike_auth_create(this->ike_sa); - - clone->tsi = this->tsi; this->tsi = NULL; - clone->tsr = this->tsr; this->tsr = NULL; - clone->eap_auth = this->eap_auth; this->eap_auth = NULL; - clone->eap_next = this->eap_next; this->eap_next = NULL; - clone->build_child = this->build_child; - clone->nonce_i = this->nonce_i; this->nonce_i = chunk_empty; - clone->nonce_r = this->nonce_r; this->nonce_r = chunk_empty; - clone->child_sa = this->child_sa; this->child_sa = NULL; - clone->proposal = this->proposal; this->proposal = NULL; - clone->peer_authenticated = this->peer_authenticated; - clone->connection = this->connection; this->connection = NULL; - clone->policy = this->policy; this->policy = NULL; - - return clone; -} - -/** - * Implementation of transaction_t.get_response. - */ -static status_t get_response(private_ike_auth_t *this, message_t *request, - message_t **result, transaction_t **next) -{ - host_t *me, *other; - identification_t *my_id, *other_id; - message_t *response; - status_t status; - iterator_t *payloads; - payload_t *payload; - id_payload_t *idi_request = NULL; - id_payload_t *idr_request = NULL; - auth_payload_t *auth_request = NULL; - certreq_payload_t *certreq_request = NULL; - cert_payload_t *cert_request = NULL; - sa_payload_t *sa_request = NULL; - ts_payload_t *tsi_request = NULL; - ts_payload_t *tsr_request = NULL; - eap_payload_t *eap_request = NULL; - id_payload_t *idr_response; - - /* check if we already have built a response (retransmission) */ - if (this->message) - { - *result = this->message; - return SUCCESS; - } - - SIG(CHILD_UP_START, "setting up CHILD_SA along with IKE_AUTH"); - - me = this->ike_sa->get_my_host(this->ike_sa); - other = this->ike_sa->get_other_host(this->ike_sa); - my_id = this->ike_sa->get_my_id(this->ike_sa); - other_id = this->ike_sa->get_other_id(this->ike_sa); - this->message_id = request->get_message_id(request); - - /* set up response */ - response = message_create(); - response->set_source(response, me->clone(me)); - response->set_destination(response, other->clone(other)); - response->set_exchange_type(response, IKE_AUTH); - response->set_request(response, FALSE); - response->set_message_id(response, this->message_id); - response->set_ike_sa_id(response, this->ike_sa->get_id(this->ike_sa)); - this->message = response; - *result = response; - - /* check message type */ - if (request->get_exchange_type(request) != IKE_AUTH) - { - SIG(IKE_UP_FAILED, "IKE_AUTH response of invalid type, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - - /* Iterate over all payloads. */ - payloads = request->get_payload_iterator(request); - while (payloads->iterate(payloads, (void**)&payload)) - { - switch (payload->get_type(payload)) - { - case ID_INITIATOR: - idi_request = (id_payload_t*)payload; - break; - case ID_RESPONDER: - idr_request = (id_payload_t*)payload; - break; - case AUTHENTICATION: - auth_request = (auth_payload_t*)payload; - break; - case CERTIFICATE_REQUEST: - certreq_request = (certreq_payload_t*)payload; - process_certificate_request(this, certreq_request); - break; - case CERTIFICATE: - cert_request = (cert_payload_t*)payload; - break; - case SECURITY_ASSOCIATION: - sa_request = (sa_payload_t*)payload; - break; - case TRAFFIC_SELECTOR_INITIATOR: - tsi_request = (ts_payload_t*)payload; - break; - case TRAFFIC_SELECTOR_RESPONDER: - tsr_request = (ts_payload_t*)payload; - break; - case EXTENSIBLE_AUTHENTICATION: - eap_request = (eap_payload_t*)payload; - break; - case NOTIFY: - { - status = process_notifies(this, (notify_payload_t*)payload); - if (status == FAILED) - { - payloads->destroy(payloads); - /* we return SUCCESS, returned FAILED means do next transaction */ - return SUCCESS; - } - if (status == DESTROY_ME) - { - payloads->destroy(payloads); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - break; - } - default: - { - DBG1(DBG_IKE, "ignoring %N payload", - payload_type_names, payload->get_type(payload)); - break; - } - } - } - payloads->destroy(payloads); - - /* if message contains an EAP payload, we process it */ - if (eap_request && this->eap_auth) - { - eap_payload_t *eap_response; - private_ike_auth_t *next_auth; - - status = this->eap_auth->process(this->eap_auth, eap_request, &eap_response); - response->add_payload(response, (payload_t*)eap_response); - - if (status == FAILED) - { - /* shut down if EAP message is EAP_FAILURE */ - return DESTROY_ME; - } - - next_auth = clone_for_eap(this); - next_auth->message_id = this->message_id + 1; - *next = (transaction_t*)next_auth; - return SUCCESS; - } - - /* if we do EAP authentication and a AUTH payload comes in, verify it */ - if (auth_request && this->eap_auth) - { - auth_payload_t *auth_response; - authenticator_t *authenticator = (authenticator_t*)this->eap_auth; - - if (authenticator->verify(authenticator, this->init_request, - this->nonce_r, auth_request) != SUCCESS) - { - SIG(IKE_UP_FAILED, "authentication with EAP failed, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - build_notify(AUTHENTICATION_FAILED, response, TRUE); - return DESTROY_ME; - } - - if (authenticator->build(authenticator, this->init_response, - this->nonce_i, &auth_response) != SUCCESS) - { - SIG(IKE_UP_FAILED, "EAP authentication data generation failed, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - build_notify(AUTHENTICATION_FAILED, response, TRUE); - return DESTROY_ME; - } - response->add_payload(response, (payload_t*)auth_response); - - SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %H[%D]...%H[%D]", - this->ike_sa->get_name(this->ike_sa), me, my_id, other, other_id); - this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - - setup_child_sa(this, response); - - return SUCCESS; - } - - /* check if we have all payloads (AUTH is not checked, not required with EAP) */ - if (!(idi_request && sa_request && tsi_request && tsr_request)) - { - build_notify(INVALID_SYNTAX, response, TRUE); - SIG(IKE_UP_FAILED, "request message incomplete, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - - { /* process ID payload */ - other_id = idi_request->get_identification(idi_request); - if (idr_request) - { - my_id = idr_request->get_identification(idr_request); - } - else - { - my_id = identification_create_from_encoding(ID_ANY, chunk_empty); - } - } - - { /* get a policy and process traffic selectors */ - linked_list_t *my_ts, *other_ts; - - my_ts = tsr_request->get_traffic_selectors(tsr_request); - other_ts = tsi_request->get_traffic_selectors(tsi_request); - - this->policy = charon->policies->get_policy(charon->policies, - my_id, other_id, - my_ts, other_ts, - me, other); - - if (this->policy) - { - this->tsr = this->policy->select_my_traffic_selectors(this->policy, my_ts, me); - this->tsi = this->policy->select_other_traffic_selectors(this->policy, other_ts, other); - } - my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); - other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); - - /* TODO: We should check somehow if we have a policy, but with other - * traffic selectors. Then we would create a IKE_SA without a CHILD_SA. */ - if (this->policy == NULL) - { - SIG(IKE_UP_FAILED, "no acceptable policy for IDs %D - %D found, " - "deleting IKE_SA", my_id, other_id); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - my_id->destroy(my_id); - other_id->destroy(other_id); - build_notify(AUTHENTICATION_FAILED, response, TRUE); - return DESTROY_ME; - } - my_id->destroy(my_id); - - /* get my id from policy, which must contain a fully qualified valid id */ - my_id = this->policy->get_my_id(this->policy); - this->ike_sa->set_my_id(this->ike_sa, my_id->clone(my_id)); - this->ike_sa->set_other_id(this->ike_sa, other_id); - - idr_response = id_payload_create_from_identification(FALSE, my_id); - response->add_payload(response, (payload_t*)idr_response); - } - - if (this->policy->get_auth_method(this->policy) == AUTH_RSA && - this->connection->get_cert_policy(this->connection) != CERT_NEVER_SEND) - { /* build certificate payload */ - x509_t *cert; - cert_payload_t *cert_payload; - - cert = charon->credentials->get_certificate(charon->credentials, my_id); - if (cert) - { - cert_payload = cert_payload_create_from_x509(cert); - response->add_payload(response, (payload_t *)cert_payload); - } - else - { - DBG1(DBG_IKE, "could not find my certificate, cert payload omitted"); - } - } - - if (cert_request) - { /* process certificate payload */ - import_certificate(cert_request); - } - - { /* process SA payload */ - linked_list_t *proposal_list; - - /* get proposals from request, and select one with ours */ - proposal_list = sa_request->get_proposals(sa_request); - DBG2(DBG_IKE, "selecting proposals:"); - this->proposal = this->policy->select_proposal(this->policy, proposal_list); - proposal_list->destroy_offset(proposal_list, offsetof(proposal_t, destroy)); - - /* do we have a proposal? */ - if (this->proposal == NULL) - { - SIG(CHILD_UP_FAILED, "CHILD_SA proposals unacceptable, no CHILD_SA created"); - DBG1(DBG_IKE, "adding NO_PROPOSAL_CHOSEN notify to response"); - build_notify(NO_PROPOSAL_CHOSEN, response, FALSE); - this->build_child = FALSE; - } - /* do we have traffic selectors? */ - else if (this->tsi->get_count(this->tsi) == 0 || this->tsr->get_count(this->tsr) == 0) - { - SIG(CHILD_UP_FAILED, "CHILD_SA traffic selectors unacceptable, no CHILD_SA created"); - DBG1(DBG_IKE, "adding TS_UNACCEPTABLE notify to response"); - build_notify(TS_UNACCEPTABLE, response, FALSE); - this->build_child = FALSE; - } - } - - if (!this->eap_only || this->policy->get_auth_method(this->policy) != AUTH_EAP) - { /* build response AUTH payload when not using a mutual EAP authentication */ - auth_payload_t *auth_response; - authenticator_t *authenticator; - auth_method_t auth_method; - status_t status; - - auth_method = this->policy->get_auth_method(this->policy); - if (auth_method == AUTH_EAP) - { - SIG(IKE_UP_FAILED, - "peer does not support EAP only authentication, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, - "initiating CHILD_SA failed, unable to create IKE_SA"); - build_notify(AUTHENTICATION_FAILED, response, TRUE); - return DESTROY_ME; - } - - authenticator = authenticator_create(this->ike_sa, auth_method); - if (authenticator == NULL) - { - SIG(IKE_UP_FAILED, "auth method %N not supported, deleting IKE_SA", - auth_method_names, auth_method); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - build_notify(AUTHENTICATION_FAILED, response, TRUE); - return DESTROY_ME; - } - status = authenticator->build(authenticator, this->init_response, - this->nonce_i, &auth_response); - authenticator->destroy(authenticator); - if (status != SUCCESS) - { - SIG(IKE_UP_FAILED, "authentication data generation failed, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - build_notify(AUTHENTICATION_FAILED, response, TRUE); - return DESTROY_ME; - } - response->add_payload(response, (payload_t*)auth_response); - } - - if (auth_request) - { /* process auth payload, if not using EAP */ - authenticator_t *authenticator; - auth_method_t auth_method; - status_t status; - - auth_method = auth_request->get_auth_method(auth_request); - authenticator = authenticator_create(this->ike_sa, auth_method); - if (authenticator == NULL) - { - SIG(IKE_UP_FAILED, "auth method %N not supported, deleting IKE_SA", - auth_method_names, auth_method); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - status = authenticator->verify(authenticator, this->init_request, - this->nonce_r, auth_request); - authenticator->destroy(authenticator); - if (status != SUCCESS) - { - SIG(IKE_UP_FAILED, "authentication failed, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - build_notify(AUTHENTICATION_FAILED, response, TRUE); - return DESTROY_ME; - } - - SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %H[%D]...%H[%D]", - this->ike_sa->get_name(this->ike_sa), me, my_id, other, other_id); - this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - - /* set up CHILD_SA if negotiation succeded */ - if (this->build_child) - { - setup_child_sa(this, response); - } - - this->peer_authenticated = TRUE; - } - else - { - /* if no AUTH payload was included, we start with an EAP exchange. - * eap_response is a request in the EAP meaning, but is - * contained in a IKEv2 response */ - eap_payload_t *eap_response; - private_ike_auth_t *next_auth; - eap_type_t eap_type; - - eap_type = this->policy->get_eap_type(this->policy); - this->eap_auth = eap_authenticator_create(this->ike_sa); - status = this->eap_auth->initiate(this->eap_auth, eap_type, &eap_response); - response->add_payload(response, (payload_t*)eap_response); - - if (status == FAILED) - { - /* EAP initiaton failed, we send the EAP_FAILURE message and quit */ - return DESTROY_ME; - } - /* we send an EAP request. to handle the reply, we reschedule - * this transaction, as it knows how to handle the reply */ - next_auth = clone_for_eap(this); - next_auth->message_id = this->message_id + 1; - *next = (transaction_t*)next_auth; - } - return SUCCESS; -} - -/** - * Implementation of transaction_t.conclude - */ -static status_t conclude(private_ike_auth_t *this, message_t *response, - transaction_t **next) -{ - iterator_t *payloads; - payload_t *payload; - host_t *me, *other; - identification_t *other_id, *my_id; - ts_payload_t *tsi_payload = NULL; - ts_payload_t *tsr_payload = NULL; - id_payload_t *idr_payload = NULL; - cert_payload_t *cert_payload = NULL; - auth_payload_t *auth_payload = NULL; - sa_payload_t *sa_payload = NULL; - eap_payload_t *eap_payload = NULL; - status_t status; - - /* check message type */ - if (response->get_exchange_type(response) != IKE_AUTH) - { - SIG(IKE_UP_FAILED, "IKE_AUTH response of invalid type, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - - me = this->ike_sa->get_my_host(this->ike_sa); - other = this->ike_sa->get_other_host(this->ike_sa); - my_id = this->ike_sa->get_my_id(this->ike_sa); - other_id = this->ike_sa->get_other_id(this->ike_sa); - - /* Iterate over all payloads to collect them */ - payloads = response->get_payload_iterator(response); - while (payloads->iterate(payloads, (void**)&payload)) - { - switch (payload->get_type(payload)) - { - case ID_RESPONDER: - idr_payload = (id_payload_t*)payload; - break; - case AUTHENTICATION: - auth_payload = (auth_payload_t*)payload; - break; - case CERTIFICATE: - cert_payload = (cert_payload_t*)payload; - break; - case SECURITY_ASSOCIATION: - sa_payload = (sa_payload_t*)payload; - break; - case TRAFFIC_SELECTOR_INITIATOR: - tsi_payload = (ts_payload_t*)payload; - break; - case TRAFFIC_SELECTOR_RESPONDER: - tsr_payload = (ts_payload_t*)payload; - break; - case EXTENSIBLE_AUTHENTICATION: - eap_payload = (eap_payload_t*)payload; - break; - case NOTIFY: - { - status = process_notifies(this, (notify_payload_t*)payload); - if (status == FAILED) - { - payloads->destroy(payloads); - /* we return SUCCESS, as transaction completet */ - return SUCCESS; - } - if (status == DESTROY_ME) - { - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - payloads->destroy(payloads); - return status; - } - break; - } - default: - { - DBG1(DBG_IKE, "ignoring payload %N", - payload_type_names, payload->get_type(payload)); - break; - } - } - } - payloads->destroy(payloads); - - if (idr_payload) - { /* process idr payload */ - identification_t *configured_other_id; - int wildcards; - - other_id = idr_payload->get_identification(idr_payload); - configured_other_id = this->policy->get_other_id(this->policy); - - if (!other_id->matches(other_id, configured_other_id, &wildcards)) - { - other_id->destroy(other_id); - SIG(IKE_UP_FAILED, "other peer uses unacceptable ID (%D, excepted " - "%D), deleting IKE_SA", other_id, configured_other_id); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - /* update other ID. It was already set, but may contain wildcards */ - this->ike_sa->set_other_id(this->ike_sa, other_id); - } - - if (cert_payload) - { /* process cert payload */ - import_certificate(cert_payload); - } - - if (auth_payload && idr_payload) - { /* authenticate peer */ - authenticator_t *authenticator; - auth_method_t auth_method; - status_t status; - - my_id = this->policy->get_my_id(this->policy); - auth_method = auth_payload->get_auth_method(auth_payload); - authenticator = authenticator_create(this->ike_sa, auth_method); - if (authenticator == NULL) - { - SIG(IKE_UP_FAILED, "auth method %N not supported, deleting IKE_SA", - auth_method_names, auth_method); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - status = authenticator->verify(authenticator, this->init_response, - this->nonce_i, auth_payload); - authenticator->destroy(authenticator); - if (status != SUCCESS) - { - SIG(IKE_UP_FAILED, "authentication of '%D' with %N failed, " - "deleting IKE_SA", other_id, auth_method_names, auth_method); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - this->peer_authenticated = TRUE; - } - - if (eap_payload && this->eap_auth) - { - switch (this->eap_auth->process(this->eap_auth, eap_payload, &this->eap_next)) - { - case SUCCESS: - { - /* EAP message was EAP_SUCCESS, send AUTH in next transaction */ - DBG2(DBG_IKE, "EAP authentication exchanges completed successful"); - this->eap_next = NULL; - /* fall through */ - } - case NEED_MORE: - { - /* EAP message was a EAP_REQUEST, handle it in next transaction */ - private_ike_auth_t *next_auth = clone_for_eap(this); - next_auth->message_id = this->message_id + 1; - *next = (transaction_t*)next_auth; - return SUCCESS; - } - case FAILED: - default: - { - /* EAP message was EAP_FAILURE */ - SIG(IKE_UP_FAILED, "EAP authentication failed, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - } - } - - if (!(auth_payload && sa_payload && tsi_payload && tsr_payload)) - { - SIG(IKE_UP_FAILED, "response message incomplete, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - - /* if we do EAP authentication and a AUTH payload comes in, verify it */ - if (this->eap_auth && - (this->eap_auth->is_mutual(this->eap_auth) || this->peer_authenticated)) - { - authenticator_t *authenticator = (authenticator_t*)this->eap_auth; - - if (authenticator->verify(authenticator, this->init_response, - this->nonce_i, auth_payload) != SUCCESS) - { - SIG(IKE_UP_FAILED, "authentication with EAP failed, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - this->peer_authenticated = TRUE; - } - - if (!this->peer_authenticated) - { - SIG(IKE_UP_FAILED, "server didn't send authentication data, deleting IKE_SA"); - SIG(CHILD_UP_FAILED, "initiating CHILD_SA failed, unable to create IKE_SA"); - return DESTROY_ME; - } - - SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %H[%D]...%H[%D]", - this->ike_sa->get_name(this->ike_sa), me, my_id, other, other_id); - this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - - { /* process traffic selectors for us */ - linked_list_t *ts_received = tsi_payload->get_traffic_selectors(tsi_payload); - this->tsi = this->policy->select_my_traffic_selectors(this->policy, ts_received, me); - ts_received->destroy_offset(ts_received, offsetof(traffic_selector_t, destroy)); - } - - { /* process traffic selectors for other */ - linked_list_t *ts_received = tsr_payload->get_traffic_selectors(tsr_payload); - this->tsr = this->policy->select_other_traffic_selectors(this->policy, ts_received, other); - ts_received->destroy_offset(ts_received, offsetof(traffic_selector_t, destroy)); - } - - { /* process sa payload */ - linked_list_t *proposal_list; - - proposal_list = sa_payload->get_proposals(sa_payload); - /* we have to re-check here if other's selection is valid */ - this->proposal = this->policy->select_proposal(this->policy, proposal_list); - proposal_list->destroy_offset(proposal_list, offsetof(proposal_t, destroy)); - - /* everything fine to create CHILD? */ - if (this->proposal == NULL || - this->tsi->get_count(this->tsi) == 0 || - this->tsr->get_count(this->tsr) == 0 || - !this->build_child) - { - SIG(CHILD_UP_FAILED, "CHILD_SA negotiation failed, no CHILD_SA built"); - } - else - { - /* check mode if it is acceptable */ - switch (this->mode) - { - case MODE_TUNNEL: - /* is the default */ - break; - case MODE_TRANSPORT: - /* TODO: we should close the CHILD_SA if negotiated - * mode is not acceptable for us */ - if (!ts_list_is_host(this->tsi, me) || - !ts_list_is_host(this->tsr, other)) - { - this->mode = MODE_TUNNEL; - DBG1(DBG_IKE, "not using tranport mode, not host-to-host"); - } - else if (this->ike_sa->is_natt_enabled(this->ike_sa)) - { - this->mode = MODE_TUNNEL; - DBG1(DBG_IKE, "not using tranport mode, as connection NATed"); - } - break; - case MODE_BEET: - if (!ts_list_is_host(this->tsi, NULL) || - !ts_list_is_host(this->tsr, NULL)) - { - this->mode = MODE_TUNNEL; - DBG1(DBG_IKE, "not using BEET mode, not host-to-host"); - } - break; - } - - if (install_child_sa(this, TRUE) != SUCCESS) - { - SIG(CHILD_UP_FAILED, "installing CHILD_SA '%s' failed, no CHILD_SA built", - this->policy->get_name(this->policy)); - /* TODO: we should send a DELETE for that CHILD to stay - * synchronous with the peer */ - } - else - { - SIG(CHILD_UP_SUCCESS, "CHILD_SA '%s' created", - this->policy->get_name(this->policy)); - } - } - } - return SUCCESS; -} - -/** - * implements transaction_t.destroy - */ -static void destroy(private_ike_auth_t *this) -{ - DESTROY_IF(this->message); - DESTROY_IF(this->proposal); - DESTROY_IF(this->child_sa); - DESTROY_IF(this->policy); - DESTROY_IF(this->connection); - DESTROY_IF(this->cacerts); - if (this->eap_auth) - { - this->eap_auth->authenticator_interface.destroy(&this->eap_auth->authenticator_interface); - } - DESTROY_IF(this->eap_next); - if (this->tsi) - { - this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy)); - } - if (this->tsr) - { - this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy)); - } - chunk_free(&this->nonce_i); - chunk_free(&this->nonce_r); - chunk_free(&this->init_request); - chunk_free(&this->init_response); - free(this); -} - -/* - * Described in header. - */ -ike_auth_t *ike_auth_create(ike_sa_t *ike_sa) -{ - private_ike_auth_t *this = malloc_thing(private_ike_auth_t); - - /* transaction interface functions */ - this->public.transaction.get_request = (status_t(*)(transaction_t*,message_t**))get_request; - this->public.transaction.get_response = (status_t(*)(transaction_t*,message_t*,message_t**,transaction_t**))get_response; - this->public.transaction.conclude = (status_t(*)(transaction_t*,message_t*,transaction_t**))conclude; - this->public.transaction.get_message_id = (u_int32_t(*)(transaction_t*))get_message_id; - this->public.transaction.requested = (u_int32_t(*)(transaction_t*))requested; - this->public.transaction.destroy = (void(*)(transaction_t*))destroy; - - /* public functions */ - this->public.set_config = (void(*)(ike_auth_t*,connection_t*,policy_t*))set_config; - this->public.set_reqid = (void(*)(ike_auth_t*,u_int32_t))set_reqid; - this->public.set_nonces = (void(*)(ike_auth_t*,chunk_t,chunk_t))set_nonces; - this->public.set_init_messages = (void(*)(ike_auth_t*,chunk_t,chunk_t))set_init_messages; - - /* private data */ - this->ike_sa = ike_sa; - this->message_id = 0; - this->message = NULL; - this->requested = 0; - this->nonce_i = chunk_empty; - this->nonce_r = chunk_empty; - this->init_request = chunk_empty; - this->init_response = chunk_empty; - this->child_sa = NULL; - this->proposal = NULL; - this->policy = NULL; - this->connection = NULL; - this->tsi = NULL; - this->tsr = NULL; - this->build_child = TRUE; - this->eap_auth = NULL; - this->eap_next = NULL; - this->eap_only = FALSE; - this->peer_authenticated = FALSE; - this->reqid = 0; - this->cacerts = linked_list_create(); - this->mode = MODE_TUNNEL; - - return &this->public; -} |