749 lines
20 KiB
Diff
749 lines
20 KiB
Diff
|
From: Guilhem Moulin <guilhem@debian.org>
|
||
|
Date: Fri, 09 Jun 2017 13:21:23 +0200
|
||
|
Subject: compile without TLS support
|
||
|
|
||
|
tls.h isn't available in libsd-dev, and -C is already taken for
|
||
|
CRLF line-ending in the Debian-specific patches.
|
||
|
|
||
|
---
|
||
|
Makefile | 2
|
||
|
nc.1 | 63 -----------------------
|
||
|
netcat.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------
|
||
|
3 files changed, 144 insertions(+), 87 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
|
||
|
@@ -101,20 +95,10 @@ to use IPv4 addresses only.
|
||
|
Forces
|
||
|
.Nm
|
||
|
to use IPv6 addresses only.
|
||
|
-.It Fl C Ar certfile
|
||
|
-Specifies the filename from which the public key part of the TLS
|
||
|
-certificate is loaded, in PEM format.
|
||
|
-May only be used with TLS.
|
||
|
-.It Fl c
|
||
|
-If using a TCP socket to connect or listen, use TLS.
|
||
|
-Illegal if not using TCP sockets.
|
||
|
.It Fl D
|
||
|
Enable debugging on the socket.
|
||
|
.It Fl d
|
||
|
Do not attempt to read from stdin.
|
||
|
-.It Fl e Ar name
|
||
|
-Specify the name that must be present in the peer certificate when using TLS.
|
||
|
-Illegal if not using TLS.
|
||
|
.It Fl F
|
||
|
Pass the first connected socket using
|
||
|
.Xr sendmsg 2
|
||
|
@@ -130,11 +114,6 @@ using the
|
||
|
.Xr ssh_config 5
|
||
|
.Cm ProxyUseFdpass
|
||
|
option).
|
||
|
-.It Fl H Ar hash
|
||
|
-Specifies the required hash string of the peer certificate when using TLS.
|
||
|
-The string format required is that used by
|
||
|
-.Xr tls_peer_cert_hash 3 .
|
||
|
-Illegal if not using TLS, and may not be used with -T noverify.
|
||
|
.It Fl h
|
||
|
Prints out
|
||
|
.Nm
|
||
|
@@ -144,10 +123,6 @@ Specifies the size of the TCP receive bu
|
||
|
.It Fl i Ar interval
|
||
|
Specifies a delay time interval between lines of text sent and received.
|
||
|
Also causes a delay time between connections to multiple ports.
|
||
|
-.It Fl K Ar keyfile
|
||
|
-Specifies the filename from which the private key
|
||
|
-is loaded in PEM format.
|
||
|
-May only be used with TLS.
|
||
|
.It Fl k
|
||
|
Forces
|
||
|
.Nm
|
||
|
@@ -188,12 +163,6 @@ Do not do any DNS or service lookups on
|
||
|
hostnames or ports.
|
||
|
.It Fl O Ar length
|
||
|
Specifies the size of the TCP send buffer.
|
||
|
-.It Fl o Ar staplefile
|
||
|
-Specifies the filename from which to load data to be stapled
|
||
|
-during the TLS handshake.
|
||
|
-The file is expected to contain an OCSP response from an OCSP server in
|
||
|
-DER format.
|
||
|
-May only be used with TLS and when a certificate is being used.
|
||
|
.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.
|
||
|
@@ -202,12 +171,6 @@ Proxy authentication is only supported f
|
||
|
Specifies the source port
|
||
|
.Nm
|
||
|
should use, subject to privilege restrictions and availability.
|
||
|
-.It Fl R Ar CAfile
|
||
|
-Specifies the filename from which the root CA bundle for certificate
|
||
|
-verification is loaded, in PEM format.
|
||
|
-Illegal if not using TLS.
|
||
|
-The default is
|
||
|
-.Pa /etc/ssl/cert.pem .
|
||
|
.It Fl r
|
||
|
Specifies that source and/or destination ports should be chosen randomly
|
||
|
instead of sequentially within a range or in the order that the system
|
||
|
@@ -224,24 +187,7 @@ It is an error to use this option in con
|
||
|
.Fl l
|
||
|
option.
|
||
|
.It Fl T Ar keyword
|
||
|
-Change IPv4 TOS value or TLS options.
|
||
|
-For TLS options
|
||
|
-.Ar keyword
|
||
|
-may be one of
|
||
|
-.Ar tlsall ;
|
||
|
-which allows the use of all supported TLS protocols and ciphers,
|
||
|
-.Ar noverify ;
|
||
|
-which disables certificate verification;
|
||
|
-.Ar noname ,
|
||
|
-which disables certificate name checking;
|
||
|
-.Ar clientcert ,
|
||
|
-which requires a client certificate on incoming connections; or
|
||
|
-.Ar muststaple ,
|
||
|
-which requires the peer to provide a valid stapled OCSP response
|
||
|
-with the handshake.
|
||
|
-It is illegal to specify TLS options if not using TLS.
|
||
|
-.Pp
|
||
|
-For IPv4 TOS value
|
||
|
+Change IPv4 TOS value.
|
||
|
.Ar keyword
|
||
|
may be one of
|
||
|
.Ar critical ,
|
||
|
@@ -483,11 +429,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.google.ca, and negotiate TLS.
|
||
|
-Check for a different name in the certificate for validation.
|
||
|
-.Pp
|
||
|
-.Dl $ nc -v -c -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 <string.h>
|
||
|
#include <time.h>
|
||
|
#include <unistd.h>
|
||
|
-#include <tls.h>
|
||
|
+#ifdef TLS
|
||
|
+# include <tls.h>
|
||
|
+#endif
|
||
|
#include <bsd/stdlib.h>
|
||
|
#include <bsd/string.h>
|
||
|
#include "atomicio.h"
|
||
|
@@ -112,13 +114,15 @@
|
||
|
#define POLL_NETIN 2
|
||
|
#define POLL_STDOUT 3
|
||
|
#define BUFSIZE 16384
|
||
|
-#define DEFAULT_CA_FILE "/etc/ssl/cert.pem"
|
||
|
+#ifdef TLS
|
||
|
+# define DEFAULT_CA_FILE "/etc/ssl/cert.pem"
|
||
|
|
||
|
-#define TLS_ALL (1 << 1)
|
||
|
-#define TLS_NOVERIFY (1 << 2)
|
||
|
-#define TLS_NONAME (1 << 3)
|
||
|
-#define TLS_CCERT (1 << 4)
|
||
|
-#define TLS_MUSTSTAPLE (1 << 5)
|
||
|
+# define TLS_ALL (1 << 1)
|
||
|
+# define TLS_NOVERIFY (1 << 2)
|
||
|
+# define TLS_NONAME (1 << 3)
|
||
|
+# define TLS_CCERT (1 << 4)
|
||
|
+# define TLS_MUSTSTAPLE (1 << 5)
|
||
|
+#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 */
|
||
|
char *Cflag; /* Public cert file */
|
||
|
char *Kflag; /* Private key file */
|
||
|
@@ -153,6 +158,7 @@ int tls_cachanged; /* Using non-defau
|
||
|
int TLSopt; /* TLS options */
|
||
|
char *tls_expectname; /* required name in peer cert */
|
||
|
char *tls_expecthash; /* required hash of peer cert */
|
||
|
+# endif
|
||
|
|
||
|
int timeout = -1;
|
||
|
int family = AF_UNSPEC;
|
||
|
@@ -165,10 +171,16 @@ void atelnet(int, unsigned char *, unsig
|
||
|
void build_ports(char *);
|
||
|
void help(void);
|
||
|
int local_listen(char *, 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 *);
|
||
|
@@ -178,14 +190,23 @@ int unix_connect(char *);
|
||
|
int unix_listen(char *);
|
||
|
void set_common_sockopts(int, int);
|
||
|
int map_tos(char *, int *);
|
||
|
+# if defined(TLS)
|
||
|
int map_tls(char *, int *);
|
||
|
+# endif
|
||
|
void report_connect(const struct sockaddr *, socklen_t, char *);
|
||
|
+# if defined(TLS)
|
||
|
void report_tls(struct tls *tls_ctx, char * host, char *tls_expectname);
|
||
|
+# 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[])
|
||
|
@@ -200,8 +221,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
|
||
|
|
||
|
ret = 1;
|
||
|
socksv = 5;
|
||
|
@@ -212,7 +235,11 @@ main(int argc, char *argv[])
|
||
|
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:X:x:z")) != -1) {
|
||
|
+# else
|
||
|
+ "46DdFhI:i:klM:m:NnO:P:p:rSs:T:tUuV:vw:X:x:z")) != -1) {
|
||
|
+# endif
|
||
|
switch (ch) {
|
||
|
case '4':
|
||
|
family = AF_INET;
|
||
|
@@ -233,24 +260,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;
|
||
|
@@ -259,9 +292,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;
|
||
|
@@ -290,10 +325,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;
|
||
|
@@ -348,9 +385,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;
|
||
|
@@ -363,8 +402,10 @@ main(int argc, char *argv[])
|
||
|
errno = 0;
|
||
|
if (map_tos(optarg, &Tflag))
|
||
|
break;
|
||
|
+# if defined(TLS)
|
||
|
if (map_tls(optarg, &TLSopt))
|
||
|
break;
|
||
|
+# endif
|
||
|
if (strlen(optarg) > 1 && optarg[0] == '0' &&
|
||
|
optarg[1] == 'x')
|
||
|
Tflag = (int)strtol(optarg, NULL, 16);
|
||
|
@@ -372,7 +413,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);
|
||
|
@@ -411,12 +456,15 @@ main(int argc, char *argv[])
|
||
|
|
||
|
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)
|
||
|
@@ -433,6 +481,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) {
|
||
|
@@ -499,6 +548,7 @@ main(int argc, char *argv[])
|
||
|
proxyhints.ai_flags |= AI_NUMERICHOST;
|
||
|
}
|
||
|
|
||
|
+# if defined(TLS)
|
||
|
if (usetls) {
|
||
|
if (Pflag) {
|
||
|
if (pledge("stdio inet dns tty rpath", NULL) == -1)
|
||
|
@@ -544,8 +594,11 @@ main(int argc, char *argv[])
|
||
|
} else if (pledge("stdio inet dns", NULL) == -1)
|
||
|
err(1, "pledge");
|
||
|
}
|
||
|
+# endif
|
||
|
if (lflag) {
|
||
|
+# if defined(TLS)
|
||
|
struct tls *tls_cctx = NULL;
|
||
|
+# endif
|
||
|
int connfd;
|
||
|
ret = 0;
|
||
|
|
||
|
@@ -556,6 +609,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)
|
||
|
@@ -564,6 +618,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)
|
||
|
@@ -575,7 +630,11 @@ main(int argc, char *argv[])
|
||
|
* receive datagrams from multiple socket pairs.
|
||
|
*/
|
||
|
if (uflag && kflag)
|
||
|
+# if defined(TLS)
|
||
|
readwrite(s, NULL);
|
||
|
+# else
|
||
|
+ readwrite(s);
|
||
|
+# endif
|
||
|
/*
|
||
|
* For UDP and not -k, we will use recvfrom() initially
|
||
|
* to wait for a caller, then use the regular functions
|
||
|
@@ -600,7 +659,11 @@ main(int argc, char *argv[])
|
||
|
if (vflag)
|
||
|
report_connect((struct sockaddr *)&z, len, NULL);
|
||
|
|
||
|
+# if defined(TLS)
|
||
|
readwrite(s, NULL);
|
||
|
+# else
|
||
|
+ readwrite(s);
|
||
|
+# endif
|
||
|
} else {
|
||
|
len = sizeof(cliaddr);
|
||
|
connfd = accept4(s, (struct sockaddr *)&cliaddr,
|
||
|
@@ -612,6 +675,7 @@ main(int argc, char *argv[])
|
||
|
if (vflag)
|
||
|
report_connect((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);
|
||
|
@@ -622,6 +686,9 @@ main(int argc, char *argv[])
|
||
|
tls_free(tls_cctx);
|
||
|
tls_cctx = NULL;
|
||
|
}
|
||
|
+# else
|
||
|
+ readwrite(connfd);
|
||
|
+# endif
|
||
|
close(connfd);
|
||
|
}
|
||
|
if (family != AF_UNIX)
|
||
|
@@ -639,7 +706,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
|
||
|
ret = 1;
|
||
|
@@ -659,6 +730,7 @@ main(int argc, char *argv[])
|
||
|
if (s != -1)
|
||
|
close(s);
|
||
|
|
||
|
+# if defined(TLS)
|
||
|
if (usetls) {
|
||
|
if ((tls_ctx = tls_client()) == NULL)
|
||
|
errx(1, "tls client creation failed");
|
||
|
@@ -666,6 +738,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,
|
||
|
@@ -703,6 +776,7 @@ main(int argc, char *argv[])
|
||
|
}
|
||
|
if (Fflag)
|
||
|
fdpass(s);
|
||
|
+# if defined(TLS)
|
||
|
else {
|
||
|
if (usetls)
|
||
|
tls_setup_client(tls_ctx, s, host);
|
||
|
@@ -714,13 +788,19 @@ main(int argc, char *argv[])
|
||
|
tls_ctx = NULL;
|
||
|
}
|
||
|
}
|
||
|
+# else
|
||
|
+ else if (!zflag)
|
||
|
+ readwrite(s);
|
||
|
+# endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (s != -1)
|
||
|
close(s);
|
||
|
|
||
|
+# if defined(TLS)
|
||
|
tls_config_free(tls_cfg);
|
||
|
+# endif
|
||
|
|
||
|
exit(ret);
|
||
|
}
|
||
|
@@ -759,6 +839,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 *))
|
||
|
{
|
||
|
@@ -840,6 +921,7 @@ tls_setup_server(struct tls *tls_ctx, in
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
+# endif
|
||
|
|
||
|
/*
|
||
|
* unix_connect()
|
||
|
@@ -1052,7 +1134,11 @@ local_listen(char *host, char *port, str
|
||
|
* 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;
|
||
|
@@ -1152,12 +1238,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)
|
||
|
@@ -1169,12 +1260,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)
|
||
|
@@ -1186,12 +1282,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) {
|
||
|
@@ -1212,12 +1313,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)
|
||
|
@@ -1241,19 +1347,29 @@ 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);
|
||
|
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 */
|
||
|
@@ -1265,19 +1381,29 @@ 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);
|
||
|
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;
|
||
|
@@ -1581,6 +1707,7 @@ map_tos(char *s, int *val)
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
+# if defined(TLS)
|
||
|
int
|
||
|
map_tls(char *s, int *val)
|
||
|
{
|
||
|
@@ -1662,6 +1789,7 @@ report_tls(struct tls * tls_ctx, char *
|
||
|
|
||
|
}
|
||
|
}
|
||
|
+# endif
|
||
|
|
||
|
void
|
||
|
report_connect(const struct sockaddr *sa, socklen_t salen, char *path)
|
||
|
@@ -1704,17 +1832,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\
|
||
|
@@ -1722,14 +1845,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\
|
||
|
@@ -1747,11 +1868,8 @@ 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 timeout] "
|
||
|
"[-X proxy_protocol]\n"
|
||
|
"\t [-x proxy_address[:port]] [destination] [port]\n");
|