From 1960312cfd65ff46f843632ce5d19bb3df6d54f9 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 25 Nov 2011 16:05:00 +0100 Subject: [PATCH] Avoid parsing retransmits we already responded to. Decryption will fail as we already moved the IV when we sent the response. Without this change, encrypted retransmits would have been discarded during parsing already. --- src/libcharon/sa/task_manager_v1.c | 71 ++++++++++++++++-------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/src/libcharon/sa/task_manager_v1.c b/src/libcharon/sa/task_manager_v1.c index 9e94d96db..b9d2e2336 100644 --- a/src/libcharon/sa/task_manager_v1.c +++ b/src/libcharon/sa/task_manager_v1.c @@ -653,46 +653,22 @@ METHOD(task_manager_t, process_message, status_t, host_t *me, *other; status_t status; - status = msg->parse_body(msg, this->ike_sa->get_keymat(this->ike_sa)); - if (status != SUCCESS) - { - return status; - } - + /* TODO-IKEv1: update hosts more selectively */ me = msg->get_destination(msg); other = msg->get_source(msg); - - /* if this IKE_SA is virgin, we check for a config */ - if (this->ike_sa->get_ike_cfg(this->ike_sa) == NULL) - { - ike_sa_id_t *ike_sa_id; - ike_cfg_t *ike_cfg; - job_t *job; - ike_cfg = charon->backends->get_ike_cfg(charon->backends, me, other); - if (ike_cfg == NULL) - { - /* no config found for these hosts, destroy */ - DBG1(DBG_IKE, "no IKE config found for %H...%H", me, other); - return DESTROY_ME; - } - this->ike_sa->set_ike_cfg(this->ike_sa, ike_cfg); - ike_cfg->destroy(ike_cfg); - /* add a timeout if peer does not establish it completely */ - ike_sa_id = this->ike_sa->get_id(this->ike_sa); - job = (job_t*)delete_ike_sa_job_create(ike_sa_id, FALSE); - lib->scheduler->schedule_job(lib->scheduler, job, - lib->settings->get_int(lib->settings, - "charon.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT)); - } - this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, - time_monotonic(NULL)); - - /* TODO-IKEv1: update hosts more selectively */ mid = msg->get_message_id(msg); + if ((mid && mid == this->initiating.mid) || (this->initiating.mid == 0 && this->active_tasks->get_count(this->active_tasks))) { + status = msg->parse_body(msg, this->ike_sa->get_keymat(this->ike_sa)); + if (status != SUCCESS) + { + return status; + } + this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, + time_monotonic(NULL)); this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE); charon->bus->message(charon->bus, msg, FALSE); if (process_response(this, msg) != SUCCESS) @@ -712,6 +688,35 @@ METHOD(task_manager_t, process_message, status_t, this->responding.packet->clone(this->responding.packet)); return SUCCESS; } + status = msg->parse_body(msg, this->ike_sa->get_keymat(this->ike_sa)); + if (status != SUCCESS) + { + return status; + } + /* if this IKE_SA is virgin, we check for a config */ + if (this->ike_sa->get_ike_cfg(this->ike_sa) == NULL) + { + ike_sa_id_t *ike_sa_id; + ike_cfg_t *ike_cfg; + job_t *job; + ike_cfg = charon->backends->get_ike_cfg(charon->backends, me, other); + if (ike_cfg == NULL) + { + /* no config found for these hosts, destroy */ + DBG1(DBG_IKE, "no IKE config found for %H...%H", me, other); + return DESTROY_ME; + } + this->ike_sa->set_ike_cfg(this->ike_sa, ike_cfg); + ike_cfg->destroy(ike_cfg); + /* add a timeout if peer does not establish it completely */ + ike_sa_id = this->ike_sa->get_id(this->ike_sa); + job = (job_t*)delete_ike_sa_job_create(ike_sa_id, FALSE); + lib->scheduler->schedule_job(lib->scheduler, job, + lib->settings->get_int(lib->settings, + "charon.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT)); + } + this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, + time_monotonic(NULL)); this->ike_sa->update_hosts(this->ike_sa, me, other, TRUE); charon->bus->message(charon->bus, msg, TRUE); if (process_request(this, msg) != SUCCESS)