diff options
author | Martin Willi <martin@revosec.ch> | 2013-09-04 17:12:23 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2013-09-13 13:56:43 +0200 |
commit | 96136a12298e0804e8bd5f5b2d2d68e508da9810 (patch) | |
tree | d872b7946604db44b7bf9994144cf72ad769c88a /src | |
parent | 791fde166998fa1f48c837576ec155e38bcdd1be (diff) | |
download | strongswan-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.c | 10 | ||||
-rw-r--r-- | src/libipsec/ipsec_policy_mgr.h | 4 | ||||
-rw-r--r-- | src/libipsec/ipsec_processor.c | 7 |
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", |