aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2013-09-04 17:12:23 +0200
committerMartin Willi <martin@revosec.ch>2013-09-13 13:56:43 +0200
commit96136a12298e0804e8bd5f5b2d2d68e508da9810 (patch)
treed872b7946604db44b7bf9994144cf72ad769c88a /src
parent791fde166998fa1f48c837576ec155e38bcdd1be (diff)
downloadstrongswan-96136a12298e0804e8bd5f5b2d2d68e508da9810.tar.bz2
strongswan-96136a12298e0804e8bd5f5b2d2d68e508da9810.tar.xz
libipsec: check for a policy with the reqid of the SA on decapsulation
To prevent a client from sending a packet with a source address of a different client, we require a policy bound via reqid to the decapsulating SA.
Diffstat (limited to 'src')
-rw-r--r--src/libipsec/ipsec_policy_mgr.c10
-rw-r--r--src/libipsec/ipsec_policy_mgr.h4
-rw-r--r--src/libipsec/ipsec_processor.c7
3 files changed, 14 insertions, 7 deletions
diff --git a/src/libipsec/ipsec_policy_mgr.c b/src/libipsec/ipsec_policy_mgr.c
index 72f94ec20..02dc59d65 100644
--- a/src/libipsec/ipsec_policy_mgr.c
+++ b/src/libipsec/ipsec_policy_mgr.c
@@ -230,7 +230,8 @@ METHOD(ipsec_policy_mgr_t, flush_policies, status_t,
}
METHOD(ipsec_policy_mgr_t, find_by_packet, ipsec_policy_t*,
- private_ipsec_policy_mgr_t *this, ip_packet_t *packet, bool inbound)
+ private_ipsec_policy_mgr_t *this, ip_packet_t *packet, bool inbound,
+ u_int32_t reqid)
{
enumerator_t *enumerator;
ipsec_policy_entry_t *current;
@@ -245,8 +246,11 @@ METHOD(ipsec_policy_mgr_t, find_by_packet, ipsec_policy_t*,
if ((inbound == (policy->get_direction(policy) == POLICY_IN)) &&
policy->match_packet(policy, packet))
{
- found = policy->get_ref(policy);
- break;
+ if (reqid == 0 || reqid == policy->get_reqid(policy))
+ {
+ found = policy->get_ref(policy);
+ break;
+ }
}
}
enumerator->destroy(enumerator);
diff --git a/src/libipsec/ipsec_policy_mgr.h b/src/libipsec/ipsec_policy_mgr.h
index dfa4b12c3..30406bdb7 100644
--- a/src/libipsec/ipsec_policy_mgr.h
+++ b/src/libipsec/ipsec_policy_mgr.h
@@ -97,10 +97,12 @@ struct ipsec_policy_mgr_t {
*
* @param packet IP packet to match
* @param inbound TRUE for an inbound packet
+ * @param reqid require a policy with a specific reqid, 0 for any
* @return reference to the policy, or NULL if none found
*/
ipsec_policy_t *(*find_by_packet)(ipsec_policy_mgr_t *this,
- ip_packet_t *packet, bool inbound);
+ ip_packet_t *packet, bool inbound,
+ u_int32_t reqid);
/**
* Destroy an ipsec_policy_mgr_t
diff --git a/src/libipsec/ipsec_processor.c b/src/libipsec/ipsec_processor.c
index e142157f8..eae2ed2f1 100644
--- a/src/libipsec/ipsec_processor.c
+++ b/src/libipsec/ipsec_processor.c
@@ -93,7 +93,7 @@ static job_requeue_t process_inbound(private_ipsec_processor_t *this)
esp_packet_t *packet;
ipsec_sa_t *sa;
u_int8_t next_header;
- u_int32_t spi;
+ u_int32_t spi, reqid;
packet = (esp_packet_t*)this->inbound_queue->dequeue(this->inbound_queue);
@@ -126,6 +126,7 @@ static job_requeue_t process_inbound(private_ipsec_processor_t *this)
packet->destroy(packet);
return JOB_REQUEUE_DIRECT;
}
+ reqid = sa->get_reqid(sa);
ipsec->sas->checkin(ipsec->sas, sa);
next_header = packet->get_next_header(packet);
@@ -139,7 +140,7 @@ static job_requeue_t process_inbound(private_ipsec_processor_t *this)
ip_packet = packet->get_payload(packet);
policy = ipsec->policies->find_by_packet(ipsec->policies,
- ip_packet, TRUE);
+ ip_packet, TRUE, reqid);
if (policy)
{ /* TODO-IPSEC: update policy/sa stats? */
deliver_inbound(this, packet);
@@ -193,7 +194,7 @@ static job_requeue_t process_outbound(private_ipsec_processor_t *this)
packet = (ip_packet_t*)this->outbound_queue->dequeue(this->outbound_queue);
- policy = ipsec->policies->find_by_packet(ipsec->policies, packet, FALSE);
+ policy = ipsec->policies->find_by_packet(ipsec->policies, packet, FALSE, 0);
if (!policy)
{
DBG2(DBG_ESP, "no matching outbound IPsec policy for %H == %H",