summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/ikev2/tasks/child_create.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/sa/ikev2/tasks/child_create.c')
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_create.c50
1 files changed, 32 insertions, 18 deletions
diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c
index 6d9132a68..6bae960ad 100644
--- a/src/libcharon/sa/ikev2/tasks/child_create.c
+++ b/src/libcharon/sa/ikev2/tasks/child_create.c
@@ -65,6 +65,11 @@ struct private_child_create_t {
chunk_t other_nonce;
/**
+ * nonce generator
+ */
+ nonce_gen_t *nonceg;
+
+ /**
* config to create the CHILD_SA from
*/
child_cfg_t *config;
@@ -214,25 +219,21 @@ static status_t get_nonce(message_t *message, chunk_t *nonce)
/**
* generate a new nonce to include in a CREATE_CHILD_SA message
*/
-static status_t generate_nonce(private_child_create_t *this)
+static bool generate_nonce(private_child_create_t *this)
{
- nonce_gen_t *nonceg;
-
- nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
- if (!nonceg)
+ this->nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
+ if (!this->nonceg)
{
DBG1(DBG_IKE, "no nonce generator found to create nonce");
- return FAILED;
+ return FALSE;
}
- if (!nonceg->allocate_nonce(nonceg, NONCE_SIZE, &this->my_nonce))
+ if (!this->nonceg->allocate_nonce(this->nonceg, NONCE_SIZE,
+ &this->my_nonce))
{
DBG1(DBG_IKE, "nonce allocation failed");
- nonceg->destroy(nonceg);
- return FAILED;
+ return FALSE;
}
- nonceg->destroy(nonceg);
-
- return SUCCESS;
+ return TRUE;
}
/**
@@ -933,9 +934,10 @@ METHOD(task_t, build_i, status_t,
case IKE_SA_INIT:
return get_nonce(message, &this->my_nonce);
case CREATE_CHILD_SA:
- if (generate_nonce(this) != SUCCESS)
+ if (!generate_nonce(this))
{
- message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
+ message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
+ chunk_empty);
return SUCCESS;
}
if (!this->retry)
@@ -1092,7 +1094,10 @@ METHOD(task_t, process_r, status_t,
static void handle_child_sa_failure(private_child_create_t *this,
message_t *message)
{
- if (message->get_exchange_type(message) == IKE_AUTH &&
+ bool is_first;
+
+ is_first = message->get_exchange_type(message) == IKE_AUTH;
+ if (is_first &&
lib->settings->get_bool(lib->settings,
"%s.close_ike_on_child_failure", FALSE, lib->ns))
{
@@ -1106,7 +1111,8 @@ static void handle_child_sa_failure(private_child_create_t *this,
else
{
DBG1(DBG_IKE, "failed to establish CHILD_SA, keeping IKE_SA");
- charon->bus->alert(charon->bus, ALERT_KEEP_ON_CHILD_SA_FAILURE);
+ charon->bus->alert(charon->bus, ALERT_KEEP_ON_CHILD_SA_FAILURE,
+ is_first);
}
}
@@ -1190,7 +1196,7 @@ METHOD(task_t, build_r, status_t,
case IKE_SA_INIT:
return get_nonce(message, &this->my_nonce);
case CREATE_CHILD_SA:
- if (generate_nonce(this) != SUCCESS )
+ if (!generate_nonce(this))
{
message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
chunk_empty);
@@ -1203,6 +1209,13 @@ METHOD(task_t, build_r, status_t,
chunk_empty);
return SUCCESS;
}
+ if (this->dh_failed)
+ {
+ DBG1(DBG_IKE, "applying DH public value failed");
+ message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
+ chunk_empty);
+ return SUCCESS;
+ }
no_dh = FALSE;
break;
case IKE_AUTH:
@@ -1575,6 +1588,7 @@ METHOD(task_t, migrate, void,
}
DESTROY_IF(this->child_sa);
DESTROY_IF(this->proposal);
+ DESTROY_IF(this->nonceg);
DESTROY_IF(this->dh);
this->dh_failed = FALSE;
if (this->proposals)
@@ -1627,6 +1641,7 @@ METHOD(task_t, destroy, void,
}
DESTROY_IF(this->config);
+ DESTROY_IF(this->nonceg);
free(this);
}
@@ -1678,6 +1693,5 @@ child_create_t *child_create_create(ike_sa_t *ike_sa,
this->public.task.process = _process_r;
this->initiator = FALSE;
}
-
return &this->public;
}