From 12f0053dbbd5ad74eb22a18de4826a47a69fb615 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jun 28 2017 15:09:46 +0000 Subject: import conntrack-tools-1.4.4-3.el7_3 --- diff --git a/.conntrack-tools.metadata b/.conntrack-tools.metadata index 26de907..174887b 100644 --- a/.conntrack-tools.metadata +++ b/.conntrack-tools.metadata @@ -1 +1 @@ -509db30f34b283f4a74a7e638ba0ca713d3fe98c SOURCES/conntrack-tools-1.4.3.tar.bz2 +25b36fb6832373ef899bade3b82adf5382b9a05b SOURCES/conntrack-tools-1.4.4.tar.bz2 diff --git a/.gitignore b/.gitignore index b447185..e5fee0e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/conntrack-tools-1.4.3.tar.bz2 +SOURCES/conntrack-tools-1.4.4.tar.bz2 diff --git a/SOURCES/conntrack-tools-1.4.4-conntrack.patch b/SOURCES/conntrack-tools-1.4.4-conntrack.patch new file mode 100644 index 0000000..5148073 --- /dev/null +++ b/SOURCES/conntrack-tools-1.4.4-conntrack.patch @@ -0,0 +1,438 @@ +diff --git a/src/conntrack.c b/src/conntrack.c +index bd337f4..6e96b58 100644 +--- a/src/conntrack.c ++++ b/src/conntrack.c +@@ -43,6 +43,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -437,6 +439,9 @@ static const int opt2type[] = { + static const int opt2maskopt[] = { + ['s'] = '{', + ['d'] = '}', ++ ['g'] = 0, ++ ['j'] = 0, ++ ['n'] = 0, + ['r'] = 0, /* no netmask */ + ['q'] = 0, /* support yet */ + ['{'] = 0, +@@ -448,6 +453,8 @@ static const int opt2maskopt[] = { + static const int opt2family_attr[][2] = { + ['s'] = { ATTR_ORIG_IPV4_SRC, ATTR_ORIG_IPV6_SRC }, + ['d'] = { ATTR_ORIG_IPV4_DST, ATTR_ORIG_IPV6_DST }, ++ ['g'] = { ATTR_DNAT_IPV4, ATTR_DNAT_IPV6 }, ++ ['n'] = { ATTR_SNAT_IPV4, ATTR_SNAT_IPV6 }, + ['r'] = { ATTR_REPL_IPV4_SRC, ATTR_REPL_IPV6_SRC }, + ['q'] = { ATTR_REPL_IPV4_DST, ATTR_REPL_IPV6_DST }, + ['{'] = { ATTR_ORIG_IPV4_SRC, ATTR_ORIG_IPV6_SRC }, +@@ -459,6 +466,8 @@ static const int opt2family_attr[][2] = { + static const int opt2attr[] = { + ['s'] = ATTR_ORIG_L3PROTO, + ['d'] = ATTR_ORIG_L3PROTO, ++ ['g'] = ATTR_ORIG_L3PROTO, ++ ['n'] = ATTR_ORIG_L3PROTO, + ['r'] = ATTR_REPL_L3PROTO, + ['q'] = ATTR_REPL_L3PROTO, + ['{'] = ATTR_ORIG_L3PROTO, +@@ -1094,58 +1103,85 @@ parse_addr(const char *cp, union ct_address *address, int *mask) + return family; + } + +-static void +-nat_parse(char *arg, struct nf_conntrack *obj, int type) ++static bool ++valid_port(char *cursor) + { +- char *colon, *error; +- union ct_address parse; ++ const char *str = cursor; ++ /* Missing port number */ ++ if (!*str) ++ return false; + +- colon = strchr(arg, ':'); ++ /* Must be entirely digits - no spaces or +/- */ ++ while (*cursor) { ++ if (!isdigit(*cursor)) ++ return false; ++ else ++ ++cursor; ++ } + +- if (colon) { +- uint16_t port; ++ /* Must be in range */ ++ errno = 0; ++ long port = strtol(str, NULL, 10); + +- *colon = '\0'; ++ if ((errno == ERANGE && (port == LONG_MAX || port == LONG_MIN)) ++ || (errno != 0 && port == 0) || (port > USHRT_MAX)) ++ return false; + +- port = (uint16_t)atoi(colon+1); +- if (port == 0) { +- if (strlen(colon+1) == 0) { +- exit_error(PARAMETER_PROBLEM, +- "No port specified after `:'"); +- } else { +- exit_error(PARAMETER_PROBLEM, +- "Port `%s' not valid", colon+1); +- } +- } ++ return true; ++} ++ ++static void ++split_address_and_port(const char *arg, char **address, char **port_str) ++{ ++ char *cursor = strchr(arg, '['); ++ ++ if (cursor) { ++ /* IPv6 address with port*/ ++ char *start = cursor + 1; + +- error = strchr(colon+1, ':'); +- if (error) ++ cursor = strchr(start, ']'); ++ if (start == cursor) { ++ exit_error(PARAMETER_PROBLEM, ++ "No IPv6 address specified"); ++ } else if (!cursor) { + exit_error(PARAMETER_PROBLEM, +- "Invalid port:port syntax"); +- +- if (type == CT_OPT_SRC_NAT) +- nfct_set_attr_u16(tmpl.ct, ATTR_SNAT_PORT, ntohs(port)); +- else if (type == CT_OPT_DST_NAT) +- nfct_set_attr_u16(tmpl.ct, ATTR_DNAT_PORT, ntohs(port)); +- else if (type == CT_OPT_ANY_NAT) { +- nfct_set_attr_u16(tmpl.ct, ATTR_SNAT_PORT, ntohs(port)); +- nfct_set_attr_u16(tmpl.ct, ATTR_DNAT_PORT, ntohs(port)); ++ "No closing ']' around IPv6 address"); + } +- } ++ size_t len = cursor - start; + +- if (parse_addr(arg, &parse, NULL) == AF_UNSPEC) { +- if (strlen(arg) == 0) { +- exit_error(PARAMETER_PROBLEM, "No IP specified"); ++ cursor = strchr(cursor, ':'); ++ if (cursor) { ++ /* Copy address only if there is a port */ ++ *address = strndup(start, len); ++ } ++ } else { ++ cursor = strchr(arg, ':'); ++ if (cursor && !strchr(cursor + 1, ':')) { ++ /* IPv4 address with port */ ++ *address = strndup(arg, cursor - arg); + } else { ++ /* v6 address */ ++ cursor = NULL; ++ } ++ } ++ if (cursor) { ++ /* Parse port entry */ ++ cursor++; ++ if (strlen(cursor) == 0) { + exit_error(PARAMETER_PROBLEM, +- "Invalid IP address `%s'", arg); ++ "No port specified after `:'"); + } ++ if (!valid_port(cursor)) { ++ exit_error(PARAMETER_PROBLEM, ++ "Invalid port `%s'", cursor); ++ } ++ *port_str = strdup(cursor); ++ } else { ++ /* No port colon or more than one colon (ipv6) ++ * assume arg is straight IP address and no port ++ */ ++ *address = strdup(arg); + } +- +- if (type == CT_OPT_SRC_NAT || type == CT_OPT_ANY_NAT) +- nfct_set_attr_u32(tmpl.ct, ATTR_SNAT_IPV4, parse.v4); +- else if (type == CT_OPT_DST_NAT || type == CT_OPT_ANY_NAT) +- nfct_set_attr_u32(tmpl.ct, ATTR_DNAT_IPV4, parse.v4); + } + + static void +@@ -1289,7 +1325,7 @@ nfct_ip6_net_cmp(const union ct_address *addr, const struct ct_network *net) + + static int + nfct_ip_net_cmp(int family, const union ct_address *addr, +- const struct ct_network *net) ++ const struct ct_network *net) + { + switch(family) { + case AF_INET: +@@ -2128,6 +2164,7 @@ static void merge_bitmasks(struct nfct_bitmask **current, + nfct_bitmask_destroy(src); + } + ++ + static void + nfct_build_netmask(uint32_t *dst, int b, int n) + { +@@ -2147,10 +2184,9 @@ nfct_build_netmask(uint32_t *dst, int b, int n) + } + + static void +-nfct_set_addr_opt(int opt, struct nf_conntrack *ct, union ct_address *ad, +- int l3protonum) ++nfct_set_addr_only(const int opt, struct nf_conntrack *ct, union ct_address *ad, ++ const int l3protonum) + { +- options |= opt2type[opt]; + switch (l3protonum) { + case AF_INET: + nfct_set_attr_u32(ct, +@@ -2163,24 +2199,33 @@ nfct_set_addr_opt(int opt, struct nf_conntrack *ct, union ct_address *ad, + &ad->v6); + break; + } ++} ++ ++static void ++nfct_set_addr_opt(const int opt, struct nf_conntrack *ct, union ct_address *ad, ++ const int l3protonum) ++{ ++ options |= opt2type[opt]; ++ nfct_set_addr_only(opt, ct, ad, l3protonum); + nfct_set_attr_u8(ct, opt2attr[opt], l3protonum); + } + + static void +-nfct_parse_addr_from_opt(int opt, struct nf_conntrack *ct, +- struct nf_conntrack *ctmask, +- union ct_address *ad, int *family) ++nfct_parse_addr_from_opt(const int opt, const char *arg, ++ struct nf_conntrack *ct, ++ struct nf_conntrack *ctmask, ++ union ct_address *ad, int *family) + { +- int l3protonum, mask, maskopt; ++ int mask, maskopt; + +- l3protonum = parse_addr(optarg, ad, &mask); ++ const int l3protonum = parse_addr(arg, ad, &mask); + if (l3protonum == AF_UNSPEC) { + exit_error(PARAMETER_PROBLEM, +- "Invalid IP address `%s'", optarg); ++ "Invalid IP address `%s'", arg); + } + set_family(family, l3protonum); + maskopt = opt2maskopt[opt]; +- if (!maskopt && mask != -1) { ++ if (mask != -1 && !maskopt) { + exit_error(PARAMETER_PROBLEM, + "CIDR notation unavailable" + " for `--%s'", get_long_opt(opt)); +@@ -2192,7 +2237,7 @@ nfct_parse_addr_from_opt(int opt, struct nf_conntrack *ct, + nfct_set_addr_opt(opt, ct, ad, l3protonum); + + /* bail if we don't have a netmask to set*/ +- if (!maskopt || mask == -1 || ctmask == NULL) ++ if (mask == -1 || !maskopt || ctmask == NULL) + return; + + switch(l3protonum) { +@@ -2211,6 +2256,24 @@ nfct_parse_addr_from_opt(int opt, struct nf_conntrack *ct, + nfct_set_addr_opt(maskopt, ctmask, ad, l3protonum); + } + ++static void ++nfct_set_nat_details(const int opt, struct nf_conntrack *ct, ++ union ct_address *ad, const char *port_str, ++ const int family) ++{ ++ const int type = opt2type[opt]; ++ ++ nfct_set_addr_only(opt, ct, ad, family); ++ if (port_str && type == CT_OPT_SRC_NAT) { ++ nfct_set_attr_u16(ct, ATTR_SNAT_PORT, ++ ntohs((uint16_t)atoi(port_str))); ++ } else if (port_str && type == CT_OPT_DST_NAT) { ++ nfct_set_attr_u16(ct, ATTR_DNAT_PORT, ++ ntohs((uint16_t)atoi(port_str))); ++ } ++ ++} ++ + int main(int argc, char *argv[]) + { + int c, cmd; +@@ -2289,17 +2352,18 @@ int main(int argc, char *argv[]) + case 'd': + case 'r': + case 'q': +- nfct_parse_addr_from_opt(c, tmpl.ct, tmpl.mask, +- &ad, &family); ++ nfct_parse_addr_from_opt(c, optarg, tmpl.ct, ++ tmpl.mask, &ad, &family); + break; + case '[': + case ']': +- nfct_parse_addr_from_opt(c, tmpl.exptuple, tmpl.mask, +- &ad, &family); ++ nfct_parse_addr_from_opt(c, optarg, tmpl.exptuple, ++ tmpl.mask, &ad, &family); + break; + case '{': + case '}': +- nfct_parse_addr_from_opt(c, tmpl.mask, NULL, &ad, &family); ++ nfct_parse_addr_from_opt(c, optarg, tmpl.mask, ++ NULL, &ad, &family); + break; + case 'p': + options |= CT_OPT_PROTO; +@@ -2341,19 +2405,34 @@ int main(int argc, char *argv[]) + break; + case 'n': + case 'g': +- case 'j': { +- char *tmp = NULL; +- ++ case 'j': + options |= opt2type[c]; +- +- tmp = get_optional_arg(argc, argv); +- if (tmp == NULL) +- continue; +- +- set_family(&family, AF_INET); +- nat_parse(tmp, tmpl.ct, opt2type[c]); ++ char *optional_arg = get_optional_arg(argc, argv); ++ ++ if (optional_arg) { ++ char *port_str = NULL; ++ char *nat_address = NULL; ++ ++ split_address_and_port(optional_arg, ++ &nat_address, ++ &port_str); ++ nfct_parse_addr_from_opt(c, nat_address, ++ tmpl.ct, NULL, ++ &ad, &family); ++ if (c == 'j') { ++ /* Set details on both src and dst ++ * with any-nat ++ */ ++ nfct_set_nat_details('g', tmpl.ct, &ad, ++ port_str, family); ++ nfct_set_nat_details('n', tmpl.ct, &ad, ++ port_str, family); ++ } else { ++ nfct_set_nat_details(c, tmpl.ct, &ad, ++ port_str, family); ++ } ++ } + break; +- } + case 'w': + case '(': + case ')': +diff --git a/tests/conntrack/testsuite/00create b/tests/conntrack/testsuite/00create +index 40e2c19..afe4342 100644 +--- a/tests/conntrack/testsuite/00create ++++ b/tests/conntrack/testsuite/00create +@@ -18,3 +18,9 @@ + -I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; OK + # delete reverse + -D -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK ++# create a v6 conntrack ++-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK ++# delete v6 conntrack ++-D -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK ++# mismatched address family ++-I -s 2001:DB8::1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +diff --git a/tests/conntrack/testsuite/03nat b/tests/conntrack/testsuite/03nat +index f94e8ff..014feb8 100644 +--- a/tests/conntrack/testsuite/03nat ++++ b/tests/conntrack/testsuite/03nat +@@ -36,5 +36,13 @@ + -L --dst-nat 3.3.3.3:81 ; OK + # show + -L --dst-nat 1.1.1.1:80 ; OK ++# badport ++-L --dst-nat 1.1.1.1: ; BAD ++# badport ++-L --dst-nat 1.1.1.1::; BAD ++# badport ++-L --dst-nat 1.1.1.1:80:80; BAD ++# badport ++-L --dst-nat 1.1.1.1:65536; BAD + # delete + -D -s 1.1.1.1 ; OK +diff --git a/tests/conntrack/testsuite/07nat6 b/tests/conntrack/testsuite/07nat6 +new file mode 100644 +index 0000000..8cecd8e +--- /dev/null ++++ b/tests/conntrack/testsuite/07nat6 +@@ -0,0 +1,56 @@ ++# create dummy ++-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 --dst-nat 2001:DB8::3.3.3.3 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK ++# show ++-L --dst-nat ; OK ++# show ++-L --dst-nat 2001:DB8::3.3.3.3 ; OK ++# show ++-L --src-nat ; OK ++# delete ++-D -s 2001:DB8::1.1.1.1 ; OK ++# create dummy again ++-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 --src-nat 2001:DB8::3.3.3.3 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK ++# show ++-L --src-nat ; OK ++# show ++-L --src-nat 2001:DB8::3.3.3.3 ; OK ++# show ++-L --dst-nat ; OK ++# show any-nat ++-L --any-nat ; OK ++# delete ++-D -s 2001:DB8::1.1.1.1 ; OK ++# bad combination ++-L --dst-nat --any-nat ; BAD ++# bad combination ++-L --src-nat --any-nat ; BAD ++# bad combination ++-L --src-nat --dst-nat --any-nat ; BAD ++# create ++-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 --dst-nat [2001:DB8::3.3.3.3]:80 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK ++# show ++-L --dst-nat [2001:DB8::3.3.3.3]:80 ; OK ++# show ++-L --any-nat [2001:DB8::3.3.3.3]:80 ; OK ++# show ++-L --dst-nat [2001:DB8::3.3.3.3]:81 ; OK ++# show ++-L --dst-nat [2001:DB8::1.1.1.1]:80 ; OK ++# noport ++-L --dst-nat [2001:DB8::1.1.1.1]: ; BAD ++# badport ++-L --dst-nat [2001:DB8::1.1.1.1]:: ; BAD ++# badport ++-L --dst-nat [2001:DB8::1.1.1.1]:80:80 ; BAD ++# badport ++-L --dst-nat [2001:DB8::1.1.1.1]:65536 ; BAD ++# delete ++-D -s 2001:DB8::1.1.1.1 ; OK ++# mismatched address family ++-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 --dst-nat 3.3.3.3 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD ++# mismatched address family ++-I -s 1.1.1.1 -d 2.2.2.2 --dst-nat 2001:DB8::3.3.3.3 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD ++# create - brackets only for ports in nat ++-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 --dst-nat [2001:DB8::3.3.3.3] -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD ++# create - brackets rejected elsewhere ++-I -s [2001:DB8::1.1.1.1] -d 2001:DB8::2.2.2.2 --dst-nat 2001:DB8::3.3.3.3 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-- +2.7.4 + diff --git a/SPECS/conntrack-tools.spec b/SPECS/conntrack-tools.spec index 766cb15..6b3d5d8 100644 --- a/SPECS/conntrack-tools.spec +++ b/SPECS/conntrack-tools.spec @@ -1,6 +1,6 @@ Name: conntrack-tools -Version: 1.4.3 -Release: 1%{?dist} +Version: 1.4.4 +Release: 3%{?dist} Summary: Manipulate netfilter connection tracking table and run High Availability Group: System Environment/Base License: GPLv2 @@ -8,10 +8,11 @@ URL: http://netfilter.org Source0: http://netfilter.org/projects/%{name}/files/%{name}-%{version}.tar.bz2 Source1: conntrackd.service Source2: conntrackd.conf -BuildRequires: libnfnetlink-devel >= 1.0.1, libnetfilter_conntrack-devel >= 1.0.4 +BuildRequires: libnfnetlink-devel >= 1.0.1, libnetfilter_conntrack-devel >= 1.0.6 BuildRequires: libnetfilter_cttimeout-devel >= 1.0.0, libnetfilter_cthelper-devel >= 1.0.0 BuildRequires: libmnl-devel >= 1.0.3, libnetfilter_queue-devel >= 1.0.2 BuildRequires: pkgconfig bison flex +Requires: libnetfilter_conntrack >= 1.0.6 Provides: conntrack = 1.0-1 Obsoletes: conntrack < 1.0-1 Requires(post): systemd @@ -19,6 +20,8 @@ Requires(preun): systemd Requires(postun): systemd BuildRequires: systemd +Patch1: conntrack-tools-1.4.4-conntrack.patch + %description With conntrack-tools you can setup a High Availability cluster and synchronize conntrack state between multiple firewalls. @@ -40,6 +43,7 @@ show an event message (one line) per newly established connection. %prep %setup -q +%patch1 -p1 %build # do not use --enable-cthelper --enable-cttimeout, it causes disabling of these features @@ -65,6 +69,7 @@ install -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/conntrackd/ %{_sbindir}/conntrackd %{_sbindir}/nfct %{_mandir}/man8/* +%{_mandir}/man5/* %dir %{_libdir}/conntrack-tools %{_libdir}/conntrack-tools/* @@ -78,6 +83,15 @@ install -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/conntrackd/ %systemd_postun conntrackd.service %changelog +* Mon Apr 03 2017 Paul Wouters - 1.4.4-3 +- Resolves: rhbz#1425552 (explicitely Require: libnetfilter_conntrack >= 1.0.6 as it is same .so version) + +* Thu Mar 16 2017 Paul Wouters - 1.4.4-2 +- Resolves: rhbz#1425552 (conntrack cmd was missing IPv6 support as well) + +* Fri Mar 03 2017 Paul Wouters - 1.4.4-1 +- Resolves: rhbz#1425552 conntrack does not support Ipv6 NAT + * Fri Aug 12 2016 Paul Wouters - 1.4.3-1 - Resolves: rhbz#1351701 conntrackd -d throws "ERROR: Helper support is disabled"