From d14e78e9e36f2c6dfd1e5fc827f93ef65fec4c92 Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Thu, 10 Sep 2009 22:01:18 +1200 Subject: [PATCH] Detect et/com_err.h --- configure.in | 2 +- src/cache_cf.cc | 6 +++++ src/comm.cc | 10 +++++--- src/defines.h | 1 + src/ip/IpIntercept.cc | 58 +++++++++++++++++++++++++++++++++++++++++++ src/ip/IpIntercept.h | 11 ++++++++ 6 files changed, 84 insertions(+), 4 deletions(-) diff --git a/configure.in b/configure.in index 77076a9b27..deed47f129 100644 --- a/configure.in +++ b/configure.in @@ -1857,7 +1857,7 @@ if test "$ac_krb5_config" = "yes" ; then if test "x$ac_heimdal" == "x" ; then AC_CHECK_HEADERS(gssapi/gssapi_generic.h) fi - AC_CHECK_HEADERS(krb5.h com_err.h et/comm_err.h) + AC_CHECK_HEADERS(krb5.h com_err.h et/com_err.h) AC_MSG_CHECKING([for max_skew in struct krb5_context]) AC_TRY_COMPILE([ #include diff --git a/src/cache_cf.cc b/src/cache_cf.cc index f17dbba68b..207c28075f 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -3090,6 +3090,12 @@ parse_http_port_option(http_port_list * s, char *token) debugs(3, DBG_IMPORTANT, "Starting IP Spoofing on port " << s->s); debugs(3, DBG_IMPORTANT, "Disabling Authentication on port " << s->s << " (IP spoofing enabled)"); + if (!IpInterceptor.ProbeForTproxy(s->s)) { + debugs(3,DBG_CRITICAL, "http(s)_port: TPROXY support in the system does not work."); + self_destruct(); + } +#endif + } else if (strcmp(token, "ipv4") == 0) { #if USE_IPV6 if ( !s->s.SetIPv4() ) { diff --git a/src/comm.cc b/src/comm.cc index cd6972c157..e7c3c7de8c 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -628,6 +628,9 @@ comm_open_listener(int sock_type, { int sock = -1; + /* all listener sockets require bind() */ + flags |= COMM_DOBIND; + /* attempt native enabled port. */ sock = comm_openex(sock_type, proto, addr, flags, 0, note); @@ -790,10 +793,8 @@ comm_openex(int sock_type, if (addr.GetPort() > (u_short) 0) { #ifdef _SQUID_MSWIN_ - if (sock_type != SOCK_DGRAM) #endif - commSetNoLinger(new_socket); if (opt_reuseaddr) @@ -805,7 +806,10 @@ comm_openex(int sock_type, comm_set_transparent(new_socket); } - if (!addr.IsNoAddr()) { + if ( (flags & COMM_DOBIND) || addr.GetPort() > 0 || !addr.IsAnyAddr() ) { + if ( !(flags & COMM_DOBIND) && addr.IsAnyAddr() ) + debugs(5,1,"WARNING: Squid is attempting to bind() port " << addr << " without being a listener."); + if (commBind(new_socket, *AI) != COMM_OK) { comm_close(new_socket); addr.FreeAddrInfo(AI); diff --git a/src/defines.h b/src/defines.h index c54093d3be..a6ac3eeaec 100644 --- a/src/defines.h +++ b/src/defines.h @@ -66,6 +66,7 @@ #define COMM_NOCLOEXEC 0x02 #define COMM_REUSEADDR 0x04 #define COMM_TRANSPARENT 0x08 +#define COMM_DOBIND 0x10 #define safe_free(x) if (x) { xxfree(x); x = NULL; } diff --git a/src/ip/IpIntercept.cc b/src/ip/IpIntercept.cc index cdb8f01c34..20b9bf7e2f 100644 --- a/src/ip/IpIntercept.cc +++ b/src/ip/IpIntercept.cc @@ -438,3 +438,61 @@ IpIntercept::SetTproxy2OutgoingAddr(int fd, const IpAddress &src) return 0; } #endif + +bool +IpIntercept::ProbeForTproxy(IpAddress &test) +{ +#if LINUX_TPROXY2 + +#if USE_IPV6 + /* TPROXYv2 is not IPv6 capable. Force wildcard sockets to IPv4. Die on IPv6 IPs */ + debugs(3, DBG_IMPORTANT, "Disabling IPv6 on port " << test << " (TPROXYv2 interception enabled)"); + if ( test.IsIPv6() && !test.SetIPv4() ) { + debugs(3, DBG_CRITICAL, "IPv6 requires TPROXYv4 support. You only have TPROXYv2 for " << test ); + return false; + } +#endif /* USE_IPV6 */ + return true; + +#else /* not LINUX_TPROXY2 */ + + int tos = 1; + int tmp_sock = -1; + +#if USE_IPV6 + /* Probe to see if the Kernel TPROXY support is IPv6-enabled */ + if (test.IsIPv6()) { + debugs(3, 3, "Probing for IPv6 TPROXY support on port " << test); + + struct sockaddr_in6 tmp_ip6; + + test.GetSockAddr(tmp_ip6); + + if ( (tmp_sock = socket(PF_INET6, SOCK_STREAM, PROTO_TCP)) >= 0 && + setsockopt(tmp_sock, SOL_IP, IP_TRANSPARENT, (char *)&tos, sizeof(int)) == 0 && + bind(tmp_sock, tmp_ip6.sa_addr, tmp_ip6.sa_addrlen) == 0 ) { + + debugs(3, 3, "IPv6 TPROXY support detected. Using."); + return true; + } + } +#endif + + /* Probe to see if the Kernel TPROXY support is IPv4-enabled (aka present) */ + if (!tproxy_capable && s->s.SetIPv4()) { + debugs(3, 3, "Probing for IPv6 TPROXY support on port " << s->s); + + struct sockaddr_in tmp_ip4; + test.GetSockAddr(tmp_ip4); + + if ( (tmp_sock = socket(PF_INET, SOCK_STREAM, PROTO_TCP)) >= 0 && + setsockopt(tmp_sock, SOL_IP, IP_TRANSPARENT, (char *)&tos, sizeof(int)) == 0 && + bind(tmp_sock, tmp_ip4.sa_addr, tmp_ip4.sa_addrlen) == 0 ) { + + debugs(3, 3, "IPv4 TPROXY support detected. Using."); + return true; + } + } + + return false; +} diff --git a/src/ip/IpIntercept.h b/src/ip/IpIntercept.h index 3dfff4b7b6..541e9c600c 100644 --- a/src/ip/IpIntercept.h +++ b/src/ip/IpIntercept.h @@ -35,6 +35,17 @@ public: int SetTproxy2OutgoingAddr(int fd, const IpAddress &src); #endif + /** + * Test system networking calls for TPROXY support. + * Detects IPv6 and IPv4 level of support matches the address being listened on + * and if the compiled v2/v4 is usable as far down as a bind()ing. + * + * \param test Address set on the http(s)_port being checked. + * \retval true TPROXY is available. + * \retval false TPROXY is not available. + */ + bool ProbeForTproxy(IpAddress &test); + /** \retval 0 Full transparency is disabled. \retval 1 Full transparency is enabled and active. -- 2.47.2