]> git.saurik.com Git - apple/ipsec.git/blobdiff - ipsec-tools/racoon/policy.c
ipsec-332.100.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / policy.c
index d553d267475e6198af33e772ba0a089e130f0ca2..5abafad7a0edeadda55364e7d4275de38d6bdaa2 100644 (file)
@@ -90,14 +90,66 @@ getsp(spidx)
  */
 #if 1
 struct secpolicy *
-getsp_r(spidx)
+getsp_r(spidx, iph2)
        struct policyindex *spidx;
+       phase2_handle_t *iph2;
 {
        struct secpolicy *p;
+       int mismatched_outer_addr = 0;
 
        for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) {
-               if (!cmpspidxwild(spidx, &p->spidx))
-                       return p;
+               if (!cmpspidxwild(spidx, &p->spidx)) {
+                       if (spidx->dir != IPSEC_DIR_ANY) {
+                               struct ipsecrequest *isr;
+                               for (isr = p->req; isr != NULL; isr = isr->next) {
+                                       if (isr->saidx.mode != IPSEC_MODE_TUNNEL) {
+                                               plog(ASL_LEVEL_DEBUG, "%s, skipping policy. dir %d, mode %d\n",
+                                                        __FUNCTION__, spidx->dir, isr->saidx.mode);
+                                               continue;
+                                       }
+
+                                       // for tunnel mode: verify the outer ip addresses match the phase2's addresses
+                                       if (spidx->dir == IPSEC_DIR_INBOUND) {
+                                               // TODO: look out for wildcards
+                                               if (!cmpsaddrwop(iph2->dst, &isr->saidx.src) &&
+                                                       !cmpsaddrwop(iph2->src, &isr->saidx.dst)) {
+                                                       plog(ASL_LEVEL_DEBUG, "%s, inbound policy outer addresses matched Phase 2 addresses\n",
+                                                                __FUNCTION__);
+                                                       return p;
+                                               } else {
+                                                       mismatched_outer_addr = 1;
+                                               }
+                                       } else if (spidx->dir == IPSEC_DIR_OUTBOUND) {
+                                               // TODO: look out for wildcards
+                                               if (!cmpsaddrwop(iph2->src, &isr->saidx.src) &&
+                                                       !cmpsaddrwop(iph2->dst, &isr->saidx.dst)) {
+                                                       plog(ASL_LEVEL_DEBUG, "%s, outbound policy outer addresses matched Phase 2 addresses\n",
+                                                                __FUNCTION__);
+                                                       return p;
+                                               } else {
+                                                       mismatched_outer_addr = 1;
+                                               }
+                                       } else {
+                                               mismatched_outer_addr = 1;
+                                       }
+                                       if (mismatched_outer_addr) {
+                                               plog(ASL_LEVEL_DEBUG, "%s, policy outer addresses matched Phase 2 addresses: dir %d\n",
+                                                        __FUNCTION__, spidx->dir);
+                                               plog(ASL_LEVEL_DEBUG, "src1: %s\n",
+                                                        saddr2str((struct sockaddr *)iph2->src));
+                                               plog(ASL_LEVEL_DEBUG, "src2: %s\n",
+                                                        saddr2str((struct sockaddr *)&isr->saidx.src));
+                                               plog(ASL_LEVEL_DEBUG, "dst1: %s\n",
+                                                        saddr2str((struct sockaddr *)iph2->dst));
+                                               plog(ASL_LEVEL_DEBUG, "dst2: %s\n",
+                                                        saddr2str((struct sockaddr *)&isr->saidx.dst));
+                                       }
+                               }
+                       }
+                       if (!mismatched_outer_addr) {
+                               return p;
+                       }
+               }
        }
 
        return NULL;
@@ -106,15 +158,15 @@ getsp_r(spidx)
 struct secpolicy *
 getsp_r(spidx, iph2)
        struct policyindex *spidx;
-       struct ph2handle *iph2;
+       phase2_handle_t *iph2;
 {
        struct secpolicy *p;
        u_int8_t prefixlen;
 
-       plog(LLV_DEBUG, LOCATION, NULL, "checking for transport mode\n");
+       plog(ASL_LEVEL_DEBUG, "checking for transport mode\n");
 
        if (spidx->src.ss_family != spidx->dst.ss_family) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "address family mismatch, src:%d dst:%d\n",
                                spidx->src.ss_family,
                                spidx->dst.ss_family);
@@ -130,29 +182,29 @@ getsp_r(spidx, iph2)
                break;
 #endif
        default:
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "invalid family: %d\n", spidx->src.ss_family);
                return NULL;
        }
 
        /* is it transport mode SA negotiation? */
-       plog(LLV_DEBUG, LOCATION, NULL, "src1: %s\n",
+       plog(ASL_LEVEL_DEBUG, "src1: %s\n",
                saddr2str(iph2->src));
-       plog(LLV_DEBUG, LOCATION, NULL, "src2: %s\n",
-               saddr2str((struct sockaddr *)&spidx->src));
-       if (cmpsaddrwop(iph2->src, (struct sockaddr *)&spidx->src)
+       plog(ASL_LEVEL_DEBUG, "src2: %s\n",
+               saddr2str(&spidx->src));
+       if (cmpsaddrwop(iph2->src, &spidx->src)
         || spidx->prefs != prefixlen)
                return NULL;
 
-       plog(LLV_DEBUG, LOCATION, NULL, "dst1: %s\n",
+       plog(ASL_LEVEL_DEBUG, "dst1: %s\n",
                saddr2str(iph2->dst));
-       plog(LLV_DEBUG, LOCATION, NULL, "dst2: %s\n",
-               saddr2str((struct sockaddr *)&spidx->dst));
-       if (cmpsaddrwop(iph2->dst, (struct sockaddr *)&spidx->dst)
+       plog(ASL_LEVEL_DEBUG, "dst2: %s\n",
+               saddr2str(&spidx->dst));
+       if (cmpsaddrwop(iph2->dst, &spidx->dst)
         || spidx->prefd != prefixlen)
                return NULL;
 
-       plog(LLV_DEBUG, LOCATION, NULL, "looks to be transport mode\n");
+       plog(ASL_LEVEL_DEBUG, "looks to be transport mode\n");
 
        for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) {
                if (!cmpspidx_wild(spidx, &p->spidx))
@@ -187,8 +239,6 @@ int
 cmpspidxstrict(a, b)
        struct policyindex *a, *b;
 {
-       plog(LLV_DEBUG, LOCATION, NULL, "sub:%p: %s\n", a, spidx2str(a));
-       plog(LLV_DEBUG, LOCATION, NULL, "db :%p: %s\n", b, spidx2str(b));
 
        /* XXX don't check direction now, but it's to be checked carefully. */
        if (a->dir != b->dir
@@ -197,11 +247,9 @@ cmpspidxstrict(a, b)
         || a->ul_proto != b->ul_proto)
                return 1;
 
-       if (cmpsaddrstrict((struct sockaddr *)&a->src,
-                          (struct sockaddr *)&b->src))
+       if (cmpsaddrstrict(&a->src, &b->src))
                return 1;
-       if (cmpsaddrstrict((struct sockaddr *)&a->dst,
-                          (struct sockaddr *)&b->dst))
+       if (cmpsaddrstrict(&a->dst, &b->dst))
                return 1;
 
        return 0;
@@ -219,9 +267,6 @@ cmpspidxwild(a, b)
 {
        struct sockaddr_storage sa1, sa2;
 
-       plog(LLV_DEBUG, LOCATION, NULL, "sub:%p: %s\n", a, spidx2str(a));
-       plog(LLV_DEBUG, LOCATION, NULL, "db: %p: %s\n", b, spidx2str(b));
-
        if (!(b->dir == IPSEC_DIR_ANY || a->dir == b->dir))
                return 1;
 
@@ -235,43 +280,35 @@ cmpspidxwild(a, b)
        if (a->dst.ss_family != b->dst.ss_family)
                return 1;
 
-#ifndef __linux__
        /* compare src address */
        if (sizeof(sa1) < a->src.ss_len || sizeof(sa2) < b->src.ss_len) {
-               plog(LLV_ERROR, LOCATION, NULL,
+               plog(ASL_LEVEL_ERR, 
                        "unexpected error: "
                        "src.ss_len:%d dst.ss_len:%d\n",
                        a->src.ss_len, b->src.ss_len);
                return 1;
        }
-#endif
-       mask_sockaddr((struct sockaddr *)&sa1, (struct sockaddr *)&a->src,
-               b->prefs);
-       mask_sockaddr((struct sockaddr *)&sa2, (struct sockaddr *)&b->src,
-               b->prefs);
-       plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n",
+       mask_sockaddr(&sa1, &a->src, b->prefs);
+       mask_sockaddr(&sa2, &b->src, b->prefs);
+       plog(ASL_LEVEL_DEBUG, "%p masked with /%d: %s\n",
                a, b->prefs, saddr2str((struct sockaddr *)&sa1));
-       plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n",
+       plog(ASL_LEVEL_DEBUG, "%p masked with /%d: %s\n",
                b, b->prefs, saddr2str((struct sockaddr *)&sa2));
-       if (cmpsaddrwild((struct sockaddr *)&sa1, (struct sockaddr *)&sa2))
+       if (cmpsaddrwild(&sa1, &sa2))
                return 1;
 
-#ifndef __linux__
        /* compare dst address */
        if (sizeof(sa1) < a->dst.ss_len || sizeof(sa2) < b->dst.ss_len) {
-               plog(LLV_ERROR, LOCATION, NULL, "unexpected error\n");
+               plog(ASL_LEVEL_ERR, "unexpected error\n");
                exit(1);
        }
-#endif
-       mask_sockaddr((struct sockaddr *)&sa1, (struct sockaddr *)&a->dst,
-               b->prefd);
-       mask_sockaddr((struct sockaddr *)&sa2, (struct sockaddr *)&b->dst,
-               b->prefd);
-       plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n",
+       mask_sockaddr(&sa1, &a->dst, b->prefd);
+       mask_sockaddr(&sa2, &b->dst, b->prefd);
+       plog(ASL_LEVEL_DEBUG, "%p masked with /%d: %s\n",
                a, b->prefd, saddr2str((struct sockaddr *)&sa1));
-       plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n",
+       plog(ASL_LEVEL_DEBUG, "%p masked with /%d: %s\n",
                b, b->prefd, saddr2str((struct sockaddr *)&sa2));
-       if (cmpsaddrwild((struct sockaddr *)&sa1, (struct sockaddr *)&sa2))
+       if (cmpsaddrwild(&sa1, &sa2))
                return 1;
 
        return 0;
@@ -383,7 +420,7 @@ inssp(new)
        }
        if (p == NULL)
 #endif
-               TAILQ_INSERT_TAIL(&sptree, new, chain);
+               TAILQ_INSERT_HEAD(&sptree, new, chain);
 
        check_auto_exit();
        return;