Blame SOURCES/libreswan-3.15-cisco-delete.patch

738028
diff --git a/programs/pluto/ikev1_main.c b/programs/pluto/ikev1_main.c
738028
index de20a83..31d959b 100644
738028
--- a/programs/pluto/ikev1_main.c
738028
+++ b/programs/pluto/ikev1_main.c
738028
@@ -2983,13 +2983,12 @@ bool accept_delete(struct msg_digest *md,
738028
 			 * IPSEC (ESP/AH)
738028
 			 */
738028
 			ipsec_spi_t spi;	/* network order */
738028
-			bool bogus;
738028
-			struct state *dst;
738028
 
738028
 			if (!in_raw(&spi, sizeof(spi), &p->pbs, "SPI"))
738028
 				return self_delete;
738028
 
738028
-			dst = find_phase2_state_to_delete(st,
738028
+			bool bogus;
738028
+			struct state *dst = find_phase2_state_to_delete(st,
738028
 							d->isad_protoid,
738028
 							spi,
738028
 							&bogus);
738028
@@ -2997,14 +2996,19 @@ bool accept_delete(struct msg_digest *md,
738028
 			passert(dst != st);	/* st is an IKE SA */
738028
 			if (dst == NULL) {
738028
 				loglog(RC_LOG_SERIOUS,
738028
-					"ignoring Delete SA payload: %s SA(0x%08" PRIx32 ") not found (%s)",
738028
+					"ignoring Delete SA payload: %s SA(0x%08" PRIx32 ") not found (maybe expired)",
738028
 					enum_show(&protocol_names,
738028
 						d->isad_protoid),
738028
-					ntohl(spi),
738028
-					bogus ?
738028
-						"our SPI - bogus implementation" :
738028
-						"maybe expired");
738028
+					ntohl(spi));
738028
 			} else {
738028
+				if (bogus) {
738028
+					loglog(RC_LOG_SERIOUS,
738028
+						"warning: Delete SA payload: %s SA(0x%08" PRIx32 ") is our own SPI (bogus implementation) - deleting anyway",
738028
+						enum_show(&protocol_names,
738028
+							d->isad_protoid),
738028
+						ntohl(spi));
738028
+				}
738028
+
738028
 				struct connection *rc = dst->st_connection;
738028
 				struct connection *oldc = cur_connection;
738028
 
738028
diff --git a/programs/pluto/state.c b/programs/pluto/state.c
738028
index b2eac62..c5d4484 100644
738028
--- a/programs/pluto/state.c
738028
+++ b/programs/pluto/state.c
738028
@@ -1537,37 +1537,52 @@ struct state *find_likely_sender(size_t packet_len, u_char *packet)
738028
 	return NULL;
738028
 }
738028
 
738028
+/*
738028
+ * find_phase2_state_to_delete: find an AH or ESP SA to delete
738028
+ *
738028
+ * We are supposed to be given the other side's SPI.
738028
+ * Certain CISCO implementations send our side's SPI instead.
738028
+ * We'll accept this, but mark it as bogus.
738028
+ */
738028
 struct state *find_phase2_state_to_delete(const struct state *p1st,
738028
 					  u_int8_t protoid,
738028
 					  ipsec_spi_t spi,
738028
 					  bool *bogus)
738028
 {
738028
-	struct state *st;
738028
+	struct state  *bogusst = NULL;
738028
 	int i;
738028
 
738028
 	*bogus = FALSE;
738028
 	for (i = 0; i < STATE_TABLE_SIZE; i++) {
738028
+		struct state *st;
738028
+
738028
 		FOR_EACH_ENTRY(st, i, {
738028
 			if (IS_IPSEC_SA_ESTABLISHED(st->st_state) &&
738028
 				p1st->st_connection->host_pair ==
738028
 				st->st_connection->host_pair &&
738028
 				same_peer_ids(p1st->st_connection,
738028
-					st->st_connection, NULL)) {
738028
+					st->st_connection, NULL))
738028
+			{
738028
 				struct ipsec_proto_info *pr =
738028
 					protoid == PROTO_IPSEC_AH ?
738028
 					&st->st_ah : &st->st_esp;
738028
 
738028
 				if (pr->present) {
738028
-					if (pr->attrs.spi == spi)
738028
+					if (pr->attrs.spi == spi) {
738028
+						*bogus = FALSE;
738028
 						return st;
738028
+					}
738028
 
738028
-					if (pr->our_spi == spi)
738028
+					if (pr->our_spi == spi) {
738028
 						*bogus = TRUE;
738028
+						bogusst = st;
738028
+						/* don't return! */
738028
+					}
738028
 				}
738028
 			}
738028
 		});
738028
 	}
738028
-	return NULL;
738028
+	return bogusst;
738028
 }
738028
 
738028
 /*