summaryrefslogtreecommitdiff
path: root/src/charon/sa/tasks
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2009-02-28 22:02:31 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2009-02-28 22:02:31 +0000
commit19364e11c66714324bd3d5d0dc9212db397085cb (patch)
treefe7f5e55f0474dad1d0c29ba7c0a6f4546c99c3a /src/charon/sa/tasks
parentc7f1b0530b85bc7654e68992f25ed8ced5d0a80d (diff)
downloadvyos-strongswan-19364e11c66714324bd3d5d0dc9212db397085cb.tar.gz
vyos-strongswan-19364e11c66714324bd3d5d0dc9212db397085cb.zip
[svn-upgrade] Integrating new upstream version, strongswan (4.2.12)
Diffstat (limited to 'src/charon/sa/tasks')
-rw-r--r--src/charon/sa/tasks/child_create.c242
-rw-r--r--src/charon/sa/tasks/child_delete.c36
-rw-r--r--src/charon/sa/tasks/child_delete.h8
-rw-r--r--src/charon/sa/tasks/child_rekey.c112
-rw-r--r--src/charon/sa/tasks/child_rekey.h8
-rw-r--r--src/charon/sa/tasks/ike_auth.c76
-rw-r--r--src/charon/sa/tasks/ike_config.c106
-rw-r--r--src/charon/sa/tasks/ike_init.c69
-rw-r--r--src/charon/sa/tasks/ike_mobike.c21
-rw-r--r--src/charon/sa/tasks/ike_rekey.c48
10 files changed, 483 insertions, 243 deletions
diff --git a/src/charon/sa/tasks/child_create.c b/src/charon/sa/tasks/child_create.c
index 767ceef55..f6043979f 100644
--- a/src/charon/sa/tasks/child_create.c
+++ b/src/charon/sa/tasks/child_create.c
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: child_create.c 4618 2008-11-11 09:22:00Z tobias $
+ * $Id: child_create.c 4860 2009-02-11 13:09:52Z martin $
*/
#include "child_create.h"
@@ -117,7 +117,22 @@ struct private_child_create_t {
ipcomp_transform_t ipcomp_received;
/**
- * Other Compression Parameter Index (CPI)
+ * Own allocated SPI
+ */
+ u_int32_t my_spi;
+
+ /**
+ * SPI received in proposal
+ */
+ u_int32_t other_spi;
+
+ /**
+ * Own allocated Compression Parameter Index (CPI)
+ */
+ u_int16_t my_cpi;
+
+ /**
+ * Other Compression Parameter Index (CPI), received via IPCOMP_SUPPORTED
*/
u_int16_t other_cpi;
@@ -189,6 +204,36 @@ static bool ts_list_is_host(linked_list_t *list, host_t *host)
}
/**
+ * Allocate SPIs and update proposals
+ */
+static bool allocate_spi(private_child_create_t *this)
+{
+ enumerator_t *enumerator;
+ proposal_t *proposal;
+
+ /* TODO: allocate additional SPI for AH if we have such proposals */
+ this->my_spi = this->child_sa->alloc_spi(this->child_sa, PROTO_ESP);
+ if (this->my_spi)
+ {
+ if (this->initiator)
+ {
+ enumerator = this->proposals->create_enumerator(this->proposals);
+ while (enumerator->enumerate(enumerator, &proposal))
+ {
+ proposal->set_spi(proposal, this->my_spi);
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ this->proposal->set_spi(this->proposal, this->my_spi);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
* Install a CHILD_SA for usage, return value:
* - FAILED: no acceptable proposal
* - INVALID_ARG: diffie hellman group inacceptable
@@ -197,7 +242,9 @@ static bool ts_list_is_host(linked_list_t *list, host_t *host)
static status_t select_and_install(private_child_create_t *this, bool no_dh)
{
status_t status;
- chunk_t nonce_i, nonce_r, encr_i, integ_i, encr_r, integ_r;
+ chunk_t nonce_i, nonce_r;
+ chunk_t encr_i = chunk_empty, encr_r = chunk_empty;
+ chunk_t integ_i = chunk_empty, integ_r = chunk_empty;
linked_list_t *my_ts, *other_ts;
host_t *me, *other, *other_vip, *my_vip;
@@ -216,7 +263,7 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
other = this->ike_sa->get_other_host(this->ike_sa);
my_vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
other_vip = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
-
+
this->proposal = this->config->select_proposal(this->config, this->proposals,
no_dh);
if (this->proposal == NULL)
@@ -224,6 +271,14 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
DBG1(DBG_IKE, "no acceptable proposal found");
return FAILED;
}
+ this->other_spi = this->proposal->get_spi(this->proposal);
+
+ if (!this->initiator && !allocate_spi(this))
+ { /* responder has no SPI allocated yet */
+ DBG1(DBG_IKE, "allocating SPI failed");
+ return FAILED;
+ }
+ this->child_sa->set_proposal(this->child_sa, this->proposal);
if (!this->proposal->has_dh_group(this->proposal, this->dh_group))
{
@@ -328,26 +383,33 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
}
this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
+ this->child_sa->set_ipcomp(this->child_sa, this->ipcomp);
+ this->child_sa->set_mode(this->child_sa, this->mode);
+ this->child_sa->set_protocol(this->child_sa,
+ this->proposal->get_protocol(this->proposal));
- if (this->ipcomp != IPCOMP_NONE)
+ if (this->my_cpi == 0 || this->other_cpi == 0 || this->ipcomp == IPCOMP_NONE)
{
- this->child_sa->activate_ipcomp(this->child_sa, this->ipcomp,
- this->other_cpi);
+ this->my_cpi = this->other_cpi = 0;
+ this->ipcomp = IPCOMP_NONE;
}
-
status = FAILED;
if (this->keymat->derive_child_keys(this->keymat, this->proposal,
this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
{
if (this->initiator)
{
- status = this->child_sa->update(this->child_sa, this->proposal,
- this->mode, integ_r, integ_i, encr_r, encr_i);
+ status = this->child_sa->install(this->child_sa, encr_r, integ_r,
+ this->my_spi, this->my_cpi, TRUE);
+ status = this->child_sa->install(this->child_sa, encr_i, integ_i,
+ this->other_spi, this->other_cpi, FALSE);
}
else
{
- status = this->child_sa->add(this->child_sa, this->proposal,
- this->mode, integ_i, integ_r, encr_i, encr_r);
+ status = this->child_sa->install(this->child_sa, encr_i, integ_i,
+ this->my_spi, this->my_cpi, TRUE);
+ status = this->child_sa->install(this->child_sa, encr_r, integ_r,
+ this->other_spi, this->other_cpi, FALSE);
}
}
chunk_clear(&integ_i);
@@ -361,8 +423,7 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
return FAILED;
}
- status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts,
- this->mode, this->proposal->get_protocol(this->proposal));
+ status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts);
if (status != SUCCESS)
{
DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel");
@@ -436,33 +497,71 @@ static void build_payloads(private_child_create_t *this, message_t *message)
}
/**
- * Adds an IPCOMP_SUPPORTED notify to the message, if possible
+ * Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
*/
-static void build_ipcomp_supported_notify(private_child_create_t *this,
- message_t *message)
+static void add_ipcomp_notify(private_child_create_t *this,
+ message_t *message, u_int8_t ipcomp)
{
- u_int16_t cpi;
- u_int8_t tid;
-
if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
{
DBG1(DBG_IKE, "IPComp is not supported if either peer is natted, "
"IPComp disabled");
- this->ipcomp = IPCOMP_NONE;
return;
}
- cpi = this->child_sa->allocate_cpi(this->child_sa);
- tid = this->ipcomp;
- if (cpi)
+ this->my_cpi = this->child_sa->alloc_cpi(this->child_sa);
+ if (this->my_cpi)
{
- message->add_notify(message, FALSE, IPCOMP_SUPPORTED,
- chunk_cata("cc", chunk_from_thing(cpi), chunk_from_thing(tid)));
+ this->ipcomp = ipcomp;
+ message->add_notify(message, FALSE, IPCOMP_SUPPORTED,
+ chunk_cata("cc", chunk_from_thing(this->my_cpi),
+ chunk_from_thing(ipcomp)));
}
else
{
DBG1(DBG_IKE, "unable to allocate a CPI from kernel, IPComp disabled");
- this->ipcomp = IPCOMP_NONE;
+ }
+}
+
+/**
+ * handle a received notify payload
+ */
+static void handle_notify(private_child_create_t *this, notify_payload_t *notify)
+{
+ switch (notify->get_notify_type(notify))
+ {
+ case USE_TRANSPORT_MODE:
+ this->mode = MODE_TRANSPORT;
+ break;
+ case USE_BEET_MODE:
+ this->mode = MODE_BEET;
+ break;
+ case IPCOMP_SUPPORTED:
+ {
+ ipcomp_transform_t ipcomp;
+ u_int16_t cpi;
+ chunk_t data;
+
+ data = notify->get_notification_data(notify);
+ cpi = *(u_int16_t*)data.ptr;
+ ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
+ switch (ipcomp)
+ {
+ case IPCOMP_DEFLATE:
+ this->other_cpi = cpi;
+ this->ipcomp_received = ipcomp;
+ break;
+ case IPCOMP_LZS:
+ case IPCOMP_LZJH:
+ default:
+ DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a "
+ "transform ID we don't support %N",
+ ipcomp_transform_names, ipcomp);
+ break;
+ }
+ }
+ default:
+ break;
}
}
@@ -476,7 +575,6 @@ static void process_payloads(private_child_create_t *this, message_t *message)
sa_payload_t *sa_payload;
ke_payload_t *ke_payload;
ts_payload_t *ts_payload;
- notify_payload_t *notify_payload;
/* defaults to TUNNEL mode */
this->mode = MODE_TUNNEL;
@@ -512,37 +610,7 @@ static void process_payloads(private_child_create_t *this, message_t *message)
this->tsr = ts_payload->get_traffic_selectors(ts_payload);
break;
case NOTIFY:
- notify_payload = (notify_payload_t*)payload;
- switch (notify_payload ->get_notify_type(notify_payload ))
- {
- case USE_TRANSPORT_MODE:
- this->mode = MODE_TRANSPORT;
- break;
- case USE_BEET_MODE:
- this->mode = MODE_BEET;
- break;
- case IPCOMP_SUPPORTED:
- {
- chunk_t data = notify_payload->get_notification_data(notify_payload);
- u_int16_t cpi = *(u_int16_t*)data.ptr;
- ipcomp_transform_t ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
- switch(ipcomp)
- {
- case IPCOMP_DEFLATE:
- this->other_cpi = cpi;
- this->ipcomp_received = ipcomp;
- break;
- case IPCOMP_LZS:
- case IPCOMP_LZJH:
- default:
- DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a transform"
- " ID we don't support %N", ipcomp_transform_names, ipcomp);
- break;
- }
- }
- default:
- break;
- }
+ handle_notify(this, (notify_payload_t*)payload);
break;
default:
break;
@@ -557,9 +625,8 @@ static void process_payloads(private_child_create_t *this, message_t *message)
static status_t build_i(private_child_create_t *this, message_t *message)
{
host_t *me, *other, *vip;
- bool propose_all = FALSE;
peer_cfg_t *peer_cfg;
-
+
switch (message->get_exchange_type(message))
{
case IKE_SA_INIT:
@@ -610,23 +677,18 @@ static status_t build_i(private_child_create_t *this, message_t *message)
}
/* check if we want a virtual IP, but don't have one */
- if (!this->reqid)
+ peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
+ vip = peer_cfg->get_virtual_ip(peer_cfg);
+ if (!this->reqid && vip)
{
- peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
- vip = peer_cfg->get_virtual_ip(peer_cfg);
- if (vip)
- {
- propose_all = TRUE;
- }
- }
-
- if (propose_all)
- { /* propose a 0.0.0.0/0 subnet when we use virtual ip */
+ /* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
+ vip = host_create_any(vip->get_family(vip));
this->tsi = this->config->get_traffic_selectors(this->config, TRUE,
- NULL, NULL);
+ NULL, vip);
+ vip->destroy(vip);
}
else
- { /* but shorten a 0.0.0.0/0 subnet for host2host/we already have a vip */
+ { /* but narrow it for host2host / if we already have a vip */
this->tsi = this->config->get_traffic_selectors(this->config, TRUE,
NULL, me);
}
@@ -641,7 +703,7 @@ static status_t build_i(private_child_create_t *this, message_t *message)
this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
- if (this->child_sa->alloc(this->child_sa, this->proposals) != SUCCESS)
+ if (!allocate_spi(this))
{
DBG1(DBG_IKE, "unable to allocate SPIs from kernel");
return FAILED;
@@ -652,10 +714,10 @@ static status_t build_i(private_child_create_t *this, message_t *message)
this->dh = this->keymat->create_dh(this->keymat, this->dh_group);
}
- if (this->config->use_ipcomp(this->config)) {
+ if (this->config->use_ipcomp(this->config))
+ {
/* IPCOMP_DEFLATE is the only transform we support at the moment */
- this->ipcomp = IPCOMP_DEFLATE;
- build_ipcomp_supported_notify(this, message);
+ add_ipcomp_notify(this, message, IPCOMP_DEFLATE);
}
build_payloads(this, message);
@@ -821,16 +883,17 @@ static status_t build_r(private_child_create_t *this, message_t *message)
this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
- if (this->config->use_ipcomp(this->config) &&
- this->ipcomp_received != IPCOMP_NONE)
+ if (this->ipcomp_received != IPCOMP_NONE)
{
- this->ipcomp = this->ipcomp_received;
- build_ipcomp_supported_notify(this, message);
- }
- else if (this->ipcomp_received != IPCOMP_NONE)
- {
- DBG1(DBG_IKE, "received %N notify but IPComp is disabled, ignoring",
- notify_type_names, IPCOMP_SUPPORTED);
+ if (this->config->use_ipcomp(this->config))
+ {
+ add_ipcomp_notify(this, message, this->ipcomp_received);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received %N notify but IPComp is disabled, ignoring",
+ notify_type_names, IPCOMP_SUPPORTED);
+ }
}
switch (select_and_install(this, no_dh))
@@ -1052,6 +1115,8 @@ static void migrate(private_child_create_t *this, ike_sa_t *ike_sa)
}
this->ike_sa = ike_sa;
+ this->keymat = ike_sa->get_keymat(ike_sa);
+ this->proposal = NULL;
this->proposals = NULL;
this->tsi = NULL;
this->tsr = NULL;
@@ -1137,6 +1202,9 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config)
this->mode = MODE_TUNNEL;
this->ipcomp = IPCOMP_NONE;
this->ipcomp_received = IPCOMP_NONE;
+ this->my_spi = 0;
+ this->other_spi = 0;
+ this->my_cpi = 0;
this->other_cpi = 0;
this->reqid = 0;
this->established = FALSE;
diff --git a/src/charon/sa/tasks/child_delete.c b/src/charon/sa/tasks/child_delete.c
index cab1d63f0..0fd4a056b 100644
--- a/src/charon/sa/tasks/child_delete.c
+++ b/src/charon/sa/tasks/child_delete.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: child_delete.c 4434 2008-10-14 08:52:13Z martin $
+ * $Id: child_delete.c 4730 2008-12-01 18:38:28Z martin $
*/
#include "child_delete.h"
@@ -44,9 +44,19 @@ struct private_child_delete_t {
bool initiator;
/**
- * wheter to enforce delete action policy
- */
- bool check_delete_action;
+ * Protocol of CHILD_SA to delete
+ */
+ protocol_id_t protocol;
+
+ /**
+ * Inbound SPI of CHILD_SA to delete
+ */
+ u_int32_t spi;
+
+ /**
+ * wheter to enforce delete action policy
+ */
+ bool check_delete_action;
/**
* CHILD_SAs which get deleted
@@ -238,6 +248,16 @@ static void log_children(private_child_delete_t *this)
*/
static status_t build_i(private_child_delete_t *this, message_t *message)
{
+ child_sa_t *child_sa;
+
+ child_sa = this->ike_sa->get_child_sa(this->ike_sa, this->protocol,
+ this->spi, TRUE);
+ if (!child_sa)
+ { /* child does not exist anymore */
+ return SUCCESS;
+ }
+ this->child_sas->insert_last(this->child_sas, child_sa);
+
log_children(this);
build_payloads(this, message);
return NEED_MORE;
@@ -323,7 +343,8 @@ static void destroy(private_child_delete_t *this)
/*
* Described in header.
*/
-child_delete_t *child_delete_create(ike_sa_t *ike_sa, child_sa_t *child_sa)
+child_delete_t *child_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol,
+ u_int32_t spi)
{
private_child_delete_t *this = malloc_thing(private_child_delete_t);
@@ -335,13 +356,14 @@ child_delete_t *child_delete_create(ike_sa_t *ike_sa, child_sa_t *child_sa)
this->ike_sa = ike_sa;
this->check_delete_action = FALSE;
this->child_sas = linked_list_create();
+ this->protocol = protocol;
+ this->spi = spi;
- if (child_sa != NULL)
+ if (protocol != PROTO_NONE)
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
this->initiator = TRUE;
- this->child_sas->insert_last(this->child_sas, child_sa);
}
else
{
diff --git a/src/charon/sa/tasks/child_delete.h b/src/charon/sa/tasks/child_delete.h
index c304ea9d8..c5ebec338 100644
--- a/src/charon/sa/tasks/child_delete.h
+++ b/src/charon/sa/tasks/child_delete.h
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: child_delete.h 3589 2008-03-13 14:14:44Z martin $
+ * $Id: child_delete.h 4730 2008-12-01 18:38:28Z martin $
*/
/**
@@ -52,9 +52,11 @@ struct child_delete_t {
* Create a new child_delete task.
*
* @param ike_sa IKE_SA this task works for
- * @param child_sa CHILD_SA to delete, or NULL as responder
+ * @param protocol protocol of CHILD_SA to delete, PROTO_NONE as responder
+ * @param spi inbound SPI of CHILD_SA to delete
* @return child_delete task to handle by the task_manager
*/
-child_delete_t *child_delete_create(ike_sa_t *ike_sa, child_sa_t *child_sa);
+child_delete_t *child_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol,
+ u_int32_t spi);
#endif /* CHILD_DELETE_H_ @} */
diff --git a/src/charon/sa/tasks/child_rekey.c b/src/charon/sa/tasks/child_rekey.c
index e50ad33be..0d8cf2db7 100644
--- a/src/charon/sa/tasks/child_rekey.c
+++ b/src/charon/sa/tasks/child_rekey.c
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: child_rekey.c 4659 2008-11-14 14:05:47Z martin $
+ * $Id: child_rekey.c 4730 2008-12-01 18:38:28Z martin $
*/
#include "child_rekey.h"
@@ -49,11 +49,26 @@ struct private_child_rekey_t {
bool initiator;
/**
+ * Protocol of CHILD_SA to rekey
+ */
+ protocol_id_t protocol;
+
+ /**
+ * Inbound SPI of CHILD_SA to rekey
+ */
+ u_int32_t spi;
+
+ /**
* the CHILD_CREATE task which is reused to simplify rekeying
*/
child_create_t *child_create;
/**
+ * the CHILD_DELETE task to delete rekeyed CHILD_SA
+ */
+ child_delete_t *child_delete;
+
+ /**
* CHILD_SA which gets rekeyed
*/
child_sa_t *child_sa;
@@ -65,6 +80,25 @@ struct private_child_rekey_t {
};
/**
+ * Implementation of task_t.build for initiator, after rekeying
+ */
+static status_t build_i_delete(private_child_rekey_t *this, message_t *message)
+{
+ /* update exchange type to INFORMATIONAL for the delete */
+ message->set_exchange_type(message, INFORMATIONAL);
+
+ return this->child_delete->task.build(&this->child_delete->task, message);
+}
+
+/**
+ * Implementation of task_t.process for initiator, after rekeying
+ */
+static status_t process_i_delete(private_child_rekey_t *this, message_t *message)
+{
+ return this->child_delete->task.process(&this->child_delete->task, message);
+}
+
+/**
* find a child using the REKEY_SA notify
*/
static void find_child(private_child_rekey_t *this, message_t *message)
@@ -104,25 +138,33 @@ static void find_child(private_child_rekey_t *this, message_t *message)
* Implementation of task_t.build for initiator
*/
static status_t build_i(private_child_rekey_t *this, message_t *message)
-{
+{
notify_payload_t *notify;
- protocol_id_t protocol;
- u_int32_t spi, reqid;
+ u_int32_t reqid;
+ child_cfg_t *config;
+
+ this->child_sa = this->ike_sa->get_child_sa(this->ike_sa, this->protocol,
+ this->spi, TRUE);
+ if (!this->child_sa)
+ { /* CHILD_SA is gone, unable to rekey */
+ return SUCCESS;
+ }
+ config = this->child_sa->get_config(this->child_sa);
/* we just need the rekey notify ... */
- protocol = this->child_sa->get_protocol(this->child_sa);
- spi = this->child_sa->get_spi(this->child_sa, TRUE);
- notify = notify_payload_create_from_protocol_and_type(protocol, REKEY_SA);
- notify->set_spi(notify, spi);
+ notify = notify_payload_create_from_protocol_and_type(this->protocol,
+ REKEY_SA);
+ notify->set_spi(notify, this->spi);
message->add_payload(message, (payload_t*)notify);
-
+
/* ... our CHILD_CREATE task does the hard work for us. */
reqid = this->child_sa->get_reqid(this->child_sa);
+ this->child_create = child_create_create(this->ike_sa, config);
this->child_create->use_reqid(this->child_create, reqid);
this->child_create->task.build(&this->child_create->task, message);
this->child_sa->set_state(this->child_sa, CHILD_REKEYING);
-
+
return NEED_MORE;
}
@@ -133,7 +175,7 @@ static status_t process_r(private_child_rekey_t *this, message_t *message)
{
/* let the CHILD_CREATE task process the message */
this->child_create->task.process(&this->child_create->task, message);
-
+
find_child(this, message);
return NEED_MORE;
@@ -265,11 +307,13 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
spi = to_delete->get_spi(to_delete, TRUE);
protocol = to_delete->get_protocol(to_delete);
- if (this->ike_sa->delete_child_sa(this->ike_sa, protocol, spi) != SUCCESS)
- {
- return FAILED;
- }
- return SUCCESS;
+
+ /* rekeying done, delete the obsolete CHILD_SA using a subtask */
+ this->child_delete = child_delete_create(this->ike_sa, protocol, spi);
+ this->public.task.build = (status_t(*)(task_t*,message_t*))build_i_delete;
+ this->public.task.process = (status_t(*)(task_t*,message_t*))process_i_delete;
+
+ return NEED_MORE;
}
/**
@@ -319,9 +363,16 @@ static void collide(private_child_rekey_t *this, task_t *other)
*/
static void migrate(private_child_rekey_t *this, ike_sa_t *ike_sa)
{
- this->child_create->task.migrate(&this->child_create->task, ike_sa);
+ if (this->child_create)
+ {
+ this->child_create->task.migrate(&this->child_create->task, ike_sa);
+ }
+ if (this->child_delete)
+ {
+ this->child_delete->task.migrate(&this->child_delete->task, ike_sa);
+ }
DESTROY_IF(this->collision);
-
+
this->ike_sa = ike_sa;
this->collision = NULL;
}
@@ -331,7 +382,14 @@ static void migrate(private_child_rekey_t *this, ike_sa_t *ike_sa)
*/
static void destroy(private_child_rekey_t *this)
{
- this->child_create->task.destroy(&this->child_create->task);
+ if (this->child_create)
+ {
+ this->child_create->task.destroy(&this->child_create->task);
+ }
+ if (this->child_delete)
+ {
+ this->child_delete->task.destroy(&this->child_delete->task);
+ }
DESTROY_IF(this->collision);
free(this);
}
@@ -339,22 +397,21 @@ static void destroy(private_child_rekey_t *this)
/*
* Described in header.
*/
-child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, child_sa_t *child_sa)
+child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol,
+ u_int32_t spi)
{
- child_cfg_t *config;
private_child_rekey_t *this = malloc_thing(private_child_rekey_t);
-
+
this->public.collide = (void (*)(child_rekey_t*,task_t*))collide;
this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
this->public.task.destroy = (void(*)(task_t*))destroy;
- if (child_sa != NULL)
+ if (protocol != PROTO_NONE)
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
this->initiator = TRUE;
- config = child_sa->get_config(child_sa);
- this->child_create = child_create_create(ike_sa, config);
+ this->child_create = NULL;
}
else
{
@@ -365,8 +422,11 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, child_sa_t *child_sa)
}
this->ike_sa = ike_sa;
- this->child_sa = child_sa;
+ this->child_sa = NULL;
+ this->protocol = protocol;
+ this->spi = spi;
this->collision = NULL;
+ this->child_delete = NULL;
return &this->public;
}
diff --git a/src/charon/sa/tasks/child_rekey.h b/src/charon/sa/tasks/child_rekey.h
index b386ef3c6..37b61a9ef 100644
--- a/src/charon/sa/tasks/child_rekey.h
+++ b/src/charon/sa/tasks/child_rekey.h
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: child_rekey.h 3589 2008-03-13 14:14:44Z martin $
+ * $Id: child_rekey.h 4730 2008-12-01 18:38:28Z martin $
*/
/**
@@ -56,9 +56,11 @@ struct child_rekey_t {
* Create a new CHILD_REKEY task.
*
* @param ike_sa IKE_SA this task works for
- * @param child_sa child_sa to rekey, NULL if responder
+ * @param protocol protocol of CHILD_SA to rekey, PROTO_NONE as responder
+ * @param spi inbound SPI of CHILD_SA to rekey
* @return child_rekey task to handle by the task_manager
*/
-child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, child_sa_t *child_sa);
+child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol,
+ u_int32_t spi);
#endif /* CHILD_REKEY_H_ @} */
diff --git a/src/charon/sa/tasks/ike_auth.c b/src/charon/sa/tasks/ike_auth.c
index 5c3f33cbd..93b145755 100644
--- a/src/charon/sa/tasks/ike_auth.c
+++ b/src/charon/sa/tasks/ike_auth.c
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details
*
- * $Id: ike_auth.c 4463 2008-10-20 11:38:16Z martin $
+ * $Id: ike_auth.c 4858 2009-02-10 17:21:44Z martin $
*/
#include "ike_auth.h"
@@ -88,70 +88,6 @@ struct private_ike_auth_t {
};
/**
- * check uniqueness and delete duplicates
- */
-static bool check_uniqueness(private_ike_auth_t *this)
-{
- ike_sa_t *duplicate;
- unique_policy_t policy;
- status_t status = SUCCESS;
- peer_cfg_t *peer_cfg;
- bool cancel = FALSE;
-
- peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
- policy = peer_cfg->get_unique_policy(peer_cfg);
- if (policy == UNIQUE_NO)
- {
- return FALSE;
- }
- duplicate = charon->ike_sa_manager->checkout_duplicate(
- charon->ike_sa_manager, this->ike_sa);
- if (duplicate)
- {
- peer_cfg = duplicate->get_peer_cfg(duplicate);
- if (peer_cfg &&
- peer_cfg->equals(peer_cfg, this->ike_sa->get_peer_cfg(this->ike_sa)))
- {
- switch (duplicate->get_state(duplicate))
- {
- case IKE_ESTABLISHED:
- case IKE_REKEYING:
- switch (policy)
- {
- case UNIQUE_REPLACE:
- DBG1(DBG_IKE, "deleting duplicate IKE_SA due "
- "uniqueness policy");
- status = duplicate->delete(duplicate);
- break;
- case UNIQUE_KEEP:
- DBG1(DBG_IKE, "cancelling IKE_SA setup due "
- "uniqueness policy");
- cancel = TRUE;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
- if (status == DESTROY_ME)
- {
- charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
- duplicate);
- }
- else
- {
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, duplicate);
- }
- }
- /* set threads active IKE_SA after checkin */
- charon->bus->set_sa(charon->bus, this->ike_sa);
- return cancel;
-}
-
-/**
* get the authentication class of a config
*/
auth_class_t get_auth_class(peer_cfg_t *config)
@@ -400,6 +336,12 @@ static status_t build_auth_eap(private_ike_auth_t *this, message_t *message)
authenticator_t *auth;
auth_payload_t *auth_payload;
+ if (!this->initiator && !this->peer_authenticated)
+ {
+ message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
+ return FAILED;
+ }
+
auth = (authenticator_t*)this->eap_auth;
if (auth->build(auth, this->my_packet->get_data(this->my_packet),
this->other_nonce, &auth_payload) != SUCCESS)
@@ -681,8 +623,10 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
return FAILED;
}
- if (check_uniqueness(this))
+ if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
+ this->ike_sa))
{
+ DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy");
message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
return FAILED;
}
diff --git a/src/charon/sa/tasks/ike_config.c b/src/charon/sa/tasks/ike_config.c
index e89f381d3..b890e93ba 100644
--- a/src/charon/sa/tasks/ike_config.c
+++ b/src/charon/sa/tasks/ike_config.c
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: ike_config.c 4129 2008-07-01 06:36:52Z martin $
+ * $Id: ike_config.c 4867 2009-02-13 11:57:50Z andreas $
*/
#include "ike_config.h"
@@ -21,6 +21,9 @@
#include <daemon.h>
#include <encoding/payloads/cp_payload.h>
+#define DNS_SERVER_MAX 2
+#define NBNS_SERVER_MAX 2
+
typedef struct private_ike_config_t private_ike_config_t;
/**
@@ -52,6 +55,11 @@ struct private_ike_config_t {
* list of DNS servers
*/
linked_list_t *dns;
+
+ /**
+ * list of WINS servers
+ */
+ linked_list_t *nbns;
};
/**
@@ -121,7 +129,10 @@ static void build_payloads(private_ike_config_t *this, message_t *message,
else
{
host_t *ip;
- iterator_t *iterator = this->dns->create_iterator(this->dns, TRUE);
+ iterator_t *iterator;
+
+ /* Add internal DNS servers */
+ iterator = this->dns->create_iterator(this->dns, TRUE);
while (iterator->iterate(iterator, (void**)&ip))
{
ca = configuration_attribute_create();
@@ -138,6 +149,25 @@ static void build_payloads(private_ike_config_t *this, message_t *message,
cp->add_configuration_attribute(cp, ca);
}
iterator->destroy(iterator);
+
+ /* Add internal WINS servers */
+ iterator = this->nbns->create_iterator(this->nbns, TRUE);
+ while (iterator->iterate(iterator, (void**)&ip))
+ {
+ ca = configuration_attribute_create();
+ if (ip->get_family(ip) == AF_INET)
+ {
+ ca->set_type(ca, INTERNAL_IP4_NBNS);
+ }
+ else
+ {
+ ca->set_type(ca, INTERNAL_IP6_NBNS);
+ }
+ chunk = ip->get_address(ip);
+ ca->set_value(ca, chunk);
+ cp->add_configuration_attribute(cp, ca);
+ }
+ iterator->destroy(iterator);
}
message->add_payload(message, (payload_t*)cp);
}
@@ -201,7 +231,22 @@ static void process_attribute(private_ike_config_t *this,
}
case INTERNAL_IP4_NBNS:
case INTERNAL_IP6_NBNS:
- /* TODO */
+ {
+ addr = ca->get_value(ca);
+ if (addr.len == 0)
+ {
+ ip = host_create_any(family);
+ }
+ else
+ {
+ ip = host_create_from_chunk(family, addr, 0);
+ }
+ if (ip)
+ {
+ this->nbns->insert_last(this->nbns, ip);
+ }
+ break;
+ }
default:
DBG1(DBG_IKE, "ignoring %N config attribute",
configuration_attribute_type_names,
@@ -351,7 +396,7 @@ static status_t process_i(private_ike_config_t *this, message_t *message)
process_payloads(this, message);
if (this->virtual_ip == NULL)
- { /* force a configured virtual IP, even server didn't return one */
+ { /* force a configured virtual IP, even if server didn't return one */
config = this->ike_sa->get_peer_cfg(this->ike_sa);
this->virtual_ip = config->get_virtual_ip(config);
if (this->virtual_ip)
@@ -406,6 +451,7 @@ static void destroy(private_ike_config_t *this)
{
DESTROY_IF(this->virtual_ip);
this->dns->destroy_offset(this->dns, offsetof(host_t, destroy));
+ this->nbns->destroy_offset(this->nbns, offsetof(host_t, destroy));
free(this);
}
@@ -420,6 +466,12 @@ ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator)
this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
this->public.task.destroy = (void(*)(task_t*))destroy;
+ this->initiator = initiator;
+ this->ike_sa = ike_sa;
+ this->virtual_ip = NULL;
+ this->dns = linked_list_create();
+ this->nbns = linked_list_create();
+
if (initiator)
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
@@ -427,13 +479,49 @@ ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator)
}
else
{
+ int i;
+
+ /* assign DNS servers */
+ for (i = 1; i <= DNS_SERVER_MAX; i++)
+ {
+ char dns_key[16], *dns_str;
+
+ snprintf(dns_key, sizeof(dns_key), "charon.dns%d", i);
+ dns_str = lib->settings->get_str(lib->settings, dns_key, NULL);
+ if (dns_str)
+ {
+ host_t *dns = host_create_from_string(dns_str, 0);
+
+ if (dns)
+ {
+ DBG2(DBG_CFG, "assigning DNS server %H to peer", dns);
+ this->dns->insert_last(this->dns, dns);
+ }
+ }
+ }
+
+ /* assign WINS servers */
+ for (i = 1; i <= NBNS_SERVER_MAX; i++)
+ {
+ char nbns_key[16], *nbns_str;
+
+ snprintf(nbns_key, sizeof(nbns_key), "charon.nbns%d", i);
+ nbns_str = lib->settings->get_str(lib->settings, nbns_key, NULL);
+ if (nbns_str)
+ {
+ host_t *nbns = host_create_from_string(nbns_str, 0);
+
+ if (nbns)
+ {
+ DBG2(DBG_CFG, "assigning NBNS server %H to peer", nbns);
+ this->nbns->insert_last(this->nbns, nbns);
+ }
+ }
+ }
+
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 = initiator;
- this->ike_sa = ike_sa;
- this->virtual_ip = NULL;
- this->dns = linked_list_create();
-
+
return &this->public;
}
diff --git a/src/charon/sa/tasks/ike_init.c b/src/charon/sa/tasks/ike_init.c
index bd2cd39bb..139107480 100644
--- a/src/charon/sa/tasks/ike_init.c
+++ b/src/charon/sa/tasks/ike_init.c
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: ike_init.c 4531 2008-10-30 12:58:54Z martin $
+ * $Id: ike_init.c 4717 2008-11-28 09:51:44Z martin $
*/
#include "ike_init.h"
@@ -370,13 +370,46 @@ static status_t process_r(private_ike_init_t *this, message_t *message)
}
/**
- * Implementation of task_t.build for responder
+ * Derive the keymat for the IKE_SA
*/
-static status_t build_r(private_ike_init_t *this, message_t *message)
+static bool derive_keys(private_ike_init_t *this,
+ chunk_t nonce_i, chunk_t nonce_r)
{
- keymat_t *old_keymat = NULL;
+ keymat_t *old_keymat;
+ pseudo_random_function_t prf_alg = PRF_UNDEFINED;
+ chunk_t skd = chunk_empty;
ike_sa_id_t *id;
+ id = this->ike_sa->get_id(this->ike_sa);
+ if (this->old_sa)
+ {
+ /* rekeying: Include old SKd, use old PRF, apply SPI */
+ old_keymat = this->old_sa->get_keymat(this->old_sa);
+ prf_alg = old_keymat->get_skd(old_keymat, &skd);
+ if (this->initiator)
+ {
+ id->set_responder_spi(id, this->proposal->get_spi(this->proposal));
+ }
+ else
+ {
+ id->set_initiator_spi(id, this->proposal->get_spi(this->proposal));
+ }
+ }
+ if (!this->keymat->derive_ike_keys(this->keymat, this->proposal, this->dh,
+ nonce_i, nonce_r, id, prf_alg, skd))
+ {
+ return FALSE;
+ }
+ charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh,
+ nonce_i, nonce_r, this->old_sa);
+ return TRUE;
+}
+
+/**
+ * Implementation of task_t.build for responder
+ */
+static status_t build_r(private_ike_init_t *this, message_t *message)
+{
/* check if we have everything we need */
if (this->proposal == NULL ||
this->other_nonce.len == 0 || this->my_nonce.len == 0)
@@ -410,23 +443,12 @@ static status_t build_r(private_ike_init_t *this, message_t *message)
return FAILED;
}
- id = this->ike_sa->get_id(this->ike_sa);
- if (this->old_sa)
- { /* rekeying: Apply SPI, include keymat from old SA in key derivation */
- id->set_initiator_spi(id, this->proposal->get_spi(this->proposal));
- old_keymat = this->old_sa->get_keymat(this->old_sa);
- }
- if (!this->keymat->derive_ike_keys(this->keymat, this->proposal, this->dh,
- this->other_nonce, this->my_nonce, id, old_keymat))
+ if (!derive_keys(this, this->other_nonce, this->my_nonce))
{
DBG1(DBG_IKE, "key derivation failed");
message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
return FAILED;
}
-
- charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh,
- this->other_nonce, this->my_nonce, this->old_sa);
-
build_payloads(this, message);
return SUCCESS;
}
@@ -436,8 +458,6 @@ static status_t build_r(private_ike_init_t *this, message_t *message)
*/
static status_t process_i(private_ike_init_t *this, message_t *message)
{
- keymat_t *old_keymat = NULL;
- ike_sa_id_t *id;
iterator_t *iterator;
payload_t *payload;
@@ -521,22 +541,11 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
return FAILED;
}
- id = this->ike_sa->get_id(this->ike_sa);
- if (this->old_sa)
- { /* rekeying: Apply SPI, include keymat from old SA in key derivation */
- id->set_responder_spi(id, this->proposal->get_spi(this->proposal));
- old_keymat = this->old_sa->get_keymat(this->old_sa);
- }
- if (!this->keymat->derive_ike_keys(this->keymat, this->proposal, this->dh,
- this->my_nonce, this->other_nonce, id, old_keymat))
+ if (!derive_keys(this, this->my_nonce, this->other_nonce))
{
DBG1(DBG_IKE, "key derivation failed");
return FAILED;
}
-
- charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh,
- this->my_nonce, this->other_nonce, this->old_sa);
-
return SUCCESS;
}
diff --git a/src/charon/sa/tasks/ike_mobike.c b/src/charon/sa/tasks/ike_mobike.c
index a791d1892..b5e065081 100644
--- a/src/charon/sa/tasks/ike_mobike.c
+++ b/src/charon/sa/tasks/ike_mobike.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: ike_mobike.c 4618 2008-11-11 09:22:00Z tobias $
+ * $Id: ike_mobike.c 4816 2008-12-19 14:34:40Z martin $
*/
#include "ike_mobike.h"
@@ -24,6 +24,7 @@
#include <encoding/payloads/notify_payload.h>
#define COOKIE2_SIZE 16
+#define MAX_ADDITIONAL_ADDRS 8
typedef struct private_ike_mobike_t private_ike_mobike_t;
@@ -191,8 +192,8 @@ static void build_address_list(private_ike_mobike_t *this, message_t *message)
enumerator_t *enumerator;
host_t *host, *me;
notify_type_t type;
- bool additional = FALSE;
-
+ int added = 0;
+
me = this->ike_sa->get_my_host(this->ike_sa);
enumerator = charon->kernel_interface->create_address_enumerator(
charon->kernel_interface, FALSE, FALSE);
@@ -214,9 +215,13 @@ static void build_address_list(private_ike_mobike_t *this, message_t *message)
continue;
}
message->add_notify(message, FALSE, type, host->get_address(host));
- additional = TRUE;
+ if (++added >= MAX_ADDITIONAL_ADDRS)
+ { /* limit number of notifys, some implementations do not like too
+ * many of them (f.e. strongSwan ;-) */
+ break;
+ }
}
- if (!additional)
+ if (!added)
{
message->add_notify(message, FALSE, NO_ADDITIONAL_ADDRESSES, chunk_empty);
}
@@ -251,7 +256,7 @@ static void update_children(private_ike_mobike_t *this)
iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa);
while (iterator->iterate(iterator, (void**)&child_sa))
{
- if (child_sa->update_hosts(child_sa,
+ if (child_sa->update(child_sa,
this->ike_sa->get_my_host(this->ike_sa),
this->ike_sa->get_other_host(this->ike_sa),
this->ike_sa->get_virtual_ip(this->ike_sa, TRUE),
@@ -516,6 +521,10 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message)
/* start the update with the same task */
this->check = FALSE;
this->address = FALSE;
+ if (this->natd)
+ {
+ this->natd->task.destroy(&this->natd->task);
+ }
this->natd = ike_natd_create(this->ike_sa, this->initiator);
this->ike_sa->set_pending_updates(this->ike_sa, 1);
return NEED_MORE;
diff --git a/src/charon/sa/tasks/ike_rekey.c b/src/charon/sa/tasks/ike_rekey.c
index 28d63cca7..e61d161bc 100644
--- a/src/charon/sa/tasks/ike_rekey.c
+++ b/src/charon/sa/tasks/ike_rekey.c
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: ike_rekey.c 4659 2008-11-14 14:05:47Z martin $
+ * $Id: ike_rekey.c 4730 2008-12-01 18:38:28Z martin $
*/
#include "ike_rekey.h"
@@ -21,6 +21,7 @@
#include <daemon.h>
#include <encoding/payloads/notify_payload.h>
#include <sa/tasks/ike_init.h>
+#include <sa/tasks/ike_delete.h>
#include <processing/jobs/delete_ike_sa_job.h>
#include <processing/jobs/rekey_ike_sa_job.h>
@@ -58,12 +59,36 @@ struct private_ike_rekey_t {
ike_init_t *ike_init;
/**
+ * IKE_DELETE task to delete the old IKE_SA after rekeying was successful
+ */
+ ike_delete_t *ike_delete;
+
+ /**
* colliding task detected by the task manager
*/
task_t *collision;
};
/**
+ * Implementation of task_t.build for initiator, after rekeying
+ */
+static status_t build_i_delete(private_ike_rekey_t *this, message_t *message)
+{
+ /* update exchange type to INFORMATIONAL for the delete */
+ message->set_exchange_type(message, INFORMATIONAL);
+
+ return this->ike_delete->task.build(&this->ike_delete->task, message);
+}
+
+/**
+ * Implementation of task_t.process for initiator, after rekeying
+ */
+static status_t process_i_delete(private_ike_rekey_t *this, message_t *message)
+{
+ return this->ike_delete->task.process(&this->ike_delete->task, message);
+}
+
+/**
* Implementation of task_t.build for initiator
*/
static status_t build_i(private_ike_rekey_t *this, message_t *message)
@@ -168,7 +193,6 @@ static status_t build_r(private_ike_rekey_t *this, message_t *message)
*/
static status_t process_i(private_ike_rekey_t *this, message_t *message)
{
- job_t *job;
ike_sa_id_t *to_delete;
iterator_t *iterator;
payload_t *payload;
@@ -271,10 +295,12 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
charon->bus->set_sa(charon->bus, this->ike_sa);
}
- job = (job_t*)delete_ike_sa_job_create(to_delete, TRUE);
- charon->processor->queue_job(charon->processor, job);
+ /* rekeying successful, delete the IKE_SA using a subtask */
+ this->ike_delete = ike_delete_create(this->ike_sa, TRUE);
+ this->public.task.build = (status_t(*)(task_t*,message_t*))build_i_delete;
+ this->public.task.process = (status_t(*)(task_t*,message_t*))process_i_delete;
- return SUCCESS;
+ return NEED_MORE;
}
/**
@@ -300,6 +326,10 @@ static void migrate(private_ike_rekey_t *this, ike_sa_t *ike_sa)
{
this->ike_init->task.destroy(&this->ike_init->task);
}
+ if (this->ike_delete)
+ {
+ this->ike_delete->task.destroy(&this->ike_delete->task);
+ }
if (this->new_sa)
{
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
@@ -308,11 +338,12 @@ static void migrate(private_ike_rekey_t *this, ike_sa_t *ike_sa)
charon->bus->set_sa(charon->bus, this->ike_sa);
}
DESTROY_IF(this->collision);
-
+
this->collision = NULL;
this->ike_sa = ike_sa;
this->new_sa = NULL;
this->ike_init = NULL;
+ this->ike_delete = NULL;
}
/**
@@ -339,6 +370,10 @@ static void destroy(private_ike_rekey_t *this)
{
this->ike_init->task.destroy(&this->ike_init->task);
}
+ if (this->ike_delete)
+ {
+ this->ike_delete->task.destroy(&this->ike_delete->task);
+ }
DESTROY_IF(this->collision);
free(this);
}
@@ -368,6 +403,7 @@ ike_rekey_t *ike_rekey_create(ike_sa_t *ike_sa, bool initiator)
this->ike_sa = ike_sa;
this->new_sa = NULL;
this->ike_init = NULL;
+ this->ike_delete = NULL;
this->initiator = initiator;
this->collision = NULL;