aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcharon/bus/bus.h2
-rw-r--r--src/libcharon/sa/ikev1/tasks/quick_mode.c22
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_create.c27
3 files changed, 48 insertions, 3 deletions
diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h
index 9f820e62f..aba8acdbd 100644
--- a/src/libcharon/bus/bus.h
+++ b/src/libcharon/bus/bus.h
@@ -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 */
diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c
index 73a23f4ea..8f2d192a0 100644
--- a/src/libcharon/sa/ikev1/tasks/quick_mode.c
+++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c
@@ -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:
diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c
index d7d912fdc..3520760b0 100644
--- a/src/libcharon/sa/ikev2/tasks/child_create.c
+++ b/src/libcharon/sa/ikev2/tasks/child_create.c
@@ -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");