controller: Use separate callbacks to track termination and initiation of SAs
If a local authentication failure occurs in IKEv1 we delete the IKE_SA, which we don't want the controller to detect as success. Fixes #1449.
This commit is contained in:
@@ -271,6 +271,28 @@ METHOD(listener_t, ike_state_change, bool,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* ME */
|
#endif /* ME */
|
||||||
|
case IKE_DESTROYING:
|
||||||
|
return listener_done(this);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(listener_t, ike_state_change_terminate, bool,
|
||||||
|
interface_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
|
||||||
|
{
|
||||||
|
ike_sa_t *target;
|
||||||
|
|
||||||
|
this->lock->lock(this->lock);
|
||||||
|
target = this->ike_sa;
|
||||||
|
this->lock->unlock(this->lock);
|
||||||
|
|
||||||
|
if (target == ike_sa)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
case IKE_DESTROYING:
|
case IKE_DESTROYING:
|
||||||
if (ike_sa->get_state(ike_sa) == IKE_DELETING)
|
if (ike_sa->get_state(ike_sa) == IKE_DELETING)
|
||||||
{ /* proper termination */
|
{ /* proper termination */
|
||||||
@@ -304,10 +326,6 @@ METHOD(listener_t, child_state_change, bool,
|
|||||||
case CHILD_DESTROYING:
|
case CHILD_DESTROYING:
|
||||||
switch (child_sa->get_state(child_sa))
|
switch (child_sa->get_state(child_sa))
|
||||||
{
|
{
|
||||||
case CHILD_DELETING:
|
|
||||||
/* proper delete */
|
|
||||||
this->status = SUCCESS;
|
|
||||||
break;
|
|
||||||
case CHILD_RETRYING:
|
case CHILD_RETRYING:
|
||||||
/* retrying with a different DH group; survive another
|
/* retrying with a different DH group; survive another
|
||||||
* initiation round */
|
* initiation round */
|
||||||
@@ -331,6 +349,38 @@ METHOD(listener_t, child_state_change, bool,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(listener_t, child_state_change_terminate, bool,
|
||||||
|
interface_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
||||||
|
child_sa_state_t state)
|
||||||
|
{
|
||||||
|
ike_sa_t *target;
|
||||||
|
|
||||||
|
this->lock->lock(this->lock);
|
||||||
|
target = this->ike_sa;
|
||||||
|
this->lock->unlock(this->lock);
|
||||||
|
|
||||||
|
if (target == ike_sa)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case CHILD_DESTROYING:
|
||||||
|
switch (child_sa->get_state(child_sa))
|
||||||
|
{
|
||||||
|
case CHILD_DELETING:
|
||||||
|
/* proper delete */
|
||||||
|
this->status = SUCCESS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return listener_done(this);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(job_t, destroy_job, void,
|
METHOD(job_t, destroy_job, void,
|
||||||
interface_job_t *this)
|
interface_job_t *this)
|
||||||
{
|
{
|
||||||
@@ -537,8 +587,8 @@ METHOD(controller_t, terminate_ike, status_t,
|
|||||||
INIT(job,
|
INIT(job,
|
||||||
.listener = {
|
.listener = {
|
||||||
.public = {
|
.public = {
|
||||||
.ike_state_change = _ike_state_change,
|
.ike_state_change = _ike_state_change_terminate,
|
||||||
.child_state_change = _child_state_change,
|
.child_state_change = _child_state_change_terminate,
|
||||||
},
|
},
|
||||||
.logger = {
|
.logger = {
|
||||||
.public = {
|
.public = {
|
||||||
@@ -639,8 +689,8 @@ METHOD(controller_t, terminate_child, status_t,
|
|||||||
INIT(job,
|
INIT(job,
|
||||||
.listener = {
|
.listener = {
|
||||||
.public = {
|
.public = {
|
||||||
.ike_state_change = _ike_state_change,
|
.ike_state_change = _ike_state_change_terminate,
|
||||||
.child_state_change = _child_state_change,
|
.child_state_change = _child_state_change_terminate,
|
||||||
},
|
},
|
||||||
.logger = {
|
.logger = {
|
||||||
.public = {
|
.public = {
|
||||||
|
|||||||
Reference in New Issue
Block a user