diff options
Diffstat (limited to 'main/ipsec-tools')
-rw-r--r-- | main/ipsec-tools/00-verify-cert-leak.patch | 11 | ||||
-rw-r--r-- | main/ipsec-tools/20-natoa-fix.patch | 33 | ||||
-rw-r--r-- | main/ipsec-tools/30-natt-ports-cleanup.patch | 393 | ||||
-rw-r--r-- | main/ipsec-tools/40-cmpsaddr-cleanup.patch | 1403 | ||||
-rw-r--r-- | main/ipsec-tools/50-reverse-connect.patch | 207 | ||||
-rw-r--r-- | main/ipsec-tools/60-debug-quick.patch | 211 | ||||
-rw-r--r-- | main/ipsec-tools/APKBUILD | 59 | ||||
-rw-r--r-- | main/ipsec-tools/racoon.confd | 19 | ||||
-rw-r--r-- | main/ipsec-tools/racoon.initd | 58 |
9 files changed, 2394 insertions, 0 deletions
diff --git a/main/ipsec-tools/00-verify-cert-leak.patch b/main/ipsec-tools/00-verify-cert-leak.patch new file mode 100644 index 0000000000..9e67813359 --- /dev/null +++ b/main/ipsec-tools/00-verify-cert-leak.patch @@ -0,0 +1,11 @@ +--- a/src/racoon/crypto_openssl.c 20 Apr 2009 13:22:41 -0000 1.18 ++++ b/src/racoon/crypto_openssl.c 29 Apr 2009 10:48:51 -0000 +@@ -510,7 +510,7 @@ + X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK_ALL); + #endif + error = X509_verify_cert(csc); +- X509_STORE_CTX_cleanup(csc); ++ X509_STORE_CTX_free(csc); + + /* + * if x509_verify_cert() is successful then the value of error is diff --git a/main/ipsec-tools/20-natoa-fix.patch b/main/ipsec-tools/20-natoa-fix.patch new file mode 100644 index 0000000000..91d7224e2a --- /dev/null +++ b/main/ipsec-tools/20-natoa-fix.patch @@ -0,0 +1,33 @@ +Fix nat-oa parsing when rekeying. + +From: Timo Teras <timo.teras@iki.fi> + + +--- + + src/racoon/handler.c | 11 +++++++++++ + 1 files changed, 11 insertions(+), 0 deletions(-) + + +diff --git a/src/racoon/handler.c b/src/racoon/handler.c +index 6f91beb..960b5b3 100644 +--- a/src/racoon/handler.c ++++ b/src/racoon/handler.c +@@ -736,6 +736,17 @@ initph2(iph2) + oakley_delivm(iph2->ivm); + iph2->ivm = NULL; + } ++ ++#ifdef ENABLE_NATT ++ if (iph2->natoa_src) { ++ racoon_free(iph2->natoa_src); ++ iph2->natoa_src = NULL; ++ } ++ if (iph2->natoa_dst) { ++ racoon_free(iph2->natoa_dst); ++ iph2->natoa_dst = NULL; ++ } ++#endif + } + + /* diff --git a/main/ipsec-tools/30-natt-ports-cleanup.patch b/main/ipsec-tools/30-natt-ports-cleanup.patch new file mode 100644 index 0000000000..19360347da --- /dev/null +++ b/main/ipsec-tools/30-natt-ports-cleanup.patch @@ -0,0 +1,393 @@ +From Yvan Vanhullebus: Use SADB_X_EXT_NAT_T_* consistently for passing the + +From: Timo Teras <timo.teras@iki.fi> + +NAT-T port information. +--- + + src/libipsec/libpfkey.h | 12 ++++++++ + src/libipsec/pfkey.c | 49 +++++++++++++++++++++++++++++++++ + src/racoon/isakmp.c | 11 +++++++ + src/racoon/isakmp_inf.c | 37 +++++++++++++------------ + src/racoon/pfkey.c | 69 +++++++++++++++++++++++++++++++++-------------- + src/racoon/pfkey.h | 1 + + 6 files changed, 140 insertions(+), 39 deletions(-) + + +diff --git a/src/libipsec/libpfkey.h b/src/libipsec/libpfkey.h +index 8a503dd..c9b228b 100644 +--- a/src/libipsec/libpfkey.h ++++ b/src/libipsec/libpfkey.h +@@ -117,6 +117,10 @@ u_int pfkey_set_softrate __P((u_int, u_int)); + u_int pfkey_get_softrate __P((u_int)); + int pfkey_send_getspi __P((int, u_int, u_int, struct sockaddr *, + struct sockaddr *, u_int32_t, u_int32_t, u_int32_t, u_int32_t)); ++int pfkey_send_getspi_nat __P((int, u_int, u_int, ++ struct sockaddr *, struct sockaddr *, u_int8_t, u_int16_t, u_int16_t, ++ u_int32_t, u_int32_t, u_int32_t, u_int32_t)); ++ + int pfkey_send_update2 __P((struct pfkey_send_sa_args *)); + int pfkey_send_add2 __P((struct pfkey_send_sa_args *)); + int pfkey_send_delete __P((int, u_int, u_int, +@@ -155,6 +159,14 @@ int pfkey_send_migrate __P((int, struct sockaddr *, struct sockaddr *, + caddr_t, int, u_int32_t)); + #endif + ++/* XXX should be somewhere else !!! ++ */ ++#ifdef SADB_X_NAT_T_NEW_MAPPING ++#define PFKEY_ADDR_X_PORT(ext) (ntohs(((struct sadb_x_nat_t_port *)ext)->sadb_x_nat_t_port_port)) ++#define PFKEY_ADDR_X_NATTYPE(ext) ( ext != NULL && ((struct sadb_x_nat_t_type *)ext)->sadb_x_nat_t_type_type ) ++#endif ++ ++ + int pfkey_open __P((void)); + void pfkey_close __P((int)); + int pfkey_set_buffer_size __P((int, int)); +diff --git a/src/libipsec/pfkey.c b/src/libipsec/pfkey.c +index 0a944c2..b39ffca 100644 +--- a/src/libipsec/pfkey.c ++++ b/src/libipsec/pfkey.c +@@ -380,10 +380,12 @@ pfkey_get_softrate(type) + * -1 : error occured, and set errno. + */ + int +-pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) ++pfkey_send_getspi_nat(so, satype, mode, src, dst, natt_type, sport, dport, min, max, reqid, seq) + int so; + u_int satype, mode; + struct sockaddr *src, *dst; ++ u_int8_t natt_type; ++ u_int16_t sport, dport; + u_int32_t min, max, reqid, seq; + { + struct sadb_msg *newmsg; +@@ -431,6 +433,14 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) + len += sizeof(struct sadb_spirange); + } + ++#ifdef SADB_X_EXT_NAT_T_TYPE ++ if(natt_type||sport||dport){ ++ len += sizeof(struct sadb_x_nat_t_type); ++ len += sizeof(struct sadb_x_nat_t_port); ++ len += sizeof(struct sadb_x_nat_t_port); ++ } ++#endif ++ + if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { + __ipsec_set_strerror(strerror(errno)); + return -1; +@@ -466,6 +476,32 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) + return -1; + } + ++#ifdef SADB_X_EXT_NAT_T_TYPE ++ /* Add nat-t messages */ ++ if (natt_type) { ++ p = pfkey_set_natt_type(p, ep, SADB_X_EXT_NAT_T_TYPE, ++ natt_type); ++ if (!p) { ++ free(newmsg); ++ return -1; ++ } ++ ++ p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_SPORT, ++ sport); ++ if (!p) { ++ free(newmsg); ++ return -1; ++ } ++ ++ p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_DPORT, ++ dport); ++ if (!p) { ++ free(newmsg); ++ return -1; ++ } ++ } ++#endif ++ + /* proccessing spi range */ + if (need_spirange) { + struct sadb_spirange spirange; +@@ -501,6 +537,17 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) + return len; + } + ++int ++pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) ++ int so; ++ u_int satype, mode; ++ struct sockaddr *src, *dst; ++ u_int32_t min, max, reqid, seq; ++{ ++ return pfkey_send_getspi_nat(so, satype, mode, src, dst, 0, 0, 0, ++ min, max, reqid, seq); ++} ++ + /* + * sending SADB_UPDATE message to the kernel. + * The length of key material is a_keylen + e_keylen. +diff --git a/src/racoon/isakmp.c b/src/racoon/isakmp.c +index c8670f6..fe51653 100644 +--- a/src/racoon/isakmp.c ++++ b/src/racoon/isakmp.c +@@ -3324,6 +3324,17 @@ purge_remote(iph1) + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + ++#ifdef SADB_X_NAT_T_NEW_MAPPING ++ if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) { ++ /* NAT-T is enabled for this SADB entry; copy ++ * the ports from NAT-T extensions */ ++ if(mhp[SADB_X_EXT_NAT_T_SPORT] != NULL) ++ set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT])); ++ if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL) ++ set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT])); ++ } ++#endif ++ + if (sa->sadb_sa_state != SADB_SASTATE_LARVAL && + sa->sadb_sa_state != SADB_SASTATE_MATURE && + sa->sadb_sa_state != SADB_SASTATE_DYING) { +diff --git a/src/racoon/isakmp_inf.c b/src/racoon/isakmp_inf.c +index 1ada07f..a712825 100644 +--- a/src/racoon/isakmp_inf.c ++++ b/src/racoon/isakmp_inf.c +@@ -1128,8 +1128,7 @@ purge_ipsec_spi(dst0, proto, spi, n) + size_t i; + caddr_t mhp[SADB_EXT_MAX + 1]; + #ifdef ENABLE_NATT +- struct sadb_x_nat_t_type *natt_type; +- struct sadb_x_nat_t_port *natt_port; ++ int natt_port_forced; + #endif + + plog(LLV_DEBUG2, LOCATION, NULL, +@@ -1184,22 +1183,25 @@ purge_ipsec_spi(dst0, proto, spi, n) + continue; + } + #ifdef ENABLE_NATT +- natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE]; +- if (natt_type && natt_type->sadb_x_nat_t_type_type) { ++ if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) { + /* NAT-T is enabled for this SADB entry; copy + * the ports from NAT-T extensions */ +- natt_port = (void *)mhp[SADB_X_EXT_NAT_T_SPORT]; +- if (extract_port(src) == 0 && natt_port != NULL) +- set_port(src, ntohs(natt_port->sadb_x_nat_t_port_port)); +- +- natt_port = (void *)mhp[SADB_X_EXT_NAT_T_DPORT]; +- if (extract_port(dst) == 0 && natt_port != NULL) +- set_port(dst, ntohs(natt_port->sadb_x_nat_t_port_port)); +- }else{ +- /* Force default UDP ports, so CMPSADDR will match SAs with NO encapsulation +- */ ++ if (extract_port(src) == 0 && ++ mhp[SADB_X_EXT_NAT_T_SPORT] != NULL) { ++ set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT])); ++ } ++ ++ if (extract_port(dst) == 0 && ++ mhp[SADB_X_EXT_NAT_T_DPORT] != NULL) { ++ set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT])); ++ } ++ natt_port_forced = 0; ++ } else { ++ /* Force default UDP ports, so ++ * CMPSADDR will match SAs with NO encapsulation */ + set_port(src, PORT_ISAKMP); + set_port(dst, PORT_ISAKMP); ++ natt_port_forced = 1; + } + #endif + plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src)); +@@ -1215,10 +1217,9 @@ purge_ipsec_spi(dst0, proto, spi, n) + } + + #ifdef ENABLE_NATT +- if (natt_type == NULL || +- ! natt_type->sadb_x_nat_t_type_type) { +- /* Set back port to 0 if it was forced to default UDP port +- */ ++ if (natt_port_forced) { ++ /* Set back port to 0 if it was forced ++ * to default UDP port */ + set_port(src, 0); + set_port(dst, 0); + } +diff --git a/src/racoon/pfkey.c b/src/racoon/pfkey.c +index 610cc09..c210c5e 100644 +--- a/src/racoon/pfkey.c ++++ b/src/racoon/pfkey.c +@@ -769,6 +769,28 @@ keylen_ealg(enctype, encklen) + return res; + } + ++void ++pk_fixup_sa_addresses(mhp) ++ caddr_t *mhp; ++{ ++ struct sockaddr *src, *dst; ++ src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); ++ dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); ++#ifdef ENABLE_NATT ++ if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) { ++ /* NAT-T is enabled for this SADB entry; copy ++ * the ports from NAT-T extensions */ ++ if(mhp[SADB_X_EXT_NAT_T_SPORT] != NULL) ++ set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT])); ++ if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL) ++ set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT])); ++ } ++#else ++ set_port(src, 0); ++ set_port(dst, 0); ++#endif ++} ++ + int + pfkey_convertfromipsecdoi(proto_id, t_id, hashtype, + e_type, e_keylen, a_type, a_keylen, flags) +@@ -866,6 +888,8 @@ pk_sendgetspi(iph2) + struct saprop *pp; + struct saproto *pr; + u_int32_t minspi, maxspi; ++ u_int8_t natt_type = 0; ++ u_int16_t sport = 0, dport = 0; + + if (iph2->side == INITIATOR) + pp = iph2->proposal; +@@ -919,19 +943,27 @@ pk_sendgetspi(iph2) + } + + #ifdef ENABLE_NATT +- if (! pr->udp_encap) { +- /* Remove port information, that SA doesn't use it */ +- set_port(iph2->src, 0); +- set_port(iph2->dst, 0); ++ if (pr->udp_encap) { ++ natt_type = iph2->ph1->natt_options->encaps_type; ++ sport=extract_port(src); ++ dport=extract_port(dst); + } + #endif ++ /* Always remove port information, it will be sent in ++ * SADB_X_EXT_NAT_T_[S|D]PORT if needed */ ++ set_port(src, 0); ++ set_port(dst, 0); ++ + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n"); +- if (pfkey_send_getspi( ++ if (pfkey_send_getspi_nat( + lcconf->sock_pfkey, + satype, + mode, + dst, /* src of SA */ + src, /* dst of SA */ ++ natt_type, ++ dport, ++ sport, + minspi, maxspi, + pr->reqid_in, iph2->seq) < 0) { + plog(LLV_ERROR, LOCATION, NULL, +@@ -1157,13 +1189,13 @@ pk_sendupdate(iph2) + #ifdef SADB_X_EXT_NAT_T_FRAG + sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag; + #endif +- } else { +- /* Remove port information, that SA doesn't use it */ +- set_port(sa_args.src, 0); +- set_port(sa_args.dst, 0); + } +- + #endif ++ /* Always remove port information, it will be sent in ++ * SADB_X_EXT_NAT_T_[S|D]PORT if needed */ ++ set_port(sa_args.src, 0); ++ set_port(sa_args.dst, 0); ++ + /* more info to fill in */ + sa_args.spi = pr->spi; + sa_args.reqid = pr->reqid_in; +@@ -1236,6 +1268,7 @@ pk_recvupdate(mhp) + return -1; + } + msg = (struct sadb_msg *)mhp[0]; ++ pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; +@@ -1328,7 +1361,6 @@ pk_recvupdate(mhp) + /* Force the update of ph2's ports, as there is at least one + * situation where they'll mismatch with ph1's values + */ +- + #ifdef ENABLE_NATT + set_port(iph2->src, extract_port(iph2->ph1->local)); + set_port(iph2->dst, extract_port(iph2->ph1->remote)); +@@ -1456,17 +1488,12 @@ pk_sendadd(iph2) + #ifdef SADB_X_EXT_NAT_T_FRAG + sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag; + #endif +- } else { +- /* Remove port information, that SA doesn't use it */ +- set_port(sa_args.src, 0); +- set_port(sa_args.dst, 0); + } +- +-#else +- /* Remove port information, it is not used without NAT-T */ ++#endif ++ /* Always remove port information, it will be sent in ++ * SADB_X_EXT_NAT_T_[S|D]PORT if needed */ + set_port(sa_args.src, 0); + set_port(sa_args.dst, 0); +-#endif + + /* more info to fill in */ + sa_args.spi = pr->spi_p; +@@ -1596,6 +1623,7 @@ pk_recvexpire(mhp) + } + msg = (struct sadb_msg *)mhp[0]; + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; ++ pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + +@@ -1721,6 +1749,7 @@ pk_recvacquire(mhp) + } + msg = (struct sadb_msg *)mhp[0]; + xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; ++ pk_fixup_sa_addresses(mhp); + sp_src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + sp_dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + +@@ -1971,6 +2000,7 @@ pk_recvdelete(mhp) + } + msg = (struct sadb_msg *)mhp[0]; + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; ++ pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + +@@ -2709,7 +2739,6 @@ pk_recvspddump(mhp) + return -1; + } + msg = (struct sadb_msg *)mhp[0]; +- + saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; + daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; + xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; +diff --git a/src/racoon/pfkey.h b/src/racoon/pfkey.h +index a3acd1c..f1b037d 100644 +--- a/src/racoon/pfkey.h ++++ b/src/racoon/pfkey.h +@@ -52,6 +52,7 @@ extern struct pfkey_st *pfkey_getpst __P((caddr_t *, int, int)); + extern int pk_checkalg __P((int, int, int)); + + struct ph2handle; ++extern void pk_fixup_sa_addresses __P((caddr_t *mhp)); + extern int pk_sendgetspi __P((struct ph2handle *)); + extern int pk_sendupdate __P((struct ph2handle *)); + extern int pk_sendadd __P((struct ph2handle *)); diff --git a/main/ipsec-tools/40-cmpsaddr-cleanup.patch b/main/ipsec-tools/40-cmpsaddr-cleanup.patch new file mode 100644 index 0000000000..c5e3e4b330 --- /dev/null +++ b/main/ipsec-tools/40-cmpsaddr-cleanup.patch @@ -0,0 +1,1403 @@ +Get rid of CMPSADDR hack in port comparisons. Trac #295. + +From: Timo Teras <timo.teras@iki.fi> + + +--- + + src/racoon/admin.c | 37 ++++--- + src/racoon/grabmyaddr.c | 22 ++-- + src/racoon/handler.c | 41 +++----- + src/racoon/handler.h | 7 - + src/racoon/isakmp.c | 90 ++++------------- + src/racoon/isakmp_cfg.c | 9 -- + src/racoon/isakmp_inf.c | 111 ++++----------------- + src/racoon/isakmp_quick.c | 29 +++--- + src/racoon/nattraversal.c | 8 +- + src/racoon/pfkey.c | 52 +++------- + src/racoon/policy.c | 22 ++-- + src/racoon/remoteconf.c | 30 +----- + src/racoon/remoteconf.h | 3 - + src/racoon/sockmisc.c | 234 +++------------------------------------------ + src/racoon/sockmisc.h | 15 +-- + src/racoon/throttle.c | 2 + 16 files changed, 170 insertions(+), 542 deletions(-) + + +diff --git a/src/racoon/admin.c b/src/racoon/admin.c +index 576e191..b67e545 100644 +--- a/src/racoon/admin.c ++++ b/src/racoon/admin.c +@@ -167,6 +167,14 @@ end: + return error; + } + ++static int admin_ph1_delete_sa(struct ph1handle *iph1, void *arg) ++{ ++ if (iph1->status >= PHASE1ST_ESTABLISHED) ++ isakmp_info_send_d1(iph1); ++ purge_remote(iph1); ++ return 0; ++} ++ + /* + * main child's process. + */ +@@ -257,7 +265,7 @@ admin_process(so2, combuf) + break; + } + +- iph1 = getph1byaddrwop(src, dst); ++ iph1 = getph1byaddr(src, dst, 0); + if (iph1 == NULL) { + l_ac_errno = ENOENT; + break; +@@ -292,30 +300,25 @@ admin_process(so2, combuf) + + case ADMIN_DELETE_SA: { + struct ph1handle *iph1; +- struct sockaddr *dst; +- struct sockaddr *src; ++ struct ph1selector sel; + char *loc, *rem; + +- src = (struct sockaddr *) ++ memset(&sel, 0, sizeof(sel)); ++ sel.local = (struct sockaddr *) + &((struct admin_com_indexes *) + ((caddr_t)com + sizeof(*com)))->src; +- dst = (struct sockaddr *) ++ sel.remote = (struct sockaddr *) + &((struct admin_com_indexes *) + ((caddr_t)com + sizeof(*com)))->dst; + +- loc = racoon_strdup(saddrwop2str(src)); +- rem = racoon_strdup(saddrwop2str(dst)); ++ loc = racoon_strdup(saddr2str(sel.local)); ++ rem = racoon_strdup(saddr2str(sel.remote)); + STRDUP_FATAL(loc); + STRDUP_FATAL(rem); + +- if ((iph1 = getph1byaddrwop(src, dst)) == NULL) { +- plog(LLV_ERROR, LOCATION, NULL, +- "phase 1 for %s -> %s not found\n", loc, rem); +- } else { +- if (iph1->status >= PHASE1ST_ESTABLISHED) +- isakmp_info_send_d1(iph1); +- purge_remote(iph1); +- } ++ plog(LLV_INFO, LOCATION, NULL, ++ "admin delete-sa %s %s\n", loc, rem); ++ enumph1(&sel, admin_ph1_delete_sa, NULL); + + racoon_free(loc); + racoon_free(rem); +@@ -360,7 +363,7 @@ admin_process(so2, combuf) + plog(LLV_INFO, LOCATION, NULL, + "Flushing all SAs for peer %s\n", rem); + +- while ((iph1 = getph1bydstaddrwop(dst)) != NULL) { ++ while ((iph1 = getph1bydstaddr(dst)) != NULL) { + loc = racoon_strdup(saddrwop2str(iph1->local)); + STRDUP_FATAL(loc); + +@@ -429,7 +432,7 @@ admin_process(so2, combuf) + l_ac_errno = -1; + + /* connected already? */ +- ph1 = getph1byaddrwop(src, dst); ++ ph1 = getph1byaddr(src, dst, 0); + if (ph1 != NULL) { + event_list = &ph1->evt_listeners; + if (ph1->status == PHASE1ST_ESTABLISHED) +diff --git a/src/racoon/grabmyaddr.c b/src/racoon/grabmyaddr.c +index f866dd5..cb1b638 100644 +--- a/src/racoon/grabmyaddr.c ++++ b/src/racoon/grabmyaddr.c +@@ -100,7 +100,7 @@ myaddr_configured(addr) + return TRUE; + + LIST_FOREACH(cfg, &configured, chain) { +- if (cmpsaddrstrict(addr, (struct sockaddr *) &cfg->addr) == 0) ++ if (cmpsaddr(addr, (struct sockaddr *) &cfg->addr) == 0) + return TRUE; + } + +@@ -116,7 +116,7 @@ myaddr_open(addr, udp_encap) + + /* Already open? */ + LIST_FOREACH(my, &opened, chain) { +- if (cmpsaddrstrict(addr, (struct sockaddr *) &my->addr) == 0) ++ if (cmpsaddr(addr, (struct sockaddr *) &my->addr) == 0) + return TRUE; + } + +@@ -156,7 +156,7 @@ myaddr_open_all_configured(addr) + + LIST_FOREACH(cfg, &configured, chain) { + if (addr != NULL && +- cmpsaddrwop(addr, (struct sockaddr *) &cfg->addr) != 0) ++ cmpsaddr(addr, (struct sockaddr *) &cfg->addr) != 0) + continue; + if (!myaddr_open((struct sockaddr *) &cfg->addr, cfg->udp_encap)) + return FALSE; +@@ -187,8 +187,8 @@ myaddr_close_all_open(addr) + for (my = LIST_FIRST(&opened); my; my = next) { + next = LIST_NEXT(my, chain); + +- if (!cmpsaddrwop((struct sockaddr *) &addr, +- (struct sockaddr *) &my->addr)) ++ if (!cmpsaddr((struct sockaddr *) &addr, ++ (struct sockaddr *) &my->addr)) + myaddr_delete(my); + } + } +@@ -261,7 +261,7 @@ myaddr_getfd(addr) + struct myaddr *my; + + LIST_FOREACH(my, &opened, chain) { +- if (cmpsaddrstrict((struct sockaddr *) &my->addr, addr) == 0) ++ if (cmpsaddr((struct sockaddr *) &my->addr, addr) == 0) + return my->fd; + } + +@@ -273,19 +273,13 @@ myaddr_getsport(addr) + struct sockaddr *addr; + { + struct myaddr *my; +- int bestmatch_port = -1; + + LIST_FOREACH(my, &opened, chain) { +- if (cmpsaddrstrict((struct sockaddr *) &my->addr, addr) == 0) ++ if (cmpsaddr((struct sockaddr *) &my->addr, addr) == 0) + return extract_port((struct sockaddr *) &my->addr); +- if (cmpsaddrwop((struct sockaddr *) &my->addr, addr) != 0) +- continue; +- if (bestmatch_port == -1 || +- extract_port((struct sockaddr *) &my->addr) == PORT_ISAKMP) +- bestmatch_port = extract_port((struct sockaddr *) &my->addr); + } + +- return bestmatch_port; ++ return PORT_ISAKMP; + } + + void +diff --git a/src/racoon/handler.c b/src/racoon/handler.c +index 960b5b3..b33986f 100644 +--- a/src/racoon/handler.c ++++ b/src/racoon/handler.c +@@ -120,11 +120,11 @@ enumph1(sel, enum_func, enum_arg) + LIST_FOREACH(p, &ph1tree, chain) { + if (sel != NULL) { + if (sel->local != NULL && +- CMPSADDR(sel->local, p->local) != 0) ++ cmpsaddr(sel->local, p->local) != 0) + continue; + + if (sel->remote != NULL && +- CMPSADDR(sel->remote, p->remote) != 0) ++ cmpsaddr(sel->remote, p->remote) != 0) + continue; + } + +@@ -201,17 +201,12 @@ getph1(rmconf, local, remote, flags) + "status %d, skipping\n", p->status); + continue; + } +- if (flags & GETPH1_F_WITHOUT_PORTS) { +- if (local != NULL && cmpsaddrwop(local, p->local) != 0) +- continue; +- if (remote != NULL && cmpsaddrwop(remote, p->remote) != 0) +- continue; +- } else { +- if (local != NULL && CMPSADDR(local, p->local) != 0) +- continue; +- if (remote != NULL && CMPSADDR(remote, p->remote) != 0) +- continue; +- } ++ ++ if (local != NULL && cmpsaddr(local, p->local) != 0) ++ continue; ++ ++ if (remote != NULL && cmpsaddr(remote, p->remote) != 0) ++ continue; + + plog(LLV_DEBUG2, LOCATION, NULL, "matched\n"); + return p; +@@ -287,8 +282,8 @@ void migrate_dying_ph12(iph1) + if (p->status < PHASE1ST_DYING) + continue; + +- if (CMPSADDR(iph1->local, p->local) == 0 +- && CMPSADDR(iph1->remote, p->remote) == 0) ++ if (cmpsaddr(iph1->local, p->local) == 0 ++ && cmpsaddr(iph1->remote, p->remote) == 0) + migrate_ph12(p, iph1); + } + } +@@ -518,11 +513,11 @@ enumph2(sel, enum_func, enum_arg) + continue; + + if (sel->src != NULL && +- CMPSADDR(sel->src, p->src) != 0) ++ cmpsaddr(sel->src, p->src) != 0) + continue; + + if (sel->dst != NULL && +- CMPSADDR(sel->dst, p->dst) != 0) ++ cmpsaddr(sel->dst, p->dst) != 0) + continue; + } + +@@ -586,8 +581,8 @@ getph2byid(src, dst, spid) + + LIST_FOREACH(p, &ph2tree, chain) { + if (spid == p->spid && +- cmpsaddrwild(src, p->src) == 0 && +- cmpsaddrwild(dst, p->dst) == 0){ ++ cmpsaddr(src, p->src) == 0 && ++ cmpsaddr(dst, p->dst) == 0){ + /* Sanity check to detect zombie handlers + * XXX Sould be done "somewhere" more interesting, + * because we have lots of getph2byxxxx(), but this one +@@ -614,8 +609,8 @@ getph2bysaddr(src, dst) + struct ph2handle *p; + + LIST_FOREACH(p, &ph2tree, chain) { +- if (cmpsaddrstrict(src, p->src) == 0 && +- cmpsaddrstrict(dst, p->dst) == 0) ++ if (cmpsaddr(src, p->src) == 0 && ++ cmpsaddr(dst, p->dst) == 0) + return p; + } + +@@ -918,7 +913,7 @@ getcontacted(remote) + struct contacted *p; + + LIST_FOREACH(p, &ctdtree, chain) { +- if (cmpsaddrstrict(remote, p->remote) == 0) ++ if (cmpsaddr(remote, p->remote) == 0) + return p; + } + +@@ -997,7 +992,7 @@ check_recvdpkt(remote, local, rbuf) + /* + * the packet was processed before, but the remote address mismatches. + */ +- if (cmpsaddrstrict(remote, r->remote) != 0) ++ if (cmpsaddr(remote, r->remote) != 0) + return 2; + + /* +diff --git a/src/racoon/handler.h b/src/racoon/handler.h +index c31753d..8f19c88 100644 +--- a/src/racoon/handler.h ++++ b/src/racoon/handler.h +@@ -467,7 +467,6 @@ extern int enumph1 __P((struct ph1selector *ph1sel, + void *enum_arg)); + + #define GETPH1_F_ESTABLISHED 0x0001 +-#define GETPH1_F_WITHOUT_PORTS 0x0002 + + extern struct ph1handle *getph1 __P((struct remoteconf *rmconf, + struct sockaddr *local, +@@ -476,10 +475,8 @@ extern struct ph1handle *getph1 __P((struct remoteconf *rmconf, + + #define getph1byaddr(local, remote, est) \ + getph1(NULL, local, remote, est ? GETPH1_F_ESTABLISHED : 0) +-#define getph1byaddrwop(local, remote) \ +- getph1(NULL, local, remote, GETPH1_F_WITHOUT_PORTS) +-#define getph1bydstaddrwop(remote) \ +- getph1(NULL, NULL, remote, GETPH1_F_WITHOUT_PORTS) ++#define getph1bydstaddr(remote) \ ++ getph1(NULL, NULL, remote, 0) + + #ifdef ENABLE_HYBRID + struct ph1handle *getph1bylogin __P((char *)); +diff --git a/src/racoon/isakmp.c b/src/racoon/isakmp.c +index fe51653..0de16d1 100644 +--- a/src/racoon/isakmp.c ++++ b/src/racoon/isakmp.c +@@ -475,8 +475,8 @@ isakmp_main(msg, remote, local) + /* Floating ports for NAT-T */ + if (NATT_AVAILABLE(iph1) && + ! (iph1->natt_flags & NAT_PORTS_CHANGED) && +- ((cmpsaddrstrict(iph1->remote, remote) != 0) || +- (cmpsaddrstrict(iph1->local, local) != 0))) ++ ((cmpsaddr(iph1->remote, remote) != 0) || ++ (cmpsaddr(iph1->local, local) != 0))) + { + /* prevent memory leak */ + racoon_free(iph1->remote); +@@ -517,7 +517,7 @@ isakmp_main(msg, remote, local) + #endif + + /* must be same addresses in one stream of a phase at least. */ +- if (cmpsaddrstrict(iph1->remote, remote) != 0) { ++ if (cmpsaddr(iph1->remote, remote) != 0) { + char *saddr_db, *saddr_act; + + saddr_db = racoon_strdup(saddr2str(iph1->remote)); +@@ -643,7 +643,7 @@ isakmp_main(msg, remote, local) + "exchange received.\n"); + return -1; + } +- if (cmpsaddrstrict(iph1->remote, remote) != 0) { ++ if (cmpsaddr(iph1->remote, remote) != 0) { + plog(LLV_WARNING, LOCATION, remote, + "remote address mismatched. " + "db=%s\n", +@@ -1275,6 +1275,12 @@ isakmp_ph2begin_i(iph1, iph2) + } + #endif + ++ /* fixup ph2 ports for this ph1 */ ++ if (extract_port(iph2->src) == 0) ++ set_port(iph2->src, extract_port(iph1->local)); ++ if (extract_port(iph2->dst) == 0) ++ set_port(iph2->dst, extract_port(iph1->remote)); ++ + /* found ISAKMP-SA. */ + plog(LLV_DEBUG, LOCATION, NULL, "===\n"); + plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n"); +@@ -1353,15 +1359,6 @@ isakmp_ph2begin_r(iph1, msg) + delph2(iph2); + return -1; + } +-#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) +- if (set_port(iph2->dst, 0) == NULL || +- set_port(iph2->src, 0) == NULL) { +- plog(LLV_ERROR, LOCATION, NULL, +- "invalid family: %d\n", iph2->dst->sa_family); +- delph2(iph2); +- return -1; +- } +-#endif + + /* add new entry to isakmp status table */ + insph2(iph2); +@@ -2186,23 +2183,12 @@ isakmp_post_acquire(iph2) + return 0; + } + +- /* +- * Search isakmp status table by address and port +- * If NAT-T is in use, consider null ports as a +- * wildcard and use IKE ports instead. ++ /* ++ * XXX Searching by IP addresses + ports might fail on ++ * some cases, we should use the ISAKMP identity to search ++ * matching ISAKMP. + */ +-#ifdef ENABLE_NATT +- if (!extract_port(iph2->src) && !extract_port(iph2->dst)) { +- if ((iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL) { +- set_port(iph2->src, extract_port(iph1->local)); +- set_port(iph2->dst, extract_port(iph1->remote)); +- } +- } else { +- iph1 = getph1byaddr(iph2->src, iph2->dst, 0); +- } +-#else + iph1 = getph1byaddr(iph2->src, iph2->dst, 0); +-#endif + + /* no ISAKMP-SA found. */ + if (iph1 == NULL) { +@@ -2380,26 +2366,8 @@ isakmp_chkph1there(iph2) + return; + } + +- /* +- * Search isakmp status table by address and port +- * If NAT-T is in use, consider null ports as a +- * wildcard and use IKE ports instead. +- */ +-#ifdef ENABLE_NATT +- if (!extract_port(iph2->src) && !extract_port(iph2->dst)) { +- plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: extract_port.\n"); +- if( (iph1 = getph1byaddrwop(iph2->src, iph2->dst)) != NULL){ +- plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: found a ph1 wop.\n"); +- } +- } else { +- plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: searching byaddr.\n"); +- iph1 = getph1byaddr(iph2->src, iph2->dst, 0); +- if(iph1 != NULL) +- plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: found byaddr.\n"); +- } +-#else ++ /* Search isakmp status table by address and port */ + iph1 = getph1byaddr(iph2->src, iph2->dst, 0); +-#endif + + /* XXX Even if ph1 as responder is there, should we not start + * phase 2 negotiation ? */ +@@ -3321,20 +3289,10 @@ purge_remote(iph1) + msg = next; + continue; + } ++ pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + +-#ifdef SADB_X_NAT_T_NEW_MAPPING +- if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) { +- /* NAT-T is enabled for this SADB entry; copy +- * the ports from NAT-T extensions */ +- if(mhp[SADB_X_EXT_NAT_T_SPORT] != NULL) +- set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT])); +- if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL) +- set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT])); +- } +-#endif +- + if (sa->sadb_sa_state != SADB_SASTATE_LARVAL && + sa->sadb_sa_state != SADB_SASTATE_MATURE && + sa->sadb_sa_state != SADB_SASTATE_DYING) { +@@ -3346,22 +3304,14 @@ purge_remote(iph1) + * check in/outbound SAs. + * Select only SAs where src == local and dst == remote (outgoing) + * or src == remote and dst == local (incoming). +- * XXX we sometime have src/dst ports set to 0 and want to match +- * iph1->local/remote with ports set to 500. This is a bug, see trac:2 + */ +-#ifdef ENABLE_NATT +- if ((cmpsaddrmagic(iph1->local, src) || cmpsaddrmagic(iph1->remote, dst)) && +- (cmpsaddrmagic(iph1->local, dst) || cmpsaddrmagic(iph1->remote, src))) { +- msg = next; +- continue; +- } +-#else +- if ((CMPSADDR(iph1->local, src) || CMPSADDR(iph1->remote, dst)) && +- (CMPSADDR(iph1->local, dst) || CMPSADDR(iph1->remote, src))) { ++ if ((cmpsaddr(iph1->local, src) || ++ cmpsaddr(iph1->remote, dst)) && ++ (cmpsaddr(iph1->local, dst) || ++ cmpsaddr(iph1->remote, src))) { + msg = next; + continue; + } +-#endif + + proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); + iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); +diff --git a/src/racoon/isakmp_cfg.c b/src/racoon/isakmp_cfg.c +index 62916f8..df763f8 100644 +--- a/src/racoon/isakmp_cfg.c ++++ b/src/racoon/isakmp_cfg.c +@@ -1151,15 +1151,6 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange) + goto end; + } + +-#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) +- if (set_port(iph2->dst, 0) == NULL || +- set_port(iph2->src, 0) == NULL) { +- plog(LLV_ERROR, LOCATION, NULL, +- "invalid family: %d\n", iph1->remote->sa_family); +- delph2(iph2); +- goto end; +- } +-#endif + iph2->side = INITIATOR; + iph2->status = PHASE2ST_START; + +diff --git a/src/racoon/isakmp_inf.c b/src/racoon/isakmp_inf.c +index a712825..6fa3498 100644 +--- a/src/racoon/isakmp_inf.c ++++ b/src/racoon/isakmp_inf.c +@@ -903,15 +903,6 @@ isakmp_info_send_common(iph1, payload, np, flags) + delph2(iph2); + goto end; + } +-#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) +- if (set_port(iph2->dst, 0) == NULL || +- set_port(iph2->src, 0) == NULL) { +- plog(LLV_ERROR, LOCATION, NULL, +- "invalid family: %d\n", iph1->remote->sa_family); +- delph2(iph2); +- goto end; +- } +-#endif + iph2->side = INITIATOR; + iph2->status = PHASE2ST_START; + iph2->msgid = isakmp_newmsgid2(iph1); +@@ -1127,9 +1118,6 @@ purge_ipsec_spi(dst0, proto, spi, n) + u_int64_t created; + size_t i; + caddr_t mhp[SADB_EXT_MAX + 1]; +-#ifdef ENABLE_NATT +- int natt_port_forced; +-#endif + + plog(LLV_DEBUG2, LOCATION, NULL, + "purge_ipsec_spi:\n"); +@@ -1169,6 +1157,7 @@ purge_ipsec_spi(dst0, proto, spi, n) + msg = next; + continue; + } ++ pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; +@@ -1182,28 +1171,7 @@ purge_ipsec_spi(dst0, proto, spi, n) + msg = next; + continue; + } +-#ifdef ENABLE_NATT +- if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) { +- /* NAT-T is enabled for this SADB entry; copy +- * the ports from NAT-T extensions */ +- if (extract_port(src) == 0 && +- mhp[SADB_X_EXT_NAT_T_SPORT] != NULL) { +- set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT])); +- } + +- if (extract_port(dst) == 0 && +- mhp[SADB_X_EXT_NAT_T_DPORT] != NULL) { +- set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT])); +- } +- natt_port_forced = 0; +- } else { +- /* Force default UDP ports, so +- * CMPSADDR will match SAs with NO encapsulation */ +- set_port(src, PORT_ISAKMP); +- set_port(dst, PORT_ISAKMP); +- natt_port_forced = 1; +- } +-#endif + plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(src)); + plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(dst)); + +@@ -1211,19 +1179,11 @@ purge_ipsec_spi(dst0, proto, spi, n) + + /* don't delete inbound SAs at the moment */ + /* XXX should we remove SAs with opposite direction as well? */ +- if (CMPSADDR(dst0, dst)) { ++ if (cmpsaddr(dst0, dst)) { + msg = next; + continue; + } + +-#ifdef ENABLE_NATT +- if (natt_port_forced) { +- /* Set back port to 0 if it was forced +- * to default UDP port */ +- set_port(src, 0); +- set_port(dst, 0); +- } +-#endif + for (i = 0; i < n; i++) { + plog(LLV_DEBUG, LOCATION, NULL, + "check spi(packet)=%u spi(db)=%u.\n", +@@ -1354,37 +1314,33 @@ isakmp_info_recv_initialcontact(iph1, protectedph2) + msg = (struct sadb_msg *)buf->v; + end = (struct sadb_msg *)(buf->v + buf->l); + +- while (msg < end) { ++ for (; msg < end; msg = next) { + if ((msg->sadb_msg_len << 3) < sizeof(*msg)) + break; ++ + next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); +- if (msg->sadb_msg_type != SADB_DUMP) { +- msg = next; ++ if (msg->sadb_msg_type != SADB_DUMP) + continue; +- } + + if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { + plog(LLV_ERROR, LOCATION, NULL, + "pfkey_check (%s)\n", ipsec_strerror()); +- msg = next; + continue; + } + + if (mhp[SADB_EXT_SA] == NULL + || mhp[SADB_EXT_ADDRESS_SRC] == NULL +- || mhp[SADB_EXT_ADDRESS_DST] == NULL) { +- msg = next; ++ || mhp[SADB_EXT_ADDRESS_DST] == NULL) + continue; +- } ++ + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; ++ pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + + if (sa->sadb_sa_state != SADB_SASTATE_MATURE +- && sa->sadb_sa_state != SADB_SASTATE_DYING) { +- msg = next; ++ && sa->sadb_sa_state != SADB_SASTATE_DYING) + continue; +- } + + /* + * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that +@@ -1394,39 +1350,18 @@ isakmp_info_recv_initialcontact(iph1, protectedph2) + * racoon only deletes SA which is matched both the + * source address and the destination accress. + */ +-#ifdef ENABLE_NATT +- /* +- * XXX RFC 3947 says that whe MUST NOT use IP+port to find old SAs +- * from this peer ! +- */ +- if(iph1->natt_flags & NAT_DETECTED){ +- if (CMPSADDR(iph1->local, src) == 0 && +- CMPSADDR(iph1->remote, dst) == 0) +- ; +- else if (CMPSADDR(iph1->remote, src) == 0 && +- CMPSADDR(iph1->local, dst) == 0) +- ; +- else { +- msg = next; +- continue; +- } +- } else +-#endif +- /* If there is no NAT-T, we don't have to check addr + port... +- * XXX what about a configuration with a remote peers which is not +- * NATed, but which NATs some other peers ? +- * Here, the INITIAl-CONTACT would also flush all those NATed peers !! +- */ +- if (cmpsaddrwop(iph1->local, src) == 0 && +- cmpsaddrwop(iph1->remote, dst) == 0) +- ; +- else if (cmpsaddrwop(iph1->remote, src) == 0 && +- cmpsaddrwop(iph1->local, dst) == 0) +- ; +- else { +- msg = next; ++ ++ /* ++ * Check that the IP and port match. But this is not optimal, ++ * since NAT-T can make the peer have multiple different ++ * ports. Correct thing to do is delete all entries with ++ * same identity. -TT ++ */ ++ if ((cmpsaddr(iph1->local, src) != 0 || ++ cmpsaddr(iph1->remote, dst) != 0) && ++ (cmpsaddr(iph1->local, dst) != 0 || ++ cmpsaddr(iph1->remote, src) != 0)) + continue; +- } + + /* + * Make sure this is an SATYPE that we manage. +@@ -1438,10 +1373,8 @@ isakmp_info_recv_initialcontact(iph1, protectedph2) + msg->sadb_msg_satype) + break; + } +- if (i == pfkey_nsatypes) { +- msg = next; ++ if (i == pfkey_nsatypes) + continue; +- } + + plog(LLV_INFO, LOCATION, NULL, + "purging spi=%u.\n", ntohl(sa->sadb_sa_spi)); +@@ -1461,8 +1394,6 @@ isakmp_info_recv_initialcontact(iph1, protectedph2) + remph2(iph2); + delph2(iph2); + } +- +- msg = next; + } + + vfree(buf); +diff --git a/src/racoon/isakmp_quick.c b/src/racoon/isakmp_quick.c +index 804c1bf..46c84c1 100644 +--- a/src/racoon/isakmp_quick.c ++++ b/src/racoon/isakmp_quick.c +@@ -610,17 +610,19 @@ quick_i2recv(iph2, msg0) + error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED; + goto end; + } ++#ifdef ENABLE_NATT ++ set_port(iph2->natoa_src, ++ extract_port((struct sockaddr *) &proposed_addr)); ++#endif + +- if (cmpsaddrstrict((struct sockaddr *) &proposed_addr, +- (struct sockaddr *) &got_addr) == 0) { ++ if (cmpsaddr((struct sockaddr *) &proposed_addr, ++ (struct sockaddr *) &got_addr) == 0) { + plog(LLV_DEBUG, LOCATION, NULL, + "IDci matches proposal.\n"); + #ifdef ENABLE_NATT + } else if (iph2->natoa_src != NULL +- && cmpsaddrwop(iph2->natoa_src, +- (struct sockaddr *) &got_addr) == 0 +- && extract_port((struct sockaddr *) &proposed_addr) == +- extract_port((struct sockaddr *) &got_addr)) { ++ && cmpsaddr(iph2->natoa_src, ++ (struct sockaddr *) &got_addr) == 0) { + plog(LLV_DEBUG, LOCATION, NULL, + "IDci matches NAT-OAi.\n"); + #endif +@@ -656,16 +658,19 @@ quick_i2recv(iph2, msg0) + goto end; + } + +- if (cmpsaddrstrict((struct sockaddr *) &proposed_addr, +- (struct sockaddr *) &got_addr) == 0) { ++#ifdef ENABLE_NATT ++ set_port(iph2->natoa_dst, ++ extract_port((struct sockaddr *) &proposed_addr)); ++#endif ++ ++ if (cmpsaddr((struct sockaddr *) &proposed_addr, ++ (struct sockaddr *) &got_addr) == 0) { + plog(LLV_DEBUG, LOCATION, NULL, + "IDcr matches proposal.\n"); + #ifdef ENABLE_NATT + } else if (iph2->natoa_dst != NULL +- && cmpsaddrwop(iph2->natoa_dst, +- (struct sockaddr *) &got_addr) == 0 +- && extract_port((struct sockaddr *) &proposed_addr) == +- extract_port((struct sockaddr *) &got_addr)) { ++ && cmpsaddr(iph2->natoa_dst, ++ (struct sockaddr *) &got_addr) == 0) { + plog(LLV_DEBUG, LOCATION, NULL, + "IDcr matches NAT-OAr.\n"); + #endif +diff --git a/src/racoon/nattraversal.c b/src/racoon/nattraversal.c +index f23341a..92095de 100644 +--- a/src/racoon/nattraversal.c ++++ b/src/racoon/nattraversal.c +@@ -379,8 +379,8 @@ natt_keepalive_add (struct sockaddr *src, struct sockaddr *dst) + struct natt_ka_addrs *ka = NULL, *new_addr; + + TAILQ_FOREACH (ka, &ka_tree, chain) { +- if (cmpsaddrstrict(ka->src, src) == 0 && +- cmpsaddrstrict(ka->dst, dst) == 0) { ++ if (cmpsaddr(ka->src, src) == 0 && ++ cmpsaddr(ka->dst, dst) == 0) { + ka->in_use++; + plog (LLV_INFO, LOCATION, NULL, "KA found: %s (in_use=%u)\n", + saddr2str_fromto("%s->%s", src, dst), ka->in_use); +@@ -443,8 +443,8 @@ natt_keepalive_remove (struct sockaddr *src, struct sockaddr *dst) + plog (LLV_DEBUG, LOCATION, NULL, "KA tree dump: %s (in_use=%u)\n", + saddr2str_fromto("%s->%s", src, dst), ka->in_use); + +- if (cmpsaddrstrict(ka->src, src) == 0 && +- cmpsaddrstrict(ka->dst, dst) == 0 && ++ if (cmpsaddr(ka->src, src) == 0 && ++ cmpsaddr(ka->dst, dst) == 0 && + -- ka->in_use <= 0) { + + plog (LLV_DEBUG, LOCATION, NULL, "KA removing this one...\n"); +diff --git a/src/racoon/pfkey.c b/src/racoon/pfkey.c +index c210c5e..3778ef2 100644 +--- a/src/racoon/pfkey.c ++++ b/src/racoon/pfkey.c +@@ -774,8 +774,12 @@ pk_fixup_sa_addresses(mhp) + caddr_t *mhp; + { + struct sockaddr *src, *dst; ++ + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); ++ set_port(src, PORT_ISAKMP); ++ set_port(dst, PORT_ISAKMP); ++ + #ifdef ENABLE_NATT + if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) { + /* NAT-T is enabled for this SADB entry; copy +@@ -785,9 +789,6 @@ pk_fixup_sa_addresses(mhp) + if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL) + set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT])); + } +-#else +- set_port(src, 0); +- set_port(dst, 0); + #endif + } + +@@ -949,10 +950,6 @@ pk_sendgetspi(iph2) + dport=extract_port(dst); + } + #endif +- /* Always remove port information, it will be sent in +- * SADB_X_EXT_NAT_T_[S|D]PORT if needed */ +- set_port(src, 0); +- set_port(dst, 0); + + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n"); + if (pfkey_send_getspi_nat( +@@ -1009,6 +1006,7 @@ pk_recvgetspi(mhp) + } + msg = (struct sadb_msg *)mhp[0]; + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; ++ pk_fixup_sa_addresses(mhp); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); /* note SA dir */ + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + +@@ -1183,18 +1181,14 @@ pk_sendupdate(iph2) + #ifdef ENABLE_NATT + if (pr->udp_encap) { + sa_args.l_natt_type = iph2->ph1->natt_options->encaps_type; +- sa_args.l_natt_sport = extract_port (iph2->ph1->remote); +- sa_args.l_natt_dport = extract_port (iph2->ph1->local); ++ sa_args.l_natt_sport = extract_port(iph2->ph1->remote); ++ sa_args.l_natt_dport = extract_port(iph2->ph1->local); + sa_args.l_natt_oa = iph2->natoa_src; + #ifdef SADB_X_EXT_NAT_T_FRAG + sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag; + #endif + } + #endif +- /* Always remove port information, it will be sent in +- * SADB_X_EXT_NAT_T_[S|D]PORT if needed */ +- set_port(sa_args.src, 0); +- set_port(sa_args.dst, 0); + + /* more info to fill in */ + sa_args.spi = pr->spi; +@@ -1358,14 +1352,6 @@ pk_recvupdate(mhp) + /* turn off schedule */ + sched_cancel(&iph2->scr); + +- /* Force the update of ph2's ports, as there is at least one +- * situation where they'll mismatch with ph1's values +- */ +-#ifdef ENABLE_NATT +- set_port(iph2->src, extract_port(iph2->ph1->local)); +- set_port(iph2->dst, extract_port(iph2->ph1->remote)); +-#endif +- + /* + * since we are going to reuse the phase2 handler, we need to + * remain it and refresh all the references between ph1 and ph2 to use. +@@ -1418,7 +1404,7 @@ pk_sendadd(iph2) + racoon_free(sa_args.src); + racoon_free(sa_args.dst); + return -1; +- } ++ } + + for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { + /* validity check */ +@@ -1490,11 +1476,6 @@ pk_sendadd(iph2) + #endif + } + #endif +- /* Always remove port information, it will be sent in +- * SADB_X_EXT_NAT_T_[S|D]PORT if needed */ +- set_port(sa_args.src, 0); +- set_port(sa_args.dst, 0); +- + /* more info to fill in */ + sa_args.spi = pr->spi_p; + sa_args.reqid = pr->reqid_out; +@@ -1559,6 +1540,7 @@ pk_recvadd(mhp) + return -1; + } + msg = (struct sadb_msg *)mhp[0]; ++ pk_fixup_sa_addresses(mhp); + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; +@@ -1749,7 +1731,9 @@ pk_recvacquire(mhp) + } + msg = (struct sadb_msg *)mhp[0]; + xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; +- pk_fixup_sa_addresses(mhp); ++ /* acquire does not have nat-t ports; so do not bother setting ++ * the default port 500; just use the port zero for wildcard ++ * matching the get a valid natted destination */ + sp_src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); + sp_dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + +@@ -2884,8 +2868,8 @@ migrate_ph1_ike_addresses(iph1, arg) + u_int16_t port; + + /* Already up-to-date? */ +- if (cmpsaddrwop(iph1->local, ma->local) == 0 && +- cmpsaddrwop(iph1->remote, ma->remote) == 0) ++ if (cmpsaddr(iph1->local, ma->local) == 0 && ++ cmpsaddr(iph1->remote, ma->remote) == 0) + return 0; + + if (iph1->status < PHASE1ST_ESTABLISHED) { +@@ -2985,8 +2969,8 @@ migrate_ph2_ike_addresses(iph2, arg) + migrate_ph1_ike_addresses(iph2->ph1, arg); + + /* Already up-to-date? */ +- if (CMPSADDR(iph2->src, ma->local) == 0 && +- CMPSADDR(iph2->dst, ma->remote) == 0) ++ if (cmpsaddr(iph2->src, ma->local) == 0 && ++ cmpsaddr(iph2->dst, ma->remote) == 0) + return 0; + + /* save src/dst as sa_src/sa_dst before rewriting */ +@@ -3206,8 +3190,8 @@ migrate_ph2_one_isr(spid, isr_cur, xisr_old, xisr_new) + "changing address families (%d to %d) for endpoints.\n", + osaddr->sa_family, nsaddr->sa_family); + +- if (CMPSADDR(osaddr, (struct sockaddr *)&saidx->src) || +- CMPSADDR(odaddr, (struct sockaddr *)&saidx->dst)) { ++ if (cmpsaddr(osaddr, (struct sockaddr *) &saidx->src) || ++ cmpsaddr(odaddr, (struct sockaddr *) &saidx->dst)) { + plog(LLV_DEBUG, LOCATION, NULL, "SADB_X_MIGRATE: " + "mismatch of addresses in saidx and xisr.\n"); + return -1; +diff --git a/src/racoon/policy.c b/src/racoon/policy.c +index 850fa6b..058753f 100644 +--- a/src/racoon/policy.c ++++ b/src/racoon/policy.c +@@ -141,16 +141,18 @@ getsp_r(spidx, iph2) + saddr2str(iph2->src)); + plog(LLV_DEBUG, LOCATION, NULL, "src2: %s\n", + saddr2str((struct sockaddr *)&spidx->src)); +- if (cmpsaddrwop(iph2->src, (struct sockaddr *)&spidx->src) +- || spidx->prefs != prefixlen) ++ ++ if (cmpsaddr(iph2->src, (struct sockaddr *) &spidx->src) || ++ spidx->prefs != prefixlen) + return NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "dst1: %s\n", + saddr2str(iph2->dst)); + plog(LLV_DEBUG, LOCATION, NULL, "dst2: %s\n", + saddr2str((struct sockaddr *)&spidx->dst)); +- if (cmpsaddrwop(iph2->dst, (struct sockaddr *)&spidx->dst) +- || spidx->prefd != prefixlen) ++ ++ if (cmpsaddr(iph2->dst, (struct sockaddr *) &spidx->dst) || ++ spidx->prefd != prefixlen) + return NULL; + + plog(LLV_DEBUG, LOCATION, NULL, "looks to be transport mode\n"); +@@ -198,11 +200,11 @@ cmpspidxstrict(a, b) + || a->ul_proto != b->ul_proto) + return 1; + +- if (cmpsaddrstrict((struct sockaddr *)&a->src, +- (struct sockaddr *)&b->src)) ++ if (cmpsaddr((struct sockaddr *) &a->src, ++ (struct sockaddr *) &b->src)) + return 1; +- if (cmpsaddrstrict((struct sockaddr *)&a->dst, +- (struct sockaddr *)&b->dst)) ++ if (cmpsaddr((struct sockaddr *) &a->dst, ++ (struct sockaddr *) &b->dst)) + return 1; + + #ifdef HAVE_SECCTX +@@ -259,7 +261,7 @@ cmpspidxwild(a, b) + a, b->prefs, saddr2str((struct sockaddr *)&sa1)); + plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n", + b, b->prefs, saddr2str((struct sockaddr *)&sa2)); +- if (cmpsaddrwild((struct sockaddr *)&sa1, (struct sockaddr *)&sa2)) ++ if (cmpsaddr((struct sockaddr *)&sa1, (struct sockaddr *)&sa2)) + return 1; + + #ifndef __linux__ +@@ -277,7 +279,7 @@ cmpspidxwild(a, b) + a, b->prefd, saddr2str((struct sockaddr *)&sa1)); + plog(LLV_DEBUG, LOCATION, NULL, "%p masked with /%d: %s\n", + b, b->prefd, saddr2str((struct sockaddr *)&sa2)); +- if (cmpsaddrwild((struct sockaddr *)&sa1, (struct sockaddr *)&sa2)) ++ if (cmpsaddr((struct sockaddr *)&sa1, (struct sockaddr *)&sa2)) + return 1; + + #ifdef HAVE_SECCTX +diff --git a/src/racoon/remoteconf.c b/src/racoon/remoteconf.c +index 73d80bc..88c622c 100644 +--- a/src/racoon/remoteconf.c ++++ b/src/racoon/remoteconf.c +@@ -200,15 +200,9 @@ rmconf_match_type(rmsel, rmconf) + /* Check address */ + if (rmsel->remote != NULL) { + if (rmconf->remote->sa_family != AF_UNSPEC) { +- if (rmsel->flags & GETRMCONF_F_NO_PORTS) { +- if (cmpsaddrwop(rmsel->remote, +- rmconf->remote) != 0) +- return 0; +- } else { +- if (cmpsaddrstrict(rmsel->remote, +- rmconf->remote) != 0) +- return 0; +- } ++ if (cmpsaddr(rmsel->remote, rmconf->remote) != 0) ++ return 0; ++ + /* Address matched */ + ret = 2; + } +@@ -262,7 +256,7 @@ void rmconf_selector_from_ph1(rmsel, iph1) + struct ph1handle *iph1; + { + memset(rmsel, 0, sizeof(*rmsel)); +- rmsel->flags = GETRMCONF_F_NO_PORTS; ++ rmsel->flags = 0; + rmsel->remote = iph1->remote; + rmsel->etype = iph1->etype; + rmsel->approval = iph1->approval; +@@ -357,22 +351,8 @@ getrmconf(remote, flags) + int n = 0; + + memset(&ctx, 0, sizeof(ctx)); +- ctx.sel.flags = flags | GETRMCONF_F_NO_PORTS; ++ ctx.sel.flags = flags; + ctx.sel.remote = remote; +-#ifndef ENABLE_NATT +- /* +- * We never have ports set in our remote configurations, but when +- * NAT-T is enabled, the kernel can have policies with ports and +- * send us an acquire message for a destination that has a port set. +- * If we do this port check here, we don't find the remote config. +- * +- * In an ideal world, we would be able to have remote conf with +- * port, and the port could be a wildcard. That test could be used. +- */ +- if (remote->sa_family != AF_UNSPEC && +- extract_port(remote) != IPSEC_PORT_ANY) +- ctx.sel.flags &= ~GETRMCONF_F_NO_PORTS; +-#endif /* ENABLE_NATT */ + + if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) { + plog(LLV_ERROR, LOCATION, remote, +diff --git a/src/racoon/remoteconf.h b/src/racoon/remoteconf.h +index 38faf03..b2e9e4a 100644 +--- a/src/racoon/remoteconf.h ++++ b/src/racoon/remoteconf.h +@@ -189,8 +189,7 @@ extern int enumrmconf __P((struct rmconfselector *rmsel, + void *enum_arg)); + + #define GETRMCONF_F_NO_ANONYMOUS 0x0001 +-#define GETRMCONF_F_NO_PORTS 0x0002 +-#define GETRMCONF_F_NO_PASSIVE 0x0004 ++#define GETRMCONF_F_NO_PASSIVE 0x0002 + + #define RMCONF_ERR_MULTIPLE ((struct remoteconf *) -1) + +diff --git a/src/racoon/sockmisc.c b/src/racoon/sockmisc.c +index 5c1f9c7..2bc2177 100644 +--- a/src/racoon/sockmisc.c ++++ b/src/racoon/sockmisc.c +@@ -80,87 +77,28 @@ + const int niflags = 0; + + /* +- * compare two sockaddr without port number. +- * OUT: 0: equal. +- * 1: not equal. +- */ +-int +-cmpsaddrwop(addr1, addr2) +- const struct sockaddr *addr1; +- const struct sockaddr *addr2; +-{ +- caddr_t sa1, sa2; +- +- if (addr1 == 0 && addr2 == 0) +- return 0; +- if (addr1 == 0 || addr2 == 0) +- return 1; +- +-#ifdef __linux__ +- if (addr1->sa_family != addr2->sa_family) +- return 1; +-#else +- if (addr1->sa_len != addr2->sa_len +- || addr1->sa_family != addr2->sa_family) +- return 1; +- +-#endif /* __linux__ */ +- +- switch (addr1->sa_family) { +- case AF_UNSPEC: +- break; +- case AF_INET: +- sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr; +- sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr; +- if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0) +- return 1; +- break; +-#ifdef INET6 +- case AF_INET6: +- sa1 = (caddr_t)&((struct sockaddr_in6 *)addr1)->sin6_addr; +- sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr; +- if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0) +- return 1; +- if (((struct sockaddr_in6 *)addr1)->sin6_scope_id != +- ((struct sockaddr_in6 *)addr2)->sin6_scope_id) +- return 1; +- break; +-#endif +- default: +- return 1; +- } +- +- return 0; +-} +- +-/* + * compare two sockaddr with port, taking care wildcard. + * addr1 is a subject address, addr2 is in a database entry. + * OUT: 0: equal. + * 1: not equal. + */ + int +-cmpsaddrwild(addr1, addr2) ++cmpsaddr(addr1, addr2) + const struct sockaddr *addr1; + const struct sockaddr *addr2; + { + caddr_t sa1, sa2; + u_short port1, port2; + +- if (addr1 == 0 && addr2 == 0) +- return 0; +- if (addr1 == 0 || addr2 == 0) +- return 1; ++ if (addr1 == NULL && addr2 == NULL) ++ return CMPSADDR_MATCH; + +-#ifdef __linux__ +- if (addr1->sa_family != addr2->sa_family) +- return 1; +-#else +- if (addr1->sa_len != addr2->sa_len +- || addr1->sa_family != addr2->sa_family) +- return 1; ++ if (addr1 == NULL || addr2 == NULL) ++ return CMPSADDR_MISMATCH; + +-#endif /* __linux__ */ ++ if (addr1->sa_family != addr2->sa_family || ++ sysdep_sa_len(addr1) != sysdep_sa_len(addr2)) ++ return CMPSADDR_MISMATCH; + + switch (addr1->sa_family) { + case AF_UNSPEC: +@@ -170,12 +108,8 @@ cmpsaddrwild(addr1, addr2) + sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr; + port1 = ((struct sockaddr_in *)addr1)->sin_port; + port2 = ((struct sockaddr_in *)addr2)->sin_port; +- if (!(port1 == IPSEC_PORT_ANY || +- port2 == IPSEC_PORT_ANY || +- port1 == port2)) +- return 1; + if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0) +- return 1; ++ return CMPSADDR_MISMATCH; + break; + #ifdef INET6 + case AF_INET6: +@@ -183,155 +117,23 @@ cmpsaddrwild(addr1, addr2) + sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr; + port1 = ((struct sockaddr_in6 *)addr1)->sin6_port; + port2 = ((struct sockaddr_in6 *)addr2)->sin6_port; +- if (!(port1 == IPSEC_PORT_ANY || +- port2 == IPSEC_PORT_ANY || +- port1 == port2)) +- return 1; + if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0) +- return 1; ++ return CMPSADDR_MISMATCH; + if (((struct sockaddr_in6 *)addr1)->sin6_scope_id != + ((struct sockaddr_in6 *)addr2)->sin6_scope_id) +- return 1; ++ return CMPSADDR_MISMATCH; + break; + #endif + default: +- return 1; ++ return CMPSADDR_MISMATCH; + } + +- return 0; +-} +- +-/* +- * compare two sockaddr with port, taking care specific situation: +- * one addr has 0 as port, and the other has 500 (network order), return equal +- * OUT: 0: equal. +- * 1: not equal. +- */ +-int +-cmpsaddrmagic(addr1, addr2) +- const struct sockaddr *addr1; +- const struct sockaddr *addr2; +-{ +- caddr_t sa1, sa2; +- u_short port1, port2; +- +- if (addr1 == 0 && addr2 == 0) +- return 0; +- if (addr1 == 0 || addr2 == 0) +- return 1; +- +-#ifdef __linux__ +- if (addr1->sa_family != addr2->sa_family) +- return 1; +-#else +- if (addr1->sa_len != addr2->sa_len +- || addr1->sa_family != addr2->sa_family) +- return 1; ++ if (port1 == port2 || ++ port1 == IPSEC_PORT_ANY || ++ port2 == IPSEC_PORT_ANY) ++ return CMPSADDR_MATCH; + +-#endif /* __linux__ */ +- +- switch (addr1->sa_family) { +- case AF_UNSPEC: +- break; +- case AF_INET: +- sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr; +- sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr; +- port1 = ((struct sockaddr_in *)addr1)->sin_port; +- port2 = ((struct sockaddr_in *)addr2)->sin_port; +- plog(LLV_DEBUG, LOCATION, NULL, "cmpsaddr_magic: port1 == %d, port2 == %d\n", port1, port2); +- if (!((port1 == IPSEC_PORT_ANY && port2 == ntohs(PORT_ISAKMP)) || +- (port2 == IPSEC_PORT_ANY && port1 == ntohs(PORT_ISAKMP)) || +- (port1 == port2))){ +- plog(LLV_DEBUG, LOCATION, NULL, "cmpsaddr_magic: ports mismatch\n"); +- return 1; +- } +- plog(LLV_DEBUG, LOCATION, NULL, "cmpsaddr_magic: ports matched\n"); +- if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0) +- return 1; +- break; +-#ifdef INET6 +- case AF_INET6: +- sa1 = (caddr_t)&((struct sockaddr_in6 *)addr1)->sin6_addr; +- sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr; +- port1 = ((struct sockaddr_in6 *)addr1)->sin6_port; +- port2 = ((struct sockaddr_in6 *)addr2)->sin6_port; +- if (!((port1 == IPSEC_PORT_ANY && port2 == PORT_ISAKMP) || +- (port2 == IPSEC_PORT_ANY && port1 == PORT_ISAKMP) || +- (port1 == port2))) +- return 1; +- if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0) +- return 1; +- if (((struct sockaddr_in6 *)addr1)->sin6_scope_id != +- ((struct sockaddr_in6 *)addr2)->sin6_scope_id) +- return 1; +- break; +-#endif +- default: +- return 1; +- } +- +- return 0; +-} +- +-/* +- * compare two sockaddr with strict match on port. +- * OUT: 0: equal. +- * 1: not equal. +- */ +-int +-cmpsaddrstrict(addr1, addr2) +- const struct sockaddr *addr1; +- const struct sockaddr *addr2; +-{ +- caddr_t sa1, sa2; +- u_short port1, port2; +- +- if (addr1 == 0 && addr2 == 0) +- return 0; +- if (addr1 == 0 || addr2 == 0) +- return 1; +- +-#ifdef __linux__ +- if (addr1->sa_family != addr2->sa_family) +- return 1; +-#else +- if (addr1->sa_len != addr2->sa_len +- || addr1->sa_family != addr2->sa_family) +- return 1; +- +-#endif /* __linux__ */ +- +- switch (addr1->sa_family) { +- case AF_INET: +- sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr; +- sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr; +- port1 = ((struct sockaddr_in *)addr1)->sin_port; +- port2 = ((struct sockaddr_in *)addr2)->sin_port; +- if (port1 != port2) +- return 1; +- if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0) +- return 1; +- break; +-#ifdef INET6 +- case AF_INET6: +- sa1 = (caddr_t)&((struct sockaddr_in6 *)addr1)->sin6_addr; +- sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr; +- port1 = ((struct sockaddr_in6 *)addr1)->sin6_port; +- port2 = ((struct sockaddr_in6 *)addr2)->sin6_port; +- if (port1 != port2) +- return 1; +- if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0) +- return 1; +- if (((struct sockaddr_in6 *)addr1)->sin6_scope_id != +- ((struct sockaddr_in6 *)addr2)->sin6_scope_id) +- return 1; +- break; +-#endif +- default: +- return 1; +- } +- +- return 0; ++ return CMPSADDR_WOP_MATCH; + } + + /* get local address against the destination. */ +@@ -1129,7 +931,7 @@ naddr_score(const struct netaddr *naddr, const struct sockaddr *saddr) + free(a2); + free(a3); + } +- if (cmpsaddrwop(&sa, &naddr->sa.sa) == 0) ++ if (cmpsaddr(&sa, &naddr->sa.sa) == 0) + return naddr->prefix + port_score; + + return -1; +diff --git a/src/racoon/sockmisc.h b/src/racoon/sockmisc.h +index fcc286f..0a58f44 100644 +--- a/src/racoon/sockmisc.h ++++ b/src/racoon/sockmisc.h +@@ -54,16 +54,11 @@ struct netaddr { + + extern const int niflags; + +-extern int cmpsaddrwop __P((const struct sockaddr *, const struct sockaddr *)); +-extern int cmpsaddrwild __P((const struct sockaddr *, const struct sockaddr *)); +-extern int cmpsaddrstrict __P((const struct sockaddr *, const struct sockaddr *)); +-extern int cmpsaddrmagic __P((const struct sockaddr *, const struct sockaddr *)); +- +-#ifdef ENABLE_NATT +-#define CMPSADDR(saddr1, saddr2) cmpsaddrstrict((saddr1), (saddr2)) +-#else +-#define CMPSADDR(saddr1, saddr2) cmpsaddrwop((saddr1), (saddr2)) +-#endif ++#define CMPSADDR_MATCH 0 ++#define CMPSADDR_WOP_MATCH 1 ++#define CMPSADDR_MISMATCH 2 ++ ++extern int cmpsaddr __P((const struct sockaddr *, const struct sockaddr *)); + + extern struct sockaddr *getlocaladdr __P((struct sockaddr *)); + +diff --git a/src/racoon/throttle.c b/src/racoon/throttle.c +index 5ab62c3..64b566b 100644 +--- a/src/racoon/throttle.c ++++ b/src/racoon/throttle.c +@@ -104,7 +104,7 @@ restart: + goto restart; + } + +- if (cmpsaddrwop(addr, (struct sockaddr *)&te->host) == 0) { ++ if (cmpsaddr(addr, (struct sockaddr *) &te->host) == 0) { + found = 1; + break; + } diff --git a/main/ipsec-tools/50-reverse-connect.patch b/main/ipsec-tools/50-reverse-connect.patch new file mode 100644 index 0000000000..c49eae347f --- /dev/null +++ b/main/ipsec-tools/50-reverse-connect.patch @@ -0,0 +1,207 @@ +When new ISAKMP is required, allow incoming reverse connection to take + +From: Timo Teras <timo.teras@iki.fi> + +over pending phase1:s. Useful when the other party is firewalled or NATted. +--- + + src/racoon/admin.c | 12 ++++++++++++ + src/racoon/evt.c | 13 +++++++++++++ + src/racoon/evt.h | 3 +++ + src/racoon/handler.c | 28 +++++++++++++++++++++------- + src/racoon/isakmp.c | 39 ++++++++++++++++++++++++++++++++++----- + 5 files changed, 83 insertions(+), 12 deletions(-) + + +diff --git a/src/racoon/admin.c b/src/racoon/admin.c +index b67e545..710c9bf 100644 +--- a/src/racoon/admin.c ++++ b/src/racoon/admin.c +@@ -414,11 +414,23 @@ admin_process(so2, combuf) + struct sockaddr *dst; + struct sockaddr *src; + char *name = NULL; ++ char *loc, *rem; + + ndx = (struct admin_com_indexes *) ((caddr_t)com + sizeof(*com)); + src = (struct sockaddr *) &ndx->src; + dst = (struct sockaddr *) &ndx->dst; + ++ loc = racoon_strdup(saddr2str(src)); ++ rem = racoon_strdup(saddr2str(dst)); ++ STRDUP_FATAL(loc); ++ STRDUP_FATAL(rem); ++ ++ plog(LLV_INFO, LOCATION, NULL, ++ "admin establish-sa %x %s %s\n", ++ com->ac_proto, loc, rem); ++ racoon_free(loc); ++ racoon_free(rem); ++ + if (com->ac_cmd == ADMIN_ESTABLISH_SA && + com->ac_len > sizeof(*com) + sizeof(*ndx)) + name = (char *) ((caddr_t) ndx + sizeof(*ndx)); +diff --git a/src/racoon/evt.c b/src/racoon/evt.c +index 4ce1334..000c1f8 100644 +--- a/src/racoon/evt.c ++++ b/src/racoon/evt.c +@@ -396,4 +396,17 @@ evt_list_cleanup(list) + evt_unsubscribe(LIST_FIRST(list)); + } + ++void ++evt_list_move(from, to) ++ struct evt_listener_list *from, *to; ++{ ++ struct evt_listener *l; ++ ++ while (!LIST_EMPTY(from)) { ++ l = LIST_FIRST(from); ++ LIST_REMOVE(l, ll_chain); ++ LIST_INSERT_HEAD(to, l, ll_chain); ++ } ++} ++ + #endif /* ENABLE_ADMINPORT */ +diff --git a/src/racoon/evt.h b/src/racoon/evt.h +index 0ce65bd..ba7fb57 100644 +--- a/src/racoon/evt.h ++++ b/src/racoon/evt.h +@@ -124,6 +124,8 @@ void evt_phase2 __P((const struct ph2handle *ph2, int type, vchar_t *optdata)); + vchar_t *evt_dump __P((void)); + + int evt_subscribe __P((struct evt_listener_list *list, int fd)); ++void evt_list_move __P((struct evt_listener_list *from, ++ struct evt_listener_list *to)); + void evt_list_init __P((struct evt_listener_list *list)); + void evt_list_cleanup __P((struct evt_listener_list *list)); + +@@ -136,6 +138,7 @@ void evt_list_cleanup __P((struct evt_listener_list *list)); + #define evt_phase2(ph2, type, optdata) ; + + #define evt_subscribe(eventlist, fd) ; ++#deifne evt_list_move(from, to) ; + #define evt_list_init(eventlist) ; + #define evt_list_cleanup(eventlist) ; + #define evt_get_fdmask(nfds, fdset) nfds +diff --git a/src/racoon/handler.c b/src/racoon/handler.c +index b33986f..9fd3817 100644 +--- a/src/racoon/handler.c ++++ b/src/racoon/handler.c +@@ -269,26 +269,40 @@ migrate_ph12(old_iph1, new_iph1) + } + + /* +- * the iph1 is new, migrate all phase2s that belong to a dying or dead ph1 ++ * the iph1 is new, migrate all phase2s that belong to a dying or dead ph1. + */ + void migrate_dying_ph12(iph1) + struct ph1handle *iph1; + { +- struct ph1handle *p; ++ struct ph1handle *p, *next; + +- LIST_FOREACH(p, &ph1tree, chain) { ++ for (p = LIST_FIRST(&ph1tree); p; p = next) { ++ next = LIST_NEXT(p, chain); + if (p == iph1) + continue; +- if (p->status < PHASE1ST_DYING) ++ ++ /* Same remote? */ ++ if (cmpsaddr(iph1->local, p->local) > CMPSADDR_WOP_MATCH || ++ cmpsaddr(iph1->remote, p->remote) > CMPSADDR_WOP_MATCH || ++ iph1->rmconf != p->rmconf) + continue; + +- if (cmpsaddr(iph1->local, p->local) == 0 +- && cmpsaddr(iph1->remote, p->remote) == 0) ++ /* migrate phase2:s from expiring entries */ ++ if (p->status >= PHASE1ST_DYING) + migrate_ph12(p, iph1); ++ ++ /* and allow reverse connections to release ++ * pending connections that do not work due ++ * to firewall or nat */ ++ if (iph1->side == RESPONDER && p->side == INITIATOR && ++ p->status < PHASE1ST_MSG3RECEIVED) { ++ evt_list_move(&p->evt_listeners, &iph1->evt_listeners); ++ remph1(p); ++ delph1(p); ++ } + } + } + +- + /* + * dump isakmp-sa + */ +diff --git a/src/racoon/isakmp.c b/src/racoon/isakmp.c +index 0de16d1..2dfda2f 100644 +--- a/src/racoon/isakmp.c ++++ b/src/racoon/isakmp.c +@@ -2138,13 +2138,33 @@ isakmp_ph2delete(iph2) + + remph2(iph2); + delph2(iph2); +- +- return; + } + + /* %%% + * Interface between PF_KEYv2 and ISAKMP + */ ++ ++static void ++isakmp_chkph2there(p) ++ struct sched *p; ++{ ++ struct ph2handle *iph2 = container_of(p, struct ph2handle, sce); ++ struct ph2handle *tmp; ++ ++ /* Check if a similar phase2 appared meanwhile */ ++ remph2(iph2); ++ tmp = getph2byid(iph2->src, iph2->dst, iph2->spid); ++ if (tmp == NULL) { ++ /* Nope, lets start this then */ ++ insph2(iph2); ++ isakmp_chkph1there(iph2); ++ } else { ++ /* Yes, delete this initiation attempt as redundant */ ++ evt_phase2(iph2, EVT_PHASE2_UP, NULL); ++ delph2(iph2); ++ } ++} ++ + /* + * receive ACQUIRE from kernel, and begin either phase1 or phase2. + * if phase1 has been finished, begin phase2. +@@ -2220,8 +2240,14 @@ isakmp_post_acquire(iph2) + /*NOTREACHED*/ + } + +- /* found established ISAKMP-SA */ +- /* i.e. iph1->status == PHASE1ST_ESTABLISHED */ ++ /* found established ISAKMP-SA, if this is a RESPONDER ISAKMP-SA ++ * add a small delay; this will make sure the initiator gets ++ * an first attempt at rekeying, and usually avoids duplicate ph2:s */ ++ if (iph1->side == RESPONDER) { ++ iph2->retry_checkph1 = 1; ++ sched_schedule(&iph2->sce, 1, isakmp_chkph2there); ++ return 0; ++ } + + /* found ISAKMP-SA. */ + plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n"); +@@ -2388,7 +2414,10 @@ isakmp_chkph1there(iph2) + plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst)); + + /* begin quick mode */ +- (void)isakmp_ph2begin_i(iph1, iph2); ++ if (isakmp_ph2begin_i(iph1, iph2)) { ++ remph2(iph2); ++ delph2(iph2); ++ } + return; + } + diff --git a/main/ipsec-tools/60-debug-quick.patch b/main/ipsec-tools/60-debug-quick.patch new file mode 100644 index 0000000000..a5c3346ee9 --- /dev/null +++ b/main/ipsec-tools/60-debug-quick.patch @@ -0,0 +1,211 @@ +debugging prints for quick mode errors + +From: Timo Teras <timo.teras@iki.fi> + + +--- + + src/racoon/isakmp.c | 21 ++++++++++++++------- + src/racoon/isakmp_quick.c | 46 ++++++++++++++++++++++++++++++++++++++------- + 2 files changed, 53 insertions(+), 14 deletions(-) + + +diff --git a/src/racoon/isakmp.c b/src/racoon/isakmp.c +index 2dfda2f..87ce598 100644 +--- a/src/racoon/isakmp.c ++++ b/src/racoon/isakmp.c +@@ -817,7 +817,8 @@ ph1_main(iph1, msg) + + if (iph1->side == RESPONDER && iph1->status == PHASE1ST_START) { + plog(LLV_ERROR, LOCATION, iph1->remote, +- "failed to pre-process packet.\n"); ++ "failed to pre-process ph1 packet (side: %d, status %d).\n", ++ iph1->side, iph1->status); + return -1; + } else { + /* ignore the error and keep phase 1 handler */ +@@ -845,7 +846,8 @@ ph1_main(iph1, msg) + [iph1->side] + [iph1->status])(iph1, msg) != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, +- "failed to process packet.\n"); ++ "failed to process ph1 packet (side: %d, status: %d).\n", ++ iph1->side, iph1->status); + return -1; + } + +@@ -997,7 +999,8 @@ quick_main(iph2, msg) + [iph2->status])(iph2, msg); + if (error != 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, +- "failed to pre-process packet.\n"); ++ "failed to pre-process ph2 packet (side: %d, status %d).\n", ++ iph2->side, iph2->status); + if (error == ISAKMP_INTERNAL_ERROR) + return 0; + isakmp_info_send_n1(iph2->ph1, error, NULL); +@@ -1025,7 +1028,8 @@ quick_main(iph2, msg) + [iph2->side] + [iph2->status])(iph2, msg) != 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, +- "failed to process packet.\n"); ++ "failed to process ph2 packet (side: %d, status: %d).\n", ++ iph2->side, iph2->status); + return -1; + } + +@@ -1233,7 +1237,8 @@ isakmp_ph1begin_r(msg, remote, local, etype) + [iph1->side] + [iph1->status])(iph1, msg) < 0) { + plog(LLV_ERROR, LOCATION, remote, +- "failed to process packet.\n"); ++ "failed to process ph1 packet (side: %d, status: %d).\n", ++ iph1->side, iph1->status); + remph1(iph1); + delph1(iph1); + return -1; +@@ -1386,7 +1391,8 @@ isakmp_ph2begin_r(iph1, msg) + [iph2->status])(iph2, msg); + if (error != 0) { + plog(LLV_ERROR, LOCATION, iph1->remote, +- "failed to pre-process packet.\n"); ++ "failed to pre-process ph2 packet (side: %d, status: %d).\n", ++ iph2->side, iph2->status); + if (error != ISAKMP_INTERNAL_ERROR) + isakmp_info_send_n1(iph2->ph1, error, NULL); + /* +@@ -1404,7 +1410,8 @@ isakmp_ph2begin_r(iph1, msg) + [iph2->side] + [iph2->status])(iph2, msg) < 0) { + plog(LLV_ERROR, LOCATION, iph2->ph1->remote, +- "failed to process packet.\n"); ++ "failed to process ph2 packet (side: %d, status: %d).\n", ++ iph2->side, iph2->status); + /* don't release handler */ + return -1; + } +diff --git a/src/racoon/isakmp_quick.c b/src/racoon/isakmp_quick.c +index 46c84c1..2657407 100644 +--- a/src/racoon/isakmp_quick.c ++++ b/src/racoon/isakmp_quick.c +@@ -495,18 +495,27 @@ quick_i2recv(iph2, msg0) + "isn't supported.\n"); + break; + } +- if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) ++ if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) { ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "duplicate ISAKMP_NPTYPE_SA.\n"); + goto end; ++ } + break; + + case ISAKMP_NPTYPE_NONCE: +- if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) ++ if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) { ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "duplicate ISAKMP_NPTYPE_NONCE.\n"); + goto end; ++ } + break; + + case ISAKMP_NPTYPE_KE: +- if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) ++ if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) { ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "duplicate ISAKMP_NPTYPE_KE.\n"); + goto end; ++ } + break; + + case ISAKMP_NPTYPE_ID: +@@ -517,6 +526,8 @@ quick_i2recv(iph2, msg0) + if (isakmp_p2ph(&idcr, pa->ptr) < 0) + goto end; + } else { ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "too many ISAKMP_NPTYPE_ID payloads.\n"); + goto end; + } + break; +@@ -557,6 +568,8 @@ quick_i2recv(iph2, msg0) + iph2->natoa_dst = daddr; + else { + racoon_free(daddr); ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "too many ISAKMP_NPTYPE_NATOA payloads.\n"); + goto end; + } + } +@@ -718,6 +731,8 @@ quick_i2recv(iph2, msg0) + + /* validity check SA payload sent from responder */ + if (ipsecdoi_checkph2proposal(iph2) < 0) { ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "proposal check failed.\n"); + error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; + goto end; + } +@@ -1077,8 +1092,11 @@ quick_r1recv(iph2, msg0) + } + /* decrypt packet */ + msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive); +- if (msg == NULL) ++ if (msg == NULL) { ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "Packet decryption failed.\n"); + goto end; ++ } + + /* create buffer for using to validate HASH(1) */ + /* +@@ -1162,18 +1180,27 @@ quick_r1recv(iph2, msg0) + "Multi SAs isn't supported.\n"); + goto end; + } +- if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) ++ if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) { ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "duplicate ISAKMP_NPTYPE_SA.\n"); + goto end; ++ } + break; + + case ISAKMP_NPTYPE_NONCE: +- if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) ++ if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) { ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "duplicate ISAKMP_NPTYPE_NONCE.\n"); + goto end; ++ } + break; + + case ISAKMP_NPTYPE_KE: +- if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) ++ if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) { ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "duplicate ISAKMP_NPTYPE_KE.\n"); + goto end; ++ } + break; + + case ISAKMP_NPTYPE_ID: +@@ -1241,6 +1268,9 @@ quick_r1recv(iph2, msg0) + iph2->natoa_src = daddr; + else { + racoon_free(daddr); ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "received too many NAT-OA payloads.\n"); ++ error = ISAKMP_NTYPE_PAYLOAD_MALFORMED; + goto end; + } + } +@@ -1333,6 +1363,8 @@ quick_r1recv(iph2, msg0) + case 0: + /* select single proposal or reject it. */ + if (ipsecdoi_selectph2proposal(iph2) < 0) { ++ plog(LLV_ERROR, LOCATION, iph2->ph1->remote, ++ "no proposal chosen.\n"); + error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; + goto end; + } diff --git a/main/ipsec-tools/APKBUILD b/main/ipsec-tools/APKBUILD new file mode 100644 index 0000000000..b947b9b695 --- /dev/null +++ b/main/ipsec-tools/APKBUILD @@ -0,0 +1,59 @@ +# Maintainer: Natanael Copa <ncopa@alpinelinux.org> +pkgname=ipsec-tools +pkgver=0.8_alpha20090422 +_myver=0.8-alpha20090422 +pkgrel=0 +pkgdesc="User-space IPsec tools for various IPsec implementations" +url="http://ipsec-tools.sourceforge.net/" +license="BSD" +depends="openssl uclibc" +makedepends="openssl-dev bison flex" +subpackages="$pkgname-doc $pkgname-dev" +source="http://downloads.sourceforge.net/$pkgname/$pkgname-$_myver.tar.gz + racoon.initd + racoon.confd + 00-verify-cert-leak.patch + 20-natoa-fix.patch + 30-natt-ports-cleanup.patch + 40-cmpsaddr-cleanup.patch + 50-reverse-connect.patch + 60-debug-quick.patch + " + +build() { + cd "$srcdir/$pkgname-$_myver" + for i in ../*.patch; do + msg "Applying $i..." + patch -p1 -i $i || return 1 + done + sed -i 's:-Werror::g' configure + + ./configure --prefix=/usr \ + --sysconfdir=/etc \ + --mandir=/usr/share/man \ + --infodir=/usr/share/info \ + --localstatedir=/var/lib \ + --with-kernel-headers=/usr/include \ + --disable-security-context \ + --enable-adminport \ + --enable-dpd \ + --enable-frag \ + --enable-hybrid \ + --enable-ipv6 \ + --enable-natt + make || return 1 + make DESTDIR="$pkgdir" install + + install -D -m755 ../racoon.initd "$pkgdir"/etc/init.d/racoon + install -D -m644 ../racoon.confd "$pkgdir"/etc/conf.d/racoon +} + +md5sums="8327401b5d1aa91e9c554d2cc536f823 ipsec-tools-0.8-alpha20090422.tar.gz +16d66458442750e6401fa459e93172b7 racoon.initd +788e3de82c1c6532dab0dc0c19c1bf40 racoon.confd +e0abf570c29519e8e36406dfc3bbe3c8 00-verify-cert-leak.patch +2adb8796c75f62811b08c8370c75312c 20-natoa-fix.patch +17b3f05426537afa1e94947c39b10163 30-natt-ports-cleanup.patch +5fcaf5a01340132d4bfe55997bc5c60b 40-cmpsaddr-cleanup.patch +91eb6da2726c4ed83df990f6908a7553 50-reverse-connect.patch +baa13d7f0f48955c792f7fcd42a8587a 60-debug-quick.patch" diff --git a/main/ipsec-tools/racoon.confd b/main/ipsec-tools/racoon.confd new file mode 100644 index 0000000000..66f8ed7674 --- /dev/null +++ b/main/ipsec-tools/racoon.confd @@ -0,0 +1,19 @@ +# Copyright 1999-2004 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/net-firewall/ipsec-tools/files/racoon.conf.d,v 1.3 2004/07/14 23:29:57 agriffis Exp $ + +# Config file for /etc/init.d/racoon + +# See the manual pages for racoon or run `racoon --help` +# for valid command-line options + +RACOON_OPTS="-4" + +RACOON_CONF="/etc/racoon/racoon.conf" +RACOON_PSK_FILE="/etc/racoon/psk.txt" +SETKEY_CONF="/etc/ipsec.conf" + +# Comment or remove the following if you don't want the policy tables +# to be flushed when racoon is stopped. + +RACOON_RESET_TABLES="true" diff --git a/main/ipsec-tools/racoon.initd b/main/ipsec-tools/racoon.initd new file mode 100644 index 0000000000..16fdec7e3a --- /dev/null +++ b/main/ipsec-tools/racoon.initd @@ -0,0 +1,58 @@ +#!/sbin/runscript +# Copyright 1999-2004 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +depend() { + before netmount + use net +} + +checkconfig() { + if [ ! -e ${SETKEY_CONF} ] ; then + eerror "You need to configure setkey before starting racoon." + return 1 + fi + if [ ! -e ${RACOON_CONF} ] ; then + eerror "You need a configuration file to start racoon." + return 1 + fi + if [ ! -z ${RACOON_PSK_FILE} ] ; then + if [ ! -f ${RACOON_PSK_FILE} ] ; then + eerror "PSK file not found as specified." + eerror "Set RACOON_PSK_FILE in /etc/conf.d/racoon." + return 1 + fi + case "`ls -Lldn ${RACOON_PSK_FILE}`" in + -r--------*) + ;; + *) + eerror "Your defined PSK file should be mode 400 for security!" + return 1 + ;; + esac + fi +} + +start() { + checkconfig || return 1 + einfo "Loading ipsec policies from ${SETKEY_CONF}." + /usr/sbin/setkey -f ${SETKEY_CONF} + if [ $? -eq 1 ] ; then + eerror "Error while loading ipsec policies" + fi + ebegin "Starting racoon" + start-stop-daemon -S -x /usr/sbin/racoon -- -f ${RACOON_CONF} ${RACOON_OPTS} + eend $? +} + +stop() { + ebegin "Stopping racoon" + start-stop-daemon -K -p /var/run/racoon.pid + eend $? + if [ -n "${RACOON_RESET_TABLES}" ]; then + ebegin "Flushing policy entries" + /usr/sbin/setkey -F + /usr/sbin/setkey -FP + eend $? + fi +} |