diff options
author | René Mayrhofer <rene@mayrhofer.eu.org> | 2011-05-19 13:41:58 +0200 |
---|---|---|
committer | René Mayrhofer <rene@mayrhofer.eu.org> | 2011-05-19 13:41:58 +0200 |
commit | b590992f735393c97489fce191e7810eaae4f6d7 (patch) | |
tree | 286595c4aa43dbf3d616d816e5fade6ac364771a /src/libcharon/sa | |
parent | 2fce29055b7b5bc2860d503d1ae822931f80b7aa (diff) | |
parent | 0a9d51a49042a68daa15b0c74a2b7f152f52606b (diff) | |
download | vyos-strongswan-b590992f735393c97489fce191e7810eaae4f6d7.tar.gz vyos-strongswan-b590992f735393c97489fce191e7810eaae4f6d7.zip |
Merge upstream version 4.5.2
Diffstat (limited to 'src/libcharon/sa')
32 files changed, 604 insertions, 1775 deletions
diff --git a/src/libcharon/sa/authenticators/authenticator.c b/src/libcharon/sa/authenticators/authenticator.c index 3f176f9be..83f5fbaad 100644 --- a/src/libcharon/sa/authenticators/authenticator.c +++ b/src/libcharon/sa/authenticators/authenticator.c @@ -39,12 +39,8 @@ ENUM_END(auth_method_names, AUTH_ECDSA_521); */ authenticator_t *authenticator_create_builder(ike_sa_t *ike_sa, auth_cfg_t *cfg, chunk_t received_nonce, chunk_t sent_nonce, -<<<<<<< HEAD - chunk_t received_init, chunk_t sent_init) -======= chunk_t received_init, chunk_t sent_init, char reserved[3]) ->>>>>>> upstream/4.5.1 { switch ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS)) { @@ -52,15 +48,6 @@ authenticator_t *authenticator_create_builder(ike_sa_t *ike_sa, auth_cfg_t *cfg, /* defaults to PUBKEY */ case AUTH_CLASS_PUBKEY: return (authenticator_t*)pubkey_authenticator_create_builder(ike_sa, -<<<<<<< HEAD - received_nonce, sent_init); - case AUTH_CLASS_PSK: - return (authenticator_t*)psk_authenticator_create_builder(ike_sa, - received_nonce, sent_init); - case AUTH_CLASS_EAP: - return (authenticator_t*)eap_authenticator_create_builder(ike_sa, - received_nonce, sent_nonce, received_init, sent_init); -======= received_nonce, sent_init, reserved); case AUTH_CLASS_PSK: return (authenticator_t*)psk_authenticator_create_builder(ike_sa, @@ -69,7 +56,6 @@ authenticator_t *authenticator_create_builder(ike_sa_t *ike_sa, auth_cfg_t *cfg, return (authenticator_t*)eap_authenticator_create_builder(ike_sa, received_nonce, sent_nonce, received_init, sent_init, reserved); ->>>>>>> upstream/4.5.1 default: return NULL; } @@ -81,12 +67,8 @@ authenticator_t *authenticator_create_builder(ike_sa_t *ike_sa, auth_cfg_t *cfg, authenticator_t *authenticator_create_verifier( ike_sa_t *ike_sa, message_t *message, chunk_t received_nonce, chunk_t sent_nonce, -<<<<<<< HEAD - chunk_t received_init, chunk_t sent_init) -======= chunk_t received_init, chunk_t sent_init, char reserved[3]) ->>>>>>> upstream/4.5.1 { auth_payload_t *auth_payload; @@ -94,12 +76,8 @@ authenticator_t *authenticator_create_verifier( if (auth_payload == NULL) { return (authenticator_t*)eap_authenticator_create_verifier(ike_sa, -<<<<<<< HEAD - received_nonce, sent_nonce, received_init, sent_init); -======= received_nonce, sent_nonce, received_init, sent_init, reserved); ->>>>>>> upstream/4.5.1 } switch (auth_payload->get_auth_method(auth_payload)) { @@ -108,17 +86,10 @@ authenticator_t *authenticator_create_verifier( case AUTH_ECDSA_384: case AUTH_ECDSA_521: return (authenticator_t*)pubkey_authenticator_create_verifier(ike_sa, -<<<<<<< HEAD - sent_nonce, received_init); - case AUTH_PSK: - return (authenticator_t*)psk_authenticator_create_verifier(ike_sa, - sent_nonce, received_init); -======= sent_nonce, received_init, reserved); case AUTH_PSK: return (authenticator_t*)psk_authenticator_create_verifier(ike_sa, sent_nonce, received_init, reserved); ->>>>>>> upstream/4.5.1 default: return NULL; } diff --git a/src/libcharon/sa/authenticators/authenticator.h b/src/libcharon/sa/authenticators/authenticator.h index d30094c9b..d27e006a3 100644 --- a/src/libcharon/sa/authenticators/authenticator.h +++ b/src/libcharon/sa/authenticators/authenticator.h @@ -130,21 +130,14 @@ struct authenticator_t { * @param sent_nonce nonce sent in IKE_SA_INIT * @param received_init received IKE_SA_INIT message data * @param sent_init sent IKE_SA_INIT message data -<<<<<<< HEAD -======= * @param reserved reserved bytes of the ID payload ->>>>>>> upstream/4.5.1 * @return authenticator, NULL if not supported */ authenticator_t *authenticator_create_builder( ike_sa_t *ike_sa, auth_cfg_t *cfg, chunk_t received_nonce, chunk_t sent_nonce, -<<<<<<< HEAD - chunk_t received_init, chunk_t sent_init); -======= chunk_t received_init, chunk_t sent_init, char reserved[3]); ->>>>>>> upstream/4.5.1 /** * Create an authenticator to verify signatures. @@ -155,20 +148,13 @@ authenticator_t *authenticator_create_builder( * @param sent_nonce nonce sent in IKE_SA_INIT * @param received_init received IKE_SA_INIT message data * @param sent_init sent IKE_SA_INIT message data -<<<<<<< HEAD -======= * @param reserved reserved bytes of the ID payload ->>>>>>> upstream/4.5.1 * @return authenticator, NULL if not supported */ authenticator_t *authenticator_create_verifier( ike_sa_t *ike_sa, message_t *message, chunk_t received_nonce, chunk_t sent_nonce, -<<<<<<< HEAD - chunk_t received_init, chunk_t sent_init); -======= chunk_t received_init, chunk_t sent_init, char reserved[3]); ->>>>>>> upstream/4.5.1 #endif /** AUTHENTICATOR_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap/eap_method.h b/src/libcharon/sa/authenticators/eap/eap_method.h index 9961039ff..0eab2b5ff 100644 --- a/src/libcharon/sa/authenticators/eap/eap_method.h +++ b/src/libcharon/sa/authenticators/eap/eap_method.h @@ -113,14 +113,29 @@ struct eap_method_t { * Not all EAP methods establish a shared secret. For implementations of * the EAP-Identity method, get_msk() returns the received identity. * - * @param msk chunk receiving internal stored MSK + * @param msk chunk receiving internal stored MSK * @return - * - SUCCESS, or - * - FAILED, if MSK not established (yet) + * - SUCCESS, or + * - FAILED, if MSK not established (yet) */ status_t (*get_msk) (eap_method_t *this, chunk_t *msk); /** + * Get the current EAP identifier. + * + * @return current EAP identifier + */ + u_int8_t (*get_identifier) (eap_method_t *this); + + /** + * Set the EAP identifier to a deterministic value, overwriting + * the randomly initialized default value. + * + * @param identifier current EAP identifier + */ + void (*set_identifier) (eap_method_t *this, u_int8_t identifier); + + /** * Destroys a eap_method_t object. */ void (*destroy) (eap_method_t *this); diff --git a/src/libcharon/sa/authenticators/eap/sim_card.h b/src/libcharon/sa/authenticators/eap/sim_card.h new file mode 100644 index 000000000..5f5dc580b --- /dev/null +++ b/src/libcharon/sa/authenticators/eap/sim_card.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2008-2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup sim_card sim_card + * @{ @ingroup eap + */ + +#ifndef SIM_CARD_H_ +#define SIM_CARD_H_ + +typedef struct sim_card_t sim_card_t; + +/** + * Interface for a (U)SIM card (used as EAP client). + * + * The SIM card completes triplets/quintuplets requested in a challenge + * received from the server. + * An implementation supporting only one of SIM/AKA authentication may + * implement the other methods with return_false()/return NOT_SUPPORTED/NULL. + */ +struct sim_card_t { + + /** + * Calculate SRES/KC from a RAND for SIM authentication. + * + * @param id permanent identity to get a triplet for + * @param rand RAND input buffer, fixed size 16 bytes + * @param sres SRES output buffer, fixed size 4 byte + * @param kc KC output buffer, fixed size 8 bytes + * @return TRUE if SRES/KC calculated, FALSE on error/wrong identity + */ + bool (*get_triplet)(sim_card_t *this, identification_t *id, + char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], + char kc[SIM_KC_LEN]); + + /** + * Calculate CK/IK/RES from RAND/AUTN for AKA authentication. + * + * If the received sequence number (in autn) is out of sync, INVALID_STATE + * is returned. + * The RES value is the only one with variable length. Pass a buffer + * of at least AKA_RES_MAX, the actual number of bytes is written to the + * res_len value. While the standard would allow any bit length between + * 32 and 128 bits, we support only full bytes for now. + * + * @param id permanent identity to request quintuplet for + * @param rand random value rand + * @param autn authentication token autn + * @param ck buffer receiving encryption key ck + * @param ik buffer receiving integrity key ik + * @param res buffer receiving authentication result res + * @param res_len nubmer of bytes written to res buffer + * @return SUCCESS, FAILED, or INVALID_STATE if out of sync + */ + status_t (*get_quintuplet)(sim_card_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], + char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], + char res[AKA_RES_MAX], int *res_len); + + /** + * Calculate AUTS from RAND for AKA resynchronization. + * + * @param id permanent identity to request quintuplet for + * @param rand random value rand + * @param auts resynchronization parameter auts + * @return TRUE if parameter generated successfully + */ + bool (*resync)(sim_card_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]); + + /** + * Set the pseudonym to use for next authentication. + * + * @param id permanent identity of the peer + * @param pseudonym pseudonym identity received from the server + */ + void (*set_pseudonym)(sim_card_t *this, identification_t *id, + identification_t *pseudonym); + + /** + * Get the pseudonym previously stored via set_pseudonym(). + * + * @param id permanent identity of the peer + * @return associated pseudonym identity, NULL if none stored + */ + identification_t* (*get_pseudonym)(sim_card_t *this, identification_t *id); + + /** + * Store parameters to use for the next fast reauthentication. + * + * @param id permanent identity of the peer + * @param next next fast reauthentication identity to use + * @param mk master key MK to store for reauthentication + * @param counter counter value to store, host order + */ + void (*set_reauth)(sim_card_t *this, identification_t *id, + identification_t *next, char mk[HASH_SIZE_SHA1], + u_int16_t counter); + + /** + * Retrieve parameters for fast reauthentication stored via set_reauth(). + * + * @param id permanent identity of the peer + * @param mk buffer receiving master key MK + * @param counter pointer receiving counter value, in host order + * @return fast reauthentication identity, NULL if not found + */ + identification_t* (*get_reauth)(sim_card_t *this, identification_t *id, + char mk[HASH_SIZE_SHA1], u_int16_t *counter); +}; + +#endif /** SIM_CARD_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap/sim_hooks.h b/src/libcharon/sa/authenticators/eap/sim_hooks.h new file mode 100644 index 000000000..0a675e4ab --- /dev/null +++ b/src/libcharon/sa/authenticators/eap/sim_hooks.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008-2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup sim_hooks sim_hooks + * @{ @ingroup eap + */ + +#ifndef SIM_HOOKS_H_ +#define SIM_HOOKS_H_ + +typedef struct sim_hooks_t sim_hooks_t; + +/** + * Additional hooks invoked during EAP-SIM/AKA message processing. + */ +struct sim_hooks_t { + + /** + * SIM/AKA message parsing. + * + * As a SIM/AKA optionally contains encrypted attributes, the hook + * might get invoked twice, once before and once after decryption. + * + * @param message SIM/AKA message + * @param inbound TRUE for incoming messages, FALSE for outgoing + * @param decrypted TRUE if AT_ENCR_DATA has been decrypted + */ + void (*message)(sim_hooks_t *this, simaka_message_t *message, + bool inbound, bool decrypted); + + /** + * SIM/AKA encryption/authentication key hooks. + * + * @param k_encr derived SIM/AKA encryption key k_encr + * @param k_auth derived SIM/AKA authentication key k_auth + */ + void (*keys)(sim_hooks_t *this, chunk_t k_encr, chunk_t k_auth); +}; + +#endif /** SIM_HOOKS_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap/sim_manager.c b/src/libcharon/sa/authenticators/eap/sim_manager.c index 157865083..9ccaf5298 100644 --- a/src/libcharon/sa/authenticators/eap/sim_manager.c +++ b/src/libcharon/sa/authenticators/eap/sim_manager.c @@ -17,6 +17,7 @@ #include <daemon.h> #include <utils/linked_list.h> +#include <threading/rwlock.h> typedef struct private_sim_manager_t private_sim_manager_t; @@ -44,65 +45,67 @@ struct private_sim_manager_t { * list of added hooks */ linked_list_t *hooks; + + /** + * lock for lists above + */ + rwlock_t *lock; }; -/** - * Implementation of sim_manager_t.add_card - */ -static void add_card(private_sim_manager_t *this, sim_card_t *card) +METHOD(sim_manager_t, add_card, void, + private_sim_manager_t *this, sim_card_t *card) { + this->lock->write_lock(this->lock); this->cards->insert_last(this->cards, card); + this->lock->unlock(this->lock); } -/** - * Implementation of sim_manager_t.remove_card - */ -static void remove_card(private_sim_manager_t *this, sim_card_t *card) +METHOD(sim_manager_t, remove_card, void, + private_sim_manager_t *this, sim_card_t *card) { + this->lock->write_lock(this->lock); this->cards->remove(this->cards, card, NULL); + this->lock->unlock(this->lock); } -/** - * Implementation of sim_manager_t.card_get_triplet - */ -static bool card_get_triplet(private_sim_manager_t *this, identification_t *id, - char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], - char kc[SIM_KC_LEN]) +METHOD(sim_manager_t, card_get_triplet, bool, + private_sim_manager_t *this, identification_t *id, + char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]) { enumerator_t *enumerator; sim_card_t *card; int tried = 0; + this->lock->read_lock(this->lock); enumerator = this->cards->create_enumerator(this->cards); while (enumerator->enumerate(enumerator, &card)) { if (card->get_triplet(card, id, rand, sres, kc)) { enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return TRUE; } tried++; } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); DBG1(DBG_IKE, "tried %d SIM cards, but none has triplets for '%Y'", tried, id); return FALSE; } -/** - * Implementation of sim_manager_t.card_get_quintuplet - */ -static status_t card_get_quintuplet(private_sim_manager_t *this, - identification_t *id, char rand[AKA_RAND_LEN], - char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], - char ik[AKA_IK_LEN], char res[AKA_RES_MAX], - int *res_len) +METHOD(sim_manager_t, card_get_quintuplet, status_t, + private_sim_manager_t *this, identification_t *id, char rand[AKA_RAND_LEN], + char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], + char res[AKA_RES_MAX], int *res_len) { enumerator_t *enumerator; sim_card_t *card; status_t status = NOT_FOUND; int tried = 0; + this->lock->read_lock(this->lock); enumerator = this->cards->create_enumerator(this->cards); while (enumerator->enumerate(enumerator, &card)) { @@ -112,6 +115,7 @@ static status_t card_get_quintuplet(private_sim_manager_t *this, case SUCCESS: case INVALID_STATE: enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return status; case NOT_SUPPORTED: case FAILED: @@ -121,62 +125,62 @@ static status_t card_get_quintuplet(private_sim_manager_t *this, } } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); DBG1(DBG_IKE, "tried %d SIM cards, but none has quintuplets for '%Y'", tried, id); return status; } -/** - * Implementation of sim_manager_t.card_resync - */ -static bool card_resync(private_sim_manager_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]) +METHOD(sim_manager_t, card_resync, bool, + private_sim_manager_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]) { enumerator_t *enumerator; sim_card_t *card; + this->lock->read_lock(this->lock); enumerator = this->cards->create_enumerator(this->cards); while (enumerator->enumerate(enumerator, &card)) { if (card->resync(card, id, rand, auts)) { enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return TRUE; } } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return FALSE; } -/** - * Implementation of sim_manager_t.card_set_pseudonym - */ -static void card_set_pseudonym(private_sim_manager_t *this, - identification_t *id, identification_t *pseudonym) +METHOD(sim_manager_t, card_set_pseudonym, void, + private_sim_manager_t *this, identification_t *id, + identification_t *pseudonym) { enumerator_t *enumerator; sim_card_t *card; DBG1(DBG_IKE, "storing pseudonym '%Y' for '%Y'", pseudonym, id); + this->lock->read_lock(this->lock); enumerator = this->cards->create_enumerator(this->cards); while (enumerator->enumerate(enumerator, &card)) { card->set_pseudonym(card, id, pseudonym); } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); } -/** - * Implementation of sim_manager_t.card_get_pseudonym - */ -static identification_t* card_get_pseudonym(private_sim_manager_t *this, - identification_t *id) +METHOD(sim_manager_t, card_get_pseudonym, identification_t*, + private_sim_manager_t *this, identification_t *id) { enumerator_t *enumerator; sim_card_t *card; identification_t *pseudonym = NULL; + this->lock->read_lock(this->lock); enumerator = this->cards->create_enumerator(this->cards); while (enumerator->enumerate(enumerator, &card)) { @@ -189,15 +193,13 @@ static identification_t* card_get_pseudonym(private_sim_manager_t *this, } } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return pseudonym; } -/** - * Implementation of sim_manager_t.card_set_reauth - */ -static void card_set_reauth(private_sim_manager_t *this, identification_t *id, - identification_t *next, char mk[HASH_SIZE_SHA1], - u_int16_t counter) +METHOD(sim_manager_t, card_set_reauth, void, + private_sim_manager_t *this, identification_t *id, identification_t *next, + char mk[HASH_SIZE_SHA1], u_int16_t counter) { enumerator_t *enumerator; sim_card_t *card; @@ -205,25 +207,25 @@ static void card_set_reauth(private_sim_manager_t *this, identification_t *id, DBG1(DBG_IKE, "storing next reauthentication identity '%Y' for '%Y'", next, id); + this->lock->read_lock(this->lock); enumerator = this->cards->create_enumerator(this->cards); while (enumerator->enumerate(enumerator, &card)) { card->set_reauth(card, id, next, mk, counter); } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); } -/** - * Implementation of sim_manager_t.card_get_reauth - */ -static identification_t* card_get_reauth(private_sim_manager_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1], - u_int16_t *counter) +METHOD(sim_manager_t, card_get_reauth, identification_t*, + private_sim_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1], + u_int16_t *counter) { enumerator_t *enumerator; sim_card_t *card; identification_t *reauth = NULL; + this->lock->read_lock(this->lock); enumerator = this->cards->create_enumerator(this->cards); while (enumerator->enumerate(enumerator, &card)) { @@ -236,66 +238,63 @@ static identification_t* card_get_reauth(private_sim_manager_t *this, } } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return reauth; } -/** - * Implementation of sim_manager_t.add_provider - */ -static void add_provider(private_sim_manager_t *this, sim_provider_t *provider) +METHOD(sim_manager_t, add_provider, void, + private_sim_manager_t *this, sim_provider_t *provider) { + this->lock->write_lock(this->lock); this->providers->insert_last(this->providers, provider); + this->lock->unlock(this->lock); } -/** - * Implementation of sim_manager_t.remove_provider - */ -static void remove_provider(private_sim_manager_t *this, - sim_provider_t *provider) +METHOD(sim_manager_t, remove_provider, void, + private_sim_manager_t *this, sim_provider_t *provider) { + this->lock->write_lock(this->lock); this->providers->remove(this->providers, provider, NULL); + this->lock->unlock(this->lock); } -/** - * Implementation of sim_manager_t.provider_get_triplet - */ -static bool provider_get_triplet(private_sim_manager_t *this, - identification_t *id, char rand[SIM_RAND_LEN], - char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]) +METHOD(sim_manager_t, provider_get_triplet, bool, + private_sim_manager_t *this, identification_t *id, char rand[SIM_RAND_LEN], + char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]) { enumerator_t *enumerator; sim_provider_t *provider; int tried = 0; + this->lock->read_lock(this->lock); enumerator = this->providers->create_enumerator(this->providers); while (enumerator->enumerate(enumerator, &provider)) { if (provider->get_triplet(provider, id, rand, sres, kc)) { enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return TRUE; } tried++; } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); DBG1(DBG_IKE, "tried %d SIM providers, but none had a triplet for '%Y'", tried, id); return FALSE; } -/** - * Implementation of sim_manager_t.provider_get_quintuplet - */ -static bool provider_get_quintuplet(private_sim_manager_t *this, - identification_t *id, char rand[AKA_RAND_LEN], - char xres[AKA_RES_MAX], int *xres_len, - char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], - char autn[AKA_AUTN_LEN]) +METHOD(sim_manager_t, provider_get_quintuplet, bool, + private_sim_manager_t *this, identification_t *id, char rand[AKA_RAND_LEN], + char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], + char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]) { enumerator_t *enumerator; sim_provider_t *provider; int tried = 0; + this->lock->read_lock(this->lock); enumerator = this->providers->create_enumerator(this->providers); while (enumerator->enumerate(enumerator, &provider)) { @@ -303,47 +302,48 @@ static bool provider_get_quintuplet(private_sim_manager_t *this, ck, ik, autn)) { enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return TRUE; } } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); DBG1(DBG_IKE, "tried %d SIM providers, but none had a quintuplet for '%Y'", tried, id); return FALSE; } -/** - * Implementation of sim_manager_t.provider_resync - */ -static bool provider_resync(private_sim_manager_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]) +METHOD(sim_manager_t, provider_resync, bool, + private_sim_manager_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]) { enumerator_t *enumerator; sim_provider_t *provider; + this->lock->read_lock(this->lock); enumerator = this->providers->create_enumerator(this->providers); while (enumerator->enumerate(enumerator, &provider)) { if (provider->resync(provider, id, rand, auts)) { enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return TRUE; } } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return FALSE; } -/** - * Implementation of sim_manager_t.provider_is_pseudonym - */ -static identification_t* provider_is_pseudonym(private_sim_manager_t *this, - identification_t *id) +METHOD(sim_manager_t, provider_is_pseudonym, identification_t*, + private_sim_manager_t *this, identification_t *id) { enumerator_t *enumerator; sim_provider_t *provider; identification_t *permanent = NULL; + this->lock->read_lock(this->lock); enumerator = this->providers->create_enumerator(this->providers); while (enumerator->enumerate(enumerator, &provider)) { @@ -356,19 +356,18 @@ static identification_t* provider_is_pseudonym(private_sim_manager_t *this, } } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return permanent; } -/** - * Implementation of sim_manager_t.provider_gen_pseudonym - */ -static identification_t* provider_gen_pseudonym(private_sim_manager_t *this, - identification_t *id) +METHOD(sim_manager_t, provider_gen_pseudonym, identification_t*, + private_sim_manager_t *this, identification_t *id) { enumerator_t *enumerator; sim_provider_t *provider; identification_t *pseudonym = NULL; + this->lock->read_lock(this->lock); enumerator = this->providers->create_enumerator(this->providers); while (enumerator->enumerate(enumerator, &provider)) { @@ -380,20 +379,19 @@ static identification_t* provider_gen_pseudonym(private_sim_manager_t *this, } } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return pseudonym; } -/** - * Implementation of sim_manager_t.provider_is_reauth - */ -static identification_t* provider_is_reauth(private_sim_manager_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1], - u_int16_t *counter) +METHOD(sim_manager_t, provider_is_reauth, identification_t*, + private_sim_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1], + u_int16_t *counter) { enumerator_t *enumerator; sim_provider_t *provider; identification_t *permanent = NULL; + this->lock->read_lock(this->lock); enumerator = this->providers->create_enumerator(this->providers); while (enumerator->enumerate(enumerator, &provider)) { @@ -406,19 +404,18 @@ static identification_t* provider_is_reauth(private_sim_manager_t *this, } } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return permanent; } -/** - * Implementation of sim_manager_t.provider_gen_reauth - */ -static identification_t* provider_gen_reauth(private_sim_manager_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1]) +METHOD(sim_manager_t, provider_gen_reauth, identification_t*, + private_sim_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1]) { enumerator_t *enumerator; sim_provider_t *provider; identification_t *reauth = NULL; + this->lock->read_lock(this->lock); enumerator = this->providers->create_enumerator(this->providers); while (enumerator->enumerate(enumerator, &provider)) { @@ -430,67 +427,66 @@ static identification_t* provider_gen_reauth(private_sim_manager_t *this, } } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); return reauth; } -/** - * Implementation of sim_manager_t.add_hooks - */ -static void add_hooks(private_sim_manager_t *this, sim_hooks_t *hooks) +METHOD(sim_manager_t, add_hooks, void, + private_sim_manager_t *this, sim_hooks_t *hooks) { + this->lock->write_lock(this->lock); this->hooks->insert_last(this->hooks, hooks); + this->lock->unlock(this->lock); } -/** - * Implementation of sim_manager_t.remove_hooks - */ -static void remove_hooks(private_sim_manager_t *this, sim_hooks_t *hooks) +METHOD(sim_manager_t, remove_hooks, void, + private_sim_manager_t *this, sim_hooks_t *hooks) { + this->lock->write_lock(this->lock); this->hooks->remove(this->hooks, hooks, NULL); + this->lock->unlock(this->lock); } -/** - * Implementation of sim_manager_t.message_hook - */ -static void message_hook(private_sim_manager_t *this, - simaka_message_t *message, bool inbound, bool decrypted) +METHOD(sim_manager_t, message_hook, void, + private_sim_manager_t *this, simaka_message_t *message, + bool inbound, bool decrypted) { enumerator_t *enumerator; sim_hooks_t *hooks; + this->lock->read_lock(this->lock); enumerator = this->hooks->create_enumerator(this->hooks); while (enumerator->enumerate(enumerator, &hooks)) { hooks->message(hooks, message, inbound, decrypted); } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); } -/** - * Implementation of sim_manager_t.key_hook - */ -static void key_hook(private_sim_manager_t *this, - chunk_t k_encr, chunk_t k_auth) +METHOD(sim_manager_t, key_hook, void, + private_sim_manager_t *this, chunk_t k_encr, chunk_t k_auth) { enumerator_t *enumerator; sim_hooks_t *hooks; + this->lock->read_lock(this->lock); enumerator = this->hooks->create_enumerator(this->hooks); while (enumerator->enumerate(enumerator, &hooks)) { hooks->keys(hooks, k_encr, k_auth); } enumerator->destroy(enumerator); + this->lock->unlock(this->lock); } -/** - * Implementation of sim_manager_t.destroy. - */ -static void destroy(private_sim_manager_t *this) +METHOD(sim_manager_t, destroy, void, + private_sim_manager_t *this) { this->cards->destroy(this->cards); this->providers->destroy(this->providers); this->hooks->destroy(this->hooks); + this->lock->destroy(this->lock); free(this); } @@ -499,35 +495,39 @@ static void destroy(private_sim_manager_t *this) */ sim_manager_t *sim_manager_create() { - private_sim_manager_t *this = malloc_thing(private_sim_manager_t); - - this->public.add_card = (void(*)(sim_manager_t*, sim_card_t *card))add_card; - this->public.remove_card = (void(*)(sim_manager_t*, sim_card_t *card))remove_card; - this->public.card_get_triplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))card_get_triplet; - this->public.card_get_quintuplet = (status_t(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len))card_get_quintuplet; - this->public.card_resync = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))card_resync; - this->public.card_set_pseudonym = (void(*)(sim_manager_t*, identification_t *id, identification_t *pseudonym))card_set_pseudonym; - this->public.card_get_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))card_get_pseudonym; - this->public.card_set_reauth = (void(*)(sim_manager_t*, identification_t *id, identification_t *next, char mk[HASH_SIZE_SHA1], u_int16_t counter))card_set_reauth; - this->public.card_get_reauth = (identification_t*(*)(sim_manager_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))card_get_reauth; - this->public.add_provider = (void(*)(sim_manager_t*, sim_provider_t *provider))add_provider; - this->public.remove_provider = (void(*)(sim_manager_t*, sim_provider_t *provider))remove_provider; - this->public.provider_get_triplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))provider_get_triplet; - this->public.provider_get_quintuplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))provider_get_quintuplet; - this->public.provider_resync = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))provider_resync; - this->public.provider_is_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))provider_is_pseudonym; - this->public.provider_gen_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))provider_gen_pseudonym; - this->public.provider_is_reauth = (identification_t*(*)(sim_manager_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))provider_is_reauth; - this->public.provider_gen_reauth = (identification_t*(*)(sim_manager_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))provider_gen_reauth; - this->public.add_hooks = (void(*)(sim_manager_t*, sim_hooks_t *hooks))add_hooks; - this->public.remove_hooks = (void(*)(sim_manager_t*, sim_hooks_t *hooks))remove_hooks; - this->public.message_hook = (void(*)(sim_manager_t*, simaka_message_t *message, bool inbound, bool decrypted))message_hook; - this->public.key_hook = (void(*)(sim_manager_t*, chunk_t k_encr, chunk_t k_auth))key_hook; - this->public.destroy = (void(*)(sim_manager_t*))destroy; - - this->cards = linked_list_create(); - this->providers = linked_list_create(); - this->hooks = linked_list_create(); + private_sim_manager_t *this; + + INIT(this, + .public = { + .add_card = _add_card, + .remove_card = _remove_card, + .card_get_triplet = _card_get_triplet, + .card_get_quintuplet = _card_get_quintuplet, + .card_resync = _card_resync, + .card_set_pseudonym = _card_set_pseudonym, + .card_get_pseudonym = _card_get_pseudonym, + .card_set_reauth = _card_set_reauth, + .card_get_reauth = _card_get_reauth, + .add_provider = _add_provider, + .remove_provider = _remove_provider, + .provider_get_triplet = _provider_get_triplet, + .provider_get_quintuplet = _provider_get_quintuplet, + .provider_resync = _provider_resync, + .provider_is_pseudonym = _provider_is_pseudonym, + .provider_gen_pseudonym = _provider_gen_pseudonym, + .provider_is_reauth = _provider_is_reauth, + .provider_gen_reauth = _provider_gen_reauth, + .add_hooks = _add_hooks, + .remove_hooks = _remove_hooks, + .message_hook = _message_hook, + .key_hook = _key_hook, + .destroy = _destroy, + }, + .cards = linked_list_create(), + .providers = linked_list_create(), + .hooks = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + ); return &this->public; } diff --git a/src/libcharon/sa/authenticators/eap/sim_manager.h b/src/libcharon/sa/authenticators/eap/sim_manager.h index 9aa661ac8..db4a65011 100644 --- a/src/libcharon/sa/authenticators/eap/sim_manager.h +++ b/src/libcharon/sa/authenticators/eap/sim_manager.h @@ -27,9 +27,6 @@ #include <sa/authenticators/eap/eap_method.h> typedef struct sim_manager_t sim_manager_t; -typedef struct sim_card_t sim_card_t; -typedef struct sim_provider_t sim_provider_t; -typedef struct sim_hooks_t sim_hooks_t; /** implemented in libsimaka, but we need it for the message hook */ typedef struct simaka_message_t simaka_message_t; @@ -45,229 +42,9 @@ typedef struct simaka_message_t simaka_message_t; #define AKA_AUTN_LEN 16 #define AKA_AUTS_LEN 14 -/** - * Interface for a (U)SIM card (used as EAP client). - * - * The SIM card completes triplets/quintuplets requested in a challenge - * received from the server. - * An implementation supporting only one of SIM/AKA authentication may - * implement the other methods with return_false()/return NOT_SUPPORTED/NULL. - */ -struct sim_card_t { - - /** - * Calculate SRES/KC from a RAND for SIM authentication. - * - * @param id permanent identity to get a triplet for - * @param rand RAND input buffer, fixed size 16 bytes - * @param sres SRES output buffer, fixed size 4 byte - * @param kc KC output buffer, fixed size 8 bytes - * @return TRUE if SRES/KC calculated, FALSE on error/wrong identity - */ - bool (*get_triplet)(sim_card_t *this, identification_t *id, - char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], - char kc[SIM_KC_LEN]); - - /** - * Calculate CK/IK/RES from RAND/AUTN for AKA authentication. - * - * If the received sequence number (in autn) is out of sync, INVALID_STATE - * is returned. - * The RES value is the only one with variable length. Pass a buffer - * of at least AKA_RES_MAX, the actual number of bytes is written to the - * res_len value. While the standard would allow any bit length between - * 32 and 128 bits, we support only full bytes for now. - * - * @param id permanent identity to request quintuplet for - * @param rand random value rand - * @param autn authentication token autn - * @param ck buffer receiving encryption key ck - * @param ik buffer receiving integrity key ik - * @param res buffer receiving authentication result res - * @param res_len nubmer of bytes written to res buffer - * @return SUCCESS, FAILED, or INVALID_STATE if out of sync - */ - status_t (*get_quintuplet)(sim_card_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], - char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], - char res[AKA_RES_MAX], int *res_len); - - /** - * Calculate AUTS from RAND for AKA resynchronization. - * - * @param id permanent identity to request quintuplet for - * @param rand random value rand - * @param auts resynchronization parameter auts - * @return TRUE if parameter generated successfully - */ - bool (*resync)(sim_card_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]); - - /** - * Set the pseudonym to use for next authentication. - * - * @param id permanent identity of the peer - * @param pseudonym pseudonym identity received from the server - */ - void (*set_pseudonym)(sim_card_t *this, identification_t *id, - identification_t *pseudonym); - - /** - * Get the pseudonym previously stored via set_pseudonym(). - * - * @param id permanent identity of the peer - * @return associated pseudonym identity, NULL if none stored - */ - identification_t* (*get_pseudonym)(sim_card_t *this, identification_t *id); - - /** - * Store parameters to use for the next fast reauthentication. - * - * @param id permanent identity of the peer - * @param next next fast reauthentication identity to use - * @param mk master key MK to store for reauthentication - * @param counter counter value to store, host order - */ - void (*set_reauth)(sim_card_t *this, identification_t *id, - identification_t *next, char mk[HASH_SIZE_SHA1], - u_int16_t counter); - - /** - * Retrieve parameters for fast reauthentication stored via set_reauth(). - * - * @param id permanent identity of the peer - * @param mk buffer receiving master key MK - * @param counter pointer receiving counter value, in host order - * @return fast reauthentication identity, NULL if not found - */ - identification_t* (*get_reauth)(sim_card_t *this, identification_t *id, - char mk[HASH_SIZE_SHA1], u_int16_t *counter); -}; - -/** - * Interface for a triplet/quintuplet provider (used as EAP server). - * - * A SIM provider hands out triplets for SIM authentication and quintuplets - * for AKA authentication. Multiple SIM provider instances can serve as - * authentication backend to authenticate clients using SIM/AKA. - * An implementation supporting only one of SIM/AKA authentication may - * implement the other methods with return_false(). - */ -struct sim_provider_t { - - /** - * Create a challenge for SIM authentication. - * - * @param id permanent identity of peer to gen triplet for - * @param rand RAND output buffer, fixed size 16 bytes - * @param sres SRES output buffer, fixed size 4 byte - * @param kc KC output buffer, fixed size 8 bytes - * @return TRUE if triplet received, FALSE otherwise - */ - bool (*get_triplet)(sim_provider_t *this, identification_t *id, - char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], - char kc[SIM_KC_LEN]); - - /** - * Create a challenge for AKA authentication. - * - * The XRES value is the only one with variable length. Pass a buffer - * of at least AKA_RES_MAX, the actual number of bytes is written to the - * xres_len value. While the standard would allow any bit length between - * 32 and 128 bits, we support only full bytes for now. - * - * @param id permanent identity of peer to create challenge for - * @param rand buffer receiving random value rand - * @param xres buffer receiving expected authentication result xres - * @param xres_len nubmer of bytes written to xres buffer - * @param ck buffer receiving encryption key ck - * @param ik buffer receiving integrity key ik - * @param autn authentication token autn - * @return TRUE if quintuplet generated successfully - */ - bool (*get_quintuplet)(sim_provider_t *this, identification_t *id, - char rand[AKA_RAND_LEN], - char xres[AKA_RES_MAX], int *xres_len, - char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], - char autn[AKA_AUTN_LEN]); - - /** - * Process AKA resynchroniusation request of a peer. - * - * @param id permanent identity of peer requesting resynchronisation - * @param rand random value rand - * @param auts synchronization parameter auts - * @return TRUE if resynchronized successfully - */ - bool (*resync)(sim_provider_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]); - - /** - * Check if peer uses a pseudonym, get permanent identity. - * - * @param id pseudonym identity candidate - * @return permanent identity, NULL if id not a pseudonym - */ - identification_t* (*is_pseudonym)(sim_provider_t *this, - identification_t *id); - - /** - * Generate a pseudonym identitiy for a given peer identity. - * - * @param id permanent identity to generate a pseudonym for - * @return generated pseudonym, NULL to not use a pseudonym identity - */ - identification_t* (*gen_pseudonym)(sim_provider_t *this, - identification_t *id); - - /** - * Check if peer uses reauthentication, retrieve reauth parameters. - * - * @param id reauthentication identity (candidate) - * @param mk buffer receiving master key MK - * @param counter pointer receiving current counter value, host order - * @return permanent identity, NULL if id not a reauth identity - */ - identification_t* (*is_reauth)(sim_provider_t *this, identification_t *id, - char mk[HASH_SIZE_SHA1], u_int16_t *counter); - - /** - * Generate a fast reauthentication identity, associated to a master key. - * - * @param id permanent peer identity - * @param mk master key to store along with generated identity - * @return fast reauthentication identity, NULL to not use reauth - */ - identification_t* (*gen_reauth)(sim_provider_t *this, identification_t *id, - char mk[HASH_SIZE_SHA1]); -}; - -/** - * Additional hooks invoked during EAP-SIM/AKA message processing. - */ -struct sim_hooks_t { - - /** - * SIM/AKA message parsing. - * - * As a SIM/AKA optionally contains encrypted attributes, the hook - * might get invoked twice, once before and once after decryption. - * - * @param message SIM/AKA message - * @param inbound TRUE for incoming messages, FALSE for outgoing - * @param decrypted TRUE if AT_ENCR_DATA has been decrypted - */ - void (*message)(sim_hooks_t *this, simaka_message_t *message, - bool inbound, bool decrypted); - - /** - * SIM/AKA encryption/authentication key hooks. - * - * @param k_encr derived SIM/AKA encryption key k_encr - * @param k_auth derived SIM/AKA authentication key k_auth - */ - void (*keys)(sim_hooks_t *this, chunk_t k_encr, chunk_t k_auth); -}; +#include <sa/authenticators/eap/sim_card.h> +#include <sa/authenticators/eap/sim_provider.h> +#include <sa/authenticators/eap/sim_hooks.h> /** * The SIM manager handles multiple (U)SIM cards/providers and hooks. diff --git a/src/libcharon/sa/authenticators/eap/sim_provider.h b/src/libcharon/sa/authenticators/eap/sim_provider.h new file mode 100644 index 000000000..191e094db --- /dev/null +++ b/src/libcharon/sa/authenticators/eap/sim_provider.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2008-2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup sim_provider sim_provider + * @{ @ingroup eap + */ + +#ifndef SIM_PROVIDER_H_ +#define SIM_PROVIDER_H_ + +typedef struct sim_provider_t sim_provider_t; + +/** + * Interface for a triplet/quintuplet provider (used as EAP server). + * + * A SIM provider hands out triplets for SIM authentication and quintuplets + * for AKA authentication. Multiple SIM provider instances can serve as + * authentication backend to authenticate clients using SIM/AKA. + * An implementation supporting only one of SIM/AKA authentication may + * implement the other methods with return_false(). + */ +struct sim_provider_t { + + /** + * Create a challenge for SIM authentication. + * + * @param id permanent identity of peer to gen triplet for + * @param rand RAND output buffer, fixed size 16 bytes + * @param sres SRES output buffer, fixed size 4 byte + * @param kc KC output buffer, fixed size 8 bytes + * @return TRUE if triplet received, FALSE otherwise + */ + bool (*get_triplet)(sim_provider_t *this, identification_t *id, + char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], + char kc[SIM_KC_LEN]); + + /** + * Create a challenge for AKA authentication. + * + * The XRES value is the only one with variable length. Pass a buffer + * of at least AKA_RES_MAX, the actual number of bytes is written to the + * xres_len value. While the standard would allow any bit length between + * 32 and 128 bits, we support only full bytes for now. + * + * @param id permanent identity of peer to create challenge for + * @param rand buffer receiving random value rand + * @param xres buffer receiving expected authentication result xres + * @param xres_len nubmer of bytes written to xres buffer + * @param ck buffer receiving encryption key ck + * @param ik buffer receiving integrity key ik + * @param autn authentication token autn + * @return TRUE if quintuplet generated successfully + */ + bool (*get_quintuplet)(sim_provider_t *this, identification_t *id, + char rand[AKA_RAND_LEN], + char xres[AKA_RES_MAX], int *xres_len, + char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], + char autn[AKA_AUTN_LEN]); + + /** + * Process AKA resynchroniusation request of a peer. + * + * @param id permanent identity of peer requesting resynchronisation + * @param rand random value rand + * @param auts synchronization parameter auts + * @return TRUE if resynchronized successfully + */ + bool (*resync)(sim_provider_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]); + + /** + * Check if peer uses a pseudonym, get permanent identity. + * + * @param id pseudonym identity candidate + * @return permanent identity, NULL if id not a pseudonym + */ + identification_t* (*is_pseudonym)(sim_provider_t *this, + identification_t *id); + + /** + * Generate a pseudonym identitiy for a given peer identity. + * + * @param id permanent identity to generate a pseudonym for + * @return generated pseudonym, NULL to not use a pseudonym identity + */ + identification_t* (*gen_pseudonym)(sim_provider_t *this, + identification_t *id); + + /** + * Check if peer uses reauthentication, retrieve reauth parameters. + * + * @param id reauthentication identity (candidate) + * @param mk buffer receiving master key MK + * @param counter pointer receiving current counter value, host order + * @return permanent identity, NULL if id not a reauth identity + */ + identification_t* (*is_reauth)(sim_provider_t *this, identification_t *id, + char mk[HASH_SIZE_SHA1], u_int16_t *counter); + + /** + * Generate a fast reauthentication identity, associated to a master key. + * + * @param id permanent peer identity + * @param mk master key to store along with generated identity + * @return fast reauthentication identity, NULL to not use reauth + */ + identification_t* (*gen_reauth)(sim_provider_t *this, identification_t *id, + char mk[HASH_SIZE_SHA1]); +}; + +#endif /** SIM_CARD_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap_authenticator.c b/src/libcharon/sa/authenticators/eap_authenticator.c index a5268e186..d442acb00 100644 --- a/src/libcharon/sa/authenticators/eap_authenticator.c +++ b/src/libcharon/sa/authenticators/eap_authenticator.c @@ -58,14 +58,11 @@ struct private_eap_authenticator_t { chunk_t sent_init; /** -<<<<<<< HEAD -======= * Reserved bytes of ID payload */ char reserved[3]; /** ->>>>>>> upstream/4.5.1 * Current EAP method processing */ eap_method_t *method; @@ -186,16 +183,18 @@ static eap_payload_t* server_initiate_eap(private_eap_authenticator_t *this, if (this->method) { action = "initiating"; + type = this->method->get_type(this->method, &vendor); if (this->method->initiate(this->method, &out) == NEED_MORE) { if (vendor) { - DBG1(DBG_IKE, "initiating EAP vendor type %d-%d method", - type, vendor); + DBG1(DBG_IKE, "initiating EAP vendor type %d-%d method (id 0x%02X)", + type, vendor, out->get_identifier(out)); } else { - DBG1(DBG_IKE, "initiating %N method", eap_type_names, type); + DBG1(DBG_IKE, "initiating %N method (id 0x%02X)", eap_type_names, + type, out->get_identifier(out)); } return out; } @@ -374,13 +373,13 @@ static eap_payload_t* client_process_eap(private_eap_authenticator_t *this, { if (vendor) { - DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d", - type, vendor); + DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d ", + "(id 0x%02X)", type, vendor, in->get_identifier(in)); } else { - DBG1(DBG_IKE, "server requested %N authentication", - eap_type_names, type); + DBG1(DBG_IKE, "server requested %N authentication (id 0x%02X)", + eap_type_names, type, in->get_identifier(in)); } this->method = load_method(this, type, vendor, EAP_PEER); if (!this->method) @@ -430,11 +429,7 @@ static bool verify_auth(private_eap_authenticator_t *this, message_t *message, other_id = this->ike_sa->get_other_id(this->ike_sa); keymat = this->ike_sa->get_keymat(this->ike_sa); auth_data = keymat->get_psk_sig(keymat, TRUE, init, nonce, -<<<<<<< HEAD - this->msk, other_id); -======= this->msk, other_id, this->reserved); ->>>>>>> upstream/4.5.1 recv_auth_data = auth_payload->get_data(auth_payload); if (!auth_data.len || !chunk_equals(auth_data, recv_auth_data)) { @@ -470,12 +465,8 @@ static void build_auth(private_eap_authenticator_t *this, message_t *message, DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N", my_id, auth_class_names, AUTH_CLASS_EAP); -<<<<<<< HEAD - auth_data = keymat->get_psk_sig(keymat, FALSE, init, nonce, this->msk, my_id); -======= auth_data = keymat->get_psk_sig(keymat, FALSE, init, nonce, this->msk, my_id, this->reserved); ->>>>>>> upstream/4.5.1 auth_payload = auth_payload_create(); auth_payload->set_auth_method(auth_payload, AUTH_PSK); auth_payload->set_data(auth_payload, auth_data); @@ -659,12 +650,8 @@ METHOD(authenticator_t, destroy, void, */ eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa, chunk_t received_nonce, chunk_t sent_nonce, -<<<<<<< HEAD - chunk_t received_init, chunk_t sent_init) -======= chunk_t received_init, chunk_t sent_init, char reserved[3]) ->>>>>>> upstream/4.5.1 { private_eap_authenticator_t *this; @@ -683,10 +670,7 @@ eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa, .sent_init = sent_init, .sent_nonce = sent_nonce, ); -<<<<<<< HEAD -======= memcpy(this->reserved, reserved, sizeof(this->reserved)); ->>>>>>> upstream/4.5.1 return &this->public; } @@ -696,12 +680,8 @@ eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa, */ eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa, chunk_t received_nonce, chunk_t sent_nonce, -<<<<<<< HEAD - chunk_t received_init, chunk_t sent_init) -======= chunk_t received_init, chunk_t sent_init, char reserved[3]) ->>>>>>> upstream/4.5.1 { private_eap_authenticator_t *this; @@ -720,10 +700,7 @@ eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa, .sent_init = sent_init, .sent_nonce = sent_nonce, ); -<<<<<<< HEAD -======= memcpy(this->reserved, reserved, sizeof(this->reserved)); ->>>>>>> upstream/4.5.1 return &this->public; } diff --git a/src/libcharon/sa/authenticators/eap_authenticator.h b/src/libcharon/sa/authenticators/eap_authenticator.h index 625084d4f..726411a18 100644 --- a/src/libcharon/sa/authenticators/eap_authenticator.h +++ b/src/libcharon/sa/authenticators/eap_authenticator.h @@ -75,20 +75,13 @@ struct eap_authenticator_t { * @param sent_nonce nonce sent in IKE_SA_INIT * @param received_init received IKE_SA_INIT message data * @param sent_init sent IKE_SA_INIT message data -<<<<<<< HEAD -======= * @param reserved reserved bytes of ID payload ->>>>>>> upstream/4.5.1 * @return EAP authenticator */ eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa, chunk_t received_nonce, chunk_t sent_nonce, -<<<<<<< HEAD - chunk_t received_init, chunk_t sent_init); -======= chunk_t received_init, chunk_t sent_init, char reserved[3]); ->>>>>>> upstream/4.5.1 /** * Create an authenticator to authenticate EAP clients. @@ -98,19 +91,12 @@ eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa, * @param sent_nonce nonce sent in IKE_SA_INIT * @param received_init received IKE_SA_INIT message data * @param sent_init sent IKE_SA_INIT message data -<<<<<<< HEAD -======= * @param reserved reserved bytes of ID payload ->>>>>>> upstream/4.5.1 * @return EAP authenticator */ eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa, chunk_t received_nonce, chunk_t sent_nonce, -<<<<<<< HEAD - chunk_t received_init, chunk_t sent_init); -======= chunk_t received_init, chunk_t sent_init, char reserved[3]); ->>>>>>> upstream/4.5.1 #endif /** EAP_AUTHENTICATOR_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/psk_authenticator.c b/src/libcharon/sa/authenticators/psk_authenticator.c index 9789ec93b..21fc0f9b8 100644 --- a/src/libcharon/sa/authenticators/psk_authenticator.c +++ b/src/libcharon/sa/authenticators/psk_authenticator.c @@ -45,14 +45,6 @@ struct private_psk_authenticator_t { * IKE_SA_INIT message data to include in AUTH calculation */ chunk_t ike_sa_init; -<<<<<<< HEAD -}; - -/* - * Implementation of authenticator_t.build for builder - */ -static status_t build(private_psk_authenticator_t *this, message_t *message) -======= /** * Reserved bytes of ID payload @@ -62,7 +54,6 @@ static status_t build(private_psk_authenticator_t *this, message_t *message) METHOD(authenticator_t, build, status_t, private_psk_authenticator_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { identification_t *my_id, *other_id; auth_payload_t *auth_payload; @@ -82,11 +73,7 @@ METHOD(authenticator_t, build, status_t, return NOT_FOUND; } auth_data = keymat->get_psk_sig(keymat, FALSE, this->ike_sa_init, -<<<<<<< HEAD - this->nonce, key->get_key(key), my_id); -======= this->nonce, key->get_key(key), my_id, this->reserved); ->>>>>>> upstream/4.5.1 key->destroy(key); DBG2(DBG_IKE, "successfully created shared key MAC"); auth_payload = auth_payload_create(); @@ -98,15 +85,8 @@ METHOD(authenticator_t, build, status_t, return SUCCESS; } -<<<<<<< HEAD -/** - * Implementation of authenticator_t.process for verifier - */ -static status_t process(private_psk_authenticator_t *this, message_t *message) -======= METHOD(authenticator_t, process, status_t, private_psk_authenticator_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { chunk_t auth_data, recv_auth_data; identification_t *my_id, *other_id; @@ -134,11 +114,7 @@ METHOD(authenticator_t, process, status_t, keys_found++; auth_data = keymat->get_psk_sig(keymat, TRUE, this->ike_sa_init, -<<<<<<< HEAD - this->nonce, key->get_key(key), other_id); -======= this->nonce, key->get_key(key), other_id, this->reserved); ->>>>>>> upstream/4.5.1 if (auth_data.len && chunk_equals(auth_data, recv_auth_data)) { DBG1(DBG_IKE, "authentication of '%Y' with %N successful", @@ -166,24 +142,8 @@ METHOD(authenticator_t, process, status_t, return SUCCESS; } -<<<<<<< HEAD -/** - * Implementation of authenticator_t.process for builder - * Implementation of authenticator_t.build for verifier - */ -static status_t return_failed() -{ - return FAILED; -} - -/** - * Implementation of authenticator_t.destroy. - */ -static void destroy(private_psk_authenticator_t *this) -======= METHOD(authenticator_t, destroy, void, private_psk_authenticator_t *this) ->>>>>>> upstream/4.5.1 { free(this); } @@ -192,20 +152,6 @@ METHOD(authenticator_t, destroy, void, * Described in header. */ psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa, -<<<<<<< HEAD - chunk_t received_nonce, chunk_t sent_init) -{ - private_psk_authenticator_t *this = malloc_thing(private_psk_authenticator_t); - - this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))build; - this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))return_failed; - this->public.authenticator.is_mutual = (bool(*)(authenticator_t*))return_false; - this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy; - - this->ike_sa = ike_sa; - this->ike_sa_init = sent_init; - this->nonce = received_nonce; -======= chunk_t received_nonce, chunk_t sent_init, char reserved[3]) { @@ -225,7 +171,6 @@ psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa, .nonce = received_nonce, ); memcpy(this->reserved, reserved, sizeof(this->reserved)); ->>>>>>> upstream/4.5.1 return &this->public; } @@ -234,20 +179,6 @@ psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa, * Described in header. */ psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa, -<<<<<<< HEAD - chunk_t sent_nonce, chunk_t received_init) -{ - private_psk_authenticator_t *this = malloc_thing(private_psk_authenticator_t); - - this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *messageh))return_failed; - this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process; - this->public.authenticator.is_mutual = (bool(*)(authenticator_t*))return_false; - this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy; - - this->ike_sa = ike_sa; - this->ike_sa_init = received_init; - this->nonce = sent_nonce; -======= chunk_t sent_nonce, chunk_t received_init, char reserved[3]) { @@ -267,7 +198,6 @@ psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa, .nonce = sent_nonce, ); memcpy(this->reserved, reserved, sizeof(this->reserved)); ->>>>>>> upstream/4.5.1 return &this->public; } diff --git a/src/libcharon/sa/authenticators/psk_authenticator.h b/src/libcharon/sa/authenticators/psk_authenticator.h index 2897c3fe2..8cf1a0f98 100644 --- a/src/libcharon/sa/authenticators/psk_authenticator.h +++ b/src/libcharon/sa/authenticators/psk_authenticator.h @@ -42,19 +42,12 @@ struct psk_authenticator_t { * @param ike_sa associated ike_sa * @param received_nonce nonce received in IKE_SA_INIT * @param sent_init sent IKE_SA_INIT message data -<<<<<<< HEAD - * @return PSK authenticator - */ -psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa, - chunk_t received_nonce, chunk_t sent_init); -======= * @param reserved reserved bytes of ID payload * @return PSK authenticator */ psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa, chunk_t received_nonce, chunk_t sent_init, char reserved[3]); ->>>>>>> upstream/4.5.1 /** * Create an authenticator to verify PSK signatures. @@ -62,18 +55,11 @@ psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa, * @param ike_sa associated ike_sa * @param sent_nonce nonce sent in IKE_SA_INIT * @param received_init received IKE_SA_INIT message data -<<<<<<< HEAD - * @return PSK authenticator - */ -psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa, - chunk_t sent_nonce, chunk_t received_init); -======= * @param reserved reserved bytes of ID payload * @return PSK authenticator */ psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa, chunk_t sent_nonce, chunk_t received_init, char reserved[3]); ->>>>>>> upstream/4.5.1 #endif /** PSK_AUTHENTICATOR_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/pubkey_authenticator.c b/src/libcharon/sa/authenticators/pubkey_authenticator.c index 030433db0..247891670 100644 --- a/src/libcharon/sa/authenticators/pubkey_authenticator.c +++ b/src/libcharon/sa/authenticators/pubkey_authenticator.c @@ -46,14 +46,6 @@ struct private_pubkey_authenticator_t { * IKE_SA_INIT message data to include in AUTH calculation */ chunk_t ike_sa_init; -<<<<<<< HEAD -}; - -/** - * Implementation of authenticator_t.build for builder - */ -static status_t build(private_pubkey_authenticator_t *this, message_t *message) -======= /** * Reserved bytes of ID payload @@ -63,7 +55,6 @@ static status_t build(private_pubkey_authenticator_t *this, message_t *message) METHOD(authenticator_t, build, status_t, private_pubkey_authenticator_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { chunk_t octets, auth_data; status_t status = FAILED; @@ -121,11 +112,7 @@ METHOD(authenticator_t, build, status_t, } keymat = this->ike_sa->get_keymat(this->ike_sa); octets = keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init, -<<<<<<< HEAD - this->nonce, id); -======= this->nonce, id, this->reserved); ->>>>>>> upstream/4.5.1 if (private->sign(private, scheme, octets, &auth_data)) { auth_payload = auth_payload_create(); @@ -144,15 +131,8 @@ METHOD(authenticator_t, build, status_t, return status; } -<<<<<<< HEAD -/** - * Implementation of authenticator_t.process for verifier - */ -static status_t process(private_pubkey_authenticator_t *this, message_t *message) -======= METHOD(authenticator_t, process, status_t, private_pubkey_authenticator_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { public_key_t *public; auth_method_t auth_method; @@ -196,11 +176,7 @@ METHOD(authenticator_t, process, status_t, id = this->ike_sa->get_other_id(this->ike_sa); keymat = this->ike_sa->get_keymat(this->ike_sa); octets = keymat->get_auth_octets(keymat, TRUE, this->ike_sa_init, -<<<<<<< HEAD - this->nonce, id); -======= this->nonce, id, this->reserved); ->>>>>>> upstream/4.5.1 auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); enumerator = lib->credmgr->create_public_enumerator(lib->credmgr, key_type, id, auth); @@ -231,24 +207,8 @@ METHOD(authenticator_t, process, status_t, return status; } -<<<<<<< HEAD -/** - * Implementation of authenticator_t.process for builder - * Implementation of authenticator_t.build for verifier - */ -static status_t return_failed() -{ - return FAILED; -} - -/** - * Implementation of authenticator_t.destroy. - */ -static void destroy(private_pubkey_authenticator_t *this) -======= METHOD(authenticator_t, destroy, void, private_pubkey_authenticator_t *this) ->>>>>>> upstream/4.5.1 { free(this); } @@ -257,20 +217,6 @@ METHOD(authenticator_t, destroy, void, * Described in header. */ pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa, -<<<<<<< HEAD - chunk_t received_nonce, chunk_t sent_init) -{ - private_pubkey_authenticator_t *this = malloc_thing(private_pubkey_authenticator_t); - - this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))build; - this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))return_failed; - this->public.authenticator.is_mutual = (bool(*)(authenticator_t*))return_false; - this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy; - - this->ike_sa = ike_sa; - this->ike_sa_init = sent_init; - this->nonce = received_nonce; -======= chunk_t received_nonce, chunk_t sent_init, char reserved[3]) { @@ -290,7 +236,6 @@ pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa, .nonce = received_nonce, ); memcpy(this->reserved, reserved, sizeof(this->reserved)); ->>>>>>> upstream/4.5.1 return &this->public; } @@ -299,20 +244,6 @@ pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa, * Described in header. */ pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa, -<<<<<<< HEAD - chunk_t sent_nonce, chunk_t received_init) -{ - private_pubkey_authenticator_t *this = malloc_thing(private_pubkey_authenticator_t); - - this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))return_failed; - this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process; - this->public.authenticator.is_mutual = (bool(*)(authenticator_t*))return_false; - this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy; - - this->ike_sa = ike_sa; - this->ike_sa_init = received_init; - this->nonce = sent_nonce; -======= chunk_t sent_nonce, chunk_t received_init, char reserved[3]) { @@ -332,7 +263,6 @@ pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa, .nonce = sent_nonce, ); memcpy(this->reserved, reserved, sizeof(this->reserved)); ->>>>>>> upstream/4.5.1 return &this->public; } diff --git a/src/libcharon/sa/authenticators/pubkey_authenticator.h b/src/libcharon/sa/authenticators/pubkey_authenticator.h index 9e2606b95..4c3937ecc 100644 --- a/src/libcharon/sa/authenticators/pubkey_authenticator.h +++ b/src/libcharon/sa/authenticators/pubkey_authenticator.h @@ -43,19 +43,12 @@ struct pubkey_authenticator_t { * @param ike_sa associated ike_sa * @param received_nonce nonce received in IKE_SA_INIT * @param sent_init sent IKE_SA_INIT message data -<<<<<<< HEAD - * @return public key authenticator - */ -pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa, - chunk_t received_nonce, chunk_t sent_init); -======= * @param reserved reserved bytes of ID payload * @return public key authenticator */ pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa, chunk_t received_nonce, chunk_t sent_init, char reserved[3]); ->>>>>>> upstream/4.5.1 /** * Create an authenticator to verify public key signatures. @@ -63,18 +56,11 @@ pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa, * @param ike_sa associated ike_sa * @param sent_nonce nonce sent in IKE_SA_INIT * @param received_init received IKE_SA_INIT message data -<<<<<<< HEAD - * @return public key authenticator - */ -pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa, - chunk_t sent_nonce, chunk_t received_init); -======= * @param reserved reserved bytes of ID payload * @return public key authenticator */ pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa, chunk_t sent_nonce, chunk_t received_init, char reserved[3]); ->>>>>>> upstream/4.5.1 #endif /** PUBKEY_AUTHENTICATOR_H_ @}*/ diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index a29e692fd..dc42ba787 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -559,21 +559,15 @@ METHOD(child_sa_t, alloc_cpi, u_int16_t, METHOD(child_sa_t, install, status_t, private_child_sa_t *this, chunk_t encr, chunk_t integ, u_int32_t spi, -<<<<<<< HEAD - u_int16_t cpi, bool inbound, linked_list_t *my_ts, -======= u_int16_t cpi, bool inbound, bool tfcv3, linked_list_t *my_ts, ->>>>>>> upstream/4.5.1 linked_list_t *other_ts) { u_int16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size; + u_int16_t esn = NO_EXT_SEQ_NUMBERS; traffic_selector_t *src_ts = NULL, *dst_ts = NULL; time_t now; lifetime_cfg_t *lifetime; -<<<<<<< HEAD -======= u_int32_t tfc = 0; ->>>>>>> upstream/4.5.1 host_t *src, *dst; status_t status; bool update = FALSE; @@ -598,14 +592,11 @@ METHOD(child_sa_t, install, status_t, dst = this->other_addr; this->other_spi = spi; this->other_cpi = cpi; -<<<<<<< HEAD -======= if (tfcv3) { tfc = this->config->get_tfc(this->config); } ->>>>>>> upstream/4.5.1 } DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound", @@ -618,6 +609,8 @@ METHOD(child_sa_t, install, status_t, &enc_alg, &size); this->proposal->get_algorithm(this->proposal, INTEGRITY_ALGORITHM, &int_alg, &size); + this->proposal->get_algorithm(this->proposal, EXTENDED_SEQUENCE_NUMBERS, + &esn, NULL); lifetime = this->config->get_lifetime(this->config); @@ -636,11 +629,7 @@ METHOD(child_sa_t, install, status_t, lifetime->time.rekey = 0; } -<<<<<<< HEAD - if (this->mode == MODE_BEET) -======= if (this->mode == MODE_BEET || this->mode == MODE_TRANSPORT) ->>>>>>> upstream/4.5.1 { /* BEET requires the bound address from the traffic selectors. * TODO: We add just the first traffic selector for now, as the @@ -659,13 +648,9 @@ METHOD(child_sa_t, install, status_t, status = hydra->kernel_interface->add_sa(hydra->kernel_interface, src, dst, spi, proto_ike2ip(this->protocol), this->reqid, -<<<<<<< HEAD - inbound ? this->mark_in : this->mark_out, -======= inbound ? this->mark_in : this->mark_out, tfc, ->>>>>>> upstream/4.5.1 lifetime, enc_alg, encr, int_alg, integ, this->mode, - this->ipcomp, cpi, this->encap, update, src_ts, dst_ts); + this->ipcomp, cpi, this->encap, esn, update, src_ts, dst_ts); free(lifetime); diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h index 513807b34..f17ef01ac 100644 --- a/src/libcharon/sa/child_sa.h +++ b/src/libcharon/sa/child_sa.h @@ -313,20 +313,13 @@ struct child_sa_t { * @param spi SPI to use, allocated for inbound * @param cpi CPI to use, allocated for outbound * @param inbound TRUE to install an inbound SA, FALSE for outbound -<<<<<<< HEAD -======= * @param tfcv3 TRUE if peer supports ESPv3 TFC ->>>>>>> upstream/4.5.1 * @param my_ts negotiated local traffic selector list * @param other_ts negotiated remote traffic selector list * @return SUCCESS or FAILED */ status_t (*install)(child_sa_t *this, chunk_t encr, chunk_t integ, -<<<<<<< HEAD - u_int32_t spi, u_int16_t cpi, bool inbound, -======= u_int32_t spi, u_int16_t cpi, bool inbound, bool tfcv3, ->>>>>>> upstream/4.5.1 linked_list_t *my_ts, linked_list_t *other_ts); /** * Install the policies using some traffic selectors. diff --git a/src/libcharon/sa/connect_manager.c b/src/libcharon/sa/connect_manager.c index f481f2059..972cc98ad 100644 --- a/src/libcharon/sa/connect_manager.c +++ b/src/libcharon/sa/connect_manager.c @@ -1194,14 +1194,10 @@ static job_requeue_t initiate_mediated(initiate_data_t *data) DBG1(DBG_IKE, "establishing mediated connection failed"); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa); } -<<<<<<< HEAD - charon->ike_sa_manager->checkin(charon->ike_sa_manager, sa); -======= else { charon->ike_sa_manager->checkin(charon->ike_sa_manager, sa); } ->>>>>>> upstream/4.5.1 } iterator->destroy(iterator); } diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 58d24b48c..2fc186fe8 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -50,10 +50,7 @@ #include <processing/jobs/send_dpd_job.h> #include <processing/jobs/send_keepalive_job.h> #include <processing/jobs/rekey_ike_sa_job.h> -<<<<<<< HEAD -======= #include <encoding/payloads/unknown_payload.h> ->>>>>>> upstream/4.5.1 #ifdef ME #include <sa/tasks/ike_me.h> @@ -563,16 +560,6 @@ METHOD(ike_sa_t, send_dpd, status_t, time_t diff, delay; delay = this->peer_cfg->get_dpd(this->peer_cfg); -<<<<<<< HEAD - - if (delay == 0) - { - /* DPD disabled */ - return SUCCESS; - } - -======= ->>>>>>> upstream/4.5.1 if (this->task_manager->busy(this->task_manager)) { /* an exchange is in the air, no need to start a DPD check */ @@ -585,11 +572,7 @@ METHOD(ike_sa_t, send_dpd, status_t, last_in = get_use_time(this, TRUE); now = time_monotonic(NULL); diff = now - last_in; -<<<<<<< HEAD - if (diff >= delay) -======= if (!delay || diff >= delay) ->>>>>>> upstream/4.5.1 { /* to long ago, initiate dead peer detection */ task_t *task; @@ -615,16 +598,11 @@ METHOD(ike_sa_t, send_dpd, status_t, } } /* recheck in "interval" seconds */ -<<<<<<< HEAD - job = (job_t*)send_dpd_job_create(this->ike_sa_id); - lib->scheduler->schedule_job(lib->scheduler, job, delay - diff); -======= if (delay) { job = (job_t*)send_dpd_job_create(this->ike_sa_id); lib->scheduler->schedule_job(lib->scheduler, job, delay - diff); } ->>>>>>> upstream/4.5.1 return SUCCESS; } @@ -699,14 +677,10 @@ METHOD(ike_sa_t, set_state, void, } /* start DPD checks */ -<<<<<<< HEAD - send_dpd(this); -======= if (this->peer_cfg->get_dpd(this->peer_cfg)) { send_dpd(this); } ->>>>>>> upstream/4.5.1 } break; } @@ -851,11 +825,7 @@ METHOD(ike_sa_t, float_ports, void, } METHOD(ike_sa_t, update_hosts, void, -<<<<<<< HEAD - private_ike_sa_t *this, host_t *me, host_t *other) -======= private_ike_sa_t *this, host_t *me, host_t *other, bool force) ->>>>>>> upstream/4.5.1 { bool update = FALSE; @@ -888,11 +858,7 @@ METHOD(ike_sa_t, update_hosts, void, if (!other->equals(other, this->other_host)) { /* update others adress if we are NOT NATed */ -<<<<<<< HEAD - if (!has_condition(this, COND_NAT_HERE)) -======= if (force || !has_condition(this, COND_NAT_HERE)) ->>>>>>> upstream/4.5.1 { set_other_host(this, other->clone(other)); update = TRUE; @@ -925,10 +891,6 @@ METHOD(ike_sa_t, update_hosts, void, METHOD(ike_sa_t, generate_message, status_t, private_ike_sa_t *this, message_t *message, packet_t **packet) { -<<<<<<< HEAD - this->stats[STAT_OUTBOUND] = time_monotonic(NULL); - message->set_ike_sa_id(message, this->ike_sa_id); -======= if (message->is_encoded(message)) { /* already done */ *packet = message->get_packet(message); @@ -937,7 +899,6 @@ METHOD(ike_sa_t, generate_message, status_t, this->stats[STAT_OUTBOUND] = time_monotonic(NULL); message->set_ike_sa_id(message, this->ike_sa_id); charon->bus->message(charon->bus, message, FALSE); ->>>>>>> upstream/4.5.1 return message->generate(message, this->keymat->get_aead(this->keymat, FALSE), packet); } @@ -946,11 +907,7 @@ METHOD(ike_sa_t, generate_message, status_t, * send a notify back to the sender */ static void send_notify_response(private_ike_sa_t *this, message_t *request, -<<<<<<< HEAD - notify_type_t type) -======= notify_type_t type, chunk_t data) ->>>>>>> upstream/4.5.1 { message_t *response; packet_t *packet; @@ -959,11 +916,7 @@ static void send_notify_response(private_ike_sa_t *this, message_t *request, response->set_exchange_type(response, request->get_exchange_type(request)); response->set_request(response, FALSE); response->set_message_id(response, request->get_message_id(request)); -<<<<<<< HEAD - response->add_notify(response, FALSE, type, chunk_empty); -======= response->add_notify(response, FALSE, type, data); ->>>>>>> upstream/4.5.1 if (this->my_host->is_anyaddr(this->my_host)) { this->my_host->destroy(this->my_host); @@ -1228,10 +1181,7 @@ METHOD(ike_sa_t, process_message, status_t, { status_t status; bool is_request; -<<<<<<< HEAD -======= u_int8_t type = 0; ->>>>>>> upstream/4.5.1 if (this->state == IKE_PASSIVE) { /* do not handle messages in passive state */ @@ -1242,11 +1192,6 @@ METHOD(ike_sa_t, process_message, status_t, status = message->parse_body(message, this->keymat->get_aead(this->keymat, TRUE)); -<<<<<<< HEAD - if (status != SUCCESS) - { - -======= if (status == SUCCESS) { /* check for unsupported critical payloads */ enumerator_t *enumerator; @@ -1270,7 +1215,6 @@ METHOD(ike_sa_t, process_message, status_t, } if (status != SUCCESS) { ->>>>>>> upstream/4.5.1 if (is_request) { switch (status) @@ -1279,40 +1223,28 @@ METHOD(ike_sa_t, process_message, status_t, DBG1(DBG_IKE, "critical unknown payloads found"); if (is_request) { -<<<<<<< HEAD - send_notify_response(this, message, UNSUPPORTED_CRITICAL_PAYLOAD); -======= send_notify_response(this, message, UNSUPPORTED_CRITICAL_PAYLOAD, chunk_from_thing(type)); this->task_manager->incr_mid(this->task_manager, FALSE); ->>>>>>> upstream/4.5.1 } break; case PARSE_ERROR: DBG1(DBG_IKE, "message parsing failed"); if (is_request) { -<<<<<<< HEAD - send_notify_response(this, message, INVALID_SYNTAX); -======= send_notify_response(this, message, INVALID_SYNTAX, chunk_empty); this->task_manager->incr_mid(this->task_manager, FALSE); ->>>>>>> upstream/4.5.1 } break; case VERIFY_ERROR: DBG1(DBG_IKE, "message verification failed"); if (is_request) { -<<<<<<< HEAD - send_notify_response(this, message, INVALID_SYNTAX); -======= send_notify_response(this, message, INVALID_SYNTAX, chunk_empty); this->task_manager->incr_mid(this->task_manager, FALSE); ->>>>>>> upstream/4.5.1 } break; case FAILED: @@ -1321,13 +1253,6 @@ METHOD(ike_sa_t, process_message, status_t, break; case INVALID_STATE: DBG1(DBG_IKE, "found encrypted message, but no keys available"); -<<<<<<< HEAD - if (is_request) - { - send_notify_response(this, message, INVALID_SYNTAX); - } -======= ->>>>>>> upstream/4.5.1 default: break; } @@ -1357,12 +1282,8 @@ METHOD(ike_sa_t, process_message, status_t, /* 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); -<<<<<<< HEAD - send_notify_response(this, message, NO_PROPOSAL_CHOSEN); -======= send_notify_response(this, message, NO_PROPOSAL_CHOSEN, chunk_empty); ->>>>>>> upstream/4.5.1 return DESTROY_ME; } /* add a timeout if peer does not establish it completely */ @@ -1652,7 +1573,7 @@ METHOD(ike_sa_t, reestablish, status_t, #endif /* ME */ )) { - DBG1(DBG_IKE, "unable to reestablish IKE_SA due asymetric setup"); + DBG1(DBG_IKE, "unable to reestablish IKE_SA due to asymmetric setup"); return FAILED; } @@ -1975,7 +1896,7 @@ METHOD(ike_sa_t, create_task_enumerator, enumerator_t*, return this->task_manager->create_task_enumerator(this->task_manager, queue); } -METHOD(ike_sa_t, inherit, status_t, +METHOD(ike_sa_t, inherit, void, private_ike_sa_t *this, ike_sa_t *other_public) { private_ike_sa_t *other = (private_ike_sa_t*)other_public; @@ -2056,8 +1977,6 @@ METHOD(ike_sa_t, inherit, status_t, lib->scheduler->schedule_job(lib->scheduler, (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE), delete); } - /* we have to initate here, there may be new tasks to handle */ - return this->task_manager->initiate(this->task_manager); } METHOD(ike_sa_t, destroy, void, @@ -2068,6 +1987,7 @@ METHOD(ike_sa_t, destroy, void, charon->bus->set_sa(charon->bus, &this->public); set_state(this, IKE_DESTROYING); + this->task_manager->destroy(this->task_manager); /* remove attributes first, as we pass the IKE_SA to the handler */ while (this->attributes->remove_last(this->attributes, @@ -2085,7 +2005,6 @@ METHOD(ike_sa_t, destroy, void, /* unset SA after here to avoid usage by the listeners */ charon->bus->set_sa(charon->bus, NULL); - this->task_manager->destroy(this->task_manager); this->keymat->destroy(this->keymat); if (this->my_virtual_ip) diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 1f96f9abd..69a74d8b7 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -343,14 +343,9 @@ struct ike_sa_t { * * @param me new local host address, or NULL * @param other new remote host address, or NULL -<<<<<<< HEAD - */ - void (*update_hosts)(ike_sa_t *this, host_t *me, host_t *other); -======= * @param force force update */ void (*update_hosts)(ike_sa_t *this, host_t *me, host_t *other, bool force); ->>>>>>> upstream/4.5.1 /** * Get the own identification. @@ -917,9 +912,8 @@ struct ike_sa_t { * As this call may initiate inherited tasks, a status is returned. * * @param other other task to inherit from - * @return DESTROY_ME if initiation of inherited task failed */ - status_t (*inherit) (ike_sa_t *this, ike_sa_t *other); + void (*inherit) (ike_sa_t *this, ike_sa_t *other); /** * Reset the IKE_SA, useable when initiating fails diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index ea31f5359..d695c7f7c 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -1,12 +1,7 @@ /* -<<<<<<< HEAD - * Copyright (C) 2008 Tobias Brunner - * Copyright (C) 2005-2008 Martin Willi -======= * Copyright (C) 2005-2011 Martin Willi * Copyright (C) 2011 revosec AG * Copyright (C) 2008 Tobias Brunner ->>>>>>> upstream/4.5.1 * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -91,13 +86,9 @@ struct entry_t { chunk_t init_hash; /** -<<<<<<< HEAD - * remote host address, required for DoS detection -======= * remote host address, required for DoS detection and duplicate * checking (host with same my_id and other_id is *not* considered * a duplicate if the address family differs) ->>>>>>> upstream/4.5.1 */ host_t *other; @@ -253,12 +244,9 @@ struct connected_peers_t { /** remote identity */ identification_t *other_id; -<<<<<<< HEAD -======= /** ip address family of peer */ int family; ->>>>>>> upstream/4.5.1 /** list of ike_sa_id_t objects of IKE_SAs between the two identities */ linked_list_t *sas; }; @@ -275,19 +263,12 @@ static void connected_peers_destroy(connected_peers_t *this) * Function that matches connected_peers_t objects by the given ids. */ static bool connected_peers_match(connected_peers_t *connected_peers, -<<<<<<< HEAD - identification_t *my_id, identification_t *other_id) -{ - return my_id->equals(my_id, connected_peers->my_id) && - other_id->equals(other_id, connected_peers->other_id); -======= identification_t *my_id, identification_t *other_id, uintptr_t family) { return my_id->equals(my_id, connected_peers->my_id) && other_id->equals(other_id, connected_peers->other_id) && family == connected_peers->family; ->>>>>>> upstream/4.5.1 } typedef struct segment_t segment_t; @@ -423,11 +404,7 @@ static void lock_all_segments(private_ike_sa_manager_t *this) { u_int i; -<<<<<<< HEAD - for (i = 0; i < this->segment_count; ++i) -======= for (i = 0; i < this->segment_count; i++) ->>>>>>> upstream/4.5.1 { this->segments[i].mutex->lock(this->segments[i].mutex); } @@ -440,11 +417,7 @@ static void unlock_all_segments(private_ike_sa_manager_t *this) { u_int i; -<<<<<<< HEAD - for (i = 0; i < this->segment_count; ++i) -======= for (i = 0; i < this->segment_count; i++) ->>>>>>> upstream/4.5.1 { this->segments[i].mutex->unlock(this->segments[i].mutex); } @@ -488,15 +461,8 @@ struct private_enumerator_t { enumerator_t *current; }; -<<<<<<< HEAD -/** - * Implementation of private_enumerator_t.enumerator.enumerate. - */ -static bool enumerate(private_enumerator_t *this, entry_t **entry, u_int *segment) -======= METHOD(enumerator_t, enumerate, bool, private_enumerator_t *this, entry_t **entry, u_int *segment) ->>>>>>> upstream/4.5.1 { if (this->entry) { @@ -542,15 +508,8 @@ METHOD(enumerator_t, enumerate, bool, return FALSE; } -<<<<<<< HEAD -/** - * Implementation of private_enumerator_t.enumerator.destroy. - */ -static void enumerator_destroy(private_enumerator_t *this) -======= METHOD(enumerator_t, enumerator_destroy, void, private_enumerator_t *this) ->>>>>>> upstream/4.5.1 { if (this->entry) { @@ -569,18 +528,6 @@ METHOD(enumerator_t, enumerator_destroy, void, */ static enumerator_t* create_table_enumerator(private_ike_sa_manager_t *this) { -<<<<<<< HEAD - private_enumerator_t *enumerator = malloc_thing(private_enumerator_t); - - enumerator->enumerator.enumerate = (void*)enumerate; - enumerator->enumerator.destroy = (void*)enumerator_destroy; - enumerator->manager = this; - enumerator->segment = 0; - enumerator->entry = NULL; - enumerator->row = 0; - enumerator->current = NULL; - -======= private_enumerator_t *enumerator; INIT(enumerator, @@ -590,7 +537,6 @@ static enumerator_t* create_table_enumerator(private_ike_sa_manager_t *this) }, .manager = this, ); ->>>>>>> upstream/4.5.1 return &enumerator->enumerator; } @@ -601,13 +547,6 @@ static enumerator_t* create_table_enumerator(private_ike_sa_manager_t *this) static u_int put_entry(private_ike_sa_manager_t *this, entry_t *entry) { linked_list_t *list; -<<<<<<< HEAD - u_int row = ike_sa_id_hash(entry->ike_sa_id) & this->table_mask; - u_int segment = row & this->segment_mask; - - lock_single_segment(this, segment); - if ((list = this->ike_sa_table[row]) == NULL) -======= u_int row, segment; row = ike_sa_id_hash(entry->ike_sa_id) & this->table_mask; @@ -616,7 +555,6 @@ static u_int put_entry(private_ike_sa_manager_t *this, entry_t *entry) lock_single_segment(this, segment); list = this->ike_sa_table[row]; if (!list) ->>>>>>> upstream/4.5.1 { list = this->ike_sa_table[row] = linked_list_create(); } @@ -632,16 +570,6 @@ static u_int put_entry(private_ike_sa_manager_t *this, entry_t *entry) static void remove_entry(private_ike_sa_manager_t *this, entry_t *entry) { linked_list_t *list; -<<<<<<< HEAD - u_int row = ike_sa_id_hash(entry->ike_sa_id) & this->table_mask; - u_int segment = row & this->segment_mask; - - if ((list = this->ike_sa_table[row]) != NULL) - { - entry_t *current; - - enumerator_t *enumerator = list->create_enumerator(list); -======= u_int row, segment; row = ike_sa_id_hash(entry->ike_sa_id) & this->table_mask; @@ -653,7 +581,6 @@ static void remove_entry(private_ike_sa_manager_t *this, entry_t *entry) enumerator_t *enumerator; enumerator = list->create_enumerator(list); ->>>>>>> upstream/4.5.1 while (enumerator->enumerate(enumerator, ¤t)) { if (current == entry) @@ -691,13 +618,6 @@ static status_t get_entry_by_match_function(private_ike_sa_manager_t *this, { entry_t *current; linked_list_t *list; -<<<<<<< HEAD - u_int row = ike_sa_id_hash(ike_sa_id) & this->table_mask; - u_int seg = row & this->segment_mask; - - lock_single_segment(this, seg); - if ((list = this->ike_sa_table[row]) != NULL) -======= u_int row, seg; row = ike_sa_id_hash(ike_sa_id) & this->table_mask; @@ -706,7 +626,6 @@ static status_t get_entry_by_match_function(private_ike_sa_manager_t *this, lock_single_segment(this, seg); list = this->ike_sa_table[row]; if (list) ->>>>>>> upstream/4.5.1 { if (list->find_first(list, match, (void**)¤t, p1, p2) == SUCCESS) { @@ -790,21 +709,6 @@ static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry) { half_open_t *half_open = NULL; linked_list_t *list; -<<<<<<< HEAD - chunk_t addr = entry->other->get_address(entry->other); - u_int row = chunk_hash(addr) & this->table_mask; - u_int segment = row & this->segment_mask; - - rwlock_t *lock = this->half_open_segments[segment].lock; - lock->write_lock(lock); - if ((list = this->half_open_table[row]) == NULL) - { - list = this->half_open_table[row] = linked_list_create(); - } - else - { - half_open_t *current; -======= chunk_t addr; u_int row, segment; rwlock_t *lock; @@ -819,7 +723,6 @@ static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry) { half_open_t *current; ->>>>>>> upstream/4.5.1 if (list->find_first(list, (linked_list_match_t)half_open_match, (void**)¤t, &addr) == SUCCESS) { @@ -828,14 +731,6 @@ static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry) this->half_open_segments[segment].count++; } } -<<<<<<< HEAD - - if (!half_open) - { - half_open = malloc_thing(half_open_t); - half_open->other = chunk_clone(addr); - half_open->count = 1; -======= else { list = this->half_open_table[row] = linked_list_create(); @@ -847,7 +742,6 @@ static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry) .other = chunk_clone(addr), .count = 1, ); ->>>>>>> upstream/4.5.1 list->insert_last(list, half_open); this->half_open_segments[segment].count++; } @@ -860,18 +754,6 @@ static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry) static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry) { linked_list_t *list; -<<<<<<< HEAD - chunk_t addr = entry->other->get_address(entry->other); - u_int row = chunk_hash(addr) & this->table_mask; - u_int segment = row & this->segment_mask; - - rwlock_t *lock = this->half_open_segments[segment].lock; - lock->write_lock(lock); - if ((list = this->half_open_table[row]) != NULL) - { - half_open_t *current; - enumerator_t *enumerator = list->create_enumerator(list); -======= chunk_t addr; u_int row, segment; rwlock_t *lock; @@ -888,7 +770,6 @@ static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry) enumerator_t *enumerator; enumerator = list->create_enumerator(list); ->>>>>>> upstream/4.5.1 while (enumerator->enumerate(enumerator, ¤t)) { if (half_open_match(current, &addr)) @@ -912,26 +793,6 @@ static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry) */ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry) { -<<<<<<< HEAD - linked_list_t *list; - connected_peers_t *connected_peers = NULL; - chunk_t my_id = entry->my_id->get_encoding(entry->my_id), - other_id = entry->other_id->get_encoding(entry->other_id); - u_int row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask; - u_int segment = row & this->segment_mask; - - rwlock_t *lock = this->connected_peers_segments[segment].lock; - lock->write_lock(lock); - if ((list = this->connected_peers_table[row]) == NULL) - { - list = this->connected_peers_table[row] = linked_list_create(); - } - else - { - connected_peers_t *current; - if (list->find_first(list, (linked_list_match_t)connected_peers_match, - (void**)¤t, entry->my_id, entry->other_id) == SUCCESS) -======= connected_peers_t *connected_peers = NULL; chunk_t my_id, other_id; linked_list_t *list; @@ -952,7 +813,6 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry) if (list->find_first(list, (linked_list_match_t)connected_peers_match, (void**)¤t, entry->my_id, entry->other_id, (uintptr_t)entry->other->get_family(entry->other)) == SUCCESS) ->>>>>>> upstream/4.5.1 { connected_peers = current; if (connected_peers->sas->find_first(connected_peers->sas, @@ -964,15 +824,6 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry) } } } -<<<<<<< HEAD - - if (!connected_peers) - { - connected_peers = malloc_thing(connected_peers_t); - connected_peers->my_id = entry->my_id->clone(entry->my_id); - connected_peers->other_id = entry->other_id->clone(entry->other_id); - connected_peers->sas = linked_list_create(); -======= else { list = this->connected_peers_table[row] = linked_list_create(); @@ -986,7 +837,6 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry) .family = entry->other->get_family(entry->other), .sas = linked_list_create(), ); ->>>>>>> upstream/4.5.1 list->insert_last(list, connected_peers); } connected_peers->sas->insert_last(connected_peers->sas, @@ -1000,26 +850,6 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry) */ static void remove_connected_peers(private_ike_sa_manager_t *this, entry_t *entry) { -<<<<<<< HEAD - linked_list_t *list; - chunk_t my_id = entry->my_id->get_encoding(entry->my_id), - other_id = entry->other_id->get_encoding(entry->other_id); - u_int row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask; - u_int segment = row & this->segment_mask; - - rwlock_t *lock = this->connected_peers_segments[segment].lock; - lock->write_lock(lock); - if ((list = this->connected_peers_table[row]) != NULL) - { - connected_peers_t *current; - enumerator_t *enumerator = list->create_enumerator(list); - while (enumerator->enumerate(enumerator, ¤t)) - { - if (connected_peers_match(current, entry->my_id, entry->other_id)) - { - ike_sa_id_t *ike_sa_id; - enumerator_t *inner = current->sas->create_enumerator(current->sas); -======= chunk_t my_id, other_id; linked_list_t *list; u_int row, segment; @@ -1048,7 +878,6 @@ static void remove_connected_peers(private_ike_sa_manager_t *this, entry_t *entr enumerator_t *inner; inner = current->sas->create_enumerator(current->sas); ->>>>>>> upstream/4.5.1 while (inner->enumerate(inner, &ike_sa_id)) { if (ike_sa_id->equals(ike_sa_id, entry->ike_sa_id)) @@ -1074,22 +903,6 @@ static void remove_connected_peers(private_ike_sa_manager_t *this, entry_t *entr } /** -<<<<<<< HEAD - * Implementation of private_ike_sa_manager_t.get_next_spi. - */ -static u_int64_t get_next_spi(private_ike_sa_manager_t *this) -{ - u_int64_t spi; - - this->rng->get_bytes(this->rng, sizeof(spi), (u_int8_t*)&spi); - return spi; -} - -/** - * Implementation of of ike_sa_manager.checkout. - */ -static ike_sa_t* checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id) -======= * Get a random SPI for new IKE_SAs */ static u_int64_t get_spi(private_ike_sa_manager_t *this) @@ -1105,7 +918,6 @@ static u_int64_t get_spi(private_ike_sa_manager_t *this) METHOD(ike_sa_manager_t, checkout, ike_sa_t*, private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id) ->>>>>>> upstream/4.5.1 { ike_sa_t *ike_sa = NULL; entry_t *entry; @@ -1128,27 +940,6 @@ METHOD(ike_sa_manager_t, checkout, ike_sa_t*, return ike_sa; } -<<<<<<< HEAD -/** - * Implementation of of ike_sa_manager.checkout_new. - */ -static ike_sa_t *checkout_new(private_ike_sa_manager_t* this, bool initiator) -{ - ike_sa_id_t *ike_sa_id; - ike_sa_t *ike_sa; - entry_t *entry; - u_int segment; - - if (initiator) - { - ike_sa_id = ike_sa_id_create(get_next_spi(this), 0, TRUE); - } - else - { - ike_sa_id = ike_sa_id_create(0, get_next_spi(this), FALSE); - } - ike_sa = ike_sa_create(ike_sa_id); -======= METHOD(ike_sa_manager_t, checkout_new, ike_sa_t*, private_ike_sa_manager_t* this, bool initiator) { @@ -1165,63 +956,30 @@ METHOD(ike_sa_manager_t, checkout_new, ike_sa_t*, } ike_sa = ike_sa_create(ike_sa_id); ike_sa_id->destroy(ike_sa_id); ->>>>>>> upstream/4.5.1 DBG2(DBG_MGR, "created IKE_SA %s[%u]", ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa)); -<<<<<<< HEAD - if (!initiator) - { - ike_sa_id->destroy(ike_sa_id); - return ike_sa; - } - - entry = entry_create(); - entry->ike_sa_id = ike_sa_id; - entry->ike_sa = ike_sa; - segment = put_entry(this, entry); - entry->checked_out = TRUE; - unlock_single_segment(this, segment); - return entry->ike_sa; -} - -/** - * Implementation of of ike_sa_manager.checkout_by_message. - */ -static ike_sa_t* checkout_by_message(private_ike_sa_manager_t* this, - message_t *message) -======= return ike_sa; } METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*, private_ike_sa_manager_t* this, message_t *message) ->>>>>>> upstream/4.5.1 { u_int segment; entry_t *entry; ike_sa_t *ike_sa = NULL; -<<<<<<< HEAD - ike_sa_id_t *id = message->get_ike_sa_id(message); - -======= ike_sa_id_t *id; id = message->get_ike_sa_id(message); ->>>>>>> upstream/4.5.1 id = id->clone(id); id->switch_initiator(id); DBG2(DBG_MGR, "checkout IKE_SA by message"); if (message->get_request(message) && -<<<<<<< HEAD - message->get_exchange_type(message) == IKE_SA_INIT) -======= message->get_exchange_type(message) == IKE_SA_INIT && this->hasher) ->>>>>>> upstream/4.5.1 { /* IKE_SA_INIT request. Check for an IKE_SA with such a message hash. */ chunk_t data, hash; @@ -1257,11 +1015,7 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*, message->get_exchange_type(message) == IKE_SA_INIT) { /* no IKE_SA found, create a new one */ -<<<<<<< HEAD - id->set_responder_spi(id, get_next_spi(this)); -======= id->set_responder_spi(id, get_spi(this)); ->>>>>>> upstream/4.5.1 entry = entry_create(); entry->ike_sa = ike_sa_create(id); entry->ike_sa_id = id->clone(id); @@ -1321,16 +1075,8 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*, return ike_sa; } -<<<<<<< HEAD -/** - * Implementation of of ike_sa_manager.checkout_by_config. - */ -static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this, - peer_cfg_t *peer_cfg) -======= METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*, private_ike_sa_manager_t *this, peer_cfg_t *peer_cfg) ->>>>>>> upstream/4.5.1 { enumerator_t *enumerator; entry_t *entry; @@ -1385,16 +1131,8 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*, return ike_sa; } -<<<<<<< HEAD -/** - * Implementation of of ike_sa_manager.checkout_by_id. - */ -static ike_sa_t* checkout_by_id(private_ike_sa_manager_t *this, u_int32_t id, - bool child) -======= METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*, private_ike_sa_manager_t *this, u_int32_t id, bool child) ->>>>>>> upstream/4.5.1 { enumerator_t *enumerator; iterator_t *children; @@ -1447,16 +1185,8 @@ METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*, return ike_sa; } -<<<<<<< HEAD -/** - * Implementation of of ike_sa_manager.checkout_by_name. - */ -static ike_sa_t* checkout_by_name(private_ike_sa_manager_t *this, char *name, - bool child) -======= METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*, private_ike_sa_manager_t *this, char *name, bool child) ->>>>>>> upstream/4.5.1 { enumerator_t *enumerator; iterator_t *children; @@ -1521,22 +1251,6 @@ static bool enumerator_filter(private_ike_sa_manager_t *this, return FALSE; } -<<<<<<< HEAD -/** - * Implementation of ike_sa_manager_t.create_enumerator. - */ -static enumerator_t *create_enumerator(private_ike_sa_manager_t* this) -{ - return enumerator_create_filter( - create_table_enumerator(this), - (void*)enumerator_filter, this, NULL); -} - -/** - * Implementation of ike_sa_manager_t.checkin. - */ -static void checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa) -======= METHOD(ike_sa_manager_t, create_enumerator, enumerator_t*, private_ike_sa_manager_t* this) { @@ -1546,7 +1260,6 @@ METHOD(ike_sa_manager_t, create_enumerator, enumerator_t*, METHOD(ike_sa_manager_t, checkin, void, private_ike_sa_manager_t *this, ike_sa_t *ike_sa) ->>>>>>> upstream/4.5.1 { /* to check the SA back in, we look for the pointer of the ike_sa * in all entries. @@ -1611,25 +1324,16 @@ METHOD(ike_sa_manager_t, checkin, void, segment = put_entry(this, entry); } -<<<<<<< HEAD - /* apply identities for duplicate test (only as responder) */ - if (!entry->ike_sa_id->is_initiator(entry->ike_sa_id) && - ike_sa->get_state(ike_sa) == IKE_ESTABLISHED && -======= /* apply identities for duplicate test */ if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED && ->>>>>>> upstream/4.5.1 entry->my_id == NULL && entry->other_id == NULL) { entry->my_id = my_id->clone(my_id); entry->other_id = other_id->clone(other_id); -<<<<<<< HEAD -======= if (!entry->other) { entry->other = other->clone(other); } ->>>>>>> upstream/4.5.1 put_connected_peers(this, entry); } @@ -1638,15 +1342,8 @@ METHOD(ike_sa_manager_t, checkin, void, charon->bus->set_sa(charon->bus, NULL); } -<<<<<<< HEAD -/** - * Implementation of ike_sa_manager_t.checkin_and_destroy. - */ -static void checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ike_sa) -======= METHOD(ike_sa_manager_t, checkin_and_destroy, void, private_ike_sa_manager_t *this, ike_sa_t *ike_sa) ->>>>>>> upstream/4.5.1 { /* deletion is a bit complex, we must ensure that no thread is waiting for * this SA. @@ -1683,12 +1380,7 @@ METHOD(ike_sa_manager_t, checkin_and_destroy, void, { remove_half_open(this, entry); } -<<<<<<< HEAD - if (!entry->ike_sa_id->is_initiator(entry->ike_sa_id) && - entry->my_id && entry->other_id) -======= if (entry->my_id && entry->other_id) ->>>>>>> upstream/4.5.1 { remove_connected_peers(this, entry); } @@ -1705,16 +1397,8 @@ METHOD(ike_sa_manager_t, checkin_and_destroy, void, charon->bus->set_sa(charon->bus, NULL); } -<<<<<<< HEAD - -/** - * Implementation of ike_sa_manager_t.check_uniqueness. - */ -static bool check_uniqueness(private_ike_sa_manager_t *this, ike_sa_t *ike_sa) -======= METHOD(ike_sa_manager_t, check_uniqueness, bool, private_ike_sa_manager_t *this, ike_sa_t *ike_sa, bool force_replace) ->>>>>>> upstream/4.5.1 { bool cancel = FALSE; peer_cfg_t *peer_cfg; @@ -1728,11 +1412,7 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool, peer_cfg = ike_sa->get_peer_cfg(ike_sa); policy = peer_cfg->get_unique_policy(peer_cfg); -<<<<<<< HEAD - if (policy == UNIQUE_NO) -======= if (policy == UNIQUE_NO && !force_replace) ->>>>>>> upstream/4.5.1 { return FALSE; } @@ -1746,14 +1426,6 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool, lock = this->connected_peers_segments[segment & this->segment_mask].lock; lock->read_lock(lock); -<<<<<<< HEAD - if ((list = this->connected_peers_table[row]) != NULL) - { - connected_peers_t *current; - - if (list->find_first(list, (linked_list_match_t)connected_peers_match, - (void**)¤t, me, other) == SUCCESS) -======= list = this->connected_peers_table[row]; if (list) { @@ -1764,7 +1436,6 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool, if (list->find_first(list, (linked_list_match_t)connected_peers_match, (void**)¤t, me, other, (uintptr_t)other_host->get_family(other_host)) == SUCCESS) ->>>>>>> upstream/4.5.1 { /* clone the list, so we can release the lock */ duplicate_ids = current->sas->clone_offset(current->sas, @@ -1789,8 +1460,6 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool, { continue; } -<<<<<<< HEAD -======= if (force_replace) { DBG1(DBG_IKE, "destroying duplicate IKE_SA for peer '%Y', " @@ -1798,7 +1467,6 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool, checkin_and_destroy(this, duplicate); continue; } ->>>>>>> upstream/4.5.1 peer_cfg = duplicate->get_peer_cfg(duplicate); if (peer_cfg && peer_cfg->equals(peer_cfg, ike_sa->get_peer_cfg(ike_sa))) { @@ -1843,13 +1511,6 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool, return cancel; } -<<<<<<< HEAD -/** - * Implementation of ike_sa_manager_t.get_half_open_count. - */ -static int get_half_open_count(private_ike_sa_manager_t *this, host_t *ip) -{ -======= METHOD(ike_sa_manager_t, has_contact, bool, private_ike_sa_manager_t *this, identification_t *me, identification_t *other, int family) @@ -1885,24 +1546,14 @@ METHOD(ike_sa_manager_t, get_half_open_count, int, u_int segment, row; rwlock_t *lock; chunk_t addr; ->>>>>>> upstream/4.5.1 int count = 0; if (ip) { -<<<<<<< HEAD - linked_list_t *list; - chunk_t addr = ip->get_address(ip); - u_int row = chunk_hash(addr) & this->table_mask; - u_int segment = row & this->segment_mask; - - rwlock_t *lock = this->half_open_segments[segment & this->segment_mask].lock; -======= addr = ip->get_address(ip); row = chunk_hash(addr) & this->table_mask; segment = row & this->segment_mask; lock = this->half_open_segments[segment & this->segment_mask].lock; ->>>>>>> upstream/4.5.1 lock->read_lock(lock); if ((list = this->half_open_table[row]) != NULL) { @@ -1918,38 +1569,19 @@ METHOD(ike_sa_manager_t, get_half_open_count, int, } else { -<<<<<<< HEAD - u_int segment; - - for (segment = 0; segment < this->segment_count; ++segment) - { - rwlock_t *lock; -======= for (segment = 0; segment < this->segment_count; segment++) { ->>>>>>> upstream/4.5.1 lock = this->half_open_segments[segment & this->segment_mask].lock; lock->read_lock(lock); count += this->half_open_segments[segment].count; lock->unlock(lock); } } -<<<<<<< HEAD - - return count; -} - -/** - * Implementation of ike_sa_manager_t.flush. - */ -static void flush(private_ike_sa_manager_t *this) -======= return count; } METHOD(ike_sa_manager_t, flush, void, private_ike_sa_manager_t *this) ->>>>>>> upstream/4.5.1 { /* destroy all list entries */ enumerator_t *enumerator; @@ -2013,12 +1645,7 @@ METHOD(ike_sa_manager_t, flush, void, { remove_half_open(this, entry); } -<<<<<<< HEAD - if (!entry->ike_sa_id->is_initiator(entry->ike_sa_id) && - entry->my_id && entry->other_id) -======= if (entry->my_id && entry->other_id) ->>>>>>> upstream/4.5.1 { remove_connected_peers(this, entry); } @@ -2030,34 +1657,6 @@ METHOD(ike_sa_manager_t, flush, void, unlock_all_segments(this); this->rng->destroy(this->rng); -<<<<<<< HEAD - this->hasher->destroy(this->hasher); -} - -/** - * Implementation of ike_sa_manager_t.destroy. - */ -static void destroy(private_ike_sa_manager_t *this) -{ - u_int i; - - for (i = 0; i < this->table_size; ++i) - { - linked_list_t *list; - - if ((list = this->ike_sa_table[i]) != NULL) - { - list->destroy(list); - } - if ((list = this->half_open_table[i]) != NULL) - { - list->destroy(list); - } - if ((list = this->connected_peers_table[i]) != NULL) - { - list->destroy(list); - } -======= this->rng = NULL; this->hasher->destroy(this->hasher); this->hasher = NULL; @@ -2073,16 +1672,11 @@ METHOD(ike_sa_manager_t, destroy, void, DESTROY_IF(this->ike_sa_table[i]); DESTROY_IF(this->half_open_table[i]); DESTROY_IF(this->connected_peers_table[i]); ->>>>>>> upstream/4.5.1 } free(this->ike_sa_table); free(this->half_open_table); free(this->connected_peers_table); -<<<<<<< HEAD - for (i = 0; i < this->segment_count; ++i) -======= for (i = 0; i < this->segment_count; i++) ->>>>>>> upstream/4.5.1 { this->segments[i].mutex->destroy(this->segments[i].mutex); this->half_open_segments[i].lock->destroy(this->half_open_segments[i].lock); @@ -2118,27 +1712,6 @@ static u_int get_nearest_powerof2(u_int n) */ ike_sa_manager_t *ike_sa_manager_create() { -<<<<<<< HEAD - u_int i; - private_ike_sa_manager_t *this = malloc_thing(private_ike_sa_manager_t); - - /* assign public functions */ - this->public.flush = (void(*)(ike_sa_manager_t*))flush; - this->public.destroy = (void(*)(ike_sa_manager_t*))destroy; - this->public.checkout = (ike_sa_t*(*)(ike_sa_manager_t*, ike_sa_id_t*))checkout; - this->public.checkout_new = (ike_sa_t*(*)(ike_sa_manager_t*,bool))checkout_new; - this->public.checkout_by_message = (ike_sa_t*(*)(ike_sa_manager_t*,message_t*))checkout_by_message; - this->public.checkout_by_config = (ike_sa_t*(*)(ike_sa_manager_t*,peer_cfg_t*))checkout_by_config; - this->public.checkout_by_id = (ike_sa_t*(*)(ike_sa_manager_t*,u_int32_t,bool))checkout_by_id; - this->public.checkout_by_name = (ike_sa_t*(*)(ike_sa_manager_t*,char*,bool))checkout_by_name; - this->public.check_uniqueness = (bool(*)(ike_sa_manager_t*, ike_sa_t *ike_sa))check_uniqueness; - this->public.create_enumerator = (enumerator_t*(*)(ike_sa_manager_t*))create_enumerator; - this->public.checkin = (void(*)(ike_sa_manager_t*,ike_sa_t*))checkin; - this->public.checkin_and_destroy = (void(*)(ike_sa_manager_t*,ike_sa_t*))checkin_and_destroy; - this->public.get_half_open_count = (int(*)(ike_sa_manager_t*,host_t*))get_half_open_count; - - /* initialize private variables */ -======= private_ike_sa_manager_t *this; u_int i; @@ -2161,7 +1734,6 @@ ike_sa_manager_t *ike_sa_manager_create() }, ); ->>>>>>> upstream/4.5.1 this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_PREFERRED); if (this->hasher == NULL) { @@ -2177,10 +1749,7 @@ ike_sa_manager_t *ike_sa_manager_create() free(this); return NULL; } -<<<<<<< HEAD -======= ->>>>>>> upstream/4.5.1 this->table_size = get_nearest_powerof2(lib->settings->get_int(lib->settings, "charon.ikesa_table_size", DEFAULT_HASHTABLE_SIZE)); this->table_size = max(1, min(this->table_size, MAX_HASHTABLE_SIZE)); @@ -2190,18 +1759,10 @@ ike_sa_manager_t *ike_sa_manager_create() "charon.ikesa_table_segments", DEFAULT_SEGMENT_COUNT)); this->segment_count = max(1, min(this->segment_count, this->table_size)); this->segment_mask = this->segment_count - 1; -<<<<<<< HEAD - - this->ike_sa_table = calloc(this->table_size, sizeof(linked_list_t*)); - - this->segments = (segment_t*)calloc(this->segment_count, sizeof(segment_t)); - for (i = 0; i < this->segment_count; ++i) -======= this->ike_sa_table = calloc(this->table_size, sizeof(linked_list_t*)); this->segments = (segment_t*)calloc(this->segment_count, sizeof(segment_t)); for (i = 0; i < this->segment_count; i++) ->>>>>>> upstream/4.5.1 { this->segments[i].mutex = mutex_create(MUTEX_TYPE_RECURSIVE); this->segments[i].count = 0; @@ -2210,11 +1771,7 @@ ike_sa_manager_t *ike_sa_manager_create() /* we use the same table parameters for the table to track half-open SAs */ this->half_open_table = calloc(this->table_size, sizeof(linked_list_t*)); this->half_open_segments = calloc(this->segment_count, sizeof(shareable_segment_t)); -<<<<<<< HEAD - for (i = 0; i < this->segment_count; ++i) -======= for (i = 0; i < this->segment_count; i++) ->>>>>>> upstream/4.5.1 { this->half_open_segments[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT); this->half_open_segments[i].count = 0; @@ -2223,11 +1780,7 @@ ike_sa_manager_t *ike_sa_manager_create() /* also for the hash table used for duplicate tests */ this->connected_peers_table = calloc(this->table_size, sizeof(linked_list_t*)); this->connected_peers_segments = calloc(this->segment_count, sizeof(shareable_segment_t)); -<<<<<<< HEAD - for (i = 0; i < this->segment_count; ++i) -======= for (i = 0; i < this->segment_count; i++) ->>>>>>> upstream/4.5.1 { this->connected_peers_segments[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT); this->connected_peers_segments[i].count = 0; diff --git a/src/libcharon/sa/ike_sa_manager.h b/src/libcharon/sa/ike_sa_manager.h index 2c81592d2..ec157ab3a 100644 --- a/src/libcharon/sa/ike_sa_manager.h +++ b/src/libcharon/sa/ike_sa_manager.h @@ -52,12 +52,6 @@ struct ike_sa_manager_t { /** * Create and check out a new IKE_SA. * -<<<<<<< HEAD - * @note If initiator equals FALSE, the returned IKE_SA is not registered - * in the manager. - * -======= ->>>>>>> upstream/4.5.1 * @param initiator TRUE for initiator, FALSE otherwise * @returns created and checked out IKE_SA */ @@ -112,12 +106,6 @@ struct ike_sa_manager_t { * deadlocks occur otherwise. * * @param ike_sa ike_sa to check -<<<<<<< HEAD - * @return TRUE, if the given IKE_SA has duplicates and - * should be deleted - */ - bool (*check_uniqueness)(ike_sa_manager_t *this, ike_sa_t *ike_sa); -======= * @param force_replace replace existing SAs, regardless of unique policy * @return TRUE, if the given IKE_SA has duplicates and * should be deleted @@ -135,7 +123,6 @@ struct ike_sa_manager_t { */ bool (*has_contact)(ike_sa_manager_t *this, identification_t *me, identification_t *other, int family); ->>>>>>> upstream/4.5.1 /** * Check out an IKE_SA a unique ID. diff --git a/src/libcharon/sa/keymat.c b/src/libcharon/sa/keymat.c index 2721fb3b9..33ece24b2 100644 --- a/src/libcharon/sa/keymat.c +++ b/src/libcharon/sa/keymat.c @@ -214,11 +214,7 @@ static bool derive_ike_traditional(private_keymat_t *this, u_int16_t enc_alg, { DBG1(DBG_IKE, "%N %N (key size %d) not supported!", transform_type_names, ENCRYPTION_ALGORITHM, -<<<<<<< HEAD - encryption_algorithm_names, enc_alg, key_size); -======= encryption_algorithm_names, enc_alg, enc_size); ->>>>>>> upstream/4.5.1 signer_i->destroy(signer_i); signer_r->destroy(signer_r); return FALSE; @@ -544,11 +540,7 @@ METHOD(keymat_t, get_aead, aead_t*, METHOD(keymat_t, get_auth_octets, chunk_t, private_keymat_t *this, bool verify, chunk_t ike_sa_init, -<<<<<<< HEAD - chunk_t nonce, identification_t *id) -======= chunk_t nonce, identification_t *id, char reserved[3]) ->>>>>>> upstream/4.5.1 { chunk_t chunk, idx, octets; chunk_t skp; @@ -556,13 +548,8 @@ METHOD(keymat_t, get_auth_octets, chunk_t, skp = verify ? this->skp_verify : this->skp_build; chunk = chunk_alloca(4); -<<<<<<< HEAD - memset(chunk.ptr, 0, chunk.len); - chunk.ptr[0] = id->get_type(id); -======= chunk.ptr[0] = id->get_type(id); memcpy(chunk.ptr + 1, reserved, 3); ->>>>>>> upstream/4.5.1 idx = chunk_cata("cc", chunk, id->get_encoding(id)); DBG3(DBG_IKE, "IDx' %B", &idx); @@ -583,11 +570,7 @@ METHOD(keymat_t, get_auth_octets, chunk_t, METHOD(keymat_t, get_psk_sig, chunk_t, private_keymat_t *this, bool verify, chunk_t ike_sa_init, -<<<<<<< HEAD - chunk_t nonce, chunk_t secret, identification_t *id) -======= chunk_t nonce, chunk_t secret, identification_t *id, char reserved[3]) ->>>>>>> upstream/4.5.1 { chunk_t key_pad, key, sig, octets; @@ -595,11 +578,7 @@ METHOD(keymat_t, get_psk_sig, chunk_t, { /* EAP uses SK_p if no MSK has been established */ secret = verify ? this->skp_verify : this->skp_build; } -<<<<<<< HEAD - octets = get_auth_octets(this, verify, ike_sa_init, nonce, id); -======= octets = get_auth_octets(this, verify, ike_sa_init, nonce, id, reserved); ->>>>>>> upstream/4.5.1 /* AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>) */ key_pad = chunk_create(IKEV2_KEY_PAD, IKEV2_KEY_PAD_LENGTH); this->prf->set_key(this->prf, secret); diff --git a/src/libcharon/sa/keymat.h b/src/libcharon/sa/keymat.h index d1d0591c5..11e0fa79a 100644 --- a/src/libcharon/sa/keymat.h +++ b/src/libcharon/sa/keymat.h @@ -117,19 +117,12 @@ struct keymat_t { * @param ike_sa_init encoded ike_sa_init message * @param nonce nonce value * @param id identity -<<<<<<< HEAD - * @return authentication octets - */ - chunk_t (*get_auth_octets)(keymat_t *this, bool verify, chunk_t ike_sa_init, - chunk_t nonce, identification_t *id); -======= * @param reserved reserved bytes of id_payload * @return authentication octets */ chunk_t (*get_auth_octets)(keymat_t *this, bool verify, chunk_t ike_sa_init, chunk_t nonce, identification_t *id, char reserved[3]); ->>>>>>> upstream/4.5.1 /** * Build the shared secret signature used for PSK and EAP authentication. * @@ -142,19 +135,12 @@ struct keymat_t { * @param nonce nonce value * @param secret optional secret to include into signature * @param id identity -<<<<<<< HEAD - * @return signature octets - */ - chunk_t (*get_psk_sig)(keymat_t *this, bool verify, chunk_t ike_sa_init, - chunk_t nonce, chunk_t secret, identification_t *id); -======= * @param reserved reserved bytes of id_payload * @return signature octets */ chunk_t (*get_psk_sig)(keymat_t *this, bool verify, chunk_t ike_sa_init, chunk_t nonce, chunk_t secret, identification_t *id, char reserved[3]); ->>>>>>> upstream/4.5.1 /** * Destroy a keymat_t. */ diff --git a/src/libcharon/sa/task_manager.c b/src/libcharon/sa/task_manager.c index 97c5510f2..f07d2e384 100644 --- a/src/libcharon/sa/task_manager.c +++ b/src/libcharon/sa/task_manager.c @@ -161,12 +161,12 @@ static void flush(private_task_manager_t *this) { this->queued_tasks->destroy_offset(this->queued_tasks, offsetof(task_t, destroy)); + this->queued_tasks = linked_list_create(); this->passive_tasks->destroy_offset(this->passive_tasks, offsetof(task_t, destroy)); + this->passive_tasks = linked_list_create(); this->active_tasks->destroy_offset(this->active_tasks, offsetof(task_t, destroy)); - this->queued_tasks = linked_list_create(); - this->passive_tasks = linked_list_create(); this->active_tasks = linked_list_create(); } @@ -465,10 +465,6 @@ METHOD(task_manager_t, initiate, status_t, /* update exchange type if a task changed it */ this->initiating.type = message->get_exchange_type(message); -<<<<<<< HEAD - charon->bus->message(charon->bus, message, FALSE); -======= ->>>>>>> upstream/4.5.1 status = this->ike_sa->generate_message(this->ike_sa, message, &this->initiating.packet); if (status != SUCCESS) @@ -549,7 +545,7 @@ static status_t process_response(private_task_manager_t *this, /** * handle exchange collisions */ -static void handle_collisions(private_task_manager_t *this, task_t *task) +static bool handle_collisions(private_task_manager_t *this, task_t *task) { iterator_t *iterator; task_t *active; @@ -588,12 +584,11 @@ static void handle_collisions(private_task_manager_t *this, task_t *task) continue; } iterator->destroy(iterator); - return; + return TRUE; } iterator->destroy(iterator); } - /* destroy task if not registered in any active task */ - task->destroy(task); + return FALSE; } /** @@ -627,9 +622,17 @@ static status_t build_response(private_task_manager_t *this, message_t *request) case SUCCESS: /* task completed, remove it */ iterator->remove(iterator); - handle_collisions(this, task); + if (!handle_collisions(this, task)) + { + task->destroy(task); + } + break; case NEED_MORE: /* processed, but task needs another exchange */ + if (handle_collisions(this, task)) + { + iterator->remove(iterator); + } break; case FAILED: default: @@ -657,10 +660,6 @@ static status_t build_response(private_task_manager_t *this, message_t *request) /* message complete, send it */ DESTROY_IF(this->responding.packet); this->responding.packet = NULL; -<<<<<<< HEAD - charon->bus->message(charon->bus, message, FALSE); -======= ->>>>>>> upstream/4.5.1 status = this->ike_sa->generate_message(this->ike_sa, message, &this->responding.packet); message->destroy(message); @@ -888,17 +887,12 @@ static status_t process_request(private_task_manager_t *this, METHOD(task_manager_t, process_message, status_t, private_task_manager_t *this, message_t *msg) { -<<<<<<< HEAD - u_int32_t mid = msg->get_message_id(msg); - host_t *me = msg->get_destination(msg), *other = msg->get_source(msg); -======= host_t *me, *other; u_int32_t mid; mid = msg->get_message_id(msg); me = msg->get_destination(msg); other = msg->get_source(msg); ->>>>>>> upstream/4.5.1 if (msg->get_request(msg)) { @@ -910,12 +904,6 @@ METHOD(task_manager_t, process_message, status_t, { /* only do host updates based on verified messages */ if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE)) { /* with MOBIKE, we do no implicit updates */ -<<<<<<< HEAD - this->ike_sa->update_hosts(this->ike_sa, me, other); - } - } - charon->bus->message(charon->bus, msg, TRUE); -======= this->ike_sa->update_hosts(this->ike_sa, me, other, mid == 1); } } @@ -924,7 +912,6 @@ METHOD(task_manager_t, process_message, status_t, { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */ return SUCCESS; } ->>>>>>> upstream/4.5.1 if (process_request(this, msg) != SUCCESS) { flush(this); @@ -935,26 +922,15 @@ METHOD(task_manager_t, process_message, status_t, else if ((mid == this->responding.mid - 1) && this->responding.packet) { packet_t *clone; -<<<<<<< HEAD - host_t *me, *other; -======= host_t *host; ->>>>>>> upstream/4.5.1 DBG1(DBG_IKE, "received retransmit of request with ID %d, " "retransmitting response", mid); clone = this->responding.packet->clone(this->responding.packet); -<<<<<<< HEAD - me = msg->get_destination(msg); - other = msg->get_source(msg); - clone->set_source(clone, me->clone(me)); - clone->set_destination(clone, other->clone(other)); -======= host = msg->get_destination(msg); clone->set_source(clone, host->clone(host)); host = msg->get_source(msg); clone->set_destination(clone, host->clone(host)); ->>>>>>> upstream/4.5.1 charon->sender->send(charon->sender, clone); } else @@ -973,12 +949,6 @@ METHOD(task_manager_t, process_message, status_t, { /* only do host updates based on verified messages */ if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE)) { /* with MOBIKE, we do no implicit updates */ -<<<<<<< HEAD - this->ike_sa->update_hosts(this->ike_sa, me, other); - } - } - charon->bus->message(charon->bus, msg, TRUE); -======= this->ike_sa->update_hosts(this->ike_sa, me, other, FALSE); } } @@ -987,7 +957,6 @@ METHOD(task_manager_t, process_message, status_t, { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */ return SUCCESS; } ->>>>>>> upstream/4.5.1 if (process_response(this, msg) != SUCCESS) { flush(this); @@ -1050,8 +1019,6 @@ METHOD(task_manager_t, busy, bool, return (this->active_tasks->get_count(this->active_tasks) > 0); } -<<<<<<< HEAD -======= METHOD(task_manager_t, incr_mid, void, private_task_manager_t *this, bool initiate) { @@ -1065,7 +1032,6 @@ METHOD(task_manager_t, incr_mid, void, } } ->>>>>>> upstream/4.5.1 METHOD(task_manager_t, reset, void, private_task_manager_t *this, u_int32_t initiate, u_int32_t respond) { @@ -1149,10 +1115,7 @@ task_manager_t *task_manager_create(ike_sa_t *ike_sa) .queue_task = _queue_task, .initiate = _initiate, .retransmit = _retransmit, -<<<<<<< HEAD -======= .incr_mid = _incr_mid, ->>>>>>> upstream/4.5.1 .reset = _reset, .adopt_tasks = _adopt_tasks, .busy = _busy, diff --git a/src/libcharon/sa/task_manager.h b/src/libcharon/sa/task_manager.h index f5dcc8977..5bc6c80c4 100644 --- a/src/libcharon/sa/task_manager.h +++ b/src/libcharon/sa/task_manager.h @@ -149,8 +149,6 @@ struct task_manager_t { void (*adopt_tasks) (task_manager_t *this, task_manager_t *other); /** -<<<<<<< HEAD -======= * Increment a message ID counter, in- or outbound. * * If a message is processed outside of the manager, this call increments @@ -161,7 +159,6 @@ struct task_manager_t { void (*incr_mid)(task_manager_t *this, bool initiate); /** ->>>>>>> upstream/4.5.1 * Reset message ID counters of the task manager. * * The IKEv2 protocol requires to restart exchanges with message IDs diff --git a/src/libcharon/sa/tasks/child_create.c b/src/libcharon/sa/tasks/child_create.c index 16f7b6d81..fc02a334b 100644 --- a/src/libcharon/sa/tasks/child_create.c +++ b/src/libcharon/sa/tasks/child_create.c @@ -117,14 +117,11 @@ struct private_child_create_t { ipsec_mode_t mode; /** -<<<<<<< HEAD -======= * peer accepts TFC padding for this SA */ bool tfcv3; /** ->>>>>>> upstream/4.5.1 * IPComp transform to use */ ipcomp_transform_t ipcomp; @@ -463,19 +460,6 @@ static status_t select_and_install(private_child_create_t *this, { if (this->initiator) { -<<<<<<< HEAD - status_i = this->child_sa->install(this->child_sa, encr_r, integ_r, - this->my_spi, this->my_cpi, TRUE, my_ts, other_ts); - status_o = this->child_sa->install(this->child_sa, encr_i, integ_i, - this->other_spi, this->other_cpi, FALSE, my_ts, other_ts); - } - else - { - status_i = this->child_sa->install(this->child_sa, encr_i, integ_i, - this->my_spi, this->my_cpi, TRUE, my_ts, other_ts); - status_o = this->child_sa->install(this->child_sa, encr_r, integ_r, - this->other_spi, this->other_cpi, FALSE, my_ts, other_ts); -======= status_i = this->child_sa->install(this->child_sa, encr_r, integ_r, this->my_spi, this->my_cpi, TRUE, this->tfcv3, my_ts, other_ts); @@ -491,7 +475,6 @@ static status_t select_and_install(private_child_create_t *this, status_o = this->child_sa->install(this->child_sa, encr_r, integ_r, this->other_spi, this->other_cpi, FALSE, this->tfcv3, my_ts, other_ts); ->>>>>>> upstream/4.5.1 } } chunk_clear(&integ_i); @@ -657,9 +640,6 @@ static void handle_notify(private_child_create_t *this, notify_payload_t *notify ipcomp_transform_names, ipcomp); break; } -<<<<<<< HEAD - } -======= break; } case ESP_TFC_PADDING_NOT_SUPPORTED: @@ -667,7 +647,6 @@ static void handle_notify(private_child_create_t *this, notify_payload_t *notify notify_type_names, notify->get_notify_type(notify)); this->tfcv3 = FALSE; break; ->>>>>>> upstream/4.5.1 default: break; } @@ -727,15 +706,8 @@ static void process_payloads(private_child_create_t *this, message_t *message) enumerator->destroy(enumerator); } -<<<<<<< HEAD -/** - * Implementation of task_t.build for initiator - */ -static status_t build_i(private_child_create_t *this, message_t *message) -======= METHOD(task_t, build_i, status_t, private_child_create_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { host_t *me, *other, *vip; peer_cfg_t *peer_cfg; @@ -872,15 +844,8 @@ METHOD(task_t, build_i, status_t, return NEED_MORE; } -<<<<<<< HEAD -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_child_create_t *this, message_t *message) -======= METHOD(task_t, process_r, status_t, private_child_create_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { switch (message->get_exchange_type(message)) { @@ -923,15 +888,8 @@ static void handle_child_sa_failure(private_child_create_t *this, } } -<<<<<<< HEAD -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_child_create_t *this, message_t *message) -======= METHOD(task_t, build_r, status_t, private_child_create_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { peer_cfg_t *peer_cfg; payload_t *payload; @@ -1009,11 +967,7 @@ METHOD(task_t, build_r, status_t, case INTERNAL_ADDRESS_FAILURE: case FAILED_CP_REQUIRED: { -<<<<<<< HEAD - DBG1(DBG_IKE,"configuration payload negotation " -======= DBG1(DBG_IKE,"configuration payload negotiation " ->>>>>>> upstream/4.5.1 "failed, no CHILD_SA built"); enumerator->destroy(enumerator); handle_child_sa_failure(this, message); @@ -1084,15 +1038,8 @@ METHOD(task_t, build_r, status_t, return SUCCESS; } -<<<<<<< HEAD -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_child_create_t *this, message_t *message) -======= METHOD(task_t, process_i, status_t, private_child_create_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { enumerator_t *enumerator; payload_t *payload; @@ -1163,9 +1110,6 @@ METHOD(task_t, process_i, status_t, return NEED_MORE; } default: -<<<<<<< HEAD - break; -======= { if (message->get_exchange_type(message) == CREATE_CHILD_SA) { /* handle notifies if not handled in IKE_AUTH */ @@ -1181,7 +1125,6 @@ METHOD(task_t, process_i, status_t, } break; } ->>>>>>> upstream/4.5.1 } } } @@ -1233,49 +1176,20 @@ METHOD(task_t, process_i, status_t, return SUCCESS; } -<<<<<<< HEAD -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_child_create_t *this) -{ - return CHILD_CREATE; -} - -/** - * Implementation of child_create_t.use_reqid - */ -static void use_reqid(private_child_create_t *this, u_int32_t reqid) -======= METHOD(child_create_t, use_reqid, void, private_child_create_t *this, u_int32_t reqid) ->>>>>>> upstream/4.5.1 { this->reqid = reqid; } -<<<<<<< HEAD -/** - * Implementation of child_create_t.get_child - */ -static child_sa_t* get_child(private_child_create_t *this) -======= METHOD(child_create_t, get_child, child_sa_t*, private_child_create_t *this) ->>>>>>> upstream/4.5.1 { return this->child_sa; } -<<<<<<< HEAD -/** - * Implementation of child_create_t.get_lower_nonce - */ -static chunk_t get_lower_nonce(private_child_create_t *this) -======= METHOD(child_create_t, get_lower_nonce, chunk_t, private_child_create_t *this) ->>>>>>> upstream/4.5.1 { if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr, min(this->my_nonce.len, this->other_nonce.len)) < 0) @@ -1288,12 +1202,6 @@ METHOD(child_create_t, get_lower_nonce, chunk_t, } } -<<<<<<< HEAD -/** - * Implementation of task_t.migrate - */ -static void migrate(private_child_create_t *this, ike_sa_t *ike_sa) -======= METHOD(task_t, get_type, task_type_t, private_child_create_t *this) { @@ -1302,7 +1210,6 @@ METHOD(task_t, get_type, task_type_t, METHOD(task_t, migrate, void, private_child_create_t *this, ike_sa_t *ike_sa) ->>>>>>> upstream/4.5.1 { chunk_free(&this->my_nonce); chunk_free(&this->other_nonce); @@ -1338,15 +1245,8 @@ METHOD(task_t, migrate, void, this->established = FALSE; } -<<<<<<< HEAD -/** - * Implementation of task_t.destroy - */ -static void destroy(private_child_create_t *this) -======= METHOD(task_t, destroy, void, private_child_create_t *this) ->>>>>>> upstream/4.5.1 { chunk_free(&this->my_nonce); chunk_free(&this->other_nonce); @@ -1382,20 +1282,6 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config, bool rekey, traffic_selector_t *tsi, traffic_selector_t *tsr) { -<<<<<<< HEAD - private_child_create_t *this = malloc_thing(private_child_create_t); - - this->public.get_child = (child_sa_t*(*)(child_create_t*))get_child; - this->public.get_lower_nonce = (chunk_t(*)(child_create_t*))get_lower_nonce; - this->public.use_reqid = (void(*)(child_create_t*,u_int32_t))use_reqid; - 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 (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; -======= private_child_create_t *this; INIT(this, @@ -1426,49 +1312,15 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, { this->public.task.build = _build_i; this->public.task.process = _process_i; ->>>>>>> upstream/4.5.1 this->initiator = TRUE; config->get_ref(config); } else { -<<<<<<< HEAD - 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->ike_sa = ike_sa; - this->config = config; - this->my_nonce = chunk_empty; - this->other_nonce = chunk_empty; - this->proposals = NULL; - this->proposal = NULL; - this->tsi = NULL; - this->tsr = NULL; - this->packet_tsi = tsi ? tsi->clone(tsi) : NULL; - this->packet_tsr = tsr ? tsr->clone(tsr) : NULL; - this->dh = NULL; - this->dh_group = MODP_NONE; - this->keymat = ike_sa->get_keymat(ike_sa); - this->child_sa = NULL; - this->mode = MODE_TUNNEL; - this->ipcomp = IPCOMP_NONE; - this->ipcomp_received = IPCOMP_NONE; - this->my_spi = 0; - this->other_spi = 0; - this->my_cpi = 0; - this->other_cpi = 0; - this->reqid = 0; - this->established = FALSE; - this->rekey = rekey; - -======= this->public.task.build = _build_r; this->public.task.process = _process_r; this->initiator = FALSE; } ->>>>>>> upstream/4.5.1 return &this->public; } diff --git a/src/libcharon/sa/tasks/child_delete.c b/src/libcharon/sa/tasks/child_delete.c index 45e97e4cd..e6834a93c 100644 --- a/src/libcharon/sa/tasks/child_delete.c +++ b/src/libcharon/sa/tasks/child_delete.c @@ -163,6 +163,7 @@ static void process_payloads(private_child_delete_t *this, message_t *message) protocol, spi); continue; } + /* fall through */ case CHILD_INSTALLED: if (!this->initiator) { /* reestablish installed children if required */ diff --git a/src/libcharon/sa/tasks/child_rekey.c b/src/libcharon/sa/tasks/child_rekey.c index 5ffe49293..b39a5fc67 100644 --- a/src/libcharon/sa/tasks/child_rekey.c +++ b/src/libcharon/sa/tasks/child_rekey.c @@ -241,20 +241,11 @@ static child_sa_t *handle_collision(private_child_rekey_t *this) /* if we have the lower nonce, delete rekeyed SA. If not, delete * the redundant. */ if (memcmp(this_nonce.ptr, other_nonce.ptr, -<<<<<<< HEAD - min(this_nonce.len, other_nonce.len)) < 0) - { - child_sa_t *child_sa; - - DBG1(DBG_IKE, "CHILD_SA rekey collision won, " - "deleting rekeyed child"); -======= min(this_nonce.len, other_nonce.len)) > 0) { child_sa_t *child_sa; DBG1(DBG_IKE, "CHILD_SA rekey collision won, deleting old child"); ->>>>>>> upstream/4.5.1 to_delete = this->child_sa; /* don't touch child other created, it has already been deleted */ if (!this->other_child_destroyed) @@ -267,11 +258,7 @@ static child_sa_t *handle_collision(private_child_rekey_t *this) else { DBG1(DBG_IKE, "CHILD_SA rekey collision lost, " -<<<<<<< HEAD - "deleting redundant child"); -======= "deleting rekeyed child"); ->>>>>>> upstream/4.5.1 to_delete = this->child_create->get_child(this->child_create); } } @@ -395,7 +382,7 @@ static void collide(private_child_rekey_t *this, task_t *other) if (other->get_type(other) == CHILD_REKEY) { private_child_rekey_t *rekey = (private_child_rekey_t*)other; - if (rekey == NULL || rekey->child_sa != this->child_sa) + if (rekey->child_sa != this->child_sa) { /* not the same child => no collision */ other->destroy(other); @@ -412,7 +399,7 @@ static void collide(private_child_rekey_t *this, task_t *other) other->destroy(other); return; } - if (del == NULL || del->get_child(del) != this->child_sa) + if (del->get_child(del) != this->child_sa) { /* not the same child => no collision */ other->destroy(other); @@ -425,6 +412,8 @@ static void collide(private_child_rekey_t *this, task_t *other) other->destroy(other); return; } + DBG1(DBG_IKE, "detected %N collision with %N", task_type_names, CHILD_REKEY, + task_type_names, other->get_type(other)); DESTROY_IF(this->collision); this->collision = other; } diff --git a/src/libcharon/sa/tasks/ike_auth.c b/src/libcharon/sa/tasks/ike_auth.c index fbc177d6f..0756c7d60 100644 --- a/src/libcharon/sa/tasks/ike_auth.c +++ b/src/libcharon/sa/tasks/ike_auth.c @@ -68,14 +68,11 @@ struct private_ike_auth_t { packet_t *other_packet; /** -<<<<<<< HEAD -======= * Reserved bytes of ID payload */ char reserved[3]; /** ->>>>>>> upstream/4.5.1 * currently active authenticator, to authenticate us */ authenticator_t *my_auth; @@ -109,14 +106,11 @@ struct private_ike_auth_t { * should we send a AUTHENTICATION_FAILED notify? */ bool authentication_failed; -<<<<<<< HEAD -======= /** * received an INITIAL_CONTACT? */ bool initial_contact; ->>>>>>> upstream/4.5.1 }; /** @@ -176,8 +170,6 @@ static status_t collect_other_init_data(private_ike_auth_t *this, } /** -<<<<<<< HEAD -======= * Get and store reserved bytes of id_payload, required for AUTH payload */ static void get_reserved_id_bytes(private_ike_auth_t *this, id_payload_t *id) @@ -196,7 +188,6 @@ static void get_reserved_id_bytes(private_ike_auth_t *this, id_payload_t *id) } /** ->>>>>>> upstream/4.5.1 * Get the next authentication configuration */ static auth_cfg_t *get_auth_cfg(private_ike_auth_t *this, bool local) @@ -366,15 +357,8 @@ static bool update_cfg_candidates(private_ike_auth_t *this, bool strict) return this->peer_cfg != NULL; } -<<<<<<< HEAD -/** - * Implementation of task_t.build for initiator - */ -static status_t build_i(private_ike_auth_t *this, message_t *message) -======= METHOD(task_t, build_i, status_t, private_ike_auth_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { auth_cfg_t *cfg; @@ -409,11 +393,7 @@ METHOD(task_t, build_i, status_t, /* check if an authenticator is in progress */ if (this->my_auth == NULL) { -<<<<<<< HEAD - identification_t *id; -======= identification_t *idi, *idr = NULL; ->>>>>>> upstream/4.5.1 id_payload_t *id_payload; /* clean up authentication config from a previous round */ @@ -424,44 +404,24 @@ METHOD(task_t, build_i, status_t, cfg = get_auth_cfg(this, FALSE); if (cfg) { -<<<<<<< HEAD - id = cfg->get(cfg, AUTH_RULE_IDENTITY); - if (id && !id->contains_wildcards(id)) - { - this->ike_sa->set_other_id(this->ike_sa, id->clone(id)); - id_payload = id_payload_create_from_identification( - ID_RESPONDER, id); -======= idr = cfg->get(cfg, AUTH_RULE_IDENTITY); if (idr && !idr->contains_wildcards(idr)) { this->ike_sa->set_other_id(this->ike_sa, idr->clone(idr)); id_payload = id_payload_create_from_identification( ID_RESPONDER, idr); ->>>>>>> upstream/4.5.1 message->add_payload(message, (payload_t*)id_payload); } } /* add IDi */ cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE); cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE); -<<<<<<< HEAD - id = cfg->get(cfg, AUTH_RULE_IDENTITY); - if (!id) -======= idi = cfg->get(cfg, AUTH_RULE_IDENTITY); if (!idi) ->>>>>>> upstream/4.5.1 { DBG1(DBG_CFG, "configuration misses IDi"); return FAILED; } -<<<<<<< HEAD - this->ike_sa->set_my_id(this->ike_sa, id->clone(id)); - id_payload = id_payload_create_from_identification(ID_INITIATOR, id); - message->add_payload(message, (payload_t*)id_payload); - -======= this->ike_sa->set_my_id(this->ike_sa, idi->clone(idi)); id_payload = id_payload_create_from_identification(ID_INITIATOR, idi); get_reserved_id_bytes(this, id_payload); @@ -480,17 +440,12 @@ METHOD(task_t, build_i, status_t, } } ->>>>>>> upstream/4.5.1 /* build authentication data */ this->my_auth = authenticator_create_builder(this->ike_sa, cfg, this->other_nonce, this->my_nonce, this->other_packet->get_data(this->other_packet), -<<<<<<< HEAD - this->my_packet->get_data(this->my_packet)); -======= this->my_packet->get_data(this->my_packet), this->reserved); ->>>>>>> upstream/4.5.1 if (!this->my_auth) { return FAILED; @@ -527,15 +482,8 @@ METHOD(task_t, build_i, status_t, return NEED_MORE; } -<<<<<<< HEAD -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_auth_t *this, message_t *message) -======= METHOD(task_t, process_r, status_t, private_ike_auth_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { auth_cfg_t *cfg, *cand; id_payload_t *id_payload; @@ -589,10 +537,7 @@ METHOD(task_t, process_r, status_t, return FAILED; } id = id_payload->get_identification(id_payload); -<<<<<<< HEAD -======= get_reserved_id_bytes(this, id_payload); ->>>>>>> upstream/4.5.1 this->ike_sa->set_other_id(this->ike_sa, id); cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id)); @@ -643,12 +588,8 @@ METHOD(task_t, process_r, status_t, this->other_auth = authenticator_create_verifier(this->ike_sa, message, this->other_nonce, this->my_nonce, this->other_packet->get_data(this->other_packet), -<<<<<<< HEAD - this->my_packet->get_data(this->my_packet)); -======= this->my_packet->get_data(this->my_packet), this->reserved); ->>>>>>> upstream/4.5.1 if (!this->other_auth) { this->authentication_failed = TRUE; @@ -672,12 +613,6 @@ METHOD(task_t, process_r, status_t, return NEED_MORE; } -<<<<<<< HEAD - /* store authentication information */ - cfg = auth_cfg_create(); - cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE); - this->ike_sa->add_auth_cfg(this->ike_sa, FALSE, cfg); -======= /* If authenticated (with non-EAP) and received INITIAL_CONTACT, * delete any existing IKE_SAs with that peer. */ if (message->get_message_id(message) == 1 && @@ -685,7 +620,6 @@ METHOD(task_t, process_r, status_t, { this->initial_contact = TRUE; } ->>>>>>> upstream/4.5.1 /* another auth round done, invoke authorize hook */ if (!charon->bus->authorize(charon->bus, FALSE)) @@ -695,14 +629,11 @@ METHOD(task_t, process_r, status_t, return NEED_MORE; } -<<<<<<< HEAD -======= /* store authentication information */ cfg = auth_cfg_create(); cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE); this->ike_sa->add_auth_cfg(this->ike_sa, FALSE, cfg); ->>>>>>> upstream/4.5.1 if (!update_cfg_candidates(this, FALSE)) { this->authentication_failed = TRUE; @@ -721,15 +652,8 @@ METHOD(task_t, process_r, status_t, return NEED_MORE; } -<<<<<<< HEAD -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_auth_t *this, message_t *message) -======= METHOD(task_t, build_r, status_t, private_ike_auth_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { auth_cfg_t *cfg; @@ -785,10 +709,6 @@ METHOD(task_t, build_r, status_t, } id_payload = id_payload_create_from_identification(ID_RESPONDER, id); -<<<<<<< HEAD - message->add_payload(message, (payload_t*)id_payload); - -======= get_reserved_id_bytes(this, id_payload); message->add_payload(message, (payload_t*)id_payload); @@ -799,7 +719,6 @@ METHOD(task_t, build_r, status_t, this->initial_contact = FALSE; } ->>>>>>> upstream/4.5.1 if ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS) == AUTH_CLASS_EAP) { /* EAP-only authentication */ if (!this->ike_sa->supports_extension(this->ike_sa, @@ -818,12 +737,8 @@ METHOD(task_t, build_r, status_t, this->my_auth = authenticator_create_builder(this->ike_sa, cfg, this->other_nonce, this->my_nonce, this->other_packet->get_data(this->other_packet), -<<<<<<< HEAD - this->my_packet->get_data(this->my_packet)); -======= this->my_packet->get_data(this->my_packet), this->reserved); ->>>>>>> upstream/4.5.1 if (!this->my_auth) { message->add_notify(message, TRUE, AUTHENTICATION_FAILED, @@ -885,11 +800,7 @@ METHOD(task_t, build_r, status_t, if (!this->do_another_auth && !this->expect_another_auth) { if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager, -<<<<<<< HEAD - this->ike_sa)) -======= this->ike_sa, FALSE)) ->>>>>>> upstream/4.5.1 { DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy"); message->add_notify(message, TRUE, AUTHENTICATION_FAILED, @@ -917,15 +828,8 @@ METHOD(task_t, build_r, status_t, return NEED_MORE; } -<<<<<<< HEAD -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_auth_t *this, message_t *message) -======= METHOD(task_t, process_i, status_t, private_ike_auth_t *this, message_t *message) ->>>>>>> upstream/4.5.1 { enumerator_t *enumerator; payload_t *payload; @@ -1007,10 +911,7 @@ METHOD(task_t, process_i, status_t, return FAILED; } id = id_payload->get_identification(id_payload); -<<<<<<< HEAD -======= get_reserved_id_bytes(this, id_payload); ->>>>>>> upstream/4.5.1 this->ike_sa->set_other_id(this->ike_sa, id); cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id)); @@ -1021,12 +922,8 @@ METHOD(task_t, process_i, status_t, this->other_auth = authenticator_create_verifier(this->ike_sa, message, this->other_nonce, this->my_nonce, this->other_packet->get_data(this->other_packet), -<<<<<<< HEAD - this->my_packet->get_data(this->my_packet)); -======= this->my_packet->get_data(this->my_packet), this->reserved); ->>>>>>> upstream/4.5.1 if (!this->other_auth) { return FAILED; @@ -1052,28 +949,17 @@ METHOD(task_t, process_i, status_t, this->other_auth->destroy(this->other_auth); this->other_auth = NULL; } -<<<<<<< HEAD - /* store authentication information, reset authenticator */ - cfg = auth_cfg_create(); - cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE); - this->ike_sa->add_auth_cfg(this->ike_sa, FALSE, cfg); - -======= ->>>>>>> upstream/4.5.1 /* another auth round done, invoke authorize hook */ if (!charon->bus->authorize(charon->bus, FALSE)) { DBG1(DBG_IKE, "authorization forbids IKE_SA, cancelling"); return FAILED; } -<<<<<<< HEAD -======= /* store authentication information, reset authenticator */ cfg = auth_cfg_create(); cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE); this->ike_sa->add_auth_cfg(this->ike_sa, FALSE, cfg); ->>>>>>> upstream/4.5.1 } if (this->my_auth) @@ -1134,28 +1020,14 @@ METHOD(task_t, process_i, status_t, return NEED_MORE; } -<<<<<<< HEAD -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_auth_t *this) -======= METHOD(task_t, get_type, task_type_t, private_ike_auth_t *this) ->>>>>>> upstream/4.5.1 { return IKE_AUTHENTICATE; } -<<<<<<< HEAD -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_auth_t *this, ike_sa_t *ike_sa) -======= METHOD(task_t, migrate, void, private_ike_auth_t *this, ike_sa_t *ike_sa) ->>>>>>> upstream/4.5.1 { chunk_free(&this->my_nonce); chunk_free(&this->other_nonce); @@ -1178,15 +1050,8 @@ METHOD(task_t, migrate, void, this->candidates = linked_list_create(); } -<<<<<<< HEAD -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_auth_t *this) -======= METHOD(task_t, destroy, void, private_ike_auth_t *this) ->>>>>>> upstream/4.5.1 { chunk_free(&this->my_nonce); chunk_free(&this->other_nonce); @@ -1204,39 +1069,6 @@ METHOD(task_t, destroy, void, */ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator) { -<<<<<<< HEAD - private_ike_auth_t *this = malloc_thing(private_ike_auth_t); - - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; - - if (initiator) - { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; - } - else - { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_r; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_r; - } - - this->ike_sa = ike_sa; - this->initiator = initiator; - this->my_nonce = chunk_empty; - this->other_nonce = chunk_empty; - this->my_packet = NULL; - this->other_packet = NULL; - this->peer_cfg = NULL; - this->candidates = linked_list_create(); - this->my_auth = NULL; - this->other_auth = NULL; - this->do_another_auth = TRUE; - this->expect_another_auth = TRUE; - this->authentication_failed = FALSE; - -======= private_ike_auth_t *this; INIT(this, @@ -1260,7 +1092,6 @@ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator) this->public.task.build = _build_i; this->public.task.process = _process_i; } ->>>>>>> upstream/4.5.1 return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_cert_pre.c b/src/libcharon/sa/tasks/ike_cert_pre.c index 8da8d549a..a59b8dcce 100644 --- a/src/libcharon/sa/tasks/ike_cert_pre.c +++ b/src/libcharon/sa/tasks/ike_cert_pre.c @@ -76,10 +76,7 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message) { certreq_payload_t *certreq = (certreq_payload_t*)payload; enumerator_t *enumerator; -<<<<<<< HEAD -======= u_int unknown = 0; ->>>>>>> upstream/4.5.1 chunk_t keyid; this->ike_sa->set_condition(this->ike_sa, COND_CERTREQ_SEEN, TRUE); @@ -107,26 +104,18 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message) } else { -<<<<<<< HEAD - DBG1(DBG_IKE, "received cert request for unknown ca " - "with keyid %Y", id); -======= DBG2(DBG_IKE, "received cert request for unknown ca " "with keyid %Y", id); unknown++; ->>>>>>> upstream/4.5.1 } id->destroy(id); } enumerator->destroy(enumerator); -<<<<<<< HEAD -======= if (unknown) { DBG1(DBG_IKE, "received %u cert requests for an unknown ca", unknown); } ->>>>>>> upstream/4.5.1 break; } case NOTIFY: @@ -271,8 +260,6 @@ static void process_certs(private_ike_cert_pre_t *this, message_t *message) } break; } -<<<<<<< HEAD -======= case ENC_CRL: cert = cert_payload->get_cert(cert_payload); if (cert) @@ -282,15 +269,10 @@ static void process_certs(private_ike_cert_pre_t *this, message_t *message) auth->add(auth, AUTH_HELPER_REVOCATION_CERT, cert); } break; ->>>>>>> upstream/4.5.1 case ENC_PKCS7_WRAPPED_X509: case ENC_PGP: case ENC_DNS_SIGNED_KEY: case ENC_KERBEROS_TOKEN: -<<<<<<< HEAD - case ENC_CRL: -======= ->>>>>>> upstream/4.5.1 case ENC_ARL: case ENC_SPKI: case ENC_X509_ATTRIBUTE: diff --git a/src/libcharon/sa/tasks/ike_config.c b/src/libcharon/sa/tasks/ike_config.c index c92b5bca5..a61663c48 100644 --- a/src/libcharon/sa/tasks/ike_config.c +++ b/src/libcharon/sa/tasks/ike_config.c @@ -317,7 +317,7 @@ static status_t build_r(private_ike_config_t *this, message_t *message) id = this->ike_sa->get_other_eap_id(this->ike_sa); config = this->ike_sa->get_peer_cfg(this->ike_sa); - if (config && this->virtual_ip) + if (this->virtual_ip) { DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip); if (config->get_pool(config)) diff --git a/src/libcharon/sa/tasks/ike_rekey.c b/src/libcharon/sa/tasks/ike_rekey.c index 1698ddd34..c055dabc1 100644 --- a/src/libcharon/sa/tasks/ike_rekey.c +++ b/src/libcharon/sa/tasks/ike_rekey.c @@ -68,9 +68,45 @@ struct private_ike_rekey_t { }; /** - * Implementation of task_t.build for initiator, after rekeying + * Establish the new replacement IKE_SA */ -static status_t build_i_delete(private_ike_rekey_t *this, message_t *message) +static void establish_new(private_ike_rekey_t *this) +{ + if (this->new_sa) + { + this->new_sa->set_state(this->new_sa, IKE_ESTABLISHED); + DBG0(DBG_IKE, "IKE_SA %s[%d] rekeyed between %H[%Y]...%H[%Y]", + this->new_sa->get_name(this->new_sa), + this->new_sa->get_unique_id(this->new_sa), + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa)); + + this->new_sa->inherit(this->new_sa, this->ike_sa); + charon->bus->ike_rekey(charon->bus, this->ike_sa, this->new_sa); + charon->ike_sa_manager->checkin(charon->ike_sa_manager, this->new_sa); + this->new_sa = NULL; + /* set threads active IKE_SA after checkin */ + charon->bus->set_sa(charon->bus, this->ike_sa); + } +} + +METHOD(task_t, process_r_delete, status_t, + private_ike_rekey_t *this, message_t *message) +{ + establish_new(this); + return this->ike_delete->task.process(&this->ike_delete->task, message); +} + +METHOD(task_t, build_r_delete, status_t, + private_ike_rekey_t *this, message_t *message) +{ + return this->ike_delete->task.build(&this->ike_delete->task, message); +} + +METHOD(task_t, build_i_delete, status_t, + private_ike_rekey_t *this, message_t *message) { /* update exchange type to INFORMATIONAL for the delete */ message->set_exchange_type(message, INFORMATIONAL); @@ -78,18 +114,14 @@ static status_t build_i_delete(private_ike_rekey_t *this, message_t *message) return this->ike_delete->task.build(&this->ike_delete->task, message); } -/** - * Implementation of task_t.process for initiator, after rekeying - */ -static status_t process_i_delete(private_ike_rekey_t *this, message_t *message) +METHOD(task_t, process_i_delete, status_t, + private_ike_rekey_t *this, message_t *message) { return this->ike_delete->task.process(&this->ike_delete->task, message); } -/** - * Implementation of task_t.build for initiator - */ -static status_t build_i(private_ike_rekey_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_rekey_t *this, message_t *message) { peer_cfg_t *peer_cfg; host_t *other_host; @@ -112,10 +144,8 @@ static status_t build_i(private_ike_rekey_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_rekey_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_ike_rekey_t *this, message_t *message) { peer_cfg_t *peer_cfg; iterator_t *iterator; @@ -156,10 +186,8 @@ static status_t process_r(private_ike_rekey_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_rekey_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_ike_rekey_t *this, message_t *message) { if (this->new_sa == NULL) { @@ -174,22 +202,17 @@ static status_t build_r(private_ike_rekey_t *this, message_t *message) } this->ike_sa->set_state(this->ike_sa, IKE_REKEYING); - this->new_sa->set_state(this->new_sa, IKE_ESTABLISHED); - DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]", - this->new_sa->get_name(this->new_sa), - this->new_sa->get_unique_id(this->new_sa), - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa)); - - return SUCCESS; + + /* rekeying successful, delete the IKE_SA using a subtask */ + this->ike_delete = ike_delete_create(this->ike_sa, FALSE); + this->public.task.build = _build_r_delete; + this->public.task.process = _process_r_delete; + + return NEED_MORE; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_rekey_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_rekey_t *this, message_t *message) { if (message->get_notify(message, NO_ADDITIONAL_SAS)) { @@ -228,15 +251,6 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) break; } - this->new_sa->set_state(this->new_sa, IKE_ESTABLISHED); - DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]", - this->new_sa->get_name(this->new_sa), - this->new_sa->get_unique_id(this->new_sa), - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa)); - /* check for collisions */ if (this->collision && this->collision->get_type(this->collision) == IKE_REKEY) @@ -255,53 +269,40 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) /* if we have the lower nonce, delete rekeyed SA. If not, delete * the redundant. */ if (memcmp(this_nonce.ptr, other_nonce.ptr, -<<<<<<< HEAD - min(this_nonce.len, other_nonce.len)) < 0) -======= min(this_nonce.len, other_nonce.len)) > 0) ->>>>>>> upstream/4.5.1 { /* peer should delete this SA. Add a timeout just in case. */ job_t *job = (job_t*)delete_ike_sa_job_create( other->new_sa->get_id(other->new_sa), TRUE); lib->scheduler->schedule_job(lib->scheduler, job, 10); -<<<<<<< HEAD - DBG1(DBG_IKE, "IKE_SA rekey collision won, deleting rekeyed IKE_SA"); -======= DBG1(DBG_IKE, "IKE_SA rekey collision won, waiting for delete"); ->>>>>>> upstream/4.5.1 charon->ike_sa_manager->checkin(charon->ike_sa_manager, other->new_sa); other->new_sa = NULL; } else { -<<<<<<< HEAD - DBG1(DBG_IKE, "IKE_SA rekey collision lost, deleting redundant IKE_SA"); -======= DBG1(DBG_IKE, "IKE_SA rekey collision lost, " "deleting redundant IKE_SA"); ->>>>>>> upstream/4.5.1 /* apply host for a proper delete */ host = this->ike_sa->get_my_host(this->ike_sa); this->new_sa->set_my_host(this->new_sa, host->clone(host)); host = this->ike_sa->get_other_host(this->ike_sa); this->new_sa->set_other_host(this->new_sa, host->clone(host)); this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); + this->new_sa->set_state(this->new_sa, IKE_REKEYING); if (this->new_sa->delete(this->new_sa) == DESTROY_ME) { - charon->ike_sa_manager->checkin_and_destroy( - charon->ike_sa_manager, this->new_sa); + this->new_sa->destroy(this->new_sa); } else { charon->ike_sa_manager->checkin( charon->ike_sa_manager, this->new_sa); + /* set threads active IKE_SA after checkin */ + charon->bus->set_sa(charon->bus, this->ike_sa); } - /* set threads active IKE_SA after checkin */ - charon->bus->set_sa(charon->bus, this->ike_sa); - /* inherit to other->new_sa in destroy() */ - this->new_sa = other->new_sa; - other->new_sa = NULL; + this->new_sa = NULL; + establish_new(other); return SUCCESS; } } @@ -309,32 +310,33 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) charon->bus->set_sa(charon->bus, this->ike_sa); } + establish_new(this); + /* rekeying successful, delete the IKE_SA using a subtask */ this->ike_delete = ike_delete_create(this->ike_sa, TRUE); - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i_delete; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i_delete; + this->public.task.build = _build_i_delete; + this->public.task.process = _process_i_delete; return NEED_MORE; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_rekey_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_rekey_t *this) { return IKE_REKEY; } -static void collide(private_ike_rekey_t* this, task_t *other) +METHOD(ike_rekey_t, collide, void, + private_ike_rekey_t* this, task_t *other) { + DBG1(DBG_IKE, "detected %N collision with %N", task_type_names, IKE_REKEY, + task_type_names, other->get_type(other)); DESTROY_IF(this->collision); this->collision = other; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_rekey_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_rekey_t *this, ike_sa_t *ike_sa) { if (this->ike_init) { @@ -344,13 +346,7 @@ static void migrate(private_ike_rekey_t *this, ike_sa_t *ike_sa) { this->ike_delete->task.destroy(&this->ike_delete->task); } - if (this->new_sa) - { - charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, - this->new_sa); - /* set threads active IKE_SA after checkin */ - charon->bus->set_sa(charon->bus, this->ike_sa); - } + DESTROY_IF(this->new_sa); DESTROY_IF(this->collision); this->collision = NULL; @@ -360,28 +356,9 @@ static void migrate(private_ike_rekey_t *this, ike_sa_t *ike_sa) this->ike_delete = NULL; } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_rekey_t *this) +METHOD(task_t, destroy, void, + private_ike_rekey_t *this) { - if (this->new_sa) - { - if (this->new_sa->get_state(this->new_sa) == IKE_ESTABLISHED && - this->new_sa->inherit(this->new_sa, this->ike_sa) != DESTROY_ME) - { - /* invoke hook if rekeying was successful */ - charon->bus->ike_rekey(charon->bus, this->ike_sa, this->new_sa); - charon->ike_sa_manager->checkin(charon->ike_sa_manager, this->new_sa); - } - else - { - charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, - this->new_sa); - } - /* set threads active IKE_SA after checkin */ - charon->bus->set_sa(charon->bus, this->ike_sa); - } if (this->ike_init) { this->ike_init->task.destroy(&this->ike_init->task); @@ -390,6 +367,7 @@ static void destroy(private_ike_rekey_t *this) { this->ike_delete->task.destroy(&this->ike_delete->task); } + DESTROY_IF(this->new_sa); DESTROY_IF(this->collision); free(this); } @@ -399,29 +377,27 @@ static void destroy(private_ike_rekey_t *this) */ ike_rekey_t *ike_rekey_create(ike_sa_t *ike_sa, bool initiator) { - private_ike_rekey_t *this = malloc_thing(private_ike_rekey_t); - - this->public.collide = (void(*)(ike_rekey_t*,task_t*))collide; - 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; + private_ike_rekey_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .build = _build_r, + .process = _process_r, + .migrate = _migrate, + .destroy = _destroy, + }, + .collide = _collide, + }, + .ike_sa = ike_sa, + .initiator = initiator, + ); 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->public.task.build = _build_i; + this->public.task.process = _process_i; } - else - { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_r; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_r; - } - - this->ike_sa = ike_sa; - this->new_sa = NULL; - this->ike_init = NULL; - this->ike_delete = NULL; - this->initiator = initiator; - this->collision = NULL; return &this->public; } |