File set-TCP-MD5SIG-correctly-for-client-connections.patch of Package netcat-openbsd

From: Thomas Habets <habets@google.com>
Date: Sat, 18 Feb 2017 21:07:22 +0000
Subject: Fix TCP MD5SIG for client connections

---
 netcat.c | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/netcat.c b/netcat.c
index 8291173..990c31b 100644
--- a/netcat.c
+++ b/netcat.c
@@ -46,6 +46,9 @@
 #ifdef __linux__
 # include <linux/in6.h>
 #endif
+#if defined(TCP_MD5SIG_EXT) && defined(TCP_MD5SIG_MAXKEYLEN)
+# include <bsd/readpassphrase.h>
+#endif
 
 #ifndef IPTOS_LOWDELAY
 # define IPTOS_LOWDELAY 0x10
@@ -175,6 +178,9 @@ FILE	*Zflag;					/* file to save peer cert */
 int	Cflag = 0;			/* CRLF line-ending */
 #endif
 
+#if defined(TCP_MD5SIG_EXT) && defined(TCP_MD5SIG_MAXKEYLEN)
+char Sflag_password[TCP_MD5SIG_MAXKEYLEN];
+#endif
 int recvcount, recvlimit;
 int timeout = -1;
 int family = AF_UNSPEC;
@@ -206,7 +212,7 @@ void	connection_info(const char *, const char *, const char *, const char *);
 int	unix_bind(char *, int);
 int	unix_connect(char *);
 int	unix_listen(char *);
-void	set_common_sockopts(int, int);
+void	set_common_sockopts(int, const struct sockaddr *);
 int	process_tos_opt(char *, int *);
 #ifdef HAVE_TLS
 int	process_tls_opt(char *, int *);
@@ -456,7 +462,10 @@ main(int argc, char *argv[])
 			break;
 #endif
 		case 'S':
-#ifdef TCP_MD5SIG
+#if defined(TCP_MD5SIG_EXT) && defined(TCP_MD5SIG_MAXKEYLEN)
+			if (readpassphrase("TCP MD5SIG password: ",
+					Sflag_password, TCP_MD5SIG_MAXKEYLEN, RPP_REQUIRE_TTY) == NULL)
+				errx(1, "Unable to read TCP MD5SIG password");
 			Sflag = 1;
 #else
 			errx(1, "no TCP MD5 signature support available");
@@ -1161,7 +1170,7 @@ remote_connect(const char *host, const char *port, struct addrinfo hints,
 			freeaddrinfo(ares);
 		}
 
-		set_common_sockopts(s, res->ai_family);
+		set_common_sockopts(s, res->ai_addr);
 
 		if (ipaddr != NULL) {
 			herr = getnameinfo(res->ai_addr, res->ai_addrlen,
@@ -1336,7 +1345,7 @@ local_listen(const char *host, const char *port, struct addrinfo hints)
 			err(1, NULL);
 #endif
 
-		set_common_sockopts(s, res->ai_family);
+		set_common_sockopts(s, res->ai_addr);
 
 		if (bind(s, (struct sockaddr *)res->ai_addr,
 		    res->ai_addrlen) == 0)
@@ -1910,9 +1919,10 @@ connection_info(const char *host, const char *port, const char *proto,
 }
 
 void
-set_common_sockopts(int s, int af)
+set_common_sockopts(int s, const struct sockaddr* sa)
 {
 	int x = 1;
+	int af = sa->sa_family;
 
 #ifdef SO_BROADCAST
 	if (bflag) {
@@ -1923,10 +1933,18 @@ set_common_sockopts(int s, int af)
 			err(1, NULL);
 	}
 #endif
-#ifdef TCP_MD5SIG
+#if defined(TCP_MD5SIG_EXT) && defined(TCP_MD5SIG_MAXKEYLEN)
 	if (Sflag) {
-		if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
-		    &x, sizeof(x)) == -1)
+		struct tcp_md5sig sig;
+		memset(&sig, 0, sizeof(sig));
+		memcpy(&sig.tcpm_addr, sa, sizeof(struct sockaddr_storage));
+		sig.tcpm_keylen = TCP_MD5SIG_MAXKEYLEN < strlen(Sflag_password)
+		    ? TCP_MD5SIG_MAXKEYLEN
+		    : strlen(Sflag_password);
+		memcpy(sig.tcpm_key, Sflag_password, sig.tcpm_keylen);
+		sig.tcpm_flags = TCP_MD5SIG_FLAG_PREFIX;
+		if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG_EXT,
+		    &sig, sizeof(sig)) == -1)
 			err(1, NULL);
 	}
 #endif
openSUSE Build Service is sponsored by