]> git.saurik.com Git - apple/ipsec.git/blobdiff - ipsec-tools/racoon/proposal.c
ipsec-93.15.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / proposal.c
index a2f053a3b525ca9efbbdff515180c53025441436..7a299e00eea7b18dc11f4bc3eacab02cb1e4bbf8 100644 (file)
@@ -180,6 +180,50 @@ inssatrns(pr, new)
        return;
 }
 
+#ifdef ENABLE_NATT
+static void
+saprop_udp_encap (struct saproto *pr)
+{
+       switch (pr->encmode) {
+               case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
+               case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
+                       pr->encmode = IPSECDOI_ATTR_ENC_MODE_TUNNEL;
+                       pr->udp_encap = 1;
+                       break;
+               case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
+               case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
+                       pr->encmode = IPSECDOI_ATTR_ENC_MODE_TRNS;
+                       pr->udp_encap = 1;
+                       break;
+       }
+}
+
+static void
+saprop_adjust_encmode (struct saproto *pr2, struct saproto *pr1)
+{
+       int prev;
+
+       if (natt_udp_encap(pr2->encmode)) {
+               prev = pr2->encmode;
+               saprop_udp_encap(pr2);
+               plog(LLV_INFO, LOCATION, NULL, "Adjusting my encmode %s(%d)->%s(%d)\n",
+                        s_ipsecdoi_encmode(prev),
+                        prev,
+                        s_ipsecdoi_encmode(pr2->encmode),
+                        pr2->encmode);
+       }
+       if (natt_udp_encap(pr1->encmode)) {
+               prev = pr1->encmode;
+               saprop_udp_encap(pr1);
+               plog(LLV_INFO, LOCATION, NULL, "Adjusting peer's encmode %s(%d)->%s(%d)\n",
+                        s_ipsecdoi_encmode(prev),
+                        prev,
+                        s_ipsecdoi_encmode(pr1->encmode),
+                        pr1->encmode);
+       }       
+}
+#endif // ENABLE_NATT
+
 /*
  * take a single match between saprop.  allocate a new proposal and return it
  * for future use (like picking single proposal from a bundle).
@@ -388,27 +432,9 @@ cmpsaprop_alloc(ph1, pp1, pp2, side)
                        goto err;
                }
 
-#ifdef ENABLE_NATT
-               if ((ph1->natt_flags & NAT_DETECTED) && 
-                   natt_udp_encap (pr2->encmode))
-               {
-                       plog(LLV_INFO, LOCATION, NULL, "Adjusting my encmode %s->%s\n",
-                            s_ipsecdoi_encmode(pr2->encmode),
-                            s_ipsecdoi_encmode(pr2->encmode - ph1->natt_options->mode_udp_diff));
-                       pr2->encmode -= ph1->natt_options->mode_udp_diff;
-                       pr2->udp_encap = 1;
-               }
-
-               if ((ph1->natt_flags & NAT_DETECTED) &&
-                   natt_udp_encap (pr1->encmode))
-               {
-                       plog(LLV_INFO, LOCATION, NULL, "Adjusting peer's encmode %s(%d)->%s(%d)\n",
-                            s_ipsecdoi_encmode(pr1->encmode),
-                            pr1->encmode,
-                            s_ipsecdoi_encmode(pr1->encmode - ph1->natt_options->mode_udp_diff),
-                            pr1->encmode - ph1->natt_options->mode_udp_diff);
-                       pr1->encmode -= ph1->natt_options->mode_udp_diff;
-                       pr1->udp_encap = 1;
+#ifdef ENABLE_NATT             
+               if (ph1->natt_flags & NAT_DETECTED) {
+                       saprop_adjust_encmode(pr2, pr1);
                }
 #endif
 
@@ -452,6 +478,7 @@ cmpsaprop_alloc(ph1, pp1, pp2, side)
                if (newtr == NULL) {
                        plog(LLV_ERROR, LOCATION, NULL,
                                "failed to allocate satrns.\n");
+                       racoon_free(newpr);
                        goto err;
                }
                newtr->trns_no = tr1->trns_no;
@@ -706,6 +733,7 @@ aproppair2saprop(p0)
                if (sizeof(newpr->spi) < p->prop->spi_size) {
                        plog(LLV_ERROR, LOCATION, NULL,
                                "invalid spi size %d.\n", p->prop->spi_size);
+                       racoon_free(newpr);
                        goto err;
                }
 
@@ -740,11 +768,15 @@ aproppair2saprop(p0)
                        if (newtr == NULL) {
                                plog(LLV_ERROR, LOCATION, NULL,
                                        "failed to allocate satrns.\n");
+                               racoon_free(newpr);
                                goto err;
                        }
 
-                       if (ipsecdoi_t2satrns(t->trns, newpp, newpr, newtr) < 0) {
+                       if (ipsecdoi_t2satrns(t->trns, 
+                           newpp, newpr, newtr) < 0) {
                                flushsaprop(newpp);
+                               racoon_free(newtr);
+                               racoon_free(newpr);
                                return NULL;
                        }
 
@@ -1047,6 +1079,7 @@ set_proposal_from_policy(iph2, sp_main, sp_sub)
                if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) {
                        plog(LLV_ERROR, LOCATION, NULL,
                                "failed to get algorithms.\n");
+                       racoon_free(newpr);
                        goto err;
                }
 
@@ -1077,10 +1110,14 @@ set_proposal_from_policy(iph2, sp_main, sp_sub)
 
        iph2->proposal = newpp;
 
+    ike_session_update_mode(iph2);
+
        printsaprop0(LLV_DEBUG, newpp);
 
        return 0;
 err:
+       if (newpp)
+               flushsaprop(newpp);
        return -1;
 }
 
@@ -1111,6 +1148,10 @@ set_proposal_from_proposal(iph2)
         for (i = 0; i < MAXPROPPAIRLEN; i++) {
                 if (pair[i] == NULL)
                         continue;
+
+               if (pp_peer != NULL)
+                       flushsaprop(pp_peer);
+
                pp_peer = aproppair2saprop(pair[i]);
                if (pp_peer == NULL)
                        goto end;
@@ -1138,6 +1179,7 @@ set_proposal_from_proposal(iph2)
                        if (newpr == NULL) {
                                plog(LLV_ERROR, LOCATION, NULL,
                                    "failed to allocate saproto.\n");
+                               racoon_free(pp0);
                                goto end;
                        }
                        newpr->proto_id = pr->proto_id;
@@ -1147,15 +1189,17 @@ set_proposal_from_proposal(iph2)
                        newpr->spi_p = pr->spi; /* copy peer's SPI */
                        newpr->reqid_in = 0;
                        newpr->reqid_out = 0;
-               }
 
-               if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "failed to get algorithms.\n");
-                       goto end;
+                       if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) {
+                               plog(LLV_ERROR, LOCATION, NULL,
+                                       "failed to get algorithms.\n");
+                               racoon_free(newpr);
+                               racoon_free(pp0);
+                               goto end;
+                       }
+                       inssaproto(pp0, newpr);
                }
 
-               inssaproto(pp0, newpr);
                inssaprop(&newpp, pp0);
        }
 
@@ -1164,6 +1208,8 @@ set_proposal_from_proposal(iph2)
 
        iph2->proposal = newpp;
 
+       ike_session_update_mode(iph2);
+
        error = 0;
 
 end:
@@ -1172,7 +1218,8 @@ end:
 
        if (pp_peer)
                flushsaprop(pp_peer);
-       free_proppair(pair);
+       if (pair)
+               free_proppair(pair);
        return error;
 }
 
@@ -1187,3 +1234,84 @@ tunnel_mode_prop(p)
                        return 1;
        return 0;
 }
+
+void
+dupsatrns(newpr, head)
+       struct saproto *newpr;
+       struct satrns *head;
+{
+       struct satrns *p, *newtr;
+
+       for (p = head; p != NULL; p = p->next) {
+               newtr = newsatrns();
+               if (newtr) {
+                       newtr->trns_no = p->trns_no;
+                       newtr->trns_id = p->trns_id;
+                       newtr->encklen = p->encklen;
+                       newtr->authtype = p->authtype;
+                       inssatrns(newpr, newtr);
+               } else {
+                       break;
+               }
+
+       }
+
+       return;
+}
+       
+void
+dupsaproto(newpp, head, ignore_spis)
+       struct saprop  *newpp;
+       struct saproto *head;
+       int ignore_spis;
+{
+       struct saproto *p, *newpr;
+
+       for (p = head; p != NULL; p = p->next) {
+               newpr = newsaproto();
+               if (newpr) {
+                       newpr->proto_id = p->proto_id;
+                       newpr->spisize = p->spisize;
+                       newpr->encmode = p->encmode;
+                       newpr->udp_encap = p->udp_encap;
+                       if (!ignore_spis) {
+                               newpr->spi = p->spi;
+                               newpr->spi_p = p->spi_p;
+                               newpr->reqid_in = p->reqid_in;
+                               newpr->reqid_out = p->reqid_out;
+                       }
+                       dupsatrns(newpr, p->head);
+                       inssaproto(newpp, newpr);
+               } else {
+                       break;
+               }
+
+       }
+
+       return;
+}
+
+struct saprop *
+dupsaprop(head, ignore_spis)
+       struct saprop *head;
+       int ignore_spis;
+{
+       struct saprop *p, *newpp;
+
+       for (p = head, newpp = NULL; p != NULL; p = p->next) {
+               struct saprop *tmp = newsaprop();
+               if (tmp) {
+                       tmp->prop_no = p->prop_no;
+                       tmp->lifetime = p->lifetime;
+                       tmp->lifebyte = p->lifebyte;
+                       tmp->pfs_group = p->pfs_group;
+                       tmp->claim = p->claim;
+                       dupsaproto(tmp, p->head, ignore_spis);
+                       inssaprop(&newpp, tmp);
+               } else {
+                       break;
+               }
+       }
+
+       return newpp;
+}