Add a responder narrow() hook to change TS in the kernel, but not on the wire
This commit is contained in:
@@ -111,6 +111,8 @@ enum narrow_hook_t {
|
||||
NARROW_INITIATOR_PRE_AUTH,
|
||||
/** invoked as responder during exchange, peer is authenticated */
|
||||
NARROW_RESPONDER,
|
||||
/** invoked as responder after exchange, peer is authenticated */
|
||||
NARROW_RESPONDER_POST,
|
||||
/** invoked as initiator after exchange, follows a INITIATOR_PRE_NOAUTH */
|
||||
NARROW_INITIATOR_POST_NOAUTH,
|
||||
/** invoked as initiator after exchange, follows a INITIATOR_PRE_AUTH */
|
||||
|
||||
@@ -214,7 +214,7 @@ static bool install(private_quick_mode_t *this)
|
||||
else
|
||||
{
|
||||
charon->bus->narrow(charon->bus, this->child_sa,
|
||||
NARROW_RESPONDER, tsr, tsi);
|
||||
NARROW_RESPONDER_POST, tsr, tsi);
|
||||
}
|
||||
if (tsi->get_count(tsi) == 0 || tsr->get_count(tsr) == 0)
|
||||
{
|
||||
@@ -419,7 +419,7 @@ static traffic_selector_t* select_ts(private_quick_mode_t *this, bool local,
|
||||
supplied, host);
|
||||
if (list->get_first(list, (void**)&ts) == SUCCESS)
|
||||
{
|
||||
if (list->get_count(list) > 1)
|
||||
if (this->initiator && list->get_count(list) > 1)
|
||||
{
|
||||
DBG1(DBG_IKE, "configuration has more than one %s traffic selector,"
|
||||
" using first only", local ? "local" : "remote");
|
||||
@@ -974,6 +974,24 @@ METHOD(task_t, process_r, status_t,
|
||||
this->ike_sa->get_my_host(this->ike_sa),
|
||||
this->ike_sa->get_other_host(this->ike_sa),
|
||||
this->config, this->reqid, this->udp);
|
||||
|
||||
tsi = linked_list_create();
|
||||
tsr = linked_list_create();
|
||||
tsi->insert_last(tsi, this->tsi);
|
||||
tsr->insert_last(tsr, this->tsr);
|
||||
this->tsi = this->tsr = NULL;
|
||||
charon->bus->narrow(charon->bus, this->child_sa,
|
||||
NARROW_RESPONDER, tsr, tsi);
|
||||
if (tsi->remove_first(tsi, (void**)&this->tsi) != SUCCESS ||
|
||||
tsr->remove_first(tsr, (void**)&this->tsr) != SUCCESS)
|
||||
{
|
||||
tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
|
||||
tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
|
||||
return send_notify(this, INVALID_ID_INFORMATION);
|
||||
}
|
||||
tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy));
|
||||
tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy));
|
||||
|
||||
return NEED_MORE;
|
||||
}
|
||||
case QM_NEGOTIATED:
|
||||
|
||||
@@ -516,7 +516,32 @@ static status_t select_and_install(private_child_create_t *this,
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts);
|
||||
if (this->initiator)
|
||||
{
|
||||
status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use a copy of the traffic selectors, as the POST hook should not
|
||||
* change payloads */
|
||||
my_ts = this->tsr->clone_offset(this->tsr,
|
||||
offsetof(traffic_selector_t, clone));
|
||||
other_ts = this->tsi->clone_offset(this->tsi,
|
||||
offsetof(traffic_selector_t, clone));
|
||||
charon->bus->narrow(charon->bus, this->child_sa,
|
||||
NARROW_RESPONDER_POST, my_ts, other_ts);
|
||||
if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0)
|
||||
{
|
||||
status = FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = this->child_sa->add_policies(this->child_sa,
|
||||
my_ts, other_ts);
|
||||
}
|
||||
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
|
||||
other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
|
||||
}
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel");
|
||||
|
||||
Reference in New Issue
Block a user