Changeset View
Changeset View
Standalone View
Standalone View
mux.c
/* $OpenBSD: mux.c,v 1.77 2018/09/26 07:32:44 djm Exp $ */ | /* $OpenBSD: mux.c,v 1.80 2019/06/28 13:35:04 deraadt Exp $ */ | ||||
/* | /* | ||||
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> | * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> | ||||
* | * | ||||
* Permission to use, copy, modify, and distribute this software for any | * Permission to use, copy, modify, and distribute this software for any | ||||
* purpose with or without fee is hereby granted, provided that the above | * purpose with or without fee is hereby granted, provided that the above | ||||
* copyright notice and this permission notice appear in all copies. | * copyright notice and this permission notice appear in all copies. | ||||
* | * | ||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
▲ Show 20 Lines • Show All 595 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) | mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) | ||||
{ | { | ||||
struct mux_channel_confirm_ctx *fctx = ctxt; | struct mux_channel_confirm_ctx *fctx = ctxt; | ||||
char *failmsg = NULL; | char *failmsg = NULL; | ||||
struct Forward *rfwd; | struct Forward *rfwd; | ||||
Channel *c; | Channel *c; | ||||
struct sshbuf *out; | struct sshbuf *out; | ||||
u_int port; | |||||
int r; | int r; | ||||
if ((c = channel_by_id(ssh, fctx->cid)) == NULL) { | if ((c = channel_by_id(ssh, fctx->cid)) == NULL) { | ||||
/* no channel for reply */ | /* no channel for reply */ | ||||
error("%s: unknown channel", __func__); | error("%s: unknown channel", __func__); | ||||
return; | return; | ||||
} | } | ||||
if ((out = sshbuf_new()) == NULL) | if ((out = sshbuf_new()) == NULL) | ||||
fatal("%s: sshbuf_new", __func__); | fatal("%s: sshbuf_new", __func__); | ||||
if (fctx->fid >= options.num_remote_forwards || | if (fctx->fid >= options.num_remote_forwards || | ||||
(options.remote_forwards[fctx->fid].connect_path == NULL && | (options.remote_forwards[fctx->fid].connect_path == NULL && | ||||
options.remote_forwards[fctx->fid].connect_host == NULL)) { | options.remote_forwards[fctx->fid].connect_host == NULL)) { | ||||
xasprintf(&failmsg, "unknown forwarding id %d", fctx->fid); | xasprintf(&failmsg, "unknown forwarding id %d", fctx->fid); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
rfwd = &options.remote_forwards[fctx->fid]; | rfwd = &options.remote_forwards[fctx->fid]; | ||||
debug("%s: %s for: listen %d, connect %s:%d", __func__, | debug("%s: %s for: listen %d, connect %s:%d", __func__, | ||||
type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", | ||||
rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path : | rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path : | ||||
rfwd->connect_host, rfwd->connect_port); | rfwd->connect_host, rfwd->connect_port); | ||||
if (type == SSH2_MSG_REQUEST_SUCCESS) { | if (type == SSH2_MSG_REQUEST_SUCCESS) { | ||||
if (rfwd->listen_port == 0) { | if (rfwd->listen_port == 0) { | ||||
rfwd->allocated_port = packet_get_int(); | if ((r = sshpkt_get_u32(ssh, &port)) != 0) | ||||
fatal("%s: packet error: %s", | |||||
__func__, ssh_err(r)); | |||||
if (port > 65535) { | |||||
fatal("Invalid allocated port %u for " | |||||
"mux remote forward to %s:%d", port, | |||||
rfwd->connect_host, rfwd->connect_port); | |||||
} | |||||
rfwd->allocated_port = (int)port; | |||||
debug("Allocated port %u for mux remote forward" | debug("Allocated port %u for mux remote forward" | ||||
" to %s:%d", rfwd->allocated_port, | " to %s:%d", rfwd->allocated_port, | ||||
rfwd->connect_host, rfwd->connect_port); | rfwd->connect_host, rfwd->connect_port); | ||||
if ((r = sshbuf_put_u32(out, | if ((r = sshbuf_put_u32(out, | ||||
MUX_S_REMOTE_PORT)) != 0 || | MUX_S_REMOTE_PORT)) != 0 || | ||||
(r = sshbuf_put_u32(out, fctx->rid)) != 0 || | (r = sshbuf_put_u32(out, fctx->rid)) != 0 || | ||||
(r = sshbuf_put_u32(out, | (r = sshbuf_put_u32(out, | ||||
rfwd->allocated_port)) != 0) | rfwd->allocated_port)) != 0) | ||||
▲ Show 20 Lines • Show All 757 Lines • ▼ Show 20 Lines | if (client_x11_get_proto(ssh, display, options.xauth_location, | ||||
client_expect_confirm(ssh, id, "X11 forwarding", | client_expect_confirm(ssh, id, "X11 forwarding", | ||||
CONFIRM_WARN); | CONFIRM_WARN); | ||||
} | } | ||||
} | } | ||||
if (cctx->want_agent_fwd && options.forward_agent) { | if (cctx->want_agent_fwd && options.forward_agent) { | ||||
debug("Requesting authentication agent forwarding."); | debug("Requesting authentication agent forwarding."); | ||||
channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0); | channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0); | ||||
packet_send(); | if ((r = sshpkt_send(ssh)) != 0) | ||||
fatal("%s: packet error: %s", __func__, ssh_err(r)); | |||||
} | } | ||||
client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys, | client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys, | ||||
cctx->term, &cctx->tio, c->rfd, cctx->cmd, cctx->env); | cctx->term, &cctx->tio, c->rfd, cctx->cmd, cctx->env); | ||||
debug3("%s: sending success reply", __func__); | debug3("%s: sending success reply", __func__); | ||||
/* prepare reply */ | /* prepare reply */ | ||||
if ((r = sshbuf_put_u32(reply, MUX_S_SESSION_OPENED)) != 0 || | if ((r = sshbuf_put_u32(reply, MUX_S_SESSION_OPENED)) != 0 || | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | mux_client_read(int fd, struct sshbuf *b, size_t need) | ||||
if ((r = sshbuf_reserve(b, need, &p)) != 0) | if ((r = sshbuf_reserve(b, need, &p)) != 0) | ||||
fatal("%s: reserve: %s", __func__, ssh_err(r)); | fatal("%s: reserve: %s", __func__, ssh_err(r)); | ||||
for (have = 0; have < need; ) { | for (have = 0; have < need; ) { | ||||
if (muxclient_terminate) { | if (muxclient_terminate) { | ||||
errno = EINTR; | errno = EINTR; | ||||
return -1; | return -1; | ||||
} | } | ||||
len = read(fd, p + have, need - have); | len = read(fd, p + have, need - have); | ||||
if (len < 0) { | if (len == -1) { | ||||
switch (errno) { | switch (errno) { | ||||
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) | #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) | ||||
case EWOULDBLOCK: | case EWOULDBLOCK: | ||||
#endif | #endif | ||||
case EAGAIN: | case EAGAIN: | ||||
(void)poll(&pfd, 1, -1); | (void)poll(&pfd, 1, -1); | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case EINTR: | case EINTR: | ||||
Show All 32 Lines | mux_client_write_packet(int fd, struct sshbuf *m) | ||||
for (have = 0; have < need; ) { | for (have = 0; have < need; ) { | ||||
if (muxclient_terminate) { | if (muxclient_terminate) { | ||||
sshbuf_free(queue); | sshbuf_free(queue); | ||||
errno = EINTR; | errno = EINTR; | ||||
return -1; | return -1; | ||||
} | } | ||||
len = write(fd, ptr + have, need - have); | len = write(fd, ptr + have, need - have); | ||||
if (len < 0) { | if (len == -1) { | ||||
switch (errno) { | switch (errno) { | ||||
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) | #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) | ||||
case EWOULDBLOCK: | case EWOULDBLOCK: | ||||
#endif | #endif | ||||
case EAGAIN: | case EAGAIN: | ||||
(void)poll(&pfd, 1, -1); | (void)poll(&pfd, 1, -1); | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case EINTR: | case EINTR: | ||||
▲ Show 20 Lines • Show All 766 Lines • ▼ Show 20 Lines | muxclient(const char *path) | ||||
memset(&addr, '\0', sizeof(addr)); | memset(&addr, '\0', sizeof(addr)); | ||||
addr.sun_family = AF_UNIX; | addr.sun_family = AF_UNIX; | ||||
if (strlcpy(addr.sun_path, path, | if (strlcpy(addr.sun_path, path, | ||||
sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) | sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) | ||||
fatal("ControlPath too long ('%s' >= %u bytes)", path, | fatal("ControlPath too long ('%s' >= %u bytes)", path, | ||||
(unsigned int)sizeof(addr.sun_path)); | (unsigned int)sizeof(addr.sun_path)); | ||||
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) | if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) | ||||
fatal("%s socket(): %s", __func__, strerror(errno)); | fatal("%s socket(): %s", __func__, strerror(errno)); | ||||
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) { | if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) { | ||||
switch (muxclient_command) { | switch (muxclient_command) { | ||||
case SSHMUX_COMMAND_OPEN: | case SSHMUX_COMMAND_OPEN: | ||||
case SSHMUX_COMMAND_STDIO_FWD: | case SSHMUX_COMMAND_STDIO_FWD: | ||||
break; | break; | ||||
default: | default: | ||||
▲ Show 20 Lines • Show All 66 Lines • Show Last 20 Lines |