main/netcat-openbsd: upgrade to 1.130, disable check(), modernize APKBUILD

This commit is contained in:
Leonardo Arena 2017-04-10 14:38:03 +00:00
parent be30326a67
commit 3a368567d8
14 changed files with 2117 additions and 2852 deletions

View File

@ -0,0 +1,438 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:59:31 +0800
Subject: port to linux with libsd
---
Makefile | 17 ++++++++++--
nc.1 | 4 +--
netcat.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
socks.c | 46 +++++++++++++++----------------
4 files changed, 122 insertions(+), 41 deletions(-)
diff --git a/Makefile b/Makefile
index 150f829..96a6587 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,19 @@
-# $OpenBSD: Makefile,v 1.6 2001/09/02 18:45:41 jakob Exp $
+# $OpenBSD: Makefile,v 1.6 2001/09/02 18:45:41 jakob Exp $
PROG= nc
SRCS= netcat.c atomicio.c socks.c
-.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
diff --git a/nc.1 b/nc.1
index d83cb5c..67cc19f 100644
--- a/nc.1
+++ b/nc.1
@@ -169,9 +169,6 @@ Proxy authentication is only supported for HTTP CONNECT proxies at present.
Specifies the source port
.Nm
should use, subject to privilege restrictions and availability.
-It is an error to use this option in conjunction with the
-.Fl l
-option.
.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
@@ -193,6 +190,7 @@ Change IPv4 TOS value.
may be one of
.Ar critical ,
.Ar inetcontrol ,
+.Ar lowcost ,
.Ar lowdelay ,
.Ar netcontrol ,
.Ar throughput ,
diff --git a/netcat.c b/netcat.c
index 6358539..30591de 100644
--- a/netcat.c
+++ b/netcat.c
@@ -42,6 +42,46 @@
#include <netinet/ip.h>
#include <arpa/telnet.h>
+#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 <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -54,6 +94,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <bsd/stdlib.h>
+#include <bsd/string.h>
#include "atomicio.h"
#ifndef SUN_LEN
@@ -130,7 +172,7 @@ main(int argc, char *argv[])
struct servent *sv;
socklen_t len;
struct sockaddr_storage cliaddr;
- char *proxy;
+ char *proxy = NULL;
const char *errstr, *proxyhost = "", *proxyport = NULL;
struct addrinfo proxyhints;
char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];
@@ -211,10 +253,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;
@@ -249,7 +295,11 @@ main(int argc, char *argv[])
errstr, 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;
@@ -276,6 +326,15 @@ main(int argc, char *argv[])
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 (zflag)
+ errx(1, "cannot use -z and -l");
+ if (pflag)
+ uport=pflag;
+ } else if (!lflag && kflag) {
+ errx(1, "cannot use -k without -l");
} else if (argv[0] && !argv[1]) {
if (!lflag)
usage(1);
@@ -287,14 +346,7 @@ main(int argc, char *argv[])
} else
usage(1);
- 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");
+
/* Get name of temporary socket for unix datagram client */
if ((family == AF_UNIX) && uflag && !lflag) {
@@ -303,8 +355,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;
}
}
@@ -598,16 +650,20 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
res0->ai_protocol)) < 0)
continue;
+# if defined(RT_TABLEID_MAX)
if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE,
&rtableid, sizeof(rtableid)) == -1))
err(1, "setsockopt SO_RTABLE");
+# endif
/* Bind to a local port or source address if specified. */
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 = res0->ai_family;
ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
@@ -707,13 +763,21 @@ local_listen(char *host, char *port, struct addrinfo hints)
res0->ai_protocol)) < 0)
continue;
+# if defined(RT_TABLEID_MAX)
if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE,
&rtableid, sizeof(rtableid)) == -1))
err(1, "setsockopt SO_RTABLE");
+# endif
+ 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, res0->ai_family);
@@ -1134,11 +1198,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)
@@ -1201,6 +1267,7 @@ map_tos(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 },
@@ -1247,6 +1314,9 @@ report_connect(const struct sockaddr *sa, socklen_t salen)
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\
@@ -1278,7 +1348,7 @@ help(void)
\t-x addr[:port]\tSpecify proxy address and port\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
@@ -1286,7 +1356,7 @@ usage(int ret)
{
fprintf(stderr,
"usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n"
- "\t [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n"
+ "\t [-P proxy_username] [-p source_port] [-s source] [-T toskeyword]\n"
"\t [-V rtable] [-w timeout] [-X proxy_protocol]\n"
"\t [-x proxy_address[:port]] [destination] [port]\n");
if (ret)
diff --git a/socks.c b/socks.c
index 1b06e0e..57e4316 100644
--- 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"
@@ -167,11 +167,11 @@ socks_connect(const char *host, const char *port,
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");
@@ -220,23 +220,23 @@ socks_connect(const char *host, const char *port,
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, SOCKS error %d", buf[1]);
switch (buf[3]) {
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");
@@ -256,11 +256,11 @@ socks_connect(const char *host, const char *port,
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, SOCKS error %d", buf[1]);
} else if (socksv == -1) {
@@ -272,39 +272,39 @@ socks_connect(const char *host, const char *port,
/* 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 resp[1024];
proxypass = getproxypass(proxyuser, proxyhost);
- r = snprintf(buf, sizeof(buf), "%s:%s",
+ r = snprintf((char*)buf, sizeof(buf), "%s:%s",
proxyuser, 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);
}
/* Terminate headers */
@@ -312,22 +312,22 @@ socks_connect(const char *host, const char *port,
err(1, "write failed (%zu/2)", cnt);
/* Read status reply */
- proxy_read_line(proxyfd, buf, sizeof(buf));
+ proxy_read_line(proxyfd, (char*)buf, sizeof(buf));
if (proxyuser != NULL &&
- strncmp(buf, "HTTP/1.0 407 ", 12) == 0) {
+ strncmp((char*)buf, "HTTP/1.0 407 ", 12) == 0) {
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;
}
--

View File

@ -0,0 +1,121 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 14:43:56 +0800
Subject: connect timeout
---
netcat.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 75 insertions(+), 2 deletions(-)
diff --git a/netcat.c b/netcat.c
index 30591de..d40e3a5 100644
--- a/netcat.c
+++ b/netcat.c
@@ -113,6 +113,10 @@
#define POLL_STDOUT 3
#define BUFSIZE 16384
+#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 */
@@ -163,6 +167,9 @@ void usage(int);
ssize_t drainbuf(int, unsigned char *, size_t *);
ssize_t fillbuf(int, unsigned char *, size_t *);
+static int connect_with_timeout(int fd, const struct sockaddr *sa,
+ socklen_t salen, int ctimeout);
+
int
main(int argc, char *argv[])
{
@@ -680,11 +687,14 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
set_common_sockopts(s, res0->ai_family);
- if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
+ if ((error = connect_with_timeout(s, res0->ai_addr, res0->ai_addrlen, timeout))== CONNECTION_SUCCESS)
break;
- else if (vflag)
+ else 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");
close(s);
s = -1;
@@ -732,6 +742,69 @@ timeout_connect(int s, const struct sockaddr *name, socklen_t namelen)
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
--

View File

@ -0,0 +1,34 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 14:45:08 +0800
Subject: get sev by name
---
netcat.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/netcat.c b/netcat.c
index d40e3a5..e0ad5c7 100644
--- a/netcat.c
+++ b/netcat.c
@@ -1193,12 +1193,19 @@ atelnet(int nfd, unsigned char *buf, unsigned int size)
void
build_ports(char *p)
{
+ struct servent *sv;
const char *errstr;
char *n;
int hi, lo, cp;
int x = 0;
- if ((n = strchr(p, '-')) != NULL) {
+ sv = getservbyname(p, uflag ? "udp" : "tcp");
+ if (sv) {
+ portlist[0] = calloc(1, PORT_MAX_LEN);
+ if (portlist[0] == NULL)
+ err(1, NULL);
+ snprintf(portlist[0], PORT_MAX_LEN, "%d", ntohs(sv->s_port));
+ } else if ((n = strchr(p, '-')) != NULL) {
*n = '\0';
n++;
--

View File

@ -0,0 +1,173 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 14:57:45 +0800
Subject: send crlf
---
nc.1 | 6 ++++--
netcat.c | 50 ++++++++++++++++++++++++++++++++++++--------------
2 files changed, 40 insertions(+), 16 deletions(-)
diff --git a/nc.1 b/nc.1
index 67cc19f..746d3b6 100644
--- a/nc.1
+++ b/nc.1
@@ -34,7 +34,7 @@
.Sh SYNOPSIS
.Nm nc
.Bk -words
-.Op Fl 46DdFhklNnrStUuvz
+.Op Fl 46CDdFhklNnrStUuvz
.Op Fl I Ar length
.Op Fl i Ar interval
.Op Fl O Ar length
@@ -98,6 +98,8 @@ to use IPv4 addresses only.
Forces
.Nm
to use IPv6 addresses only.
+.It Fl C
+Send CRLF as line-ending.
.It Fl D
Enable debugging on the socket.
.It Fl d
@@ -377,7 +379,7 @@ More complicated examples can be built up when the user knows the format
of requests required by the server.
As another example, an email may be submitted to an SMTP server using:
.Bd -literal -offset indent
-$ nc localhost 25 \*(Lt\*(Lt EOF
+$ nc [\-C] localhost 25 \*(Lt\*(Lt EOF
HELO host.example.com
MAIL FROM:\*(Ltuser@host.example.com\*(Gt
RCPT TO:\*(Ltuser2@host.example.com\*(Gt
diff --git a/netcat.c b/netcat.c
index e0ad5c7..1c90145 100644
--- a/netcat.c
+++ b/netcat.c
@@ -118,6 +118,7 @@
#define CONNECTION_TIMEOUT 2
/* Command Line Options */
+int Cflag = 0; /* CRLF line-ending */
int dflag; /* detached, no stdin */
int Fflag; /* fdpass sock to stdout */
unsigned int iflag; /* Interval Flag */
@@ -164,7 +165,7 @@ void set_common_sockopts(int, int);
int map_tos(char *, int *);
void report_connect(const struct sockaddr *, socklen_t);
void usage(int);
-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 *);
static int connect_with_timeout(int fd, const struct sockaddr *sa,
@@ -194,7 +195,7 @@ main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN);
while ((ch = getopt(argc, argv,
- "46DdFhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) {
+ "46CDdFhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) {
switch (ch) {
case '4':
family = AF_INET;
@@ -322,6 +323,9 @@ main(int argc, char *argv[])
if (Tflag < 0 || Tflag > 255 || errstr || errno)
errx(1, "illegal tos value %s", optarg);
break;
+ case 'C':
+ Cflag = 1;
+ break;
default:
usage(1);
}
@@ -928,12 +932,6 @@ readwrite(int net_fd)
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);
@@ -999,7 +997,7 @@ readwrite(int net_fd)
/* try to write to network */
if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) {
ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf,
- &stdinbufpos);
+ &stdinbufpos, (iflag || Cflag) ? 1 : 0);
if (ret == -1)
pfd[POLL_NETOUT].fd = -1;
/* buffer empty - remove self from polling */
@@ -1034,7 +1032,7 @@ readwrite(int net_fd)
/* try to write to stdout */
if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) {
ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf,
- &netinbufpos);
+ &netinbufpos, 0);
if (ret == -1)
pfd[POLL_STDOUT].fd = -1;
/* buffer empty - remove self from polling */
@@ -1059,17 +1057,40 @@ readwrite(int net_fd)
}
ssize_t
-drainbuf(int fd, unsigned char *buf, size_t *bufpos)
+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 (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);
- n = write(fd, buf, *bufpos);
/* 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)
@@ -1401,6 +1422,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\
@@ -1435,7 +1457,7 @@ void
usage(int ret)
{
fprintf(stderr,
- "usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n"
+ "usage: nc [-46CDdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n"
"\t [-P proxy_username] [-p source_port] [-s source] [-T toskeyword]\n"
"\t [-V rtable] [-w timeout] [-X proxy_protocol]\n"
"\t [-x proxy_address[:port]] [destination] [port]\n");
--

View File

@ -0,0 +1,140 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:16:04 +0800
Subject: quit timer
---
nc.1 | 5 +++++
netcat.c | 52 +++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/nc.1 b/nc.1
index 746d3b6..1ee6887 100644
--- a/nc.1
+++ b/nc.1
@@ -40,6 +40,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 toskeyword
.Op Fl V Ar rtable
@@ -171,6 +172,15 @@ Proxy authentication is only supported for HTTP CONNECT proxies at present.
Specifies 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
Specifies that source and/or destination ports should be chosen randomly
instead of sequentially within a range or in the order that the system
diff --git a/netcat.c b/netcat.c
index 1c90145..7572bb2 100644
--- a/netcat.c
+++ b/netcat.c
@@ -128,6 +128,7 @@ int Nflag; /* shutdown() network socket */
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 */
@@ -171,6 +172,8 @@ ssize_t fillbuf(int, unsigned char *, size_t *);
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[])
{
@@ -195,7 +198,7 @@ main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN);
while ((ch = getopt(argc, argv,
- "46CDdFhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) {
+ "46CDdFhI:i:klNnO:P:p:q:rSs:tT:UuV:vw:X:x:z")) != -1) {
switch (ch) {
case '4':
family = AF_INET;
@@ -248,6 +251,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;
case 'r':
rflag = 1;
break;
@@ -918,18 +928,26 @@ readwrite(int net_fd)
if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1
&& stdinbufpos == 0 && netinbufpos == 0) {
close(net_fd);
- return;
+ 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) {
close(net_fd);
- return;
+ 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) {
close(net_fd);
- return;
+ if (qflag <= 0)
+ return;
+delay_exit:
+ signal(SIGALRM, quit);
+ alarm(qflag);
}
/* poll */
@@ -1436,6 +1454,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 addr\t Local source address\n\
@@ -1458,9 +1477,18 @@ usage(int ret)
{
fprintf(stderr,
"usage: nc [-46CDdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n"
- "\t [-P proxy_username] [-p source_port] [-s source] [-T toskeyword]\n"
- "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n"
+ "\t [-P proxy_username] [-p source_port] [-q seconds] [-s source]\n"
+ "\t [-T toskeyword] [-V rtable] [-w timeout] [-X proxy_protocol]\n"
"\t [-x proxy_address[:port]] [destination] [port]\n");
if (ret)
exit(1);
}
+
+/*
+ * quit()
+ * handler for a "-q" timeout (exit 0 instead of 1)
+ */
+static void quit()
+{
+ exit(0);
+}

View File

@ -0,0 +1,60 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:29:37 +0800
Subject: udp scan timeout
---
netcat.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/netcat.c b/netcat.c
index f971893..9ab507a 100644
--- a/netcat.c
+++ b/netcat.c
@@ -117,6 +117,8 @@
#define CONNECTION_FAILED 1
#define CONNECTION_TIMEOUT 2
+#define UDP_SCAN_TIMEOUT 3 /* Seconds */
+
/* Command Line Options */
int Cflag = 0; /* CRLF line-ending */
int dflag; /* detached, no stdin */
@@ -525,7 +527,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) {
@@ -1298,15 +1300,20 @@ build_ports(char *p)
int
udptest(int s)
{
- int i, ret;
-
- for (i = 0; i <= 3; i++) {
- if (write(s, "X", 1) == 1)
- ret = 1;
- else
- ret = -1;
+ int i, t;
+
+ 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,58 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:38:15 +0800
Subject: verbose numeric port
---
netcat.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/netcat.c b/netcat.c
index 9ab507a..3240a08 100644
--- a/netcat.c
+++ b/netcat.c
@@ -41,6 +41,7 @@
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <arpa/telnet.h>
+#include <arpa/inet.h>
#ifndef IPTOS_LOWDELAY
# define IPTOS_LOWDELAY 0x10
@@ -436,6 +437,18 @@ main(int argc, char *argv[])
s = local_listen(host, uport, hints);
if (s < 0)
err(1, NULL);
+
+ char* local;
+ if (family == AF_INET6
+ local = "0.0.0.0";
+ else if (family == AF_INET)
+ local = ":::";
+ else
+ local = "unknown"
+ fprintf(stderr, "Listening on [%s] (family %d, port %d)\n",
+ host ?: local,
+ family,
+ *uport);
/*
* For UDP and -k, don't connect the socket, let it
* receive datagrams from multiple socket pairs.
@@ -452,14 +465,14 @@ main(int argc, char *argv[])
char buf[16384];
struct sockaddr_storage z;
- len = sizeof(z);
+ len = sizeof(cliaddr);
plen = 2048;
rv = recvfrom(s, buf, plen, MSG_PEEK,
- (struct sockaddr *)&z, &len);
+ (struct sockaddr *)&cliaddr, &len);
if (rv < 0)
err(1, "recvfrom");
- rv = connect(s, (struct sockaddr *)&z, len);
+ rv = connect(s, (struct sockaddr *)&cliaddr, len);
if (rv < 0)
err(1, "connect");
--

View File

@ -0,0 +1,262 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:56:51 +0800
Subject: dccp support
---
nc.1 | 4 ++-
netcat.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 88 insertions(+), 18 deletions(-)
diff --git a/nc.1 b/nc.1
index 1ee6887..fe42909 100644
--- a/nc.1
+++ b/nc.1
@@ -34,7 +34,7 @@
.Sh SYNOPSIS
.Nm nc
.Bk -words
-.Op Fl 46CDdFhklNnrStUuvz
+.Op Fl 46CDdFhklNnrStUuvZz
.Op Fl I Ar length
.Op Fl i Ar interval
.Op Fl O Ar length
@@ -279,6 +279,8 @@ If
.Ar port
is not specified, the well-known port for the proxy protocol is used (1080
for SOCKS, 3128 for HTTPS).
+.It Fl Z
+DCCP mode.
.It Fl z
Specifies that
.Nm
diff --git a/netcat.c b/netcat.c
index 3240a08..f4d85af 100644
--- a/netcat.c
+++ b/netcat.c
@@ -136,6 +136,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 */
@@ -171,6 +172,7 @@ void report_connect(const struct sockaddr *, socklen_t);
void usage(int);
ssize_t drainbuf(int, unsigned char *, size_t *, int);
ssize_t fillbuf(int, unsigned char *, size_t *);
+char *proto_name(int uflag, int dccpflag);
static int connect_with_timeout(int fd, const struct sockaddr *sa,
socklen_t salen, int ctimeout);
@@ -200,7 +202,7 @@ main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN);
while ((ch = getopt(argc, argv,
- "46CDdFhI:i:klNnO:P:p:q:rSs:tT:UuV:vw:X:x:z")) != -1) {
+ "46CDdFhI:i:klNnO:P:p:q:rSs:tT:UuV:vw:X:x:Zz")) != -1) {
switch (ch) {
case '4':
family = AF_INET;
@@ -270,6 +272,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,
@@ -345,6 +354,12 @@ main(int argc, char *argv[])
/* Cruft to make sure options are clean, and used properly. */
if (argv[0] && !argv[1] && family == AF_UNIX) {
+ if (uflag)
+ errx(1, "cannot use -u and -U");
+# 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) {
@@ -386,8 +401,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;
}
@@ -395,7 +422,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");
@@ -439,12 +469,12 @@ main(int argc, char *argv[])
err(1, NULL);
char* local;
- if (family == AF_INET6
+ if (family == AF_INET6 )
local = "0.0.0.0";
else if (family == AF_INET)
local = ":::";
else
- local = "unknown"
+ local = "unknown";
fprintf(stderr, "Listening on [%s] (family %d, port %d)\n",
host ?: local,
family,
@@ -549,19 +579,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)
@@ -663,6 +694,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
@@ -699,8 +748,21 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
# endif
memset(&ahints, 0, sizeof(struct addrinfo));
ahints.ai_family = res0->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));
@@ -712,15 +774,19 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
}
set_common_sockopts(s, res0->ai_family);
+ char *proto = proto_name(uflag, dccpflag);
- if ((error = connect_with_timeout(s, res0->ai_addr, res0->ai_addrlen, timeout))== CONNECTION_SUCCESS)
+ if ((error = connect_with_timeout(s, res0->ai_addr, res0->ai_addrlen, timeout))== CONNECTION_SUCCESS) {
break;
- else if (vflag && error == CONNECTION_FAILED)
+ }
+ else 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);
+ }
close(s);
s = -1;
@@ -1250,7 +1316,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) {
portlist[0] = calloc(1, PORT_MAX_LEN);
if (portlist[0] == NULL)
@@ -1484,6 +1551,7 @@ help(void)
\t-w secs\t 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);
@@ -1493,7 +1561,7 @@ void
usage(int ret)
{
fprintf(stderr,
- "usage: nc [-46CDdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n"
+ "usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-O length]\n"
"\t [-P proxy_username] [-p source_port] [-q seconds] [-s source]\n"
"\t [-T toskeyword] [-V rtable] [-w timeout] [-X proxy_protocol]\n"
"\t [-x proxy_address[:port]] [destination] [port]\n");
--

View File

@ -0,0 +1,75 @@
From: Aron Xu <aron@debian.org>
Date: Tue, 14 Feb 2012 23:02:00 +0800
Subject: serialized handling multiple clients
---
netcat.c | 39 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/netcat.c b/netcat.c
index f4d85af..5d3a2d3 100644
--- a/netcat.c
+++ b/netcat.c
@@ -459,26 +459,24 @@ main(int argc, char *argv[])
s = unix_bind(host);
else
s = unix_listen(host);
- }
+ } else
+ s = local_listen(host, uport, hints);
+ if (s < 0)
+ err(1, NULL);
+
+ char* local;
+ if (family == AF_INET6)
+ local = ":::";
+ else
+ local = "0.0.0.0";
+ fprintf(stderr, "Listening on [%s] (family %d, port %d)\n",
+ host ?: local,
+ family,
+ *uport);
/* Allow only one connection at a time, but stay alive. */
for (;;) {
- if (family != AF_UNIX)
- s = local_listen(host, uport, hints);
- if (s < 0)
- err(1, NULL);
- char* local;
- if (family == AF_INET6 )
- local = "0.0.0.0";
- else if (family == AF_INET)
- local = ":::";
- else
- local = "unknown";
- fprintf(stderr, "Listening on [%s] (family %d, port %d)\n",
- host ?: local,
- family,
- *uport);
/*
* For UDP and -k, don't connect the socket, let it
* receive datagrams from multiple socket pairs.
@@ -525,15 +523,16 @@ main(int argc, char *argv[])
close(connfd);
}
- if (family != AF_UNIX)
+ if (kflag)
+ continue;
+ if (family != AF_UNIX) {
close(s);
+ }
else if (uflag) {
if (connect(s, NULL, 0) < 0)
err(1, "connect");
}
-
- if (!kflag)
- break;
+ break;
}
} else if (family == AF_UNIX) {
ret = 0;
--

View File

@ -0,0 +1,404 @@
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 19:06:52 +0800
Subject: misc failures and features
---
Makefile | 3 +-
nc.1 | 76 ++++++++++++++++++++++++++++++++++++++++++++---
netcat.c | 101 +++++++++++++++++++++++++++++++++++++++++++--------------------
3 files changed, 143 insertions(+), 37 deletions(-)
diff --git a/Makefile b/Makefile
index 96a6587..becd854 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,8 @@
PROG= nc
SRCS= netcat.c atomicio.c socks.c
-LIBS= `pkg-config --libs libbsd` -lresolv
+PKG_CONFIG ?= pkg-config
+LIBS= `$(PKG_CONFIG) --libs libbsd` -lresolv
OBJS= $(SRCS:.c=.o)
CFLAGS= -g -O2
LDFLAGS= -Wl,--no-add-needed
diff --git a/nc.1 b/nc.1
index fe42909..e95918a 100644
--- a/nc.1
+++ b/nc.1
@@ -34,7 +34,7 @@
.Sh SYNOPSIS
.Nm nc
.Bk -words
-.Op Fl 46CDdFhklNnrStUuvZz
+.Op Fl 46bCDdFhklNnrStUuvZz
.Op Fl I Ar length
.Op Fl i Ar interval
.Op Fl O Ar length
@@ -99,6 +99,8 @@ to use IPv4 addresses only.
Forces
.Nm
to use IPv6 addresses only.
+.It Fl b
+Allow broadcast.
.It Fl C
Send CRLF as line-ending.
.It Fl D
@@ -345,6 +347,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.
@@ -404,15 +454,30 @@ 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.
+.Pp
+You can also specify a list of ports to scan, for example:
+.Bd -literal -offset indent
+$ nc \-zv host.example.com 80 20 22
+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!
+.Ed
+.Pp
+The ports are scanned by the order you given.
.Pp
Alternatively, it might be useful to know which server software
is running, and which versions.
@@ -477,6 +542,9 @@ Original implementation by *Hobbit*
.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
diff --git a/netcat.c b/netcat.c
index 258a29a..c47fc0f 100644
--- a/netcat.c
+++ b/netcat.c
@@ -90,6 +90,7 @@
#include <netdb.h>
#include <poll.h>
#include <signal.h>
+#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -121,6 +122,7 @@
#define UDP_SCAN_TIMEOUT 3 /* Seconds */
/* Command Line Options */
+int bflag; /* Allow Broadcast */
int Cflag = 0; /* CRLF line-ending */
int dflag; /* detached, no stdin */
int Fflag; /* fdpass sock to stdout */
@@ -153,7 +155,7 @@ char *portlist[PORT_MAX+1];
char *unix_dg_tmp_socket;
void atelnet(int, unsigned char *, unsigned int);
-void build_ports(char *);
+void build_ports(char **);
void help(void);
int local_listen(char *, char *, struct addrinfo);
void readwrite(int);
@@ -182,11 +184,14 @@ int
main(int argc, char *argv[])
{
int ch, s, ret, socksv;
- char *host, *uport;
+ char *host, **uport;
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;
const char *errstr, *proxyhost = "", *proxyport = NULL;
struct addrinfo proxyhints;
@@ -202,7 +207,7 @@ main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN);
while ((ch = getopt(argc, argv,
- "46CDdFhI:i:klNnO:P:p:q:rSs:tT:UuV:vw:X:x:Zz")) != -1) {
+ "46bCDdFhI:i:klNnO:P:p:q:rSs:tT:UuV:vw:X:x:Zz")) != -1) {
switch (ch) {
case '4':
family = AF_INET;
@@ -210,6 +215,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;
@@ -354,35 +366,40 @@ main(int argc, char *argv[])
/* Cruft to make sure options are clean, and used properly. */
if (argv[0] && !argv[1] && family == AF_UNIX) {
- if (uflag)
- errx(1, "cannot use -u and -U");
# 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 (zflag)
- errx(1, "cannot use -z and -l");
- if (pflag)
- uport=pflag;
- } else if (!lflag && kflag) {
- errx(1, "cannot use -k without -l");
- } else if (argv[0] && !argv[1]) {
- if (!lflag)
- usage(1);
- uport = argv[0];
+ } else if (argv[0] && !argv[1] && lflag) {
+ if (pflag) {
+ uport = &pflag;
+ host = argv[0];
+ } else {
+ uport = argv;
+ host = NULL;
+ }
+ } else if (!argv[0] && lflag && pflag) {
+ uport = &pflag;
host = NULL;
} else if (argv[0] && argv[1]) {
host = argv[0];
- uport = argv[1];
+ uport = &argv[1];
} else
usage(1);
-
+ if (lflag) {
+ if (sflag)
+ errx(1, "cannot use -s and -l");
+ if (zflag)
+ errx(1, "cannot use -z and -l");
+ if (pflag)
+ /* This still does not work well because of getopt mess
+ errx(1, "cannot use -p and -l"); */
+ uport = &pflag;
+ } else if (!lflag && kflag)
+ errx(1, "cannot use -k without -l");
/* Get name of temporary socket for unix datagram client */
if ((family == AF_UNIX) && uflag && !lflag) {
@@ -460,7 +477,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);
@@ -469,7 +486,8 @@ main(int argc, char *argv[])
local = ":::";
else
local = "0.0.0.0";
- fprintf(stderr, "Listening on [%s] (family %d, port %d)\n",
+ if (vflag && (family != AF_UNIX))
+ fprintf(stderr, "Listening on [%s] (family %d, port %s)\n",
host ?: local,
family,
*uport);
@@ -632,6 +650,8 @@ unix_bind(char *path)
return (-1);
}
+ unlink(path);
+
if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
close(s);
return (-1);
@@ -653,8 +673,10 @@ unix_connect(char *path)
if ((s = unix_bind(unix_dg_tmp_socket)) < 0)
return (-1);
} else {
- if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ errx(1,"create unix socket failed");
return (-1);
+ }
}
(void)fcntl(s, F_SETFD, FD_CLOEXEC);
@@ -665,9 +687,11 @@ unix_connect(char *path)
sizeof(sun.sun_path)) {
close(s);
errno = ENAMETOOLONG;
+ warn("unix connect abandoned");
return (-1);
}
if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
+ warn("unix connect failed");
close(s);
return (-1);
}
@@ -1307,22 +1331,23 @@ atelnet(int nfd, unsigned char *buf, unsigned int size)
* that we should try to connect to.
*/
void
-build_ports(char *p)
+build_ports(char **p)
{
struct servent *sv;
const char *errstr;
char *n;
int hi, lo, cp;
int x = 0;
+ int i;
char *proto = proto_name(uflag, dccpflag);
- sv = getservbyname(p, proto);
+ sv = getservbyname(*p, proto);
if (sv) {
portlist[0] = calloc(1, PORT_MAX_LEN);
if (portlist[0] == NULL)
err(1, NULL);
snprintf(portlist[0], PORT_MAX_LEN, "%d", ntohs(sv->s_port));
- } else if ((n = strchr(p, '-')) != NULL) {
+ } else if ((n = strchr(*p, '-')) != NULL) {
*n = '\0';
n++;
@@ -1330,9 +1355,9 @@ build_ports(char *p)
hi = strtonum(n, 1, PORT_MAX, &errstr);
if (errstr)
errx(1, "port number %s: %s", errstr, n);
- lo = strtonum(p, 1, PORT_MAX, &errstr);
+ lo = strtonum(*p, 1, PORT_MAX, &errstr);
if (errstr)
- errx(1, "port number %s: %s", errstr, p);
+ errx(1, "port number %s: %s", errstr, *p);
if (lo > hi) {
cp = hi;
@@ -1362,10 +1387,12 @@ build_ports(char *p)
}
}
} else {
- hi = strtonum(p, 1, PORT_MAX, &errstr);
+ hi = strtonum(*p, 1, PORT_MAX, &errstr);
if (errstr)
- errx(1, "port number %s: %s", errstr, p);
- portlist[0] = strdup(p);
+ errx(1, "port number %s: %s", errstr, *p);
+ for (i=0;p[i];i++) {
+ portlist[i] = strdup(p[i]);
+ }
if (portlist[0] == NULL)
err(1, NULL);
}
@@ -1400,6 +1427,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,
@@ -1523,6 +1559,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

@ -1,57 +1,59 @@
# Maintainer: Leonardo Arena <rnalrd@alpinelinux.org>
pkgname=netcat-openbsd
pkgver=1.89
pkgrel=2
pkgver=1.130
pkgrel=0
pkgdesc="The TCP/IP swiss army knife. OpenBSD variant."
url="http://packages.debian.org/sid/netcat-openbsd"
arch="all"
license="GPL"
depends=
depends_dev="glib-dev"
makedepends="$depends_dev"
install=
makedepends="glib-dev libbsd-dev"
subpackages="$pkgname-doc"
source="http://distfiles.alpinelinux.org/distfiles/${pkgname}_$pkgver.orig.tar.gz
netcat-openbsd_1.89-4.diff
fix-cdefs.patch
"
options="!check"
source="$pkgname-$pkgver.tar.gz::http://http.debian.net/debian/pool/main/n/netcat-openbsd/netcat-openbsd_${pkgver}.orig.tar.gz
base64.c
_builddir="$srcdir"/$pkgname-$pkgver.orig
0001-port-to-linux-with-libsd.patch
0002-connect-timeout.patch
0003-get-sev-by-name.patch
0004-send-crlf.patch
0005-quit-timer.patch
0006-udp-scan-timeout.patch
0007-verbose-numeric-port.patch
0008-dccp-support.patch
0009-serialized-handling-multiple-clients.patch
0010-misc-failures-and-features.patch
"
builddir="$srcdir"/$pkgname-$pkgver
prepare() {
local i
cd "$_builddir"
for i in $source; do
case $i in
*.patch|*.diff) msg $i; patch -p1 -i "$srcdir"/$i || return 1;;
esac
done
for i in `cat debian/patches/series`; do
echo "Applying patch $i" 1>&2
patch -p1 -i "debian/patches/$i" || return 1
done
cd "$builddir"
cp "$srcdir"/base64.c .
default_prepare
sed -i Makefile -e "/SRCS=/s;\(.*\);& base64.c;"
}
build() {
cd "$_builddir"
make CFLAGS="$CFLAGS -DDEBIAN_VERSION=\"\\\"4\\\"\"" || return 1
cd "$builddir"
make CFLAGS="$CFLAGS -DDEBIAN_VERSION=\"\\\"${pkgver}\\\"\"" || return 1
}
package() {
cd "$_builddir"
cd "$builddir"
install -d $pkgdir/usr/bin/
install -d $pkgdir/usr/share/man/man1/
install nc $pkgdir/usr/bin/nc
install nc.1 $pkgdir/usr/share/man/man1/nc.openbsd.1
}
md5sums="7238ce15aae43069e96ba7faf03f153e netcat-openbsd_1.89.orig.tar.gz
71e9261d1209ee7475718632216f72ba netcat-openbsd_1.89-4.diff
c9161b439eb4c4a75295be39ad32d1ac fix-cdefs.patch"
sha256sums="72e844dde8a2a7cba61971d493758dbea9ef0b164bccef15fd4a36490dc77f2b netcat-openbsd_1.89.orig.tar.gz
55a4303e3cf6b9a97cf7bb3e81c74df97ba2d2f6491891b663fac478d6f87599 netcat-openbsd_1.89-4.diff
4bf424667b7321a895e48bb9fafcc7b85b578fcecd27d1b982f9e28350429b6c fix-cdefs.patch"
sha512sums="4e18289c507461fb8257e466ab082a2b18489218c3065af5b4626369cd3acb378f68eb69cfe77ff46d5fba222c12e2bc30dc71c0a88d2921a7e513b926b8b75d netcat-openbsd_1.89.orig.tar.gz
ad36f08ecaf1d599b6fe4c8ba65aeb436f879c6d4b13777a9ceca9e6f5df7c69dd40fe04610c868ffc4c549dbe28e54b8bc373f080f6c8edc5896f7c07fc97e0 netcat-openbsd_1.89-4.diff
b70e19344c358ece0c5edcafc2be3df3b09c0fcbef95dc21e0bf8fe31593905a3191870cc9bb5eb707d12748d727276a19918c3998277d6f0a9a10954931a0a0 fix-cdefs.patch"
sha512sums="fb2b80ccbfce364f3d376bd396f38a218127627721052694f1da24751e45a239a72c839b07b54bfc6846be6efa0c557a9cdab349711631ecff7055b763fd98e4 netcat-openbsd-1.130.tar.gz
2d4b117397e6882b0f4357bb11ca1f520746c59e0305a58f8651582a9cff17f4c59cacb14ce93de1d0fe78db5ba7fd9096c0176afc61b2c715b0b9a0444c2b4f base64.c
06ebc872c7bedd1961b615625e3690909cdfe5c7635c5bb14826aa5a12ab333fa6cedfd38e1b1dddc00cc6b6527927dee730377c194617f7dc889edec7de410e 0001-port-to-linux-with-libsd.patch
70dca0943a8045951a50aa3897b0066b3838bec6ea58a6325b888ffe0cbace30afdce52741257ef080e36d2c1d4db2d51287d08d1a5942c0f98327343c036f27 0002-connect-timeout.patch
e4fca460b25aaa2f6ae360137bfa46b12e1329bacc59f249b46fd55246fbdc4ad8ae0eb6c3ecc4989ab92e385da7b0b9353bc3d72ca230b149b5cd93263ff893 0003-get-sev-by-name.patch
46c8a5774792590487732e4a5bcca7d5e5be1b4587cccf5c757f7198900d6e4154ef01425a846bbdd3ec52ea476db5d79e80c94620a21e29f277aadecbd1210d 0004-send-crlf.patch
21bb871a2f55d7cb5759734b16c5b64be937cf7d1a50be7995fdc8885fbcd55ef70a6173c5b266918c5aedf2dc36cf031aa2a3db9c5fcf89d834cd834ac948b4 0005-quit-timer.patch
f927d547a837314b0418f119ff0d0d83a662a90470fe1739e808c854a7fbe536326a445a2bf83a43af473a159a76d2262f68b5851b86a7a88b72ea0e69995a68 0006-udp-scan-timeout.patch
4c5ea10262098d411ea428ef1eac59d2cffa85b2d485b4af62ea71a9fd9ee2bc90644b8ba0259f5b182b371bad6a3cdbddca7818f0dd312421768ea4170bf9d6 0007-verbose-numeric-port.patch
cf3f37272e06908f7fb5ea6d1ab0217cfbc69b19dd5cfd805749498c46177efd208c62c24864ffddaeb7aa4302424d0b964909d1195d72056a000cf204b2a1cc 0008-dccp-support.patch
fff37c6854403586f1b2e838ad9ee19c511277ada17063847ecaec7066ee052980a646db76c3ffc53bf917e661bbbdc74e944e1bffeba9dc100d9521c15c3b23 0009-serialized-handling-multiple-clients.patch
ed618931b28e21b52eb8844758edaa434293217ab7f7bd064b56029bb4eef35a45d87800171c14dbef31674490ff9aa9539753ced80fa07f13b567b7e75df3b6 0010-misc-failures-and-features.patch"

View File

@ -0,0 +1,315 @@
/*
* Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Portions Copyright (c) 1995 by International Business Machines, Inc.
*
* International Business Machines, Inc. (hereinafter called IBM) grants
* permission under its copyrights to use, copy, modify, and distribute this
* Software with or without fee, provided that the above copyright notice and
* all paragraphs of this notice appear in all copies, and that the name of IBM
* not be used in connection with the marketing of any product incorporating
* the Software or modifications thereof, without specific, written prior
* permission.
*
* To the extent it has a right to do so, IBM grants an immunity from suit
* under its patents, if any, for the use, sale or manufacture of products to
* the extent that such products are used for performing Domain Name System
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
* granted for any product per se or for any other function of any product.
*
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
#if !defined(LINT) && !defined(CODECENTER)
static const char rcsid[] = "$BINDId: base64.c,v 8.7 1999/10/13 16:39:33 vixie Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ctype.h>
#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define Assert(Cond) if (!(Cond)) abort()
static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char Pad64 = '=';
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
The following encoding technique is taken from RFC 1521 by Borenstein
and Freed. It is reproduced here in a slightly edited form for
convenience.
A 65-character subset of US-ASCII is used, enabling 6 bits to be
represented per printable character. (The extra 65th character, "=",
is used to signify a special processing function.)
The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8-bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
Each 6-bit group is used as an index into an array of 64 printable
characters. The character referenced by the index is placed in the
output string.
Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
Special processing is performed if fewer than 24 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a quantity. When fewer than 24 input
bits are available in an input group, zero bits are added (on the
right) to form an integral number of 6-bit groups. Padding at the
end of the data is performed using the '=' character.
Since all base64 input is an integral number of octets, only the
-------------------------------------------------
following cases can arise:
(1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded
output will be an integral multiple of 4 characters
with no "=" padding,
(2) the final quantum of encoding input is exactly 8 bits;
here, the final unit of encoded output will be two
characters followed by two "=" padding characters, or
(3) the final quantum of encoding input is exactly 16 bits;
here, the final unit of encoded output will be three
characters followed by one "=" padding character.
*/
int
b64_ntop(const uint8_t* src, size_t srclength, char* target, size_t targsize)
{
size_t datalength = 0;
uint8_t input[3];
uint8_t output[4];
size_t i;
while (2 < srclength) {
input[0] = *src++;
input[1] = *src++;
input[2] = *src++;
srclength -= 3;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
output[3] = input[2] & 0x3f;
Assert(output[0] < 64);
Assert(output[1] < 64);
Assert(output[2] < 64);
Assert(output[3] < 64);
if (datalength + 4 > targsize)
return (-1);
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
target[datalength++] = Base64[output[2]];
target[datalength++] = Base64[output[3]];
}
/* Now we worry about padding. */
if (0 != srclength) {
/* Get what's left. */
input[0] = input[1] = input[2] = '\0';
for (i = 0; i < srclength; i++)
input[i] = *src++;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
Assert(output[0] < 64);
Assert(output[1] < 64);
Assert(output[2] < 64);
if (datalength + 4 > targsize)
return (-1);
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
if (srclength == 1)
target[datalength++] = Pad64;
else
target[datalength++] = Base64[output[2]];
target[datalength++] = Pad64;
}
if (datalength >= targsize)
return (-1);
target[datalength] = '\0'; /* Returned value doesn't count \0. */
return (datalength);
}
/* skips all whitespace anywhere.
converts characters, four at a time, starting at (or after)
src from base - 64 numbers into three 8 bit bytes in the target area.
it returns the number of data bytes stored at the target, or -1 on error.
*/
int b64_pton(const char* src, uint8_t* target, size_t targsize)
{
int tarindex, state, ch;
char *pos;
state = 0;
tarindex = 0;
while ((ch = *src++) != '\0') {
if (isspace(ch)) /* Skip whitespace anywhere. */
continue;
if (ch == Pad64)
break;
pos = strchr(Base64, ch);
if (pos == 0) /* A non-base64 character. */
return (-1);
switch (state) {
case 0:
if (target) {
if ((size_t)tarindex >= targsize)
return (-1);
target[tarindex] = (pos - Base64) << 2;
}
state = 1;
break;
case 1:
if (target) {
if ((size_t)tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 4;
target[tarindex+1] = ((pos - Base64) & 0x0f)
<< 4 ;
}
tarindex++;
state = 2;
break;
case 2:
if (target) {
if ((size_t)tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 2;
target[tarindex+1] = ((pos - Base64) & 0x03)
<< 6;
}
tarindex++;
state = 3;
break;
case 3:
if (target) {
if ((size_t)tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - Base64);
}
tarindex++;
state = 0;
break;
default:
abort();
}
}
/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad64) { /* We got a pad char. */
ch = *src++; /* Skip it, get next. */
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for ((void)NULL; ch != '\0'; ch = *src++)
if (!isspace(ch))
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = *src++; /* Skip the = */
/* Fall through to "single trailing =" case. */
/* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for ((void)NULL; ch != '\0'; ch = *src++)
if (!isspace(ch))
return (-1);
/*
* Now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. If we don't check them, they become a
* subliminal channel.
*/
if (target && target[tarindex] != 0)
return (-1);
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}

View File

@ -1,24 +0,0 @@
Only in netcat-openbsd-1.89.orig: atomicio.o
Only in netcat-openbsd-1.89.orig: openbsd-compat/base64.o
--- netcat-openbsd-1.89.orig.orig/openbsd-compat/readpassphrase.h
+++ netcat-openbsd-1.89.orig/openbsd-compat/readpassphrase.h
@@ -31,10 +31,14 @@
#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */
#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */
-#include <sys/cdefs.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
-__BEGIN_DECLS
char * readpassphrase(const char *, char *, size_t, int);
-__END_DECLS
+
+#ifdef __cplusplus
+};
+#endif
#endif /* !_READPASSPHRASE_H_ */
Only in netcat-openbsd-1.89.orig: openbsd-compat/readpassphrase.o
Only in netcat-openbsd-1.89.orig: socks.o

File diff suppressed because it is too large Load Diff