summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/clientloop.c
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2005-06-05 15:40:50 +0000
committerdes <des@FreeBSD.org>2005-06-05 15:40:50 +0000
commit11a09ab416e21c995885dc0e5847151627094217 (patch)
tree7767975616a98948a7ef791c43b28a21711a22c7 /crypto/openssh/clientloop.c
parentd5d493f03ae792146848e3cba16bb9e667c73125 (diff)
downloadFreeBSD-src-11a09ab416e21c995885dc0e5847151627094217.zip
FreeBSD-src-11a09ab416e21c995885dc0e5847151627094217.tar.gz
Vendor import of OpenSSH 4.0p1.
Diffstat (limited to 'crypto/openssh/clientloop.c')
-rw-r--r--crypto/openssh/clientloop.c175
1 files changed, 106 insertions, 69 deletions
diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c
index 0b9a0fb..1e25088 100644
--- a/crypto/openssh/clientloop.c
+++ b/crypto/openssh/clientloop.c
@@ -59,7 +59,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.130 2004/08/11 21:43:04 avsm Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.135 2005/03/01 10:09:52 djm Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -432,8 +432,6 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
static void
client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
{
- struct winsize oldws, newws;
-
/* Flush stdout and stderr buffers. */
if (buffer_len(bout) > 0)
atomicio(vwrite, fileno(stdout), buffer_ptr(bout), buffer_len(bout));
@@ -450,19 +448,11 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
buffer_free(bout);
buffer_free(berr);
- /* Save old window size. */
- ioctl(fileno(stdin), TIOCGWINSZ, &oldws);
-
/* Send the suspend signal to the program itself. */
kill(getpid(), SIGTSTP);
- /* Check if the window size has changed. */
- if (ioctl(fileno(stdin), TIOCGWINSZ, &newws) >= 0 &&
- (oldws.ws_row != newws.ws_row ||
- oldws.ws_col != newws.ws_col ||
- oldws.ws_xpixel != newws.ws_xpixel ||
- oldws.ws_ypixel != newws.ws_ypixel))
- received_window_change_signal = 1;
+ /* Reset window sizes in case they have changed */
+ received_window_change_signal = 1;
/* OK, we have been continued by the user. Reinitialize buffers. */
buffer_init(bin);
@@ -571,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;
@@ -601,39 +591,74 @@ client_process_control(fd_set * readset)
return;
}
- allowed = 1;
- if (options.control_master == 2) {
- char *p, prompt[1024];
-
- allowed = 0;
- snprintf(prompt, sizeof(prompt),
- "Allow shared connection to %s? ", host);
- p = read_passphrase(prompt, RP_USE_ASKPASS|RP_ALLOW_EOF);
- if (p != NULL) {
- /*
- * Accept empty responses and responses consisting
- * of the word "yes" as affirmative.
- */
- if (*p == '\0' || *p == '\n' ||
- strcasecmp(p, "yes") == 0)
- allowed = 1;
- xfree(p);
- }
- }
-
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");
@@ -642,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);
@@ -658,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);
@@ -692,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);
@@ -732,11 +763,11 @@ static void
process_cmdline(void)
{
void (*handler)(int);
- char *s, *cmd;
- u_short fwd_port, fwd_host_port;
- char buf[1024], sfwd_port[6], sfwd_host_port[6];
+ char *s, *cmd, *cancel_host;
int delete = 0;
int local = 0;
+ u_short cancel_port;
+ Forward fwd;
leave_raw_mode();
handler = signal(SIGINT, SIG_IGN);
@@ -782,37 +813,38 @@ process_cmdline(void)
s++;
if (delete) {
- if (sscanf(s, "%5[0-9]", sfwd_host_port) != 1) {
- logit("Bad forwarding specification.");
- goto out;
+ cancel_port = 0;
+ cancel_host = hpdelim(&s); /* may be NULL */
+ if (s != NULL) {
+ cancel_port = a2port(s);
+ cancel_host = cleanhostname(cancel_host);
+ } else {
+ cancel_port = a2port(cancel_host);
+ cancel_host = NULL;
}
- if ((fwd_host_port = a2port(sfwd_host_port)) == 0) {
- logit("Bad forwarding port(s).");
+ if (cancel_port == 0) {
+ logit("Bad forwarding close port");
goto out;
}
- channel_request_rforward_cancel(fwd_host_port);
+ channel_request_rforward_cancel(cancel_host, cancel_port);
} else {
- if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]",
- sfwd_port, buf, sfwd_host_port) != 3 &&
- sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]",
- sfwd_port, buf, sfwd_host_port) != 3) {
+ if (!parse_forward(&fwd, s)) {
logit("Bad forwarding specification.");
goto out;
}
- if ((fwd_port = a2port(sfwd_port)) == 0 ||
- (fwd_host_port = a2port(sfwd_host_port)) == 0) {
- logit("Bad forwarding port(s).");
- goto out;
- }
if (local) {
- if (channel_setup_local_fwd_listener(fwd_port, buf,
- fwd_host_port, options.gateway_ports) < 0) {
+ if (channel_setup_local_fwd_listener(fwd.listen_host,
+ fwd.listen_port, fwd.connect_host,
+ fwd.connect_port, options.gateway_ports) < 0) {
logit("Port forwarding failed.");
goto out;
}
- } else
- channel_request_remote_forwarding(fwd_port, buf,
- fwd_host_port);
+ } else {
+ channel_request_remote_forwarding(fwd.listen_host,
+ fwd.listen_port, fwd.connect_host,
+ fwd.connect_port);
+ }
+
logit("Forwarding port.");
}
@@ -1196,14 +1228,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
* Set signal handlers, (e.g. to restore non-blocking mode)
* but don't overwrite SIG_IGN, matches behaviour from rsh(1)
*/
+ if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
+ signal(SIGHUP, signal_handler);
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, signal_handler);
if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
signal(SIGQUIT, signal_handler);
if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
signal(SIGTERM, signal_handler);
- if (have_pty)
- signal(SIGWINCH, window_change_handler);
+ signal(SIGWINCH, window_change_handler);
if (have_pty)
enter_raw_mode();
@@ -1311,8 +1344,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/* Terminate the session. */
/* Stop watching for window change. */
- if (have_pty)
- signal(SIGWINCH, SIG_DFL);
+ signal(SIGWINCH, SIG_DFL);
channel_free_all();
@@ -1679,9 +1711,13 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
dispatch_fn *subsys_repl)
{
int len;
+ Channel *c = NULL;
debug2("%s: id %d", __func__, id);
+ if ((c = channel_lookup(id)) == NULL)
+ fatal("client_session2_setup: channel %d: unknown channel", id);
+
if (want_tty) {
struct winsize ws;
struct termios tio;
@@ -1700,6 +1736,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
tty_make_modes(-1, tiop != NULL ? tiop : &tio);
packet_send();
/* XXX wait for reply */
+ c->client_tty = 1;
}
/* Transfer any environment variables from client to server */
OpenPOWER on IntegriCloud