Sync from SUSE:SLFO:Main netcat-openbsd revision b8bab34c32ac35e9a811ac8d63952a8e

This commit is contained in:
Adrian Schröter 2024-05-03 16:58:42 +02:00
commit 3b439fccdc
20 changed files with 3158 additions and 0 deletions

23
.gitattributes vendored Normal file
View File

@ -0,0 +1,23 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text

89
broadcast-support.patch Normal file
View File

@ -0,0 +1,89 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 19:06:52 +0800
Subject: broadcast support
---
nc.1 | 4 +++-
netcat.c | 22 ++++++++++++++++++++--
2 files changed, 23 insertions(+), 3 deletions(-)
--- a/nc.1
+++ b/nc.1
@@ -33,7 +33,7 @@
.Nd arbitrary TCP and UDP connections and listens
.Sh SYNOPSIS
.Nm nc
-.Op Fl 46CDdFhklNnrStUuvZz
+.Op Fl 46bCDdFhklNnrStUuvZz
.Op Fl I Ar length
.Op Fl i Ar interval
.Op Fl M Ar ttl
@@ -93,6 +93,8 @@ The options are as follows:
Use IPv4 addresses only.
.It Fl 6
Use IPv6 addresses only.
+.It Fl b
+Allow broadcast.
.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
--- a/netcat.c
+++ b/netcat.c
@@ -132,6 +132,7 @@
#define UDP_SCAN_TIMEOUT 3 /* Seconds */
/* Command Line Options */
+int bflag; /* Allow Broadcast */
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[])
while ((ch = getopt(argc, argv,
# if defined(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
- "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
!= -1) {
switch (ch) {
@@ -275,6 +276,13 @@ main(int argc, char *argv[])
case '6':
family = AF_INET6;
break;
+ case 'b':
+# if defined(SO_BROADCAST)
+ bflag = 1;
+# else
+ errx(1, "no broadcast frame support available");
+# endif
+ break;
case 'U':
family = AF_UNIX;
break;
@@ -1852,6 +1860,15 @@ set_common_sockopts(int s, int af)
{
int x = 1;
+# if defined(SO_BROADCAST)
+ if (bflag) {
+ /* allow datagram sockets to send packets to a broadcast address
+ * (this option has no effect on stream-oriented sockets) */
+ if (setsockopt(s, SOL_SOCKET, SO_BROADCAST,
+ &x, sizeof(x)) == -1)
+ err(1, NULL);
+ }
+# endif
# if defined(TCP_MD5SIG)
if (Sflag) {
if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
@@ -2127,6 +2144,7 @@ help(void)
fprintf(stderr, "\tCommand Summary:\n\
\t-4 Use IPv4\n\
\t-6 Use IPv6\n\
+ \t-b Allow broadcast\n\
\t-C Send CRLF as line-ending\n\
\t-D Enable the debug socket option\n\
\t-d Detach from stdin\n\

View File

@ -0,0 +1,872 @@
From: Guilhem Moulin <guilhem@debian.org>
Date: Fri, 09 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)
that are already used by our Debian-specific patches.
---
Makefile | 2
nc.1 | 114 ++---------------------------------------
netcat.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 153 insertions(+), 135 deletions(-)
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,6 @@
PROG= nc
SRCS= netcat.c atomicio.c socks.c
-LDADD+= -ltls -lssl -lcrypto
-DPADD+= ${LIBTLS} ${LIBSSL} ${LIBCRYPTO}
LIBS= `pkg-config --libs libbsd` -lresolv
OBJS= $(SRCS:.c=.o)
--- a/nc.1
+++ b/nc.1
@@ -33,20 +33,14 @@
.Nd arbitrary TCP and UDP connections and listens
.Sh SYNOPSIS
.Nm nc
-.Op Fl 46cDdFhklNnrStUuvz
-.Op Fl C Ar certfile
-.Op Fl e Ar name
-.Op Fl H Ar hash
+.Op Fl 46DdFhklNnrStUuvz
.Op Fl I Ar length
.Op Fl i Ar interval
-.Op Fl K Ar keyfile
.Op Fl M Ar ttl
.Op Fl m Ar minttl
.Op Fl O Ar length
-.Op Fl o Ar staplefile
.Op Fl P Ar proxy_username
.Op Fl p Ar source_port
-.Op Fl R Ar CAfile
.Op Fl s Ar source
.Op Fl T Ar keyword
.Op Fl V Ar rtable
@@ -54,7 +48,6 @@
.Op Fl w Ar timeout
.Op Fl X Ar proxy_protocol
.Op Fl x Ar proxy_address Ns Op : Ns Ar port
-.Op Fl Z Ar peercertfile
.Op Ar destination
.Op Ar port
.Sh DESCRIPTION
@@ -99,28 +92,10 @@ The options are as follows:
Use IPv4 addresses only.
.It Fl 6
Use IPv6 addresses only.
-.It Fl C Ar certfile
-Load the public key part of the TLS peer certificate from
-.Ar certfile ,
-in PEM format.
-Requires
-.Fl c .
-.It Fl c
-Use TLS to connect or listen.
-Cannot be used together with any of the options
-.Fl FuU .
.It Fl D
Enable debugging on the socket.
.It Fl d
Do not attempt to read from stdin.
-.It Fl e Ar name
-Only accept the TLS peer certificate if it contains the
-.Ar name .
-Requires
-.Fl c .
-If not specified,
-.Ar destination
-is used.
.It Fl F
Pass the first connected socket using
.Xr sendmsg 2
@@ -137,18 +112,7 @@ using the
.Cm ProxyUseFdpass
option).
Cannot be used with
-.Fl c
-or
.Fl U .
-.It Fl H Ar hash
-Only accept the TLS peer certificate if its hash returned from
-.Xr tls_peer_cert_hash 3
-matches
-.Ar hash .
-Requires
-.Fl c
-and cannot be used with
-.Fl T Cm noverify .
.It Fl h
Print out the
.Nm
@@ -160,12 +124,6 @@ Sleep for
.Ar interval
seconds between lines of text sent and received.
Also causes a delay time between connections to multiple ports.
-.It Fl K Ar keyfile
-Load the TLS private key from
-.Ar keyfile ,
-in PEM format.
-Requires
-.Fl c .
.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.
.It Fl O Ar length
Specify the size of the TCP send buffer.
-.It Fl o Ar staplefile
-During the TLS handshake, load data to be stapled from
-.Ar staplefile ,
-which is expected to contain an OCSP response from an OCSP server in
-DER format.
-Requires
-.Fl c
-and
-.Fl C .
.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
Specify the source port
.Nm
should use, subject to privilege restrictions and availability.
-.It Fl R Ar CAfile
-Load the root CA bundle for TLS certificate verification from
-.Ar CAfile ,
-in PEM format, instead of
-.Pa /etc/ssl/cert.pem .
-Requires
-.Fl c .
.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
or
.Fl x .
.It Fl T Ar keyword
-Change the IPv4 TOS/IPv6 traffic class value or the TLS options.
-.Pp
-For TLS options,
-.Ar keyword
-may be one of:
-.Cm noverify ,
-which disables certificate verification;
-.Cm noname ,
-which disables certificate name checking;
-.Cm clientcert ,
-which requires a client certificate on incoming connections; or
-.Cm muststaple ,
-which requires the peer to provide a valid stapled OCSP response
-with the handshake.
-The following TLS options specify a value in the form of a
-.Ar key Ns = Ns Ar value
-pair:
-.Cm ciphers ,
-which allows the supported TLS ciphers to be specified (see
-.Xr tls_config_set_ciphers 3
-for further details);
-.Cm protocols ,
-which allows the supported TLS protocols to be specified (see
-.Xr tls_config_parse_protocols 3
-for further details).
-Specifying TLS options requires
-.Fl c .
-.Pp
-For the IPv4 TOS/IPv6 traffic class value,
+Change the IPv4 TOS/IPv6 traffic class value.
.Ar keyword
may be one of
.Cm critical ,
@@ -291,13 +205,13 @@ to script telnet sessions.
Use
.Ux Ns -domain
sockets.
-Cannot be used together with any of the options
-.Fl cFx .
+Cannot be used together with
+.Fl F
+or
+.Fl x .
.It Fl u
Use UDP instead of TCP.
Cannot be used together with
-.Fl c
-or
.Fl x .
For
.Ux Ns -domain
@@ -360,12 +274,6 @@ An IPv6 address can be specified unambig
in square brackets.
A proxy cannot be used with any of the options
.Fl lsuU .
-.It Fl Z Ar peercertfile
-Save the peer certificates to
-.Ar peercertfile ,
-in PEM format.
-Requires
-.Fl c .
.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
.Pp
.Dl $ nc -p 31337 -w 5 host.example.com 42
.Pp
-Open a TCP connection to port 443 of www.example.com, and negotiate TLS with
-any supported TLS protocol version and "compat" ciphers:
-.Pp
-.Dl $ nc -cv -T protocols=all -T ciphers=compat www.example.com 443
-.Pp
-Open a TCP connection to port 443 of www.google.ca, and negotiate TLS.
-Check for a different name in the certificate for validation:
-.Pp
-.Dl $ nc -cv -e adsf.au.doubleclick.net www.google.ca 443
-.Pp
Open a UDP connection to port 53 of host.example.com:
.Pp
.Dl $ nc -u host.example.com 53
--- a/netcat.c
+++ b/netcat.c
@@ -99,7 +99,9 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include <tls.h>
+#ifdef TLS
+# include <tls.h>
+#endif
#include <unistd.h>
#include <bsd/stdlib.h>
#include <bsd/string.h>
@@ -115,10 +117,12 @@
#define POLL_STDOUT 3
#define BUFSIZE 16384
-#define TLS_NOVERIFY (1 << 1)
-#define TLS_NONAME (1 << 2)
-#define TLS_CCERT (1 << 3)
-#define TLS_MUSTSTAPLE (1 << 4)
+#ifdef TLS
+# define TLS_NOVERIFY (1 << 1)
+# define TLS_NONAME (1 << 2)
+# define TLS_CCERT (1 << 3)
+# define TLS_MUSTSTAPLE (1 << 4)
+#endif
/* Command Line Options */
int dflag; /* detached, no stdin */
@@ -144,6 +148,7 @@ int Sflag; /* TCP MD5 signature opti
int Tflag = -1; /* IP Type of Service */
int rtableid = -1;
+# if defined(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
char *tls_ciphers; /* TLS ciphers */
char *tls_protocols; /* TLS protocols */
FILE *Zflag; /* file to save peer cert */
+# endif
int recvcount, recvlimit;
int timeout = -1;
@@ -170,10 +176,16 @@ int strtoport(char *portstr, int udp);
void build_ports(char *);
void help(void) __attribute__((noreturn));
int local_listen(const char *, const char *, struct addrinfo);
+# if defined(TLS)
void readwrite(int, struct tls *);
+# else
+void readwrite(int);
+# endif
void fdpass(int nfd) __attribute__((noreturn));
int remote_connect(const char *, const char *, struct addrinfo);
+# if defined(TLS)
int timeout_tls(int, struct tls *, int (*)(struct tls *));
+# 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 *);
int unix_listen(char *);
void set_common_sockopts(int, int);
int process_tos_opt(char *, int *);
+# if defined(TLS)
int process_tls_opt(char *, int *);
void save_peer_cert(struct tls *_tls_ctx, FILE *_fp);
+# endif
void report_sock(const char *, const struct sockaddr *, socklen_t, char *);
+# if defined(TLS)
void report_tls(struct tls *tls_ctx, char * host);
+# endif
void usage(int);
+# if defined(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
+ssize_t drainbuf(int, unsigned char *, size_t *);
+ssize_t fillbuf(int, unsigned char *, size_t *);
+# endif
int
main(int argc, char *argv[])
@@ -206,8 +227,10 @@ 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)
struct tls_config *tls_cfg = NULL;
struct tls *tls_ctx = NULL;
+# endif
uint32_t protocols;
ret = 1;
@@ -215,12 +238,18 @@ main(int argc, char *argv[])
host = NULL;
uport = NULL;
sv = NULL;
+# if defined(TLS)
Rflag = tls_default_ca_cert_file();
+# endif
signal(SIGPIPE, SIG_IGN);
while ((ch = getopt(argc, argv,
+# if defined(TLS)
"46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
+# else
+ "46DdFhI:i:klM:m:NnO:P:p:rSs:T:tUuV:vW:w:X:x:z"))
+# endif
!= -1) {
switch (ch) {
case '4':
@@ -242,24 +271,30 @@ main(int argc, char *argv[])
else
errx(1, "unsupported proxy protocol");
break;
+# if defined(TLS)
case 'C':
Cflag = optarg;
break;
case 'c':
usetls = 1;
break;
+# endif
case 'd':
dflag = 1;
break;
+# if defined(TLS)
case 'e':
tls_expectname = optarg;
break;
+# endif
case 'F':
Fflag = 1;
break;
+# if defined(TLS)
case 'H':
tls_expecthash = optarg;
break;
+# endif
case 'h':
help();
break;
@@ -268,9 +303,11 @@ main(int argc, char *argv[])
if (errstr)
errx(1, "interval %s: %s", errstr, optarg);
break;
+# if defined(TLS)
case 'K':
Kflag = optarg;
break;
+# endif
case 'k':
kflag = 1;
break;
@@ -299,10 +336,12 @@ main(int argc, char *argv[])
case 'p':
pflag = optarg;
break;
+# if defined(TLS)
case 'R':
tls_cachanged = 1;
Rflag = optarg;
break;
+# endif
case 'r':
rflag = 1;
break;
@@ -344,12 +383,14 @@ main(int argc, char *argv[])
if ((proxy = strdup(optarg)) == NULL)
err(1, NULL);
break;
+# if defined(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
case 'z':
zflag = 1;
break;
@@ -368,9 +409,11 @@ main(int argc, char *argv[])
errx(1, "TCP send window %s: %s",
errstr, optarg);
break;
+# if defined(TLS)
case 'o':
oflag = optarg;
break;
+# endif
case 'S':
# if defined(TCP_MD5SIG)
Sflag = 1;
@@ -381,8 +424,10 @@ main(int argc, char *argv[])
case 'T':
errstr = NULL;
errno = 0;
+# if defined(TLS)
if (process_tls_opt(optarg, &TLSopt))
break;
+# endif
if (process_tos_opt(optarg, &Tflag))
break;
if (strlen(optarg) > 1 && optarg[0] == '0' &&
@@ -392,7 +437,11 @@ main(int argc, char *argv[])
Tflag = (int)strtonum(optarg, 0, 255,
&errstr);
if (Tflag < 0 || Tflag > 255 || errstr || errno)
+# if defined(TLS)
errx(1, "illegal tos/tls value %s", optarg);
+# else
+ errx(1, "illegal tos value %s", optarg);
+# endif
break;
default:
usage(1);
@@ -429,6 +478,7 @@ main(int argc, char *argv[])
} else
usage(1);
+# if defined(TLS)
if (usetls) {
if (Cflag && unveil(Cflag, "r") == -1)
err(1, "unveil");
@@ -451,15 +501,19 @@ main(int argc, char *argv[])
err(1, "unveil");
}
}
+# endif
if (!lflag && kflag)
errx(1, "must use -l with -k");
+# if defined(TLS)
if (uflag && usetls)
errx(1, "cannot use -c and -u");
if ((family == AF_UNIX) && usetls)
errx(1, "cannot use -c and -U");
+# endif
if ((family == AF_UNIX) && Fflag)
errx(1, "cannot use -F and -U");
+# if defined(TLS)
if (Fflag && usetls)
errx(1, "cannot use -c and -F");
if (TLSopt && !usetls)
@@ -478,6 +532,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
/* Get name of temporary socket for unix datagram client */
if ((family == AF_UNIX) && uflag && !lflag) {
@@ -544,6 +599,7 @@ main(int argc, char *argv[])
proxyhints.ai_flags |= AI_NUMERICHOST;
}
+# if defined(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");
} else if (pledge("stdio inet dns", NULL) == -1)
err(1, "pledge");
- }
+ }
+# endif
if (lflag) {
ret = 0;
@@ -590,6 +647,7 @@ main(int argc, char *argv[])
s = unix_listen(host);
}
+# if defined(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[])
errx(1, "tls configuration failed (%s)",
tls_error(tls_ctx));
}
+# 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[])
* let it receive datagrams from multiple
* socket pairs.
*/
+# if defined(TLS)
readwrite(s, NULL);
+# else
+ readwrite(s);
+# 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);
+# if defined(TLS)
readwrite(s, NULL);
} else {
struct tls *tls_cctx = NULL;
+# else
+ readwrite(s);
+ } else {
+# endif
int connfd;
len = sizeof(cliaddr);
@@ -654,6 +722,7 @@ main(int argc, char *argv[])
report_sock("Connection received",
(struct sockaddr *)&cliaddr, len,
family == AF_UNIX ? host : NULL);
+# if defined(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[])
timeout_tls(s, tls_cctx, tls_close);
close(connfd);
tls_free(tls_cctx);
+# else
+ readwrite(connfd);
+ close(connfd);
+# endif
}
if (family == AF_UNIX && uflag) {
if (connect(s, NULL, 0) < 0)
@@ -677,7 +750,11 @@ main(int argc, char *argv[])
if ((s = unix_connect(host)) > 0) {
if (!zflag)
+# if defined(TLS)
readwrite(s, NULL);
+# else
+ readwrite(s);
+# endif
close(s);
} else {
warn("%s", host);
@@ -698,6 +775,7 @@ main(int argc, char *argv[])
for (s = -1, i = 0; portlist[i] != NULL; i++) {
if (s != -1)
close(s);
+# if defined(TLS)
tls_free(tls_ctx);
tls_ctx = NULL;
@@ -708,6 +786,7 @@ main(int argc, char *argv[])
errx(1, "tls configuration failed (%s)",
tls_error(tls_ctx));
}
+# endif
if (xflag)
s = socks_connect(host, portlist[i], hints,
proxy, proxyport, proxyhints, socksv,
@@ -745,6 +824,7 @@ main(int argc, char *argv[])
}
if (Fflag)
fdpass(s);
+# if defined(TLS)
else {
if (usetls)
tls_setup_client(tls_ctx, s, host);
@@ -753,13 +833,19 @@ main(int argc, char *argv[])
if (tls_ctx)
timeout_tls(s, tls_ctx, tls_close);
}
+# else
+ else if (!zflag)
+ readwrite(s);
+# endif
}
}
if (s != -1)
close(s);
+# if defined(TLS)
tls_free(tls_ctx);
tls_config_free(tls_cfg);
+# endif
return ret;
}
@@ -801,6 +887,7 @@ unix_bind(char *path, int flags)
return s;
}
+# if defined(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
}
return NULL;
}
+# endif
/*
* unix_connect()
@@ -1112,7 +1200,11 @@ local_listen(const char *host, const cha
* Loop that polls on the network file descriptor and stdin.
*/
void
+# if defined(TLS)
readwrite(int net_fd, struct tls *tls_ctx)
+# else
+readwrite(int net_fd)
+# endif
{
struct pollfd pfd[4];
int stdin_fd = STDIN_FILENO;
@@ -1212,12 +1304,17 @@ readwrite(int net_fd, struct tls *tls_ct
/* try to read from stdin */
if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) {
ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf,
+# if defined(TLS)
&stdinbufpos, NULL);
if (ret == TLS_WANT_POLLIN)
pfd[POLL_STDIN].events = POLLIN;
else if (ret == TLS_WANT_POLLOUT)
pfd[POLL_STDIN].events = POLLOUT;
- else if (ret == 0 || ret == -1)
+ else
+# else
+ &stdinbufpos);
+# 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
/* try to write to network */
if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) {
ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf,
+# if defined(TLS)
&stdinbufpos, tls_ctx);
if (ret == TLS_WANT_POLLIN)
pfd[POLL_NETOUT].events = POLLIN;
else if (ret == TLS_WANT_POLLOUT)
pfd[POLL_NETOUT].events = POLLOUT;
- else if (ret == -1)
+ else
+# else
+ &stdinbufpos);
+# 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
/* try to read from network */
if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) {
ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf,
+# if defined(TLS)
&netinbufpos, tls_ctx);
if (ret == TLS_WANT_POLLIN)
pfd[POLL_NETIN].events = POLLIN;
else if (ret == TLS_WANT_POLLOUT)
pfd[POLL_NETIN].events = POLLOUT;
- else if (ret == -1)
+ else
+# else
+ &netinbufpos);
+# 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
/* try to write to stdout */
if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) {
ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf,
+# if defined(TLS)
&netinbufpos, NULL);
if (ret == TLS_WANT_POLLIN)
pfd[POLL_STDOUT].events = POLLIN;
else if (ret == TLS_WANT_POLLOUT)
pfd[POLL_STDOUT].events = POLLOUT;
- else if (ret == -1)
+ else
+# else
+ &netinbufpos);
+# 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
}
ssize_t
+# if defined(TLS)
drainbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
+# else
+drainbuf(int fd, unsigned char *buf, size_t *bufpos)
+# endif
{
ssize_t n;
ssize_t adjust;
+# if defined(TLS)
if (tls) {
n = tls_write(tls, buf, *bufpos);
if (n == -1)
errx(1, "tls write failed (%s)", tls_error(tls));
} else {
+# endif
n = write(fd, buf, *bufpos);
/* don't treat EAGAIN, EINTR as error */
if (n == -1 && (errno == EAGAIN || errno == EINTR))
+# if defined(TLS)
n = TLS_WANT_POLLOUT;
}
+# else
+ n = -2;
+# endif
if (n <= 0)
return n;
/* adjust buffer */
@@ -1333,21 +1455,31 @@ drainbuf(int fd, unsigned char *buf, siz
}
ssize_t
+# if defined(TLS)
fillbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
+# else
+fillbuf(int fd, unsigned char *buf, size_t *bufpos)
+# endif
{
size_t num = BUFSIZE - *bufpos;
ssize_t n;
+# if defined(TLS)
if (tls) {
n = tls_read(tls, buf + *bufpos, num);
if (n == -1)
errx(1, "tls read failed (%s)", tls_error(tls));
} else {
+# endif
n = read(fd, buf + *bufpos, num);
/* don't treat EAGAIN, EINTR as error */
if (n == -1 && (errno == EAGAIN || errno == EINTR))
+# if defined(TLS)
n = TLS_WANT_POLLIN;
}
+# else
+ n = -2;
+# endif
if (n <= 0)
return n;
*bufpos += n;
@@ -1665,6 +1797,7 @@ process_tos_opt(char *s, int *val)
return 0;
}
+# if defined(TLS)
int
process_tls_opt(char *s, int *flags)
{
@@ -1778,6 +1911,7 @@ report_tls(struct tls * tls_ctx, char *
}
}
+# endif
void
report_sock(const char *msg, const struct sockaddr *sa, socklen_t salen,
@@ -1816,17 +1950,12 @@ help(void)
fprintf(stderr, "\tCommand Summary:\n\
\t-4 Use IPv4\n\
\t-6 Use IPv6\n\
- \t-C certfile Public key file\n\
- \t-c Use TLS\n\
\t-D Enable the debug socket option\n\
\t-d Detach from stdin\n\
- \t-e name\t Required name in peer certificate\n\
\t-F Pass socket fd\n\
- \t-H hash\t Hash string of peer certificate\n\
\t-h This help text\n\
\t-I length TCP receive buffer length\n\
\t-i interval Delay interval for lines sent, ports scanned\n\
- \t-K keyfile Private key file\n\
\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)
\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\
- \t-o staplefile Staple file\n\
\t-P proxyuser\tUsername for proxy authentication\n\
\t-p port\t Specify local port for remote connects\n\
- \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-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)
\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\
- \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");
exit(0);
@@ -1861,15 +1987,11 @@ void
usage(int ret)
{
fprintf(stderr,
- "usage: nc [-46cDdFhklNnrStUuvz] [-C certfile] [-e name] "
- "[-H hash] [-I length]\n"
- "\t [-i interval] [-K keyfile] [-M ttl] [-m minttl] [-O length]\n"
- "\t [-o staplefile] [-P proxy_username] [-p source_port] "
- "[-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] "
"[-w timeout]\n"
"\t [-X proxy_protocol] [-x proxy_address[:port]] "
- "[-Z peercertfile]\n"
"\t [destination] [port]\n");
if (ret)
exit(1);

126
connect-timeout.patch Normal file
View File

@ -0,0 +1,126 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 14:43:56 +0800
Subject: connect timeout
---
netcat.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 76 insertions(+), 2 deletions(-)
--- a/netcat.c
+++ b/netcat.c
@@ -90,6 +90,7 @@
#include <ctype.h>
#include <err.h>
#include <errno.h>
+#include <fcntl.h>
#include <limits.h>
#include <netdb.h>
#include <poll.h>
@@ -124,6 +125,10 @@
# define TLS_MUSTSTAPLE (1 << 4)
#endif
+#define CONNECTION_SUCCESS 0
+#define CONNECTION_FAILED 1
+#define CONNECTION_TIMEOUT 2
+
/* 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
ssize_t fillbuf(int, unsigned char *, size_t *);
# endif
+static int connect_with_timeout(int fd, const struct sockaddr *sa,
+ socklen_t salen, int ctimeout);
+
int
main(int argc, char *argv[])
{
@@ -1078,11 +1086,14 @@ remote_connect(const char *host, const c
set_common_sockopts(s, res->ai_family);
- 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)
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");
save_errno = errno;
close(s);
@@ -1123,6 +1134,69 @@ timeout_connect(int s, const struct sock
return ret;
}
+static int connect_with_timeout(int fd, const struct sockaddr *sa,
+ socklen_t salen, int ctimeout)
+{
+ int err;
+ struct timeval tv, *tvp = NULL;
+ fd_set connect_fdset;
+ socklen_t len;
+ int orig_flags;
+
+ orig_flags = fcntl(fd, F_GETFL, 0);
+ if (fcntl(fd, F_SETFL, orig_flags | O_NONBLOCK) < 0 ) {
+ warn("can't set O_NONBLOCK - timeout not available");
+ if (connect(fd, sa, salen) == 0)
+ return CONNECTION_SUCCESS;
+ else
+ return CONNECTION_FAILED;
+ }
+
+ /* set connect timeout */
+ if (ctimeout > 0) {
+ tv.tv_sec = (time_t)ctimeout/1000;
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+
+ /* attempt the connection */
+ err = connect(fd, sa, salen);
+ if (err != 0 && errno == EINPROGRESS) {
+ /* connection is proceeding
+ * it is complete (or failed) when select returns */
+
+ /* initialize connect_fdset */
+ FD_ZERO(&connect_fdset);
+ FD_SET(fd, &connect_fdset);
+
+ /* call select */
+ do {
+ err = select(fd + 1, NULL, &connect_fdset,
+ NULL, tvp);
+ } while (err < 0 && errno == EINTR);
+
+ /* select error */
+ if (err < 0)
+ errx(1,"select error: %s", strerror(errno));
+ /* we have reached a timeout */
+ if (err == 0)
+ return CONNECTION_TIMEOUT;
+ /* select returned successfully, but we must test socket
+ * error for result */
+ len = sizeof(err);
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
+ errx(1, "getsockopt error: %s", strerror(errno));
+ /* setup errno according to the result returned by
+ * getsockopt */
+ if (err != 0)
+ errno = err;
+ }
+
+ /* return aborted if an error occured, and valid otherwise */
+ fcntl(fd, F_SETFL, orig_flags);
+ return (err != 0)? CONNECTION_FAILED : CONNECTION_SUCCESS;
+}
+
/*
* local_listen()
* Returns a socket listening on a local port, binds to specified source

235
dccp-support.patch Normal file
View File

@ -0,0 +1,235 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:56:51 +0800
Subject: dccp support
---
nc.1 | 4 ++
netcat.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 79 insertions(+), 14 deletions(-)
--- a/nc.1
+++ b/nc.1
@@ -33,7 +33,7 @@
.Nd arbitrary TCP and UDP connections and listens
.Sh SYNOPSIS
.Nm nc
-.Op Fl 46CDdFhklNnrStUuvz
+.Op Fl 46CDdFhklNnrStUuvZz
.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
in square brackets.
A proxy cannot be used with any of the options
.Fl lsuU .
+.It Fl Z
+DCCP mode.
.It Fl z
Only scan for listening daemons, without sending any data to them.
Cannot be used together with
--- a/netcat.c
+++ b/netcat.c
@@ -146,6 +146,7 @@ int rflag; /* Random ports flag */
char *sflag; /* Source Address */
int tflag; /* Telnet Emulation */
int uflag; /* UDP - Default to TCP */
+int dccpflag; /* DCCP - Default to TCP */
int vflag; /* Verbosity */
int xflag; /* Socks proxy */
int zflag; /* Port Scan Flag */
@@ -224,6 +225,7 @@ ssize_t drainbuf(int, unsigned char *, s
ssize_t fillbuf(int, unsigned char *, size_t *);
# endif
+char *proto_name(int uflag, int dccpflag);
static int connect_with_timeout(int fd, const struct sockaddr *sa,
socklen_t salen, int ctimeout);
@@ -263,7 +265,7 @@ main(int argc, char *argv[])
# if defined(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
- "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
!= -1) {
switch (ch) {
@@ -380,6 +382,13 @@ main(int argc, char *argv[])
case 'u':
uflag = 1;
break;
+ case 'Z':
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ dccpflag = 1;
+# else
+ errx(1, "no DCCP support available");
+# endif
+ break;
case 'V':
# if defined(RT_TABLEID_MAX)
rtableid = (int)strtonum(optarg, 0,
@@ -484,6 +493,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 (dccpflag)
+ errx(1, "cannot use -Z and -U");
+# endif
host = argv[0];
uport = NULL;
} else if (!argv[0] && lflag) {
@@ -577,8 +590,20 @@ main(int argc, char *argv[])
if (family != AF_UNIX) {
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = family;
- hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
- hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
+ if (uflag) {
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ }
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ else if (dccpflag) {
+ hints.ai_socktype = SOCK_DCCP;
+ hints.ai_protocol = IPPROTO_DCCP;
+ }
+# endif
+ else {
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ }
if (nflag)
hints.ai_flags |= AI_NUMERICHOST;
}
@@ -586,7 +611,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 (dccpflag)
+ errx(1, "no proxy support for DCCP mode");
+# endif
if (lflag)
errx(1, "no proxy support for listen");
@@ -833,19 +861,20 @@ main(int argc, char *argv[])
}
}
+ 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 : "*");
}
if (Fflag)
@@ -1060,6 +1089,24 @@ unix_listen(char *path)
return s;
}
+char *proto_name(int uflag, int dccpflag) {
+
+ char *proto = NULL;
+ if (uflag) {
+ proto = "udp";
+ }
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ else if (dccpflag) {
+ proto = "dccp";
+ }
+# endif
+ else {
+ proto = "tcp";
+ }
+
+ return proto;
+}
+
/*
* 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
memset(&ahints, 0, sizeof(struct addrinfo));
ahints.ai_family = res->ai_family;
- ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
- ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
+ if (uflag) {
+ ahints.ai_socktype = SOCK_DGRAM;
+ ahints.ai_protocol = IPPROTO_UDP;
+
+ }
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ else if (dccpflag) {
+ hints.ai_socktype = SOCK_DCCP;
+ hints.ai_protocol = IPPROTO_DCCP;
+ }
+# endif
+ else {
+ ahints.ai_socktype = SOCK_STREAM;
+ ahints.ai_protocol = IPPROTO_TCP;
+ }
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
}
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)
int hi, lo, cp;
int x = 0;
- sv = getservbyname(p, uflag ? "udp" : "tcp");
+ char *proto = proto_name(uflag, dccpflag);
+ sv = getservbyname(p, proto);
if (sv) {
if (asprintf(&portlist[0], "%d", ntohs(sv->s_port)) < 0)
err(1, "asprintf");
@@ -2095,6 +2157,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\
+ \t-Z DCCP mode\n\
\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
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"

191
destination-port-list.patch Normal file
View File

@ -0,0 +1,191 @@
From: Guilhem Moulin <guilhem@debian.org>
Date: Mon, 22 Oct 2018 04:15:52 +0200
Subject: destination port list
---
nc.1 | 26 ++++++++++++++++---
netcat.c | 86 ++++++++++++++++++++++++++++++++-------------------------------
2 files changed, 68 insertions(+), 44 deletions(-)
--- a/nc.1
+++ b/nc.1
@@ -414,15 +414,35 @@ The
flag can be used to tell
.Nm
to report open ports,
-rather than initiate a connection.
+rather than initiate a connection. Usually it's useful to turn on verbose
+output to stderr by use this option in conjunction with
+.Fl v
+option.
+.Pp
For example:
.Bd -literal -offset indent
-$ nc -z host.example.com 20-30
+$ nc \-zv host.example.com 20-30
Connection to host.example.com 22 port [tcp/ssh] succeeded!
Connection to host.example.com 25 port [tcp/smtp] succeeded!
.Ed
.Pp
-The port range was specified to limit the search to ports 20 \- 30.
+The port range was specified to limit the search to ports 20 \- 30, and is
+scanned by increasing order (unless the
+.Fl r
+flag is set).
+.Pp
+You can also specify a list of ports to scan, for example:
+.Bd -literal -offset indent
+$ nc \-zv host.example.com http 20 22-23
+nc: connect to host.example.com 80 (tcp) failed: Connection refused
+nc: connect to host.example.com 20 (tcp) failed: Connection refused
+Connection to host.example.com port [tcp/ssh] succeeded!
+nc: connect to host.example.com 23 (tcp) failed: Connection refused
+.Ed
+.Pp
+The ports are scanned by the order you given (unless the
+.Fl r
+flag is set).
.Pp
Alternatively, it might be useful to know which server software
is running, and which versions.
--- a/netcat.c
+++ b/netcat.c
@@ -191,7 +191,7 @@ int minttl = -1;
void atelnet(int, unsigned char *, unsigned int);
int strtoport(char *portstr, int udp);
-void build_ports(char *);
+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
main(int argc, char *argv[])
{
int ch, s = -1, ret, socksv;
- char *host, *uport;
+ char *host, **uport;
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);
- uport = argv[0];
+ uport = &argv[0];
host = NULL;
} else if (argv[0] && argv[1]) {
host = argv[0];
- uport = argv[1];
+ uport = &argv[1];
} else
usage(1);
@@ -717,7 +717,7 @@ main(int argc, char *argv[])
else
s = unix_listen(host);
} else
- s = local_listen(host, uport, hints);
+ s = local_listen(host, *uport, hints);
if (s < 0)
err(1, NULL);
@@ -1785,57 +1785,61 @@ strtoport(char *portstr, int udp)
* that we should try to connect to.
*/
void
-build_ports(char *p)
+build_ports(char **p)
{
struct servent *sv;
char *n;
int hi, lo, cp;
int x = 0;
+ int i;
char *proto = proto_name(uflag, dccpflag);
- sv = getservbyname(p, proto);
- if (sv) {
- if (asprintf(&portlist[0], "%d", ntohs(sv->s_port)) < 0)
- err(1, "asprintf");
- } else if (isdigit((unsigned char)*p) && (n = strchr(p, '-')) != NULL) {
- *n = '\0';
- n++;
-
- /* Make sure the ports are in order: lowest->highest. */
- hi = strtoport(n, uflag);
- lo = strtoport(p, uflag);
- if (lo > hi) {
- cp = hi;
- hi = lo;
- lo = cp;
- }
-
- /*
- * Initialize portlist with a random permutation. Based on
- * Knuth, as in ip_randomid() in sys/netinet/ip_id.c.
- */
- if (rflag) {
- for (x = 0; x <= hi - lo; x++) {
- cp = arc4random_uniform(x + 1);
- portlist[x] = portlist[cp];
- if (asprintf(&portlist[cp], "%d", x + lo) < 0)
- err(1, "asprintf");
+ for (i = 0; p[i] != NULL; i++) {
+ sv = getservbyname(p[i], proto);
+ if (sv) {
+ if (asprintf(&portlist[x], "%d", ntohs(sv->s_port)) < 0)
+ err(1, "asprintf");
+ x++;
+ } else if (isdigit((unsigned char)*p[i]) && (n = strchr(p[i], '-')) != NULL) {
+ *n = '\0';
+ n++;
+
+ /* Make sure the ports are in order: lowest->highest. */
+ hi = strtoport(n, uflag);
+ lo = strtoport(p[i], uflag);
+ if (lo > hi) {
+ cp = hi;
+ hi = lo;
+ lo = cp;
}
- } else { /* Load ports sequentially. */
+
+ /* Load ports sequentially. */
for (cp = lo; cp <= hi; cp++) {
if (asprintf(&portlist[x], "%d", cp) < 0)
err(1, "asprintf");
x++;
}
+ } else {
+ hi = strtoport(p[i], uflag);
+ if (asprintf(&portlist[x], "%d", hi) < 0)
+ err(1, "asprintf");
+ x++;
}
- } else {
- char *tmp;
+ }
- hi = strtoport(p, uflag);
- if (asprintf(&tmp, "%d", hi) != -1)
- portlist[0] = tmp;
- else
- err(1, NULL);
+ /*
+ * Initialize portlist with a random permutation using
+ * FisherYates shuffle.
+ */
+ if (rflag) {
+ for (i = x-1; i > 0; i--) {
+ cp = arc4random_uniform(i+1);
+ if (cp != i) {
+ n = portlist[i];
+ portlist[i] = portlist[cp];
+ portlist[cp] = n;
+ }
+ }
}
}

View File

@ -0,0 +1,35 @@
Index: netcat-openbsd-1.203/netcat.c
===================================================================
--- netcat-openbsd-1.203.orig/netcat.c
+++ netcat-openbsd-1.203/netcat.c
@@ -1889,6 +1889,21 @@ udptest(int s)
return 1;
}
+static int
+enable_icmp_errors (int family, int fd)
+{
+ int one = 1;
+ switch (family)
+ {
+ case AF_INET:
+ return setsockopt (fd, SOL_IP, IP_RECVERR, &one, sizeof (one));
+ case AF_INET6:
+ return setsockopt (fd, SOL_IPV6, IPV6_RECVERR, &one, sizeof (one));
+ default:
+ return -1;
+ }
+}
+
void
set_common_sockopts(int s, const struct sockaddr* sa)
{
@@ -1982,6 +1997,8 @@ set_common_sockopts(int s, const struct
errx(1, "can't set IPv6 min hop count (unavailable)");
#endif
}
+ if(uflag)
+ enable_icmp_errors(af,s);
}
int

28
get-sev-by-name.patch Normal file
View File

@ -0,0 +1,28 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 14:45:08 +0800
Subject: get sev by name
---
netcat.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/netcat.c
+++ b/netcat.c
@@ -1679,11 +1679,16 @@ strtoport(char *portstr, int udp)
void
build_ports(char *p)
{
+ struct servent *sv;
char *n;
int hi, lo, cp;
int x = 0;
- if (isdigit((unsigned char)*p) && (n = strchr(p, '-')) != NULL) {
+ sv = getservbyname(p, uflag ? "udp" : "tcp");
+ if (sv) {
+ if (asprintf(&portlist[0], "%d", ntohs(sv->s_port)) < 0)
+ err(1, "asprintf");
+ } else if (isdigit((unsigned char)*p) && (n = strchr(p, '-')) != NULL) {
*n = '\0';
n++;

View File

@ -0,0 +1,145 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 19:06:52 +0800
Subject: misc failures and features
---
Makefile | 3 ++-
nc.1 | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
netcat.c | 14 ++++++++++++--
3 files changed, 65 insertions(+), 3 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
--- 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 .
+.Pp
+There is no
+.Fl c
+or
+.Fl e
+option in this netcat, but you still can execute a command after connection
+being established by redirecting file descriptors. Be cautious here because
+opening a port and let anyone connected execute arbitrary command on your
+site is DANGEROUS. If you really need to do this, here is an example:
+.Pp
+On
+.Sq server
+side:
+.Pp
+.Dl $ rm -f /tmp/f; mkfifo /tmp/f
+.Dl $ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
+.Pp
+On
+.Sq client
+side:
+.Pp
+.Dl $ nc host.example.com 1234
+.Dl $ (shell prompt from host.example.com)
+.Pp
+By doing this, you create a fifo at /tmp/f and make nc listen at port 1234
+of address 127.0.0.1 on
+.Sq server
+side, when a
+.Sq client
+establishes a connection successfully to that port, /bin/sh gets executed
+on
+.Sq server
+side and the shell prompt is given to
+.Sq client
+side.
+.Pp
+When connection is terminated,
+.Nm
+quits as well. Use
+.Fl k
+if you want it keep listening, but if the command quits this option won't
+restart it or keep
+.Nm
+running. Also don't forget to remove the file descriptor once you don't need
+it anymore:
+.Pp
+.Dl $ rm -f /tmp/f
+.Pp
.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
.br
Rewritten with IPv6 support by
.An Eric Jackson Aq Mt ericj@monkey.org .
+.br
+Modified for Debian port by Aron Xu
+.Aq aron@debian.org .
.Sh CAVEATS
UDP port scans using the
.Fl uz
--- 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)
return -1;
+ 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) {
save_errno = errno;
+ warn("unix connect failed");
close(s);
errno = save_errno;
return -1;

182
netcat-openbsd.changes Normal file
View File

@ -0,0 +1,182 @@
-------------------------------------------------------------------
Mon Nov 22 10:16:15 UTC 2021 - Peter Simons <psimons@suse.com>
- Fix download URL. Debian has purged older versions from their
servers.
-------------------------------------------------------------------
Tue Dec 15 13:15:37 UTC 2020 - Cristian Rodríguez <crrodriguez@opensuse.org>
- Build with hidden visibility since no symbols should be exported
-------------------------------------------------------------------
Tue Dec 15 13:05:05 UTC 2020 - Cristian Rodríguez <crrodriguez@opensuse.org>
- enable-udp-ip_recverr.patch: Enable IP_RECVERR on UDP sockets
to match *bsd behaviour and avoid long timeouts if an error
ocurrs.
-------------------------------------------------------------------
Mon Dec 7 13:09:09 UTC 2020 - Cristian Rodríguez <crrodriguez@opensuse.org>
- Add port-select-on-connect.patch: if -s is given but not -p
do not select port at bind() but at connect() time.
-------------------------------------------------------------------
Mon Sep 9 18:48:35 UTC 2019 - Tomáš Chvátal <tchvatal@suse.com>
- Update to 1.203 matching debian
- Remove patch verbose-numeric-port.patch
- Refresh patches:
* broadcast-support.patch
* build-without-TLS-support.patch
* connect-timeout.patch
* dccp-support.patch
* destination-port-list.patch
* get-sev-by-name.patch
* misc-failures-and-features.patch
* port-to-linux-with-libsd.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
-------------------------------------------------------------------
Wed Nov 14 13:12:29 UTC 2018 - Tomáš Chvátal <tchvatal@suse.com>
- Update to 1.195 release matching with debian
- Added new patches:
* broadcast-support.patch
* build-without-TLS-support.patch
* destination-port-list.patch
* use-flags-to-specify-listen-address.patch
- Refreshed patches:
* connect-timeout.patch
* dccp-support.patch
* get-sev-by-name.patch
* misc-failures-and-features.patch
* port-to-linux-with-libsd.patch
* quit-timer.patch
* send-crlf.patch
* serialized-handling-multiple-clients.patch
* set-TCP-MD5SIG-correctly-for-client-connections.patch
* udp-scan-timeout.patch
* verbose-numeric-port.patch
- Drop patch compile-without-TLS-support.patch, renamed
-------------------------------------------------------------------
Mon Jul 17 13:11:34 UTC 2017 - tchvatal@suse.com
- Drop all patches that were never upstreamed:
* connect-timeout.patch
* dccp.patch
* gcc-warnings.patch
* getservbyname.patch
* glib-strlcpy.patch
* help-version-exit.patch
* nc-1.84-udp_stop.patch
* netcat-info.patch
* netcat-openbsd-debian.patch
* netcat-openbsd-examples.patch
* netcat-openbsd-openbsd-compat.patch
* no-strtonum.patch
* pollhup.patch
* quit-timer.patch
* reuseaddr.patch
* send-crlf.patch
* silence-z.patch
* socks-b64-prototype.patch
* udp-scan-timeout.patch
* verbose-message-to-stderr.patch
* verbose-numeric-port.patch
- Switch to debian package to not waste resources on doing exactly
the same.
- Switches URL for debian package
- Apply patches already prepared for debian package
* port-to-linux-with-libsd.patch
* compile-without-TLS-support.patch
* connect-timeout.patch
* get-sev-by-name.patch
* send-crlf.patch
* quit-timer.patch
* udp-scan-timeout.patch
* verbose-numeric-port.patch
* dccp-support.patch
* serialized-handling-multiple-clients.patch
* set-TCP-MD5SIG-correctly-for-client-connections.patch
* misc-failures-and-features.patch
- Do not use hand provided CMakeLists.txt but rely on upstream makefile
-------------------------------------------------------------------
Fri Jan 17 23:36:07 UTC 2014 - crrodriguez@opensuse.org
- drop dependency on glib, strlcpy can be implemented with
snprintf with glibc/linux
- drop "quilt" from buildrequires, no longer used.
- Use fvisibiliy=hidden to build, this is a program not
a library and no symbols should be exported.
- modified patches:
* glib-strlcpy.patch
-------------------------------------------------------------------
Mon Sep 2 20:12:17 CEST 2013 - pth@suse.de
- Split up the huge ubuntu patch into a debian specific patch,
a patch that creates the examples, a patch with the openbasd-compat
stuff and single files for each of the patches in debian/patches.
This hugely eases maintainabilty:
connect-timeout.patch, dccp.patch, gcc-warnings.patch,
getservbyname.patch, glib-strlcpy.patch, help-version-exit.patch,
nc-1.84-udp_stop.patch, netcat-info.patch, netcat-openbsd-debian.patch,
netcat-openbsd-examples.patch, netcat-openbsd-openbsd-compat.patch,
no-strtonum.patch, pollhup.patch, quit-timer.patch, reuseaddr.patch,
send-crlf.patch, silence-z.patch, socks-b64-prototype.patch,
udp-scan-timeout.patch, verbose-message-to-stderr.patch,
verbose-numeric-port.patch.
-------------------------------------------------------------------
Sat Dec 10 17:46:07 UTC 2011 - crrodriguez@opensuse.org
- Update xbuntu patches.
- Ensure we have large file support in 32 bit builds
- Fix rpmlint warnings
-------------------------------------------------------------------
Sat Jul 16 13:34:18 UTC 2011 - andrea.turrini@gmail.com
- Fixed typos in description of netcat-openbsd.spec
-------------------------------------------------------------------
Fri Jun 25 16:55:06 UTC 2010 - lmuelle@suse.de
- Use update-alternatives to set netcat symbolic links for compatibility.
- Provides and obsoltes netcat.
-------------------------------------------------------------------
Fri May 28 16:27:34 UTC 2010 - cristian.rodriguez@opensuse.org
- Obsolete nc6
-------------------------------------------------------------------
Tue May 18 18:10:16 UTC 2010 - cristian.rodriguez@opensuse.org
- sync recent bugfixes from Ubuntu
-------------------------------------------------------------------
Fri Feb 20 15:19:28 CET 2009 - crrodriguez@suse.de
- sync most recent bugfixes from debian/Ubuntu
-------------------------------------------------------------------
Sat Jul 5 19:30:39 CEST 2008 - crrodriguez@suse.de
- netcat-openbsd conflicts with netcat but it should not [BNC#406581]
-------------------------------------------------------------------
Sun Apr 13 05:08:48 CEST 2008 - crrodriguez@suse.de
- initial version for the OBS

83
netcat-openbsd.spec Normal file
View File

@ -0,0 +1,83 @@
#
# spec file for package netcat-openbsd
#
# Copyright (c) 2021 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
Name: netcat-openbsd
Version: 1.203
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
Patch1: build-without-TLS-support.patch
Patch2: connect-timeout.patch
Patch3: get-sev-by-name.patch
Patch4: send-crlf.patch
Patch5: quit-timer.patch
Patch6: udp-scan-timeout.patch
Patch7: dccp-support.patch
Patch8: broadcast-support.patch
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
BuildRequires: pkgconfig
BuildRequires: pkgconfig(libbsd)
Provides: nc6 = %{version}
Provides: netcat = %{version}
Obsoletes: nc6 <= 1.0
Obsoletes: netcat <= 1.10
%description
A simple Unix utility which reads and writes data across network
connections using TCP or UDP protocol. It is designed to be a reliable
"back-end" tool that can be used directly or easily driven by other
programs and scripts. At the same time it is a feature-rich network
debugging and exploration tool, since it can create almost any kind of
connection you would need and has several interesting built-in
capabilities.
This package contains the OpenBSD rewrite of netcat, including support
for IPv6, proxies, and Unix sockets.
%prep
%setup -q
%autopatch -p1
%build
make %{?_smp_mflags} \
CFLAGS="%{optflags} -fvisibility=hidden"
%install
install -D -m0755 nc %{buildroot}%{_bindir}/nc
install -D -m0644 nc.1 %{buildroot}/%{_mandir}/man1/nc.1
ln -s -f %{_bindir}/nc %{buildroot}/%{_bindir}/netcat
ln -s -f nc.1%{ext_man} %{buildroot}/%{_mandir}/man1/netcat.1%{ext_man}
%files
%{_bindir}/nc
%{_bindir}/netcat
%{_mandir}/man1/nc.1%{?ext_man}
%{_mandir}/man1/netcat.1%{?ext_man}
%changelog

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

Binary file not shown.

View File

@ -0,0 +1,16 @@
Index: netcat-openbsd-1.203/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
ahints.ai_flags = AI_PASSIVE;
if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
errx(1, "getaddrinfo: %s", gai_strerror(error));
-
+#ifdef IP_BIND_ADDRESS_NO_PORT
+ if(sflag && !pflag)
+ 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)
err(1, "bind failed");

View File

@ -0,0 +1,483 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:59:31 +0800
Subject: port to linux with libsd
---
Makefile | 15 ++++++-
nc.1 | 3 -
netcat.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++---------------
socks.c | 46 +++++++++++-----------
4 files changed, 139 insertions(+), 56 deletions(-)
--- a/Makefile
+++ b/Makefile
@@ -5,4 +5,17 @@ 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
+OBJS= $(SRCS:.c=.o)
+CFLAGS= -g -O2
+LDFLAGS= -Wl,--no-add-needed
+
+all: nc
+nc: $(OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o nc
+
+$(OBJS): %.o: %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+clean:
+ rm -f $(OBJS) nc
--- a/nc.1
+++ b/nc.1
@@ -213,8 +213,6 @@ Proxy authentication is only supported f
Specify the source port
.Nm
should use, subject to privilege restrictions and availability.
-Cannot be used together with
-.Fl l .
.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
may be one of
.Cm critical ,
.Cm inetcontrol ,
+.Cm lowcost ,
.Cm lowdelay ,
.Cm netcontrol ,
.Cm throughput ,
--- a/netcat.c
+++ b/netcat.c
@@ -32,6 +32,8 @@
* *Hobbit* <hobbit@avian.org>.
*/
+#define _GNU_SOURCE
+
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
@@ -41,6 +43,49 @@
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <arpa/telnet.h>
+#ifdef __linux__
+# include <linux/in6.h>
+#endif
+
+#ifndef IPTOS_LOWDELAY
+# define IPTOS_LOWDELAY 0x10
+# define IPTOS_THROUGHPUT 0x08
+# define IPTOS_RELIABILITY 0x04
+# define IPTOS_LOWCOST 0x02
+# define IPTOS_MINCOST IPTOS_LOWCOST
+#endif /* IPTOS_LOWDELAY */
+
+# ifndef IPTOS_DSCP_AF11
+# define IPTOS_DSCP_AF11 0x28
+# define IPTOS_DSCP_AF12 0x30
+# define IPTOS_DSCP_AF13 0x38
+# define IPTOS_DSCP_AF21 0x48
+# define IPTOS_DSCP_AF22 0x50
+# define IPTOS_DSCP_AF23 0x58
+# define IPTOS_DSCP_AF31 0x68
+# define IPTOS_DSCP_AF32 0x70
+# define IPTOS_DSCP_AF33 0x78
+# define IPTOS_DSCP_AF41 0x88
+# define IPTOS_DSCP_AF42 0x90
+# define IPTOS_DSCP_AF43 0x98
+# define IPTOS_DSCP_EF 0xb8
+#endif /* IPTOS_DSCP_AF11 */
+
+#ifndef IPTOS_DSCP_CS0
+# define IPTOS_DSCP_CS0 0x00
+# define IPTOS_DSCP_CS1 0x20
+# define IPTOS_DSCP_CS2 0x40
+# define IPTOS_DSCP_CS3 0x60
+# define IPTOS_DSCP_CS4 0x80
+# define IPTOS_DSCP_CS5 0xa0
+# define IPTOS_DSCP_CS6 0xc0
+# define IPTOS_DSCP_CS7 0xe0
+#endif /* IPTOS_DSCP_CS0 */
+
+#ifndef IPTOS_DSCP_EF
+# define IPTOS_DSCP_EF 0xb8
+#endif /* IPTOS_DSCP_EF */
+
#include <ctype.h>
#include <err.h>
@@ -56,6 +101,8 @@
#include <time.h>
#include <tls.h>
#include <unistd.h>
+#include <bsd/stdlib.h>
+#include <bsd/string.h>
#include "atomicio.h"
@@ -269,10 +316,14 @@ main(int argc, char *argv[])
uflag = 1;
break;
case 'V':
+# if defined(RT_TABLEID_MAX)
rtableid = (int)strtonum(optarg, 0,
RT_TABLEID_MAX, &errstr);
if (errstr)
errx(1, "rtable %s: %s", errstr, optarg);
+# else
+ errx(1, "no alternate routing table support available");
+# endif
break;
case 'v':
vflag = 1;
@@ -321,7 +372,11 @@ main(int argc, char *argv[])
oflag = optarg;
break;
case 'S':
+# if defined(TCP_MD5SIG)
Sflag = 1;
+# else
+ errx(1, "no TCP MD5 signature support available");
+# endif
break;
case 'T':
errstr = NULL;
@@ -346,14 +401,23 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
+# if defined(RT_TABLEID_MAX)
if (rtableid >= 0)
if (setrtable(rtableid) == -1)
err(1, "setrtable");
+# endif
/* Cruft to make sure options are clean, and used properly. */
if (argv[0] && !argv[1] && family == AF_UNIX) {
host = argv[0];
uport = NULL;
+ } else if (!argv[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[])
}
}
- if (family == AF_UNIX) {
- if (pledge("stdio rpath wpath cpath tmppath unix", NULL) == -1)
- err(1, "pledge");
- } else if (Fflag && Pflag) {
- if (pledge("stdio inet dns sendfd tty", NULL) == -1)
- err(1, "pledge");
- } else if (Fflag) {
- if (pledge("stdio inet dns sendfd", NULL) == -1)
- err(1, "pledge");
- } else if (Pflag && usetls) {
- if (pledge("stdio rpath inet dns tty", NULL) == -1)
- err(1, "pledge");
- } else if (Pflag) {
- if (pledge("stdio inet dns tty", NULL) == -1)
- err(1, "pledge");
- } else if (usetls) {
- if (pledge("stdio rpath inet dns", NULL) == -1)
- err(1, "pledge");
- } else if (pledge("stdio inet dns", NULL) == -1)
- err(1, "pledge");
-
- if (lflag && sflag)
- errx(1, "cannot use -s and -l");
- if (lflag && pflag)
- errx(1, "cannot use -p and -l");
- if (lflag && zflag)
- errx(1, "cannot use -z and -l");
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
if (sflag || pflag) {
struct addrinfo ahints, *ares;
+# if defined (SO_BINDANY)
/* try SO_BINDANY, but don't insist */
setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on));
+# 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)
continue;
+ ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
+ if (ret == -1)
+ err(1, NULL);
+
+# if defined(SO_REUSEPORT)
ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
if (ret == -1)
err(1, NULL);
+# endif
set_common_sockopts(s, res->ai_family);
@@ -1498,11 +1543,13 @@ set_common_sockopts(int s, int af)
{
int x = 1;
+# if defined(TCP_MD5SIG)
if (Sflag) {
if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
&x, sizeof(x)) == -1)
err(1, NULL);
}
+# 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)
IP_TOS, &Tflag, sizeof(Tflag)) == -1)
err(1, "set IP ToS");
+#if defined(IPV6_TCLASS)
else if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6,
IPV6_TCLASS, &Tflag, sizeof(Tflag)) == -1)
err(1, "set IPv6 traffic class");
+#else
+ else if (af == AF_INET6)
+ errx(1, "can't set IPv6 traffic class (unavailable)");
+#endif
}
if (Iflag) {
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
@@ -1533,19 +1585,34 @@ set_common_sockopts(int s, int af)
IP_TTL, &ttl, sizeof(ttl)))
err(1, "set IP TTL");
+#if defined(IPV6_UNICAST_HOPS)
else if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6,
IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)))
err(1, "set IPv6 unicast hops");
+#else
+ else if (af == AF_INET6)
+ errx(1, "can't set IPv6 unicast hops (unavailable)");
+#endif
}
if (minttl != -1) {
+#if defined(IP_MINTTL)
if (af == AF_INET && setsockopt(s, IPPROTO_IP,
IP_MINTTL, &minttl, sizeof(minttl)))
err(1, "set IP min TTL");
+#else
+ if (af == AF_INET)
+ errx(1, "can't set IP min TTL (unavailable)");
+#endif
+#if defined(IPV6_MINHOPCOUNT)
else if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6,
IPV6_MINHOPCOUNT, &minttl, sizeof(minttl)))
err(1, "set IPv6 min hop count");
+#else
+ else if (af == AF_INET6)
+ errx(1, "can't set IPv6 min hop count (unavailable)");
+#endif
}
}
@@ -1580,6 +1647,7 @@ process_tos_opt(char *s, int *val)
{ "cs7", IPTOS_DSCP_CS7 },
{ "ef", IPTOS_DSCP_EF },
{ "inetcontrol", IPTOS_PREC_INTERNETCONTROL },
+ { "lowcost", IPTOS_LOWCOST },
{ "lowdelay", IPTOS_LOWDELAY },
{ "netcontrol", IPTOS_PREC_NETCONTROL },
{ "reliability", IPTOS_RELIABILITY },
@@ -1741,6 +1809,9 @@ report_sock(const char *msg, const struc
void
help(void)
{
+# if defined(DEBIAN_VERSION)
+ fprintf(stderr, "OpenBSD netcat (Debian patchlevel " DEBIAN_VERSION ")\n");
+# endif
usage(0);
fprintf(stderr, "\tCommand Summary:\n\
\t-4 Use IPv4\n\
@@ -1783,7 +1854,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");
- exit(1);
+ exit(0);
}
void
--- a/socks.c
+++ b/socks.c
@@ -38,7 +38,7 @@
#include <string.h>
#include <unistd.h>
#include <resolv.h>
-#include <readpassphrase.h>
+#include <bsd/readpassphrase.h>
#include "atomicio.h"
#define SOCKS_PORT "1080"
@@ -217,11 +217,11 @@ socks_connect(const char *host, const ch
buf[2] = SOCKS_NOAUTH;
cnt = atomicio(vwrite, proxyfd, buf, 3);
if (cnt != 3)
- err(1, "write failed (%zu/3)", cnt);
+ err(1, "write failed (%zu/3)", (size_t)cnt);
cnt = atomicio(read, proxyfd, buf, 2);
if (cnt != 2)
- err(1, "read failed (%zu/3)", cnt);
+ err(1, "read failed (%zu/3)", (size_t)cnt);
if (buf[1] == SOCKS_NOMETHOD)
errx(1, "authentication method negotiation failed");
@@ -270,11 +270,11 @@ socks_connect(const char *host, const ch
cnt = atomicio(vwrite, proxyfd, buf, wlen);
if (cnt != wlen)
- err(1, "write failed (%zu/%zu)", cnt, wlen);
+ err(1, "write failed (%zu/%zu)", (size_t)cnt, (size_t)wlen);
cnt = atomicio(read, proxyfd, buf, 4);
if (cnt != 4)
- err(1, "read failed (%zu/4)", cnt);
+ err(1, "read failed (%zu/4)", (size_t)cnt);
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
case SOCKS_IPV4:
cnt = atomicio(read, proxyfd, buf + 4, 6);
if (cnt != 6)
- err(1, "read failed (%zu/6)", cnt);
+ err(1, "read failed (%zu/6)", (size_t)cnt);
break;
case SOCKS_IPV6:
cnt = atomicio(read, proxyfd, buf + 4, 18);
if (cnt != 18)
- err(1, "read failed (%zu/18)", cnt);
+ err(1, "read failed (%zu/18)", (size_t)cnt);
break;
default:
errx(1, "connection failed, unsupported address type");
@@ -308,11 +308,11 @@ socks_connect(const char *host, const ch
cnt = atomicio(vwrite, proxyfd, buf, wlen);
if (cnt != wlen)
- err(1, "write failed (%zu/%zu)", cnt, wlen);
+ err(1, "write failed (%zu/%zu)", (size_t)cnt, (size_t)wlen);
cnt = atomicio(read, proxyfd, buf, 8);
if (cnt != 8)
- err(1, "read failed (%zu/8)", cnt);
+ err(1, "read failed (%zu/8)", (size_t)cnt);
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
/* Try to be sane about numeric IPv6 addresses */
if (strchr(host, ':') != NULL) {
- r = snprintf(buf, sizeof(buf),
+ r = snprintf((char*)buf, sizeof(buf),
"CONNECT [%s]:%d HTTP/1.0\r\n",
host, ntohs(serverport));
} else {
- r = snprintf(buf, sizeof(buf),
+ r = snprintf((char*)buf, sizeof(buf),
"CONNECT %s:%d HTTP/1.0\r\n",
host, ntohs(serverport));
}
if (r == -1 || (size_t)r >= sizeof(buf))
errx(1, "hostname too long");
- r = strlen(buf);
+ r = strlen((char*)buf);
cnt = atomicio(vwrite, proxyfd, buf, r);
if (cnt != r)
- err(1, "write failed (%zu/%d)", cnt, r);
+ err(1, "write failed (%zu/%d)", (size_t)cnt, (int)r);
if (authretry > 1) {
char proxypass[256];
@@ -348,20 +348,20 @@ socks_connect(const char *host, const ch
getproxypass(proxyuser, proxyhost,
proxypass, sizeof proxypass);
- r = snprintf(buf, sizeof(buf), "%s:%s",
+ r = snprintf((char*)buf, sizeof(buf), "%s:%s",
proxyuser, proxypass);
explicit_bzero(proxypass, sizeof proxypass);
if (r == -1 || (size_t)r >= sizeof(buf) ||
- b64_ntop(buf, strlen(buf), resp,
+ b64_ntop(buf, strlen((char*)buf), resp,
sizeof(resp)) == -1)
errx(1, "Proxy username/password too long");
- 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))
errx(1, "Proxy auth response too long");
- r = strlen(buf);
+ r = strlen((char*)buf);
if ((cnt = atomicio(vwrite, proxyfd, buf, r)) != r)
- err(1, "write failed (%zu/%d)", cnt, r);
+ err(1, "write failed (%zu/%d)", (size_t)cnt, r);
explicit_bzero(proxypass, sizeof proxypass);
explicit_bzero(buf, sizeof buf);
}
@@ -371,22 +371,22 @@ socks_connect(const char *host, const ch
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) {
if (authretry > 1) {
fprintf(stderr, "Proxy authentication "
"failed\n");
}
close(proxyfd);
goto again;
- } else if (strncmp(buf, "HTTP/1.0 200 ", 12) != 0 &&
- strncmp(buf, "HTTP/1.1 200 ", 12) != 0)
+ } else if (strncmp((char*)buf, "HTTP/1.0 200 ", 12) != 0 &&
+ strncmp((char*)buf, "HTTP/1.1 200 ", 12) != 0)
errx(1, "Proxy error: \"%s\"", buf);
/* Headers continue until we hit an empty line */
for (r = 0; r < HTTP_MAXHDRS; r++) {
- proxy_read_line(proxyfd, buf, sizeof(buf));
+ proxy_read_line(proxyfd, (char*)buf, sizeof(buf));
if (*buf == '\0')
break;
}

143
quit-timer.patch Normal file
View File

@ -0,0 +1,143 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:16:04 +0800
Subject: quit timer
---
nc.1 | 10 ++++++++++
netcat.c | 50 +++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 51 insertions(+), 9 deletions(-)
--- a/nc.1
+++ b/nc.1
@@ -41,6 +41,7 @@
.Op Fl O Ar length
.Op Fl P Ar proxy_username
.Op Fl p Ar source_port
+.Op Fl q Ar seconds
.Op Fl s Ar source
.Op Fl T Ar keyword
.Op Fl V Ar rtable
@@ -167,6 +168,15 @@ Proxy authentication is only supported f
Specify the source port
.Nm
should use, subject to privilege restrictions and availability.
+.It Fl q Ar seconds
+after EOF on stdin, wait the specified number of
+.Ar seconds
+and then quit. If
+.Ar seconds
+is negative, wait forever (default). Specifying a non-negative
+.Ar seconds
+implies
+.Fl N .
.It Fl r
Choose source and/or destination ports randomly
instead of sequentially within a range or in the order that the system
--- a/netcat.c
+++ b/netcat.c
@@ -139,6 +139,7 @@ int Nflag; /* shutdown() network soc
int nflag; /* Don't do name look up */
char *Pflag; /* Proxy username */
char *pflag; /* Localport flag */
+int qflag = -1; /* Quit after some secs */
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);
+static void quit();
+
int
main(int argc, char *argv[])
{
@@ -256,9 +259,9 @@ main(int argc, char *argv[])
while ((ch = getopt(argc, argv,
# if defined(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
- "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
!= -1) {
switch (ch) {
@@ -350,6 +353,13 @@ main(int argc, char *argv[])
case 'p':
pflag = optarg;
break;
+ case 'q':
+ qflag = strtonum(optarg, INT_MIN, INT_MAX, &errstr);
+ if (errstr)
+ errx(1, "quit timer %s: %s", errstr, optarg);
+ if (qflag >= 0)
+ Nflag = 1;
+ break;
# if defined(TLS)
case 'R':
tls_cachanged = 1;
@@ -1319,15 +1329,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 &&
- stdinbufpos == 0 && netinbufpos == 0)
- return;
+ stdinbufpos == 0 && netinbufpos == 0) {
+ if (qflag <= 0)
+ return;
+ goto delay_exit;
+ }
/* both outputs are gone, we can't continue */
- if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1)
- return;
+ if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) {
+ if (qflag <= 0)
+ return;
+ goto delay_exit;
+ }
/* listen and net in gone, queues empty, done */
if (lflag && pfd[POLL_NETIN].fd == -1 &&
- stdinbufpos == 0 && netinbufpos == 0)
- return;
+ stdinbufpos == 0 && netinbufpos == 0) {
+ if (qflag <= 0)
+ return;
+delay_exit:
+ close(net_fd);
+ signal(SIGALRM, quit);
+ alarm(qflag);
+ }
/* poll */
num_fds = poll(pfd, 4, timeout);
@@ -2052,6 +2074,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)
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 [destination] [port]\n");
if (ret)
exit(1);
}
+
+/*
+ * quit()
+ * handler for a "-q" timeout (exit 0 instead of 1)
+ */
+static void quit()
+{
+ exit(0);
+}

192
send-crlf.patch Normal file
View File

@ -0,0 +1,192 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 14:57:45 +0800
Subject: send crlf
---
nc.1 | 9 +++++--
netcat.c | 74 ++++++++++++++++++++++++++++++++++-----------------------------
2 files changed, 48 insertions(+), 35 deletions(-)
--- a/nc.1
+++ b/nc.1
@@ -33,7 +33,7 @@
.Nd arbitrary TCP and UDP connections and listens
.Sh SYNOPSIS
.Nm nc
-.Op Fl 46DdFhklNnrStUuvz
+.Op Fl 46CDdFhklNnrStUuvz
.Op Fl I Ar length
.Op Fl i Ar interval
.Op Fl M Ar ttl
@@ -92,6 +92,11 @@ The options are as follows:
Use IPv4 addresses only.
.It Fl 6
Use IPv6 addresses only.
+.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
+feed characters that are already preceded with a carriage return (CR)
+are not translated. Received data is not affected.
.It Fl D
Enable debugging on the socket.
.It Fl d
@@ -377,7 +382,7 @@ More complicated examples can be built u
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
HELO host.example.com
MAIL FROM:\*(Ltuser@host.example.com\*(Gt
RCPT TO:\*(Ltuser2@host.example.com\*(Gt
--- a/netcat.c
+++ b/netcat.c
@@ -166,6 +166,8 @@ char *tls_expecthash; /* required hash
char *tls_ciphers; /* TLS ciphers */
char *tls_protocols; /* TLS protocols */
FILE *Zflag; /* file to save peer cert */
+# else
+int Cflag = 0; /* CRLF line-ending */
# endif
int recvcount, recvlimit;
@@ -215,7 +217,7 @@ ssize_t fillbuf(int, unsigned char *, si
void tls_setup_client(struct tls *, int, char *);
struct tls *tls_setup_server(struct tls *, int, char *);
# 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
@@ -256,7 +258,7 @@ main(int argc, char *argv[])
# if defined(TLS)
"46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
# 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
!= -1) {
switch (ch) {
@@ -286,6 +288,10 @@ main(int argc, char *argv[])
case 'c':
usetls = 1;
break;
+# else
+ case 'C':
+ Cflag = 1;
+ break;
# endif
case 'd':
dflag = 1;
@@ -1323,12 +1329,6 @@ readwrite(int net_fd)
stdinbufpos == 0 && netinbufpos == 0)
return;
- /* help says -i is for "wait between lines sent". We read and
- * write arbitrary amounts of data, and we don't want to start
- * scanning for newlines, so this is as good as it gets */
- if (iflag)
- sleep(iflag);
-
/* poll */
num_fds = poll(pfd, 4, timeout);
@@ -1408,7 +1408,7 @@ readwrite(int net_fd)
pfd[POLL_NETOUT].events = POLLOUT;
else
# else
- &stdinbufpos);
+ &stdinbufpos, (iflag || Cflag) ? 1 : 0);
# endif
if (ret == -1)
pfd[POLL_NETOUT].fd = -1;
@@ -1467,7 +1467,7 @@ readwrite(int net_fd)
pfd[POLL_STDOUT].events = POLLOUT;
else
# else
- &netinbufpos);
+ &netinbufpos, 0);
# endif
if (ret == -1)
pfd[POLL_STDOUT].fd = -1;
@@ -1493,33 +1493,40 @@ readwrite(int net_fd)
}
ssize_t
-# if defined(TLS)
-drainbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
-# else
-drainbuf(int fd, unsigned char *buf, size_t *bufpos)
-# endif
+drainbuf(int fd, unsigned char *buf, size_t *bufpos, int oneline)
{
- ssize_t n;
+ ssize_t n, r;
ssize_t adjust;
+ unsigned char *lf = NULL;
-# if defined(TLS)
- if (tls) {
- n = tls_write(tls, buf, *bufpos);
- if (n == -1)
- errx(1, "tls write failed (%s)", tls_error(tls));
- } else {
-# endif
- n = write(fd, buf, *bufpos);
- /* don't treat EAGAIN, EINTR as error */
- if (n == -1 && (errno == EAGAIN || errno == EINTR))
-# if defined(TLS)
- n = TLS_WANT_POLLOUT;
- }
-# else
- n = -2;
-# endif
+ if (oneline)
+ lf = memchr(buf, '\n', *bufpos);
+ if (lf == NULL) {
+ n = *bufpos;
+ oneline = 0;
+ }
+ else if (Cflag && (lf == buf || buf[lf - buf - 1] != '\r')) {
+ n = lf - buf;
+ oneline = 2;
+ }
+ else
+ n = lf - buf + 1;
+ if (n > 0)
+ n = write(fd, buf, n);
+
+ /* don't treat EAGAIN, EINTR as error */
+ if (n == -1 && (errno == EAGAIN || errno == EINTR))
+ n = -2;
+ if (oneline == 2 && n >= 0)
+ n++;
if (n <= 0)
return n;
+
+ if (oneline == 2 && (r = atomicio(vwrite, fd, "\r\n", 2)) != 2)
+ err(1, "write failed (%zu/2)", r);
+ if (oneline > 0 && iflag)
+ sleep(iflag);
+
/* adjust buffer */
adjust = *bufpos - n;
if (adjust > 0)
@@ -2029,6 +2036,7 @@ help(void)
fprintf(stderr, "\tCommand Summary:\n\
\t-4 Use IPv4\n\
\t-6 Use IPv6\n\
+ \t-C Send CRLF as line-ending\n\
\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
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] "
"[-w timeout]\n"

View File

@ -0,0 +1,49 @@
From: Aron Xu <aron@debian.org>
Date: Tue, 14 Feb 2012 23:02:00 +0800
Subject: serialized handling multiple clients
---
netcat.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
--- a/netcat.c
+++ b/netcat.c
@@ -707,7 +707,10 @@ main(int argc, char *argv[])
s = unix_bind(host, 0);
else
s = unix_listen(host);
- }
+ } else
+ s = local_listen(host, uport, hints);
+ if (s < 0)
+ err(1, NULL);
# if defined(TLS)
if (usetls) {
@@ -721,13 +724,6 @@ main(int argc, char *argv[])
# endif
/* Allow only one connection at a time, but stay alive. */
for (;;) {
- if (family != AF_UNIX) {
- if (s != -1)
- close(s);
- s = local_listen(host, uport, hints);
- }
- if (s < 0)
- 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");
}
- if (!kflag)
+ if (!kflag) {
+ if (s != -1)
+ close(s);
break;
+ }
}
} else if (family == AF_UNIX) {
ret = 0;

View File

@ -0,0 +1,101 @@
From: Thomas Habets <habets@google.com>
Date: Sat, 18 Feb 2017 21:07:22 +0000
Subject: Set TCP MD5SIG correctly for client connections
---
netcat.c | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
--- 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)
+# include <bsd/readpassphrase.h>
+#endif
#ifndef IPTOS_LOWDELAY
# define IPTOS_LOWDELAY 0x10
@@ -175,6 +178,9 @@ FILE *Zflag; /* file to save peer ce
int Cflag = 0; /* CRLF line-ending */
# endif
+# if defined(TCP_MD5SIG) && defined(TCP_MD5SIG_MAXKEYLEN)
+char Sflag_password[TCP_MD5SIG_MAXKEYLEN];
+# endif
int recvcount, recvlimit;
int timeout = -1;
int family = AF_UNSPEC;
@@ -205,7 +211,7 @@ int udptest(int);
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)
int process_tls_opt(char *, int *);
@@ -458,7 +464,10 @@ main(int argc, char *argv[])
break;
# endif
case 'S':
-# if defined(TCP_MD5SIG)
+# if defined(TCP_MD5SIG) && 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");
@@ -1169,7 +1178,7 @@ remote_connect(const char *host, const c
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
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)
@@ -1855,9 +1864,10 @@ udptest(int s)
}
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;
# if defined(SO_BROADCAST)
if (bflag) {
@@ -1868,10 +1878,17 @@ set_common_sockopts(int s, int af)
err(1, NULL);
}
# endif
-# if defined(TCP_MD5SIG)
+# if defined(TCP_MD5SIG) && defined(TCP_MD5SIG_MAXKEYLEN)
if (Sflag) {
+ 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)
+ &sig, sizeof(sig)) == -1)
err(1, NULL);
}
# endif

56
udp-scan-timeout.patch Normal file
View File

@ -0,0 +1,56 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:29:37 +0800
Subject: udp scan timeout
---
netcat.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
--- a/netcat.c
+++ b/netcat.c
@@ -129,6 +129,8 @@
#define CONNECTION_FAILED 1
#define CONNECTION_TIMEOUT 2
+#define UDP_SCAN_TIMEOUT 3 /* Seconds */
+
/* 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)
int
udptest(int s)
{
- int i, ret;
+ int i, t;
- for (i = 0; i <= 3; i++) {
- if (write(s, "X", 1) == 1)
- ret = 1;
- else
- ret = -1;
+ if ((write(s, "X", 1) != 1) ||
+ ((write(s, "X", 1) != 1) && (errno == ECONNREFUSED)))
+ return -1;
+
+ /* Give the remote host some time to reply. */
+ for (i = 0, t = (timeout == -1) ? UDP_SCAN_TIMEOUT : (timeout / 1000);
+ i < t; i++) {
+ sleep(1);
+ if ((write(s, "X", 1) != 1) && (errno == ECONNREFUSED))
+ return -1;
}
- return ret;
+ return 1;
}
void

View File

@ -0,0 +1,106 @@
From: Guilhem Moulin <guilhem@debian.org>
Date: Mon, 22 Oct 2018 04:50:54 +0200
Subject: use -s/-p flags to specify listen address
---
nc.1 | 18 ++++++++++++++----
netcat.c | 49 +++++++++++++++++++++++++++++--------------------
2 files changed, 43 insertions(+), 24 deletions(-)
--- a/nc.1
+++ b/nc.1
@@ -143,8 +143,20 @@ multiple hosts.
.It Fl l
Listen for an incoming connection rather than initiating a
connection to a remote host.
-Cannot be used together with any of the options
-.Fl psxz .
+The
+.Ar destination
+and
+.Ar port
+to listen on can be specified either as non-optional arguments, or with
+options
+.Fl s
+and
+.Fl p
+respectively.
+Cannot be used together with
+.Fl x
+or
+.Fl z .
Additionally, any timeouts specified with the
.Fl w
option are ignored.
@@ -194,8 +206,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
-.Fl l
-or
.Fl x .
.It Fl T Ar keyword
Change the IPv4 TOS/IPv6 traffic class value.
--- a/netcat.c
+++ b/netcat.c
@@ -509,31 +509,40 @@ 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 (dccpflag)
- errx(1, "cannot use -Z and -U");
-# endif
- host = argv[0];
- uport = NULL;
- } else if (!argv[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);
- uport = &argv[0];
- host = NULL;
- } else if (argv[0] && argv[1]) {
+ if (argc == 0 && lflag) {
+ uport = &pflag;
+ host = sflag;
+ } else if (argc == 1 && !pflag && !sflag) {
+ if (family == AF_UNIX) {
+ host = argv[0];
+ uport = NULL;
+ } else if (lflag) {
+ host = NULL;
+ uport = argv;
+ }
+ } else if (argc >= 2) {
+ if (lflag && (pflag || sflag || argc > 2))
+ usage(1); /* conflict */
host = argv[0];
uport = &argv[1];
} else
usage(1);
+ if (family == AF_UNIX) {
+# if defined(IPPROTO_DCCP) && defined(SOCK_DCCP)
+ if (dccpflag)
+ errx(1, "cannot use -Z and -U");
+# endif
+ if (uport && *uport)
+ errx(1, "cannot use port with -U");
+ if (!host)
+ errx(1, "missing socket pathname");
+ } else if (!uport || !*uport)
+ errx(1, "missing port number");
+
+ if (lflag && zflag)
+ errx(1, "cannot use -z and -l");
+
# if defined(TLS)
if (usetls) {
if (Cflag && unveil(Cflag, "r") == -1)