Add a responder narrow() hook to change TS in the kernel, but not on the wire

This commit is contained in:
Martin Willi
2012-09-11 16:14:39 +02:00
parent cf85ebbfec
commit f942588f95
3 changed files with 48 additions and 3 deletions
+2
View File
@@ -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 */
+20 -2
View File
@@ -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:
+26 -1
View File
@@ -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");