Compare commits

1 Commits
1.1 ... main

22 changed files with 1011 additions and 663 deletions

View File

@@ -0,0 +1,157 @@
From: Dirk Jagdmann <doj@cubic.org>
Date: Sun, 6 Mar 2022 21:26:31 -0800
Subject: Add abstract UNIX domain socket support
When using '-U' to connect() or bind() to a UNIX domain socket, if the
address (path) starts with "@", it is read as an abstract namespace
socket (the leading "@" is replaced with a NUL byte before binding).
This feature is Linux-only.
Forwarded: not-needed
---
nc.1 | 3 +++
netcat.c | 75 ++++++++++++++++++++++++++++++++++++++++++++--------------------
2 files changed, 55 insertions(+), 23 deletions(-)
diff --git a/nc.1 b/nc.1
index d30389a..8285c10 100644
--- a/nc.1
+++ b/nc.1
@@ -235,6 +235,9 @@ Cannot be used together with
.Fl F
or
.Fl x .
+On Linux, if the name starts with an at symbol (`@') it is read as an abstract
+namespace socket: the leading `@' is replaced with a \fBNUL\fR byte
+before binding or connecting. For details, see \fBunix\fR(7).
.It Fl u
Use UDP instead of TCP.
Cannot be used together with
diff --git a/netcat.c b/netcat.c
index 061a774..2f8890b 100644
--- a/netcat.c
+++ b/netcat.c
@@ -98,6 +98,7 @@
#include <netdb.h>
#include <poll.h>
#include <signal.h>
+#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -208,6 +209,7 @@ int timeout_connect(int, const struct sockaddr *, socklen_t);
int socks_connect(const char *, const char *, struct addrinfo,
const char *, const char *, struct addrinfo, int, const char *);
int udptest(int);
+int unix_setup_sockaddr(char *, struct sockaddr_un *, int *);
void connection_info(const char *, const char *, const char *, const char *);
int unix_bind(char *, int);
int unix_connect(char *);
@@ -931,6 +933,46 @@ main(int argc, char *argv[])
return ret;
}
+int
+unix_setup_sockaddr(char *path, struct sockaddr_un *s_un, int *addrlen)
+{
+ int sun_path_len;
+
+ *addrlen = offsetof(struct sockaddr_un, sun_path);
+ memset(s_un, 0, *addrlen);
+ s_un->sun_family = AF_UNIX;
+
+ if (path[0] == '\0') {
+ /* Always reject the empty path, aka NUL abstract socket on
+ * Linux (OTOH the *empty* abstract socket is supported and
+ * specified as @""). */
+ errno = EINVAL;
+ return -1;
+ }
+#ifdef __linux__
+ /* If the unix domain socket path starts with '@',
+ * treat it as a Linux abstract name. */
+ else if (path[0] == '@') {
+ if ((sun_path_len = strlen(path)) <= sizeof(s_un->sun_path)) {
+ s_un->sun_path[0] = '\0';
+ strncpy(s_un->sun_path+1, path+1, sun_path_len-1);
+ *addrlen += sun_path_len;
+ } else {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+ }
+#endif
+ else if ((sun_path_len = strlcpy(s_un->sun_path, path, sizeof(s_un->sun_path))) <
+ sizeof(s_un->sun_path))
+ *addrlen += sun_path_len + 1; /* account for trailing '\0' */
+ else {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+ return 0;
+}
+
/*
* unix_bind()
* Returns a unix socket bound to the given path
@@ -939,24 +981,17 @@ int
unix_bind(char *path, int flags)
{
struct sockaddr_un s_un;
- int s, save_errno;
+ int s, save_errno, addrlen;
+
+ if (unix_setup_sockaddr(path, &s_un, &addrlen) == -1)
+ return -1;
/* Create unix domain socket. */
if ((s = socket(AF_UNIX, flags | (uflag ? SOCK_DGRAM : SOCK_STREAM),
0)) == -1)
return -1;
- memset(&s_un, 0, sizeof(struct sockaddr_un));
- s_un.sun_family = AF_UNIX;
-
- if (strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path)) >=
- sizeof(s_un.sun_path)) {
- close(s);
- errno = ENAMETOOLONG;
- return -1;
- }
-
- if (bind(s, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
+ if (bind(s, (struct sockaddr *)&s_un, addrlen) == -1) {
save_errno = errno;
close(s);
errno = save_errno;
@@ -1066,7 +1101,10 @@ int
unix_connect(char *path)
{
struct sockaddr_un s_un;
- int s, save_errno;
+ int s, save_errno, addrlen;
+
+ if (unix_setup_sockaddr(path, &s_un, &addrlen) == -1)
+ return -1;
if (uflag) {
if ((s = unix_bind(unix_dg_tmp_socket, SOCK_CLOEXEC)) == -1)
@@ -1076,16 +1114,7 @@ unix_connect(char *path)
return -1;
}
- memset(&s_un, 0, sizeof(struct sockaddr_un));
- s_un.sun_family = AF_UNIX;
-
- if (strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path)) >=
- sizeof(s_un.sun_path)) {
- close(s);
- errno = ENAMETOOLONG;
- return -1;
- }
- if (connect(s, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
+ if (connect(s, (struct sockaddr *)&s_un, addrlen) == -1) {
save_errno = errno;
close(s);
errno = save_errno;

View File

@@ -1,12 +1,14 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 19:06:52 +0800
Subject: broadcast support
Subject: New flag '-b' for broadcast support
---
nc.1 | 4 +++-
netcat.c | 22 ++++++++++++++++++++--
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/nc.1 b/nc.1
index da37f06..49a3d4d 100644
--- a/nc.1
+++ b/nc.1
@@ -33,7 +33,7 @@
@@ -27,6 +29,8 @@ Subject: broadcast support
.It Fl C
Send CRLF as line-ending. Each line feed (LF) character from the input
data is translated into CR+LF before being written to the socket. Line
diff --git a/netcat.c b/netcat.c
index 1c50615..99747a2 100644
--- a/netcat.c
+++ b/netcat.c
@@ -132,6 +132,7 @@
@@ -37,37 +41,37 @@ Subject: broadcast support
int dflag; /* detached, no stdin */
int Fflag; /* fdpass sock to stdout */
unsigned int iflag; /* Interval Flag */
@@ -263,9 +264,9 @@ main(int argc, char *argv[])
@@ -261,9 +262,9 @@ main(int argc, char *argv[])
while ((ch = getopt(argc, argv,
# if defined(TLS)
#ifdef HAVE_TLS
- "46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:q:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
+ "46bC:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:q:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
# else
#else
- "46CDdFhI:i:klM:m:NnO:P:p:q:rSs:T:tUuV:vW:w:X:x:Zz"))
+ "46bCDdFhI:i:klM:m:NnO:P:p:q:rSs:T:tUuV:vW:w:X:x:Zz"))
# endif
#endif
!= -1) {
switch (ch) {
@@ -275,6 +276,13 @@ main(int argc, char *argv[])
@@ -273,6 +274,13 @@ main(int argc, char *argv[])
case '6':
family = AF_INET6;
break;
+ case 'b':
+# if defined(SO_BROADCAST)
+#ifdef SO_BROADCAST
+ bflag = 1;
+# else
+#else
+ errx(1, "no broadcast frame support available");
+# endif
+#endif
+ break;
case 'U':
family = AF_UNIX;
break;
@@ -1852,6 +1860,15 @@ set_common_sockopts(int s, int af)
@@ -1907,6 +1915,15 @@ set_common_sockopts(int s, int af)
{
int x = 1;
+# if defined(SO_BROADCAST)
+#ifdef SO_BROADCAST
+ if (bflag) {
+ /* allow datagram sockets to send packets to a broadcast address
+ * (this option has no effect on stream-oriented sockets) */
@@ -75,11 +79,11 @@ Subject: broadcast support
+ &x, sizeof(x)) == -1)
+ err(1, NULL);
+ }
+# endif
# if defined(TCP_MD5SIG)
+#endif
#ifdef TCP_MD5SIG
if (Sflag) {
if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
@@ -2127,6 +2144,7 @@ help(void)
@@ -2185,6 +2202,7 @@ help(void)
fprintf(stderr, "\tCommand Summary:\n\
\t-4 Use IPv4\n\
\t-6 Use IPv6\n\

View File

@@ -1,16 +1,19 @@
From: Guilhem Moulin <guilhem@debian.org>
Date: Fri, 09 Jun 2017 13:21:23 +0200
Subject: build without TLS support
Date: Fri, 9 Jun 2017 13:21:23 +0200
Subject: Build without TLS support
tls.h isn't available in libsd-dev, and TLS supports adds options (-C, -Z)
tls.h isn't available in libbsd-dev, and TLS supports adds options (-C, -Z)
that are already used by our Debian-specific patches.
Forwarded: not-needed
---
Makefile | 2
nc.1 | 114 ++---------------------------------------
Makefile | 2 -
nc.1 | 114 +++---------------------------------------
netcat.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 153 insertions(+), 135 deletions(-)
diff --git a/Makefile b/Makefile
index 93ca5ee..31d7536 100644
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,6 @@
@@ -20,8 +23,10 @@ that are already used by our Debian-specific patches.
-LDADD+= -ltls -lssl -lcrypto
-DPADD+= ${LIBTLS} ${LIBSSL} ${LIBCRYPTO}
LIBS= `pkg-config --libs libbsd` -lresolv
OBJS= $(SRCS:.c=.o)
PKG_CONFIG ?= pkg-config
LIBS= `$(PKG_CONFIG) --libs libbsd` -lresolv
diff --git a/nc.1 b/nc.1
index 596bd8e..2eb732e 100644
--- a/nc.1
+++ b/nc.1
@@ -33,20 +33,14 @@
@@ -43,7 +48,7 @@ that are already used by our Debian-specific patches.
.Op Fl P Ar proxy_username
.Op Fl p Ar source_port
-.Op Fl R Ar CAfile
.Op Fl s Ar source
.Op Fl s Ar sourceaddr
.Op Fl T Ar keyword
.Op Fl V Ar rtable
@@ -54,7 +48,6 @@
@@ -115,8 +120,8 @@ that are already used by our Debian-specific patches.
.It Fl k
When a connection is completed, listen for another one.
Requires
@@ -196,15 +154,6 @@ Do not do any DNS or service lookups on
hostnames or ports.
@@ -196,15 +154,6 @@ Do not perform domain name resolution.
If a name cannot be resolved without DNS, an error will be reported.
.It Fl O Ar length
Specify the size of the TCP send buffer.
-.It Fl o Ar staplefile
@@ -131,7 +136,7 @@ that are already used by our Debian-specific patches.
.It Fl P Ar proxy_username
Specifies a username to present to a proxy server that requires authentication.
If no username is specified then authentication will not be attempted.
@@ -213,13 +162,6 @@ Proxy authentication is only supported f
@@ -213,13 +162,6 @@ Proxy authentication is only supported for HTTP CONNECT proxies at present.
Specify the source port
.Nm
should use, subject to privilege restrictions and availability.
@@ -145,7 +150,7 @@ that are already used by our Debian-specific patches.
.It Fl r
Choose source and/or destination ports randomly
instead of sequentially within a range or in the order that the system
@@ -239,35 +181,7 @@ Cannot be used together with
@@ -238,35 +180,7 @@ Cannot be used together with
or
.Fl x .
.It Fl T Ar keyword
@@ -182,7 +187,7 @@ that are already used by our Debian-specific patches.
.Ar keyword
may be one of
.Cm critical ,
@@ -291,13 +205,13 @@ to script telnet sessions.
@@ -290,13 +204,13 @@ to script telnet sessions.
Use
.Ux Ns -domain
sockets.
@@ -200,7 +205,7 @@ that are already used by our Debian-specific patches.
.Fl x .
For
.Ux Ns -domain
@@ -360,12 +274,6 @@ An IPv6 address can be specified unambig
@@ -359,12 +273,6 @@ An IPv6 address can be specified unambiguously by enclosing
in square brackets.
A proxy cannot be used with any of the options
.Fl lsuU .
@@ -213,7 +218,7 @@ that are already used by our Debian-specific patches.
.It Fl z
Only scan for listening daemons, without sending any data to them.
Cannot be used together with
@@ -519,16 +427,6 @@ the source port, with a timeout of 5 sec
@@ -522,16 +430,6 @@ the source port, with a timeout of 5 seconds:
.Pp
.Dl $ nc -p 31337 -w 5 host.example.com 42
.Pp
@@ -230,6 +235,8 @@ that are already used by our Debian-specific patches.
Open a UDP connection to port 53 of host.example.com:
.Pp
.Dl $ nc -u host.example.com 53
diff --git a/netcat.c b/netcat.c
index d23e566..bec6e46 100644
--- a/netcat.c
+++ b/netcat.c
@@ -99,7 +99,9 @@
@@ -237,7 +244,7 @@ that are already used by our Debian-specific patches.
#include <string.h>
#include <time.h>
-#include <tls.h>
+#ifdef TLS
+#ifdef HAVE_TLS
+# include <tls.h>
+#endif
#include <unistd.h>
@@ -251,7 +258,7 @@ that are already used by our Debian-specific patches.
-#define TLS_NONAME (1 << 2)
-#define TLS_CCERT (1 << 3)
-#define TLS_MUSTSTAPLE (1 << 4)
+#ifdef TLS
+#ifdef HAVE_TLS
+# define TLS_NOVERIFY (1 << 1)
+# define TLS_NONAME (1 << 2)
+# define TLS_CCERT (1 << 3)
@@ -260,19 +267,19 @@ that are already used by our Debian-specific patches.
/* Command Line Options */
int dflag; /* detached, no stdin */
@@ -144,6 +148,7 @@ int Sflag; /* TCP MD5 signature opti
@@ -144,6 +148,7 @@ int Sflag; /* TCP MD5 signature option */
int Tflag = -1; /* IP Type of Service */
int rtableid = -1;
+# if defined(TLS)
+#ifdef HAVE_TLS
int usetls; /* use TLS */
const char *Cflag; /* Public cert file */
const char *Kflag; /* Private key file */
@@ -156,6 +161,7 @@ char *tls_expecthash; /* required hash
@@ -156,6 +161,7 @@ char *tls_expecthash; /* required hash of peer cert */
char *tls_ciphers; /* TLS ciphers */
char *tls_protocols; /* TLS protocols */
FILE *Zflag; /* file to save peer cert */
+# endif
+#endif
int recvcount, recvlimit;
int timeout = -1;
@@ -280,71 +287,70 @@ that are already used by our Debian-specific patches.
void build_ports(char *);
void help(void) __attribute__((noreturn));
int local_listen(const char *, const char *, struct addrinfo);
+# if defined(TLS)
+#ifdef HAVE_TLS
void readwrite(int, struct tls *);
+# else
+#else
+void readwrite(int);
+# endif
+#endif
void fdpass(int nfd) __attribute__((noreturn));
int remote_connect(const char *, const char *, struct addrinfo);
+# if defined(TLS)
int remote_connect(const char *, const char *, struct addrinfo, char *);
+#ifdef HAVE_TLS
int timeout_tls(int, struct tls *, int (*)(struct tls *));
+# endif
+#endif
int timeout_connect(int, const struct sockaddr *, socklen_t);
int socks_connect(const char *, const char *, struct addrinfo,
const char *, const char *, struct addrinfo, int, const char *);
@@ -183,15 +195,24 @@ int unix_connect(char *);
@@ -184,15 +196,24 @@ int unix_connect(char *);
int unix_listen(char *);
void set_common_sockopts(int, int);
int process_tos_opt(char *, int *);
+# if defined(TLS)
+#ifdef HAVE_TLS
int process_tls_opt(char *, int *);
void save_peer_cert(struct tls *_tls_ctx, FILE *_fp);
+# endif
+#endif
void report_sock(const char *, const struct sockaddr *, socklen_t, char *);
+# if defined(TLS)
+#ifdef HAVE_TLS
void report_tls(struct tls *tls_ctx, char * host);
+# endif
+#endif
void usage(int);
+# if defined(TLS)
+#ifdef HAVE_TLS
ssize_t drainbuf(int, unsigned char *, size_t *, struct tls *);
ssize_t fillbuf(int, unsigned char *, size_t *, struct tls *);
void tls_setup_client(struct tls *, int, char *);
struct tls *tls_setup_server(struct tls *, int, char *);
+# else
+#else
+ssize_t drainbuf(int, unsigned char *, size_t *);
+ssize_t fillbuf(int, unsigned char *, size_t *);
+# endif
+#endif
int
main(int argc, char *argv[])
@@ -206,8 +227,10 @@ main(int argc, char *argv[])
@@ -207,20 +228,28 @@ main(int argc, char *argv[])
const char *errstr;
struct addrinfo proxyhints;
char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];
+# if defined(TLS)
+#ifdef HAVE_TLS
struct tls_config *tls_cfg = NULL;
struct tls *tls_ctx = NULL;
+# endif
+#endif
uint32_t protocols;
ret = 1;
@@ -215,12 +238,18 @@ main(int argc, char *argv[])
socksv = 5;
host = NULL;
uport = NULL;
sv = NULL;
+# if defined(TLS)
+#ifdef HAVE_TLS
Rflag = tls_default_ca_cert_file();
+# endif
+#endif
signal(SIGPIPE, SIG_IGN);
while ((ch = getopt(argc, argv,
+# if defined(TLS)
+#ifdef HAVE_TLS
"46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
+# else
+#else
+ "46DdFhI:i:klM:m:NnO:P:p:rSs:T:tUuV:vW:w:X:x:z"))
+# endif
+#endif
!= -1) {
switch (ch) {
case '4':
@@ -352,30 +358,30 @@ that are already used by our Debian-specific patches.
else
errx(1, "unsupported proxy protocol");
break;
+# if defined(TLS)
+#ifdef HAVE_TLS
case 'C':
Cflag = optarg;
break;
case 'c':
usetls = 1;
break;
+# endif
+#endif
case 'd':
dflag = 1;
break;
+# if defined(TLS)
+#ifdef HAVE_TLS
case 'e':
tls_expectname = optarg;
break;
+# endif
+#endif
case 'F':
Fflag = 1;
break;
+# if defined(TLS)
+#ifdef HAVE_TLS
case 'H':
tls_expecthash = optarg;
break;
+# endif
+#endif
case 'h':
help();
break;
@@ -383,11 +389,11 @@ that are already used by our Debian-specific patches.
if (errstr)
errx(1, "interval %s: %s", errstr, optarg);
break;
+# if defined(TLS)
+#ifdef HAVE_TLS
case 'K':
Kflag = optarg;
break;
+# endif
+#endif
case 'k':
kflag = 1;
break;
@@ -395,12 +401,12 @@ that are already used by our Debian-specific patches.
case 'p':
pflag = optarg;
break;
+# if defined(TLS)
+#ifdef HAVE_TLS
case 'R':
tls_cachanged = 1;
Rflag = optarg;
break;
+# endif
+#endif
case 'r':
rflag = 1;
break;
@@ -408,14 +414,14 @@ that are already used by our Debian-specific patches.
if ((proxy = strdup(optarg)) == NULL)
err(1, NULL);
break;
+# if defined(TLS)
+#ifdef HAVE_TLS
case 'Z':
if (strcmp(optarg, "-") == 0)
Zflag = stderr;
else if ((Zflag = fopen(optarg, "w")) == NULL)
err(1, "can't open %s", optarg);
break;
+# endif
+#endif
case 'z':
zflag = 1;
break;
@@ -423,22 +429,22 @@ that are already used by our Debian-specific patches.
errx(1, "TCP send window %s: %s",
errstr, optarg);
break;
+# if defined(TLS)
+#ifdef HAVE_TLS
case 'o':
oflag = optarg;
break;
+# endif
+#endif
case 'S':
# if defined(TCP_MD5SIG)
#ifdef TCP_MD5SIG
Sflag = 1;
@@ -381,8 +424,10 @@ main(int argc, char *argv[])
case 'T':
errstr = NULL;
errno = 0;
+# if defined(TLS)
+#ifdef HAVE_TLS
if (process_tls_opt(optarg, &TLSopt))
break;
+# endif
+#endif
if (process_tos_opt(optarg, &Tflag))
break;
if (strlen(optarg) > 1 && optarg[0] == '0' &&
@@ -446,219 +452,217 @@ that are already used by our Debian-specific patches.
Tflag = (int)strtonum(optarg, 0, 255,
&errstr);
if (Tflag < 0 || Tflag > 255 || errstr || errno)
+# if defined(TLS)
+#ifdef HAVE_TLS
errx(1, "illegal tos/tls value %s", optarg);
+# else
+#else
+ errx(1, "illegal tos value %s", optarg);
+# endif
+#endif
break;
default:
usage(1);
@@ -429,6 +478,7 @@ main(int argc, char *argv[])
@@ -425,6 +474,7 @@ main(int argc, char *argv[])
} else
usage(1);
+# if defined(TLS)
+#ifdef HAVE_TLS
if (usetls) {
if (Cflag && unveil(Cflag, "r") == -1)
err(1, "unveil");
@@ -451,15 +501,19 @@ main(int argc, char *argv[])
err(1, "unveil");
err(1, "unveil %s", Cflag);
@@ -459,15 +509,19 @@ main(int argc, char *argv[])
err(1, "unveil /");
}
}
+# endif
+#endif
if (!lflag && kflag)
errx(1, "must use -l with -k");
+# if defined(TLS)
+#ifdef HAVE_TLS
if (uflag && usetls)
errx(1, "cannot use -c and -u");
if ((family == AF_UNIX) && usetls)
errx(1, "cannot use -c and -U");
+# endif
+#endif
if ((family == AF_UNIX) && Fflag)
errx(1, "cannot use -F and -U");
+# if defined(TLS)
+#ifdef HAVE_TLS
if (Fflag && usetls)
errx(1, "cannot use -c and -F");
if (TLSopt && !usetls)
@@ -478,6 +532,7 @@ main(int argc, char *argv[])
@@ -486,6 +540,7 @@ main(int argc, char *argv[])
errx(1, "you must specify -c to use -H");
if (tls_expectname && !usetls)
errx(1, "you must specify -c to use -e");
+# endif
+#endif
/* Get name of temporary socket for unix datagram client */
if ((family == AF_UNIX) && uflag && !lflag) {
@@ -544,6 +599,7 @@ main(int argc, char *argv[])
@@ -552,6 +607,7 @@ main(int argc, char *argv[])
proxyhints.ai_flags |= AI_NUMERICHOST;
}
+# if defined(TLS)
+#ifdef HAVE_TLS
if (usetls) {
if ((tls_cfg = tls_config_new()) == NULL)
errx(1, "unable to allocate TLS config");
@@ -579,7 +635,8 @@ main(int argc, char *argv[])
err(1, "pledge");
@@ -588,6 +644,7 @@ main(int argc, char *argv[])
} else if (pledge("stdio inet dns", NULL) == -1)
err(1, "pledge");
- }
+ }
+# endif
}
+#endif
if (lflag) {
ret = 0;
@@ -590,6 +647,7 @@ main(int argc, char *argv[])
@@ -598,6 +655,7 @@ main(int argc, char *argv[])
s = unix_listen(host);
}
+# if defined(TLS)
+#ifdef HAVE_TLS
if (usetls) {
tls_config_verify_client_optional(tls_cfg);
if ((tls_ctx = tls_server()) == NULL)
@@ -598,6 +656,7 @@ main(int argc, char *argv[])
@@ -606,6 +664,7 @@ main(int argc, char *argv[])
errx(1, "tls configuration failed (%s)",
tls_error(tls_ctx));
}
+# endif
+#endif
/* Allow only one connection at a time, but stay alive. */
for (;;) {
if (family != AF_UNIX) {
@@ -613,7 +672,11 @@ main(int argc, char *argv[])
@@ -621,7 +680,11 @@ main(int argc, char *argv[])
* let it receive datagrams from multiple
* socket pairs.
*/
+# if defined(TLS)
+#ifdef HAVE_TLS
readwrite(s, NULL);
+# else
+#else
+ readwrite(s);
+# endif
+#endif
} else if (uflag && !kflag) {
/*
* For UDP and not -k, we will use recvfrom()
@@ -638,9 +701,14 @@ main(int argc, char *argv[])
report_sock("Connection received",
(struct sockaddr *)&z, len, NULL);
@@ -647,9 +710,14 @@ main(int argc, char *argv[])
(struct sockaddr *)&z, len,
family == AF_UNIX ? host : NULL);
+# if defined(TLS)
+#ifdef HAVE_TLS
readwrite(s, NULL);
} else {
struct tls *tls_cctx = NULL;
+# else
+#else
+ readwrite(s);
+ } else {
+# endif
+#endif
int connfd;
len = sizeof(cliaddr);
@@ -654,6 +722,7 @@ main(int argc, char *argv[])
@@ -663,6 +731,7 @@ main(int argc, char *argv[])
report_sock("Connection received",
(struct sockaddr *)&cliaddr, len,
family == AF_UNIX ? host : NULL);
+# if defined(TLS)
+#ifdef HAVE_TLS
if ((usetls) &&
(tls_cctx = tls_setup_server(tls_ctx, connfd, host)))
readwrite(connfd, tls_cctx);
@@ -663,6 +732,10 @@ main(int argc, char *argv[])
@@ -672,6 +741,10 @@ main(int argc, char *argv[])
timeout_tls(s, tls_cctx, tls_close);
close(connfd);
tls_free(tls_cctx);
+# else
+#else
+ readwrite(connfd);
+ close(connfd);
+# endif
+#endif
}
if (family == AF_UNIX && uflag) {
if (connect(s, NULL, 0) < 0)
@@ -677,7 +750,11 @@ main(int argc, char *argv[])
if (!kflag)
@@ -682,7 +755,11 @@ main(int argc, char *argv[])
if ((s = unix_connect(host)) > 0) {
if (!zflag)
+# if defined(TLS)
+#ifdef HAVE_TLS
readwrite(s, NULL);
+# else
+#else
+ readwrite(s);
+# endif
+#endif
close(s);
} else {
warn("%s", host);
@@ -698,6 +775,7 @@ main(int argc, char *argv[])
@@ -702,6 +779,7 @@ main(int argc, char *argv[])
for (s = -1, i = 0; portlist[i] != NULL; i++) {
if (s != -1)
close(s);
+# if defined(TLS)
+#ifdef HAVE_TLS
tls_free(tls_ctx);
tls_ctx = NULL;
@@ -708,6 +786,7 @@ main(int argc, char *argv[])
@@ -712,6 +790,7 @@ main(int argc, char *argv[])
errx(1, "tls configuration failed (%s)",
tls_error(tls_ctx));
}
+# endif
+#endif
if (xflag)
s = socks_connect(host, portlist[i], hints,
proxy, proxyport, proxyhints, socksv,
@@ -745,6 +824,7 @@ main(int argc, char *argv[])
@@ -741,6 +820,7 @@ main(int argc, char *argv[])
}
if (Fflag)
fdpass(s);
+# if defined(TLS)
+#ifdef HAVE_TLS
else {
if (usetls)
tls_setup_client(tls_ctx, s, host);
@@ -753,13 +833,19 @@ main(int argc, char *argv[])
@@ -749,13 +829,19 @@ main(int argc, char *argv[])
if (tls_ctx)
timeout_tls(s, tls_ctx, tls_close);
}
+# else
+#else
+ else if (!zflag)
+ readwrite(s);
+# endif
+#endif
}
}
if (s != -1)
close(s);
+# if defined(TLS)
+#ifdef HAVE_TLS
tls_free(tls_ctx);
tls_config_free(tls_cfg);
+# endif
+#endif
return ret;
}
@@ -801,6 +887,7 @@ unix_bind(char *path, int flags)
@@ -797,6 +883,7 @@ unix_bind(char *path, int flags)
return s;
}
+# if defined(TLS)
+#ifdef HAVE_TLS
int
timeout_tls(int s, struct tls *tls_ctx, int (*func)(struct tls *))
{
@@ -887,6 +974,7 @@ tls_setup_server(struct tls *tls_ctx, in
@@ -884,6 +971,7 @@ tls_setup_server(struct tls *tls_ctx, int connfd, char *host)
}
return NULL;
}
+# endif
+#endif
/*
* unix_connect()
@@ -1112,7 +1200,11 @@ local_listen(const char *host, const cha
@@ -1130,7 +1218,11 @@ local_listen(const char *host, const char *port, struct addrinfo hints)
* Loop that polls on the network file descriptor and stdin.
*/
void
+# if defined(TLS)
+#ifdef HAVE_TLS
readwrite(int net_fd, struct tls *tls_ctx)
+# else
+#else
+readwrite(int net_fd)
+# endif
+#endif
{
struct pollfd pfd[4];
int stdin_fd = STDIN_FILENO;
@@ -1212,12 +1304,17 @@ readwrite(int net_fd, struct tls *tls_ct
@@ -1230,12 +1322,17 @@ readwrite(int net_fd, struct tls *tls_ctx)
/* try to read from stdin */
if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) {
ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf,
+# if defined(TLS)
+#ifdef HAVE_TLS
&stdinbufpos, NULL);
if (ret == TLS_WANT_POLLIN)
pfd[POLL_STDIN].events = POLLIN;
@@ -666,18 +670,18 @@ that are already used by our Debian-specific patches.
pfd[POLL_STDIN].events = POLLOUT;
- else if (ret == 0 || ret == -1)
+ else
+# else
+#else
+ &stdinbufpos);
+# endif
+#endif
+ if (ret == 0 || ret == -1)
pfd[POLL_STDIN].fd = -1;
/* read something - poll net out */
if (stdinbufpos > 0)
@@ -1229,12 +1326,17 @@ readwrite(int net_fd, struct tls *tls_ct
@@ -1247,12 +1344,17 @@ readwrite(int net_fd, struct tls *tls_ctx)
/* try to write to network */
if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) {
ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf,
+# if defined(TLS)
+#ifdef HAVE_TLS
&stdinbufpos, tls_ctx);
if (ret == TLS_WANT_POLLIN)
pfd[POLL_NETOUT].events = POLLIN;
@@ -685,18 +689,18 @@ that are already used by our Debian-specific patches.
pfd[POLL_NETOUT].events = POLLOUT;
- else if (ret == -1)
+ else
+# else
+#else
+ &stdinbufpos);
+# endif
+#endif
+ if (ret == -1)
pfd[POLL_NETOUT].fd = -1;
/* buffer empty - remove self from polling */
if (stdinbufpos == 0)
@@ -1246,12 +1348,17 @@ readwrite(int net_fd, struct tls *tls_ct
@@ -1264,12 +1366,17 @@ readwrite(int net_fd, struct tls *tls_ctx)
/* try to read from network */
if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) {
ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf,
+# if defined(TLS)
+#ifdef HAVE_TLS
&netinbufpos, tls_ctx);
if (ret == TLS_WANT_POLLIN)
pfd[POLL_NETIN].events = POLLIN;
@@ -704,18 +708,18 @@ that are already used by our Debian-specific patches.
pfd[POLL_NETIN].events = POLLOUT;
- else if (ret == -1)
+ else
+# else
+#else
+ &netinbufpos);
+# endif
+#endif
+ if (ret == -1)
pfd[POLL_NETIN].fd = -1;
/* eof on net in - remove from pfd */
if (ret == 0) {
@@ -1278,12 +1385,17 @@ readwrite(int net_fd, struct tls *tls_ct
@@ -1296,12 +1403,17 @@ readwrite(int net_fd, struct tls *tls_ctx)
/* try to write to stdout */
if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) {
ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf,
+# if defined(TLS)
+#ifdef HAVE_TLS
&netinbufpos, NULL);
if (ret == TLS_WANT_POLLIN)
pfd[POLL_STDOUT].events = POLLIN;
@@ -723,94 +727,100 @@ that are already used by our Debian-specific patches.
pfd[POLL_STDOUT].events = POLLOUT;
- else if (ret == -1)
+ else
+# else
+#else
+ &netinbufpos);
+# endif
+#endif
+ if (ret == -1)
pfd[POLL_STDOUT].fd = -1;
/* buffer empty - remove self from polling */
if (netinbufpos == 0)
@@ -1307,21 +1419,31 @@ readwrite(int net_fd, struct tls *tls_ct
@@ -1325,7 +1437,11 @@ readwrite(int net_fd, struct tls *tls_ctx)
}
ssize_t
+# if defined(TLS)
+#ifdef HAVE_TLS
drainbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
+# else
+#else
+drainbuf(int fd, unsigned char *buf, size_t *bufpos)
+# endif
+#endif
{
ssize_t n;
ssize_t adjust;
@@ -1333,16 +1449,22 @@ drainbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
if (fd == -1)
return -1;
+# if defined(TLS)
+#ifdef HAVE_TLS
if (tls) {
n = tls_write(tls, buf, *bufpos);
if (n == -1)
errx(1, "tls write failed (%s)", tls_error(tls));
} else {
+# endif
+#endif
n = write(fd, buf, *bufpos);
/* don't treat EAGAIN, EINTR as error */
if (n == -1 && (errno == EAGAIN || errno == EINTR))
+# if defined(TLS)
+#ifdef HAVE_TLS
n = TLS_WANT_POLLOUT;
}
+# else
+#else
+ n = -2;
+# endif
+#endif
if (n <= 0)
return n;
/* adjust buffer */
@@ -1333,21 +1455,31 @@ drainbuf(int fd, unsigned char *buf, siz
@@ -1354,7 +1476,11 @@ drainbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
}
ssize_t
+# if defined(TLS)
+#ifdef HAVE_TLS
fillbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
+# else
+#else
+fillbuf(int fd, unsigned char *buf, size_t *bufpos)
+# endif
+#endif
{
size_t num = BUFSIZE - *bufpos;
ssize_t n;
@@ -1362,16 +1488,22 @@ fillbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
if (fd == -1)
return -1;
+# if defined(TLS)
+#ifdef HAVE_TLS
if (tls) {
n = tls_read(tls, buf + *bufpos, num);
if (n == -1)
errx(1, "tls read failed (%s)", tls_error(tls));
} else {
+# endif
+#endif
n = read(fd, buf + *bufpos, num);
/* don't treat EAGAIN, EINTR as error */
if (n == -1 && (errno == EAGAIN || errno == EINTR))
+# if defined(TLS)
+#ifdef HAVE_TLS
n = TLS_WANT_POLLIN;
}
+# else
+#else
+ n = -2;
+# endif
+#endif
if (n <= 0)
return n;
*bufpos += n;
@@ -1665,6 +1797,7 @@ process_tos_opt(char *s, int *val)
@@ -1718,6 +1850,7 @@ process_tos_opt(char *s, int *val)
return 0;
}
+# if defined(TLS)
+#ifdef HAVE_TLS
int
process_tls_opt(char *s, int *flags)
{
@@ -1778,6 +1911,7 @@ report_tls(struct tls * tls_ctx, char *
@@ -1831,6 +1964,7 @@ report_tls(struct tls *tls_ctx, char *host)
break;
}
}
+# endif
+#endif
void
report_sock(const char *msg, const struct sockaddr *sa, socklen_t salen,
@@ -1816,17 +1950,12 @@ help(void)
@@ -1872,17 +2006,12 @@ help(void)
fprintf(stderr, "\tCommand Summary:\n\
\t-4 Use IPv4\n\
\t-6 Use IPv6\n\
@@ -828,7 +838,7 @@ that are already used by our Debian-specific patches.
\t-k Keep inbound sockets open for multiple connects\n\
\t-l Listen mode, for inbound connects\n\
\t-M ttl Outgoing TTL / Hop Limit\n\
@@ -1834,14 +1963,12 @@ help(void)
@@ -1890,14 +2019,12 @@ help(void)
\t-N Shutdown the network socket after EOF on stdin\n\
\t-n Suppress name/port resolutions\n\
\t-O length TCP send buffer length\n\
@@ -838,13 +848,13 @@ that are already used by our Debian-specific patches.
- \t-R CAfile CA bundle\n\
\t-r Randomize remote ports\n\
\t-S Enable the TCP MD5 signature option\n\
\t-s source Local source address\n\
\t-s sourceaddr Local source address\n\
- \t-T keyword TOS value or TLS options\n\
+ \t-T keyword TOS value\n\
\t-t Answer TELNET negotiation\n\
\t-U Use UNIX domain socket\n\
\t-u UDP mode\n\
@@ -1851,7 +1978,6 @@ help(void)
@@ -1907,7 +2034,6 @@ help(void)
\t-w timeout Timeout for connects and final net reads\n\
\t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
\t-x addr[:port]\tSpecify proxy address and port\n\
@@ -852,7 +862,7 @@ that are already used by our Debian-specific patches.
\t-z Zero-I/O mode [used for scanning]\n\
Port numbers can be individual or ranges: lo-hi [inclusive]\n");
exit(0);
@@ -1861,15 +1987,11 @@ void
@@ -1917,15 +2043,11 @@ void
usage(int ret)
{
fprintf(stderr,
@@ -863,10 +873,11 @@ that are already used by our Debian-specific patches.
- "[-R CAfile]\n"
+ "usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-M ttl]\n"
+ "\t [-m minttl] [-O length] [-P proxy_username] [-p source_port]\n"
"\t [-s source] [-T keyword] [-V rtable] [-W recvlimit] "
"\t [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit] "
"[-w timeout]\n"
"\t [-X proxy_protocol] [-x proxy_address[:port]] "
- "\t [-X proxy_protocol] [-x proxy_address[:port]] "
- "[-Z peercertfile]\n"
+ "\t [-X proxy_protocol] [-x proxy_address[:port]]\n"
"\t [destination] [port]\n");
if (ret)
exit(1);

View File

@@ -1,11 +1,13 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 14:43:56 +0800
Subject: connect timeout
Subject: Fix connect() timeout
---
netcat.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 76 insertions(+), 2 deletions(-)
netcat.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 77 insertions(+), 5 deletions(-)
diff --git a/netcat.c b/netcat.c
index bec6e46..461e2bd 100644
--- a/netcat.c
+++ b/netcat.c
@@ -90,6 +90,7 @@
@@ -27,34 +29,43 @@ Subject: connect timeout
/* Command Line Options */
int dflag; /* detached, no stdin */
int Fflag; /* fdpass sock to stdout */
@@ -214,6 +219,9 @@ ssize_t drainbuf(int, unsigned char *, s
@@ -215,6 +220,8 @@ ssize_t drainbuf(int, unsigned char *, size_t *);
ssize_t fillbuf(int, unsigned char *, size_t *);
# endif
#endif
+static int connect_with_timeout(int fd, const struct sockaddr *sa,
+ socklen_t salen, int ctimeout);
+static int connect_with_timeout(int, const struct sockaddr *, socklen_t, int);
+
int
main(int argc, char *argv[])
{
@@ -1078,11 +1086,14 @@ remote_connect(const char *host, const c
set_common_sockopts(s, res->ai_family);
@@ -1088,18 +1095,21 @@ remote_connect(const char *host, const char *port, struct addrinfo hints,
}
}
- if (timeout_connect(s, res->ai_addr, res->ai_addrlen) == 0)
+ if ((error = connect_with_timeout(s, res->ai_addr, res->ai_addrlen, timeout)) == CONNECTION_SUCCESS)
+ if ((error = connect_with_timeout(s, res->ai_addr, res->ai_addrlen,
+ timeout)) == CONNECTION_SUCCESS)
break;
- if (vflag)
+ if (vflag && error == CONNECTION_FAILED)
warn("connect to %s port %s (%s) failed", host, port,
uflag ? "udp" : "tcp");
+ else if (vflag && error == CONNECTION_TIMEOUT)
+ warn("connect to %s port %s (%s) timed out", host, port,
+ uflag ? "udp" : "tcp");
if (vflag) {
/* only print IP if there is something to report */
if (nflag || ipaddr == NULL ||
(strncmp(host, ipaddr, NI_MAXHOST) == 0))
- warn("connect to %s port %s (%s) failed", host,
- port, uflag ? "udp" : "tcp");
+ warn("connect to %s port %s (%s) %s", host,
+ port, uflag ? "udp" : "tcp",
+ error == CONNECTION_TIMEOUT ? "timed out" : "failed");
else
- warn("connect to %s (%s) port %s (%s) failed",
- host, ipaddr, port, uflag ? "udp" : "tcp");
+ warn("connect to %s (%s) port %s (%s) %s",
+ host, ipaddr, port, uflag ? "udp" : "tcp",
+ error == CONNECTION_TIMEOUT ? "timed out" : "failed");
}
save_errno = errno;
close(s);
@@ -1123,6 +1134,69 @@ timeout_connect(int s, const struct sock
@@ -1141,6 +1151,68 @@ timeout_connect(int s, const struct sockaddr *name, socklen_t namelen)
return ret;
}
@@ -95,8 +106,7 @@ Subject: connect timeout
+
+ /* call select */
+ do {
+ err = select(fd + 1, NULL, &connect_fdset,
+ NULL, tvp);
+ err = select(fd + 1, NULL, &connect_fdset, NULL, tvp);
+ } while (err < 0 && errno == EINTR);
+
+ /* select error */

View File

@@ -1,12 +1,14 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:56:51 +0800
Subject: dccp support
Subject: New flag '-Z' for DCCP support
---
nc.1 | 4 ++
netcat.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 79 insertions(+), 14 deletions(-)
nc.1 | 4 ++-
netcat.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 76 insertions(+), 13 deletions(-)
diff --git a/nc.1 b/nc.1
index fbcc098..da37f06 100644
--- a/nc.1
+++ b/nc.1
@@ -33,7 +33,7 @@
@@ -18,7 +20,7 @@ Subject: dccp support
.Op Fl I Ar length
.Op Fl i Ar interval
.Op Fl M Ar ttl
@@ -289,6 +289,8 @@ An IPv6 address can be specified unambig
@@ -288,6 +288,8 @@ An IPv6 address can be specified unambiguously by enclosing
in square brackets.
A proxy cannot be used with any of the options
.Fl lsuU .
@@ -27,6 +29,8 @@ Subject: dccp support
.It Fl z
Only scan for listening daemons, without sending any data to them.
Cannot be used together with
diff --git a/netcat.c b/netcat.c
index dd893ac..1c50615 100644
--- a/netcat.c
+++ b/netcat.c
@@ -146,6 +146,7 @@ int rflag; /* Random ports flag */
@@ -37,49 +41,49 @@ Subject: dccp support
int vflag; /* Verbosity */
int xflag; /* Socks proxy */
int zflag; /* Port Scan Flag */
@@ -224,6 +225,7 @@ ssize_t drainbuf(int, unsigned char *, s
@@ -225,6 +226,7 @@ ssize_t drainbuf(int, unsigned char *, size_t *, int);
ssize_t fillbuf(int, unsigned char *, size_t *);
# endif
#endif
+char *proto_name(int uflag, int dccpflag);
static int connect_with_timeout(int fd, const struct sockaddr *sa,
socklen_t salen, int ctimeout);
+char *proto_name(int, int);
static int connect_with_timeout(int, const struct sockaddr *, socklen_t, int);
static void quit(int sig);
@@ -263,7 +265,7 @@ main(int argc, char *argv[])
# if defined(TLS)
@@ -261,7 +263,7 @@ main(int argc, char *argv[])
#ifdef HAVE_TLS
"46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:q:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
# else
#else
- "46CDdFhI:i:klM:m:NnO:P:p:q:rSs:T:tUuV:vW:w:X:x:z"))
+ "46CDdFhI:i:klM:m:NnO:P:p:q:rSs:T:tUuV:vW:w:X:x:Zz"))
# endif
#endif
!= -1) {
switch (ch) {
@@ -380,6 +382,13 @@ main(int argc, char *argv[])
@@ -378,6 +380,13 @@ main(int argc, char *argv[])
case 'u':
uflag = 1;
break;
+ case 'Z':
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+#if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ dccpflag = 1;
+# else
+#else
+ errx(1, "no DCCP support available");
+# endif
+#endif
+ break;
case 'V':
# if defined(RT_TABLEID_MAX)
#ifdef RT_TABLEID_MAX
rtableid = (int)strtonum(optarg, 0,
@@ -484,6 +493,10 @@ main(int argc, char *argv[])
@@ -482,6 +491,10 @@ main(int argc, char *argv[])
/* Cruft to make sure options are clean, and used properly. */
if (argv[0] && !argv[1] && family == AF_UNIX) {
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
if (argc == 1 && family == AF_UNIX) {
+#if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ if (dccpflag)
+ errx(1, "cannot use -Z and -U");
+# endif
+#endif
host = argv[0];
uport = NULL;
} else if (!argv[0] && lflag) {
@@ -577,8 +590,20 @@ main(int argc, char *argv[])
} else if (argc == 0 && lflag) {
if (sflag)
@@ -583,8 +596,20 @@ main(int argc, char *argv[])
if (family != AF_UNIX) {
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = family;
@@ -89,12 +93,12 @@ Subject: dccp support
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ }
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+#if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ else if (dccpflag) {
+ hints.ai_socktype = SOCK_DCCP;
+ hints.ai_protocol = IPPROTO_DCCP;
+ }
+# endif
+#endif
+ else {
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
@@ -102,59 +106,47 @@ Subject: dccp support
if (nflag)
hints.ai_flags |= AI_NUMERICHOST;
}
@@ -586,7 +611,10 @@ main(int argc, char *argv[])
@@ -592,7 +617,10 @@ main(int argc, char *argv[])
if (xflag) {
if (uflag)
errx(1, "no proxy support for UDP mode");
-
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+#if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ if (dccpflag)
+ errx(1, "no proxy support for DCCP mode");
+# endif
+#endif
if (lflag)
errx(1, "no proxy support for listen");
@@ -833,19 +861,20 @@ main(int argc, char *argv[])
@@ -838,9 +866,11 @@ main(int argc, char *argv[])
continue;
}
}
- if (print_info == 1)
+ if (print_info == 1) {
+ char *proto = proto_name(uflag, dccpflag);
/* Don't look up port if -n. */
if (nflag)
sv = NULL;
else {
sv = getservbyport(
ntohs(atoi(portlist[i])),
- uflag ? "udp" : "tcp");
+ proto);
}
fprintf(stderr,
"Connection to %s %s port [%s/%s] "
"succeeded!\n", host, portlist[i],
- uflag ? "udp" : "tcp",
+ proto,
sv ? sv->s_name : "*");
connection_info(host, portlist[i],
- uflag ? "udp" : "tcp", ipaddr);
+ proto, ipaddr);
+ }
}
if (Fflag)
@@ -1060,6 +1089,24 @@ unix_listen(char *path)
fdpass(s);
@@ -1054,6 +1084,21 @@ unix_listen(char *path)
return s;
}
+char *proto_name(int uflag, int dccpflag) {
+
+ char *proto = NULL;
+ if (uflag) {
+
+ if (uflag)
+ proto = "udp";
+ }
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ else if (dccpflag) {
+#if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ else if (dccpflag)
+ proto = "dccp";
+ }
+# endif
+ else {
+#endif
+ else
+ proto = "tcp";
+ }
+
+ return proto;
+}
@@ -162,8 +154,8 @@ Subject: dccp support
/*
* remote_connect()
* Returns a socket connected to a remote host. Properly binds to a local
@@ -1090,8 +1137,21 @@ remote_connect(const char *host, const c
# endif
@@ -1085,8 +1130,20 @@ remote_connect(const char *host, const char *port, struct addrinfo hints,
#endif
memset(&ahints, 0, sizeof(struct addrinfo));
ahints.ai_family = res->ai_family;
- ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
@@ -171,14 +163,13 @@ Subject: dccp support
+ if (uflag) {
+ ahints.ai_socktype = SOCK_DGRAM;
+ ahints.ai_protocol = IPPROTO_UDP;
+
+ }
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+#if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ else if (dccpflag) {
+ hints.ai_socktype = SOCK_DCCP;
+ hints.ai_protocol = IPPROTO_DCCP;
+ }
+# endif
+#endif
+ else {
+ ahints.ai_socktype = SOCK_STREAM;
+ ahints.ai_protocol = IPPROTO_TCP;
@@ -186,27 +177,28 @@ Subject: dccp support
ahints.ai_flags = AI_PASSIVE;
if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
errx(1, "getaddrinfo: %s", gai_strerror(error));
@@ -1103,15 +1163,16 @@ remote_connect(const char *host, const c
@@ -1116,16 +1173,18 @@ remote_connect(const char *host, const char *port, struct addrinfo hints,
timeout)) == CONNECTION_SUCCESS)
break;
+ char *proto = proto_name(uflag, dccpflag);
+
if (vflag) {
/* only print IP if there is something to report */
if (nflag || ipaddr == NULL ||
(strncmp(host, ipaddr, NI_MAXHOST) == 0))
warn("connect to %s port %s (%s) %s", host,
- port, uflag ? "udp" : "tcp",
+ port, proto,
error == CONNECTION_TIMEOUT ? "timed out" : "failed");
else
warn("connect to %s (%s) port %s (%s) %s",
- host, ipaddr, port, uflag ? "udp" : "tcp",
+ host, ipaddr, port, proto,
error == CONNECTION_TIMEOUT ? "timed out" : "failed");
}
set_common_sockopts(s, res->ai_family);
+ char *proto = proto_name(uflag, dccpflag);
if ((error = connect_with_timeout(s, res->ai_addr, res->ai_addrlen, timeout)) == CONNECTION_SUCCESS)
break;
if (vflag && error == CONNECTION_FAILED)
warn("connect to %s port %s (%s) failed", host, port,
- uflag ? "udp" : "tcp");
- else if (vflag && error == CONNECTION_TIMEOUT)
+ proto);
+ else if (vflag && error == CONNECTION_TIMEOUT)
warn("connect to %s port %s (%s) timed out", host, port,
- uflag ? "udp" : "tcp");
+ proto);
save_errno = errno;
close(s);
@@ -1715,7 +1776,8 @@ build_ports(char *p)
@@ -1742,7 +1801,8 @@ build_ports(char *p)
int hi, lo, cp;
int x = 0;
@@ -216,7 +208,7 @@ Subject: dccp support
if (sv) {
if (asprintf(&portlist[0], "%d", ntohs(sv->s_port)) < 0)
err(1, "asprintf");
@@ -2095,6 +2157,7 @@ help(void)
@@ -2155,6 +2215,7 @@ help(void)
\t-w timeout Timeout for connects and final net reads\n\
\t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
\t-x addr[:port]\tSpecify proxy address and port\n\
@@ -224,12 +216,12 @@ Subject: dccp support
\t-z Zero-I/O mode [used for scanning]\n\
Port numbers can be individual or ranges: lo-hi [inclusive]\n");
exit(0);
@@ -2104,7 +2167,7 @@ void
@@ -2164,7 +2225,7 @@ void
usage(int ret)
{
fprintf(stderr,
- "usage: nc [-46CDdFhklNnrStUuvz] [-I length] [-i interval] [-M ttl]\n"
+ "usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl]\n"
"\t [-m minttl] [-O length] [-P proxy_username] [-p source_port]\n"
"\t [-q seconds] [-s source] [-T keyword] [-V rtable] [-W recvlimit] "
"[-w timeout]\n"
"\t [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit]\n"
"\t [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]]\n"

View File

@@ -1,15 +1,17 @@
From: Guilhem Moulin <guilhem@debian.org>
Date: Mon, 22 Oct 2018 04:15:52 +0200
Subject: destination port list
Subject: Add ability to specify a list of destination ports
---
nc.1 | 26 ++++++++++++++++---
netcat.c | 86 ++++++++++++++++++++++++++++++++-------------------------------
nc.1 | 26 +++++++++++++++++---
netcat.c | 86 +++++++++++++++++++++++++++++++++-------------------------------
2 files changed, 68 insertions(+), 44 deletions(-)
diff --git a/nc.1 b/nc.1
index 49a3d4d..80c654c 100644
--- a/nc.1
+++ b/nc.1
@@ -414,15 +414,35 @@ The
@@ -417,15 +417,35 @@ The
flag can be used to tell
.Nm
to report open ports,
@@ -48,6 +50,8 @@ Subject: destination port list
.Pp
Alternatively, it might be useful to know which server software
is running, and which versions.
diff --git a/netcat.c b/netcat.c
index 990c31b..bef27a4 100644
--- a/netcat.c
+++ b/netcat.c
@@ -191,7 +191,7 @@ int minttl = -1;
@@ -58,31 +62,30 @@ Subject: destination port list
+void build_ports(char **);
void help(void) __attribute__((noreturn));
int local_listen(const char *, const char *, struct addrinfo);
# if defined(TLS)
@@ -242,7 +242,7 @@ int
#ifdef HAVE_TLS
@@ -241,7 +241,7 @@ int
main(int argc, char *argv[])
{
int ch, s = -1, ret, socksv;
- char *host, *uport;
+ char *host, **uport;
char ipaddr[NI_MAXHOST];
struct addrinfo hints;
struct servent *sv;
socklen_t len;
@@ -526,11 +526,11 @@ main(int argc, char *argv[])
} else if (argv[0] && !argv[1]) {
if (!lflag)
usage(1);
@@ -521,10 +521,10 @@ main(int argc, char *argv[])
if (zflag)
errx(1, "cannot use -z and -l");
} else if (argc == 1 && lflag) {
- uport = argv[0];
+ uport = &argv[0];
host = NULL;
} else if (argv[0] && argv[1]) {
} else if (argc == 2) {
host = argv[0];
- uport = argv[1];
+ uport = &argv[1];
} else
usage(1);
@@ -717,7 +717,7 @@ main(int argc, char *argv[])
@@ -723,7 +723,7 @@ main(int argc, char *argv[])
else
s = unix_listen(host);
} else
@@ -91,7 +94,7 @@ Subject: destination port list
if (s < 0)
err(1, NULL);
@@ -1785,57 +1785,61 @@ strtoport(char *portstr, int udp)
@@ -1810,57 +1810,61 @@ strtoport(char *portstr, int udp)
* that we should try to connect to.
*/
void
@@ -130,7 +133,7 @@ Subject: destination port list
- for (x = 0; x <= hi - lo; x++) {
- cp = arc4random_uniform(x + 1);
- portlist[x] = portlist[cp];
- if (asprintf(&portlist[cp], "%d", x + lo) < 0)
- if (asprintf(&portlist[cp], "%d", x + lo) == -1)
- err(1, "asprintf");
+ for (i = 0; p[i] != NULL; i++) {
+ sv = getservbyname(p[i], proto);
@@ -154,7 +157,7 @@ Subject: destination port list
+
+ /* Load ports sequentially. */
for (cp = lo; cp <= hi; cp++) {
if (asprintf(&portlist[x], "%d", cp) < 0)
if (asprintf(&portlist[x], "%d", cp) == -1)
err(1, "asprintf");
x++;
}

View File

@@ -1,9 +1,9 @@
Index: netcat-openbsd-1.203/netcat.c
Index: netcat-openbsd-1.229/netcat.c
===================================================================
--- netcat-openbsd-1.203.orig/netcat.c
+++ netcat-openbsd-1.203/netcat.c
@@ -1889,6 +1889,21 @@ udptest(int s)
return 1;
--- netcat-openbsd-1.229.orig/netcat.c 2025-06-04 07:36:53.985608901 +0000
+++ netcat-openbsd-1.229/netcat.c 2025-06-04 07:37:13.091297946 +0000
@@ -1990,6 +1990,21 @@ connection_info(const char *host, const
fprintf(stderr, " %s port [%s/%s] succeeded!\n", port, proto, service);
}
+static int
@@ -24,7 +24,7 @@ Index: netcat-openbsd-1.203/netcat.c
void
set_common_sockopts(int s, const struct sockaddr* sa)
{
@@ -1982,6 +1997,8 @@ set_common_sockopts(int s, const struct
@@ -2084,6 +2099,8 @@ set_common_sockopts(int s, const struct
errx(1, "can't set IPv6 min hop count (unavailable)");
#endif
}

View File

@@ -1,14 +1,16 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 14:45:08 +0800
Subject: get sev by name
Subject: Add ability to specify destination ports by name
---
netcat.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/netcat.c b/netcat.c
index 461e2bd..2dc1abd 100644
--- a/netcat.c
+++ b/netcat.c
@@ -1679,11 +1679,16 @@ strtoport(char *portstr, int udp)
@@ -1700,11 +1700,16 @@ strtoport(char *portstr, int udp)
void
build_ports(char *p)
{

View File

@@ -0,0 +1,30 @@
From: Guilhem Moulin <guilhem@debian.org>
Date: Fri, 5 Jun 2020 03:11:21 +0200
Subject: Make getnameinfo(3) errors non-fatal in report_sock()
report_sock() is used to show the peer's address/name and port when the
-v flag is set. Reverse resolution errors need not be fatal.
Bug-Debian: https://bugs.debian.org/961378
---
netcat.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/netcat.c b/netcat.c
index 0caba28..061a774 100644
--- a/netcat.c
+++ b/netcat.c
@@ -2220,9 +2220,11 @@ report_sock(const char *msg, const struct sockaddr *sa, socklen_t salen,
case 0:
break;
case EAI_SYSTEM:
- err(1, "getnameinfo");
+ warn("getnameinfo");
+ return;
default:
- errx(1, "getnameinfo: %s", gai_strerror(herr));
+ warnx("getnameinfo: %s", gai_strerror(herr));
+ return;
}
fprintf(stderr, "%s on %s %s\n", msg, host, port);

View File

@@ -1,31 +1,20 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 19:06:52 +0800
Subject: misc failures and features
Subject: Misc failures and features
---
Makefile | 3 ++-
nc.1 | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
netcat.c | 14 ++++++++++++--
3 files changed, 65 insertions(+), 3 deletions(-)
netcat.c | 37 +++++++++++++++++++++++++++++--------
2 files changed, 80 insertions(+), 8 deletions(-)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,8 @@
PROG= nc
SRCS= netcat.c atomicio.c socks.c
-LIBS= `pkg-config --libs libbsd` -lresolv
+PKG_CONFIG ?= pkg-config
+LIBS= `$(PKG_CONFIG) --libs libbsd` -lresolv
OBJS= $(SRCS:.c=.o)
CFLAGS= -g -O2
LDFLAGS= -Wl,--no-add-needed
diff --git a/nc.1 b/nc.1
index 8285c10..a159c73 100644
--- a/nc.1
+++ b/nc.1
@@ -365,6 +365,54 @@ and which side is being used as a
The connection may be terminated using an
.Dv EOF
.Pq Sq ^D .
@@ -371,6 +371,54 @@ The connection may be terminated using an
as the
.Fl N
flag was given.
+.Pp
+There is no
+.Fl c
@@ -77,7 +66,7 @@ Subject: misc failures and features
.Sh DATA TRANSFER
The example in the previous section can be expanded to build a
basic data transfer model.
@@ -517,6 +565,9 @@ Original implementation by
@@ -523,6 +571,9 @@ Original implementation by
.br
Rewritten with IPv6 support by
.An Eric Jackson Aq Mt ericj@monkey.org .
@@ -87,59 +76,92 @@ Subject: misc failures and features
.Sh CAVEATS
UDP port scans using the
.Fl uz
diff --git a/netcat.c b/netcat.c
index 2f8890b..2a3714a 100644
--- a/netcat.c
+++ b/netcat.c
@@ -98,6 +98,7 @@
#include <netdb.h>
#include <poll.h>
#include <signal.h>
+#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -246,7 +247,10 @@ main(int argc, char *argv[])
struct addrinfo hints;
struct servent *sv;
socklen_t len;
- struct sockaddr_storage cliaddr;
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr_un forunix;
+ } cliaddr;
char *proxy = NULL, *proxyport = NULL;
const char *errstr;
struct addrinfo proxyhints;
@@ -945,6 +949,8 @@ unix_bind(char *path, int flags)
0)) < 0)
@@ -114,7 +114,7 @@
#include "atomicio.h"
#define PORT_MAX 65535
-#define UNIX_DG_TMP_SOCKET_SIZE 19
+#define UNIX_DG_TMP_SOCKET_SIZE 25
#define POLL_STDIN 0
#define POLL_NETOUT 1
@@ -618,10 +618,20 @@ main(int argc, char *argv[])
if (sflag) {
unix_dg_tmp_socket = sflag;
} else {
- strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX",
+ /* On Linux it's tempting to use abstract sockets here in
+ * order to limit bookkeeping and avoid cluttering /tmp.
+ * Unfortunately though this has security implications, as a
+ * second client could inject server responses if they
+ * manage to connect(2) to the temporary socket between the
+ * first client's bind(2) and connect(2) calls. OTOH for
+ * pathname sockets the injection is only possible on Linux
+ * when write access to the socket is granted. */
+ strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc-XXXXXX",
+ UNIX_DG_TMP_SOCKET_SIZE);
+ if (mkdtemp(unix_dg_tmp_socket_buf) == NULL)
+ err(1, "mkdtemp");
+ strlcat(unix_dg_tmp_socket_buf, "/recv.sock",
UNIX_DG_TMP_SOCKET_SIZE);
- if (mktemp(unix_dg_tmp_socket_buf) == NULL)
- err(1, "mktemp");
unix_dg_tmp_socket = unix_dg_tmp_socket_buf;
}
}
@@ -851,8 +861,14 @@ main(int argc, char *argv[])
ret = 1;
}
- if (uflag)
+ if (uflag && !sflag) {
unlink(unix_dg_tmp_socket);
+ char *nam = strrchr(unix_dg_tmp_socket, '/');
+ if (nam != NULL) {
+ nam[0] = '\0';
+ rmdir(unix_dg_tmp_socket);
+ }
+ }
return ret;
} else {
int i = 0;
@@ -991,6 +1007,11 @@ unix_bind(char *path, int flags)
0)) == -1)
return -1;
+#ifdef __linux__
+ if (path[0] != '@')
+#endif
+ unlink(path);
+
memset(&s_un, 0, sizeof(struct sockaddr_un));
s_un.sun_family = AF_UNIX;
@@ -1070,8 +1076,10 @@ unix_connect(char *path)
if ((s = unix_bind(unix_dg_tmp_socket, SOCK_CLOEXEC)) < 0)
return -1;
} else {
- if ((s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0)
+ if ((s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0) {
+ errx(1, "create unix socket failed");
return -1;
+ }
}
memset(&s_un, 0, sizeof(struct sockaddr_un));
@@ -1081,10 +1089,12 @@ unix_connect(char *path)
sizeof(s_un.sun_path)) {
close(s);
errno = ENAMETOOLONG;
+ warn("unix connect abandoned");
return -1;
}
if (connect(s, (struct sockaddr *)&s_un, sizeof(s_un)) < 0) {
if (bind(s, (struct sockaddr *)&s_un, addrlen) == -1) {
save_errno = errno;
+ warn("unix connect failed");
close(s);
errno = save_errno;
@@ -1108,7 +1129,7 @@ unix_connect(char *path)
if (uflag) {
if ((s = unix_bind(unix_dg_tmp_socket, SOCK_CLOEXEC)) == -1)
- return -1;
+ err(1, "%s", unix_dg_tmp_socket);
} else {
if ((s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1)
return -1;
@@ -1381,12 +1402,12 @@ local_listen(const char *host, const char *port, struct addrinfo hints)
ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
if (ret == -1)
- err(1, NULL);
+ warn("Couldn't set SO_REUSEADDR");
#ifdef SO_REUSEPORT
ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
if (ret == -1)
- err(1, NULL);
+ warn("Couldn't set SO_REUSEPORT");
#endif
set_common_sockopts(s, res->ai_addr);

View File

@@ -1,3 +1,68 @@
-------------------------------------------------------------------
Wed Jun 4 07:38:37 UTC 2025 - Peter Simons <psimons@suse.com>
- Update netcat to upstream version 1.229.
* Fix build failure with GCC-15.
* In UDP mode, do not test the connection (by writing "XXX" junk)
when -z is unset and the standard input is not a TTY.
* rsync: Replace -v flag with -P.
* udp-scan-timeout.patch: Call connection_info() and udptest()
call when -z flag is set. This is the upstream behavior.
* Add support for abstract namespace sockets in the AF_UNIX family.
* Make getnameinfo(3) errors non-fatal in report_sock():
report_sock() is used to show the peer's address/name and port
when the '-v' flag is set. Reverse resolution errors need not
be fatal.
* Fix TCP MD5 signature support. The feature now requires the
TCP_MD5SIG_EXT socket option, available since Linux 4.13.
* Make -q0 quit immediately also with UDP sockets.
* Re-enable specifying client socket for UNIX-domain datagram
sockets. Regression introduced in version 1.187.
- Added "abstract-unix-domain-socket.patch": when using '-U' to
connect() or bind() to a UNIX domain socket, if the address
(path) starts with "@", it is read as an abstract namespace
socket.
- Added "make-getnameinfo-errors-nonfatal-in-report_sock.patch":
report_sock() is used to show the peer's address/name and port
when the -v flag is set. Reverse resolution errors need not be
fatal.
- Renamed the misspelled "port-to-linux-with-libsd.patch" to
"port-to-linux-with-libbsd.patch".
- Refreshed patches:
* broadcast-support.patch
* build-without-TLS-support.patch
* connect-timeout.patch
* dccp-support.patch
* destination-port-list.patch
* enable-udp-ip_recverr.patch
* get-sev-by-name.patch
* misc-failures-and-features.patch
* port-select-on-connect.patch
* port-to-linux-with-libbsd.patch
* quit-timer.patch
* send-crlf.patch
* serialized-handling-multiple-clients.patch
* set-TCP-MD5SIG-correctly-for-client-connections.patch
* udp-scan-timeout.patch
* use-flags-to-specify-listen-address.patch
-------------------------------------------------------------------
Tue Apr 8 13:01:27 UTC 2025 - Friedrich Haubensak <hsk17@mail.de>
- add -std=gnu99 to CFLAGS to fix gcc15 compile time errors
-------------------------------------------------------------------
Mon Nov 22 10:16:15 UTC 2021 - Peter Simons <psimons@suse.com>
@@ -179,4 +244,3 @@ Sat Jul 5 19:30:39 CEST 2008 - crrodriguez@suse.de
Sun Apr 13 05:08:48 CEST 2008 - crrodriguez@suse.de
- initial version for the OBS

View File

@@ -1,7 +1,7 @@
#
# spec file for package netcat-openbsd
#
# Copyright (c) 2021 SUSE LLC
# Copyright (c) 2025 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,15 +17,15 @@
Name: netcat-openbsd
Version: 1.203
Version: 1.229
Release: 0
Summary: TCP/IP swiss army knife
License: BSD-3-Clause
Group: Productivity/Networking/Other
URL: https://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/nc/
Source0: http://old.kali.org/kali/pool/main/n/netcat-openbsd/netcat-openbsd_%{version}.orig.tar.gz
#Patches from: http://http.debian.net/debian/pool/main/n/netcat-openbsd/netcat-openbsd_%{version}-2.debian.tar.xz
Patch0: port-to-linux-with-libsd.patch
Source0: http://deb.debian.org/debian/pool/main/n/netcat-openbsd/netcat-openbsd_%{version}.orig.tar.gz
# Debian patches from: http://http.debian.net/debian/pool/main/n/netcat-openbsd/netcat-openbsd_%{version}-2.debian.tar.xz
Patch0: port-to-linux-with-libbsd.patch
Patch1: build-without-TLS-support.patch
Patch2: connect-timeout.patch
Patch3: get-sev-by-name.patch
@@ -38,9 +38,12 @@ Patch9: serialized-handling-multiple-clients.patch
Patch10: set-TCP-MD5SIG-correctly-for-client-connections.patch
Patch11: destination-port-list.patch
Patch12: use-flags-to-specify-listen-address.patch
Patch13: misc-failures-and-features.patch
Patch14: port-select-on-connect.patch
Patch15: enable-udp-ip_recverr.patch
Patch13: make-getnameinfo-errors-nonfatal-in-report_sock.patch
Patch14: abstract-unix-domain-socket.patch
Patch15: misc-failures-and-features.patch
# SUSE patches
Patch20: port-select-on-connect.patch
Patch21: enable-udp-ip_recverr.patch
BuildRequires: pkgconfig
BuildRequires: pkgconfig(libbsd)
Provides: nc6 = %{version}
@@ -61,8 +64,7 @@ This package contains the OpenBSD rewrite of netcat, including support
for IPv6, proxies, and Unix sockets.
%prep
%setup -q
%autopatch -p1
%autosetup -p1
%build
make %{?_smp_mflags} \

BIN
netcat-openbsd_1.203.orig.tar.gz (Stored with Git LFS)

Binary file not shown.

BIN
netcat-openbsd_1.229.orig.tar.gz (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -1,8 +1,8 @@
Index: netcat-openbsd-1.203/netcat.c
Index: netcat-openbsd-1.229/netcat.c
===================================================================
--- netcat-openbsd-1.203.orig/netcat.c
+++ netcat-openbsd-1.203/netcat.c
@@ -1190,7 +1190,10 @@ remote_connect(const char *host, const c
--- netcat-openbsd-1.229.orig/netcat.c 2025-06-04 07:36:38.214088834 +0000
+++ netcat-openbsd-1.229/netcat.c 2025-06-04 07:36:53.985608901 +0000
@@ -1228,7 +1228,10 @@ remote_connect(const char *host, const c
ahints.ai_flags = AI_PASSIVE;
if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
errx(1, "getaddrinfo: %s", gai_strerror(error));
@@ -12,5 +12,5 @@ Index: netcat-openbsd-1.203/netcat.c
+ setsockopt(s, SOL_IP, IP_BIND_ADDRESS_NO_PORT, &on, sizeof(on));
+#endif
if (bind(s, (struct sockaddr *)ares->ai_addr,
ares->ai_addrlen) < 0)
ares->ai_addrlen) == -1)
err(1, "bind failed");

View File

@@ -1,38 +1,44 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:59:31 +0800
Subject: port to linux with libsd
Subject: Port to linux with libbsd
Forwarded: not-needed
---
Makefile | 15 ++++++-
nc.1 | 3 -
netcat.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++---------------
socks.c | 46 +++++++++++-----------
4 files changed, 139 insertions(+), 56 deletions(-)
Makefile | 16 +++++++-
nc.1 | 3 +-
netcat.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++-----------------
socks.c | 48 +++++++++++------------
4 files changed, 139 insertions(+), 63 deletions(-)
diff --git a/Makefile b/Makefile
index 5f20c40..93ca5ee 100644
--- a/Makefile
+++ b/Makefile
@@ -5,4 +5,17 @@ SRCS= netcat.c atomicio.c socks.c
@@ -5,4 +5,18 @@ SRCS= netcat.c atomicio.c socks.c
LDADD+= -ltls -lssl -lcrypto
DPADD+= ${LIBTLS} ${LIBSSL} ${LIBCRYPTO}
-.include <bsd.prog.mk>
+LIBS= `pkg-config --libs libbsd` -lresolv
+PKG_CONFIG ?= pkg-config
+LIBS= `$(PKG_CONFIG) --libs libbsd` -lresolv
+OBJS= $(SRCS:.c=.o)
+CFLAGS= -g -O2
+LDFLAGS= -Wl,--no-add-needed
+
+all: nc
+nc: $(OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o nc
+ $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
+
+$(OBJS): %.o: %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+clean:
+ rm -f $(OBJS) nc
diff --git a/nc.1 b/nc.1
index 76b6dc0..596bd8e 100644
--- a/nc.1
+++ b/nc.1
@@ -213,8 +213,6 @@ Proxy authentication is only supported f
@@ -213,8 +213,6 @@ Proxy authentication is only supported for HTTP CONNECT proxies at present.
Specify the source port
.Nm
should use, subject to privilege restrictions and availability.
@@ -41,7 +47,7 @@ Subject: port to linux with libsd
.It Fl R Ar CAfile
Load the root CA bundle for TLS certificate verification from
.Ar CAfile ,
@@ -274,6 +272,7 @@ For the IPv4 TOS/IPv6 traffic class valu
@@ -273,6 +271,7 @@ For the IPv4 TOS/IPv6 traffic class value,
may be one of
.Cm critical ,
.Cm inetcontrol ,
@@ -49,6 +55,8 @@ Subject: port to linux with libsd
.Cm lowdelay ,
.Cm netcontrol ,
.Cm throughput ,
diff --git a/netcat.c b/netcat.c
index 8c60fd1..d23e566 100644
--- a/netcat.c
+++ b/netcat.c
@@ -32,6 +32,8 @@
@@ -123,14 +131,14 @@ Subject: port to linux with libsd
uflag = 1;
break;
case 'V':
+# if defined(RT_TABLEID_MAX)
+#ifdef RT_TABLEID_MAX
rtableid = (int)strtonum(optarg, 0,
RT_TABLEID_MAX, &errstr);
if (errstr)
errx(1, "rtable %s: %s", errstr, optarg);
+# else
+#else
+ errx(1, "no alternate routing table support available");
+# endif
+#endif
break;
case 'v':
vflag = 1;
@@ -138,39 +146,38 @@ Subject: port to linux with libsd
oflag = optarg;
break;
case 'S':
+# if defined(TCP_MD5SIG)
+#ifdef TCP_MD5SIG
Sflag = 1;
+# else
+#else
+ errx(1, "no TCP MD5 signature support available");
+# endif
+#endif
break;
case 'T':
errstr = NULL;
@@ -346,14 +401,23 @@ main(int argc, char *argv[])
@@ -346,13 +401,22 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
+# if defined(RT_TABLEID_MAX)
+#ifdef RT_TABLEID_MAX
if (rtableid >= 0)
if (setrtable(rtableid) == -1)
err(1, "setrtable");
+# endif
+#endif
/* Cruft to make sure options are clean, and used properly. */
if (argv[0] && !argv[1] && family == AF_UNIX) {
if (argc == 1 && family == AF_UNIX) {
host = argv[0];
uport = NULL;
+ } else if (!argv[0] && lflag) {
+ } else if (argc == 0 && lflag) {
+ if (sflag)
+ errx(1, "cannot use -s and -l");
+ if (pflag)
+ errx(1, "cannot use -p and -l");
+ if (zflag)
+ errx(1, "cannot use -z and -l");
} else if (argv[0] && !argv[1]) {
if (!lflag)
usage(1);
@@ -388,33 +452,6 @@ main(int argc, char *argv[])
} else if (argc == 1 && lflag) {
uport = argv[0];
} else if (argc == 2) {
@@ -396,33 +460,6 @@ main(int argc, char *argv[])
}
}
@@ -204,63 +211,74 @@ Subject: port to linux with libsd
if (!lflag && kflag)
errx(1, "must use -l with -k");
if (uflag && usetls)
@@ -449,8 +486,8 @@ main(int argc, char *argv[])
} else {
strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX",
UNIX_DG_TMP_SOCKET_SIZE);
- if (mktemp(unix_dg_tmp_socket_buf) == NULL)
- err(1, "mktemp");
+ if (mkstemp(unix_dg_tmp_socket_buf) == -1)
+ err(1, "mkstemp");
unix_dg_tmp_socket = unix_dg_tmp_socket_buf;
}
}
@@ -933,8 +970,10 @@ remote_connect(const char *host, const c
@@ -579,10 +616,6 @@ main(int argc, char *argv[])
if (s == -1)
err(1, NULL);
if (uflag && kflag) {
- if (family == AF_UNIX) {
- if (pledge("stdio unix", NULL) == -1)
- err(1, "pledge");
- }
/*
* For UDP and -k, don't connect the socket,
* let it receive datagrams from multiple
@@ -609,10 +642,6 @@ main(int argc, char *argv[])
if (rv == -1)
err(1, "connect");
- if (family == AF_UNIX) {
- if (pledge("stdio unix", NULL) == -1)
- err(1, "pledge");
- }
if (vflag)
report_sock("Connection received",
(struct sockaddr *)&z, len,
@@ -938,8 +967,10 @@ remote_connect(const char *host, const char *port, struct addrinfo hints,
if (sflag || pflag) {
struct addrinfo ahints, *ares;
+# if defined (SO_BINDANY)
+#ifdef SO_BINDANY
/* try SO_BINDANY, but don't insist */
setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on));
+# endif
+#endif
memset(&ahints, 0, sizeof(struct addrinfo));
ahints.ai_family = res->ai_family;
ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
@@ -1026,9 +1065,15 @@ local_listen(const char *host, const cha
res->ai_protocol)) < 0)
@@ -1052,9 +1083,15 @@ local_listen(const char *host, const char *port, struct addrinfo hints)
res->ai_protocol)) == -1)
continue;
+ ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
+ if (ret == -1)
+ err(1, NULL);
+
+# if defined(SO_REUSEPORT)
+#ifdef SO_REUSEPORT
ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
if (ret == -1)
err(1, NULL);
+# endif
+#endif
set_common_sockopts(s, res->ai_family);
@@ -1498,11 +1543,13 @@ set_common_sockopts(int s, int af)
@@ -1559,11 +1596,13 @@ set_common_sockopts(int s, int af)
{
int x = 1;
+# if defined(TCP_MD5SIG)
+#ifdef TCP_MD5SIG
if (Sflag) {
if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
&x, sizeof(x)) == -1)
err(1, NULL);
}
+# endif
+#endif
if (Dflag) {
if (setsockopt(s, SOL_SOCKET, SO_DEBUG,
&x, sizeof(x)) == -1)
@@ -1513,9 +1560,14 @@ set_common_sockopts(int s, int af)
@@ -1574,9 +1613,14 @@ set_common_sockopts(int s, int af)
IP_TOS, &Tflag, sizeof(Tflag)) == -1)
err(1, "set IP ToS");
+#if defined(IPV6_TCLASS)
+#ifdef IPV6_TCLASS
else if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6,
IPV6_TCLASS, &Tflag, sizeof(Tflag)) == -1)
err(1, "set IPv6 traffic class");
@@ -271,11 +289,11 @@ Subject: port to linux with libsd
}
if (Iflag) {
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
@@ -1533,19 +1585,34 @@ set_common_sockopts(int s, int af)
@@ -1594,19 +1638,34 @@ set_common_sockopts(int s, int af)
IP_TTL, &ttl, sizeof(ttl)))
err(1, "set IP TTL");
+#if defined(IPV6_UNICAST_HOPS)
+#ifdef IPV6_UNICAST_HOPS
else if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6,
IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)))
err(1, "set IPv6 unicast hops");
@@ -286,7 +304,7 @@ Subject: port to linux with libsd
}
if (minttl != -1) {
+#if defined(IP_MINTTL)
+#ifdef IP_MINTTL
if (af == AF_INET && setsockopt(s, IPPROTO_IP,
IP_MINTTL, &minttl, sizeof(minttl)))
err(1, "set IP min TTL");
@@ -295,7 +313,7 @@ Subject: port to linux with libsd
+ errx(1, "can't set IP min TTL (unavailable)");
+#endif
+#if defined(IPV6_MINHOPCOUNT)
+#ifdef IPV6_MINHOPCOUNT
else if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6,
IPV6_MINHOPCOUNT, &minttl, sizeof(minttl)))
err(1, "set IPv6 min hop count");
@@ -306,7 +324,7 @@ Subject: port to linux with libsd
}
}
@@ -1580,6 +1647,7 @@ process_tos_opt(char *s, int *val)
@@ -1641,6 +1700,7 @@ process_tos_opt(char *s, int *val)
{ "cs7", IPTOS_DSCP_CS7 },
{ "ef", IPTOS_DSCP_EF },
{ "inetcontrol", IPTOS_PREC_INTERNETCONTROL },
@@ -314,17 +332,17 @@ Subject: port to linux with libsd
{ "lowdelay", IPTOS_LOWDELAY },
{ "netcontrol", IPTOS_PREC_NETCONTROL },
{ "reliability", IPTOS_RELIABILITY },
@@ -1741,6 +1809,9 @@ report_sock(const char *msg, const struc
@@ -1805,6 +1865,9 @@ report_sock(const char *msg, const struct sockaddr *sa, socklen_t salen,
void
help(void)
{
+# if defined(DEBIAN_VERSION)
+#ifdef DEBIAN_VERSION
+ fprintf(stderr, "OpenBSD netcat (Debian patchlevel " DEBIAN_VERSION ")\n");
+# endif
+#endif
usage(0);
fprintf(stderr, "\tCommand Summary:\n\
\t-4 Use IPv4\n\
@@ -1783,7 +1854,7 @@ help(void)
@@ -1847,7 +1910,7 @@ help(void)
\t-Z Peer certificate file\n\
\t-z Zero-I/O mode [used for scanning]\n\
Port numbers can be individual or ranges: lo-hi [inclusive]\n");
@@ -333,6 +351,8 @@ Subject: port to linux with libsd
}
void
diff --git a/socks.c b/socks.c
index 7c7448c..8db10d4 100644
--- a/socks.c
+++ b/socks.c
@@ -38,7 +38,7 @@
@@ -344,7 +364,7 @@ Subject: port to linux with libsd
#include "atomicio.h"
#define SOCKS_PORT "1080"
@@ -217,11 +217,11 @@ socks_connect(const char *host, const ch
@@ -217,11 +217,11 @@ socks_connect(const char *host, const char *port,
buf[2] = SOCKS_NOAUTH;
cnt = atomicio(vwrite, proxyfd, buf, 3);
if (cnt != 3)
@@ -358,7 +378,7 @@ Subject: port to linux with libsd
if (buf[1] == SOCKS_NOMETHOD)
errx(1, "authentication method negotiation failed");
@@ -270,11 +270,11 @@ socks_connect(const char *host, const ch
@@ -270,11 +270,11 @@ socks_connect(const char *host, const char *port,
cnt = atomicio(vwrite, proxyfd, buf, wlen);
if (cnt != wlen)
@@ -372,7 +392,7 @@ Subject: port to linux with libsd
if (buf[1] != 0) {
errx(1, "connection failed, SOCKSv5 error: %s",
socks5_strerror(buf[1]));
@@ -283,12 +283,12 @@ socks_connect(const char *host, const ch
@@ -283,12 +283,12 @@ socks_connect(const char *host, const char *port,
case SOCKS_IPV4:
cnt = atomicio(read, proxyfd, buf + 4, 6);
if (cnt != 6)
@@ -387,7 +407,7 @@ Subject: port to linux with libsd
break;
default:
errx(1, "connection failed, unsupported address type");
@@ -308,11 +308,11 @@ socks_connect(const char *host, const ch
@@ -308,11 +308,11 @@ socks_connect(const char *host, const char *port,
cnt = atomicio(vwrite, proxyfd, buf, wlen);
if (cnt != wlen)
@@ -401,7 +421,7 @@ Subject: port to linux with libsd
if (buf[1] != 90) {
errx(1, "connection failed, SOCKSv4 error: %s",
socks4_strerror(buf[1]));
@@ -326,21 +326,21 @@ socks_connect(const char *host, const ch
@@ -326,21 +326,21 @@ socks_connect(const char *host, const char *port,
/* Try to be sane about numeric IPv6 addresses */
if (strchr(host, ':') != NULL) {
@@ -415,7 +435,7 @@ Subject: port to linux with libsd
"CONNECT %s:%d HTTP/1.0\r\n",
host, ntohs(serverport));
}
if (r == -1 || (size_t)r >= sizeof(buf))
if (r < 0 || (size_t)r >= sizeof(buf))
errx(1, "hostname too long");
- r = strlen(buf);
+ r = strlen((char*)buf);
@@ -427,7 +447,7 @@ Subject: port to linux with libsd
if (authretry > 1) {
char proxypass[256];
@@ -348,20 +348,20 @@ socks_connect(const char *host, const ch
@@ -348,20 +348,20 @@ socks_connect(const char *host, const char *port,
getproxypass(proxyuser, proxyhost,
proxypass, sizeof proxypass);
@@ -443,7 +463,7 @@ Subject: port to linux with libsd
- r = snprintf(buf, sizeof(buf), "Proxy-Authorization: "
+ r = snprintf((char*)buf, sizeof(buf), "Proxy-Authorization: "
"Basic %s\r\n", resp);
if (r == -1 || (size_t)r >= sizeof(buf))
if (r < 0 || (size_t)r >= sizeof(buf))
errx(1, "Proxy auth response too long");
- r = strlen(buf);
+ r = strlen((char*)buf);
@@ -453,15 +473,17 @@ Subject: port to linux with libsd
explicit_bzero(proxypass, sizeof proxypass);
explicit_bzero(buf, sizeof buf);
}
@@ -371,22 +371,22 @@ socks_connect(const char *host, const ch
@@ -371,23 +371,23 @@ socks_connect(const char *host, const char *port,
err(1, "write failed (%zu/2)", cnt);
/* Read status reply */
- proxy_read_line(proxyfd, buf, sizeof(buf));
+ proxy_read_line(proxyfd, (char*)buf, sizeof(buf));
if (proxyuser != NULL &&
- strncmp(buf, "HTTP/1.0 407 ", 12) == 0) {
+ strncmp((char*)buf, "HTTP/1.0 407 ", 12) == 0) {
- (strncmp(buf, "HTTP/1.0 407 ", 12) == 0 ||
- strncmp(buf, "HTTP/1.1 407 ", 12) == 0)) {
+ (strncmp((char*)buf, "HTTP/1.0 407 ", 12) == 0 ||
+ strncmp((char*)buf, "HTTP/1.1 407 ", 12) == 0)) {
if (authretry > 1) {
fprintf(stderr, "Proxy authentication "
"failed\n");

View File

@@ -1,12 +1,14 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:16:04 +0800
Subject: quit timer
Subject: New flag '-q' to specify a quit timer
---
nc.1 | 10 ++++++++++
netcat.c | 50 +++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 51 insertions(+), 9 deletions(-)
netcat.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/nc.1 b/nc.1
index 478fedd..fbcc098 100644
--- a/nc.1
+++ b/nc.1
@@ -41,6 +41,7 @@
@@ -14,10 +16,10 @@ Subject: quit timer
.Op Fl P Ar proxy_username
.Op Fl p Ar source_port
+.Op Fl q Ar seconds
.Op Fl s Ar source
.Op Fl s Ar sourceaddr
.Op Fl T Ar keyword
.Op Fl V Ar rtable
@@ -167,6 +168,15 @@ Proxy authentication is only supported f
@@ -167,6 +168,15 @@ Proxy authentication is only supported for HTTP CONNECT proxies at present.
Specify the source port
.Nm
should use, subject to privilege restrictions and availability.
@@ -33,9 +35,11 @@ Subject: quit timer
.It Fl r
Choose source and/or destination ports randomly
instead of sequentially within a range or in the order that the system
diff --git a/netcat.c b/netcat.c
index 2f3e9a8..03d339c 100644
--- a/netcat.c
+++ b/netcat.c
@@ -139,6 +139,7 @@ int Nflag; /* shutdown() network soc
@@ -139,6 +139,7 @@ int Nflag; /* shutdown() network socket */
int nflag; /* Don't do name look up */
char *Pflag; /* Proxy username */
char *pflag; /* Localport flag */
@@ -43,28 +47,27 @@ Subject: quit timer
int rflag; /* Random ports flag */
char *sflag; /* Source Address */
int tflag; /* Telnet Emulation */
@@ -224,6 +225,8 @@ ssize_t fillbuf(int, unsigned char *, si
static int connect_with_timeout(int fd, const struct sockaddr *sa,
socklen_t salen, int ctimeout);
@@ -223,6 +224,7 @@ ssize_t fillbuf(int, unsigned char *, size_t *);
#endif
static int connect_with_timeout(int, const struct sockaddr *, socklen_t, int);
+static void quit(int sig);
+static void quit();
+
int
main(int argc, char *argv[])
{
@@ -256,9 +259,9 @@ main(int argc, char *argv[])
@@ -255,9 +257,9 @@ main(int argc, char *argv[])
while ((ch = getopt(argc, argv,
# if defined(TLS)
#ifdef HAVE_TLS
- "46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
+ "46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:q:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
# else
#else
- "46CDdFhI:i:klM:m:NnO:P:p:rSs:T:tUuV:vW:w:X:x:z"))
+ "46CDdFhI:i:klM:m:NnO:P:p:q:rSs:T:tUuV:vW:w:X:x:z"))
# endif
#endif
!= -1) {
switch (ch) {
@@ -350,6 +353,13 @@ main(int argc, char *argv[])
@@ -349,6 +351,13 @@ main(int argc, char *argv[])
case 'p':
pflag = optarg;
break;
@@ -75,10 +78,10 @@ Subject: quit timer
+ if (qflag >= 0)
+ Nflag = 1;
+ break;
# if defined(TLS)
#ifdef HAVE_TLS
case 'R':
tls_cachanged = 1;
@@ -1319,15 +1329,27 @@ readwrite(int net_fd)
@@ -1335,15 +1344,27 @@ readwrite(int net_fd)
while (1) {
/* both inputs are gone, buffers are empty, we are done */
if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1 &&
@@ -112,22 +115,37 @@ Subject: quit timer
/* poll */
num_fds = poll(pfd, 4, timeout);
@@ -2052,6 +2074,7 @@ help(void)
@@ -1500,6 +1521,13 @@ readwrite(int net_fd)
if (pfd[POLL_NETOUT].fd != -1 && Nflag)
shutdown(pfd[POLL_NETOUT].fd, SHUT_WR);
pfd[POLL_NETOUT].fd = -1;
+ /* #817050: handle UDP sockets and kflag */
+ if ((lflag || uflag) && pfd[POLL_NETIN].fd != -1 &&
+ qflag >= 0 && netinbufpos == 0) {
+ shutdown(pfd[POLL_NETIN].fd, SHUT_RD);
+ pfd[POLL_NETIN].fd = -1;
+ kflag = 0;
+ }
}
/* net in gone and queue empty? */
if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) {
@@ -2106,6 +2134,7 @@ help(void)
\t-O length TCP send buffer length\n\
\t-P proxyuser\tUsername for proxy authentication\n\
\t-p port\t Specify local port for remote connects\n\
+ \t-q secs\t quit after EOF on stdin and delay of secs\n\
\t-r Randomize remote ports\n\
\t-S Enable the TCP MD5 signature option\n\
\t-s source Local source address\n\
@@ -2076,10 +2099,19 @@ usage(int ret)
\t-s sourceaddr Local source address\n\
@@ -2130,10 +2159,18 @@ usage(int ret)
fprintf(stderr,
"usage: nc [-46CDdFhklNnrStUuvz] [-I length] [-i interval] [-M ttl]\n"
"\t [-m minttl] [-O length] [-P proxy_username] [-p source_port]\n"
- "\t [-s source] [-T keyword] [-V rtable] [-W recvlimit] "
+ "\t [-q seconds] [-s source] [-T keyword] [-V rtable] [-W recvlimit] "
"[-w timeout]\n"
"\t [-X proxy_protocol] [-x proxy_address[:port]] "
- "\t [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit] "
- "[-w timeout]\n"
- "\t [-X proxy_protocol] [-x proxy_address[:port]]\n"
+ "\t [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit]\n"
+ "\t [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]]\n"
"\t [destination] [port]\n");
if (ret)
exit(1);
@@ -137,7 +155,7 @@ Subject: quit timer
+ * quit()
+ * handler for a "-q" timeout (exit 0 instead of 1)
+ */
+static void quit()
+static void quit(__attribute__((unused)) int sig)
+{
+ exit(0);
+}

View File

@@ -1,12 +1,14 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 14:57:45 +0800
Subject: send crlf
Subject: New flag '-C' to translate terminal line feeds to CRLF
---
nc.1 | 9 +++++--
netcat.c | 74 ++++++++++++++++++++++++++++++++++-----------------------------
2 files changed, 48 insertions(+), 35 deletions(-)
nc.1 | 9 ++++++--
netcat.c | 72 +++++++++++++++++++++++++++++++++++-----------------------------
2 files changed, 47 insertions(+), 34 deletions(-)
diff --git a/nc.1 b/nc.1
index 2eb732e..478fedd 100644
--- a/nc.1
+++ b/nc.1
@@ -33,7 +33,7 @@
@@ -30,56 +32,58 @@ Subject: send crlf
.It Fl D
Enable debugging on the socket.
.It Fl d
@@ -377,7 +382,7 @@ More complicated examples can be built u
@@ -380,7 +385,7 @@ More complicated examples can be built up when the user knows the format
of requests required by the server.
As another example, an email may be submitted to an SMTP server using:
.Bd -literal -offset indent
-$ nc localhost 25 \*(Lt\*(Lt EOF
+$ nc [\-C] localhost 25 \*(Lt\*(Lt EOF
-$ nc localhost 25 << EOF
+$ nc [\-C] localhost 25 << EOF
HELO host.example.com
MAIL FROM:\*(Ltuser@host.example.com\*(Gt
RCPT TO:\*(Ltuser2@host.example.com\*(Gt
MAIL FROM:<user@host.example.com>
RCPT TO:<user2@host.example.com>
diff --git a/netcat.c b/netcat.c
index 2dc1abd..2f3e9a8 100644
--- a/netcat.c
+++ b/netcat.c
@@ -166,6 +166,8 @@ char *tls_expecthash; /* required hash
@@ -166,6 +166,8 @@ char *tls_expecthash; /* required hash of peer cert */
char *tls_ciphers; /* TLS ciphers */
char *tls_protocols; /* TLS protocols */
FILE *Zflag; /* file to save peer cert */
+# else
+#else
+int Cflag = 0; /* CRLF line-ending */
# endif
#endif
int recvcount, recvlimit;
@@ -215,7 +217,7 @@ ssize_t fillbuf(int, unsigned char *, si
@@ -216,7 +218,7 @@ ssize_t fillbuf(int, unsigned char *, size_t *, struct tls *);
void tls_setup_client(struct tls *, int, char *);
struct tls *tls_setup_server(struct tls *, int, char *);
# else
#else
-ssize_t drainbuf(int, unsigned char *, size_t *);
+ssize_t drainbuf(int, unsigned char *, size_t *, int);
ssize_t fillbuf(int, unsigned char *, size_t *);
# endif
#endif
@@ -256,7 +258,7 @@ main(int argc, char *argv[])
# if defined(TLS)
@@ -255,7 +257,7 @@ main(int argc, char *argv[])
#ifdef HAVE_TLS
"46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
# else
#else
- "46DdFhI:i:klM:m:NnO:P:p:rSs:T:tUuV:vW:w:X:x:z"))
+ "46CDdFhI:i:klM:m:NnO:P:p:rSs:T:tUuV:vW:w:X:x:z"))
# endif
#endif
!= -1) {
switch (ch) {
@@ -286,6 +288,10 @@ main(int argc, char *argv[])
@@ -285,6 +287,10 @@ main(int argc, char *argv[])
case 'c':
usetls = 1;
break;
+# else
+#else
+ case 'C':
+ Cflag = 1;
+ break;
# endif
#endif
case 'd':
dflag = 1;
@@ -1323,12 +1329,6 @@ readwrite(int net_fd)
@@ -1339,12 +1345,6 @@ readwrite(int net_fd)
stdinbufpos == 0 && netinbufpos == 0)
return;
@@ -92,33 +96,33 @@ Subject: send crlf
/* poll */
num_fds = poll(pfd, 4, timeout);
@@ -1408,7 +1408,7 @@ readwrite(int net_fd)
@@ -1424,7 +1424,7 @@ readwrite(int net_fd)
pfd[POLL_NETOUT].events = POLLOUT;
else
# else
#else
- &stdinbufpos);
+ &stdinbufpos, (iflag || Cflag) ? 1 : 0);
# endif
#endif
if (ret == -1)
pfd[POLL_NETOUT].fd = -1;
@@ -1467,7 +1467,7 @@ readwrite(int net_fd)
@@ -1483,7 +1483,7 @@ readwrite(int net_fd)
pfd[POLL_STDOUT].events = POLLOUT;
else
# else
#else
- &netinbufpos);
+ &netinbufpos, 0);
# endif
#endif
if (ret == -1)
pfd[POLL_STDOUT].fd = -1;
@@ -1493,33 +1493,40 @@ readwrite(int net_fd)
@@ -1509,36 +1509,43 @@ readwrite(int net_fd)
}
ssize_t
-# if defined(TLS)
-#ifdef HAVE_TLS
-drainbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
-# else
-#else
-drainbuf(int fd, unsigned char *buf, size_t *bufpos)
-# endif
-#endif
+drainbuf(int fd, unsigned char *buf, size_t *bufpos, int oneline)
{
- ssize_t n;
@@ -126,28 +130,30 @@ Subject: send crlf
ssize_t adjust;
+ unsigned char *lf = NULL;
-# if defined(TLS)
if (fd == -1)
return -1;
-#ifdef HAVE_TLS
- if (tls) {
- n = tls_write(tls, buf, *bufpos);
- if (n == -1)
- errx(1, "tls write failed (%s)", tls_error(tls));
- } else {
-# endif
-#endif
- n = write(fd, buf, *bufpos);
- /* don't treat EAGAIN, EINTR as error */
- if (n == -1 && (errno == EAGAIN || errno == EINTR))
-# if defined(TLS)
-#ifdef HAVE_TLS
- n = TLS_WANT_POLLOUT;
- }
-# else
- n = -2;
-# endif
+ if (oneline)
+ lf = memchr(buf, '\n', *bufpos);
+ if (lf == NULL) {
+ n = *bufpos;
+ oneline = 0;
+ }
}
-#else
- n = -2;
-#endif
+ else if (Cflag && (lf == buf || buf[lf - buf - 1] != '\r')) {
+ n = lf - buf;
+ oneline = 2;
@@ -173,7 +179,7 @@ Subject: send crlf
/* adjust buffer */
adjust = *bufpos - n;
if (adjust > 0)
@@ -2029,6 +2036,7 @@ help(void)
@@ -2083,6 +2090,7 @@ help(void)
fprintf(stderr, "\tCommand Summary:\n\
\t-4 Use IPv4\n\
\t-6 Use IPv6\n\
@@ -181,12 +187,12 @@ Subject: send crlf
\t-D Enable the debug socket option\n\
\t-d Detach from stdin\n\
\t-F Pass socket fd\n\
@@ -2066,7 +2074,7 @@ void
@@ -2120,7 +2128,7 @@ void
usage(int ret)
{
fprintf(stderr,
- "usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-M ttl]\n"
+ "usage: nc [-46CDdFhklNnrStUuvz] [-I length] [-i interval] [-M ttl]\n"
"\t [-m minttl] [-O length] [-P proxy_username] [-p source_port]\n"
"\t [-s source] [-T keyword] [-V rtable] [-W recvlimit] "
"\t [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit] "
"[-w timeout]\n"

View File

@@ -1,14 +1,16 @@
From: Aron Xu <aron@debian.org>
Date: Tue, 14 Feb 2012 23:02:00 +0800
Subject: serialized handling multiple clients
Subject: Serialized handling of multiple clients
---
netcat.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/netcat.c b/netcat.c
index 99747a2..8291173 100644
--- a/netcat.c
+++ b/netcat.c
@@ -707,7 +707,10 @@ main(int argc, char *argv[])
@@ -713,7 +713,10 @@ main(int argc, char *argv[])
s = unix_bind(host, 0);
else
s = unix_listen(host);
@@ -18,10 +20,10 @@ Subject: serialized handling multiple clients
+ if (s < 0)
+ err(1, NULL);
# if defined(TLS)
#ifdef HAVE_TLS
if (usetls) {
@@ -721,13 +724,6 @@ main(int argc, char *argv[])
# endif
@@ -727,13 +730,6 @@ main(int argc, char *argv[])
#endif
/* Allow only one connection at a time, but stay alive. */
for (;;) {
- if (family != AF_UNIX) {
@@ -29,13 +31,13 @@ Subject: serialized handling multiple clients
- close(s);
- s = local_listen(host, uport, hints);
- }
- if (s < 0)
- if (s == -1)
- err(1, NULL);
if (uflag && kflag) {
/*
* For UDP and -k, don't connect the socket,
@@ -804,8 +800,11 @@ main(int argc, char *argv[])
err(1, "connect");
@@ -807,8 +803,11 @@ main(int argc, char *argv[])
#endif
}
- if (!kflag)

View File

@@ -1,73 +1,75 @@
From: Thomas Habets <habets@google.com>
Date: Sat, 18 Feb 2017 21:07:22 +0000
Subject: Set TCP MD5SIG correctly for client connections
Subject: Fix TCP MD5SIG for client connections
---
netcat.c | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
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) && defined(TCP_MD5SIG_MAXKEYLEN)
+#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 ce
@@ -175,6 +178,9 @@ FILE *Zflag; /* file to save peer cert */
int Cflag = 0; /* CRLF line-ending */
# endif
#endif
+# if defined(TCP_MD5SIG) && defined(TCP_MD5SIG_MAXKEYLEN)
+#if defined(TCP_MD5SIG_EXT) && defined(TCP_MD5SIG_MAXKEYLEN)
+char Sflag_password[TCP_MD5SIG_MAXKEYLEN];
+# endif
+#endif
int recvcount, recvlimit;
int timeout = -1;
int family = AF_UNSPEC;
@@ -205,7 +211,7 @@ int udptest(int);
@@ -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 *);
# if defined(TLS)
#ifdef HAVE_TLS
int process_tls_opt(char *, int *);
@@ -458,7 +464,10 @@ main(int argc, char *argv[])
@@ -456,7 +462,10 @@ main(int argc, char *argv[])
break;
# endif
#endif
case 'S':
-# if defined(TCP_MD5SIG)
+# if defined(TCP_MD5SIG) && defined(TCP_MD5SIG_MAXKEYLEN)
-#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
#else
errx(1, "no TCP MD5 signature support available");
@@ -1169,7 +1178,7 @@ remote_connect(const char *host, const c
@@ -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);
char *proto = proto_name(uflag, dccpflag);
if ((error = connect_with_timeout(s, res->ai_addr, res->ai_addrlen, timeout)) == CONNECTION_SUCCESS)
@@ -1323,7 +1332,7 @@ local_listen(const char *host, const cha
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
#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)
@@ -1855,9 +1864,10 @@ udptest(int s)
@@ -1910,9 +1919,10 @@ connection_info(const char *host, const char *port, const char *proto,
}
void
@@ -77,25 +79,27 @@ Subject: Set TCP MD5SIG correctly for client connections
int x = 1;
+ int af = sa->sa_family;
# if defined(SO_BROADCAST)
#ifdef SO_BROADCAST
if (bflag) {
@@ -1868,10 +1878,17 @@ set_common_sockopts(int s, int af)
@@ -1923,10 +1933,18 @@ set_common_sockopts(int s, int af)
err(1, NULL);
}
# endif
-# if defined(TCP_MD5SIG)
+# if defined(TCP_MD5SIG) && defined(TCP_MD5SIG_MAXKEYLEN)
#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);
+ strlcpy(sig.tcpm_key, Sflag_password, sig.tcpm_keylen);
if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
- &x, sizeof(x)) == -1)
+ 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
#endif

View File

@@ -1,11 +1,13 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:29:37 +0800
Subject: udp scan timeout
Subject: Fix UDP scan timeout
---
netcat.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
netcat.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/netcat.c b/netcat.c
index 03d339c..dd893ac 100644
--- a/netcat.c
+++ b/netcat.c
@@ -129,6 +129,8 @@
@@ -17,22 +19,17 @@ Subject: udp scan timeout
/* Command Line Options */
int dflag; /* detached, no stdin */
int Fflag; /* fdpass sock to stdout */
@@ -822,7 +824,7 @@ main(int argc, char *argv[])
continue;
ret = 0;
- if (vflag || zflag) {
+ if (vflag) {
/* For UDP, make sure we are connected. */
if (uflag) {
if (udptest(s) == -1) {
@@ -1767,15 +1769,20 @@ build_ports(char *p)
@@ -1794,19 +1796,24 @@ build_ports(char *p)
int
udptest(int s)
{
- int i, ret;
+ int i, t;
/* Only write to the socket in scan mode or interactive mode. */
if (!zflag && !isatty(STDIN_FILENO))
return 0;
- for (i = 0; i <= 3; i++) {
- if (write(s, "X", 1) == 1)
- ret = 1;

View File

@@ -1,12 +1,14 @@
From: Guilhem Moulin <guilhem@debian.org>
Date: Mon, 22 Oct 2018 04:50:54 +0200
Subject: use -s/-p flags to specify listen address
Subject: Add ability to use -s/-p flags to specify listening address
---
nc.1 | 18 ++++++++++++++----
netcat.c | 49 +++++++++++++++++++++++++++++--------------------
2 files changed, 43 insertions(+), 24 deletions(-)
netcat.c | 47 +++++++++++++++++++++++++++++++----------------
2 files changed, 45 insertions(+), 20 deletions(-)
diff --git a/nc.1 b/nc.1
index 80c654c..d30389a 100644
--- a/nc.1
+++ b/nc.1
@@ -143,8 +143,20 @@ multiple hosts.
@@ -32,7 +34,7 @@ Subject: use -s/-p flags to specify listen address
Additionally, any timeouts specified with the
.Fl w
option are ignored.
@@ -194,8 +206,6 @@ For
@@ -193,8 +205,6 @@ For
datagram sockets, specifies the local temporary socket file
to create and use so that datagrams can be received.
Cannot be used together with
@@ -41,36 +43,36 @@ Subject: use -s/-p flags to specify listen address
.Fl x .
.It Fl T Ar keyword
Change the IPv4 TOS/IPv6 traffic class value.
diff --git a/netcat.c b/netcat.c
index bef27a4..0caba28 100644
--- a/netcat.c
+++ b/netcat.c
@@ -509,31 +509,40 @@ main(int argc, char *argv[])
# endif
@@ -507,27 +507,42 @@ main(int argc, char *argv[])
#endif
/* Cruft to make sure options are clean, and used properly. */
- if (argv[0] && !argv[1] && family == AF_UNIX) {
-# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
- if (argc == 1 && family == AF_UNIX) {
-#if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
- if (dccpflag)
- errx(1, "cannot use -Z and -U");
-# endif
-#endif
- host = argv[0];
- uport = NULL;
- } else if (!argv[0] && lflag) {
- } else if (argc == 0 && lflag) {
- if (sflag)
- errx(1, "cannot use -s and -l");
- if (pflag)
- errx(1, "cannot use -p and -l");
- if (zflag)
- errx(1, "cannot use -z and -l");
- } else if (argv[0] && !argv[1]) {
- if (!lflag)
- usage(1);
- } else if (argc == 1 && lflag) {
- uport = &argv[0];
- host = NULL;
- } else if (argv[0] && argv[1]) {
- } else if (argc == 2) {
+ if (argc == 0 && lflag) {
+ uport = &pflag;
+ host = sflag;
+ } else if (argc == 1 && !pflag && !sflag) {
+ } else if (argc == 1 && !pflag &&
+ /* `nc -l 12345` or `nc -U bar` or `nc -uU -s foo bar` */
+ (!sflag || (family == AF_UNIX && uflag && !lflag))) {
+ if (family == AF_UNIX) {
+ host = argv[0];
+ uport = NULL;
@@ -87,10 +89,10 @@ Subject: use -s/-p flags to specify listen address
usage(1);
+ if (family == AF_UNIX) {
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+#if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ if (dccpflag)
+ errx(1, "cannot use -Z and -U");
+# endif
+#endif
+ if (uport && *uport)
+ errx(1, "cannot use port with -U");
+ if (!host)
@@ -101,6 +103,6 @@ Subject: use -s/-p flags to specify listen address
+ if (lflag && zflag)
+ errx(1, "cannot use -z and -l");
+
# if defined(TLS)
#ifdef HAVE_TLS
if (usetls) {
if (Cflag && unveil(Cflag, "r") == -1)