aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Jude <allanjude@FreeBSD.org>2024-06-08 21:09:54 +0000
committerAllan Jude <allanjude@FreeBSD.org>2024-06-08 21:09:54 +0000
commit1849781381dd9aba25f8de2159c4b8bbb5496a00 (patch)
treea802b2824a97293a2b283d6debec5a9fe7a469cf
parentf98a010ade76871c79ffa9e72c25974083b8d4bf (diff)
downloadsrc-vendor/netcat.tar.gz
src-vendor/netcat.zip
Import netcat from OpenBSD 7.5.vendor/netcat/7.5vendor/netcat
-rw-r--r--nc.134
-rw-r--r--netcat.c244
-rw-r--r--socks.c15
3 files changed, 182 insertions, 111 deletions
diff --git a/nc.1 b/nc.1
index 6bdfe4f90415..0ef318e0e6f5 100644
--- a/nc.1
+++ b/nc.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: nc.1,v 1.93 2018/12/27 17:45:36 jmc Exp $
+.\" $OpenBSD: nc.1,v 1.97 2022/09/11 09:58:06 schwarze Exp $
.\"
.\" Copyright (c) 1996 David Sacerdote
.\" All rights reserved.
@@ -25,7 +25,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: December 27 2018 $
+.Dd $Mdocdate: September 11 2022 $
.Dt NC 1
.Os
.Sh NAME
@@ -47,7 +47,7 @@
.Op Fl P Ar proxy_username
.Op Fl p Ar source_port
.Op Fl R Ar CAfile
-.Op Fl s Ar source
+.Op Fl s Ar sourceaddr
.Op Fl T Ar keyword
.Op Fl V Ar rtable
.Op Fl W Ar recvlimit
@@ -192,8 +192,8 @@ Ask the kernel to drop incoming packets whose TTL / hop limit is under
the network socket after EOF on the input.
Some servers require this to finish their work.
.It Fl n
-Do not do any DNS or service lookups on any specified addresses,
-hostnames or ports.
+Do not perform domain name resolution.
+If a name cannot be resolved without DNS, an error will be reported.
.It Fl O Ar length
Specify the size of the TCP send buffer.
.It Fl o Ar staplefile
@@ -228,10 +228,9 @@ instead of sequentially within a range or in the order that the system
assigns them.
.It Fl S
Enable the RFC 2385 TCP MD5 signature option.
-.It Fl s Ar source
-Send packets from the interface with the
-.Ar source
-IP address.
+.It Fl s Ar sourceaddr
+Set the source address to send packets from,
+which is useful on machines with multiple interfaces.
For
.Ux Ns -domain
datagram sockets, specifies the local temporary socket file
@@ -415,7 +414,7 @@ On a second console
.Pq or a second machine ,
connect to the machine and port being listened on:
.Pp
-.Dl $ nc 127.0.0.1 1234
+.Dl $ nc -N 127.0.0.1 1234
.Pp
There should now be a connection between the ports.
Anything typed at the second console will be concatenated to the first,
@@ -428,7 +427,10 @@ and which side is being used as a
.Sq client .
The connection may be terminated using an
.Dv EOF
-.Pq Sq ^D .
+.Pq Sq ^D ,
+as the
+.Fl N
+flag was given.
.Sh DATA TRANSFER
The example in the previous section can be expanded to build a
basic data transfer model.
@@ -440,13 +442,13 @@ Start by using
.Nm
to listen on a specific port, with output captured into a file:
.Pp
-.Dl $ nc -l 1234 \*(Gt filename.out
+.Dl $ nc -l 1234 > filename.out
.Pp
Using a second machine, connect to the listening
.Nm
process, feeding it the file which is to be transferred:
.Pp
-.Dl $ nc -N host.example.com 1234 \*(Lt filename.in
+.Dl $ nc -N host.example.com 1234 < filename.in
.Pp
After the file has been transferred, the connection will close automatically.
.Sh TALKING TO SERVERS
@@ -470,10 +472,10 @@ 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 localhost 25 << EOF
HELO host.example.com
-MAIL FROM:\*(Ltuser@host.example.com\*(Gt
-RCPT TO:\*(Ltuser2@host.example.com\*(Gt
+MAIL FROM:<user@host.example.com>
+RCPT TO:<user2@host.example.com>
DATA
Body of email.
\&.
diff --git a/netcat.c b/netcat.c
index 048502bd1e5a..54ddd0ffccf7 100644
--- a/netcat.c
+++ b/netcat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netcat.c,v 1.203 2019/02/26 17:32:47 jsing Exp $ */
+/* $OpenBSD: netcat.c,v 1.226 2023/08/14 08:07:27 tb Exp $ */
/*
* Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
* Copyright (c) 2015 Bob Beck. All rights reserved.
@@ -103,7 +103,7 @@ const char *Kflag; /* Private key file */
const char *oflag; /* OCSP stapling file */
const char *Rflag; /* Root CA file */
int tls_cachanged; /* Using non-default CA file */
-int TLSopt; /* TLS options */
+int TLSopt; /* TLS options */
char *tls_expectname; /* required name in peer cert */
char *tls_expecthash; /* required hash of peer cert */
char *tls_ciphers; /* TLS ciphers */
@@ -125,12 +125,13 @@ void help(void) __attribute__((noreturn));
int local_listen(const char *, const char *, struct addrinfo);
void readwrite(int, struct tls *);
void fdpass(int nfd) __attribute__((noreturn));
-int remote_connect(const char *, const char *, struct addrinfo);
+int remote_connect(const char *, const char *, struct addrinfo, char *);
int timeout_tls(int, struct tls *, int (*)(struct tls *));
int timeout_connect(int, const struct sockaddr *, socklen_t);
int socks_connect(const char *, const char *, struct addrinfo,
const char *, const char *, struct addrinfo, int, const char *);
int udptest(int);
+void connection_info(const char *, const char *, const char *, const char *);
int unix_bind(char *, int);
int unix_connect(char *);
int unix_listen(char *);
@@ -151,8 +152,8 @@ main(int argc, char *argv[])
{
int ch, s = -1, ret, socksv;
char *host, *uport;
+ char ipaddr[NI_MAXHOST];
struct addrinfo hints;
- struct servent *sv;
socklen_t len;
struct sockaddr_storage cliaddr;
char *proxy = NULL, *proxyport = NULL;
@@ -167,7 +168,6 @@ main(int argc, char *argv[])
socksv = 5;
host = NULL;
uport = NULL;
- sv = NULL;
Rflag = tls_default_ca_cert_file();
signal(SIGPIPE, SIG_IGN);
@@ -351,15 +351,11 @@ main(int argc, char *argv[])
err(1, "setrtable");
/* Cruft to make sure options are clean, and used properly. */
- if (argv[0] && !argv[1] && family == AF_UNIX) {
+ if (argc == 1 && family == AF_UNIX) {
host = argv[0];
- uport = NULL;
- } else if (argv[0] && !argv[1]) {
- if (!lflag)
- usage(1);
+ } else if (argc == 1 && lflag) {
uport = argv[0];
- host = NULL;
- } else if (argv[0] && argv[1]) {
+ } else if (argc == 2) {
host = argv[0];
uport = argv[1];
} else
@@ -367,24 +363,36 @@ main(int argc, char *argv[])
if (usetls) {
if (Cflag && unveil(Cflag, "r") == -1)
- err(1, "unveil");
+ err(1, "unveil %s", Cflag);
if (unveil(Rflag, "r") == -1)
- err(1, "unveil");
+ err(1, "unveil %s", Rflag);
if (Kflag && unveil(Kflag, "r") == -1)
- err(1, "unveil");
+ err(1, "unveil %s", Kflag);
if (oflag && unveil(oflag, "r") == -1)
- err(1, "unveil");
+ err(1, "unveil %s", oflag);
+ } else if (family == AF_UNIX && uflag && lflag && !kflag) {
+ /*
+ * After recvfrom(2) from client, the server connects
+ * to the client socket. As the client path is determined
+ * during runtime, we cannot unveil(2).
+ */
} else {
if (family == AF_UNIX) {
if (unveil(host, "rwc") == -1)
- err(1, "unveil");
- if (uflag && !lflag) {
- if (unveil(sflag ? sflag : "/tmp", "rwc") == -1)
- err(1, "unveil");
+ err(1, "unveil %s", host);
+ if (uflag && !kflag) {
+ if (sflag) {
+ if (unveil(sflag, "rwc") == -1)
+ err(1, "unveil %s", sflag);
+ } else {
+ if (unveil("/tmp", "rwc") == -1)
+ err(1, "unveil /tmp");
+ }
}
} else {
+ /* no filesystem visibility */
if (unveil("/", "") == -1)
- err(1, "unveil");
+ err(1, "unveil /");
}
}
@@ -568,9 +576,13 @@ main(int argc, char *argv[])
close(s);
s = local_listen(host, uport, hints);
}
- if (s < 0)
+ if (s == -1)
err(1, NULL);
if (uflag && kflag) {
+ if (family == AF_UNIX) {
+ if (pledge("stdio unix", NULL) == -1)
+ err(1, "pledge");
+ }
/*
* For UDP and -k, don't connect the socket,
* let it receive datagrams from multiple
@@ -590,16 +602,21 @@ main(int argc, char *argv[])
len = sizeof(z);
rv = recvfrom(s, buf, sizeof(buf), MSG_PEEK,
(struct sockaddr *)&z, &len);
- if (rv < 0)
+ if (rv == -1)
err(1, "recvfrom");
rv = connect(s, (struct sockaddr *)&z, len);
- if (rv < 0)
+ if (rv == -1)
err(1, "connect");
+ if (family == AF_UNIX) {
+ if (pledge("stdio unix", NULL) == -1)
+ err(1, "pledge");
+ }
if (vflag)
report_sock("Connection received",
- (struct sockaddr *)&z, len, NULL);
+ (struct sockaddr *)&z, len,
+ family == AF_UNIX ? host : NULL);
readwrite(s, NULL);
} else {
@@ -628,7 +645,7 @@ main(int argc, char *argv[])
tls_free(tls_cctx);
}
if (family == AF_UNIX && uflag) {
- if (connect(s, NULL, 0) < 0)
+ if (connect(s, NULL, 0) == -1)
err(1, "connect");
}
@@ -650,7 +667,6 @@ main(int argc, char *argv[])
if (uflag)
unlink(unix_dg_tmp_socket);
return ret;
-
} else {
int i = 0;
@@ -676,35 +692,27 @@ main(int argc, char *argv[])
proxy, proxyport, proxyhints, socksv,
Pflag);
else
- s = remote_connect(host, portlist[i], hints);
+ s = remote_connect(host, portlist[i], hints,
+ ipaddr);
if (s == -1)
continue;
ret = 0;
if (vflag || zflag) {
+ int print_info = 1;
+
/* For UDP, make sure we are connected. */
if (uflag) {
- if (udptest(s) == -1) {
+ /* No info on failed or skipped test. */
+ if ((print_info = udptest(s)) == -1) {
ret = 1;
continue;
}
}
-
- /* Don't look up port if -n. */
- if (nflag)
- sv = NULL;
- else {
- sv = getservbyport(
- ntohs(atoi(portlist[i])),
- uflag ? "udp" : "tcp");
- }
-
- fprintf(stderr,
- "Connection to %s %s port [%s/%s] "
- "succeeded!\n", host, portlist[i],
- uflag ? "udp" : "tcp",
- sv ? sv->s_name : "*");
+ if (print_info == 1)
+ connection_info(host, portlist[i],
+ uflag ? "udp" : "tcp", ipaddr);
}
if (Fflag)
fdpass(s);
@@ -739,7 +747,7 @@ unix_bind(char *path, int flags)
/* Create unix domain socket. */
if ((s = socket(AF_UNIX, flags | (uflag ? SOCK_DGRAM : SOCK_STREAM),
- 0)) < 0)
+ 0)) == -1)
return -1;
memset(&s_un, 0, sizeof(struct sockaddr_un));
@@ -752,7 +760,7 @@ unix_bind(char *path, int flags)
return -1;
}
- if (bind(s, (struct sockaddr *)&s_un, sizeof(s_un)) < 0) {
+ if (bind(s, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
save_errno = errno;
close(s);
errno = save_errno;
@@ -797,7 +805,7 @@ tls_setup_client(struct tls *tls_ctx, int s, char *host)
const char *errstr;
if (tls_connect_socket(tls_ctx, s,
- tls_expectname ? tls_expectname : host) == -1) {
+ tls_expectname ? tls_expectname : host) == -1) {
errx(1, "tls connection failed (%s)",
tls_error(tls_ctx));
}
@@ -808,8 +816,8 @@ tls_setup_client(struct tls *tls_ctx, int s, char *host)
}
if (vflag)
report_tls(tls_ctx, host);
- if (tls_expecthash && tls_peer_cert_hash(tls_ctx) &&
- strcmp(tls_expecthash, tls_peer_cert_hash(tls_ctx)) != 0)
+ if (tls_expecthash && (tls_peer_cert_hash(tls_ctx) == NULL ||
+ strcmp(tls_expecthash, tls_peer_cert_hash(tls_ctx)) != 0))
errx(1, "peer certificate is not %s", tls_expecthash);
if (Zflag) {
save_peer_cert(tls_ctx, Zflag);
@@ -837,8 +845,9 @@ tls_setup_server(struct tls *tls_ctx, int connfd, char *host)
report_tls(tls_cctx, host);
if ((TLSopt & TLS_CCERT) && !gotcert)
warnx("No client certificate provided");
- else if (gotcert && tls_peer_cert_hash(tls_ctx) && tls_expecthash &&
- strcmp(tls_expecthash, tls_peer_cert_hash(tls_ctx)) != 0)
+ else if (gotcert && tls_expecthash &&
+ (tls_peer_cert_hash(tls_cctx) == NULL ||
+ strcmp(tls_expecthash, tls_peer_cert_hash(tls_cctx)) != 0))
warnx("peer certificate is not %s", tls_expecthash);
else if (gotcert && tls_expectname &&
(!tls_peer_cert_contains_name(tls_cctx, tls_expectname)))
@@ -862,10 +871,10 @@ unix_connect(char *path)
int s, save_errno;
if (uflag) {
- if ((s = unix_bind(unix_dg_tmp_socket, SOCK_CLOEXEC)) < 0)
+ if ((s = unix_bind(unix_dg_tmp_socket, SOCK_CLOEXEC)) == -1)
return -1;
} else {
- if ((s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0)
+ if ((s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1)
return -1;
}
@@ -878,14 +887,13 @@ unix_connect(char *path)
errno = ENAMETOOLONG;
return -1;
}
- if (connect(s, (struct sockaddr *)&s_un, sizeof(s_un)) < 0) {
+ if (connect(s, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
save_errno = errno;
close(s);
errno = save_errno;
return -1;
}
return s;
-
}
/*
@@ -897,9 +905,9 @@ unix_listen(char *path)
{
int s;
- if ((s = unix_bind(path, 0)) < 0)
+ if ((s = unix_bind(path, 0)) == -1)
return -1;
- if (listen(s, 5) < 0) {
+ if (listen(s, 5) == -1) {
close(s);
return -1;
}
@@ -915,10 +923,11 @@ unix_listen(char *path)
* port or source address if needed. Returns -1 on failure.
*/
int
-remote_connect(const char *host, const char *port, struct addrinfo hints)
+remote_connect(const char *host, const char *port, struct addrinfo hints,
+ char *ipaddr)
{
struct addrinfo *res, *res0;
- int s = -1, error, on = 1, save_errno;
+ int s = -1, error, herr, on = 1, save_errno;
if ((error = getaddrinfo(host, port, &hints, &res0)))
errx(1, "getaddrinfo for host \"%s\" port %s: %s", host,
@@ -926,7 +935,7 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
for (res = res0; res; res = res->ai_next) {
if ((s = socket(res->ai_family, res->ai_socktype |
- SOCK_NONBLOCK, res->ai_protocol)) < 0)
+ SOCK_NONBLOCK, res->ai_protocol)) == -1)
continue;
/* Bind to a local port or source address if specified. */
@@ -944,18 +953,39 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
errx(1, "getaddrinfo: %s", gai_strerror(error));
if (bind(s, (struct sockaddr *)ares->ai_addr,
- ares->ai_addrlen) < 0)
+ ares->ai_addrlen) == -1)
err(1, "bind failed");
freeaddrinfo(ares);
}
set_common_sockopts(s, res->ai_family);
+ if (ipaddr != NULL) {
+ herr = getnameinfo(res->ai_addr, res->ai_addrlen,
+ ipaddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+ switch (herr) {
+ case 0:
+ break;
+ case EAI_SYSTEM:
+ err(1, "getnameinfo");
+ default:
+ errx(1, "getnameinfo: %s", gai_strerror(herr));
+ }
+ }
+
if (timeout_connect(s, res->ai_addr, res->ai_addrlen) == 0)
break;
- if (vflag)
- warn("connect to %s port %s (%s) failed", host, port,
- uflag ? "udp" : "tcp");
+
+ if (vflag) {
+ /* only print IP if there is something to report */
+ if (nflag || ipaddr == NULL ||
+ (strncmp(host, ipaddr, NI_MAXHOST) == 0))
+ warn("connect to %s port %s (%s) failed", host,
+ port, uflag ? "udp" : "tcp");
+ else
+ warn("connect to %s (%s) port %s (%s) failed",
+ host, ipaddr, port, uflag ? "udp" : "tcp");
+ }
save_errno = errno;
close(s);
@@ -1023,7 +1053,7 @@ local_listen(const char *host, const char *port, struct addrinfo hints)
for (res = res0; res; res = res->ai_next) {
if ((s = socket(res->ai_family, res->ai_socktype,
- res->ai_protocol)) < 0)
+ res->ai_protocol)) == -1)
continue;
ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
@@ -1043,7 +1073,7 @@ local_listen(const char *host, const char *port, struct addrinfo hints)
}
if (!uflag && s != -1) {
- if (listen(s, 1) < 0)
+ if (listen(s, 1) == -1)
err(1, "listen");
}
if (vflag && s != -1) {
@@ -1147,7 +1177,7 @@ readwrite(int net_fd, struct tls *tls_ctx)
pfd[POLL_NETIN].fd = -1;
if (pfd[POLL_NETOUT].revents & POLLHUP) {
- if (Nflag)
+ if (pfd[POLL_NETOUT].fd != -1 && Nflag)
shutdown(pfd[POLL_NETOUT].fd, SHUT_WR);
pfd[POLL_NETOUT].fd = -1;
}
@@ -1226,7 +1256,7 @@ readwrite(int net_fd, struct tls *tls_ctx)
if (netinbufpos == BUFSIZE)
pfd[POLL_NETIN].events = 0;
/* handle telnet */
- if (tflag)
+ if (pfd[POLL_NETIN].fd != -1 && tflag)
atelnet(pfd[POLL_NETIN].fd, netinbuf,
netinbufpos);
}
@@ -1267,6 +1297,9 @@ drainbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
ssize_t n;
ssize_t adjust;
+ if (fd == -1)
+ return -1;
+
if (tls) {
n = tls_write(tls, buf, *bufpos);
if (n == -1)
@@ -1293,6 +1326,9 @@ fillbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
size_t num = BUFSIZE - *bufpos;
ssize_t n;
+ if (fd == -1)
+ return -1;
+
if (tls) {
n = tls_read(tls, buf + *bufpos, num);
if (n == -1)
@@ -1399,7 +1435,6 @@ atelnet(int nfd, unsigned char *buf, unsigned int size)
}
}
-
int
strtoport(char *portstr, int udp)
{
@@ -1453,12 +1488,12 @@ build_ports(char *p)
for (x = 0; x <= hi - lo; x++) {
cp = arc4random_uniform(x + 1);
portlist[x] = portlist[cp];
- if (asprintf(&portlist[cp], "%d", x + lo) < 0)
+ if (asprintf(&portlist[cp], "%d", x + lo) == -1)
err(1, "asprintf");
}
} else { /* Load ports sequentially. */
for (cp = lo; cp <= hi; cp++) {
- if (asprintf(&portlist[x], "%d", cp) < 0)
+ if (asprintf(&portlist[x], "%d", cp) == -1)
err(1, "asprintf");
x++;
}
@@ -1484,6 +1519,10 @@ udptest(int s)
{
int i, ret;
+ /* Only write to the socket in scan mode or interactive mode. */
+ if (!zflag && !isatty(STDIN_FILENO))
+ return 0;
+
for (i = 0; i <= 3; i++) {
if (write(s, "X", 1) == 1)
ret = 1;
@@ -1494,18 +1533,44 @@ udptest(int s)
}
void
+connection_info(const char *host, const char *port, const char *proto,
+ const char *ipaddr)
+{
+ struct servent *sv;
+ char *service = "*";
+
+ /* Look up service name unless -n. */
+ if (!nflag) {
+ sv = getservbyport(ntohs(atoi(port)), proto);
+ if (sv != NULL)
+ service = sv->s_name;
+ }
+
+ fprintf(stderr, "Connection to %s", host);
+
+ /*
+ * if we aren't connecting thru a proxy and
+ * there is something to report, print IP
+ */
+ if (!nflag && !xflag && strcmp(host, ipaddr) != 0)
+ fprintf(stderr, " (%s)", ipaddr);
+
+ fprintf(stderr, " %s port [%s/%s] succeeded!\n", port, proto, service);
+}
+
+void
set_common_sockopts(int s, int af)
{
int x = 1;
if (Sflag) {
if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
- &x, sizeof(x)) == -1)
+ &x, sizeof(x)) == -1)
err(1, NULL);
}
if (Dflag) {
if (setsockopt(s, SOL_SOCKET, SO_DEBUG,
- &x, sizeof(x)) == -1)
+ &x, sizeof(x)) == -1)
err(1, NULL);
}
if (Tflag != -1) {
@@ -1654,7 +1719,7 @@ save_peer_cert(struct tls *tls_ctx, FILE *fp)
}
void
-report_tls(struct tls * tls_ctx, char * host)
+report_tls(struct tls *tls_ctx, char *host)
{
time_t t;
const char *ocsp_url;
@@ -1682,7 +1747,7 @@ report_tls(struct tls * tls_ctx, char * host)
switch (tls_peer_ocsp_response_status(tls_ctx)) {
case TLS_OCSP_RESPONSE_SUCCESSFUL:
fprintf(stderr, "OCSP Stapling: %s\n",
- tls_peer_ocsp_result(tls_ctx) == NULL ? "" :
+ tls_peer_ocsp_result(tls_ctx) == NULL ? "" :
tls_peer_ocsp_result(tls_ctx));
fprintf(stderr,
" response_status=%d cert_status=%d crl_reason=%d\n",
@@ -1692,22 +1757,22 @@ report_tls(struct tls * tls_ctx, char * host)
t = tls_peer_ocsp_this_update(tls_ctx);
fprintf(stderr, " this update: %s",
t != -1 ? ctime(&t) : "\n");
- t = tls_peer_ocsp_next_update(tls_ctx);
+ t = tls_peer_ocsp_next_update(tls_ctx);
fprintf(stderr, " next update: %s",
t != -1 ? ctime(&t) : "\n");
- t = tls_peer_ocsp_revocation_time(tls_ctx);
+ t = tls_peer_ocsp_revocation_time(tls_ctx);
fprintf(stderr, " revocation: %s",
t != -1 ? ctime(&t) : "\n");
break;
case -1:
break;
default:
- fprintf(stderr, "OCSP Stapling: failure - response_status %d (%s)\n",
+ fprintf(stderr,
+ "OCSP Stapling: failure - response_status %d (%s)\n",
tls_peer_ocsp_response_status(tls_ctx),
- tls_peer_ocsp_result(tls_ctx) == NULL ? "" :
+ tls_peer_ocsp_result(tls_ctx) == NULL ? "" :
tls_peer_ocsp_result(tls_ctx));
break;
-
}
}
@@ -1727,12 +1792,15 @@ report_sock(const char *msg, const struct sockaddr *sa, socklen_t salen,
if (nflag)
flags |= NI_NUMERICHOST;
- if ((herr = getnameinfo(sa, salen, host, sizeof(host),
- port, sizeof(port), flags)) != 0) {
- if (herr == EAI_SYSTEM)
- err(1, "getnameinfo");
- else
- errx(1, "getnameinfo: %s", gai_strerror(herr));
+ herr = getnameinfo(sa, salen, host, sizeof(host), port, sizeof(port),
+ flags);
+ switch (herr) {
+ case 0:
+ break;
+ case EAI_SYSTEM:
+ err(1, "getnameinfo");
+ default:
+ errx(1, "getnameinfo: %s", gai_strerror(herr));
}
fprintf(stderr, "%s on %s %s\n", msg, host, port);
@@ -1769,7 +1837,7 @@ help(void)
\t-R CAfile CA bundle\n\
\t-r Randomize remote ports\n\
\t-S Enable the TCP MD5 signature option\n\
- \t-s source Local source address\n\
+ \t-s sourceaddr Local source address\n\
\t-T keyword TOS value or TLS options\n\
\t-t Answer TELNET negotiation\n\
\t-U Use UNIX domain socket\n\
@@ -1795,7 +1863,7 @@ usage(int ret)
"\t [-i interval] [-K keyfile] [-M ttl] [-m minttl] [-O length]\n"
"\t [-o staplefile] [-P proxy_username] [-p source_port] "
"[-R CAfile]\n"
- "\t [-s source] [-T keyword] [-V rtable] [-W recvlimit] "
+ "\t [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit] "
"[-w timeout]\n"
"\t [-X proxy_protocol] [-x proxy_address[:port]] "
"[-Z peercertfile]\n"
diff --git a/socks.c b/socks.c
index 856c3e744633..7c7448c9c5ff 100644
--- a/socks.c
+++ b/socks.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: socks.c,v 1.27 2019/01/10 12:44:54 mestre Exp $ */
+/* $OpenBSD: socks.c,v 1.31 2022/06/08 20:20:26 djm Exp $ */
/*
* Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
@@ -53,7 +53,7 @@
#define SOCKS_DOMAIN 3
#define SOCKS_IPV6 4
-int remote_connect(const char *, const char *, struct addrinfo);
+int remote_connect(const char *, const char *, struct addrinfo, char *);
int socks_connect(const char *, const char *, struct addrinfo,
const char *, const char *, struct addrinfo, int,
const char *);
@@ -201,7 +201,7 @@ socks_connect(const char *host, const char *port,
if (authretry++ > 3)
errx(1, "Too many authentication failures");
- proxyfd = remote_connect(proxyhost, proxyport, proxyhints);
+ proxyfd = remote_connect(proxyhost, proxyport, proxyhints, NULL);
if (proxyfd < 0)
return (-1);
@@ -321,7 +321,7 @@ socks_connect(const char *host, const char *port,
/* HTTP proxy CONNECT */
/* Disallow bad chars in hostname */
- if (strcspn(host, "\r\n\t []:") != strlen(host))
+ if (strcspn(host, "\r\n\t []") != strlen(host))
errx(1, "Invalid hostname");
/* Try to be sane about numeric IPv6 addresses */
@@ -334,7 +334,7 @@ socks_connect(const char *host, const char *port,
"CONNECT %s:%d HTTP/1.0\r\n",
host, ntohs(serverport));
}
- if (r == -1 || (size_t)r >= sizeof(buf))
+ if (r < 0 || (size_t)r >= sizeof(buf))
errx(1, "hostname too long");
r = strlen(buf);
@@ -357,7 +357,7 @@ socks_connect(const char *host, const char *port,
errx(1, "Proxy username/password too long");
r = snprintf(buf, sizeof(buf), "Proxy-Authorization: "
"Basic %s\r\n", resp);
- if (r == -1 || (size_t)r >= sizeof(buf))
+ if (r < 0 || (size_t)r >= sizeof(buf))
errx(1, "Proxy auth response too long");
r = strlen(buf);
if ((cnt = atomicio(vwrite, proxyfd, buf, r)) != r)
@@ -373,7 +373,8 @@ socks_connect(const char *host, const char *port,
/* Read status reply */
proxy_read_line(proxyfd, buf, sizeof(buf));
if (proxyuser != NULL &&
- strncmp(buf, "HTTP/1.0 407 ", 12) == 0) {
+ (strncmp(buf, "HTTP/1.0 407 ", 12) == 0 ||
+ strncmp(buf, "HTTP/1.1 407 ", 12) == 0)) {
if (authretry > 1) {
fprintf(stderr, "Proxy authentication "
"failed\n");