]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
libipsec: check for a policy with the reqid of the SA on decapsulation
authorMartin Willi <martin@revosec.ch>
Wed, 4 Sep 2013 15:12:23 +0000 (17:12 +0200)
committerMartin Willi <martin@revosec.ch>
Fri, 13 Sep 2013 11:56:43 +0000 (13:56 +0200)
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.

src/libipsec/ipsec_policy_mgr.c
src/libipsec/ipsec_policy_mgr.h
src/libipsec/ipsec_processor.c

index 72f94ec201b137849b56c676a1ca4360c8f813da..02dc59d65b8cb491d61ad17b6b075e00ee393ebc 100644 (file)
@@ -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);
index dfa4b12c32cae80cf14f894b4cc153e627fc52a7..30406bdb7dcdbcb2e23194aa17c7ed60b78aa1f3 100644 (file)
@@ -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
index e142157f82ff7e11c63dccb70719c7d0afe48d8e..eae2ed2f159fa049a1b8238c4ad670dae7615e76 100644 (file)
@@ -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",