]> git.saurik.com Git - apple/ipsec.git/commitdiff
ipsec-258.90.2.tar.gz os-x-1092 v258.90.2
authorApple <opensource@apple.com>
Tue, 11 Mar 2014 19:54:23 +0000 (19:54 +0000)
committerApple <opensource@apple.com>
Tue, 11 Mar 2014 19:54:23 +0000 (19:54 +0000)
ipsec-tools/racoon/ike_session.c
ipsec-tools/racoon/ike_session.h
ipsec-tools/racoon/isakmp.c
ipsec-tools/racoon/isakmp_inf.c
ipsec-tools/racoon/pfkey_racoon.c

index 76d520649bc201a47947c16a585031d3045a59ea..a71aff8b14f14897ef3b4b85e44a94715164d2b0 100644 (file)
@@ -192,7 +192,8 @@ ike_session_release_session (ike_session_t *session)
 ike_session_t *
 ike_session_get_session (struct sockaddr_storage *local,
                                                 struct sockaddr_storage *remote,
-                                                int              alloc_if_absent)
+                                                int              alloc_if_absent,
+                                                isakmp_index *optionalIndex)
 {
        ike_session_t    *p = NULL;
        ike_session_id_t  id;
@@ -265,6 +266,11 @@ ike_session_get_session (struct sockaddr_storage *local,
                                 p->ikev1_state.active_ph1cnt, p->ikev1_state.active_ph2cnt);
                        continue;
                }
+               
+               // Skip if the spi doesn't match
+               if (optionalIndex != NULL && ike_session_getph1byindex(p, optionalIndex) == NULL) {
+                       continue;
+               }
 
                if (memcmp(&p->session_id, &id, sizeof(id)) == 0) {
                        plog(ASL_LEVEL_DEBUG,
@@ -283,6 +289,9 @@ ike_session_get_session (struct sockaddr_storage *local,
                        return p;
                } else if (is_isakmp_remote_port && memcmp(&p->session_id, &id_wop, sizeof(id_wop)) == 0) {
                        best_match = p;
+               } else if (optionalIndex != NULL) {
+                       // If the SPI did match, this one counts as a best match
+                       best_match = p;
                }
        }
        if (best_match) {
@@ -1975,7 +1984,7 @@ ike_session_assert (struct sockaddr_storage *local,
                return -1;
        }
 
-       if ((sess = ike_session_get_session(local, remote, FALSE))) {
+       if ((sess = ike_session_get_session(local, remote, FALSE, NULL))) {
                return(ike_session_assert_session(sess));
        }
        return -1;
index 83a7fe6bd9a8038ce5e848112c7869beffc3c80f..4fa60798cf6b337fc1c751eeb179a8cfca992f06 100644 (file)
@@ -129,7 +129,7 @@ extern const char * ike_session_stopped_by_peer;
 extern void               ike_session_init (void);
 extern ike_session_t *    ike_session_create_session (ike_session_id_t *session_id);
 extern void               ike_session_release_session (ike_session_t *session);
-extern ike_session_t *   ike_session_get_session (struct sockaddr_storage *, struct sockaddr_storage *, int);
+extern ike_session_t *   ike_session_get_session (struct sockaddr_storage *, struct sockaddr_storage *, int, isakmp_index *);
 extern u_int              ike_session_get_rekey_lifetime (int, u_int);
 extern void               ike_session_update_mode (phase2_handle_t *iph2);
 extern int                ike_session_link_phase1 (ike_session_t *, phase1_handle_t *);
index 324b06491061273bb748e26d3a5caea95871163f..8133c954d8f13787d929b5578198e13c10418d78 100644 (file)
@@ -420,7 +420,10 @@ ikev1_received_packet(vchar_t *msg, struct sockaddr_storage *local, struct socka
     struct isakmp *isakmp = (struct isakmp *)msg->v;
     isakmp_index *index = (isakmp_index *)isakmp;
     
-    session = ike_session_get_session(local, remote, 1);
+    session = ike_session_get_session(local, remote, 0, index);
+    if (!session) {
+        session = ike_session_get_session(local, remote, 1, NULL);
+    }
     if (!session) {
         plog (ASL_LEVEL_INFO, "failed to allocate or find ike session.\n");
         fatal_error(-1);
@@ -723,7 +726,7 @@ ikev1_ph1begin_i(ike_session_t *session, struct remoteconf *rmconf, struct socka
 #endif
 
     if (session == NULL) {
-        session = ike_session_get_session(local, remote, 1);
+        session = ike_session_get_session(local, remote, 1, NULL);
         if (!session) {
             plog (ASL_LEVEL_INFO, "failed to allocate or find ike session.\n");
             fatal_error(-1);
index a58708735412e4831499e9d3513c717bd6d0f67b..487c5ba975e4034d6a7fb592c40ed2af12598f69 100644 (file)
@@ -698,6 +698,11 @@ isakmp_info_recv_d(phase1_handle_t *iph1, struct isakmp_pl_d *delete, u_int32_t
                                }
                        }
 #endif
+                       if (del_ph1->rmconf->natt_multiple_user &&
+                               del_ph1->parent_session->is_l2tpvpn_ipsec) {
+                               plog(ASL_LEVEL_DEBUG, "Ignoring IKE delete from peer for L2TP server\n");
+                               break;
+                       }
                        isakmp_ph1expire(del_ph1);
                }
                break;
@@ -711,6 +716,11 @@ isakmp_info_recv_d(phase1_handle_t *iph1, struct isakmp_pl_d *delete, u_int32_t
                                delete->spi_size, delete->proto_id);
                        return 0;
                }
+               if (iph1->rmconf->natt_multiple_user &&
+                       iph1->parent_session->is_l2tpvpn_ipsec) {
+                       plog(ASL_LEVEL_DEBUG, "Ignoring SA delete from peer for L2TP server\n");
+                       break;
+               }
                purge_ipsec_spi(iph1->remote, delete->proto_id,
                    ALIGNED_CAST(u_int32_t *)(delete + 1), num_spi, NULL, NULL);     // Wcast-align fix (void*) - delete payload is aligned
                break;
@@ -915,7 +925,7 @@ isakmp_info_send_nx(struct isakmp *isakmp, struct sockaddr_storage *remote, stru
        int error = -1;
        struct isakmp_pl_n *n;
        int spisiz = 0;         /* see below */
-    ike_session_t *sess = ike_session_get_session(local, remote, FALSE);
+    ike_session_t *sess = ike_session_get_session(local, remote, FALSE, NULL);
 
        /* search appropreate configuration */
        rmconf = getrmconf(remote);
index 1f20ca861ddd1160239e78a6fa654b3ae10f84ee..f977c029b251a73444a4dd2664a7999b47dd54d6 100644 (file)
@@ -1170,15 +1170,18 @@ pk_sendupdate(iph2)
                        memset (&natt, 0, sizeof (natt));
                        natt.sport = extract_port (iph2->ph1->remote);
                        flags |= SADB_X_EXT_NATT;
-                       if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
+                       if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
+                               mode == IPSEC_MODE_TRANSPORT &&
+                               src->ss_family == AF_INET) {
+                               flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
+                               if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
+                                       // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
+                                       flags |= SADB_X_EXT_NATT_DETECTED_PEER;
+                               }
+                       } else if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
                                if (iph2->ph1->rmconf->natt_keepalive == TRUE)
                                        flags |= SADB_X_EXT_NATT_KEEPALIVE;
                        } else {
-                               if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
-                                       mode == IPSEC_MODE_TRANSPORT &&
-                                       src->ss_family == AF_INET) {
-                                       flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
-                               }
                                if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
                                        // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
                                        flags |= SADB_X_EXT_NATT_DETECTED_PEER;
@@ -1481,15 +1484,18 @@ pk_sendadd(iph2)
                        memset (&natt, 0, sizeof (natt));
                        natt.dport = extract_port (iph2->ph1->remote);
                        flags |= SADB_X_EXT_NATT;
-                       if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
+                       if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
+                               mode == IPSEC_MODE_TRANSPORT &&
+                               src->ss_family == AF_INET) {
+                               flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
+                               if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
+                                       // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
+                                       flags |= SADB_X_EXT_NATT_DETECTED_PEER;
+                               }
+                       } else if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
                                if (iph2->ph1->rmconf->natt_keepalive == TRUE)
                                        flags |= SADB_X_EXT_NATT_KEEPALIVE;
                        } else {
-                               if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
-                                       mode == IPSEC_MODE_TRANSPORT &&
-                                       dst->ss_family == AF_INET) {
-                                       flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
-                               }
                                if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
                                        // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
                                        flags |= SADB_X_EXT_NATT_DETECTED_PEER;
@@ -1968,7 +1974,7 @@ pk_recvacquire(mhp)
        }
 
     if (session == NULL)
-        session = ike_session_get_session(iph2->src, iph2->dst, 1);    
+        session = ike_session_get_session(iph2->src, iph2->dst, 1, NULL);
     if (session == NULL)
         fatal_error(-1);