From 1760d65d3810e9b26cfaf4b496ce62509ceb4086 Mon Sep 17 00:00:00 2001 From: Apple Date: Tue, 11 Mar 2014 19:54:23 +0000 Subject: [PATCH 1/1] ipsec-258.90.2.tar.gz --- ipsec-tools/racoon/ike_session.c | 13 +++++++++++-- ipsec-tools/racoon/ike_session.h | 2 +- ipsec-tools/racoon/isakmp.c | 7 +++++-- ipsec-tools/racoon/isakmp_inf.c | 12 +++++++++++- ipsec-tools/racoon/pfkey_racoon.c | 32 ++++++++++++++++++------------- 5 files changed, 47 insertions(+), 19 deletions(-) diff --git a/ipsec-tools/racoon/ike_session.c b/ipsec-tools/racoon/ike_session.c index 76d5206..a71aff8 100644 --- a/ipsec-tools/racoon/ike_session.c +++ b/ipsec-tools/racoon/ike_session.c @@ -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; diff --git a/ipsec-tools/racoon/ike_session.h b/ipsec-tools/racoon/ike_session.h index 83a7fe6..4fa6079 100644 --- a/ipsec-tools/racoon/ike_session.h +++ b/ipsec-tools/racoon/ike_session.h @@ -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 *); diff --git a/ipsec-tools/racoon/isakmp.c b/ipsec-tools/racoon/isakmp.c index 324b064..8133c95 100644 --- a/ipsec-tools/racoon/isakmp.c +++ b/ipsec-tools/racoon/isakmp.c @@ -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); diff --git a/ipsec-tools/racoon/isakmp_inf.c b/ipsec-tools/racoon/isakmp_inf.c index a587087..487c5ba 100644 --- a/ipsec-tools/racoon/isakmp_inf.c +++ b/ipsec-tools/racoon/isakmp_inf.c @@ -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); diff --git a/ipsec-tools/racoon/pfkey_racoon.c b/ipsec-tools/racoon/pfkey_racoon.c index 1f20ca8..f977c02 100644 --- a/ipsec-tools/racoon/pfkey_racoon.c +++ b/ipsec-tools/racoon/pfkey_racoon.c @@ -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); -- 2.45.2