]> git.saurik.com Git - apple/ipsec.git/commitdiff
ipsec-93.15.tar.gz mac-os-x-1068 v93.15
authorApple <opensource@apple.com>
Fri, 24 Jun 2011 13:58:53 +0000 (13:58 +0000)
committerApple <opensource@apple.com>
Fri, 24 Jun 2011 13:58:53 +0000 (13:58 +0000)
ipsec-tools/racoon/ike_session.c
ipsec-tools/racoon/isakmp.c
ipsec-tools/racoon/isakmp_ident.c
ipsec-tools/racoon/isakmp_quick.c
ipsec-tools/racoon/isakmp_var.h
ipsec-tools/racoon/sainfo.c
ipsec-tools/racoon/sainfo.h

index 97e5be73f7c5e5cf1bc411f4ceba6aeab2ba3357..3d4608de021668db87356fb50e928296efc59f3d 100644 (file)
@@ -620,8 +620,9 @@ ike_session_has_other_negoing_ph2 (ike_session_t *session, struct ph2handle *iph
        }
        
        for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = LIST_NEXT(p, ph2ofsession_chain)) {
+               plog(LLV_DEBUG2, LOCATION, NULL, "%s: ph2 sub spid %d, db spid %d\n", __FUNCTION__, iph2->spid, p->spid);
                if (iph2 != p && !p->is_dying && iph2->spid == p->spid) {
-                       if (p->status >= PHASE2ST_START && p->status < PHASE2ST_ESTABLISHED) {
+                       if (p->status >= PHASE2ST_START && p->status <= PHASE2ST_ESTABLISHED) {
                                return 1;
                        }
                }
@@ -859,6 +860,7 @@ ike_session_ph2_established (struct ph2handle *iph2)
     iph2->parent_session->term_reason = NULL;
 
        ike_session_update_mode(iph2);
+       plog(LLV_DEBUG2, LOCATION, NULL, "%s phase2 established, spid %d.\n", __FUNCTION__, iph2->spid);
 }
 
 void
@@ -897,6 +899,13 @@ ike_session_cleanup_other_established_ph1s (ike_session_t    *session,
                return;
        }
 
+       /*
+        * if we are responder, then we should wait until the server sends a delete notification.
+        */
+       if (session->is_client && new_iph1->side == RESPONDER) {
+               return;
+       }
+
        for (p = LIST_FIRST(&session->ikev1_state.ph1tree); p; p = next) {
                // take next pointer now, since delete change the underlying ph1tree list
                next = LIST_NEXT(p, ph1ofsession_chain);
@@ -990,6 +999,13 @@ ike_session_cleanup_other_established_ph2s (ike_session_t    *session,
                return;
        }
 
+       /*
+        * if we are responder, then we should wait until the server sends a delete notification.
+        */
+       if (session->is_client && new_iph2->side == RESPONDER) {
+               return;
+       }
+
        for (p = LIST_FIRST(&session->ikev1_state.ph2tree); p; p = next) {
                // take next pointer now, since delete change the underlying ph2tree list
                next = LIST_NEXT(p, ph2ofsession_chain);
@@ -1592,8 +1608,13 @@ ike_session_get_sainfo_r (struct ph2handle *iph2)
                                plog(LLV_DEBUG2, LOCATION, NULL, "candidate ph2 found in %s.\n", __FUNCTION__);
                                if (ipany_ids ||
                                    ike_session_cmp_ph2_ids(iph2, p) == 0) {
-                                       plog(LLV_DEBUG2, LOCATION, NULL, "candidate ph2 matched in %s.\n", __FUNCTION__);
+                                       plog(LLV_DEBUG2, LOCATION, NULL, "candidate ph2 matched in %s, spid %d.\n", __FUNCTION__, p->spid);
                                        iph2->sainfo = p->sainfo;
+                                       if (!iph2->spid) {
+                                               iph2->spid = p->spid;
+                                       } else {
+                                               plog(LLV_DEBUG2, LOCATION, NULL, "%s: pre-assigned spid %d.\n", __FUNCTION__, iph2->spid);
+                                       }
                                        if (p->ext_nat_id) {
                                                if (iph2->ext_nat_id) {
                                                        vfree(iph2->ext_nat_id);
@@ -1632,6 +1653,11 @@ ike_session_get_proposal_r (struct ph2handle *iph2)
                                    ike_session_cmp_ph2_ids(iph2, p) == 0) {
                                        plog(LLV_DEBUG2, LOCATION, NULL, "candidate ph2 matched in %s.\n", __FUNCTION__);
                                        iph2->proposal = dupsaprop(p->approval, 1);
+                                       if (!iph2->spid) {
+                                               iph2->spid = p->spid;
+                                       } else {
+                                               plog(LLV_DEBUG2, LOCATION, NULL, "%s: pre-assigned spid %d.\n", __FUNCTION__, iph2->spid);
+                                       }
                                        return 0;
                                }
                        }
@@ -1690,6 +1716,7 @@ ike_session_ph2_retransmits (struct ph2handle *iph2)
                iph2->is_rekey &&
                iph2->ph1 &&
                iph2->ph1->sce_rekey && !iph2->ph1->sce_rekey->dead &&
+               iph2->side == INITIATOR &&
                iph2->parent_session &&
                !iph2->parent_session->is_cisco_ipsec && /* not for Cisco */
                iph2->parent_session->is_client) {
index 050ca4216a127b169a9e06491de39006802bae2b..0be52216a8a9b790f6f978386f7df29ff404f725 100644 (file)
@@ -4208,3 +4208,43 @@ setscopeid(sp_addr0, sa_addr0)
        return 0;
 }
 #endif
+
+vchar_t *
+isakmp_plist_append_initial_contact (iph1, plist)
+struct ph1handle *iph1;
+struct payload_list *plist;
+{
+       if (!iph1->is_rekey && iph1->rmconf->ini_contact && !getcontacted(iph1->remote)) {
+               vchar_t *notp_ini = NULL;
+               struct isakmp_pl_n np, *nptr;
+               char *cptr;
+               
+               np.doi = htonl(iph1->rmconf->doitype);
+               np.proto_id = IPSECDOI_PROTO_ISAKMP;
+               np.spi_size = sizeof(isakmp_index);
+               np.type = htons(ISAKMP_NTYPE_INITIAL_CONTACT);
+               if ((notp_ini = vmalloc(sizeof(struct isakmp_pl_n) - sizeof(struct isakmp_gen) 
+                                                               + sizeof(isakmp_index)))) {
+                       nptr = &np;
+                       memcpy(notp_ini->v, &nptr->doi, sizeof(struct isakmp_pl_n) - sizeof(struct isakmp_gen));
+                       cptr = notp_ini->v + sizeof(struct isakmp_pl_n) - sizeof(struct isakmp_gen);
+                       memcpy(cptr, &iph1->index, sizeof(isakmp_index));
+                       plist = isakmp_plist_append(plist, notp_ini, ISAKMP_NPTYPE_N);
+                       plog(LLV_DEBUG2, LOCATION, iph1->remote,
+                                "added initial-contact payload.\n");
+                       
+                       /* insert a node into contacted list. */
+                       if (inscontacted(iph1->remote) == -1) {
+                               plog(LLV_ERROR, LOCATION, iph1->remote,
+                                        "failed to add contacted list.\n");
+                               /* ignore */
+                       }
+                       return notp_ini;
+               } else {
+                       plog(LLV_ERROR, LOCATION, iph1->remote,
+                                "failed to allocate notification payload.\n");
+                       return NULL;
+               }
+       }
+       return NULL;
+}
index ff155e617e53b7415decc79cc6ffbaff6a234981..06f41d392820d01348dfef9f446c39b0d5020d16 100644 (file)
@@ -2225,6 +2225,7 @@ ident_ir3mx(iph1)
        vchar_t *gsstoken = NULL;
        vchar_t *gsshash = NULL;
 #endif
+       vchar_t *notp_ini = NULL;
 
        switch (AUTHMETHOD(iph1)) {
        case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
@@ -2337,6 +2338,10 @@ ident_ir3mx(iph1)
                goto end;
        }
 
+       if (iph1->side == INITIATOR) {
+               notp_ini = isakmp_plist_append_initial_contact(iph1, plist);
+       }
+       
        buf = isakmp_plist_set_all (&plist, iph1);
        
 #ifdef HAVE_PRINT_ISAKMP_C
@@ -2368,6 +2373,8 @@ end:
                vfree(buf);
                buf = NULL;
        }
+       if (notp_ini)
+               vfree(notp_ini);
 
        return buf;
 }
index 4c37b4defef68cffca2e074a7ee4ff8feb94b59f..871072ced8a2dbf5e1c11085aa1b5c6b15f5e3ce 100644 (file)
@@ -2331,6 +2331,18 @@ get_sainfo_r(iph2)
                                plog(LLV_DEBUG2, LOCATION, NULL,
                                         "get_sainfo_r case 2.\n");
                        }
+                       // still no sainfo (or anonymous): fallback to sainfo picked by dst id
+                       if ((iph2->sainfo == NULL || iph2->sainfo->idsrc == NULL) && iph2->id_p) {
+                               plog(LLV_DEBUG2, LOCATION, NULL,
+                                        "get_sainfo_r about to try dst id only.\n");
+                               iph2->sainfo = getsainfo_by_dst_id(iph2->id_p, iph2->ph1->id_p);
+                               if (iph2->sainfo) {
+                                       plog(LLV_DEBUG2, LOCATION, NULL,
+                                                "get_sainfo_r case 3.\n");
+                                       if (iph2->sainfo->idsrc == NULL)
+                                               anonymous = iph2->sainfo;
+                               }
+                       }
                }
        }
        if (iph2->sainfo == NULL) {
@@ -2400,9 +2412,9 @@ get_proposal_r(iph2)
  * NOTE: This function is only for responder.
  */
 static int
-get_proposal_r_remote(iph2, use_remote_addr)
+get_proposal_r_remote(iph2, ignore_id)
        struct ph2handle *iph2;
-       int use_remote_addr;
+       int ignore_id;
 {
        struct policyindex spidx;
        struct secpolicy *sp_in, *sp_out;
@@ -2418,13 +2430,16 @@ get_proposal_r_remote(iph2, use_remote_addr)
                return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
        }
 
-       /* make sure if id[src,dst] is null. */
-       if (iph2->src_id || iph2->dst_id) {
+       /* make sure if id[src,dst] is null (if use_remote_addr == 0). */
+       if (!ignore_id && (iph2->src_id || iph2->dst_id)) {
                plog(LLV_ERROR, LOCATION, NULL,
                        "Why do ID[src,dst] exist already.\n");
                return ISAKMP_INTERNAL_ERROR;
        }
 
+       plog(LLV_DEBUG, LOCATION, NULL,
+                "%s: ignore_id %x.\n", __FUNCTION__, ignore_id);
+
        memset(&spidx, 0, sizeof(spidx));
 
 #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
@@ -2440,7 +2455,7 @@ get_proposal_r_remote(iph2, use_remote_addr)
         * use the nat's address in the ID payload.
         */
        if (iph2->id != NULL
-        && use_remote_addr == 0
+        && ignore_id == 0
         && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
          || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR
          || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET
@@ -2506,7 +2521,7 @@ get_proposal_r_remote(iph2, use_remote_addr)
 
        /* make source address in spidx */
        if (iph2->id_p != NULL
-        && use_remote_addr == 0
+        && ignore_id == 0
         && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR
          || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR
          || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET
index a3edc8bd9f585568c3226d78a0ef45917db24462..26d5716cff051f22bc4fe92a152579cfe861087a 100644 (file)
@@ -121,6 +121,8 @@ extern struct payload_list *isakmp_plist_append __P((struct payload_list *plist,
        vchar_t *payload, int payload_type));
 extern vchar_t *isakmp_plist_set_all __P((struct payload_list **plist,
        struct ph1handle *iph1));
+extern vchar_t *isakmp_plist_append_initial_contact __P((struct ph1handle *,
+                                                                                                                struct payload_list *));
 
 #ifdef HAVE_PRINT_ISAKMP_C
 extern void isakmp_printpacket __P((vchar_t *, struct sockaddr *,
index 87093ab483669ea9da410f4a39d4bf556005feda..2c3619b17c53fd0ad22f34bf6053544665e4c607 100644 (file)
@@ -174,6 +174,61 @@ link_sainfo_to_ph2 (struct sainfo *new)
        return(0);
 }
 
+/*
+ * return matching entry.
+ * no matching entry found and if there is anonymous entry, return it.
+ * else return NULL.
+ * XXX by each data type, should be changed to compare the buffer.
+ */
+struct sainfo *
+getsainfo_by_dst_id(dst, peer)
+       const vchar_t *dst, *peer;
+{
+       struct sainfo *s = NULL;
+       struct sainfo *anonymous = NULL;
+
+       plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo_by_dst_id - dst id:\n");
+       if (dst != NULL)
+               plogdump(LLV_DEBUG2, dst->v, dst->l);
+       else
+               return NULL;
+
+       LIST_FOREACH(s, &sitree, chain) {
+               if (s->to_delete || s->to_remove) {
+                       continue;
+               }
+               if (s->idsrc != NULL) {
+                       plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo_by_dst_id - sainfo id - src & dst:\n");
+                       plogdump(LLV_DEBUG2, s->idsrc->v, s->idsrc->l);
+                       plogdump(LLV_DEBUG2, s->iddst->v, s->iddst->l);
+               } else {
+                       plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo_by_dst_id - sainfo id = anonymous\n");
+               }
+               if (s->id_i != NULL) {
+                       plog(LLV_DEBUG2, LOCATION, NULL, "getsainfo_by_dst_id - sainfo id_i:\n");
+                       plogdump(LLV_DEBUG2, s->id_i->v, s->id_i->l);
+                       if (peer == NULL)
+                               continue;
+                       if (memcmp(peer->v, s->id_i->v, s->id_i->l) != 0)
+                               continue;
+               }
+               if (s->idsrc == NULL) {
+                       anonymous = s;
+                       continue;
+               }
+
+               if (memcmp(dst->v, s->iddst->v, s->iddst->l) == 0)
+                       return s;
+       }
+
+       if (anonymous) {
+               plog(LLV_DEBUG, LOCATION, NULL,
+                        "anonymous sainfo selected.\n");
+       }
+       
+       return anonymous;
+}
+
 int
 unlink_sainfo_from_ph2 (struct sainfo *old)
 {
index c9bf7f07cc63714ca64a9f453e0e4f15f3a12e0a..ad18996ae2ee5a62bebdd113ed35e4705f0ae295 100644 (file)
@@ -74,6 +74,7 @@ struct sainfoalg {
 extern struct sainfo *getsainfo __P((const vchar_t *,
        const vchar_t *, const vchar_t *, int));
 #ifdef __APPLE__
+extern struct sainfo *getsainfo_by_dst_id __P((const vchar_t *, const vchar_t *));
 extern int            link_sainfo_to_ph2 __P((struct sainfo *));
 extern int            unlink_sainfo_from_ph2 __P((struct sainfo *));
 #endif