Author: ae
Date: Mon Jul  6 12:40:31 2015
New Revision: 285204
URL: https://svnweb.freebsd.org/changeset/base/285204

Log:
  Fill the port and protocol information in the SADB_ACQUIRE message
  in case when security policy has it as required by RFC 2367.
  
  PR:           192774
  Differential Revision:        https://reviews.freebsd.org/D2972
  MFC after:    1 week

Modified:
  head/sys/netipsec/key.c

Modified: head/sys/netipsec/key.c
==============================================================================
--- head/sys/netipsec/key.c     Mon Jul  6 10:41:29 2015        (r285203)
+++ head/sys/netipsec/key.c     Mon Jul  6 12:40:31 2015        (r285204)
@@ -6088,16 +6088,21 @@ key_getprop(const struct secasindex *sai
 static int
 key_acquire(const struct secasindex *saidx, struct secpolicy *sp)
 {
-       struct mbuf *result = NULL, *m;
+       union sockaddr_union addr;
+       struct mbuf *result, *m;
        struct secacq *newacq;
-       u_int8_t satype;
-       int error = -1;
        u_int32_t seq;
+       int error;
+       u_int16_t ul_proto;
+       u_int8_t mask, satype;
 
        IPSEC_ASSERT(saidx != NULL, ("null saidx"));
        satype = key_proto2satype(saidx->proto);
        IPSEC_ASSERT(satype != 0, ("null satype, protocol %u", saidx->proto));
 
+       error = -1;
+       result = NULL;
+       ul_proto = IPSEC_ULPROTO_ANY;
        /*
         * We never do anything about acquirng SA.  There is anather
         * solution that kernel blocks to send SADB_ACQUIRE message until
@@ -6134,17 +6139,64 @@ key_acquire(const struct secasindex *sai
         * anything related to NAT-T at this time.
         */
 
-       /* set sadb_address for saidx's. */
-       m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
-           &saidx->src.sa, FULLMASK, IPSEC_ULPROTO_ANY);
+       /*
+        * set sadb_address for saidx's.
+        *
+        * Note that if sp is supplied, then we're being called from
+        * key_checkrequest and should supply port and protocol information.
+        */
+       if (sp != NULL && (sp->spidx.ul_proto == IPPROTO_TCP ||
+           sp->spidx.ul_proto == IPPROTO_UDP))
+               ul_proto = sp->spidx.ul_proto;
+
+       addr = saidx->src;
+       mask = FULLMASK;
+       if (ul_proto != IPSEC_ULPROTO_ANY) {
+               switch (sp->spidx.src.sa.sa_family) {
+               case AF_INET:
+                       if (sp->spidx.src.sin.sin_port != IPSEC_PORT_ANY) {
+                               addr.sin.sin_port = sp->spidx.src.sin.sin_port;
+                               mask = sp->spidx.prefs;
+                       }
+                       break;
+               case AF_INET6:
+                       if (sp->spidx.src.sin6.sin6_port != IPSEC_PORT_ANY) {
+                               addr.sin6.sin6_port = 
sp->spidx.src.sin6.sin6_port;
+                               mask = sp->spidx.prefs;
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+       m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC, &addr.sa, mask, ul_proto);
        if (!m) {
                error = ENOBUFS;
                goto fail;
        }
        m_cat(result, m);
 
-       m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
-           &saidx->dst.sa, FULLMASK, IPSEC_ULPROTO_ANY);
+       addr = saidx->dst;
+       mask = FULLMASK;
+       if (ul_proto != IPSEC_ULPROTO_ANY) {
+               switch (sp->spidx.dst.sa.sa_family) {
+               case AF_INET:
+                       if (sp->spidx.dst.sin.sin_port != IPSEC_PORT_ANY) {
+                               addr.sin.sin_port = sp->spidx.dst.sin.sin_port;
+                               mask = sp->spidx.prefd;
+                       }
+                       break;
+               case AF_INET6:
+                       if (sp->spidx.dst.sin6.sin6_port != IPSEC_PORT_ANY) {
+                               addr.sin6.sin6_port = 
sp->spidx.dst.sin6.sin6_port;
+                               mask = sp->spidx.prefd;
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+       m = key_setsadbaddr(SADB_EXT_ADDRESS_DST, &addr.sa, mask, ul_proto);
        if (!m) {
                error = ENOBUFS;
                goto fail;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to