summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/mux.c
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2017-09-02 21:58:42 +0000
committerdes <des@FreeBSD.org>2017-09-02 21:58:42 +0000
commitca26403304720e30901aa6f7bde4883af9662d2d (patch)
tree24e8f197b92c6ecd99617ac7584b6ba544a46aec /crypto/openssh/mux.c
parentce0d6faba2a9fd27ff0fc0942a4e51f5203bb88f (diff)
downloadFreeBSD-src-ca26403304720e30901aa6f7bde4883af9662d2d.zip
FreeBSD-src-ca26403304720e30901aa6f7bde4883af9662d2d.tar.gz
MFH (r314306,r314720): Upgrade OpenSSH to 7.4p1.
Diffstat (limited to 'crypto/openssh/mux.c')
-rw-r--r--crypto/openssh/mux.c78
1 files changed, 68 insertions, 10 deletions
diff --git a/crypto/openssh/mux.c b/crypto/openssh/mux.c
index 3ecebbe..b21df15 100644
--- a/crypto/openssh/mux.c
+++ b/crypto/openssh/mux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mux.c,v 1.60 2016/06/03 03:14:41 dtucker Exp $ */
+/* $OpenBSD: mux.c,v 1.63 2016/10/19 23:21:56 dtucker Exp $ */
/*
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
*
@@ -80,6 +80,7 @@ __RCSID("$FreeBSD$");
#include "key.h"
#include "readconf.h"
#include "clientloop.h"
+#include "ssherr.h"
/* from ssh.c */
extern int tty_flag;
@@ -145,6 +146,7 @@ struct mux_master_state {
#define MUX_C_CLOSE_FWD 0x10000007
#define MUX_C_NEW_STDIO_FWD 0x10000008
#define MUX_C_STOP_LISTENING 0x10000009
+#define MUX_C_PROXY 0x1000000f
#define MUX_S_OK 0x80000001
#define MUX_S_PERMISSION_DENIED 0x80000002
#define MUX_S_FAILURE 0x80000003
@@ -153,6 +155,7 @@ struct mux_master_state {
#define MUX_S_SESSION_OPENED 0x80000006
#define MUX_S_REMOTE_PORT 0x80000007
#define MUX_S_TTY_ALLOC_FAIL 0x80000008
+#define MUX_S_PROXY 0x8000000f
/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */
#define MUX_FWD_LOCAL 1
@@ -170,6 +173,7 @@ static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *);
static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *);
static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *);
static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *);
+static int process_mux_proxy(u_int, Channel *, Buffer *, Buffer *);
static const struct {
u_int type;
@@ -183,6 +187,7 @@ static const struct {
{ MUX_C_CLOSE_FWD, process_mux_close_fwd },
{ MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd },
{ MUX_C_STOP_LISTENING, process_mux_stop_listening },
+ { MUX_C_PROXY, process_mux_proxy },
{ 0, NULL }
};
@@ -1111,6 +1116,18 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
return 0;
}
+static int
+process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r)
+{
+ debug("%s: channel %d: proxy request", __func__, c->self);
+
+ c->mux_rcb = channel_proxy_downstream;
+ buffer_put_int(r, MUX_S_PROXY);
+ buffer_put_int(r, rid);
+
+ return 0;
+}
+
/* Channel callbacks fired on read/write from mux slave fd */
static int
mux_master_read_cb(Channel *c)
@@ -1961,6 +1978,41 @@ mux_client_request_session(int fd)
}
static int
+mux_client_proxy(int fd)
+{
+ Buffer m;
+ char *e;
+ u_int type, rid;
+
+ buffer_init(&m);
+ buffer_put_int(&m, MUX_C_PROXY);
+ buffer_put_int(&m, muxclient_request_id);
+ if (mux_client_write_packet(fd, &m) != 0)
+ fatal("%s: write packet: %s", __func__, strerror(errno));
+
+ buffer_clear(&m);
+
+ /* Read their reply */
+ if (mux_client_read_packet(fd, &m) != 0) {
+ buffer_free(&m);
+ return 0;
+ }
+ type = buffer_get_int(&m);
+ if (type != MUX_S_PROXY) {
+ e = buffer_get_string(&m, NULL);
+ fatal("%s: master returned error: %s", __func__, e);
+ }
+ if ((rid = buffer_get_int(&m)) != muxclient_request_id)
+ fatal("%s: out of sequence reply: my id %u theirs %u",
+ __func__, muxclient_request_id, rid);
+ buffer_free(&m);
+
+ debug3("%s: done", __func__);
+ muxclient_request_id++;
+ return 0;
+}
+
+static int
mux_client_request_stdio_fwd(int fd)
{
Buffer m;
@@ -2106,7 +2158,7 @@ mux_client_request_stop_listening(int fd)
}
/* Multiplex client main loop. */
-void
+int
muxclient(const char *path)
{
struct sockaddr_un addr;
@@ -2129,7 +2181,7 @@ muxclient(const char *path)
case SSHCTL_MASTER_NO:
break;
default:
- return;
+ return -1;
}
memset(&addr, '\0', sizeof(addr));
@@ -2139,7 +2191,8 @@ muxclient(const char *path)
if (strlcpy(addr.sun_path, path,
sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
- fatal("ControlPath too long");
+ fatal("ControlPath too long ('%s' >= %u bytes)", path,
+ (unsigned int)sizeof(addr.sun_path));
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
fatal("%s socket(): %s", __func__, strerror(errno));
@@ -2164,14 +2217,14 @@ muxclient(const char *path)
strerror(errno));
}
close(sock);
- return;
+ return -1;
}
set_nonblock(sock);
if (mux_client_hello_exchange(sock) != 0) {
error("%s: master hello exchange failed", __func__);
close(sock);
- return;
+ return -1;
}
switch (muxclient_command) {
@@ -2182,7 +2235,8 @@ muxclient(const char *path)
exit(0);
case SSHMUX_COMMAND_TERMINATE:
mux_client_request_terminate(sock);
- fprintf(stderr, "Exit request sent.\r\n");
+ if (options.log_level != SYSLOG_LEVEL_QUIET)
+ fprintf(stderr, "Exit request sent.\r\n");
exit(0);
case SSHMUX_COMMAND_FORWARD:
if (mux_client_forwards(sock, 0) != 0)
@@ -2191,22 +2245,26 @@ muxclient(const char *path)
case SSHMUX_COMMAND_OPEN:
if (mux_client_forwards(sock, 0) != 0) {
error("%s: master forward request failed", __func__);
- return;
+ return -1;
}
mux_client_request_session(sock);
- return;
+ return -1;
case SSHMUX_COMMAND_STDIO_FWD:
mux_client_request_stdio_fwd(sock);
exit(0);
case SSHMUX_COMMAND_STOP:
mux_client_request_stop_listening(sock);
- fprintf(stderr, "Stop listening request sent.\r\n");
+ if (options.log_level != SYSLOG_LEVEL_QUIET)
+ fprintf(stderr, "Stop listening request sent.\r\n");
exit(0);
case SSHMUX_COMMAND_CANCEL_FWD:
if (mux_client_forwards(sock, 1) != 0)
error("%s: master cancel forward request failed",
__func__);
exit(0);
+ case SSHMUX_COMMAND_PROXY:
+ mux_client_proxy(sock);
+ return (sock);
default:
fatal("unrecognised muxclient_command %d", muxclient_command);
}
OpenPOWER on IntegriCloud