summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c75
1 files changed, 40 insertions, 35 deletions
diff --git a/clientloop.c b/clientloop.c
index 141e0fff5..e5ea74e26 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.213 2009/07/05 19:28:33 stevesk Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.218 2010/01/28 00:21:18 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -125,7 +125,7 @@ extern int stdin_null_flag;
125extern int no_shell_flag; 125extern int no_shell_flag;
126 126
127/* Control socket */ 127/* Control socket */
128extern int muxserver_sock; 128extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
129 129
130/* 130/*
131 * Name of the host we are connecting to. This is the name given on the 131 * Name of the host we are connecting to. This is the name given on the
@@ -134,6 +134,9 @@ extern int muxserver_sock;
134 */ 134 */
135extern char *host; 135extern char *host;
136 136
137/* Force TTY allocation */
138extern int force_tty_flag;
139
137/* 140/*
138 * Flag to indicate that we have received a window change signal which has 141 * Flag to indicate that we have received a window change signal which has
139 * not yet been processed. This will cause a message indicating the new 142 * not yet been processed. This will cause a message indicating the new
@@ -147,7 +150,7 @@ static volatile sig_atomic_t received_signal = 0;
147static int in_non_blocking_mode = 0; 150static int in_non_blocking_mode = 0;
148 151
149/* Common data for the client loop code. */ 152/* Common data for the client loop code. */
150static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ 153volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
151static int escape_char1; /* Escape character. (proto1 only) */ 154static int escape_char1; /* Escape character. (proto1 only) */
152static int escape_pending1; /* Last character was an escape (proto1 only) */ 155static int escape_pending1; /* Last character was an escape (proto1 only) */
153static int last_was_cr; /* Last character was a newline. */ 156static int last_was_cr; /* Last character was a newline. */
@@ -165,6 +168,8 @@ static int session_closed = 0; /* In SSH2: login session closed. */
165static void client_init_dispatch(void); 168static void client_init_dispatch(void);
166int session_ident = -1; 169int session_ident = -1;
167 170
171int session_resumed = 0;
172
168/* Track escape per proto2 channel */ 173/* Track escape per proto2 channel */
169struct escape_filter_ctx { 174struct escape_filter_ctx {
170 int escape_pending; 175 int escape_pending;
@@ -563,9 +568,6 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
563 if (packet_have_data_to_write()) 568 if (packet_have_data_to_write())
564 FD_SET(connection_out, *writesetp); 569 FD_SET(connection_out, *writesetp);
565 570
566 if (muxserver_sock != -1)
567 FD_SET(muxserver_sock, *readsetp);
568
569 /* 571 /*
570 * Wait for something to happen. This will suspend the process until 572 * Wait for something to happen. This will suspend the process until
571 * some selected descriptor can be read, written, or has some other 573 * some selected descriptor can be read, written, or has some other
@@ -612,7 +614,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
612 atomicio(vwrite, fileno(stderr), buffer_ptr(berr), 614 atomicio(vwrite, fileno(stderr), buffer_ptr(berr),
613 buffer_len(berr)); 615 buffer_len(berr));
614 616
615 leave_raw_mode(); 617 leave_raw_mode(force_tty_flag);
616 618
617 /* 619 /*
618 * Free (and clear) the buffer to reduce the amount of data that gets 620 * Free (and clear) the buffer to reduce the amount of data that gets
@@ -633,7 +635,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
633 buffer_init(bout); 635 buffer_init(bout);
634 buffer_init(berr); 636 buffer_init(berr);
635 637
636 enter_raw_mode(); 638 enter_raw_mode(force_tty_flag);
637} 639}
638 640
639static void 641static void
@@ -694,7 +696,7 @@ client_status_confirm(int type, Channel *c, void *ctx)
694 696
695 /* XXX supress on mux _client_ quietmode */ 697 /* XXX supress on mux _client_ quietmode */
696 tochan = options.log_level >= SYSLOG_LEVEL_ERROR && 698 tochan = options.log_level >= SYSLOG_LEVEL_ERROR &&
697 c->ctl_fd != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; 699 c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
698 700
699 if (type == SSH2_MSG_CHANNEL_SUCCESS) { 701 if (type == SSH2_MSG_CHANNEL_SUCCESS) {
700 debug2("%s request accepted on channel %d", 702 debug2("%s request accepted on channel %d",
@@ -776,7 +778,7 @@ process_cmdline(void)
776 bzero(&fwd, sizeof(fwd)); 778 bzero(&fwd, sizeof(fwd));
777 fwd.listen_host = fwd.connect_host = NULL; 779 fwd.listen_host = fwd.connect_host = NULL;
778 780
779 leave_raw_mode(); 781 leave_raw_mode(force_tty_flag);
780 handler = signal(SIGINT, SIG_IGN); 782 handler = signal(SIGINT, SIG_IGN);
781 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); 783 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
782 if (s == NULL) 784 if (s == NULL)
@@ -838,6 +840,7 @@ process_cmdline(void)
838 while (isspace(*++s)) 840 while (isspace(*++s))
839 ; 841 ;
840 842
843 /* XXX update list of forwards in options */
841 if (delete) { 844 if (delete) {
842 cancel_port = 0; 845 cancel_port = 0;
843 cancel_host = hpdelim(&s); /* may be NULL */ 846 cancel_host = hpdelim(&s); /* may be NULL */
@@ -879,7 +882,7 @@ process_cmdline(void)
879 882
880out: 883out:
881 signal(SIGINT, handler); 884 signal(SIGINT, handler);
882 enter_raw_mode(); 885 enter_raw_mode(force_tty_flag);
883 if (cmd) 886 if (cmd)
884 xfree(cmd); 887 xfree(cmd);
885 if (fwd.listen_host != NULL) 888 if (fwd.listen_host != NULL)
@@ -935,7 +938,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
935 escape_char); 938 escape_char);
936 buffer_append(berr, string, strlen(string)); 939 buffer_append(berr, string, strlen(string));
937 940
938 if (c && c->ctl_fd != -1) { 941 if (c && c->ctl_chan != -1) {
939 chan_read_failed(c); 942 chan_read_failed(c);
940 chan_write_failed(c); 943 chan_write_failed(c);
941 return 0; 944 return 0;
@@ -945,7 +948,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
945 948
946 case 'Z' - 64: 949 case 'Z' - 64:
947 /* XXX support this for mux clients */ 950 /* XXX support this for mux clients */
948 if (c && c->ctl_fd != -1) { 951 if (c && c->ctl_chan != -1) {
949 noescape: 952 noescape:
950 snprintf(string, sizeof string, 953 snprintf(string, sizeof string,
951 "%c%c escape not available to " 954 "%c%c escape not available to "
@@ -990,7 +993,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
990 continue; 993 continue;
991 994
992 case '&': 995 case '&':
993 if (c && c->ctl_fd != -1) 996 if (c && c->ctl_chan != -1)
994 goto noescape; 997 goto noescape;
995 /* 998 /*
996 * Detach the program (continue to serve 999 * Detach the program (continue to serve
@@ -998,7 +1001,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
998 * more new connections). 1001 * more new connections).
999 */ 1002 */
1000 /* Restore tty modes. */ 1003 /* Restore tty modes. */
1001 leave_raw_mode(); 1004 leave_raw_mode(force_tty_flag);
1002 1005
1003 /* Stop listening for new connections. */ 1006 /* Stop listening for new connections. */
1004 channel_stop_listening(); 1007 channel_stop_listening();
@@ -1041,7 +1044,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1041 continue; 1044 continue;
1042 1045
1043 case '?': 1046 case '?':
1044 if (c && c->ctl_fd != -1) { 1047 if (c && c->ctl_chan != -1) {
1045 snprintf(string, sizeof string, 1048 snprintf(string, sizeof string,
1046"%c?\r\n\ 1049"%c?\r\n\
1047Supported escape sequences:\r\n\ 1050Supported escape sequences:\r\n\
@@ -1090,7 +1093,7 @@ Supported escape sequences:\r\n\
1090 continue; 1093 continue;
1091 1094
1092 case 'C': 1095 case 'C':
1093 if (c && c->ctl_fd != -1) 1096 if (c && c->ctl_chan != -1)
1094 goto noescape; 1097 goto noescape;
1095 process_cmdline(); 1098 process_cmdline();
1096 continue; 1099 continue;
@@ -1293,7 +1296,7 @@ client_channel_closed(int id, void *arg)
1293{ 1296{
1294 channel_cancel_cleanup(id); 1297 channel_cancel_cleanup(id);
1295 session_closed = 1; 1298 session_closed = 1;
1296 leave_raw_mode(); 1299 leave_raw_mode(force_tty_flag);
1297} 1300}
1298 1301
1299/* 1302/*
@@ -1326,8 +1329,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1326 connection_in = packet_get_connection_in(); 1329 connection_in = packet_get_connection_in();
1327 connection_out = packet_get_connection_out(); 1330 connection_out = packet_get_connection_out();
1328 max_fd = MAX(connection_in, connection_out); 1331 max_fd = MAX(connection_in, connection_out);
1329 if (muxserver_sock != -1)
1330 max_fd = MAX(max_fd, muxserver_sock);
1331 1332
1332 if (!compat20) { 1333 if (!compat20) {
1333 /* enable nonblocking unless tty */ 1334 /* enable nonblocking unless tty */
@@ -1366,7 +1367,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1366 signal(SIGWINCH, window_change_handler); 1367 signal(SIGWINCH, window_change_handler);
1367 1368
1368 if (have_pty) 1369 if (have_pty)
1369 enter_raw_mode(); 1370 enter_raw_mode(force_tty_flag);
1370 1371
1371 if (compat20) { 1372 if (compat20) {
1372 session_ident = ssh2_chan_id; 1373 session_ident = ssh2_chan_id;
@@ -1454,12 +1455,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1454 /* Buffer input from the connection. */ 1455 /* Buffer input from the connection. */
1455 client_process_net_input(readset); 1456 client_process_net_input(readset);
1456 1457
1457 /* Accept control connections. */
1458 if (muxserver_sock != -1 &&FD_ISSET(muxserver_sock, readset)) {
1459 if (muxserver_accept_control())
1460 quit_pending = 1;
1461 }
1462
1463 if (quit_pending) 1458 if (quit_pending)
1464 break; 1459 break;
1465 1460
@@ -1473,6 +1468,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1473 client_process_output(writeset); 1468 client_process_output(writeset);
1474 } 1469 }
1475 1470
1471 if (session_resumed) {
1472 connection_in = packet_get_connection_in();
1473 connection_out = packet_get_connection_out();
1474 max_fd = MAX(max_fd, connection_out);
1475 max_fd = MAX(max_fd, connection_in);
1476 session_resumed = 0;
1477 }
1478
1476 /* 1479 /*
1477 * Send as much buffered packet data as possible to the 1480 * Send as much buffered packet data as possible to the
1478 * sender. 1481 * sender.
@@ -1501,7 +1504,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1501 channel_free_all(); 1504 channel_free_all();
1502 1505
1503 if (have_pty) 1506 if (have_pty)
1504 leave_raw_mode(); 1507 leave_raw_mode(force_tty_flag);
1505 1508
1506 /* restore blocking io */ 1509 /* restore blocking io */
1507 if (!isatty(fileno(stdin))) 1510 if (!isatty(fileno(stdin)))
@@ -1859,15 +1862,17 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
1859 chan_rcvd_eow(c); 1862 chan_rcvd_eow(c);
1860 } else if (strcmp(rtype, "exit-status") == 0) { 1863 } else if (strcmp(rtype, "exit-status") == 0) {
1861 exitval = packet_get_int(); 1864 exitval = packet_get_int();
1862 if (id == session_ident) { 1865 if (c->ctl_chan != -1) {
1866 mux_exit_message(c, exitval);
1867 success = 1;
1868 } else if (id == session_ident) {
1869 /* Record exit value of local session */
1863 success = 1; 1870 success = 1;
1864 exit_status = exitval; 1871 exit_status = exitval;
1865 } else if (c->ctl_fd == -1) {
1866 error("client_input_channel_req: unexpected channel %d",
1867 session_ident);
1868 } else { 1872 } else {
1869 atomicio(vwrite, c->ctl_fd, &exitval, sizeof(exitval)); 1873 /* Probably for a mux channel that has already closed */
1870 success = 1; 1874 debug("%s: no sink for exit-status on channel %d",
1875 __func__, id);
1871 } 1876 }
1872 packet_check_eom(); 1877 packet_check_eom();
1873 } 1878 }
@@ -2063,7 +2068,7 @@ client_init_dispatch(void)
2063void 2068void
2064cleanup_exit(int i) 2069cleanup_exit(int i)
2065{ 2070{
2066 leave_raw_mode(); 2071 leave_raw_mode(force_tty_flag);
2067 leave_non_blocking(); 2072 leave_non_blocking();
2068 if (options.control_path != NULL && muxserver_sock != -1) 2073 if (options.control_path != NULL && muxserver_sock != -1)
2069 unlink(options.control_path); 2074 unlink(options.control_path);