child-create: Make sure the mode selected by the responder is acceptable
Previously, the initiator would install the SA in transport mode if the peer sent back the USE_TRANSPORT_MODE notify, even if that was not requested originally.
This commit is contained in:
@@ -489,6 +489,45 @@ static linked_list_t* narrow_ts(private_child_create_t *this, bool local,
|
||||
return ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if requested mode is acceptable
|
||||
*/
|
||||
static bool check_mode(private_child_create_t *this, host_t *i, host_t *r)
|
||||
{
|
||||
switch (this->mode)
|
||||
{
|
||||
case MODE_TRANSPORT:
|
||||
if (!this->config->has_option(this->config, OPT_PROXY_MODE) &&
|
||||
(!ts_list_is_host(this->tsi, i) ||
|
||||
!ts_list_is_host(this->tsr, r))
|
||||
)
|
||||
{
|
||||
DBG1(DBG_IKE, "not using transport mode, not host-to-host");
|
||||
return FALSE;
|
||||
}
|
||||
if (this->config->get_mode(this->config) != MODE_TRANSPORT)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case MODE_BEET:
|
||||
if (!ts_list_is_host(this->tsi, NULL) ||
|
||||
!ts_list_is_host(this->tsr, NULL))
|
||||
{
|
||||
DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
|
||||
return FALSE;
|
||||
}
|
||||
if (this->config->get_mode(this->config) != MODE_BEET)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a CHILD_SA for usage, return value:
|
||||
* - FAILED: no acceptable proposal
|
||||
@@ -616,47 +655,27 @@ static status_t select_and_install(private_child_create_t *this,
|
||||
{
|
||||
this->tsi = my_ts;
|
||||
this->tsr = other_ts;
|
||||
|
||||
if (!check_mode(this, me, other))
|
||||
{
|
||||
DBG1(DBG_IKE, "%N mode requested by responder is unacceptable",
|
||||
ipsec_mode_names, this->mode);
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->tsr = my_ts;
|
||||
this->tsi = other_ts;
|
||||
|
||||
if (!check_mode(this, other, me))
|
||||
{
|
||||
this->mode = MODE_TUNNEL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->initiator)
|
||||
{
|
||||
/* check if requested mode is acceptable, downgrade if required */
|
||||
switch (this->mode)
|
||||
{
|
||||
case MODE_TRANSPORT:
|
||||
if (!this->config->has_option(this->config, OPT_PROXY_MODE) &&
|
||||
(!ts_list_is_host(this->tsi, other) ||
|
||||
!ts_list_is_host(this->tsr, me))
|
||||
)
|
||||
{
|
||||
this->mode = MODE_TUNNEL;
|
||||
DBG1(DBG_IKE, "not using transport mode, not host-to-host");
|
||||
}
|
||||
if (this->config->get_mode(this->config) != MODE_TRANSPORT)
|
||||
{
|
||||
this->mode = MODE_TUNNEL;
|
||||
}
|
||||
break;
|
||||
case MODE_BEET:
|
||||
if (!ts_list_is_host(this->tsi, NULL) ||
|
||||
!ts_list_is_host(this->tsr, NULL))
|
||||
{
|
||||
this->mode = MODE_TUNNEL;
|
||||
DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
|
||||
}
|
||||
if (this->config->get_mode(this->config) != MODE_BEET)
|
||||
{
|
||||
this->mode = MODE_TUNNEL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* use a copy of the traffic selectors, as the POST hook should not
|
||||
* change payloads */
|
||||
my_ts = this->tsr->clone_offset(this->tsr,
|
||||
|
||||
Reference in New Issue
Block a user