diff options
Diffstat (limited to 'main/ipsec-tools/30-natt-ports-cleanup.patch')
-rw-r--r-- | main/ipsec-tools/30-natt-ports-cleanup.patch | 393 |
1 files changed, 393 insertions, 0 deletions
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 00000000000..19360347dac --- /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 *)); |