task-manager-v2: Reject requests for incomplete IKE_SAs as initiator
Based on a patch by Thomas Egerer.
This commit is contained in:
@@ -1458,6 +1458,59 @@ static bool looks_like_mid_sync(private_task_manager_t *this, message_t *msg,
|
|||||||
return found && !other;
|
return found && !other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether we should reject the given request message
|
||||||
|
*/
|
||||||
|
static inline bool reject_request(private_task_manager_t *this,
|
||||||
|
message_t *msg)
|
||||||
|
{
|
||||||
|
ike_sa_state_t state;
|
||||||
|
exchange_type_t type;
|
||||||
|
ike_sa_id_t *ike_sa_id;
|
||||||
|
bool reject = FALSE;
|
||||||
|
|
||||||
|
state = this->ike_sa->get_state(this->ike_sa);
|
||||||
|
type = msg->get_exchange_type(msg);
|
||||||
|
|
||||||
|
/* reject initial messages if not received in specific states */
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case IKE_SA_INIT:
|
||||||
|
reject = state != IKE_CREATED;
|
||||||
|
break;
|
||||||
|
case IKE_AUTH:
|
||||||
|
reject = state != IKE_CONNECTING;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reject)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
/* after rekeying we only expect a DELETE in an INFORMATIONAL */
|
||||||
|
case IKE_REKEYED:
|
||||||
|
reject = type != INFORMATIONAL;
|
||||||
|
break;
|
||||||
|
/* also reject requests for half-open IKE_SAs as initiator */
|
||||||
|
case IKE_CREATED:
|
||||||
|
case IKE_CONNECTING:
|
||||||
|
ike_sa_id = this->ike_sa->get_id(this->ike_sa);
|
||||||
|
reject = ike_sa_id->is_initiator(ike_sa_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reject)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "ignoring %N in IKE_SA state %N", exchange_type_names,
|
||||||
|
type, ike_sa_state_names, state);
|
||||||
|
}
|
||||||
|
return reject;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Check if a message with message ID 0 looks like it is used to synchronize
|
* Check if a message with message ID 0 looks like it is used to synchronize
|
||||||
* the message IDs and we are prepared to process it.
|
* the message IDs and we are prepared to process it.
|
||||||
@@ -1483,8 +1536,6 @@ METHOD(task_manager_t, process_message, status_t,
|
|||||||
status_t status;
|
status_t status;
|
||||||
uint32_t mid;
|
uint32_t mid;
|
||||||
bool schedule_delete_job = FALSE;
|
bool schedule_delete_job = FALSE;
|
||||||
ike_sa_state_t state;
|
|
||||||
exchange_type_t type;
|
|
||||||
|
|
||||||
charon->bus->message(charon->bus, msg, TRUE, FALSE);
|
charon->bus->message(charon->bus, msg, TRUE, FALSE);
|
||||||
status = parse_message(this, msg);
|
status = parse_message(this, msg);
|
||||||
@@ -1525,16 +1576,8 @@ METHOD(task_manager_t, process_message, status_t,
|
|||||||
{
|
{
|
||||||
if (mid == this->responding.mid || (mid == 0 && is_mid_sync(this, msg)))
|
if (mid == this->responding.mid || (mid == 0 && is_mid_sync(this, msg)))
|
||||||
{
|
{
|
||||||
/* reject initial messages if not received in specific states,
|
if (reject_request(this, msg))
|
||||||
* after rekeying we only expect a DELETE in an INFORMATIONAL */
|
|
||||||
type = msg->get_exchange_type(msg);
|
|
||||||
state = this->ike_sa->get_state(this->ike_sa);
|
|
||||||
if ((type == IKE_SA_INIT && state != IKE_CREATED) ||
|
|
||||||
(type == IKE_AUTH && state != IKE_CONNECTING) ||
|
|
||||||
(state == IKE_REKEYED && type != INFORMATIONAL))
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "ignoring %N in IKE_SA state %N",
|
|
||||||
exchange_type_names, type, ike_sa_state_names, state);
|
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
|
if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
|
||||||
|
|||||||
Reference in New Issue
Block a user