From b77cff959f66a1bd179ffc38ffa2971118d173be Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jun 04 2019 15:41:38 +0000 Subject: import libreswan-3.25-4.8.el7_6 --- diff --git a/SOURCES/libreswan-3.25-1673105-down-restart.patch b/SOURCES/libreswan-3.25-1673105-down-restart.patch new file mode 100644 index 0000000..1aa295b --- /dev/null +++ b/SOURCES/libreswan-3.25-1673105-down-restart.patch @@ -0,0 +1,455 @@ +diff -Naur libreswan-3.25-orig/include/pluto_constants.h libreswan-3.25/include/pluto_constants.h +--- libreswan-3.25-orig/include/pluto_constants.h 2019-05-02 10:54:07.265614654 -0400 ++++ libreswan-3.25/include/pluto_constants.h 2019-05-02 10:55:42.634626504 -0400 +@@ -152,6 +152,7 @@ + EVENT_SD_WATCHDOG, /* update systemd's watchdog interval */ + EVENT_PENDING_PHASE2, /* do not make pending phase2 wait forever */ + EVENT_CHECK_CRLS, /* check/update CRLS */ ++ EVENT_REVIVE_CONNS, + + /* events associated with states */ + +@@ -203,6 +204,9 @@ + #define EVENT_CRYPTO_TIMEOUT_DELAY RETRANSMIT_TIMEOUT_DEFAULT /* wait till the other side give up on us */ + #define EVENT_PAM_TIMEOUT_DELAY RETRANSMIT_TIMEOUT_DEFAULT /* wait until this side give up on PAM */ + ++#define REVIVE_CONN_DELAY 5 /* seconds */ ++#define REVIVE_CONN_DELAY_MAX 300 /* Do not delay more than 5 minutes per attempt */ ++ + /* + * operational importance of this cryptographic operation. + * this determines if the operation will be dropped (because the other +diff -Naur libreswan-3.25-orig/programs/pluto/connections.c libreswan-3.25/programs/pluto/connections.c +--- libreswan-3.25-orig/programs/pluto/connections.c 2019-05-02 10:54:07.265614654 -0400 ++++ libreswan-3.25/programs/pluto/connections.c 2019-05-02 10:55:42.635626515 -0400 +@@ -4629,3 +4629,28 @@ + c->name, prio)); + return prio; + } ++ ++/* ++ * If the connection contains a newer SA, return it. ++ */ ++so_serial_t get_newer_sa_from_connection(struct state *st) ++{ ++ struct connection *c = st->st_connection; ++ so_serial_t newest; ++ ++ if (IS_IKE_SA(st)) { ++ newest = c->newest_isakmp_sa; ++ DBG(DBG_CONTROL, DBG_log("picked newest_isakmp_sa #%lu for #%lu", ++ newest, st->st_serialno)); ++ } else { ++ newest = c->newest_ipsec_sa; ++ DBG(DBG_CONTROL, DBG_log("picked newest_ipsec_sa #%lu for #%lu", ++ newest, st->st_serialno)); ++ } ++ ++ if (newest != SOS_NOBODY && newest > st->st_serialno) { ++ return newest; ++ } else { ++ return SOS_NOBODY; ++ } ++} +diff -Naur libreswan-3.25-orig/programs/pluto/connections.h libreswan-3.25/programs/pluto/connections.h +--- libreswan-3.25-orig/programs/pluto/connections.h 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/connections.h 2019-05-02 10:57:22.626689082 -0400 +@@ -343,6 +343,7 @@ + u_int32_t statsval; /* track what we have told statsd */ + u_int16_t nflog_group; /* NFLOG group - 0 means disabled */ + msgid_t ike_window; /* IKE v2 window size 7296#section-2.3 */ ++ int revive_delay; + }; + + extern void parse_mark_mask(const struct connection* c,int * mark, int * mask); +@@ -385,7 +386,7 @@ + struct xfrm_user_sec_ctx_ike *uctx, + #endif + err_t why); +-extern void terminate_connection(const char *name); ++extern void terminate_connection(const char *name, bool quiet); + extern void release_connection(struct connection *c, bool relations); + extern void delete_connection(struct connection *c, bool relations); + extern void suppress_delete(struct connection *c); +@@ -539,3 +540,8 @@ + extern bool idr_wildmatch(const struct connection *c, const struct id *b); + + extern uint32_t calculate_sa_prio(const struct connection *c); ++ ++so_serial_t get_newer_sa_from_connection(struct state *st); ++ ++extern void flush_revival(const struct connection *c); ++ +diff -Naur libreswan-3.25-orig/programs/pluto/hostpair.c libreswan-3.25/programs/pluto/hostpair.c +--- libreswan-3.25-orig/programs/pluto/hostpair.c 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/hostpair.c 2019-05-02 10:55:42.635626515 -0400 +@@ -274,7 +274,7 @@ + */ + passert(p == *pp); + +- terminate_connection(p->name); ++ terminate_connection(p->name, FALSE); + p->interface = NULL; /* withdraw orientation */ + + *pp = p->hp_next; /* advance *pp */ +diff -Naur libreswan-3.25-orig/programs/pluto/initiate.c libreswan-3.25/programs/pluto/initiate.c +--- libreswan-3.25-orig/programs/pluto/initiate.c 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/initiate.c 2019-05-02 10:55:42.640626568 -0400 +@@ -148,7 +148,7 @@ + c->interface->ip_dev->id_rname, + p->ip_dev->id_rname); + } +- terminate_connection(c->name); ++ terminate_connection(c->name, FALSE); + c->interface = NULL; /* withdraw orientation */ + return FALSE; + } +@@ -401,7 +401,7 @@ + { + /* This might delete c if CK_INSTANCE */ + /* ??? is there a chance hp becomes dangling? */ +- terminate_connection(d->name); ++ terminate_connection(d->name, FALSE); + } + d = next; + } +@@ -750,6 +750,12 @@ + fmt_conn_instance(c, cib)); + }); + ++ if (sr->routing == RT_ROUTED_PROSPECTIVE && eclipsable(sr)) { ++ DBG(DBG_CONTROL, DBG_log("route is eclipsed")); ++ sr->routing = RT_ROUTED_ECLIPSED; ++ eclipse_count++; ++ } ++ + idtoa(&sr->this.id, mycredentialstr, sizeof(mycredentialstr)); + + passert(c->policy & POLICY_OPPORTUNISTIC); /* can't initiate Road Warrior connections */ +diff -Naur libreswan-3.25-orig/programs/pluto/kernel.c libreswan-3.25/programs/pluto/kernel.c +--- libreswan-3.25-orig/programs/pluto/kernel.c 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/kernel.c 2019-05-02 10:55:42.640626568 -0400 +@@ -982,22 +982,11 @@ + if (ro != NULL && !routes_agree(ro, c)) { + char cib[CONN_INST_BUF]; + loglog(RC_LOG_SERIOUS, +- "cannot route -- route already in use for \"%s\"%s", ++ "cannot route -- route already in use for \"%s\"%s - but allowing anyway", + ro->name, fmt_conn_instance(ro, cib)); +- /* +- * We ignore this if the stack supports overlapping, and this +- * connection was marked that overlapping is OK. Below we will +- * check the other eroute, ero. +- */ +- if (!compatible_overlapping_connections(c, ero)) { +- /* +- * Another connection is already using the eroute. +- * TODO: NETKEY can do this? +- */ +- return route_impossible; +- } + } + ++ + /* if there is an eroute for another connection, there is a problem */ + if (ero != NULL && ero != c) { + /* +@@ -3080,7 +3069,8 @@ + /* record unrouting */ + if (route_installed) { + do { +- passert(!erouted(rosr->routing)); ++ DBG(DBG_CONTROL, ++ DBG_log("ro name=%s, rosr->routing=%d", ro->name, rosr->routing)); + rosr->routing = RT_UNROUTED; + + /* no need to keep old value */ +@@ -3292,6 +3282,14 @@ + DBG(DBG_KERNEL, + DBG_log("set up incoming SA, ref=%u/%u", st->st_ref, + st->st_refhim)); ++ ++ /* ++ * We successfully installed an IPsec SA, meaning it is safe ++ * to clear our revival back-off delay. This is based on the ++ * assumption that an unwilling partner might complete an IKE ++ * SA to us, but won't complete an IPsec SA to us. ++ */ ++ st->st_connection->revive_delay = 0; + } + + if (rb == route_unnecessary) +diff -Naur libreswan-3.25-orig/programs/pluto/kernel.h libreswan-3.25/programs/pluto/kernel.h +--- libreswan-3.25-orig/programs/pluto/kernel.h 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/kernel.h 2019-05-02 10:55:42.640626568 -0400 +@@ -421,14 +421,6 @@ + #endif + ); + +-static inline bool compatible_overlapping_connections(const struct connection *a, +- const struct connection *b) +-{ +- return kernel_ops->overlap_supported && +- a != NULL && b != NULL && +- a != b && +- LIN(POLICY_OVERLAPIP, a->policy & b->policy); +-} + + #ifdef KLIPS + extern const struct kernel_ops klips_kernel_ops; +diff -Naur libreswan-3.25-orig/programs/pluto/pluto_constants.c libreswan-3.25/programs/pluto/pluto_constants.c +--- libreswan-3.25-orig/programs/pluto/pluto_constants.c 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/pluto_constants.c 2019-05-02 10:55:42.636626526 -0400 +@@ -121,6 +121,7 @@ + "EVENT_SD_WATCHDOG", + "EVENT_PENDING_PHASE2", + "EVENT_CHECK_CRLS", ++ "EVENT_REVIVE_CONNS", + + "EVENT_SO_DISCARD", + "EVENT_v1_RETRANSMIT", +diff -Naur libreswan-3.25-orig/programs/pluto/rcv_whack.c libreswan-3.25/programs/pluto/rcv_whack.c +--- libreswan-3.25-orig/programs/pluto/rcv_whack.c 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/rcv_whack.c 2019-05-02 10:55:42.636626526 -0400 +@@ -380,8 +380,14 @@ + * To make this more useful, in only this combination, + * delete will silently ignore the lack of the connection. + */ +- if (m->whack_delete) +- delete_connections_by_name(m->name, !m->whack_connection); ++ if (m->whack_delete) { ++ if (m->name == NULL) { ++ whack_log(RC_FATAL, "received whack command to delete a connection, but did not receive the connection name - ignored"); ++ } else { ++ terminate_connection(m->name, TRUE); ++ delete_connections_by_name(m->name, !m->whack_connection); ++ } ++ } + + if (m->whack_deleteuser) { + DBG_log("received whack to delete connection by user %s", +@@ -573,7 +579,7 @@ + } + + if (m->whack_terminate) +- terminate_connection(m->name); ++ terminate_connection(m->name, TRUE); + + if (m->whack_status) + show_status(); +diff -Naur libreswan-3.25-orig/programs/pluto/state.c libreswan-3.25/programs/pluto/state.c +--- libreswan-3.25-orig/programs/pluto/state.c 2019-05-02 10:54:07.252614517 -0400 ++++ libreswan-3.25/programs/pluto/state.c 2019-05-02 10:56:28.447113336 -0400 +@@ -77,6 +77,8 @@ + #include "crypt_dh.h" + #include "hostpair.h" + ++#include "kernel.h" ++ + #include + #include + #include +@@ -128,6 +130,115 @@ + [STATE_UNDEFINED] = &state_undefined, + }; + ++/* ++ * Revival mechanism: keep track of connections ++ * that should be kept up, even though all their ++ * states have been deleted. ++ * ++ * We record the connection names. ++ * Each name is recorded only once. ++ * ++ * XXX: This functionality totally overlaps both "initiate" and ++ * "pending" and should be merged (howerver, this simple code might ++ * prove to be a better starting point). ++ */ ++ ++struct revival { ++ char *name; ++ struct revival *next; ++}; ++ ++static struct revival *revivals = NULL; ++ ++/* ++ * XXX: Return connection C's revival object's link, if found. If the ++ * connection C can't be found, then the address of the revival list's ++ * tail is returned. Perhaps, exiting the loop and returning NULL ++ * would be more obvious. ++ */ ++static struct revival **find_revival(const struct connection *c) ++{ ++ for (struct revival **rp = &revivals; ; rp = &(*rp)->next) { ++ if (*rp == NULL || streq((*rp)->name, c->name)) { ++ return rp; ++ } ++ } ++} ++ ++/* ++ * XXX: In addition to freeing RP (and killing the pointer), this ++ * "free" function has the side effect of unlinks RP from the revival ++ * list. Perhaps free*() isn't the best name. ++ */ ++static void free_revival(struct revival **rp) ++{ ++ struct revival *r = *rp; ++ *rp = r->next; ++ pfree(r->name); ++ pfree(r); ++} ++ ++void flush_revival(const struct connection *c) ++{ ++ struct revival **rp = find_revival(c); ++ ++ if (*rp == NULL) { ++ DBG(DBG_CONTROL, DBG_log("flush revival: connection '%s' wasn't on the list", ++ c->name)); ++ } else { ++ DBG(DBG_CONTROL, DBG_log("flush revival: connection '%s' revival flushed", ++ c->name)); ++ free_revival(rp); ++ } ++} ++ ++static void add_revival(struct connection *c) ++{ ++ if (*find_revival(c) == NULL) { ++ struct revival *r = alloc_thing(struct revival, ++ "revival struct"); ++ ++ r->name = clone_str(c->name, "revival conn name"); ++ r->next = revivals; ++ revivals = r; ++ int delay = c->revive_delay; ++ DBG(DBG_CONTROL, DBG_log("add revival: connection '%s' added to the list and scheduled for %d seconds", ++ c->name, delay)); ++ c->revive_delay = min(delay + REVIVE_CONN_DELAY, ++ REVIVE_CONN_DELAY_MAX); ++ /* ++ * XXX: Schedule the next revival using this ++ * connection's revival delay and not the most urgent ++ * connection's revival delay. Trying to fix this ++ * here just is annoying and probably of marginal ++ * benefit: it is something better handled with a ++ * proper connection event so that the event loop deal ++ * with all the math (this code would then be ++ * deleted); and would encroach even further on ++ * "initiate" and "pending" functionality. ++ */ ++ event_schedule(EVENT_REVIVE_CONNS, deltatime(delay), NULL); ++ } ++} ++ ++void revive_conns(void) ++{ ++ /* ++ * XXX: Revive all listed connections regardless of their ++ * DELAY. See note above in add_revival(). ++ */ ++ while (revivals != NULL) { ++ libreswan_log("Initiating connection %s which received a Delete/Notify but must remain up per local policy", ++ revivals->name); ++ initiate_connection(revivals->name, NULL_FD, empty_lmod, empty_lmod, pcim_demand_crypto, NULL); ++ free_revival(&revivals); ++ } ++} ++ ++/* end of revival mechanism */ ++ ++ ++ + void lswlog_finite_state(struct lswlog *buf, const struct finite_state *fs) + { + if (fs == NULL) { +@@ -1156,6 +1267,23 @@ + if (c->newest_isakmp_sa == st->st_serialno) + c->newest_isakmp_sa = SOS_NOBODY; + ++ if ((c->policy & POLICY_UP) && IS_IKE_SA(st)) { ++ so_serial_t newer_sa = get_newer_sa_from_connection(st); ++ ++ if (state_by_serialno(newer_sa) != NULL) { ++ /* ++ * Presumably this is an old state that has ++ * either been rekeyed or replaced. ++ */ ++ DBG(DBG_CONTROL, DBG_log("IKE delete_state() for #%lu and connection '%s' that is supposed to remain up; not a problem - have newer #%lu", ++ st->st_serialno, c->name, newer_sa)); ++ } else { ++ libreswan_log("deleting IKE SA for connection '%s' but connection is supposed to remain up; schedule EVENT_REVIVE_CONNS", ++ c->name); ++ add_revival(c); ++ } ++ } ++ + /* + * fake a state change here while we are still associated with a + * connection. Without this the state logging (when enabled) cannot +diff -Naur libreswan-3.25-orig/programs/pluto/state.h libreswan-3.25/programs/pluto/state.h +--- libreswan-3.25-orig/programs/pluto/state.h 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/state.h 2019-05-02 10:55:42.638626547 -0400 +@@ -809,5 +809,5 @@ + + extern bool uniqueIDs; /* --uniqueids? */ + extern void ISAKMP_SA_established(const struct state *pst); +- ++extern void revive_conns(void); + #endif /* _STATE_H */ +diff -Naur libreswan-3.25-orig/programs/pluto/terminate.c libreswan-3.25/programs/pluto/terminate.c +--- libreswan-3.25-orig/programs/pluto/terminate.c 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/terminate.c 2019-05-02 10:55:42.638626547 -0400 +@@ -90,7 +90,7 @@ + return 1; + } + +-void terminate_connection(const char *name) ++void terminate_connection(const char *name, bool quiet) + { + /* + * Loop because more than one may match (master and instances) +@@ -112,7 +112,8 @@ + } else { + int count = foreach_connection_by_alias(name, terminate_a_connection, NULL); + if (count == 0) { +- loglog(RC_UNKNOWN_NAME, ++ if (!quiet) ++ loglog(RC_UNKNOWN_NAME, + "no such connection or aliased connection named \"%s\"", name); + } else { + loglog(RC_COMMENT, "terminated %d connections from aliased connection \"%s\"", +diff -Naur libreswan-3.25-orig/programs/pluto/timer.c libreswan-3.25/programs/pluto/timer.c +--- libreswan-3.25-orig/programs/pluto/timer.c 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/timer.c 2019-05-02 10:55:42.638626547 -0400 +@@ -334,6 +334,7 @@ + case EVENT_SD_WATCHDOG: + case EVENT_NAT_T_KEEPALIVE: + case EVENT_CHECK_CRLS: ++ case EVENT_REVIVE_CONNS: + passert(st == NULL); + break; + +@@ -435,6 +436,10 @@ + check_crls(); + break; + ++ case EVENT_REVIVE_CONNS: ++ revive_conns(); ++ break; ++ + case EVENT_v2_RELEASE_WHACK: + DBG(DBG_CONTROL, DBG_log("%s releasing whack for #%lu %s (sock=%d)", + enum_show(&timer_event_names, type), +diff -Naur libreswan-3.25-orig/programs/pluto/timer.h libreswan-3.25/programs/pluto/timer.h +--- libreswan-3.25-orig/programs/pluto/timer.h 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/timer.h 2019-05-02 10:55:42.638626547 -0400 +@@ -47,4 +47,6 @@ + #define delete_dpd_event(ST) delete_state_event((ST), &(ST)->st_dpd_event) + + extern void timer_list(void); ++extern char *revive_conn; ++ + #endif /* _TIMER_H */ diff --git a/SOURCES/libreswan-3.25-1679735-critical_flag.patch b/SOURCES/libreswan-3.25-1679735-critical_flag.patch new file mode 100644 index 0000000..9371c31 --- /dev/null +++ b/SOURCES/libreswan-3.25-1679735-critical_flag.patch @@ -0,0 +1,86 @@ +diff -Naur libreswan-3.25-orig/programs/pluto/nss_cert_verify.c libreswan-3.25/programs/pluto/nss_cert_verify.c +--- libreswan-3.25-orig/programs/pluto/nss_cert_verify.c 2019-04-11 12:50:35.423733161 +0200 ++++ libreswan-3.25/programs/pluto/nss_cert_verify.c 2019-04-11 12:51:58.832735953 +0200 +@@ -121,7 +121,7 @@ + return FALSE; + } + +-static int nss_err_to_revfail(CERTVerifyLogNode *node) ++static int nss_err_to_revfail(char *prefix, CERTVerifyLogNode *node) + { + int ret = VERIFY_RET_FAIL; + +@@ -131,7 +131,7 @@ + + loglog(RC_LOG_SERIOUS, "Certificate %s failed verification", + node->cert->subjectName); +- loglog(RC_LOG_SERIOUS, "ERROR: %s", ++ loglog(RC_LOG_SERIOUS, "%s: %s", prefix, + nss_err_str(node->error)); + + if (node->error == SEC_ERROR_REVOKED_CERTIFICATE) { +@@ -298,18 +298,18 @@ + cvout[1].value.pointer.chain = NULL; + cvout[2].type = cert_po_end; + +- int fin; ++ int fin = VERIFY_RET_FAIL; + + #ifdef NSS_IPSEC_PROFILE + SECStatus rv = CERT_PKIXVerifyCert(end_cert, certificateUsageIPsec, + cvin, cvout, NULL); + if (rv != SECSuccess || cur_log->count > 0) { + if (cur_log->count > 0 && cur_log->head != NULL) { +- fin = nss_err_to_revfail(cur_log->head); ++ fin = nss_err_to_revfail("warning", cur_log->head); + } else { + /* + * An rv != SECSuccess without CERTVerifyLog +- * results should not * happen, but catch it anyway ++ * results should not happen, but catch it anyway + */ + loglog(RC_LOG_SERIOUS, "X509: unspecified NSS verification failure"); + fin = VERIFY_RET_FAIL; +@@ -319,7 +319,11 @@ + *end_out = end_cert; + fin = VERIFY_RET_OK; + } +-#else ++#endif ++ ++ if (fin != VERIFY_RET_OK) ++ { ++ + /* kludge alert!! + * verification may be performed twice: once with the + * 'client' usage and once with 'server', which is an NSS +@@ -332,7 +336,7 @@ + + for (usage = certificateUsageSSLClient; ; usage = certificateUsageSSLServer) { + SECStatus rv = CERT_PKIXVerifyCert(end_cert, usage, cvin, cvout, NULL); +- if (rv != SECSuccess || cur_log->count > 0) { ++ if (rv != SECSuccess) { + if (cur_log->count > 0 && cur_log->head != NULL) { + if (usage == certificateUsageSSLClient && + RETRYABLE_TYPE(cur_log->head->error)) { +@@ -348,7 +352,8 @@ + cvout[1].value.pointer.chain = NULL; + continue; + } else { +- fin = nss_err_to_revfail(cur_log->head); ++ fin = nss_err_to_revfail("ERROR", cur_log->head); ++ loglog(RC_LOG_SERIOUS, "X509: verification failure using NSS TLS profile validation"); + } + } else { + /* +@@ -365,7 +370,9 @@ + } + break; + } +-#endif ++ ++ } ++ + pexpect(fin != 0); + + CERT_DestroyCertList(trustcl); diff --git a/SOURCES/libreswan-3.25-1686991-ikev1-del.patch b/SOURCES/libreswan-3.25-1686991-ikev1-del.patch new file mode 100644 index 0000000..d8d8933 --- /dev/null +++ b/SOURCES/libreswan-3.25-1686991-ikev1-del.patch @@ -0,0 +1,39 @@ +diff -Naur libreswan-3.25-orig/programs/pluto/ikev1_main.c libreswan-3.25/programs/pluto/ikev1_main.c +--- libreswan-3.25-orig/programs/pluto/ikev1_main.c 2019-05-07 15:41:26.366181612 -0400 ++++ libreswan-3.25/programs/pluto/ikev1_main.c 2019-05-07 15:45:41.780183599 -0400 +@@ -2727,30 +2727,11 @@ + * Useful if the other peer is + * rebooting. + */ +- if (dst->st_event != NULL && +- dst->st_event->ev_type == +- EVENT_SA_REPLACE && +- !monobefore(monotimesum(mononow(), +- deltatime(DELETE_SA_DELAY)), +- dst->st_event->ev_time)) { +- /* +- * Patch from Angus Lees to +- * ignore retransmitted +- * Delete SA. +- */ +- loglog(RC_LOG_SERIOUS, +- "received Delete SA payload: already replacing IPSEC State #%lu in %ld seconds", +- dst->st_serialno, +- (long)deltasecs(monotimediff( +- dst->st_event->ev_time, +- mononow()))); +- } else { +- loglog(RC_LOG_SERIOUS, +- "received Delete SA payload: replace IPSEC State #%lu now", +- dst->st_serialno); +- dst->st_margin = deltatime(0); +- event_force(EVENT_SA_REPLACE, dst); +- } ++ loglog(RC_LOG_SERIOUS, ++ "received Delete SA payload: replace IPSEC State #%lu now", ++ dst->st_serialno); ++ dst->st_margin = deltatime(0); ++ event_force(EVENT_SA_REPLACE, dst); + } else { + loglog(RC_LOG_SERIOUS, + "received Delete SA(0x%08" PRIx32 ") payload: deleting IPSEC State #%lu", diff --git a/SOURCES/libreswan-3.27-1672921-delete.patch b/SOURCES/libreswan-3.27-1672921-delete.patch new file mode 100644 index 0000000..87447ad --- /dev/null +++ b/SOURCES/libreswan-3.27-1672921-delete.patch @@ -0,0 +1,82 @@ +diff -Naur libreswan-3.25-orig/include/pluto_constants.h libreswan-3.25/include/pluto_constants.h +--- libreswan-3.25-orig/include/pluto_constants.h 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/include/pluto_constants.h 2019-02-15 17:41:06.954865678 -0500 +@@ -436,6 +436,8 @@ + + IMPAIR_SEND_PKCS7_THINGIE_IX, /* send certificates as a PKCS7 thingie */ + ++ IMPAIR_IKEv1_DEL_WITH_NOTIFY_IX, ++ + IMPAIR_roof_IX /* first unassigned IMPAIR */ + }; + +@@ -495,6 +497,7 @@ + + #define IMPAIR_SEND_PKCS7_THINGIE LELEM(IMPAIR_SEND_PKCS7_THINGIE_IX) + ++#define IMPAIR_IKEv1_DEL_WITH_NOTIFY LELEM(IMPAIR_IKEv1_DEL_WITH_NOTIFY_IX) + /* State of exchanges + * + * The name of the state describes the last message sent, not the +diff -Naur libreswan-3.25-orig/lib/libswan/impair.c libreswan-3.25/lib/libswan/impair.c +--- libreswan-3.25-orig/lib/libswan/impair.c 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/lib/libswan/impair.c 2019-02-15 17:41:06.954865678 -0500 +@@ -75,6 +75,8 @@ + I(IMPAIR_ALLOW_DNS_INSECURE, "impair-allow-dns-insecure"), + + I(IMPAIR_SEND_PKCS7_THINGIE, "impair-send-pkcs7-thingie"), ++ ++ I(IMPAIR_IKEv1_DEL_WITH_NOTIFY, "impair-ikev1-del-with-notify"), + }; + + const enum_names impair_names = { +diff -Naur libreswan-3.25-orig/programs/pluto/ikev1_main.c libreswan-3.25/programs/pluto/ikev1_main.c +--- libreswan-3.25-orig/programs/pluto/ikev1_main.c 2018-06-27 11:42:26.000000000 -0400 ++++ libreswan-3.25/programs/pluto/ikev1_main.c 2019-02-15 17:42:50.876885416 -0500 +@@ -2491,12 +2491,36 @@ + isad.isad_protoid = ns->proto; + + isad.isad_nospi = 1; ++ ++ if (DBGP(IMPAIR_IKEv1_DEL_WITH_NOTIFY)) ++ isad.isad_np = ISAKMP_NEXT_N; /* Notify */ ++ + passert(out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, + &del_pbs)); + passert(out_raw(&ns->spi, sizeof(ipsec_spi_t), + &del_pbs, + "delete payload")); + close_output_pbs(&del_pbs); ++ ++ if (DBGP(IMPAIR_IKEv1_DEL_WITH_NOTIFY)) { ++ pb_stream cruft_pbs; ++ ++ libreswan_log("IMPAIR: adding bogus Notify payload after IKE Delete payload"); ++ struct isakmp_notification isan = { ++ .isan_np = ISAKMP_NEXT_NONE, ++ .isan_doi = ISAKMP_DOI_IPSEC, ++ .isan_protoid = PROTO_ISAKMP, ++ .isan_spisize = COOKIE_SIZE * 2, ++ .isan_type = INVALID_PAYLOAD_TYPE, ++ }; ++ ++ passert(out_struct(&isan, &isakmp_notification_desc, &r_hdr_pbs, ++ &cruft_pbs)); ++ passert(out_raw(&ns->spi, sizeof(ipsec_spi_t), &cruft_pbs, ++ "notify payload")); ++ close_output_pbs(&cruft_pbs); ++ } ++ + } + } + +@@ -2743,7 +2767,9 @@ + rc->policy &= ~POLICY_UP; + if (!shared_phase1_connection(rc)) { + flush_pending_by_connection(rc); ++ /* This also deletes the IKE SA, clear pointer */ + delete_states_by_connection(rc, FALSE); ++ md->st = NULL; + } + reset_cur_connection(); + } diff --git a/SPECS/libreswan.spec b/SPECS/libreswan.spec index ae1137e..0d803d7 100644 --- a/SPECS/libreswan.spec +++ b/SPECS/libreswan.spec @@ -24,7 +24,7 @@ Name: libreswan Summary: IPsec implementation with IKEv1 and IKEv2 keying protocols Version: 3.25 -Release: %{?prever:0.}4.1%{?prever:.%{prever}}%{?dist} +Release: %{?prever:0.}4.8%{?prever:.%{prever}}%{?dist} License: GPLv2 Group: System Environment/Daemons Url: https://libreswan.org/ @@ -41,6 +41,10 @@ Patch5: libreswan-3.25-1625303-recursive-incl.patch Patch6: libreswan-3.23-del-with-notify-1630355.patch Patch7: libreswan-3.25-1664244-xauth-null-pwd.patch Patch8: libreswan-3.25-1664521-fips-keysize.patch +Patch9: libreswan-3.27-1672921-delete.patch +Patch10: libreswan-3.25-1679735-critical_flag.patch +Patch11: libreswan-3.25-1673105-down-restart.patch +Patch12: libreswan-3.25-1686991-ikev1-del.patch Requires: iproute >= 2.6.8 Requires: nss-tools nss-softokn @@ -138,6 +142,10 @@ Libreswan is based on Openswan-2.6.38 which in turn is based on FreeS/WAN-2.04 %patch6 -p1 %patch7 -p1 %patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 %build %if %{buildefence} @@ -341,6 +349,27 @@ fi %endif %changelog +* Thu May 09 2019 Paul Wouters - 3.25-4.8 +- Resolves: rhbz#1708060 IKEv1 traffic interruption when responder deletes SAs 60 seconds before EVENT_SA_REPLACE [rhel-7.6.z] + +* Thu May 02 2019 Paul Wouters - 3.25-4.7 +- Resolves: rhbz#1683577 Opportunistic IPsec instances of /32 groups or auto=start [updated for eclipsed handling] + +* Thu Apr 11 2019 Paul Wouters - 3.25-4.6 +- Resolves: rhbz#1680483 libreswan using NSS IPsec profiles regresses when critical flags are set causing validation failure [rhel-7.6.z] [updated] + +* Sun Mar 31 2019 Paul Wouters - 3.25-4.5 +- Resolves: rhbz#1683577 Opportunistic IPsec instances of /32 groups or auto=start that receive delete won't restart [rhel-7.6.z] [updated] + +* Tue Feb 26 2019 Paul Wouters - 3.25-4.4 +- Resolves: rhbz#1683577 Opportunistic IPsec instances of /32 groups or auto=start that receive delete won't restart [rhel-7.6.z] + +* Mon Feb 25 2019 Paul Wouters - 3.25-4.3 +- Resolves: rhbz#1680483 libreswan using NSS IPsec profiles regresses when critical flags are set causing validation failure [rhel-7.6.z] + +* Fri Feb 15 2019 Paul Wouters - 3.25-4.2 +- Resolves: rhbz#1672921 - Libreswan crash upon receiving ISAKMP_NEXT_D with appended ISAKMP_NEXT_N [updated bugfix] + * Fri Jan 11 2019 Paul Wouters - 3.25-4.1 - Resolves: rhbz#1665369 libreswan 3.25 in FIPS mode is incorrectly rejecting X.509 public keys that are >= 3072 bits [rhel-7.6.z]