diff options
author | Darren Tucker <dtucker@zip.com.au> | 2004-11-07 20:06:19 +1100 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2004-11-07 20:06:19 +1100 |
commit | 7ebfc10884da0e430966cb323f57de17397f64bc (patch) | |
tree | cb4ab9a4f8cc8378a2c63ca3d46d2f94a2d5c724 /clientloop.c | |
parent | 2d963d87210c6a0c5eadfa5f02c808f6d983b47e (diff) |
- djm@cvs.openbsd.org 2004/11/07 00:01:46
[clientloop.c clientloop.h ssh.1 ssh.c]
add basic control of a running multiplex master connection; including the
ability to check its status and request it to exit; ok markus@
Diffstat (limited to 'clientloop.c')
-rw-r--r-- | clientloop.c | 86 |
1 files changed, 71 insertions, 15 deletions
diff --git a/clientloop.c b/clientloop.c index d77337b8..033a98a5 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.133 2004/10/29 22:53:56 djm Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.134 2004/11/07 00:01:46 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -561,7 +561,7 @@ client_process_control(fd_set * readset) struct sockaddr_storage addr; struct confirm_ctx *cctx; char *cmd; - u_int len, env_len; + u_int len, env_len, command, flags; uid_t euid; gid_t egid; @@ -591,24 +591,74 @@ client_process_control(fd_set * readset) return; } - allowed = 1; - if (options.control_master == 2) - allowed = ask_permission("Allow shared connection to %s? ", - host); - unset_nonblock(client_fd); + /* Read command */ buffer_init(&m); + if (ssh_msg_recv(client_fd, &m) == -1) { + error("%s: client msg_recv failed", __func__); + close(client_fd); + buffer_free(&m); + return; + } + if ((ver = buffer_get_char(&m)) != 1) { + error("%s: wrong client version %d", __func__, ver); + buffer_free(&m); + close(client_fd); + return; + } + + allowed = 1; + command = buffer_get_int(&m); + flags = buffer_get_int(&m); + + buffer_clear(&m); + switch (command) { + case SSHMUX_COMMAND_OPEN: + if (options.control_master == 2) + allowed = ask_permission("Allow shared connection " + "to %s? ", host); + /* continue below */ + break; + case SSHMUX_COMMAND_TERMINATE: + if (options.control_master == 2) + allowed = ask_permission("Terminate shared connection " + "to %s? ", host); + if (allowed) + quit_pending = 1; + /* FALLTHROUGH */ + case SSHMUX_COMMAND_ALIVE_CHECK: + /* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */ + buffer_clear(&m); + buffer_put_int(&m, allowed); + buffer_put_int(&m, getpid()); + if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { + error("%s: client msg_send failed", __func__); + close(client_fd); + buffer_free(&m); + return; + } + buffer_free(&m); + close(client_fd); + return; + default: + error("Unsupported command %d", command); + buffer_free(&m); + close(client_fd); + return; + } + + /* Reply for SSHMUX_COMMAND_OPEN */ + buffer_clear(&m); buffer_put_int(&m, allowed); buffer_put_int(&m, getpid()); - if (ssh_msg_send(client_fd, /* version */0, &m) == -1) { + if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { error("%s: client msg_send failed", __func__); close(client_fd); buffer_free(&m); return; } - buffer_clear(&m); if (!allowed) { error("Refused control connection"); @@ -617,14 +667,14 @@ client_process_control(fd_set * readset) return; } + buffer_clear(&m); if (ssh_msg_recv(client_fd, &m) == -1) { error("%s: client msg_recv failed", __func__); close(client_fd); buffer_free(&m); return; } - - if ((ver = buffer_get_char(&m)) != 0) { + if ((ver = buffer_get_char(&m)) != 1) { error("%s: wrong client version %d", __func__, ver); buffer_free(&m); close(client_fd); @@ -633,9 +683,8 @@ client_process_control(fd_set * readset) cctx = xmalloc(sizeof(*cctx)); memset(cctx, 0, sizeof(*cctx)); - - cctx->want_tty = buffer_get_int(&m); - cctx->want_subsys = buffer_get_int(&m); + cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; + cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; cctx->term = buffer_get_string(&m, &len); cmd = buffer_get_string(&m, &len); @@ -667,14 +716,21 @@ client_process_control(fd_set * readset) if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) error("%s: tcgetattr: %s", __func__, strerror(errno)); + /* This roundtrip is just for synchronisation of ttymodes */ buffer_clear(&m); - if (ssh_msg_send(client_fd, /* version */0, &m) == -1) { + if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { error("%s: client msg_send failed", __func__); close(client_fd); close(new_fd[0]); close(new_fd[1]); close(new_fd[2]); buffer_free(&m); + xfree(cctx->term); + if (env_len != 0) { + for (i = 0; i < env_len; i++) + xfree(cctx->env[i]); + xfree(cctx->env); + } return; } buffer_free(&m); |