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 */
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)
{
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");
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:
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");