Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock

Please unblock ocserv/0.11.6-2, this update includes four simple
patches cherry picked from upstream later releases, used to improve
firewall handling and MTU/MSS calculation.

Patches are attached.

Regards,
Aron
From 9f735613c496a17461f60a75caf2f394ae781d4c Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <n...@redhat.com>
Date: Thu, 23 Feb 2017 09:54:05 +0100
Subject: [PATCH 7/7] worker-vpn: use TCP_INFO on linux to obtain accurate MTU
 information

This provides a more accurate value than the one obtained using the
TCP MSS value. The latter is affected by many factors (such as tcp
options), to provide a reliable value.

Signed-off-by: Nikos Mavrogiannopoulos <n...@redhat.com>
---
 src/worker-vpn.c | 80 +++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 48 insertions(+), 32 deletions(-)

diff --git a/src/worker-vpn.c b/src/worker-vpn.c
index ea80ebd..311fc2a 100644
--- a/src/worker-vpn.c
+++ b/src/worker-vpn.c
@@ -48,7 +48,7 @@
 #include <signal.h>
 #include <poll.h>
 
-#if defined(__linux__) &&!defined(IPV6_PATHMTU)
+#if defined(__linux__) && !defined(IPV6_PATHMTU)
 # define IPV6_PATHMTU 61
 #endif
 
@@ -942,11 +942,45 @@ void mtu_ok(worker_st * ws)
 			x += r % diff; \
 		}
 
+int get_pmtu_approx(worker_st *ws)
+{
+	socklen_t sl;
+	int ret, e;
+
+#if defined(__linux__) && defined(TCP_INFO)
+	struct tcp_info ti;
+	sl = sizeof(ti);
+
+	ret = getsockopt(ws->conn_fd, IPPROTO_TCP, TCP_INFO, &ti, &sl);
+	if (ret == -1) {
+		e = errno;
+		oclog(ws, LOG_INFO, "error in getting TCP_INFO: %s",
+		      strerror(e));
+		return -1; 
+	} else {
+		return ti.tcpi_pmtu;
+	}
+#else
+	int max = -1;
+
+	sl = sizeof(max);
+	ret = getsockopt(ws->conn_fd, IPPROTO_TCP, TCP_MAXSEG, &max, &sl);
+	if (ret == -1) {
+		e = errno;
+		oclog(ws, LOG_INFO, "error in getting TCP_MAXSEG: %s",
+		      strerror(e));
+		return -1;
+	} else {
+		MSS_ADJUST(max);
+		return max;
+	}
+#endif
+}
+
 static
 int periodic_check(worker_st * ws, struct timespec *tnow, unsigned dpd)
 {
-	socklen_t sl;
-	int max, e, ret;
+	int max, ret;
 	time_t now = tnow->tv_sec;
 	time_t periodic_check_time = PERIODIC_CHECK_TIME;
 
@@ -1036,20 +1070,11 @@ int periodic_check(worker_st * ws, struct timespec *tnow, unsigned dpd)
 	}
 
 	if (ws->conn_type != SOCK_TYPE_UNIX && ws->udp_state != UP_DISABLED) {
-		sl = sizeof(max);
-		ret = getsockopt(ws->conn_fd, IPPROTO_TCP, TCP_MAXSEG, &max, &sl);
-		if (ret == -1) {
-			e = errno;
-			oclog(ws, LOG_INFO, "error in getting TCP_MAXSEG: %s",
-			      strerror(e));
-		} else {
-			MSS_ADJUST(max);
-			/*oclog(ws, LOG_DEBUG, "TCP MSS is %u", max); */
-			if (max > 0 && max < ws->link_mtu) {
-				oclog(ws, LOG_DEBUG, "reducing MTU due to TCP MSS to %u",
-				      max);
-				link_mtu_set(ws, max);
-			}
+		max = get_pmtu_approx(ws);
+		if (max > 0 && max < ws->link_mtu) {
+			oclog(ws, LOG_DEBUG, "reducing MTU due to TCP/PMTU to %u",
+			      max);
+			link_mtu_set(ws, max);
 		}
 	}
 
@@ -1571,7 +1596,7 @@ static int connect_handler(worker_st * ws)
 	struct http_req_st *req = &ws->req;
 	struct pollfd pfd[4];
 	unsigned pfd_size;
-	int e, max, ret, t;
+	int max, ret, t;
 	char *p;
 	unsigned rnd;
 #ifdef HAVE_PPOLL
@@ -1580,7 +1605,6 @@ static int connect_handler(worker_st * ws)
 	unsigned tls_pending, dtls_pending = 0, i;
 	struct timespec tnow;
 	unsigned ip6;
-	socklen_t sl;
 	sigset_t emptyset, blockset;
 
 	sigemptyset(&blockset);
@@ -1693,19 +1717,11 @@ static int connect_handler(worker_st * ws)
 	/* Attempt to use the TCP connection maximum segment size to set a more
 	 * precise MTU. */
 	if (ws->conn_type != SOCK_TYPE_UNIX) {
-		sl = sizeof(max);
-		ret = getsockopt(ws->conn_fd, IPPROTO_TCP, TCP_MAXSEG, &max, &sl);
-		if (ret == -1) {
-			e = errno;
-			oclog(ws, LOG_INFO, "error in getting TCP_MAXSEG: %s",
-			      strerror(e));
-		} else {
-			MSS_ADJUST(max);
-			if (max > 0 && max < ws->vinfo.mtu) {
-				oclog(ws, LOG_INFO,
-				      "reducing MTU due to TCP MSS to %u (from %u)", max, ws->vinfo.mtu);
-				ws->vinfo.mtu = max;
-			}
+		max = get_pmtu_approx(ws);
+		if (max > 0 && max < ws->vinfo.mtu) {
+			oclog(ws, LOG_DEBUG, "reducing MTU due to TCP/PMTU to %u",
+			      max);
+			link_mtu_set(ws, max);
 		}
 	}
 
-- 
2.1.4

From 1233f67c3f89bce5f8300c22de8c745d2ae7e9dd Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <n...@redhat.com>
Date: Wed, 22 Feb 2017 16:22:55 +0100
Subject: [PATCH 6/7] worker-vpn: corrected calculation for MTU via TCP MSS

Signed-off-by: Nikos Mavrogiannopoulos <n...@redhat.com>
---
 src/worker-vpn.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/worker-vpn.c b/src/worker-vpn.c
index 2a00ef9..ea80ebd 100644
--- a/src/worker-vpn.c
+++ b/src/worker-vpn.c
@@ -74,6 +74,13 @@
 #define CSTP_DTLS_OVERHEAD 1
 #define CSTP_OVERHEAD 8
 
+#define IP_HEADER_SIZE 20
+#define IPV6_HEADER_SIZE 40
+#define TCP_HEADER_SIZE 20
+#define UDP_HEADER_SIZE 8
+
+#define MSS_ADJUST(x) x += TCP_HEADER_SIZE + ((ws->proto == AF_INET)?(IP_HEADER_SIZE):(IPV6_HEADER_SIZE))
+
 struct worker_st *global_ws = NULL;
 
 static int terminate = 0;
@@ -1036,7 +1043,7 @@ int periodic_check(worker_st * ws, struct timespec *tnow, unsigned dpd)
 			oclog(ws, LOG_INFO, "error in getting TCP_MAXSEG: %s",
 			      strerror(e));
 		} else {
-			max -= 13;
+			MSS_ADJUST(max);
 			/*oclog(ws, LOG_DEBUG, "TCP MSS is %u", max); */
 			if (max > 0 && max < ws->link_mtu) {
 				oclog(ws, LOG_DEBUG, "reducing MTU due to TCP MSS to %u",
@@ -1485,11 +1492,6 @@ static void set_socket_timeout(worker_st * ws, int fd)
 	}
 }
 
-#define IP_HEADER_SIZE 20
-#define IPV6_HEADER_SIZE 40
-#define TCP_HEADER_SIZE 8
-#define UDP_HEADER_SIZE 8
-
 /* wild but conservative guess; this ciphersuite has the largest overhead */
 #define MAX_CSTP_CRYPTO_OVERHEAD (CSTP_OVERHEAD+tls_get_overhead(GNUTLS_TLS1_0, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1))
 #define MAX_DTLS_CRYPTO_OVERHEAD (CSTP_DTLS_OVERHEAD+tls_get_overhead(GNUTLS_DTLS1_0, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1))
@@ -1698,7 +1700,7 @@ static int connect_handler(worker_st * ws)
 			oclog(ws, LOG_INFO, "error in getting TCP_MAXSEG: %s",
 			      strerror(e));
 		} else {
-			max -= 13;
+			MSS_ADJUST(max);
 			if (max > 0 && max < ws->vinfo.mtu) {
 				oclog(ws, LOG_INFO,
 				      "reducing MTU due to TCP MSS to %u (from %u)", max, ws->vinfo.mtu);
-- 
2.1.4

From 6e83ea5217f4789f21ce2be706747d7d0aba07f5 Mon Sep 17 00:00:00 2001
From: John Thiltges <jthiltg...@unl.edu>
Date: Mon, 9 Jan 2017 15:45:22 -0600
Subject: [PATCH 3/7] ocserv-fw should send all traffic to the device-specific
 forwarding chain

After adding port-specific rules to FORWARD and creating SEC_FORWARD_CHAIN
with route-specific rules, send any remaining FORWARD traffic to
SEC_FORWARD_CHAIN.
---
 src/ocserv-fw | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/ocserv-fw b/src/ocserv-fw
index 3653364..1c2899a 100755
--- a/src/ocserv-fw
+++ b/src/ocserv-fw
@@ -270,6 +270,10 @@ else
 	iptables -A ${SEC_FORWARD_CHAIN} -i ${DEVICE} -j ACCEPT -m comment --comment "${COMMENT}"
 fi
 
+# send traffic to the route chain
+iptables  -A FORWARD -i ${DEVICE} -j ${SEC_FORWARD_CHAIN} --match comment --comment "${COMMENT}"
+ip6tables -A FORWARD -i ${DEVICE} -j ${SEC_FORWARD_CHAIN} --match comment --comment "${COMMENT}"
+
 execute_next_script
 
 exit 0
-- 
2.1.4

From 3ba8abea378f9278da377705986810556803d26e Mon Sep 17 00:00:00 2001
From: John Thiltges <jthiltg...@unl.edu>
Date: Mon, 9 Jan 2017 12:28:19 -0600
Subject: [PATCH 2/7] ocserv-fw should still create a chain if
 restrict-user-to-routes is set

ocserv-fw only creates SEC_FORWARD_CHAIN if ports are being blocked. This
leads to an error if restrict-user-to-routes is used without any port
blocking.

Since ocserv-fw is only called if restrict-user-to-routes or -ports is set,
remove the conditional check for creating the chain.
---
 src/ocserv-fw | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/src/ocserv-fw b/src/ocserv-fw
index b4c7516..3653364 100755
--- a/src/ocserv-fw
+++ b/src/ocserv-fw
@@ -204,12 +204,13 @@ for i in $OCSERV_DNS6;do
 	allow_dns6 $i
 done
 
+# create the chain
+FORWARD_CHAIN="${SEC_FORWARD_CHAIN}"
+iptables -N "${FORWARD_CHAIN}"
+ip6tables -N "${FORWARD_CHAIN}"
+
 # block ports - if needed
 if test -n "${OCSERV_DENY_PORTS}";then
-	FORWARD_CHAIN="${SEC_FORWARD_CHAIN}"
-	iptables -N "${FORWARD_CHAIN}"
-	ip6tables -N "${FORWARD_CHAIN}"
-
 	set ${OCSERV_DENY_PORTS}
 	while test $# -gt 1; do
 		proto=$1
@@ -224,10 +225,6 @@ if test -n "${OCSERV_DENY_PORTS}";then
 	done
 else
 	if test -n "${OCSERV_ALLOW_PORTS}";then
-		FORWARD_CHAIN="${SEC_FORWARD_CHAIN}"
-		iptables -N "${FORWARD_CHAIN}"
-		ip6tables -N "${FORWARD_CHAIN}"
-
 		set ${OCSERV_ALLOW_PORTS}
 		while test $# -gt 1; do
 			proto=$1
-- 
2.1.4

Reply via email to