diff options
author | Tobias Brunner <tobias@strongswan.org> | 2013-01-19 18:05:48 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2013-01-24 19:13:40 +0100 |
commit | 2ec3552fce1d8d37dc8766c548b5353f31b57370 (patch) | |
tree | 0913f37c149ce92784f4c80f5e50bf49684666f5 /src/libcharon/sa/ikev2 | |
parent | a25047e412ab89904477cd2f223f921f413e3732 (diff) | |
download | strongswan-2ec3552fce1d8d37dc8766c548b5353f31b57370.tar.bz2 strongswan-2ec3552fce1d8d37dc8766c548b5353f31b57370.tar.xz |
Fix check-in of IKE_SA when IKE_SA_INIT fails and hash table is enabled
Setting the responder SPI to 0 can only be done while generating the
response, otherwise we'd fail to check in the IKE_SA again in case the
hash table is enabled. That's because we use the responder SPI as hash
value since 5.0.0.
Diffstat (limited to 'src/libcharon/sa/ikev2')
-rw-r--r-- | src/libcharon/sa/ikev2/task_manager_v2.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 5cb1490eb..ea0117c54 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -630,6 +630,8 @@ static status_t build_response(private_task_manager_t *this, message_t *request) message_t *message; host_t *me, *other; bool delete = FALSE, hook = FALSE; + ike_sa_id_t *id = NULL; + u_int64_t responder_spi; status_t status; me = request->get_destination(request); @@ -680,10 +682,15 @@ static status_t build_response(private_task_manager_t *this, message_t *request) } enumerator->destroy(enumerator); - /* remove resonder SPI if IKE_SA_INIT failed */ + /* RFC 5996, section 2.6 mentions that in the event of a failure during + * IKE_SA_INIT the responder's SPI will be 0 in the response, while it + * actually explicitly allows it to be non-zero. Since we use the responder + * SPI to create hashes in the IKE_SA manager we can only set the SPI to + * zero temporarily, otherwise checking the SA in would fail. */ if (delete && request->get_exchange_type(request) == IKE_SA_INIT) { - ike_sa_id_t *id = this->ike_sa->get_id(this->ike_sa); + id = this->ike_sa->get_id(this->ike_sa); + responder_spi = id->get_responder_spi(id); id->set_responder_spi(id, 0); } @@ -693,6 +700,10 @@ static status_t build_response(private_task_manager_t *this, message_t *request) status = this->ike_sa->generate_message(this->ike_sa, message, &this->responding.packet); message->destroy(message); + if (id) + { + id->set_responder_spi(id, responder_spi); + } if (status != SUCCESS) { charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); |