diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f1434e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +SOURCES/ikev1_dsa.fax.bz2 +SOURCES/ikev1_psk.fax.bz2 +SOURCES/ikev2.fax.bz2 +SOURCES/libreswan-3.15.tar.gz diff --git a/.libreswan.metadata b/.libreswan.metadata new file mode 100644 index 0000000..992bed3 --- /dev/null +++ b/.libreswan.metadata @@ -0,0 +1,4 @@ +b35cd50b8bc0a08b9c07713bf19c72d53bfe66bb SOURCES/ikev1_dsa.fax.bz2 +861d97bf488f9e296cad8c43ab72f111a5b1a848 SOURCES/ikev1_psk.fax.bz2 +fcaf77f3deae3d8e99cdb3b1f8abea63167a0633 SOURCES/ikev2.fax.bz2 +f2f7f4c0e6ffc979d3cc3b301dc56b49a9dcc2f3 SOURCES/libreswan-3.15.tar.gz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/libreswan-3.15-1166146.patch b/SOURCES/libreswan-3.15-1166146.patch new file mode 100644 index 0000000..a65133e --- /dev/null +++ b/SOURCES/libreswan-3.15-1166146.patch @@ -0,0 +1,23 @@ +diff -Naur libreswan-3.15-orig/programs/pluto/connections.c libreswan-3.15/programs/pluto/connections.c +--- libreswan-3.15-orig/programs/pluto/connections.c 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/programs/pluto/connections.c 2015-09-24 13:19:16.151982555 -0400 +@@ -3334,6 +3334,11 @@ + struct connection *d; + struct spd_route *sr; + ++ /* weird things can happen to our interfaces */ ++ if (!oriented(*c)) { ++ return NULL; ++ } ++ + DBG(DBG_CONTROLMORE, { + char s1[SUBNETTOT_BUF]; + char d1[SUBNETTOT_BUF]; +@@ -3378,7 +3383,6 @@ + (sr->that.protocol == peer_protocol) && + (!sr->that.port || + sr->that.port == peer_port)) { +- passert(oriented(*c)); + if (routed(sr->routing)) + return c; + diff --git a/SOURCES/libreswan-3.15-1271778-whack-man.patch b/SOURCES/libreswan-3.15-1271778-whack-man.patch new file mode 100644 index 0000000..982e449 --- /dev/null +++ b/SOURCES/libreswan-3.15-1271778-whack-man.patch @@ -0,0 +1,11 @@ +diff -Naur libreswan-3.15-orig/programs/pluto/ipsec_pluto.8.xml libreswan-3.15/programs/pluto/ipsec_pluto.8.xml +--- libreswan-3.15-orig/programs/pluto/ipsec_pluto.8.xml 2015-08-24 22:28:32.000000000 -0400 ++++ libreswan-3.15/programs/pluto/ipsec_pluto.8.xml 2015-10-15 15:53:37.442284597 -0400 +@@ -18,6 +18,7 @@ + + + ipsec pluto ++ ipsec whack + pluto + + ipsec whack : IPsec IKE keying daemon and control interface diff --git a/SOURCES/libreswan-3.15-1271811-fipsfiles.patch b/SOURCES/libreswan-3.15-1271811-fipsfiles.patch new file mode 100644 index 0000000..2735548 --- /dev/null +++ b/SOURCES/libreswan-3.15-1271811-fipsfiles.patch @@ -0,0 +1,65 @@ +commit 19b50a501772a06fb7648b531852fb588efb0021 +Author: Paul Wouters +Date: Tue Oct 13 13:41:24 2015 -0400 + + pluto: fixup fips.h to only require libexec/ components that are compiled. + + When disabling MAST, the fips.h file list wanted to checksum updown.mast + which was not installed, and cause a FIPS selftest failure. + +diff --git a/programs/pluto/fips.h b/programs/pluto/fips.h +index 10bfff0..9c550d8 100644 +--- a/programs/pluto/fips.h ++++ b/programs/pluto/fips.h +@@ -22,32 +22,40 @@ + + const char *fips_package_files[] = { IPSEC_EXECDIR "/pluto", + IPSEC_EXECDIR "/setup", ++#ifdef USE_ADNS ++ IPSEC_EXECDIR "/_pluto_adns", ++#endif + IPSEC_EXECDIR "/addconn", + IPSEC_EXECDIR "/auto", + IPSEC_EXECDIR "/barf", +- IPSEC_EXECDIR "/eroute", + IPSEC_EXECDIR "/ikeping", + IPSEC_EXECDIR "/readwriteconf", + IPSEC_EXECDIR "/_keycensor", +- IPSEC_EXECDIR "/klipsdebug", + IPSEC_EXECDIR "/look", + IPSEC_EXECDIR "/newhostkey", +- IPSEC_EXECDIR "/pf_key", +- IPSEC_EXECDIR "/_pluto_adns", + IPSEC_EXECDIR "/_plutorun", +- IPSEC_EXECDIR "/rsasigkey", + IPSEC_EXECDIR "/_secretcensor", ++ IPSEC_EXECDIR "/rsasigkey", + IPSEC_EXECDIR "/secrets", + IPSEC_EXECDIR "/showhostkey", +- IPSEC_EXECDIR "/spi", +- IPSEC_EXECDIR "/spigrp", + IPSEC_EXECDIR "/_stackmanager", +- IPSEC_EXECDIR "/tncfg", + IPSEC_EXECDIR "/_updown", +- IPSEC_EXECDIR "/_updown.klips", +- IPSEC_EXECDIR "/_updown.mast", +- IPSEC_EXECDIR "/_updown.netkey", + IPSEC_EXECDIR "/verify", + IPSEC_EXECDIR "/whack", + IPSEC_SBINDIR "/ipsec", ++#ifdef KLIPS ++ IPSEC_EXECDIR "/pf_key", ++ IPSEC_EXECDIR "/klipsdebug", ++ IPSEC_EXECDIR "/eroute", ++ IPSEC_EXECDIR "/spi", ++ IPSEC_EXECDIR "/spigrp", ++ IPSEC_EXECDIR "/_updown.klips", ++ IPSEC_EXECDIR "/tncfg", ++#ifdef KLIPS_MAST ++ IPSEC_EXECDIR "/_updown.mast", ++#endif ++#endif ++#ifdef NETKEY_SUPPORT ++ IPSEC_EXECDIR "/_updown.netkey", ++#endif + NULL }; diff --git a/SOURCES/libreswan-3.15-609343.patch b/SOURCES/libreswan-3.15-609343.patch new file mode 100644 index 0000000..02dd768 --- /dev/null +++ b/SOURCES/libreswan-3.15-609343.patch @@ -0,0 +1,26 @@ +diff --git a/programs/pluto/hostpair.c b/programs/pluto/hostpair.c +index 9b14341..e3afecd 100644 +--- a/programs/pluto/hostpair.c ++++ b/programs/pluto/hostpair.c +@@ -284,7 +284,8 @@ void release_dead_interfaces(void) + */ + passert(p == *pp); + +- p->interface = NULL; ++ terminate_connection(p->name); ++ p->interface = NULL; /* withdraw orientation */ + + *pp = p->hp_next; /* advance *pp */ + p->host_pair = NULL; +diff --git a/programs/pluto/initiate.c b/programs/pluto/initiate.c +index 056af59..eed8bf3 100644 +--- a/programs/pluto/initiate.c ++++ b/programs/pluto/initiate.c +@@ -119,6 +119,7 @@ bool orient(struct connection *c) + c->name, c->interface->ip_dev->id_rname, + p->ip_dev->id_rname); + } ++ terminate_connection(c->name); + c->interface = NULL; /* withdraw orientation */ + return FALSE; + } diff --git a/SOURCES/libreswan-3.15-NLMSG_OK.patch b/SOURCES/libreswan-3.15-NLMSG_OK.patch new file mode 100644 index 0000000..dbd552b --- /dev/null +++ b/SOURCES/libreswan-3.15-NLMSG_OK.patch @@ -0,0 +1,444 @@ +diff -Naur libreswan-3.15-orig/programs/addconn/addconn.c libreswan-3.15/programs/addconn/addconn.c +--- libreswan-3.15-orig/programs/addconn/addconn.c 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/programs/addconn/addconn.c 2015-09-04 09:21:23.866861084 -0400 +@@ -64,6 +64,8 @@ + * If DST is not specified, full route table will be returned. + * 16kB was too small for biggish router, so do 32kB. + * TODO: This should be dynamic! Fix it in netlink_read_reply(). ++ * Note: due to our hack to dodge a bug in NLMSG_OK, ++ * RTNL_BUFSIZE must be less than or equal to USHRT_MAX. + */ + #define RTNL_BUFSIZE 32768 + +@@ -139,30 +141,34 @@ + static + ssize_t netlink_read_reply(int sock, char *buf, unsigned int seqnum, __u32 pid) + { +- struct nlmsghdr *nlhdr; +- struct sockaddr_nl sa; +- socklen_t salen = sizeof(sa); +- ssize_t readlen = 0; + ssize_t msglen = 0; + + /* TODO: use dynamic buf */ +- do { ++ for (;;) { ++ struct sockaddr_nl sa; ++ ssize_t readlen; ++ + /* Read netlink message, verifying kernel origin. */ + do { ++ socklen_t salen = sizeof(sa); ++ + readlen = recvfrom(sock, buf, RTNL_BUFSIZE - msglen, 0, + (struct sockaddr *)&sa, &salen); +- if (readlen < 0) ++ if (readlen < 0 || salen != sizeof(sa)) + return -1; + } while (sa.nl_pid != 0); + + /* Verify it's valid */ +- nlhdr = (struct nlmsghdr *) buf; ++ struct nlmsghdr *nlhdr = (struct nlmsghdr *) buf; ++ + /* +- * CAST TO unsigned short IS TO AVOID netlink.h:NLMSG_OK error +- * which triggers a GCC warning in recent GCCs: ++ * The cast to unsigned short is to dodge an error in ++ * netlink.h:NLMSG_OK() which triggers a GCC warning in recent ++ * versions of GCC (2014 August): + * error: comparison between signed and unsigned integer expressions ++ * Note: as long as RTNL_BUFSIZE <= USHRT_MAX, this is safe. + */ +- if (NLMSG_OK(nlhdr, (unsigned short)readlen) == 0 || ++ if (!NLMSG_OK(nlhdr, (unsigned short)readlen) || + nlhdr->nlmsg_type == NLMSG_ERROR) + return -1; + +@@ -174,11 +180,16 @@ + buf += readlen; + msglen += readlen; + +- /* All done if it's not a multi part */ ++ /* all done if it's not a multi part */ + if ((nlhdr->nlmsg_flags & NLM_F_MULTI) == 0) + break; +- } while (nlhdr->nlmsg_seq != seqnum || +- nlhdr->nlmsg_pid != pid); ++ ++ /* all done if this is the one we were searching for */ ++ if (nlhdr->nlmsg_seq == seqnum && ++ nlhdr->nlmsg_pid == pid) ++ break; ++ } ++ + return msglen; + } + +@@ -188,31 +199,33 @@ + static + ssize_t netlink_query(char *msgbuf) + { +- struct nlmsghdr *nlmsg; +- int sock; ++ int sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); + +- /* Create socket */ +- if ((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) { ++ if (sock < 0) { + int e = errno; +- printf("create netlink socket: (%d: %s)", e, strerror(e)); ++ ++ printf("create netlink socket failure: (%d: %s)\n", e, strerror(e)); + return -1; + } + + /* Send request */ +- nlmsg = (struct nlmsghdr *)msgbuf; ++ struct nlmsghdr *nlmsg = (struct nlmsghdr *)msgbuf; ++ + if (send(sock, nlmsg, nlmsg->nlmsg_len, 0) < 0) { + int e = errno; +- printf("write netlink socket: (%d: %s)", e, strerror(e)); ++ ++ printf("write netlink socket failure: (%d: %s)\n", e, strerror(e)); + return -1; + } + + /* Read response */ ++ errno = 0; /* in case failure does not set it */ + ssize_t len = netlink_read_reply(sock, msgbuf, 1, getpid()); + + if (len < 0) { + int e = errno; + +- printf("read netlink socket: (%d: %s)", e, strerror(e)); ++ printf("read netlink socket failure: (%d: %s)\n", e, strerror(e)); + return -1; + } + close(sock); +@@ -331,11 +344,9 @@ + * 1) find out default gateway + * 2) find out src for that default gateway + */ +- if (!has_dst) { +- if (seeking_src && seeking_gateway) { +- seeking_src = FALSE; +- query_again = 1; +- } ++ if (!has_dst && seeking_src && seeking_gateway) { ++ seeking_src = FALSE; ++ query_again = 1; + } + if (seeking_gateway) { + struct nlmsghdr *nlmsg = (struct nlmsghdr *)msgbuf; +@@ -358,19 +369,17 @@ + struct nlmsghdr *nlmsg = (struct nlmsghdr *)msgbuf; + + /* +- * CAST TO unsigned short IS TO AVOID netlink.h:NLMSG_OK error +- * which triggers a GCC warning in recent GCCs: ++ * The cast to unsigned short is to dodge an error in ++ * netlink.h:NLMSG_OK() which triggers a GCC warning in recent ++ * versions of GCC (2014 August): + * error: comparison between signed and unsigned integer expressions ++ * Note: as long as RTNL_BUFSIZE <= USHRT_MAX, this is safe. + */ +- for (; NLMSG_OK(nlmsg, (unsigned short)len); nlmsg = NLMSG_NEXT(nlmsg, len)) { +- struct rtmsg *rtmsg; +- struct rtattr *rtattr; +- int rtlen; ++ for (; NLMSG_OK(nlmsg, (unsigned short)len); nlmsg = NLMSG_NEXT(nlmsg, len)) { + char r_interface[IF_NAMESIZE+1]; + char r_source[ADDRTOT_BUF]; + char r_gateway[ADDRTOT_BUF]; + char r_destination[ADDRTOT_BUF]; +- bool ignore; + + if (nlmsg->nlmsg_type == NLMSG_DONE) + break; +@@ -378,23 +387,23 @@ + if (nlmsg->nlmsg_type == NLMSG_ERROR) { + printf("netlink error\n"); + return -1; +- break; + } + + /* ignore all but IPv4 and IPv6 */ +- rtmsg = (struct rtmsg *) NLMSG_DATA(nlmsg); ++ struct rtmsg *rtmsg = (struct rtmsg *) NLMSG_DATA(nlmsg); ++ + if (rtmsg->rtm_family != AF_INET && + rtmsg->rtm_family != AF_INET6) + continue; + + /* Parse one route entry */ +- r_interface[0] = r_interface[IF_NAMESIZE] = r_source[0] = +- r_gateway[0] = r_destination[0] = '\0'; +- rtattr = (struct rtattr *) RTM_RTA(rtmsg); +- rtlen = RTM_PAYLOAD(nlmsg); +- for (; +- RTA_OK(rtattr, rtlen); +- rtattr = RTA_NEXT(rtattr, rtlen)) { ++ zero(&r_interface); ++ r_source[0] = r_gateway[0] = r_destination[0] = '\0'; ++ ++ struct rtattr *rtattr = (struct rtattr *) RTM_RTA(rtmsg); ++ int rtlen = RTM_PAYLOAD(nlmsg); ++ ++ while (RTA_OK(rtattr, rtlen)) { + switch (rtattr->rta_type) { + case RTA_OIF: + if_indextoname(*(int *)RTA_DATA(rtattr), +@@ -417,13 +426,14 @@ + sizeof(r_destination)); + break; + } ++ rtattr = RTA_NEXT(rtattr, rtlen); + } + + /* + * Ignore if not main table. + * Ignore ipsecX or mastX interfaces. + */ +- ignore = rtmsg->rtm_table != RT_TABLE_MAIN || ++ bool ignore = rtmsg->rtm_table != RT_TABLE_MAIN || + startswith(r_interface, "ipsec") || + startswith(r_interface, "mast"); + +@@ -548,20 +558,23 @@ + int main(int argc, char *argv[]) + { + int opt = 0; +- int autoall = 0; ++ bool autoall = FALSE; + int configsetup = 0; + int checkconfig = 0; +- char *export = "export"; /* display export before the foo=bar or not */ +- int listroute = 0, liststart = 0, listignore = 0, listadd = 0, +- listall = 0, dolist = 0, liststack = 0; +- struct starter_config *cfg = NULL; +- err_t err = NULL; +- char *confdir = NULL; ++ const char *export = "export"; /* display export before the foo=bar or not */ ++ bool ++ dolist = FALSE, ++ listadd = FALSE, ++ listroute = FALSE, ++ liststart = FALSE, ++ listignore = FALSE, ++ listall = FALSE, ++ liststack = FALSE; + char *configfile = NULL; +- char *varprefix = ""; ++ const char *varprefix = ""; + int exit_status = 0; + struct starter_conn *conn = NULL; +- char *ctlbase = NULL; ++ const char *ctlbase = NULL; + bool resolvip = TRUE; /* default to looking up names */ + + #if 0 +@@ -586,7 +599,7 @@ + break; + + case 'a': +- autoall = 1; ++ autoall = TRUE; + break; + + case 'D': +@@ -595,11 +608,11 @@ + break; + + case 'T': +- configsetup++; ++ configsetup++; /* ??? is this not idempotent? */ + break; + + case 'K': +- checkconfig++; ++ checkconfig++; /* ??? is this not idempotent? */ + break; + + case 'N': +@@ -615,33 +628,33 @@ + break; + + case 'L': +- listadd = 1; +- dolist = 1; ++ listadd = TRUE; ++ dolist = TRUE; + break; + + case 'r': +- listroute = 1; +- dolist = 1; ++ listroute = TRUE; ++ dolist = TRUE; + break; + + case 's': +- liststart = 1; +- dolist = 1; ++ liststart = TRUE; ++ dolist = TRUE; + break; + + case 'S': +- liststack = 1; +- dolist = 1; ++ liststack = TRUE; ++ dolist = TRUE; + break; + + case 'i': +- listignore = 1; +- dolist = 1; ++ listignore = TRUE; ++ dolist = TRUE; + break; + + case 'A': +- listall = 1; +- dolist = 1; ++ listall = TRUE; ++ dolist = TRUE; + break; + + case 'P': +@@ -672,9 +685,7 @@ + yydebug = 1; + } + +- /* find config file */ +- if (confdir == NULL) +- confdir = IPSEC_CONFDIR; ++ char *confdir = IPSEC_CONFDIR; + + if (configfile == NULL) { + /* ??? see code clone in programs/readwriteconf/readwriteconf.c */ +@@ -694,29 +705,32 @@ + + starter_use_log(verbose != 0, TRUE, verbose == 0); + +- err = NULL; /* reset to no error */ +- + if (configsetup || checkconfig || dolist) { + /* skip if we have no use for them... causes delays */ + resolvip = FALSE; + } + +- cfg = confread_load(configfile, &err, resolvip, ctlbase, configsetup); ++ struct starter_config *cfg = NULL; + +- if (cfg == NULL) { +- fprintf(stderr, "cannot load config '%s': %s\n", +- configfile, err); +- exit(3); +- } else if (checkconfig) { +- confread_free(cfg); +- exit(0); ++ { ++ err_t err = NULL; ++ ++ cfg = confread_load(configfile, &err, resolvip, ctlbase, configsetup); ++ ++ if (cfg == NULL) { ++ fprintf(stderr, "cannot load config '%s': %s\n", ++ configfile, err); ++ exit(3); ++ } else if (checkconfig) { ++ confread_free(cfg); ++ exit(0); ++ } + } + + if (autoall) { + if (verbose) + printf("loading all conns according to their auto= settings\n"); + +- + /* + * Load all conns marked as auto=add or better. + * First, do the auto=route and auto=add conns to quickly +@@ -727,7 +741,6 @@ + if (verbose) + printf(" Pass #1: Loading auto=add, auto=route and auto=start connections\n"); + +- + for (conn = cfg->conns.tqh_first; + conn != NULL; + conn = conn->link.tqe_next) { +@@ -828,7 +841,6 @@ + conn-> + strings[KSF_CONNALIAS] + )) { +- + if (conn->state == + STATE_ADDED) { + printf("\nalias: %s conn %s already added\n", +@@ -875,12 +887,10 @@ + printf("%s ", conn->name); + printf("\n"); + } else { +- + if (listadd) { + if (verbose) + printf("listing all conns marked as auto=add\n"); + +- + /* list all conns marked as auto=add */ + for (conn = cfg->conns.tqh_first; + conn != NULL; +@@ -893,7 +903,6 @@ + if (verbose) + printf("listing all conns marked as auto=route and auto=start\n"); + +- + /* + * list all conns marked as auto=route or start or + * better +@@ -911,7 +920,6 @@ + if (verbose) + printf("listing all conns marked as auto=start\n"); + +- + /* list all conns marked as auto=start */ + for (conn = cfg->conns.tqh_first; + conn != NULL; +@@ -925,7 +933,6 @@ + if (verbose) + printf("listing all conns marked as auto=ignore\n"); + +- + /* list all conns marked as auto=start */ + for (conn = cfg->conns.tqh_first; + conn != NULL; +@@ -942,14 +949,14 @@ + + for (kd = ipsec_conf_keywords_v2; kd->keyname != NULL; kd++) { + if (strstr(kd->keyname, "protostack")) { +- if (cfg->setup.strings[kd->field]) ++ if (cfg->setup.strings[kd->field]) { + printf("%s\n", + cfg->setup.strings[kd->field]); +- else ++ } else { + /* implicit default */ + printf("netkey\n"); ++ } + } +- + } + confread_free(cfg); + exit(0); +@@ -1008,7 +1015,6 @@ + } + confread_free(cfg); + exit(0); +- + } + + confread_free(cfg); diff --git a/SOURCES/libreswan-3.15-cisco-delete.patch b/SOURCES/libreswan-3.15-cisco-delete.patch new file mode 100644 index 0000000..6cea96e --- /dev/null +++ b/SOURCES/libreswan-3.15-cisco-delete.patch @@ -0,0 +1,107 @@ +diff --git a/programs/pluto/ikev1_main.c b/programs/pluto/ikev1_main.c +index de20a83..31d959b 100644 +--- a/programs/pluto/ikev1_main.c ++++ b/programs/pluto/ikev1_main.c +@@ -2983,13 +2983,12 @@ bool accept_delete(struct msg_digest *md, + * IPSEC (ESP/AH) + */ + ipsec_spi_t spi; /* network order */ +- bool bogus; +- struct state *dst; + + if (!in_raw(&spi, sizeof(spi), &p->pbs, "SPI")) + return self_delete; + +- dst = find_phase2_state_to_delete(st, ++ bool bogus; ++ struct state *dst = find_phase2_state_to_delete(st, + d->isad_protoid, + spi, + &bogus); +@@ -2997,14 +2996,19 @@ bool accept_delete(struct msg_digest *md, + passert(dst != st); /* st is an IKE SA */ + if (dst == NULL) { + loglog(RC_LOG_SERIOUS, +- "ignoring Delete SA payload: %s SA(0x%08" PRIx32 ") not found (%s)", ++ "ignoring Delete SA payload: %s SA(0x%08" PRIx32 ") not found (maybe expired)", + enum_show(&protocol_names, + d->isad_protoid), +- ntohl(spi), +- bogus ? +- "our SPI - bogus implementation" : +- "maybe expired"); ++ ntohl(spi)); + } else { ++ if (bogus) { ++ loglog(RC_LOG_SERIOUS, ++ "warning: Delete SA payload: %s SA(0x%08" PRIx32 ") is our own SPI (bogus implementation) - deleting anyway", ++ enum_show(&protocol_names, ++ d->isad_protoid), ++ ntohl(spi)); ++ } ++ + struct connection *rc = dst->st_connection; + struct connection *oldc = cur_connection; + +diff --git a/programs/pluto/state.c b/programs/pluto/state.c +index b2eac62..c5d4484 100644 +--- a/programs/pluto/state.c ++++ b/programs/pluto/state.c +@@ -1537,37 +1537,52 @@ struct state *find_likely_sender(size_t packet_len, u_char *packet) + return NULL; + } + ++/* ++ * find_phase2_state_to_delete: find an AH or ESP SA to delete ++ * ++ * We are supposed to be given the other side's SPI. ++ * Certain CISCO implementations send our side's SPI instead. ++ * We'll accept this, but mark it as bogus. ++ */ + struct state *find_phase2_state_to_delete(const struct state *p1st, + u_int8_t protoid, + ipsec_spi_t spi, + bool *bogus) + { +- struct state *st; ++ struct state *bogusst = NULL; + int i; + + *bogus = FALSE; + for (i = 0; i < STATE_TABLE_SIZE; i++) { ++ struct state *st; ++ + FOR_EACH_ENTRY(st, i, { + if (IS_IPSEC_SA_ESTABLISHED(st->st_state) && + p1st->st_connection->host_pair == + st->st_connection->host_pair && + same_peer_ids(p1st->st_connection, +- st->st_connection, NULL)) { ++ st->st_connection, NULL)) ++ { + struct ipsec_proto_info *pr = + protoid == PROTO_IPSEC_AH ? + &st->st_ah : &st->st_esp; + + if (pr->present) { +- if (pr->attrs.spi == spi) ++ if (pr->attrs.spi == spi) { ++ *bogus = FALSE; + return st; ++ } + +- if (pr->our_spi == spi) ++ if (pr->our_spi == spi) { + *bogus = TRUE; ++ bogusst = st; ++ /* don't return! */ ++ } + } + } + }); + } +- return NULL; ++ return bogusst; + } + + /* diff --git a/SOURCES/libreswan-3.15-gcc-osw-interop-conf.patch b/SOURCES/libreswan-3.15-gcc-osw-interop-conf.patch new file mode 100644 index 0000000..27fe3f5 --- /dev/null +++ b/SOURCES/libreswan-3.15-gcc-osw-interop-conf.patch @@ -0,0 +1,910 @@ +diff -Naur libreswan-3.15-orig/include/ipsecconf/confread.h libreswan-3.15/include/ipsecconf/confread.h +--- libreswan-3.15-orig/include/ipsecconf/confread.h 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/include/ipsecconf/confread.h 2015-09-03 11:43:09.630000000 -0400 +@@ -132,7 +132,7 @@ + extern struct starter_config *confread_load(const char *file, + err_t *perr, + bool resolvip, +- char *ctlbase, ++ const char *ctlbase, + bool setuponly); + extern struct starter_conn *alloc_add_conn(struct starter_config *cfg, + char *name); +diff -Naur libreswan-3.15-orig/include/ipsecconf/keywords.h libreswan-3.15/include/ipsecconf/keywords.h +--- libreswan-3.15-orig/include/ipsecconf/keywords.h 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/include/ipsecconf/keywords.h 2015-09-03 11:43:10.538000000 -0400 +@@ -305,8 +305,7 @@ + struct kw_list { + struct kw_list *next; + struct keyword keyword; +- char *string; +- double decimal; ++ char *string; + unsigned int number; + }; + +diff -Naur libreswan-3.15-orig/lib/libipsecconf/confread.c libreswan-3.15/lib/libipsecconf/confread.c +--- libreswan-3.15-orig/lib/libipsecconf/confread.c 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/lib/libipsecconf/confread.c 2015-09-03 11:42:22.941000000 -0400 +@@ -1418,7 +1418,7 @@ + struct starter_config *confread_load(const char *file, + err_t *perr, + bool resolvip, +- char *ctlbase, ++ const char *ctlbase, + bool setuponly) + { + struct starter_config *cfg = NULL; +diff -Naur libreswan-3.15-orig/lib/libipsecconf/confwrite.c libreswan-3.15/lib/libipsecconf/confwrite.c +--- libreswan-3.15-orig/lib/libipsecconf/confwrite.c 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/lib/libipsecconf/confwrite.c 2015-09-03 11:42:22.941000000 -0400 +@@ -412,9 +412,9 @@ + + int alsoplace = 0; + +- fprintf(out, "\t#also = "); ++ fprintf(out, "\t#also ="); + while (conn->alsos[alsoplace] != NULL) { +- fprintf(out, "%s ", conn->alsos[alsoplace]); ++ fprintf(out, " %s", conn->alsos[alsoplace]); + alsoplace++; + } + fprintf(out, "\n"); +diff -Naur libreswan-3.15-orig/lib/libipsecconf/Makefile libreswan-3.15/lib/libipsecconf/Makefile +--- libreswan-3.15-orig/lib/libipsecconf/Makefile 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/lib/libipsecconf/Makefile 2015-09-03 11:42:22.941000000 -0400 +@@ -38,21 +38,45 @@ + # since all the $(OBJS) indirectly depend on the header anyway. + $(OBJS): parser.tab.h + +-# Use UNIX basename to strip off the directory. Use grep to workaround flex < 2.5.35 ++# Use UNIX basename to strip off the directory. ++# Use sed to work around two bugs: ++# ++# - flex < 2.5.35 generates an extern that isn't good ++# ++# - flex on RHEL 7 generates code that provokes GCC to warn ++# about comparing a signed value with an unsigned value ++# (Combination of a new GCC and an old flex). ++# Adding one cast makes RHEL 6's GCC unhappy, so we add two. ++# On RHEL 6, i is int and _yybytes_len is int. ++# On RHEL 7, i is int and _yybytes_len is yy_size_t ++# On Fedora 21, i is yy_size_t and _yybytes_len is yy_size_t ++# On some architectures, yy_size_t is wider than int; ++# which makes a mixed comparison OK. ++# ++# Avoid sed -i which somehow causes unwritable files ++# on fedora 20 with 9p filesystem mount. ++# Avoid creating the target file until it is done. + lex.yy.c: parser.l +- cd $(builddir) && $(LEX) -t $(srcdir)/$$(basename $<) | grep -v '^extern int isatty' > $@ ++ cd $(builddir) && \ ++ $(LEX) -o $@.$$$$ $(srcdir)/$$(basename $<) && \ ++ sed -e 's/for ( i = 0; i < _yybytes_len; ++i )$$/for ( i = 0; (yy_size_t)i < (yy_size_t)_yybytes_len; ++i )/' \ ++ -e '/^extern int isatty.*$$/d' $@.$$$$ >SEDTMP$$$$ && \ ++ rm $@.$$$$ && \ ++ mv SEDTMP$$$$ $@ + + # Use wild card rule so that GNU Make knows that both are output from + # a single recipe. + # - sed command for workaround for older bison vs GCC warning + # - avoid sed -i which somehow causes unwritable files + # on fedora 20 with 9p filesystem mount ++# - avoid creating the target file until it is done + %.tab.h %.tab.c: %.y + cd $(builddir) && \ +- $(BISON) ${BISONOSFLAGS} -v -d $(srcdir)/$$(basename $<) && \ ++ $(BISON) ${BISONOSFLAGS} -v --defines=$$(basename $< .y).tab.h -o $$(basename $< .y).tab.c$$$$ $(srcdir)/$$(basename $<) && \ + sed -e '/^ *#/s/if YYENABLE_NLS/if defined(YYENABLE_NLS) \&\& YYENABLE_NLS/' \ + -e '/^ *#/s/if YYLTYPE_IS_TRIVIAL/if defined(YYLTYPE_IS_TRIVIAL) \&\& YYLTYPE_IS_TRIVIAL/' \ +- $$(basename $< .y).tab.c >SEDTMP$$$$ && \ ++ $$(basename $< .y).tab.c$$$$ >SEDTMP$$$$ && \ ++ rm $$(basename $< .y).tab.c$$$$ && \ + mv SEDTMP$$$$ $$(basename $< .y).tab.c + + clean: parser-clean +diff -Naur libreswan-3.15-orig/lib/libipsecconf/parser.l libreswan-3.15/lib/libipsecconf/parser.l +--- libreswan-3.15-orig/lib/libipsecconf/parser.l 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/lib/libipsecconf/parser.l 2015-09-03 11:42:22.942000000 -0400 +@@ -373,7 +373,17 @@ + + [0-9]+ { + /* process a number */ +- yylval.num = strtoul(yytext, NULL, 10); ++ unsigned long val = (errno = 0, strtoul(yytext, NULL, 10)); ++ ++ if (errno != 0 || val > UINT_MAX) { ++ char ebuf[128]; ++ ++ snprintf(ebuf, sizeof(ebuf), ++ "number too large: %s", ++ yytext); ++ yyerror(ebuf); ++ } ++ yylval.num = val; + BEGIN INITIAL; + return INTEGER; + } +diff -Naur libreswan-3.15-orig/lib/libipsecconf/parser.y libreswan-3.15/lib/libipsecconf/parser.y +--- libreswan-3.15-orig/lib/libipsecconf/parser.y 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/lib/libipsecconf/parser.y 2015-09-03 11:42:22.942000000 -0400 +@@ -26,7 +26,7 @@ + #include + #include + #include +- ++#include + #define YYDEBUG 1 + + #include "ipsecconf/keywords.h" +@@ -41,16 +41,15 @@ + * Bison + */ + static char parser_errstring[ERRSTRING_LEN+1]; +-static struct kw_list *alloc_kwlist(void); +-static struct starter_comments *alloc_comment(void); + + /** + * Static Globals + */ +-static int _save_errors_; +-static struct config_parsed *_parser_cfg; +-static struct kw_list **_parser_kw, *_parser_kw_last; +-static struct starter_comments_list *_parser_comments; ++static bool save_errors; ++static struct config_parsed *parser_cfg; ++static struct kw_list **parser_kw, *parser_kw_last; ++static void new_parser_kw(struct keyword *keyword, char *string, unsigned int number); /* forward */ ++static struct starter_comments_list *parser_comments; + + /** + * Functions +@@ -60,7 +59,7 @@ + + %union { + char *s; +- unsigned int num; ++ unsigned int num; + struct keyword k; + } + %token EQUAL FIRST_SPACES EOL CONFIG SETUP CONN INCLUDE VERSION +@@ -72,6 +71,8 @@ + %token BOOLWORD + %token PERCENTWORD + %token COMMENT ++ ++%type duration + %% + + /* +@@ -84,8 +85,8 @@ + /* we have configs shipped with version 2 (INTEGER) and with version 2.0 (STRING, now NUMBER/float was removed */ + + versionstmt: /* NULL */ +- | VERSION STRING EOL blanklines +- | VERSION INTEGER EOL blanklines ++ | VERSION STRING EOL blanklines ++ | VERSION INTEGER EOL blanklines + ; + + blanklines: /* NULL */ +@@ -98,40 +99,40 @@ + + section_or_include: + CONFIG SETUP EOL { +- _parser_kw = &(_parser_cfg->config_setup); +- _parser_kw_last = NULL; +- _parser_comments = &_parser_cfg->comments; ++ parser_kw = &parser_cfg->config_setup; ++ parser_kw_last = NULL; ++ parser_comments = &parser_cfg->comments; + if (yydebug) + fprintf(stderr, "\nconfig setup read\n"); + + } kw_sections + | CONN STRING EOL { +- struct section_list *section; +- section = (struct section_list *)malloc(sizeof(struct section_list)); +- if (section != NULL) { ++ struct section_list *section = malloc(sizeof(struct section_list)); ++ ++ if (section == NULL) { ++ parser_kw = NULL; ++ parser_kw_last = NULL; ++ yyerror("can't allocate memory in section_or_include/conn"); ++ } else { + section->name = $2; + section->kw = NULL; + +- TAILQ_INSERT_TAIL(&_parser_cfg->sections, section, link); ++ TAILQ_INSERT_TAIL(&parser_cfg->sections, section, link); + +- /* setup keyword section to record values */ +- _parser_kw = &(section->kw); +- _parser_kw_last = NULL; ++ /* setup keyword section to record values */ ++ parser_kw = §ion->kw; ++ parser_kw_last = NULL; + + /* and comments */ + TAILQ_INIT(§ion->comments); +- _parser_comments = §ion->comments; ++ parser_comments = §ion->comments; + +- if(yydebug) ++ if (yydebug) + fprintf(stderr, "\nread conn %s\n", section->name); +- } else { +- _parser_kw = NULL; +- _parser_kw_last = NULL; +- yyerror("can't allocate memory in section_or_include/conn"); + } + } kw_sections + | INCLUDE STRING EOL { +- parser_y_include($2); ++ parser_y_include($2); + } + ; + +@@ -144,198 +145,174 @@ + + statement_kw: + KEYWORD EQUAL KEYWORD { +- struct kw_list *new; ++ struct keyword kw = $1; + +- assert(_parser_kw != NULL); +- new = alloc_kwlist(); +- if (new == NULL) { +- yyerror("can't allocate memory in statement_kw"); +- } else { +- struct keyword kw; +- /* because the third argument was also a keyword, we dig up the string representation. */ +- const char *value = $3.keydef->keyname; +- +- kw = $1; +- new->keyword = kw; +- +- switch(kw.keydef->type) { +- case kt_list: +- new->number = parser_enum_list(kw.keydef, value, TRUE); +- break; +- case kt_enum: +- new->number = parser_enum_list(kw.keydef, value, FALSE); +- break; +- case kt_rsakey: +- case kt_loose_enum: +- new->number = parser_loose_enum(&new->keyword, value); +- break; +- case kt_string: +- case kt_appendstring: +- case kt_appendlist: +- case kt_filename: +- case kt_dirname: +- case kt_ipaddr: +- case kt_bitstring: +- case kt_idtype: +- case kt_range: +- case kt_subnet: +- new->string = strdup(value); +- break; +- +- case kt_bool: +- case kt_invertbool: +- case kt_number: +- case kt_time: +- case kt_percent: ++ /* because the third argument was also a keyword, we dig up the string representation. */ ++ const char *value = $3.keydef->keyname; ++ ++ char *string = NULL; /* neutral placeholding value */ ++ unsigned int number = 0; /* neutral placeholding value */ ++ ++ switch(kw.keydef->type) { ++ case kt_list: ++ number = parser_enum_list(kw.keydef, value, TRUE); ++ break; ++ case kt_enum: ++ number = parser_enum_list(kw.keydef, value, FALSE); ++ break; ++ case kt_rsakey: ++ case kt_loose_enum: ++ number = parser_loose_enum(&kw, value); ++ break; ++ case kt_string: ++ case kt_appendstring: ++ case kt_appendlist: ++ case kt_filename: ++ case kt_dirname: ++ case kt_ipaddr: ++ case kt_bitstring: ++ case kt_idtype: ++ case kt_range: ++ case kt_subnet: ++ string = strdup(value); ++ break; ++ ++ case kt_bool: ++ case kt_invertbool: ++ case kt_number: ++ case kt_time: ++ case kt_percent: + yyerror("keyword value is a keyword, but type not a string"); + assert(kw.keydef->type != kt_bool); + break; + +- case kt_comment: +- break; ++ case kt_comment: ++ break; + +- case kt_obsolete: +- case kt_obsolete_quiet: +- break; +- } +- new->next = NULL; +- +- if (_parser_kw_last) +- _parser_kw_last->next = new; +- _parser_kw_last = new; +- if (*_parser_kw == NULL) +- *_parser_kw = new; ++ case kt_obsolete: ++ case kt_obsolete_quiet: ++ break; + } ++ ++ new_parser_kw(&kw, string, number); + } + | COMMENT EQUAL STRING { +- struct starter_comments *new; ++ struct starter_comments *new = ++ malloc(sizeof(struct starter_comments)); + +- new = alloc_comment(); + if (new == NULL) { +- yyerror("can't allocate memory in statement_kw"); ++ yyerror("can't allocate memory in statement_kw"); + } else { +- new->x_comment = strdup($1.string); +- new->commentvalue = strdup($3); +- TAILQ_INSERT_TAIL(_parser_comments, new, link); ++ new->x_comment = strdup($1.string); ++ new->commentvalue = strdup($3); ++ TAILQ_INSERT_TAIL(parser_comments, new, link); + } + } + | KEYWORD EQUAL STRING { +- struct kw_list *new; ++ struct keyword kw = $1; + +- assert(_parser_kw != NULL); +- new = alloc_kwlist(); +- if (new == NULL) { +- yyerror("can't allocate memory in statement_kw"); +- } else { +- struct keyword kw; ++ char *string = NULL; /* neutral placeholding value */ ++ unsigned int number = 0; /* neutral placeholding value */ + +- kw = $1; +- new->keyword = kw; ++ switch(kw.keydef->type) { ++ case kt_list: ++ number = parser_enum_list(kw.keydef, $3, TRUE); ++ break; ++ case kt_enum: ++ number = parser_enum_list(kw.keydef, $3, FALSE); ++ break; ++ case kt_rsakey: ++ case kt_loose_enum: ++ number = parser_loose_enum(&kw, $3); ++ break; ++ case kt_string: ++ case kt_appendstring: ++ case kt_appendlist: ++ case kt_filename: ++ case kt_dirname: ++ case kt_ipaddr: ++ case kt_bitstring: ++ case kt_idtype: ++ case kt_range: ++ case kt_subnet: ++ string = $3; ++ break; + +- switch(kw.keydef->type) { +- case kt_list: +- new->number = parser_enum_list(kw.keydef, $3, TRUE); +- break; +- case kt_enum: +- new->number = parser_enum_list(kw.keydef, $3, FALSE); +- break; +- case kt_rsakey: +- case kt_loose_enum: +- new->number = parser_loose_enum(&new->keyword, $3); +- break; +- case kt_string: +- case kt_appendstring: +- case kt_appendlist: +- case kt_filename: +- case kt_dirname: +- case kt_ipaddr: +- case kt_bitstring: +- case kt_idtype: +- case kt_range: +- case kt_subnet: +- new->string = $3; +- break; +- +- case kt_bool: +- case kt_invertbool: +- case kt_number: +- case kt_time: +- case kt_percent: ++ case kt_bool: ++ case kt_invertbool: ++ case kt_number: ++ case kt_time: ++ case kt_percent: + yyerror("valid keyword, but value is not a number"); +- assert(!(kw.keydef->type == kt_bool)); ++ assert(kw.keydef->type != kt_bool); ++ break; ++ case kt_comment: ++ break; ++ case kt_obsolete: ++ case kt_obsolete_quiet: + break; +- case kt_comment: +- break; +- case kt_obsolete: +- case kt_obsolete_quiet: +- break; +- } +- new->next = NULL; +- +- if (_parser_kw_last) +- _parser_kw_last->next = new; +- _parser_kw_last = new; +- if (!*_parser_kw) *_parser_kw = new; + } ++ ++ new_parser_kw(&kw, string, number); + } + + | BOOLWORD EQUAL BOOL { +- struct kw_list *new; +- +- assert(_parser_kw != NULL); +- new = alloc_kwlist(); +- if (new == NULL) { +- yyerror("can't allocate memory in statement_kw"); +- } else { +- new->keyword = $1; +- new->number = $3; /* Should not be necessary! */ +- new->next = NULL; +- if (_parser_kw_last) +- _parser_kw_last->next = new; +- _parser_kw_last = new; +- if (!*_parser_kw) *_parser_kw = new; +- } ++ new_parser_kw(&$1, NULL, $3); + } + | KEYWORD EQUAL INTEGER { +- struct kw_list *new; +- +- assert(_parser_kw != NULL); +- new = alloc_kwlist(); +- if (new == NULL) { +- yyerror("can't allocate memory in statement_kw"); +- } else { +- new->keyword = $1; +- new->number = $3; /* Should not be necessary! */ +- new->next = NULL; +- if (_parser_kw_last) +- _parser_kw_last->next = new; +- _parser_kw_last = new; +- if (!*_parser_kw) *_parser_kw = new; +- } ++ new_parser_kw(&$1, NULL, $3); + } +- | TIMEWORD EQUAL STRING { +- struct kw_list *new; +- char *endptr, *str; +- unsigned int val; ++ | TIMEWORD EQUAL duration { ++ new_parser_kw(&$1, NULL, $3); ++ } ++ | PERCENTWORD EQUAL STRING { + struct keyword kw = $1; +- bool fail; +- char buf[80]; +- +- +- fail = FALSE; +- +- str = $3; +- +- val = strtoul(str, &endptr, 10); +- +- if(endptr == str) { +- snprintf(buf, sizeof(buf), "bad duration value %s=%s", kw.keydef->keyname, str); +- yyerror(buf); +- fail = TRUE; ++ const char *const str = $3; ++ /*const*/ char *endptr; ++ char buf[80]; ++ unsigned long val = (errno = 0, strtoul(str, &endptr, 10)); ++ ++ if (endptr == str) { ++ snprintf(buf, sizeof(buf), ++ "malformed percentage %s=%s", ++ kw.keydef->keyname, str); ++ yyerror(buf); ++ } else if (*endptr != '%' || endptr[1] != '\0') { ++ snprintf(buf, sizeof(buf), ++ "bad percentage multiplier \"%s\" on %s", ++ endptr, str); ++ yyerror(buf); ++ } else if (errno != 0 || val > UINT_MAX) { ++ snprintf(buf, sizeof(buf), ++ "percentage way too large \"%s\"", str); ++ yyerror(buf); ++ } else { ++ new_parser_kw(&kw, NULL, (unsigned int)val); + } ++ } ++ | KEYWORD EQUAL BOOL { ++ new_parser_kw(&$1, NULL, $3); ++ } ++ | KEYWORD EQUAL { /* this is meaningless, we ignore it */ } ++ ; + +- if(!fail) +- { ++duration: ++ INTEGER { ++ $$ = $1; ++ } ++ | STRING { ++ const char *const str = $1; ++ /*const*/ char *endptr; ++ char buf[80]; ++ ++ unsigned long val = (errno = 0, strtoul(str, &endptr, 10)); ++ int strtoul_errno = errno; ++ ++ if (endptr == str) { ++ snprintf(buf, sizeof(buf), "bad duration value \"%s\"", str); ++ yyerror(buf); ++ } else { ++ bool bad_suffix = FALSE; + unsigned scale; + + if (*endptr == '\0') { +@@ -350,194 +327,87 @@ + case 'd': scale = secs_per_day; break; + case 'w': scale = 7*secs_per_day; break; + default: +- snprintf(buf, sizeof(buf), +- "bad duration multiplier '%c' on %s", +- *endptr, str); +- yyerror(buf); +- fail=TRUE; ++ bad_suffix = TRUE; + } + } else { ++ bad_suffix = TRUE; ++ } ++ ++ if (bad_suffix) { + snprintf(buf, sizeof(buf), + "bad duration multiplier \"%s\" on %s", + endptr, str); + yyerror(buf); +- fail=TRUE; +- } +- +- if (!fail) { +- if (UINT_MAX / scale < val) { +- snprintf(buf, sizeof(buf), +- "overflow scaling %s", +- str); +- yyerror(buf); +- fail=TRUE; +- } else { +- val *= scale; +- } ++ } else if (strtoul_errno != 0 || UINT_MAX / scale < val) { ++ snprintf(buf, sizeof(buf), ++ "duration too large: \"%s\" is more than %u seconds", ++ str, UINT_MAX); ++ yyerror(buf); ++ } else { ++ $$ = val * scale; + } +- } +- +- if(!fail) +- { +- assert(_parser_kw != NULL); +- new = alloc_kwlist(); +- if (new == NULL) { +- yyerror("can't allocate memory in statement_kw"); +- } else { +- new->keyword = $1; +- new->number = val; +- new->next = NULL; +- if (_parser_kw_last) +- _parser_kw_last->next = new; +- _parser_kw_last = new; +- if (*_parser_kw == NULL) +- *_parser_kw = new; +- } +- } +- } +- | PERCENTWORD EQUAL STRING { +- struct kw_list *new; +- char *endptr, *str; +- struct keyword kw = $1; +- unsigned int val; +- bool fail; +- char buf[80]; +- +- +- fail = FALSE; +- +- str = $3; +- +- val = strtoul(str, &endptr, 10); +- +- if(endptr == str) { +- snprintf(buf, sizeof(buf), "bad percent value %s=%s", kw.keydef->keyname, str); +- yyerror(buf); +- fail = TRUE; +- +- } +- +- if(!fail) +- { +- if ((*endptr == '%') && (endptr[1] == '\0')) { } +- else { +- snprintf(buf, sizeof(buf), "bad percentage multiplier '%c' on %s", *endptr, str); +- yyerror(buf); +- fail=TRUE; +- } +- } +- +- if(!fail) +- { +- assert(_parser_kw != NULL); +- new = alloc_kwlist(); +- if (new == NULL) { +- yyerror("can't allocate memory in statement_kw"); +- } else { +- new->keyword = $1; +- new->number = val; +- new->next = NULL; +- if (_parser_kw_last) +- _parser_kw_last->next = new; +- _parser_kw_last = new; +- if (*_parser_kw == NULL) +- *_parser_kw = new; +- } +- } +- } +- | KEYWORD EQUAL BOOL { +- struct kw_list *new; +- +- assert(_parser_kw != NULL); +- new = alloc_kwlist(); +- if (new != NULL) { +- yyerror("can't allocate memory in statement_kw"); +- } else { +- new->keyword = $1; +- new->number = $3; /* Should not be necessary! */ +- new->next = NULL; +- if (_parser_kw_last) +- _parser_kw_last->next = new; +- _parser_kw_last = new; +- if (*_parser_kw == NULL) +- *_parser_kw = new; + } +- } +- | KEYWORD EQUAL { /* this is meaningless, we ignore it */ } +- ; +- ++ }; + %% + + void yyerror(const char *s) + { +- if (_save_errors_) ++ if (save_errors) + parser_y_error(parser_errstring, ERRSTRING_LEN, s); + } + + struct config_parsed *parser_load_conf(const char *file, err_t *perr) + { +- struct config_parsed *cfg=NULL; +- int err = 0; +- FILE *f; +- +- zero(&parser_errstring); ++ parser_errstring[0] = '\0'; + if (perr != NULL) + *perr = NULL; + +- cfg = (struct config_parsed *)malloc(sizeof(struct config_parsed)); +- if (cfg == NULL) +- { +- snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory"); +- err++; +- goto end; ++ struct config_parsed *cfg = malloc(sizeof(struct config_parsed)); ++ ++ if (cfg == NULL) { ++ snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory"); ++ goto err; + } + zero(cfg); /* ??? pointer fields may not be NULLed */ +- if (strncmp(file, "-", sizeof("-")) == 0) { +- f = fdopen(STDIN_FILENO, "r"); +- } +- else { +- f = fopen(file, "r"); +- } +- if (!f) +- { +- snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", +- file); +- err++; +- goto end; ++ ++ FILE *f = streq(file, "-") ? ++ fdopen(STDIN_FILENO, "r") : fopen(file, "r"); ++ ++ if (f == NULL) { ++ snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", ++ file); ++ goto err; + } + + yyin = f; + parser_y_init(file, f); +- _save_errors_=1; ++ save_errors = TRUE; + TAILQ_INIT(&cfg->sections); + TAILQ_INIT(&cfg->comments); +- _parser_cfg = cfg; ++ parser_cfg = cfg; + +- if (yyparse()!=0) { +- if (parser_errstring[0]=='\0') { +- snprintf(parser_errstring, ERRSTRING_LEN, +- "Unknown error..."); +- } +- _save_errors_=0; +- while (yyparse()!=0); +- err++; +- goto end; +- } +- if (parser_errstring[0]!='\0') { +- err++; +- goto end; +- } +- /** +- * Config valid +- */ +-end: +- if (err) { +- if (perr) *perr = (err_t)strdup(parser_errstring); +- if (cfg) parser_free_conf (cfg); +- cfg = NULL; ++ if (yyparse() != 0) { ++ if (parser_errstring[0] == '\0') { ++ snprintf(parser_errstring, ERRSTRING_LEN, ++ "Unknown error..."); ++ } ++ save_errors = FALSE; ++ do {} while (yyparse() != 0); ++ } else if (parser_errstring[0] == '\0') { ++ /** ++ * Config valid ++ */ ++ return cfg; + } ++ /* falls through on error */ ++ ++err: ++ if (perr != NULL) ++ *perr = (err_t)strdup(parser_errstring); ++ if (cfg != NULL) ++ parser_free_conf(cfg); + +- return cfg; ++ return NULL; + } + + static void parser_free_kwlist(struct kw_list *list) +@@ -546,7 +416,7 @@ + struct kw_list *elt = list; + + list = list->next; +- if (elt->string) ++ if (elt->string != NULL) + free(elt->string); + free(elt); + } +@@ -554,16 +424,18 @@ + + void parser_free_conf(struct config_parsed *cfg) + { +- struct section_list *seci, *sec; +- if (cfg) { ++ if (cfg != NULL) { ++ struct section_list *seci; ++ + parser_free_kwlist(cfg->config_setup); + +- for(seci = cfg->sections.tqh_first; seci != NULL; ) +- { +- sec = seci; ++ for (seci = cfg->sections.tqh_first; seci != NULL; ) { ++ struct section_list *sec = seci; ++ + seci = seci->link.tqe_next; + +- if (sec->name) free(sec->name); ++ if (sec->name != NULL) ++ free(sec->name); + parser_free_kwlist(sec->kw); + free(sec); + } +@@ -572,20 +444,32 @@ + } + } + +-static struct kw_list *alloc_kwlist(void) ++static void new_parser_kw(struct keyword *keyword, char *string, unsigned int number) + { +- struct kw_list *new; +- +- new = (struct kw_list *)malloc(sizeof(struct kw_list)); +- zero(new); /* ??? pointer members might not be set to NULL */ +- return new; +-} ++ struct kw_list *new = malloc(sizeof(struct kw_list)); + +-static struct starter_comments *alloc_comment(void) +-{ +- struct starter_comments *new; ++ if (new == NULL) { ++ yyerror("cannot allocate memory for a kw_list"); ++ } else { ++ /* ++ * fill the values into new ++ * (either string or number might have a placeholder value ++ */ ++ new->keyword = *keyword; ++ new->string = string; ++ new->number = number; ++ new->next = NULL; ++ ++ /* link the new kw_list into the list */ ++ ++ if (*parser_kw == NULL) ++ *parser_kw = new; /* first in (some) list */ ++ ++ /* connect to previous last on list */ ++ if (parser_kw_last != NULL) ++ parser_kw_last->next = new; + +- new = (struct starter_comments *)malloc(sizeof(struct starter_comments)); +- zero(new); /* ??? pointer members might not be set to NULL */ +- return new; ++ /* new is new last on list */ ++ parser_kw_last = new; ++ } + } diff --git a/SOURCES/libreswan-3.15-ikev1-pam.patch b/SOURCES/libreswan-3.15-ikev1-pam.patch new file mode 100644 index 0000000..178fe26 --- /dev/null +++ b/SOURCES/libreswan-3.15-ikev1-pam.patch @@ -0,0 +1,263 @@ +diff -Naur libreswan-3.15-orig/programs/pluto/ikev1_xauth.c libreswan-3.15/programs/pluto/ikev1_xauth.c +--- libreswan-3.15-orig/programs/pluto/ikev1_xauth.c 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/programs/pluto/ikev1_xauth.c 2015-09-03 11:32:27.525000000 -0400 +@@ -1001,81 +1001,6 @@ + return STF_OK; + } + +-#ifdef XAUTH_HAVE_PAM +- +-/** Do authentication via PAM (Plugable Authentication Modules) +- * +- * We try to authenticate the user in our own PAM session. +- * +- * @return bool success +- */ +-/* IN AN AUTH THREAD */ +-static bool do_pam_authentication(void *varg) +-{ +- struct xauth_thread_arg *arg = varg; +- int retval; +- pam_handle_t *pamh = NULL; +- struct pam_conv conv; +- const char *what; +- +- /* This do-while structure is designed to allow a logical cascade +- * without excessive indentation. No actual looping happens. +- * Failure is handled by "break". +- */ +- do { +- ipstr_buf ra; +- +- conv.conv = pam_conv; +- conv.appdata_ptr = varg; +- +- what = "pam_start"; +- retval = pam_start("pluto", arg->name, &conv, &pamh); +- if (retval != PAM_SUCCESS) +- break; +- +- DBG(DBG_CONTROL, DBG_log("pam_start SUCCESS")); +- +- /* Send the remote host address to PAM */ +- what = "pam_set_item"; +- retval = pam_set_item(pamh, PAM_RHOST, +- ipstr(&arg->st->st_remoteaddr, &ra)); +- if (retval != PAM_SUCCESS) +- break; +- +- DBG(DBG_CONTROL, DBG_log("pam_set_item SUCCESS")); +- +- /* Two factor authentication - Check that the user is valid, +- * and then check if they are permitted access +- */ +- what = "pam_authenticate"; +- retval = pam_authenticate(pamh, PAM_SILENT); /* is user really user? */ +- +- if (retval != PAM_SUCCESS) +- break; +- +- DBG(DBG_CONTROL, DBG_log("pam_authenticate SUCCESS")); +- +- what = "pam_acct_mgmt"; +- retval = pam_acct_mgmt(pamh, 0); /* permitted access? */ +- if (retval != PAM_SUCCESS) +- break; +- +- /* success! */ +- libreswan_log("XAUTH: PAM_SUCCESS"); +- pam_end(pamh, PAM_SUCCESS); +- return TRUE; +- } while (FALSE); +- +- /* common failure code */ +- +- DBG(DBG_CONTROL, +- DBG_log("%s failed with '%s", what, pam_strerror(pamh, retval))); +- libreswan_log("XAUTH: %s failed with '%s'", what, pam_strerror(pamh, retval)); +- pam_end(pamh, retval); +- return FALSE; +-} +-#endif /* XAUTH_HAVE_PAM */ +- + /** Do authentication via /etc/ipsec.d/passwd file using MD5 passwords + * + * Structure is one entry per line. +@@ -1256,6 +1181,43 @@ + return win; + } + ++/* IN AN AUTH THREAD */ ++static bool ikev1_do_pam_authentication(const struct xauth_thread_arg *arg) ++{ ++ struct state *st = arg->st; ++ libreswan_log("XAUTH: pam authentication being called to authenticate user %s", ++ arg->name); ++ struct pam_thread_arg parg; ++ ipstr_buf ra; ++ struct timeval start_time; ++ struct timeval served_time; ++ struct timeval served_delta; ++ bool results = FALSE; ++ ++ parg.name = arg->name; ++ parg.password = arg->password; ++ parg.c_name = arg->connname; ++ parg.ra = clone_str(ipstr(&st->st_remoteaddr, &ra), "st remote address"); ++ parg.st_serialno = st->st_serialno; ++ parg.c_instance_serial = st->st_connection->instance_serial; ++ parg.atype = "XAUTH"; ++ gettimeofday(&start_time, NULL); ++ results = do_pam_authentication(&parg); ++ gettimeofday(&served_time, NULL); ++ timersub(&served_time, &start_time, &served_delta); ++ DBG(DBG_CONTROL, DBG_log("XAUTH PAM helper thread call " ++ "state #%lu, %s[%lu] user=%s %s. " ++ "elapsed time %lu.%06lu", ++ parg.st_serialno, parg.c_name, ++ parg.c_instance_serial, parg.name, ++ results ? "SUCCESS" : "FAIL", ++ (unsigned long)served_delta.tv_sec, ++ (unsigned long)(served_delta.tv_usec * 1000000))); ++ ++ pfreeany(parg.ra); ++ return (results); ++} ++ + /* + * Main authentication routine will then call the actual compiled-in + * method to verify the user/password +@@ -1330,10 +1292,7 @@ + switch (st->st_connection->xauthby) { + #ifdef XAUTH_HAVE_PAM + case XAUTHBY_PAM: +- libreswan_log( +- "XAUTH: pam authentication being called to authenticate user %s", +- arg->name); +- results = do_pam_authentication(varg); ++ results = ikev1_do_pam_authentication(arg); + break; + #endif + case XAUTHBY_FILE: +diff -Naur libreswan-3.15-orig/programs/pluto/ikev2_parent.c libreswan-3.15/programs/pluto/ikev2_parent.c +--- libreswan-3.15-orig/programs/pluto/ikev2_parent.c 2015-09-03 11:29:05.518000000 -0400 ++++ libreswan-3.15/programs/pluto/ikev2_parent.c 2015-09-03 11:32:27.526000000 -0400 +@@ -2417,7 +2417,7 @@ + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + pthread_setcancelstate (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + +- p->pam_status = ikev2_do_pam_authentication(&p->pam); ++ p->pam_status = do_pam_authentication(&p->pam); + gettimeofday(&p->done_time, NULL); + timersub(&p->done_time, &p->start_time, &done_delta); + +@@ -2580,6 +2580,7 @@ + p->pam.ra = clone_str(ipstr(&st->st_remoteaddr, &ra), "st remote address"); + p->pam.c_instance_serial = st->st_connection->instance_serial; + p->pam.st_serialno = st->st_serialno; ++ p->pam.atype = "IKEv2"; + + p->next = pluto_v2_pam_helpers; + pluto_v2_pam_helpers = p; +diff -Naur libreswan-3.15-orig/programs/pluto/pam_conv.c libreswan-3.15/programs/pluto/pam_conv.c +--- libreswan-3.15-orig/programs/pluto/pam_conv.c 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/programs/pluto/pam_conv.c 2015-09-03 11:32:27.526000000 -0400 +@@ -10,7 +10,7 @@ + * Copyright (C) 2012-2013 Paul Wouters + * Copyright (C) 2012-2013 Philippe Vouters + * Copyright (C) 2013 David McCullough +- * Copyright (C) 2013 Antony Antony ++ * Copyright (C) 2013-2015 Antony Antony + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the +@@ -109,15 +109,25 @@ + return PAM_SUCCESS; + } + ++static void log_pam_step(const struct pam_thread_arg *arg, const char *what, ++ const char *how) ++{ ++ DBG(DBG_CONTROL, DBG_log("%s helper thread %s %s for " ++ "state #%lu, %s[%lu] user=%s.", ++ arg->atype, what, how, ++ arg->st_serialno, arg->c_name, ++ arg->c_instance_serial, arg->name)); ++ ++} ++ + /* + * Do IKEv2 second authentication via PAM (Plugable Authentication Modules) + * + * @return bool success + */ + /* IN AN AUTH THREAD */ +-bool ikev2_do_pam_authentication(void *varg) ++bool do_pam_authentication(struct pam_thread_arg *arg) + { +- struct pam_thread_arg *arg = varg; + int retval; + pam_handle_t *pamh = NULL; + struct pam_conv conv; +@@ -129,22 +139,20 @@ + */ + do { + conv.conv = pam_conv; +- conv.appdata_ptr = varg; ++ conv.appdata_ptr = arg; + + what = "pam_start"; + retval = pam_start("pluto", arg->name, &conv, &pamh); + if (retval != PAM_SUCCESS) + break; +- +- DBG(DBG_CONTROL, DBG_log("pam_start SUCCESS")); ++ log_pam_step(arg, what, "SUCCESS"); + + /* Send the remote host address to PAM */ + what = "pam_set_item"; + retval = pam_set_item(pamh, PAM_RHOST, arg->ra); + if (retval != PAM_SUCCESS) + break; +- +- DBG(DBG_CONTROL, DBG_log("pam_set_item SUCCESS")); ++ log_pam_step(arg, what, "SUCCESS"); + + /* Two factor authentication - Check that the user is valid, + * and then check if they are permitted access +@@ -154,16 +162,16 @@ + + if (retval != PAM_SUCCESS) + break; ++ log_pam_step(arg, what, "SUCCESS"); + +- DBG(DBG_CONTROL, DBG_log("pam_authenticate SUCCESS")); +- +- what = "pam_acct_mgmt"; + retval = pam_acct_mgmt(pamh, 0); /* permitted access? */ + if (retval != PAM_SUCCESS) + break; + ++ what = "pam"; ++ log_pam_step(arg, what, "SUCCESS"); ++ + /* success! */ +- libreswan_log("IKEv2: PAM_SUCCESS"); + pam_end(pamh, PAM_SUCCESS); + return TRUE; + } while (FALSE); +diff -Naur libreswan-3.15-orig/programs/pluto/pam_conv.h libreswan-3.15/programs/pluto/pam_conv.h +--- libreswan-3.15-orig/programs/pluto/pam_conv.h 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/programs/pluto/pam_conv.h 2015-09-03 11:32:27.527000000 -0400 +@@ -23,9 +23,10 @@ + char *ra; + so_serial_t st_serialno; + unsigned long c_instance_serial; ++ char *atype; /* string XAUTH or IKEv2 */ + }; + +-extern bool ikev2_do_pam_authentication(void *varg); ++extern bool do_pam_authentication(struct pam_thread_arg *arg); + int pam_conv(int num_msg, const struct pam_message **msgm, + struct pam_response **response, void + *appdata_ptr); diff --git a/SOURCES/libreswan-3.15-migration.patch b/SOURCES/libreswan-3.15-migration.patch new file mode 100644 index 0000000..0b3c664 --- /dev/null +++ b/SOURCES/libreswan-3.15-migration.patch @@ -0,0 +1,20 @@ +diff -Naur libreswan-3.15-orig/lib/libipsecconf/keywords.c libreswan-3.15/lib/libipsecconf/keywords.c +--- libreswan-3.15-orig/lib/libipsecconf/keywords.c 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/lib/libipsecconf/keywords.c 2015-09-24 12:52:54.377592510 -0400 +@@ -342,6 +342,8 @@ + { "interfaces", kv_config, kt_string, KSF_INTERFACES, NOT_ENUM }, + { "curl-iface", kv_config, kt_string, KSF_CURLIFACE, NOT_ENUM }, + { "curl-timeout", kv_config, kt_number, KBF_CURLTIMEOUT, NOT_ENUM }, ++ { "curl_iface", kv_config | kv_alias, kt_string, KSF_CURLIFACE, NOT_ENUM }, ++ { "curl_timeout", kv_config | kv_alias, kt_number, KBF_CURLTIMEOUT, NOT_ENUM }, + { "myid", kv_config, kt_string, KSF_MYID, NOT_ENUM }, + { "myvendorid", kv_config, kt_string, KSF_MYVENDORID, NOT_ENUM }, + { "syslog", kv_config, kt_string, KSF_SYSLOG, NOT_ENUM }, +@@ -383,6 +385,7 @@ + { "ocsp-trustname", kv_config, kt_string, KSF_OCSPTRUSTNAME, NOT_ENUM }, + { "crlcheckinterval", kv_config, kt_time, KBF_CRLCHECKINTERVAL, NOT_ENUM }, + { "crl_strict", kv_config | kv_alias, kt_bool, KBF_STRICTCRLPOLICY, NOT_ENUM }, /* obsolete _ */ ++ { "strictcrlpolicy", kv_config | kv_alias, kt_bool, KBF_STRICTCRLPOLICY, NOT_ENUM }, /* obsolete used on openswan */ + { "ocsp_strict", kv_config | kv_alias, kt_bool, KBF_STRICTOCSPPOLICY, NOT_ENUM }, /* obsolete _ */ + { "ocsp_enable", kv_config | kv_alias, kt_bool, KBF_OCSPENABLE, NOT_ENUM }, /* obsolete _ */ + { "ocsp_uri", kv_config | kv_alias, kt_string, KSF_OCSPURI, NOT_ENUM }, /* obsolete _ */ diff --git a/SOURCES/libreswan-3.15-newest-labeled.patch b/SOURCES/libreswan-3.15-newest-labeled.patch new file mode 100644 index 0000000..f2c1e42 --- /dev/null +++ b/SOURCES/libreswan-3.15-newest-labeled.patch @@ -0,0 +1,13 @@ +diff -Naur libreswan-3.15-orig/programs/pluto/ikev1_main.c libreswan-3.15/programs/pluto/ikev1_main.c +--- libreswan-3.15-orig/programs/pluto/ikev1_main.c 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/programs/pluto/ikev1_main.c 2015-09-03 11:57:52.632000000 -0400 +@@ -3011,6 +3011,9 @@ + dst); + + if (rc->newest_ipsec_sa == dst->st_serialno && ++#ifdef HAVE_LABELED_IPSEC ++ dst->sec_ctx == NULL && ++#endif + (rc->policy & POLICY_UP)) { + /* + * Last IPsec SA for a permanent diff --git a/SOURCES/libreswan-3.15-racoon-padding.patch b/SOURCES/libreswan-3.15-racoon-padding.patch new file mode 100644 index 0000000..114fa0d --- /dev/null +++ b/SOURCES/libreswan-3.15-racoon-padding.patch @@ -0,0 +1,86 @@ +diff --git a/programs/pluto/ikev2_parent.c b/programs/pluto/ikev2_parent.c +index 28e93b0..cc033aa 100644 +--- a/programs/pluto/ikev2_parent.c ++++ b/programs/pluto/ikev2_parent.c +@@ -1601,16 +1601,21 @@ static stf_status ikev2_verify_and_decrypt_sk_payload(struct msg_digest *md, + size_t enc_size = integ_start - enc_start; + + /* +- * Check if block-size is valid. Do this before the payload's +- * integrity has been verified as block-alignment requirements +- * aren't exactly secret (originally this was being done +- * beteen integrity and decrypt). ++ * Check that the payload is block-size aligned. ++ * ++ * Per rfc7296 "the recipient MUST accept any length that ++ * results in proper alignment". ++ * ++ * Do this before the payload's integrity has been verified as ++ * block-alignment requirements aren't exactly secret ++ * (originally this was being done between integrity and ++ * decrypt). + */ + size_t enc_blocksize = pst->st_oakley.encrypter->enc_blocksize; + bool pad_to_blocksize = pst->st_oakley.encrypter->pad_to_blocksize; + if (pad_to_blocksize) { + if (enc_size % enc_blocksize != 0) { +- libreswan_log("cyphertext length (%zu) not a multiple of blocksize (%zu)", ++ libreswan_log("discarding invalid packet: %zu octet payload length is not a multiple of encryption block-size (%zu)", + enc_size, enc_blocksize); + return STF_FAIL; + } +@@ -1707,17 +1712,47 @@ static stf_status ikev2_verify_and_decrypt_sk_payload(struct msg_digest *md, + enc_start, enc_size + integ_size)); + } + +- +- u_char padlen = enc_start[enc_size - 1] + 1; +- if (padlen > enc_blocksize || padlen > enc_size) { +- libreswan_log("invalid padding-length octet: 0x%2x", padlen - 1); ++ /* ++ * Check the padding. ++ * ++ * Per rfc7296 "The sender SHOULD set the Pad Length to the ++ * minimum value that makes the combination of the payloads, ++ * the Padding, and the Pad Length a multiple of the block ++ * size, but the recipient MUST accept any length that results ++ * in proper alignment." ++ * ++ * Notice the "should". RACOON, for instance, sends extra ++ * blocks of padding that contain random bytes. ++ */ ++ u_int8_t padlen = enc_start[enc_size - 1] + 1; ++ if (padlen > enc_size) { ++ libreswan_log("discarding invalid packet: padding-length %u (octet 0x%02x) is larger than %zu octet payload length", ++ padlen, padlen - 1, enc_size); + return STF_FAIL; + } ++ if (pad_to_blocksize) { ++ if (padlen > enc_blocksize) { ++ /* probably racoon */ ++ DBG(DBG_CRYPT, ++ DBG_log("payload contains %zu blocks of extra padding (padding-length: %d (octet 0x%2x), encryption block-size: %zu)", ++ (padlen - 1) / enc_blocksize, ++ padlen, padlen - 1, enc_blocksize)); ++ } ++ } else { ++ if (padlen > 1) { ++ DBG(DBG_CRYPT, ++ DBG_log("payload contains %u octets of extra padding (padding-length: %u (octet 0x%2x))", ++ padlen - 1, padlen, padlen - 1)); ++ } ++ } + +- /* don't bother to check any other pad octets */ +- DBG(DBG_CRYPT, DBG_log("striping %u bytes as pad", padlen)); +- ++ /* ++ * Don't check the contents of the pad octets; racoon, for ++ * instance, sets them to random values. ++ */ ++ DBG(DBG_CRYPT, DBG_log("stripping %u octets as pad", padlen)); + setchunk(*chunk, enc_start, enc_size - padlen); ++ + return STF_OK; + } + diff --git a/SOURCES/libreswan-3.15-s90-gcc.patch b/SOURCES/libreswan-3.15-s90-gcc.patch new file mode 100644 index 0000000..309e3da --- /dev/null +++ b/SOURCES/libreswan-3.15-s90-gcc.patch @@ -0,0 +1,28 @@ +diff --git a/programs/pluto/ikev2_parent.c b/programs/pluto/ikev2_parent.c +index 8fd0bba..db890f5 100644 +--- a/programs/pluto/ikev2_parent.c ++++ b/programs/pluto/ikev2_parent.c +@@ -1596,8 +1596,8 @@ static stf_status ikev2_verify_and_decrypt_sk_payload(struct msg_digest *md, + */ + u_char *payload_end = chunk->ptr + chunk->len; + if (payload_end < (wire_iv_start + wire_iv_size + 1 + integ_size)) { +- libreswan_log("encrypted payload impossibly short (%zu)", +- payload_end - wire_iv_start); ++ libreswan_log("encrypted payload impossibly short (%tu)", ++ payload_end - wire_iv_start); + return STF_FAIL; + } + +@@ -4105,9 +4105,9 @@ stf_status process_encrypted_informational_ikev2(struct msg_digest *md) + } + + if (v2del->isad_nrspi * v2del->isad_spisize != pbs_left(&p->pbs)) { +- libreswan_log("IPsec Delete Notification payload size is %tu but %u is required", +- pbs_left(&p->pbs), +- v2del->isad_nrspi * v2del->isad_spisize); ++ libreswan_log("IPsec Delete Notification payload size is %lu but %lu is required", ++ (long unsigned int) pbs_left(&p->pbs), ++ (long unsigned int) (v2del->isad_nrspi * v2del->isad_spisize)); + return STF_FAIL + v2N_INVALID_SYNTAX; + } + diff --git a/SOURCES/libreswan-3.15-seeddev.patch b/SOURCES/libreswan-3.15-seeddev.patch new file mode 100644 index 0000000..1492a56 --- /dev/null +++ b/SOURCES/libreswan-3.15-seeddev.patch @@ -0,0 +1,13 @@ +diff --git a/programs/newhostkey/newhostkey.in b/programs/newhostkey/newhostkey.in +index a25583e..31226c2 100755 +--- a/programs/newhostkey/newhostkey.in ++++ b/programs/newhostkey/newhostkey.in +@@ -24,7 +24,7 @@ usage="Usage: $me [--output filename] [--seeddev device] [--bits n] \\ + bits= + verbose= + host= +-seeddev="--seeddev /dev/seeddev" ++seeddev="--seeddev /dev/random" + output="@FINALCONFDIR@/ipsec.secrets" + configdir="@FINALNSSDIR@" + password= diff --git a/SOURCES/libreswan-3.15-trafficstatus.patch b/SOURCES/libreswan-3.15-trafficstatus.patch new file mode 100644 index 0000000..90712de --- /dev/null +++ b/SOURCES/libreswan-3.15-trafficstatus.patch @@ -0,0 +1,96 @@ +diff -Naur libreswan-3.15-orig/programs/pluto/state.c libreswan-3.15/programs/pluto/state.c +--- libreswan-3.15-orig/programs/pluto/state.c 2015-08-24 16:52:43.000000000 -0400 ++++ libreswan-3.15/programs/pluto/state.c 2015-09-04 09:31:28.815818376 -0400 +@@ -1652,21 +1652,20 @@ + char *mbcp = traffic_buf + snprintf(traffic_buf, + sizeof(traffic_buf) - 1, ", type=%s, add_time=%" PRIu64, mode, st->st_esp.add_time); + +- if (get_sa_info(st, TRUE, NULL)) { ++ if (get_sa_info(st, FALSE, NULL)) { + size_t buf_len = traffic_buf + sizeof(traffic_buf) - mbcp; +- u_int inb = st->st_esp.present ? st->st_esp.peer_bytes : ++ u_int outb = st->st_esp.present ? st->st_esp.peer_bytes : + st->st_ah.present ? st->st_ah.peer_bytes : + st->st_ipcomp.present ? st->st_ipcomp.peer_bytes : 0; +- +- mbcp += snprintf(mbcp, buf_len - 1, ", inBytes=%u", inb); ++ mbcp += snprintf(mbcp, buf_len - 1, ", outBytes=%u", outb); + } +- if (get_sa_info(st, FALSE, NULL)) { ++ ++ if (get_sa_info(st, TRUE, NULL)) { + size_t buf_len = traffic_buf + sizeof(traffic_buf) - mbcp; +- u_int outb = st->st_esp.present ? st->st_esp.our_bytes : ++ u_int inb = st->st_esp.present ? st->st_esp.our_bytes: + st->st_ah.present ? st->st_ah.our_bytes : + st->st_ipcomp.present ? st->st_ipcomp.our_bytes : 0; +- +- snprintf(mbcp, buf_len - 1, ", outBytes=%u", outb); ++ snprintf(mbcp, buf_len - 1, ", inBytes=%u", inb); + } + } + +@@ -1815,7 +1814,7 @@ + mbcp, + traffic_buf + + sizeof(traffic_buf), +- " AHin="); ++ " AHout="); + } + #endif + add_said(&c->spd.this.host_addr, st->st_ah.our_spi, +@@ -1826,7 +1825,7 @@ + mbcp, + traffic_buf + + sizeof(traffic_buf), +- " AHout="); ++ " AHin="); + } + #endif + mbcp = humanize_number( +@@ -1842,23 +1841,23 @@ + SA_ESP); + /* ??? needs proper fix, via kernel_ops? */ + #if defined(linux) && defined(NETKEY_SUPPORT) +- if (get_sa_info(st, FALSE, NULL)) { ++ if (get_sa_info(st, TRUE, NULL)) { + mbcp = humanize_number(st->st_esp.peer_bytes, + mbcp, + traffic_buf + + sizeof(traffic_buf), +- " ESPin="); ++ " ESPout="); + } + #endif + add_said(&c->spd.this.host_addr, st->st_esp.our_spi, + SA_ESP); + #if defined(linux) && defined(NETKEY_SUPPORT) +- if (get_sa_info(st, TRUE, NULL)) { ++ if (get_sa_info(st, FALSE, NULL)) { + mbcp = humanize_number(st->st_esp.our_bytes, + mbcp, + traffic_buf + + sizeof(traffic_buf), +- " ESPout="); ++ " ESPin="); + } + #endif + +@@ -1879,7 +1878,7 @@ + mbcp, + traffic_buf + + sizeof(traffic_buf), +- " IPCOMPin="); ++ " IPCOMPout="); + } + #endif + add_said(&c->spd.this.host_addr, st->st_ipcomp.our_spi, +@@ -1891,7 +1890,7 @@ + mbcp, + traffic_buf + + sizeof(traffic_buf), +- " IPCOMPout="); ++ " IPCOMPin="); + } + #endif + diff --git a/SPECS/libreswan.spec b/SPECS/libreswan.spec new file mode 100644 index 0000000..cf0ac6a --- /dev/null +++ b/SPECS/libreswan.spec @@ -0,0 +1,474 @@ +%global USE_FIPSCHECK true +%global USE_LIBCAP_NG true +%global USE_LABELED_IPSEC true +%global USE_CRL_FETCHING true +%global USE_DNSSEC true +%global USE_NM true +%global USE_LINUX_AUDIT true + +%global _hardened_build 1 +%global buildefence 0 +%global development 0 +%global cavstests 1 + +%if 0%{?fedora} +%global rhel 7 +%endif + +#global prever rc1 + +Name: libreswan +Summary: IPsec implementation with IKEv1 and IKEv2 keying protocols +Version: 3.15 +Release: %{?prever:0.}5%{?prever:.%{prever}}%{?dist} +License: GPLv2 +Group: System Environment/Daemons +Url: https://libreswan.org/ +Source: https://download.libreswan.org/%{?prever:development/}%{name}-%{version}%{?prever}.tar.gz +Source1: ikev1_dsa.fax.bz2 +Source2: ikev1_psk.fax.bz2 +Source3: ikev2.fax.bz2 + +Patch1: libreswan-3.15-racoon-padding.patch +Patch2: libreswan-3.15-seeddev.patch +Patch3: libreswan-3.15-ikev1-pam.patch +Patch4: libreswan-3.15-gcc-osw-interop-conf.patch +Patch5: libreswan-3.15-newest-labeled.patch +Patch6: libreswan-3.15-s90-gcc.patch +Patch7: libreswan-3.15-NLMSG_OK.patch +Patch8: libreswan-3.15-trafficstatus.patch +Patch9: libreswan-3.15-cisco-delete.patch +Patch10: libreswan-3.15-migration.patch +Patch11: libreswan-3.15-1166146.patch +Patch12: libreswan-3.15-609343.patch +Patch13: libreswan-3.15-1271778-whack-man.patch +# rhbz#1272317 +Patch14: libreswan-3.15-1271811-fipsfiles.patch + +Requires: iproute >= 2.6.8 nss-tools nss-softokn + +BuildRequires: gmp-devel bison flex redhat-rpm-config pkgconfig +BuildRequires: nss-devel >= 3.16.1 nspr-devel +BuildRequires: pam-devel +BuildRequires: xmlto + +%if %{?rhel} <= 6 +BuildRequires: libevent2-devel net-tools + +Requires(post): coreutils bash +Requires(preun): initscripts chkconfig +Requires(post): /sbin/chkconfig +Requires(preun): /sbin/chkconfig +Requires(preun): /sbin/service +%else +BuildRequires: libevent-devel hostname + +BuildRequires: systemd +Requires(post): coreutils bash systemd +Requires(preun): systemd +Requires(postun): systemd +%endif + +%if %{USE_DNSSEC} +BuildRequires: unbound-devel +%endif + +%if %{USE_FIPSCHECK} +BuildRequires: fipscheck-devel +# we need fipshmac +Requires: fipscheck%{_isa} +%endif + +%if %{USE_LINUX_AUDIT} +Buildrequires: audit-libs-devel +%endif + +%if %{USE_LIBCAP_NG} +BuildRequires: libcap-ng-devel +%endif + +%if %{USE_CRL_FETCHING} +BuildRequires: openldap-devel curl-devel +%endif + +%if %{buildefence} +BuildRequires: ElectricFence +%endif + +Conflicts: openswan < %{version}-%{release} +Provides: openswan = %{version}-%{release} +Provides: openswan-doc = %{version}-%{release} + +%if %{?rhel} == 7 +# Will be obsoleted in RHEL6 when moved from optional to core +Obsoletes: openswan < %{version}-%{release} +%endif + +%description +Libreswan is a free implementation of IPsec & IKE for Linux. IPsec is +the Internet Protocol Security and uses strong cryptography to provide +both authentication and encryption services. These services allow you +to build secure tunnels through untrusted networks. Everything passing +through the untrusted net is encrypted by the ipsec gateway machine and +decrypted by the gateway at the other end of the tunnel. The resulting +tunnel is a virtual private network or VPN. + +This package contains the daemons and userland tools for setting up +Libreswan. It supports the NETKEY/XFRM IPsec kernel stack that exists +in the default Linux kernel. + +Libreswan also supports IKEv2 (RFC-7296) and Secure Labeling + +Libreswan is based on Openswan-2.6.38 which in turn is based on FreeS/WAN-2.04 + +%prep +%setup -q -n libreswan-%{version}%{?prever} +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 + +%build +%if %{buildefence} + %define efence "-lefence" +%endif + +make %{?_smp_mflags} \ +%if %{development} + USERCOMPILE="-g -DGCC_LINT %(echo %{optflags} | sed -e s/-O[0-9]*/ /) %{?efence} -fPIE -pie " \ +%else + USERCOMPILE="-g -DGCC_LINT %{optflags} %{?efence} -fPIE -pie " \ +%endif + USERLINK="-g -pie -Wl,-z,relro,-z,now %{?efence}" \ +%if %{?rhel} <= 6 + INITSYSTEM=sysvinit \ +%else + INITSYSTEM=systemd \ +%endif + USE_NM=%{USE_NM} \ + USE_XAUTHPAM=true \ +%if %{USE_FIPSCHECK} + USE_FIPSCHECK="%{USE_FIPSCHECK}" \ + FIPSPRODUCTCHECK=/etc/system-fips \ +%endif + USE_LIBCAP_NG="%{USE_LIBCAP_NG}" \ + USE_LABELED_IPSEC="%{USE_LABELED_IPSEC}" \ + USE_LINUX_AUDIT="%{USE_LINUX_AUDIT}" \ +%if %{USE_CRL_FETCHING} + USE_LDAP=true \ + USE_LIBCURL=true \ +%endif + USE_DNSSEC="%{USE_DNSSEC}" \ + INC_USRLOCAL=%{_prefix} \ + FINALLIBDIR=%{_libexecdir}/ipsec \ + FINALLIBEXECDIR=%{_libexecdir}/ipsec \ + MANTREE=%{_mandir} \ + INC_RCDEFAULT=%{_initrddir} \ + MODPROBE="modprobe -q -b" \ + programs +FS=$(pwd) + +%if %{USE_FIPSCHECK} +# Add generation of HMAC checksums of the final stripped binaries +%if %{?rhel} <= 6 +%define __spec_install_post \ + %{?__debug_package:%{__debug_install_post}} \ + %{__arch_install_post} \ + %{__os_install_post} \ + fipshmac %{buildroot}%{_libexecdir}/ipsec/* \ + fipshmac %{buildroot}%{_sbindir}/ipsec \ +%{nil} + +%else +%define __spec_install_post \ + %{?__debug_package:%{__debug_install_post}} \ + %{__arch_install_post} \ + %{__os_install_post} \ + mkdir -p %{buildroot}%{_libdir}/fipscheck/ \ + fipshmac -d %{buildroot}%{_libdir}/fipscheck %{buildroot}%{_libexecdir}/ipsec/* \ + fipshmac -d %{buildroot}%{_libdir}/fipscheck %{buildroot}%{_sbindir}/ipsec \ +%{nil} +%endif +%endif + +%install +rm -rf ${RPM_BUILD_ROOT} +make \ + DESTDIR=%{buildroot} \ + INC_USRLOCAL=%{_prefix} \ + FINALLIBDIR=%{_libexecdir}/ipsec \ + FINALLIBEXECDIR=%{_libexecdir}/ipsec \ + MANTREE=%{buildroot}%{_mandir} \ + INC_RCDEFAULT=%{_initrddir} \ + INSTMANFLAGS="-m 644" \ +%if %{?rhel} <= 6 + INITSYSTEM=sysvinit \ +%else + INITSYSTEM=systemd \ +%endif + install +FS=$(pwd) +rm -rf %{buildroot}/usr/share/doc/libreswan +# needed to activate v6neighbor-hole.conf +sed -i "s:^#include /etc/ipsec.d/\*.conf$:include /etc/ipsec.d/*.conf:" %{buildroot}%{_sysconfdir}/ipsec.conf + +install -d -m 0755 %{buildroot}%{_localstatedir}/run/pluto +# used when setting --perpeerlog without --perpeerlogbase +install -d -m 0700 %{buildroot}%{_localstatedir}/log/pluto/peer +install -d %{buildroot}%{_sbindir} +%if %{?rhel} <= 6 +# replace with rhel6 specific version +install -m 0755 initsystems/sysvinit/init.rhel %{buildroot}%{_initrddir}/ipsec +rm -fr %{buildroot}/etc/rc.d/rc* +%endif + +%if %{USE_FIPSCHECK} +%if %{?rhel} == 7 +mkdir -p %{buildroot}%{_libdir}/fipscheck +%endif +install -d %{buildroot}%{_sysconfdir}/prelink.conf.d/ +install -m644 packaging/fedora/libreswan-prelink.conf %{buildroot}%{_sysconfdir}/prelink.conf.d/libreswan-fips.conf +%endif + +echo "include /etc/ipsec.d/*.secrets" > %{buildroot}%{_sysconfdir}/ipsec.secrets + +# cavs testing +cp -a OBJ.linux.*/programs/pluto/cavp %{buildroot}%{_libexecdir}/ipsec + +%if %{cavstests} +%check +# There is an elaborate upstream testing infrastructure which we do not run here +# We only run the CAVS tests here +cp %{SOURCE1} %{SOURCE2} %{SOURCE3} . +bunzip2 *.fax.bz2 + +# work around for rhel6 builders on xen +export NSS_DISABLE_HW_GCM=1 + +: "starting CAVS test for IKEv2" +OBJ.linux.*/programs/pluto/cavp -v2 ikev2.fax | diff -u ikev2.fax - > /dev/null +: "starting CAVS test for IKEv1 RSASIG" +OBJ.linux.*/programs/pluto/cavp -v1sig ikev1_dsa.fax | diff -u ikev1_dsa.fax - > /dev/null +: "starting CAVS test for IKEv1 PSK" +OBJ.linux.*/programs/pluto/cavp -v1psk ikev1_psk.fax | diff -u ikev1_psk.fax - > /dev/null +: "CAVS tests passed" +%endif + +%if %{?rhel} <= 6 +%post +/sbin/chkconfig --add ipsec || : +%if %{USE_FIPSCHECK} +prelink -u %{_libexecdir}/ipsec/* 2>/dev/null || : +%endif + +%preun +if [ $1 -eq 0 ]; then + /sbin/service ipsec stop > /dev/null 2>&1 || : + /sbin/chkconfig --del ipsec +fi + +%postun +if [ $1 -ge 1 ] ; then + /sbin/service ipsec condrestart 2>&1 >/dev/null || : +fi +%else +%preun +%systemd_preun ipsec.service + +%postun +%systemd_postun_with_restart ipsec.service + +%post +%systemd_post ipsec.service +%endif + +%files +%doc CHANGES COPYING CREDITS README* LICENSE +%doc docs/*.* docs/examples packaging/rhel/libreswan-sysctl.conf + +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ipsec.conf +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ipsec.secrets +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/sysconfig/pluto +%attr(0700,root,root) %dir %{_sysconfdir}/ipsec.d +%attr(0644,root,root) %{_sysconfdir}/ipsec.d/v6neighbor-hole.conf +%attr(0700,root,root) %dir %{_sysconfdir}/ipsec.d/policies +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ipsec.d/policies/* +%attr(0700,root,root) %dir %{_localstatedir}/log/pluto/peer +%attr(0755,root,root) %dir %{_localstatedir}/run/pluto +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/pam.d/pluto +%{_sbindir}/ipsec +%attr(0755,root,root) %dir %{_libexecdir}/ipsec +%{_libexecdir}/ipsec/* +%attr(0644,root,root) %{_mandir}/*/*.gz +%if %{?rhel} <= 6 +%{_initrddir}/ipsec +%else +%attr(0644,root,root) %{_unitdir}/ipsec.service +%endif + +%if %{USE_FIPSCHECK} +%if %{?rhel} <= 6 +%{_sbindir}/.ipsec.hmac +%{_libexecdir}/ipsec/.*.hmac +%else +%{_libdir}/fipscheck/*.hmac +%endif + +# We own the directory so we don't have to require prelink +%attr(0755,root,root) %dir %{_sysconfdir}/prelink.conf.d/ +%{_sysconfdir}/prelink.conf.d/libreswan-fips.conf +%endif + +%changelog +* Thu Oct 15 2015 Paul Wouters - 3.15-5 +- Resolves: rhbz#1272317 libreswan FIPS test mistakenly looks for non-existent file hashes +- Resolves: rhbz#1271778 ipsec whack man page discrepancies + +* Tue Sep 29 2015 Paul Wouters - 3.15-4 +- Updates: rhbz#1233303 add libreswan to RHEL6 (fix source confusion) + +* Mon Sep 28 2015 Paul Wouters - 3.15-3 +- Updates: rhbz#1233303 add libreswan to RHEL6 + +* Tue Sep 15 2015 Paul Wouters - 3.15-2 +- Resolves: rhbz#1259208 CVE-2015-3240 +- Merge rhel6 and rhel7 spec into one +- Be lenient for racoon padding behaviour +- Fix seedev option to /dev/random +- Some IKEv1 PAM methods always gave 'Permission denied' +- Parser workarounds for differences in gcc/flex/bison on rhel6/rhel7 +- Parser fix to allow specifying time without unit (openswan compat) +- Fix Labeled IPsec on rekeyed IPsec SA's +- Workaround for wrong padding by racoon2 +- Disable NSS HW GCM to workaround rhel6 xen builers bug + +* Wed Aug 19 2015 Paul Wouters - 3.14-1 +- Resolves: rhbz#1233303 add libreswan to RHEL6 +- Resolves: CVE-2015-3240 denial of service via IKE daemon restart when receiving a bad DH gx + +* Fri May 29 2015 Paul Wouters - 3.12-10.1 +- Resolves: rhbz#1226407 CVE-2015-3204 libreswan: crafted IKE packet causes daemon restart + +* Tue May 05 2015 Paul Wouters - 3.12-10 +- Resolves: rhbz#1213652 Support CAVS [updated another prf() free symkey, bogus fips mode fix] + +* Tue Apr 28 2015 Paul Wouters - 3.12-9 +- Resolves: rhbz#1213652 Support CAVS [updated to kill another copy of prf()] +- Resolves: rhbz#1208023 Libreswan with IPv6 [updated patch by Jaroslav Aster] +- Resolves: rhbz#1208022 libreswan ignores module blacklist [updated modprobe handling] + +* Mon Apr 20 2015 Paul Wouters - 3.12-8 +- Resolves: rhbz#1213652 Support CAVS testing of the PRF/PRF+ functions + +* Mon Apr 13 2015 Paul Wouters - 3.12-7 +- Resolves: rhbz#1208022 libreswan ignores module blacklist rules +- Resolves: rhbz#1208023 Libreswan with IPv6 in RHEL7 fails after reboot +- Resolves: rhbz#1211146 pluto crashes in fips mode + +* Tue Mar 17 2015 Paul Wouters - 3.12-6 +- Resolves: rhbz#1198650 SELinux context string size limit +- Resolves: rhbz#1198649 Add new option for BSI random requirement + +* Tue Jan 20 2015 Paul Wouters - 3.12-5 +- Resolves: rhbz#826264 aes-gcm implementation support (for IKEv2) +- Resolves: rhbz#1074018 Audit key agreement (integ gcm fixup) + +* Tue Dec 30 2014 Paul Wouters - 3.12-4 +- Resolves: rhbz#1134297 aes-ctr cipher is not supported +- Resolves: rhbz#1131503 non-zero rSPI on INVALID_KE (and proper INVALID_KE handling) + +* Thu Dec 04 2014 Paul Wouters - 3.12-2 +- Resolves: rhbz#1105171 (Update man page entry) +- Resolves: rhbz#1144120 (Update for ESP CAMELLIA with IKEv2) +- Resolves: rhbz#1074018 Audit key agreement + +* Fri Nov 07 2014 Paul Wouters - 3.12-1 +- Resolves: rhbz#1136124 rebase to libreswan 3.12 +- Resolves: rhbz#1052811 [TAHI] (also clear reserved flags for isakmp_sa header) +- Resolves: rhbz#1157379 [TAHI][IKEv2] IKEv2.EN.R.1.3.3.1: Non RESERVED fields in INFORMATIONAL request + +* Mon Oct 27 2014 Paul Wouters - 3.11-2 +- Resolves: rhbz#1136124 rebase to libreswan 3.11 (coverity fixup, dpdaction=clear fix) + +* Wed Oct 22 2014 Paul Wouters - 3.11-1 +- Resolves: rhbz#1136124 rebase to libreswan 3.11 +- Resolves: rhbz#1099905 ikev2 delete payloads are not delivered to peer +- Resolves: rhbz#1147693 NetworkManger-libreswan can not connect to Red Hat IPSec Xauth VPN +- Resolves: rhbz#1055865 [TAHI][IKEv2] libreswan do not ignore the content of version bit +- Resolves: rhbz#1146106 Pluto crashes after start when some ah algorithms are used +- Resolves: rhbz#1108256 addconn compatibility with openswan +- Resolves: rhbz#1152625 [TAHI][IKEv2] IKEv2.EN.I.1.1.6.2 Part D: Integrity Algorithm AUTH_AES_XCBC_96 fail +- Resolves: rhbz#1119704 [TAHI][IKEv2]IKEv2Interop.1.13a test fail +- Resolves: rhbz#1100261 libreswan does not send response when when it receives Delete Payload for a CHILD_SA +- Resolves: rhbz#1100239 ikev2 IKE SA responder does not send delete request to IKE SA initiator +- Resolves: rhbz#1052811 [TAHI][IKEv2]IKEv2.EN.I.1.1.11.1: Non zero RESERVED fields in IKE_SA_INIT response +- Resolves: rhbz#1126868 ikev2 sequence numbers are implemented incorrectly +- Resolves: rhbz#1145245 Libreswan appears to start with systemd before all the NICs are up and running. +- Resolves: rhbz#1145231 libreswan 3.10 upgrade breaks old ipsec.secrets configs +- Resolves: rhbz#1144123 Add ESP support for AES_XCBC hash for USGv6 and IPsec-v3 compliance +- Resolves: rhbz#1144120 Add ESP support for CAMELLIA for USGv6 and IPsec-v3 compliance +- Resolves: rhbz#1099877 Missing man-pages ipsec_whack, ipsec_manual +- Resolves: rhbz#1100255 libreswan Ikev2 implementation does not send an INFORMATIONAL response when it receives an INFORMATIONAL request with a Delete Payload for an IKE_SA + +* Tue Sep 09 2014 Paul Wouters - 3.10-3 +- Resolves: rhbz#1136124 rebase to 3.10 (auto=route bug on startup) + +* Mon Sep 08 2014 Paul Wouters - 3.10-2 +- Resolves: rhbz#1136124 rebase to libreswan 3.10 + +* Mon Jul 14 2014 Paul Wouters - 3.8-6 +- Resolves: rhbz#1092047 pluto cannot write to directories not owned by root + +* Thu Apr 10 2014 Paul Wouters - 3.8-5 +- Resolves: rhbz#1052834 create_child_sa message ID handling + + +* Tue Mar 18 2014 Paul Wouters - 3.8-4 +- Resolves: rhbz#1052834 create_child_sa response + +* Wed Mar 05 2014 Paul Wouters - 3.8-3 +- Resolves: rhbz#1069024 erroneous debug line with mixture [...] +- Resolves: rhbz#1030939 update nss/x509 documents, don't load acerts +- Resolves: rhbz#1058813 newhostkey returns zero value when it fails + +* Fri Jan 24 2014 Daniel Mach - 3.8-2 +- Mass rebuild 2014-01-24 + +* Thu Jan 16 2014 Paul Wouters - 3.8-1 +- Resolves: rhbz#CVE-2013-6467 +- Resolves: rhbz#1043642 rebase to version 3.8 +- Resolves: rhbz#1029912 ipsec force-reload doesn't work +- Resolves: rhbz#826261 Implement SHA384/512 support for Openswan +- Resolves: rhbz#1039655 ipsec newhostkey generates false configuration + +* Fri Dec 27 2013 Daniel Mach - 3.6-3 +- Mass rebuild 2013-12-27 + +* Fri Nov 08 2013 Paul Wouters - 3.6-2 +- Fix race condition in post for creating nss db + +* Thu Oct 31 2013 Paul Wouters - 3.6-1 +- Updated to version 3.6 (IKEv2, MODECFG, Cisco interop fixes) +- Generate empty NSS db if none exists +- FIPS update using /etc/system-fips +- Provide: openswan-doc + +* Fri Aug 09 2013 Paul Wouters - 3.5-2 +- rebuilt and bumped EVR to avoid confusion of import->delete->import +- require iproute + +* Mon Jul 15 2013 Paul Wouters - 3.5-1 +- Initial package for RHEL7 +- Added interop patch for (some?) Cisco VPN clients sending 16 zero + bytes of extraneous IKE data +- Removed fipscheck_version