From 5dca9ea0e2931f0e2a056c7964d311bcc30a01b8 Mon Sep 17 00:00:00 2001 From: Yves-Alexis Perez Date: Thu, 22 Oct 2015 11:43:58 +0200 Subject: Imported Upstream version 5.3.3 --- src/libcharon/sa/ikev1/phase1.c | 2 +- src/libcharon/sa/ikev1/task_manager_v1.c | 35 ++++++++++++++++++++++++++++++- src/libcharon/sa/ikev1/tasks/quick_mode.c | 26 ++++++++++++++++++++++- src/libcharon/sa/ikev1/tasks/quick_mode.h | 11 ++++++++++ 4 files changed, 71 insertions(+), 3 deletions(-) (limited to 'src/libcharon/sa/ikev1') diff --git a/src/libcharon/sa/ikev1/phase1.c b/src/libcharon/sa/ikev1/phase1.c index c968b2a9c..b7047e8fc 100644 --- a/src/libcharon/sa/ikev1/phase1.c +++ b/src/libcharon/sa/ikev1/phase1.c @@ -404,7 +404,7 @@ static auth_method_t get_pubkey_method(private_phase1_t *this, auth_cfg_t *auth) id = (identification_t*)auth->get(auth, AUTH_RULE_IDENTITY); if (id) { - private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, NULL); + private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth); if (private) { switch (private->get_type(private)) diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c index ed547c4c2..678f99df1 100644 --- a/src/libcharon/sa/ikev1/task_manager_v1.c +++ b/src/libcharon/sa/ikev1/task_manager_v1.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2014 Tobias Brunner + * Copyright (C) 2007-2015 Tobias Brunner * Copyright (C) 2007-2011 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -900,6 +900,34 @@ static bool process_dpd(private_task_manager_t *this, message_t *message) return TRUE; } +/** + * Check if we already have a quick mode task queued for the exchange with the + * given message ID + */ +static bool have_quick_mode_task(private_task_manager_t *this, u_int32_t mid) +{ + enumerator_t *enumerator; + quick_mode_t *qm; + task_t *task; + bool found = FALSE; + + enumerator = this->passive_tasks->create_enumerator(this->passive_tasks); + while (enumerator->enumerate(enumerator, &task)) + { + if (task->get_type(task) == TASK_QUICK_MODE) + { + qm = (quick_mode_t*)task; + if (qm->get_mid(qm) == mid) + { + found = TRUE; + break; + } + } + } + enumerator->destroy(enumerator); + return found; +} + /** * handle an incoming request message */ @@ -911,6 +939,7 @@ static status_t process_request(private_task_manager_t *this, bool send_response = FALSE, dpd = FALSE; if (message->get_exchange_type(message) == INFORMATIONAL_V1 || + message->get_exchange_type(message) == QUICK_MODE || this->passive_tasks->get_count(this->passive_tasks) == 0) { /* create tasks depending on request type, if not already some queued */ switch (message->get_exchange_type(message)) @@ -946,6 +975,10 @@ static status_t process_request(private_task_manager_t *this, "unestablished IKE_SA, ignored"); return FAILED; } + if (have_quick_mode_task(this, message->get_message_id(message))) + { + break; + } task = (task_t *)quick_mode_create(this->ike_sa, NULL, NULL, NULL); this->passive_tasks->insert_last(this->passive_tasks, task); diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index 96edfd8d8..d6a3f2cd1 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2015 Tobias Brunner * Hochschule fuer Technik Rapperswil * * Copyright (C) 2011 Martin Willi @@ -185,6 +185,11 @@ struct private_quick_mode_t { */ bool udp; + /** + * Message ID of handled quick mode exchange + */ + u_int32_t mid; + /** states of quick mode */ enum { QM_INIT, @@ -1019,6 +1024,11 @@ static void check_for_rekeyed_child(private_quick_mode_t *this) METHOD(task_t, process_r, status_t, private_quick_mode_t *this, message_t *message) { + if (this->mid && this->mid != message->get_message_id(message)) + { /* not responsible for this quick mode exchange */ + return NEED_MORE; + } + switch (this->state) { case QM_INIT: @@ -1188,6 +1198,11 @@ METHOD(task_t, process_r, status_t, METHOD(task_t, build_r, status_t, private_quick_mode_t *this, message_t *message) { + if (this->mid && this->mid != message->get_message_id(message)) + { /* not responsible for this quick mode exchange */ + return NEED_MORE; + } + switch (this->state) { case QM_INIT: @@ -1242,6 +1257,7 @@ METHOD(task_t, build_r, status_t, add_ts(this, message); this->state = QM_NEGOTIATED; + this->mid = message->get_message_id(message); return NEED_MORE; } case QM_NEGOTIATED: @@ -1335,6 +1351,12 @@ METHOD(task_t, get_type, task_type_t, return TASK_QUICK_MODE; } +METHOD(quick_mode_t, get_mid, u_int32_t, + private_quick_mode_t *this) +{ + return this->mid; +} + METHOD(quick_mode_t, use_reqid, void, private_quick_mode_t *this, u_int32_t reqid) { @@ -1368,6 +1390,7 @@ METHOD(task_t, migrate, void, this->ike_sa = ike_sa; this->keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa); this->state = QM_INIT; + this->mid = 0; this->tsi = NULL; this->tsr = NULL; this->proposal = NULL; @@ -1414,6 +1437,7 @@ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config, .migrate = _migrate, .destroy = _destroy, }, + .get_mid = _get_mid, .use_reqid = _use_reqid, .use_marks = _use_marks, .rekey = _rekey, diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.h b/src/libcharon/sa/ikev1/tasks/quick_mode.h index ee9b64d13..062d63465 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.h +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2015 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2011 Martin Willi * Copyright (C) 2011 revosec AG * @@ -37,6 +40,14 @@ struct quick_mode_t { */ task_t task; + /** + * Get the message ID of the quick mode exchange handled by this task as + * responder. + * + * @return message ID, or 0 (not defined yet or as initiator) + */ + u_int32_t (*get_mid)(quick_mode_t *this); + /** * Use a specific reqid to install this CHILD_SA. * -- cgit v1.2.3