summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2010-03-31 10:46:28 +0100
committerColin Watson <cjwatson@debian.org>2010-03-31 10:46:28 +0100
commitefd3d4522636ae029488c2e9730b60c88e257d2e (patch)
tree31e02ac3f16090ce8c53448677356b2b7f423683 /clientloop.c
parentbbec4db36d464ea1d464a707625125f9fd5c7b5e (diff)
parentd1a87e462e1db89f19cd960588d0c6b287cb5ccc (diff)
* New upstream release (LP: #535029).
- After a transition period of about 10 years, this release disables SSH protocol 1 by default. Clients and servers that need to use the legacy protocol must explicitly enable it in ssh_config / sshd_config or on the command-line. - Remove the libsectok/OpenSC-based smartcard code and add support for PKCS#11 tokens. This support is enabled by default in the Debian packaging, since it now doesn't involve additional library dependencies (closes: #231472, LP: #16918). - Add support for certificate authentication of users and hosts using a new, minimal OpenSSH certificate format (closes: #482806). - Added a 'netcat mode' to ssh(1): "ssh -W host:port ...". - Add the ability to revoke keys in sshd(8) and ssh(1). (For the Debian package, this overlaps with the key blacklisting facility added in openssh 1:4.7p1-9, but with different file formats and slightly different scopes; for the moment, I've roughly merged the two.) - Various multiplexing improvements, including support for requesting port-forwardings via the multiplex protocol (closes: #360151). - Allow setting an explicit umask on the sftp-server(8) commandline to override whatever default the user has (closes: #496843). - Many sftp client improvements, including tab-completion, more options, and recursive transfer support for get/put (LP: #33378). The old mget/mput commands never worked properly and have been removed (closes: #270399, #428082). - Do not prompt for a passphrase if we fail to open a keyfile, and log the reason why the open failed to debug (closes: #431538). - Prevent sftp from crashing when given a "-" without a command. Also, allow whitespace to follow a "-" (closes: #531561).
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 cea0d617a..a55fe9995 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;
@@ -568,9 +573,6 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
568 if (packet_have_data_to_write()) 573 if (packet_have_data_to_write())
569 FD_SET(connection_out, *writesetp); 574 FD_SET(connection_out, *writesetp);
570 575
571 if (muxserver_sock != -1)
572 FD_SET(muxserver_sock, *readsetp);
573
574 /* 576 /*
575 * Wait for something to happen. This will suspend the process until 577 * Wait for something to happen. This will suspend the process until
576 * some selected descriptor can be read, written, or has some other 578 * some selected descriptor can be read, written, or has some other
@@ -617,7 +619,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
617 atomicio(vwrite, fileno(stderr), buffer_ptr(berr), 619 atomicio(vwrite, fileno(stderr), buffer_ptr(berr),
618 buffer_len(berr)); 620 buffer_len(berr));
619 621
620 leave_raw_mode(); 622 leave_raw_mode(force_tty_flag);
621 623
622 /* 624 /*
623 * Free (and clear) the buffer to reduce the amount of data that gets 625 * Free (and clear) the buffer to reduce the amount of data that gets
@@ -638,7 +640,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
638 buffer_init(bout); 640 buffer_init(bout);
639 buffer_init(berr); 641 buffer_init(berr);
640 642
641 enter_raw_mode(); 643 enter_raw_mode(force_tty_flag);
642} 644}
643 645
644static void 646static void
@@ -699,7 +701,7 @@ client_status_confirm(int type, Channel *c, void *ctx)
699 701
700 /* XXX supress on mux _client_ quietmode */ 702 /* XXX supress on mux _client_ quietmode */
701 tochan = options.log_level >= SYSLOG_LEVEL_ERROR && 703 tochan = options.log_level >= SYSLOG_LEVEL_ERROR &&
702 c->ctl_fd != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; 704 c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
703 705
704 if (type == SSH2_MSG_CHANNEL_SUCCESS) { 706 if (type == SSH2_MSG_CHANNEL_SUCCESS) {
705 debug2("%s request accepted on channel %d", 707 debug2("%s request accepted on channel %d",
@@ -781,7 +783,7 @@ process_cmdline(void)
781 bzero(&fwd, sizeof(fwd)); 783 bzero(&fwd, sizeof(fwd));
782 fwd.listen_host = fwd.connect_host = NULL; 784 fwd.listen_host = fwd.connect_host = NULL;
783 785
784 leave_raw_mode(); 786 leave_raw_mode(force_tty_flag);
785 handler = signal(SIGINT, SIG_IGN); 787 handler = signal(SIGINT, SIG_IGN);
786 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); 788 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
787 if (s == NULL) 789 if (s == NULL)
@@ -843,6 +845,7 @@ process_cmdline(void)
843 while (isspace(*++s)) 845 while (isspace(*++s))
844 ; 846 ;
845 847
848 /* XXX update list of forwards in options */
846 if (delete) { 849 if (delete) {
847 cancel_port = 0; 850 cancel_port = 0;
848 cancel_host = hpdelim(&s); /* may be NULL */ 851 cancel_host = hpdelim(&s); /* may be NULL */
@@ -884,7 +887,7 @@ process_cmdline(void)
884 887
885out: 888out:
886 signal(SIGINT, handler); 889 signal(SIGINT, handler);
887 enter_raw_mode(); 890 enter_raw_mode(force_tty_flag);
888 if (cmd) 891 if (cmd)
889 xfree(cmd); 892 xfree(cmd);
890 if (fwd.listen_host != NULL) 893 if (fwd.listen_host != NULL)
@@ -940,7 +943,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
940 escape_char); 943 escape_char);
941 buffer_append(berr, string, strlen(string)); 944 buffer_append(berr, string, strlen(string));
942 945
943 if (c && c->ctl_fd != -1) { 946 if (c && c->ctl_chan != -1) {
944 chan_read_failed(c); 947 chan_read_failed(c);
945 chan_write_failed(c); 948 chan_write_failed(c);
946 return 0; 949 return 0;
@@ -950,7 +953,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
950 953
951 case 'Z' - 64: 954 case 'Z' - 64:
952 /* XXX support this for mux clients */ 955 /* XXX support this for mux clients */
953 if (c && c->ctl_fd != -1) { 956 if (c && c->ctl_chan != -1) {
954 noescape: 957 noescape:
955 snprintf(string, sizeof string, 958 snprintf(string, sizeof string,
956 "%c%c escape not available to " 959 "%c%c escape not available to "
@@ -995,7 +998,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
995 continue; 998 continue;
996 999
997 case '&': 1000 case '&':
998 if (c && c->ctl_fd != -1) 1001 if (c && c->ctl_chan != -1)
999 goto noescape; 1002 goto noescape;
1000 /* 1003 /*
1001 * Detach the program (continue to serve 1004 * Detach the program (continue to serve
@@ -1003,7 +1006,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1003 * more new connections). 1006 * more new connections).
1004 */ 1007 */
1005 /* Restore tty modes. */ 1008 /* Restore tty modes. */
1006 leave_raw_mode(); 1009 leave_raw_mode(force_tty_flag);
1007 1010
1008 /* Stop listening for new connections. */ 1011 /* Stop listening for new connections. */
1009 channel_stop_listening(); 1012 channel_stop_listening();
@@ -1046,7 +1049,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1046 continue; 1049 continue;
1047 1050
1048 case '?': 1051 case '?':
1049 if (c && c->ctl_fd != -1) { 1052 if (c && c->ctl_chan != -1) {
1050 snprintf(string, sizeof string, 1053 snprintf(string, sizeof string,
1051"%c?\r\n\ 1054"%c?\r\n\
1052Supported escape sequences:\r\n\ 1055Supported escape sequences:\r\n\
@@ -1095,7 +1098,7 @@ Supported escape sequences:\r\n\
1095 continue; 1098 continue;
1096 1099
1097 case 'C': 1100 case 'C':
1098 if (c && c->ctl_fd != -1) 1101 if (c && c->ctl_chan != -1)
1099 goto noescape; 1102 goto noescape;
1100 process_cmdline(); 1103 process_cmdline();
1101 continue; 1104 continue;
@@ -1298,7 +1301,7 @@ client_channel_closed(int id, void *arg)
1298{ 1301{
1299 channel_cancel_cleanup(id); 1302 channel_cancel_cleanup(id);
1300 session_closed = 1; 1303 session_closed = 1;
1301 leave_raw_mode(); 1304 leave_raw_mode(force_tty_flag);
1302} 1305}
1303 1306
1304/* 1307/*
@@ -1331,8 +1334,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1331 connection_in = packet_get_connection_in(); 1334 connection_in = packet_get_connection_in();
1332 connection_out = packet_get_connection_out(); 1335 connection_out = packet_get_connection_out();
1333 max_fd = MAX(connection_in, connection_out); 1336 max_fd = MAX(connection_in, connection_out);
1334 if (muxserver_sock != -1)
1335 max_fd = MAX(max_fd, muxserver_sock);
1336 1337
1337 if (!compat20) { 1338 if (!compat20) {
1338 /* enable nonblocking unless tty */ 1339 /* enable nonblocking unless tty */
@@ -1371,7 +1372,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1371 signal(SIGWINCH, window_change_handler); 1372 signal(SIGWINCH, window_change_handler);
1372 1373
1373 if (have_pty) 1374 if (have_pty)
1374 enter_raw_mode(); 1375 enter_raw_mode(force_tty_flag);
1375 1376
1376 if (compat20) { 1377 if (compat20) {
1377 session_ident = ssh2_chan_id; 1378 session_ident = ssh2_chan_id;
@@ -1459,12 +1460,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1459 /* Buffer input from the connection. */ 1460 /* Buffer input from the connection. */
1460 client_process_net_input(readset); 1461 client_process_net_input(readset);
1461 1462
1462 /* Accept control connections. */
1463 if (muxserver_sock != -1 &&FD_ISSET(muxserver_sock, readset)) {
1464 if (muxserver_accept_control())
1465 quit_pending = 1;
1466 }
1467
1468 if (quit_pending) 1463 if (quit_pending)
1469 break; 1464 break;
1470 1465
@@ -1478,6 +1473,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1478 client_process_output(writeset); 1473 client_process_output(writeset);
1479 } 1474 }
1480 1475
1476 if (session_resumed) {
1477 connection_in = packet_get_connection_in();
1478 connection_out = packet_get_connection_out();
1479 max_fd = MAX(max_fd, connection_out);
1480 max_fd = MAX(max_fd, connection_in);
1481 session_resumed = 0;
1482 }
1483
1481 /* 1484 /*
1482 * Send as much buffered packet data as possible to the 1485 * Send as much buffered packet data as possible to the
1483 * sender. 1486 * sender.
@@ -1506,7 +1509,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1506 channel_free_all(); 1509 channel_free_all();
1507 1510
1508 if (have_pty) 1511 if (have_pty)
1509 leave_raw_mode(); 1512 leave_raw_mode(force_tty_flag);
1510 1513
1511 /* restore blocking io */ 1514 /* restore blocking io */
1512 if (!isatty(fileno(stdin))) 1515 if (!isatty(fileno(stdin)))
@@ -1866,15 +1869,17 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
1866 chan_rcvd_eow(c); 1869 chan_rcvd_eow(c);
1867 } else if (strcmp(rtype, "exit-status") == 0) { 1870 } else if (strcmp(rtype, "exit-status") == 0) {
1868 exitval = packet_get_int(); 1871 exitval = packet_get_int();
1869 if (id == session_ident) { 1872 if (c->ctl_chan != -1) {
1873 mux_exit_message(c, exitval);
1874 success = 1;
1875 } else if (id == session_ident) {
1876 /* Record exit value of local session */
1870 success = 1; 1877 success = 1;
1871 exit_status = exitval; 1878 exit_status = exitval;
1872 } else if (c->ctl_fd == -1) {
1873 error("client_input_channel_req: unexpected channel %d",
1874 session_ident);
1875 } else { 1879 } else {
1876 atomicio(vwrite, c->ctl_fd, &exitval, sizeof(exitval)); 1880 /* Probably for a mux channel that has already closed */
1877 success = 1; 1881 debug("%s: no sink for exit-status on channel %d",
1882 __func__, id);
1878 } 1883 }
1879 packet_check_eom(); 1884 packet_check_eom();
1880 } 1885 }
@@ -2070,7 +2075,7 @@ client_init_dispatch(void)
2070void 2075void
2071cleanup_exit(int i) 2076cleanup_exit(int i)
2072{ 2077{
2073 leave_raw_mode(); 2078 leave_raw_mode(force_tty_flag);
2074 leave_non_blocking(); 2079 leave_non_blocking();
2075 if (options.control_path != NULL && muxserver_sock != -1) 2080 if (options.control_path != NULL && muxserver_sock != -1)
2076 unlink(options.control_path); 2081 unlink(options.control_path);