Группа :: Безопасность/Сети
Пакет: LibreSSL
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: 0001-ALT-netcat-execcmd.patch
Скачать
Скачать
From 1a80522549d2658a866bcf94842deead45e9f8ee Mon Sep 17 00:00:00 2001
From: "Vladimir D. Seleznev" <vseleznv@altlinux.org>
Date: Mon, 6 Nov 2017 18:41:56 +0300
Subject: [PATCH] ALT: netcat execcmd
---
libressl/apps/nc/nc.1 | 13 +++++++---
libressl/apps/nc/netcat.c | 53 +++++++++++++++++++++++++++++++++++++--
2 files changed, 61 insertions(+), 5 deletions(-)
diff --git a/libressl/apps/nc/nc.1 b/libressl/apps/nc/nc.1
index 0ef318e..4f12508 100644
--- a/libressl/apps/nc/nc.1
+++ b/libressl/apps/nc/nc.1
@@ -35,7 +35,7 @@
.Nm nc
.Op Fl 46cDdFhklNnrStUuvz
.Op Fl C Ar certfile
-.Op Fl e Ar name
+.Op Fl e Ar name | command
.Op Fl H Ar hash
.Op Fl I Ar length
.Op Fl i Ar interval
@@ -113,8 +113,10 @@ Cannot be used together with any of the options
Enable debugging on the socket.
.It Fl d
Do not attempt to read from stdin.
-.It Fl e Ar name
-Only accept the TLS peer certificate if it contains the
+.It Fl e Ar name | command
+Specifies the name that must be present in the peer certificate when using TLS
+or starts specified command for communicating with remote side after connection
+is established when not using TLS.
.Ar name .
Requires
.Fl c .
@@ -564,6 +566,11 @@ The same example again, this time enabling proxy authentication with username
if the proxy requires it:
.Pp
.Dl $ nc -x10.2.3.4:8080 -Xconnect -Pruser host.example.com 42
+.Pp
+Listen on port 1234, send system name to connected client and exit:
+.Pp
+.Dl $ nc -l -v -e 'cat /etc/altlinux-release; uname -a' 1234
+.Pp
.Sh SEE ALSO
.Xr cat 1 ,
.Xr ssh 1
diff --git a/libressl/apps/nc/netcat.c b/libressl/apps/nc/netcat.c
index ad3b4f1..1aa4b6a 100644
--- a/libressl/apps/nc/netcat.c
+++ b/libressl/apps/nc/netcat.c
@@ -113,6 +113,7 @@ char *tls_expecthash; /* required hash of peer cert */
char *tls_ciphers; /* TLS ciphers */
char *tls_protocols; /* TLS protocols */
FILE *Zflag; /* file to save peer cert */
+char *opt_exec = NULL;
int recvcount, recvlimit;
int timeout = -1;
@@ -125,6 +126,7 @@ int minttl = -1;
void atelnet(int, unsigned char *, unsigned int);
int strtoport(char *portstr, int udp);
void build_ports(char *);
+void execcmd(int fd);
void help(void) __attribute__((noreturn));
int local_listen(const char *, const char *, struct addrinfo);
void readwrite(int, struct tls *);
@@ -458,7 +460,7 @@ main(int argc, char *argv[])
if (tls_expecthash && !usetls)
errx(1, "you must specify -c to use -H");
if (tls_expectname && !usetls)
- errx(1, "you must specify -c to use -e");
+ opt_exec = tls_expectname;
/* Get name of temporary socket for unix datagram client */
if ((family == AF_UNIX) && uflag && !lflag) {
@@ -870,6 +872,47 @@ tls_setup_server(struct tls *tls_ctx, int connfd, char *host)
return NULL;
}
+/*
+ * execcmd()
+ * Execute an external file making its stdin/stdout/stderr
+ * the actual socket. Returns never.
+ */
+void
+execcmd(int fd)
+{
+ int saved_stderr;
+ char *p;
+
+ /* save the stderr fd because we may need it later */
+ saved_stderr=dup(STDERR_FILENO);
+
+ /* duplicate the socket for the child program */
+ if (fd != STDIN_FILENO) {
+ dup2(fd, STDIN_FILENO); /* the precise order of fiddlage */
+ close(fd); /* is apparently crucial; this is */
+ }
+ dup2(STDIN_FILENO, STDOUT_FILENO); /* swiped directly out of "inetd". */
+ dup2(STDIN_FILENO, STDERR_FILENO); /* also duplicate the stderr channel */
+
+ /* change the label for the executed program */
+ if ((p = strrchr(opt_exec, '/'))) {
+ p++; /* shorter argv[0] */
+ } else {
+ p = opt_exec;
+ }
+
+ /* replace this process with the new one */
+#ifndef USE_OLD_COMPAT
+ execl("/bin/sh", p, "-c", opt_exec, NULL);
+#else
+ execl(opt_exec, p, NULL);
+#endif
+ dup2(saved_stderr, STDERR_FILENO);
+ err(1, "couldn't execute %s ", opt_exec);
+}
+
+
+
/*
* unix_connect()
* Returns a socket connected to a local unix socket. Returns -1 on failure.
@@ -1129,6 +1172,12 @@ readwrite(int net_fd, struct tls *tls_ctx)
int n, num_fds;
ssize_t ret;
+ if (opt_exec) {
+ if (vflag)
+ printf("Call sub-process %s\n", opt_exec);
+ execcmd(net_fd);
+ }
+
/* don't read from stdin if requested */
if (dflag)
stdin_fd = -1;
@@ -1889,7 +1938,7 @@ void
usage(int ret)
{
fprintf(stderr,
- "usage: nc [-46cDdFhklNnrStUuvz] [-C certfile] [-e name] "
+ "usage: nc [-46cDdFhklNnrStUuvz] [-C certfile] [-e name | cmd] "
"[-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] "
--
2.33.7