diff options
Diffstat (limited to 'src/libcharon/sa')
24 files changed, 1486 insertions, 0 deletions
diff --git a/src/libcharon/sa/authenticators/authenticator.c b/src/libcharon/sa/authenticators/authenticator.c index cd340e53e..3f176f9be 100644 --- a/src/libcharon/sa/authenticators/authenticator.c +++ b/src/libcharon/sa/authenticators/authenticator.c @@ -39,7 +39,12 @@ 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)) { @@ -47,6 +52,7 @@ 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, @@ -54,6 +60,16 @@ authenticator_t *authenticator_create_builder(ike_sa_t *ike_sa, auth_cfg_t *cfg, 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, + received_nonce, sent_init, reserved); + case AUTH_CLASS_EAP: + 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; } @@ -65,7 +81,12 @@ 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; @@ -73,7 +94,12 @@ 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)) { @@ -82,10 +108,17 @@ 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 89178b5cf..d30094c9b 100644 --- a/src/libcharon/sa/authenticators/authenticator.h +++ b/src/libcharon/sa/authenticators/authenticator.h @@ -130,12 +130,21 @@ 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. @@ -146,11 +155,20 @@ 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_authenticator.c b/src/libcharon/sa/authenticators/eap_authenticator.c index 8b22fd1d7..a5268e186 100644 --- a/src/libcharon/sa/authenticators/eap_authenticator.c +++ b/src/libcharon/sa/authenticators/eap_authenticator.c @@ -58,6 +58,14 @@ 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; @@ -422,7 +430,11 @@ 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)) { @@ -458,7 +470,12 @@ 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); @@ -642,7 +659,12 @@ 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; @@ -661,6 +683,10 @@ 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; } @@ -670,7 +696,12 @@ 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; @@ -689,6 +720,10 @@ 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 41eb6a8c9..625084d4f 100644 --- a/src/libcharon/sa/authenticators/eap_authenticator.h +++ b/src/libcharon/sa/authenticators/eap_authenticator.h @@ -75,11 +75,20 @@ 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. @@ -89,10 +98,19 @@ 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 e69f30dcf..9789ec93b 100644 --- a/src/libcharon/sa/authenticators/psk_authenticator.c +++ b/src/libcharon/sa/authenticators/psk_authenticator.c @@ -45,12 +45,24 @@ 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 + */ + char reserved[3]; +}; + +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; @@ -70,7 +82,11 @@ static status_t build(private_psk_authenticator_t *this, message_t *message) 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(); @@ -82,10 +98,15 @@ static status_t build(private_psk_authenticator_t *this, message_t *message) 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; @@ -113,7 +134,11 @@ static status_t process(private_psk_authenticator_t *this, message_t *message) 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", @@ -141,6 +166,7 @@ static status_t process(private_psk_authenticator_t *this, message_t *message) return SUCCESS; } +<<<<<<< HEAD /** * Implementation of authenticator_t.process for builder * Implementation of authenticator_t.build for verifier @@ -154,6 +180,10 @@ static status_t 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); } @@ -162,6 +192,7 @@ static void destroy(private_psk_authenticator_t *this) * 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); @@ -174,6 +205,27 @@ psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa, 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]) +{ + private_psk_authenticator_t *this; + + INIT(this, + .public = { + .authenticator = { + .build = _build, + .process = (void*)return_failed, + .is_mutual = (void*)return_false, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .ike_sa_init = sent_init, + .nonce = received_nonce, + ); + memcpy(this->reserved, reserved, sizeof(this->reserved)); +>>>>>>> upstream/4.5.1 return &this->public; } @@ -182,6 +234,7 @@ 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); @@ -194,6 +247,27 @@ psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa, 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]) +{ + private_psk_authenticator_t *this; + + INIT(this, + .public = { + .authenticator = { + .build = (void*)return_failed, + .process = _process, + .is_mutual = (void*)return_false, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .ike_sa_init = received_init, + .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 0fab11095..2897c3fe2 100644 --- a/src/libcharon/sa/authenticators/psk_authenticator.h +++ b/src/libcharon/sa/authenticators/psk_authenticator.h @@ -42,10 +42,19 @@ 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. @@ -53,9 +62,18 @@ 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 54b4338bb..030433db0 100644 --- a/src/libcharon/sa/authenticators/pubkey_authenticator.c +++ b/src/libcharon/sa/authenticators/pubkey_authenticator.c @@ -46,12 +46,24 @@ 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 + */ + char reserved[3]; +}; + +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; @@ -109,7 +121,11 @@ static status_t build(private_pubkey_authenticator_t *this, message_t *message) } 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(); @@ -128,10 +144,15 @@ static status_t build(private_pubkey_authenticator_t *this, message_t *message) 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; @@ -175,7 +196,11 @@ static status_t process(private_pubkey_authenticator_t *this, message_t *message 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); @@ -206,6 +231,7 @@ static status_t process(private_pubkey_authenticator_t *this, message_t *message return status; } +<<<<<<< HEAD /** * Implementation of authenticator_t.process for builder * Implementation of authenticator_t.build for verifier @@ -219,6 +245,10 @@ static status_t 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); } @@ -227,6 +257,7 @@ static void destroy(private_pubkey_authenticator_t *this) * 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); @@ -239,6 +270,27 @@ pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa, 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]) +{ + private_pubkey_authenticator_t *this; + + INIT(this, + .public = { + .authenticator = { + .build = _build, + .process = (void*)return_failed, + .is_mutual = (void*)return_false, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .ike_sa_init = sent_init, + .nonce = received_nonce, + ); + memcpy(this->reserved, reserved, sizeof(this->reserved)); +>>>>>>> upstream/4.5.1 return &this->public; } @@ -247,6 +299,7 @@ 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); @@ -259,6 +312,27 @@ pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa, 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]) +{ + private_pubkey_authenticator_t *this; + + INIT(this, + .public = { + .authenticator = { + .build = (void*)return_failed, + .process = _process, + .is_mutual = (void*)return_false, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .ike_sa_init = received_init, + .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 be369cb89..9e2606b95 100644 --- a/src/libcharon/sa/authenticators/pubkey_authenticator.h +++ b/src/libcharon/sa/authenticators/pubkey_authenticator.h @@ -43,10 +43,19 @@ 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. @@ -54,9 +63,18 @@ 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 b6ef31da0..a29e692fd 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -559,13 +559,21 @@ 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; 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; @@ -590,6 +598,14 @@ 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", @@ -620,7 +636,11 @@ 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 @@ -639,7 +659,11 @@ 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); diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h index 95bc297b0..513807b34 100644 --- a/src/libcharon/sa/child_sa.h +++ b/src/libcharon/sa/child_sa.h @@ -313,12 +313,20 @@ 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 1fb286863..f481f2059 100644 --- a/src/libcharon/sa/connect_manager.c +++ b/src/libcharon/sa/connect_manager.c @@ -1194,7 +1194,14 @@ 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 a4e4028ab..58d24b48c 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -50,6 +50,10 @@ #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> @@ -559,6 +563,7 @@ 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) { @@ -566,6 +571,8 @@ METHOD(ike_sa_t, send_dpd, status_t, 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 */ @@ -578,7 +585,11 @@ 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; @@ -604,8 +615,16 @@ 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; } @@ -680,7 +699,14 @@ 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; } @@ -825,7 +851,11 @@ 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; @@ -858,7 +888,11 @@ 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; @@ -891,8 +925,19 @@ 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); + return SUCCESS; + } + 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); } @@ -901,7 +946,11 @@ 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; @@ -910,7 +959,11 @@ 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); @@ -1175,6 +1228,10 @@ 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 */ @@ -1185,9 +1242,35 @@ 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; + unknown_payload_t *unknown; + payload_t *payload; + + enumerator = message->create_payload_enumerator(message); + while (enumerator->enumerate(enumerator, &payload)) + { + unknown = (unknown_payload_t*)payload; + type = payload->get_type(payload); + if (!payload_is_known(type) && + unknown->is_critical(unknown)) + { + DBG1(DBG_ENC, "payload type %N is not supported, " + "but its critical!", payload_type_names, type); + status = NOT_SUPPORTED; + } + } + enumerator->destroy(enumerator); + } + if (status != SUCCESS) + { +>>>>>>> upstream/4.5.1 if (is_request) { switch (status) @@ -1196,21 +1279,40 @@ 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: @@ -1219,10 +1321,13 @@ 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; } @@ -1252,7 +1357,12 @@ 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 */ diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index c0007e27d..1f96f9abd 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -343,8 +343,14 @@ 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. diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index fa94bb86d..ea31f5359 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -1,6 +1,12 @@ /* +<<<<<<< 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 * @@ -85,7 +91,13 @@ 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; @@ -241,6 +253,12 @@ 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; }; @@ -257,10 +275,19 @@ 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; @@ -396,7 +423,11 @@ 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); } @@ -409,7 +440,11 @@ 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); } @@ -453,10 +488,15 @@ 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) { @@ -502,10 +542,15 @@ static bool enumerate(private_enumerator_t *this, entry_t **entry, u_int *segmen 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) { @@ -524,6 +569,7 @@ static void enumerator_destroy(private_enumerator_t *this) */ 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; @@ -534,6 +580,17 @@ static enumerator_t* create_table_enumerator(private_ike_sa_manager_t *this) enumerator->row = 0; enumerator->current = NULL; +======= + private_enumerator_t *enumerator; + + INIT(enumerator, + .enumerator = { + .enumerate = (void*)_enumerate, + .destroy = _enumerator_destroy, + }, + .manager = this, + ); +>>>>>>> upstream/4.5.1 return &enumerator->enumerator; } @@ -544,11 +601,22 @@ 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; + segment = row & this->segment_mask; + + 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(); } @@ -564,6 +632,7 @@ 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; @@ -572,6 +641,19 @@ static void remove_entry(private_ike_sa_manager_t *this, entry_t *entry) 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; + segment = row & this->segment_mask; + list = this->ike_sa_table[row]; + if (list) + { + entry_t *current; + enumerator_t *enumerator; + + enumerator = list->create_enumerator(list); +>>>>>>> upstream/4.5.1 while (enumerator->enumerate(enumerator, ¤t)) { if (current == entry) @@ -609,11 +691,22 @@ 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; + seg = row & this->segment_mask; + + 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) { @@ -697,6 +790,7 @@ 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; @@ -710,6 +804,22 @@ static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry) else { half_open_t *current; +======= + chunk_t addr; + u_int row, segment; + rwlock_t *lock; + + addr = entry->other->get_address(entry->other); + row = chunk_hash(addr) & this->table_mask; + segment = row & this->segment_mask; + lock = this->half_open_segments[segment].lock; + lock->write_lock(lock); + list = this->half_open_table[row]; + if (list) + { + half_open_t *current; + +>>>>>>> upstream/4.5.1 if (list->find_first(list, (linked_list_match_t)half_open_match, (void**)¤t, &addr) == SUCCESS) { @@ -718,12 +828,26 @@ 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(); + } + + if (!half_open) + { + INIT(half_open, + .other = chunk_clone(addr), + .count = 1, + ); +>>>>>>> upstream/4.5.1 list->insert_last(list, half_open); this->half_open_segments[segment].count++; } @@ -736,6 +860,7 @@ 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; @@ -746,6 +871,24 @@ static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry) { half_open_t *current; enumerator_t *enumerator = list->create_enumerator(list); +======= + chunk_t addr; + u_int row, segment; + rwlock_t *lock; + + addr = entry->other->get_address(entry->other); + row = chunk_hash(addr) & this->table_mask; + segment = row & this->segment_mask; + lock = this->half_open_segments[segment].lock; + lock->write_lock(lock); + list = this->half_open_table[row]; + if (list) + { + half_open_t *current; + enumerator_t *enumerator; + + enumerator = list->create_enumerator(list); +>>>>>>> upstream/4.5.1 while (enumerator->enumerate(enumerator, ¤t)) { if (half_open_match(current, &addr)) @@ -769,6 +912,7 @@ 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), @@ -787,6 +931,28 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry) 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; + u_int row, segment; + rwlock_t *lock; + + my_id = entry->my_id->get_encoding(entry->my_id); + other_id = entry->other_id->get_encoding(entry->other_id); + row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask; + segment = row & this->segment_mask; + lock = this->connected_peers_segments[segment].lock; + lock->write_lock(lock); + list = this->connected_peers_table[row]; + if (list) + { + connected_peers_t *current; + + 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, @@ -798,6 +964,7 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry) } } } +<<<<<<< HEAD if (!connected_peers) { @@ -805,6 +972,21 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry) 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(); + } + + if (!connected_peers) + { + INIT(connected_peers, + .my_id = entry->my_id->clone(entry->my_id), + .other_id = entry->other_id->clone(entry->other_id), + .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, @@ -818,6 +1000,7 @@ 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); @@ -836,6 +1019,36 @@ static void remove_connected_peers(private_ike_sa_manager_t *this, entry_t *entr { 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; + rwlock_t *lock; + + my_id = entry->my_id->get_encoding(entry->my_id); + other_id = entry->other_id->get_encoding(entry->other_id); + row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask; + segment = row & this->segment_mask; + + lock = this->connected_peers_segments[segment].lock; + lock->write_lock(lock); + list = this->connected_peers_table[row]; + if (list) + { + connected_peers_t *current; + enumerator_t *enumerator; + + enumerator = list->create_enumerator(list); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (connected_peers_match(current, entry->my_id, entry->other_id, + (uintptr_t)entry->other->get_family(entry->other))) + { + ike_sa_id_t *ike_sa_id; + 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)) @@ -861,6 +1074,7 @@ 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) @@ -875,6 +1089,23 @@ static u_int64_t get_next_spi(private_ike_sa_manager_t *this) * 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) +{ + u_int64_t spi = 0; + + if (this->rng) + { + this->rng->get_bytes(this->rng, sizeof(spi), (u_int8_t*)&spi); + } + return spi; +} + +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; @@ -897,6 +1128,7 @@ static ike_sa_t* checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id return ike_sa; } +<<<<<<< HEAD /** * Implementation of of ike_sa_manager.checkout_new. */ @@ -916,10 +1148,29 @@ static ike_sa_t *checkout_new(private_ike_sa_manager_t* this, bool initiator) 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) +{ + ike_sa_id_t *ike_sa_id; + ike_sa_t *ike_sa; + + if (initiator) + { + ike_sa_id = ike_sa_id_create(get_spi(this), 0, TRUE); + } + else + { + ike_sa_id = ike_sa_id_create(0, get_spi(this), FALSE); + } + 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); @@ -940,19 +1191,37 @@ static ike_sa_t *checkout_new(private_ike_sa_manager_t* this, bool initiator) */ 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; @@ -988,7 +1257,11 @@ static ike_sa_t* checkout_by_message(private_ike_sa_manager_t* this, 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); @@ -1048,11 +1321,16 @@ static ike_sa_t* checkout_by_message(private_ike_sa_manager_t* this, 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; @@ -1107,11 +1385,16 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this, 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; @@ -1164,11 +1447,16 @@ static ike_sa_t* checkout_by_id(private_ike_sa_manager_t *this, u_int32_t id, 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; @@ -1233,6 +1521,7 @@ static bool enumerator_filter(private_ike_sa_manager_t *this, return FALSE; } +<<<<<<< HEAD /** * Implementation of ike_sa_manager_t.create_enumerator. */ @@ -1247,6 +1536,17 @@ static enumerator_t *create_enumerator(private_ike_sa_manager_t* this) * 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) +{ + return enumerator_create_filter(create_table_enumerator(this), + (void*)enumerator_filter, this, NULL); +} + +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. @@ -1311,13 +1611,25 @@ static void checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa) 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); } @@ -1326,10 +1638,15 @@ static void checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa) 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. @@ -1366,8 +1683,12 @@ static void checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ike_sa { 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); } @@ -1384,11 +1705,16 @@ static void checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ike_sa 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; @@ -1402,7 +1728,11 @@ static bool check_uniqueness(private_ike_sa_manager_t *this, ike_sa_t *ike_sa) 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; } @@ -1416,12 +1746,25 @@ static bool check_uniqueness(private_ike_sa_manager_t *this, ike_sa_t *ike_sa) 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) + { + connected_peers_t *current; + host_t *other_host; + + other_host = ike_sa->get_other_host(ike_sa); + 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, @@ -1446,6 +1789,16 @@ static bool check_uniqueness(private_ike_sa_manager_t *this, ike_sa_t *ike_sa) { continue; } +<<<<<<< HEAD +======= + if (force_replace) + { + DBG1(DBG_IKE, "destroying duplicate IKE_SA for peer '%Y', " + "received INITIAL_CONTACT", other); + 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))) { @@ -1490,21 +1843,66 @@ static bool check_uniqueness(private_ike_sa_manager_t *this, ike_sa_t *ike_sa) 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) +{ + linked_list_t *list; + u_int row, segment; + rwlock_t *lock; + bool found = FALSE; + + row = chunk_hash_inc(other->get_encoding(other), + chunk_hash(me->get_encoding(me))) & this->table_mask; + segment = row & this->segment_mask; + lock = this->connected_peers_segments[segment & this->segment_mask].lock; + lock->read_lock(lock); + list = this->connected_peers_table[row]; + if (list) + { + if (list->find_first(list, (linked_list_match_t)connected_peers_match, + NULL, me, other, family) == SUCCESS) + { + found = TRUE; + } + } + lock->unlock(lock); + + return found; +} + +METHOD(ike_sa_manager_t, get_half_open_count, int, + private_ike_sa_manager_t *this, host_t *ip) +{ + linked_list_t *list; + 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) { @@ -1520,17 +1918,23 @@ static int get_half_open_count(private_ike_sa_manager_t *this, host_t *ip) } 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; } @@ -1539,6 +1943,13 @@ static int get_half_open_count(private_ike_sa_manager_t *this, host_t *ip) * 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; @@ -1602,8 +2013,12 @@ static void flush(private_ike_sa_manager_t *this) { 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); } @@ -1615,6 +2030,7 @@ static void flush(private_ike_sa_manager_t *this) unlock_all_segments(this); this->rng->destroy(this->rng); +<<<<<<< HEAD this->hasher->destroy(this->hasher); } @@ -1641,11 +2057,32 @@ static void destroy(private_ike_sa_manager_t *this) { list->destroy(list); } +======= + this->rng = NULL; + this->hasher->destroy(this->hasher); + this->hasher = NULL; +} + +METHOD(ike_sa_manager_t, destroy, void, + private_ike_sa_manager_t *this) +{ + u_int i; + + for (i = 0; i < this->table_size; i++) + { + 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); @@ -1681,6 +2118,7 @@ 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); @@ -1700,6 +2138,30 @@ ike_sa_manager_t *ike_sa_manager_create() 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; + + INIT(this, + .public = { + .checkout = _checkout, + .checkout_new = _checkout_new, + .checkout_by_message = _checkout_by_message, + .checkout_by_config = _checkout_by_config, + .checkout_by_id = _checkout_by_id, + .checkout_by_name = _checkout_by_name, + .check_uniqueness = _check_uniqueness, + .has_contact = _has_contact, + .create_enumerator = _create_enumerator, + .checkin = _checkin, + .checkin_and_destroy = _checkin_and_destroy, + .get_half_open_count = _get_half_open_count, + .flush = _flush, + .destroy = _destroy, + }, + ); + +>>>>>>> upstream/4.5.1 this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_PREFERRED); if (this->hasher == NULL) { @@ -1715,6 +2177,10 @@ 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)); @@ -1724,11 +2190,18 @@ 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; @@ -1737,7 +2210,11 @@ 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; @@ -1746,7 +2223,11 @@ 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 f4eabf808..2c81592d2 100644 --- a/src/libcharon/sa/ike_sa_manager.h +++ b/src/libcharon/sa/ike_sa_manager.h @@ -52,9 +52,12 @@ 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 */ @@ -109,10 +112,30 @@ 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 + */ + bool (*check_uniqueness)(ike_sa_manager_t *this, ike_sa_t *ike_sa, + bool force_replace); + + /** + * Check if we already have a connected IKE_SA between two identities. + * + * @param me own identity + * @param other remote identity + * @param family address family to include in uniqueness check + * @return TRUE if we have a connected IKE_SA + */ + 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 878ad124f..2721fb3b9 100644 --- a/src/libcharon/sa/keymat.c +++ b/src/libcharon/sa/keymat.c @@ -214,7 +214,11 @@ 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; @@ -540,7 +544,11 @@ 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; @@ -548,8 +556,13 @@ 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); @@ -570,7 +583,11 @@ 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; @@ -578,7 +595,11 @@ 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 4f01aa411..d1d0591c5 100644 --- a/src/libcharon/sa/keymat.h +++ b/src/libcharon/sa/keymat.h @@ -117,10 +117,19 @@ 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. * @@ -133,10 +142,19 @@ 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 18703ce36..97c5510f2 100644 --- a/src/libcharon/sa/task_manager.c +++ b/src/libcharon/sa/task_manager.c @@ -465,7 +465,10 @@ 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) @@ -654,7 +657,10 @@ 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); @@ -882,8 +888,17 @@ 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)) { @@ -895,10 +910,21 @@ 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); + } + } + charon->bus->message(charon->bus, msg, TRUE); + if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED) + { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */ + return SUCCESS; + } +>>>>>>> upstream/4.5.1 if (process_request(this, msg) != SUCCESS) { flush(this); @@ -909,15 +935,26 @@ 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 @@ -936,10 +973,21 @@ 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); + } + } + charon->bus->message(charon->bus, msg, TRUE); + if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED) + { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */ + return SUCCESS; + } +>>>>>>> upstream/4.5.1 if (process_response(this, msg) != SUCCESS) { flush(this); @@ -1002,6 +1050,22 @@ 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) +{ + if (initiate) + { + this->initiating.mid++; + } + else + { + this->responding.mid++; + } +} + +>>>>>>> upstream/4.5.1 METHOD(task_manager_t, reset, void, private_task_manager_t *this, u_int32_t initiate, u_int32_t respond) { @@ -1085,6 +1149,10 @@ 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 14fccd5f9..f5dcc8977 100644 --- a/src/libcharon/sa/task_manager.h +++ b/src/libcharon/sa/task_manager.h @@ -149,6 +149,19 @@ 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 + * the message ID counters of the task manager. + * + * @param inititate TRUE to increment the initiating ID + */ + 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 57beedba9..16f7b6d81 100644 --- a/src/libcharon/sa/tasks/child_create.c +++ b/src/libcharon/sa/tasks/child_create.c @@ -117,6 +117,14 @@ 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; @@ -455,6 +463,7 @@ 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, @@ -466,6 +475,23 @@ static status_t select_and_install(private_child_create_t *this, 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); + status_o = this->child_sa->install(this->child_sa, + encr_i, integ_i, this->other_spi, this->other_cpi, + FALSE, this->tfcv3, 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, this->tfcv3, my_ts, other_ts); + 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); @@ -631,7 +657,17 @@ 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: + DBG1(DBG_IKE, "received %N, not using ESPv3 TFC padding", + notify_type_names, notify->get_notify_type(notify)); + this->tfcv3 = FALSE; + break; +>>>>>>> upstream/4.5.1 default: break; } @@ -691,10 +727,15 @@ 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; @@ -831,10 +872,15 @@ static status_t build_i(private_child_create_t *this, message_t *message) 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)) { @@ -877,10 +923,15 @@ 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; @@ -958,7 +1009,11 @@ static status_t build_r(private_child_create_t *this, message_t *message) 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); @@ -1029,10 +1084,15 @@ static status_t build_r(private_child_create_t *this, message_t *message) 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; @@ -1103,7 +1163,25 @@ static status_t process_i(private_child_create_t *this, message_t *message) return NEED_MORE; } default: +<<<<<<< HEAD + break; +======= + { + if (message->get_exchange_type(message) == CREATE_CHILD_SA) + { /* handle notifies if not handled in IKE_AUTH */ + if (type <= 16383) + { + DBG1(DBG_IKE, "received %N notify error", + notify_type_names, type); + enumerator->destroy(enumerator); + return SUCCESS; + } + DBG2(DBG_IKE, "received %N notify", + notify_type_names, type); + } break; + } +>>>>>>> upstream/4.5.1 } } } @@ -1155,6 +1233,7 @@ static status_t process_i(private_child_create_t *this, message_t *message) return SUCCESS; } +<<<<<<< HEAD /** * Implementation of task_t.get_type */ @@ -1167,22 +1246,36 @@ static task_type_t get_type(private_child_create_t *this) * 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) @@ -1195,10 +1288,21 @@ static chunk_t get_lower_nonce(private_child_create_t *this) } } +<<<<<<< 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) +{ + return CHILD_CREATE; +} + +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); @@ -1234,10 +1338,15 @@ static void migrate(private_child_create_t *this, ike_sa_t *ike_sa) 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); @@ -1273,6 +1382,7 @@ 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; @@ -1285,11 +1395,44 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, { this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; +======= + private_child_create_t *this; + + INIT(this, + .public = { + .get_child = _get_child, + .get_lower_nonce = _get_lower_nonce, + .use_reqid = _use_reqid, + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .config = config, + .packet_tsi = tsi ? tsi->clone(tsi) : NULL, + .packet_tsr = tsr ? tsr->clone(tsr) : NULL, + .dh_group = MODP_NONE, + .keymat = ike_sa->get_keymat(ike_sa), + .mode = MODE_TUNNEL, + .tfcv3 = TRUE, + .ipcomp = IPCOMP_NONE, + .ipcomp_received = IPCOMP_NONE, + .rekey = rekey, + ); + + if (config) + { + 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; @@ -1320,5 +1463,12 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, 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_rekey.c b/src/libcharon/sa/tasks/child_rekey.c index fdaaea4b8..5ffe49293 100644 --- a/src/libcharon/sa/tasks/child_rekey.c +++ b/src/libcharon/sa/tasks/child_rekey.c @@ -241,12 +241,20 @@ 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) @@ -259,7 +267,11 @@ 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); } } diff --git a/src/libcharon/sa/tasks/ike_auth.c b/src/libcharon/sa/tasks/ike_auth.c index b440ec811..fbc177d6f 100644 --- a/src/libcharon/sa/tasks/ike_auth.c +++ b/src/libcharon/sa/tasks/ike_auth.c @@ -68,6 +68,14 @@ 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; @@ -101,6 +109,14 @@ 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 }; /** @@ -160,6 +176,27 @@ 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) +{ + u_int8_t *byte; + int i; + + for (i = 0; i < countof(this->reserved); i++) + { + byte = payload_get_field(&id->payload_interface, RESERVED_BYTE, i); + if (byte) + { + this->reserved[i] = *byte; + } + } +} + +/** +>>>>>>> upstream/4.5.1 * Get the next authentication configuration */ static auth_cfg_t *get_auth_cfg(private_ike_auth_t *this, bool local) @@ -329,10 +366,15 @@ 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; @@ -367,7 +409,11 @@ static status_t build_i(private_ike_auth_t *this, message_t *message) /* 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 */ @@ -378,33 +424,73 @@ static status_t build_i(private_ike_auth_t *this, message_t *message) 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); + message->add_payload(message, (payload_t*)id_payload); + + if (idr && message->get_message_id(message) == 1 && + this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NO) + { + host_t *host; + + host = this->ike_sa->get_other_host(this->ike_sa); + if (!charon->ike_sa_manager->has_contact(charon->ike_sa_manager, + idi, idr, host->get_family(host))) + { + message->add_notify(message, FALSE, INITIAL_CONTACT, chunk_empty); + } + } + +>>>>>>> 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; @@ -441,10 +527,15 @@ static status_t build_i(private_ike_auth_t *this, message_t *message) 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; @@ -498,6 +589,10 @@ static status_t process_r(private_ike_auth_t *this, message_t *message) 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)); @@ -548,7 +643,12 @@ static status_t process_r(private_ike_auth_t *this, message_t *message) 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; @@ -572,10 +672,20 @@ static status_t process_r(private_ike_auth_t *this, message_t *message) 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 && + message->get_notify(message, INITIAL_CONTACT)) + { + this->initial_contact = TRUE; + } +>>>>>>> upstream/4.5.1 /* another auth round done, invoke authorize hook */ if (!charon->bus->authorize(charon->bus, FALSE)) @@ -585,6 +695,14 @@ static status_t process_r(private_ike_auth_t *this, message_t *message) 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; @@ -603,10 +721,15 @@ static status_t process_r(private_ike_auth_t *this, message_t *message) 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; @@ -662,8 +785,21 @@ static status_t build_r(private_ike_auth_t *this, message_t *message) } 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); + if (this->initial_contact) + { + charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager, + this->ike_sa, TRUE); + 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, @@ -682,7 +818,12 @@ static status_t build_r(private_ike_auth_t *this, message_t *message) 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, @@ -744,7 +885,11 @@ static status_t build_r(private_ike_auth_t *this, message_t *message) 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, @@ -772,10 +917,15 @@ static status_t build_r(private_ike_auth_t *this, message_t *message) 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; @@ -857,6 +1007,10 @@ static status_t process_i(private_ike_auth_t *this, message_t *message) 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)); @@ -867,7 +1021,12 @@ static status_t process_i(private_ike_auth_t *this, message_t *message) 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; @@ -893,17 +1052,28 @@ static status_t process_i(private_ike_auth_t *this, message_t *message) 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) @@ -964,18 +1134,28 @@ static status_t process_i(private_ike_auth_t *this, message_t *message) 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); @@ -998,10 +1178,15 @@ static void migrate(private_ike_auth_t *this, ike_sa_t *ike_sa) 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); @@ -1019,6 +1204,7 @@ static void destroy(private_ike_auth_t *this) */ 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; @@ -1050,6 +1236,31 @@ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator) this->expect_another_auth = TRUE; this->authentication_failed = FALSE; +======= + private_ike_auth_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .build = _build_r, + .process = _process_r, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .initiator = initiator, + .candidates = linked_list_create(), + .do_another_auth = TRUE, + .expect_another_auth = TRUE, + ); + if (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 1c0c54727..8da8d549a 100644 --- a/src/libcharon/sa/tasks/ike_cert_pre.c +++ b/src/libcharon/sa/tasks/ike_cert_pre.c @@ -76,6 +76,10 @@ 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); @@ -103,12 +107,26 @@ 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: @@ -253,11 +271,26 @@ 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) + { + DBG1(DBG_IKE, "received CRL \"%Y\"", + cert->get_subject(cert)); + 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_rekey.c b/src/libcharon/sa/tasks/ike_rekey.c index 1a6c140c4..1698ddd34 100644 --- a/src/libcharon/sa/tasks/ike_rekey.c +++ b/src/libcharon/sa/tasks/ike_rekey.c @@ -255,19 +255,32 @@ 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)); |