summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2011-09-06 14:56:29 +0100
committerColin Watson <cjwatson@debian.org>2011-09-06 14:56:29 +0100
commit978e62d6f14c60747bddef2cc72d66a9c8b83b54 (patch)
tree89400a44e42d84937deba7864e4964d6c7734da5 /clientloop.c
parent87c685b8c6a49814fd782288097b3093f975aa72 (diff)
parent3a7e89697ca363de0f64e0d5704c57219294e41c (diff)
* New upstream release (http://www.openssh.org/txt/release-5.9).
- Introduce sandboxing of the pre-auth privsep child using an optional sshd_config(5) "UsePrivilegeSeparation=sandbox" mode that enables mandatory restrictions on the syscalls the privsep child can perform. - Add new SHA256-based HMAC transport integrity modes from http://www.ietf.org/id/draft-dbider-sha2-mac-for-ssh-02.txt. - The pre-authentication sshd(8) privilege separation slave process now logs via a socket shared with the master process, avoiding the need to maintain /dev/log inside the chroot (closes: #75043, #429243, #599240). - ssh(1) now warns when a server refuses X11 forwarding (closes: #504757). - sshd_config(5)'s AuthorizedKeysFile now accepts multiple paths, separated by whitespace (closes: #76312). The authorized_keys2 fallback is deprecated but documented (closes: #560156). - ssh(1) and sshd(8): set IPv6 traffic class from IPQoS, as well as IPv4 ToS/DSCP (closes: #498297). - ssh-add(1) now accepts keys piped from standard input. E.g. "ssh-add - < /path/to/key" (closes: #229124). - Clean up lost-passphrase text in ssh-keygen(1) (closes: #444691). - Say "required" rather than "recommended" in unprotected-private-key warning (LP: #663455).
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c110
1 files changed, 75 insertions, 35 deletions
diff --git a/clientloop.c b/clientloop.c
index 97032e6a8..18a85c56c 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.231 2011/01/16 12:05:59 djm Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.236 2011/06/22 22:08:42 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
@@ -134,9 +134,6 @@ extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
134 */ 134 */
135extern char *host; 135extern char *host;
136 136
137/* Force TTY allocation */
138extern int force_tty_flag;
139
140/* 137/*
141 * Flag to indicate that we have received a window change signal which has 138 * Flag to indicate that we have received a window change signal which has
142 * not yet been processed. This will cause a message indicating the new 139 * not yet been processed. This will cause a message indicating the new
@@ -183,7 +180,8 @@ struct escape_filter_ctx {
183/* Context for channel confirmation replies */ 180/* Context for channel confirmation replies */
184struct channel_reply_ctx { 181struct channel_reply_ctx {
185 const char *request_type; 182 const char *request_type;
186 int id, do_close; 183 int id;
184 enum confirm_action action;
187}; 185};
188 186
189/* Global request success/failure callbacks */ 187/* Global request success/failure callbacks */
@@ -269,10 +267,10 @@ static void
269set_control_persist_exit_time(void) 267set_control_persist_exit_time(void)
270{ 268{
271 if (muxserver_sock == -1 || !options.control_persist 269 if (muxserver_sock == -1 || !options.control_persist
272 || options.control_persist_timeout == 0) 270 || options.control_persist_timeout == 0) {
273 /* not using a ControlPersist timeout */ 271 /* not using a ControlPersist timeout */
274 control_persist_exit_time = 0; 272 control_persist_exit_time = 0;
275 else if (channel_still_open()) { 273 } else if (channel_still_open()) {
276 /* some client connections are still open */ 274 /* some client connections are still open */
277 if (control_persist_exit_time > 0) 275 if (control_persist_exit_time > 0)
278 debug2("%s: cancel scheduled exit", __func__); 276 debug2("%s: cancel scheduled exit", __func__);
@@ -671,7 +669,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
671 atomicio(vwrite, fileno(stderr), buffer_ptr(berr), 669 atomicio(vwrite, fileno(stderr), buffer_ptr(berr),
672 buffer_len(berr)); 670 buffer_len(berr));
673 671
674 leave_raw_mode(force_tty_flag); 672 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
675 673
676 /* 674 /*
677 * Free (and clear) the buffer to reduce the amount of data that gets 675 * Free (and clear) the buffer to reduce the amount of data that gets
@@ -692,7 +690,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
692 buffer_init(bout); 690 buffer_init(bout);
693 buffer_init(berr); 691 buffer_init(berr);
694 692
695 enter_raw_mode(force_tty_flag); 693 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
696} 694}
697 695
698static void 696static void
@@ -751,6 +749,15 @@ client_status_confirm(int type, Channel *c, void *ctx)
751 char errmsg[256]; 749 char errmsg[256];
752 int tochan; 750 int tochan;
753 751
752 /*
753 * If a TTY was explicitly requested, then a failure to allocate
754 * one is fatal.
755 */
756 if (cr->action == CONFIRM_TTY &&
757 (options.request_tty == REQUEST_TTY_FORCE ||
758 options.request_tty == REQUEST_TTY_YES))
759 cr->action = CONFIRM_CLOSE;
760
754 /* XXX supress on mux _client_ quietmode */ 761 /* XXX supress on mux _client_ quietmode */
755 tochan = options.log_level >= SYSLOG_LEVEL_ERROR && 762 tochan = options.log_level >= SYSLOG_LEVEL_ERROR &&
756 c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; 763 c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
@@ -768,14 +775,27 @@ client_status_confirm(int type, Channel *c, void *ctx)
768 cr->request_type, c->self); 775 cr->request_type, c->self);
769 } 776 }
770 /* If error occurred on primary session channel, then exit */ 777 /* If error occurred on primary session channel, then exit */
771 if (cr->do_close && c->self == session_ident) 778 if (cr->action == CONFIRM_CLOSE && c->self == session_ident)
772 fatal("%s", errmsg); 779 fatal("%s", errmsg);
773 /* If error occurred on mux client, append to their stderr */ 780 /*
774 if (tochan) 781 * If error occurred on mux client, append to
775 buffer_append(&c->extended, errmsg, strlen(errmsg)); 782 * their stderr.
776 else 783 */
784 if (tochan) {
785 buffer_append(&c->extended, errmsg,
786 strlen(errmsg));
787 } else
777 error("%s", errmsg); 788 error("%s", errmsg);
778 if (cr->do_close) { 789 if (cr->action == CONFIRM_TTY) {
790 /*
791 * If a TTY allocation error occurred, then arrange
792 * for the correct TTY to leave raw mode.
793 */
794 if (c->self == session_ident)
795 leave_raw_mode(0);
796 else
797 mux_tty_alloc_failed(c);
798 } else if (cr->action == CONFIRM_CLOSE) {
779 chan_read_failed(c); 799 chan_read_failed(c);
780 chan_write_failed(c); 800 chan_write_failed(c);
781 } 801 }
@@ -789,13 +809,14 @@ client_abandon_status_confirm(Channel *c, void *ctx)
789 xfree(ctx); 809 xfree(ctx);
790} 810}
791 811
792static void 812void
793client_expect_confirm(int id, const char *request, int do_close) 813client_expect_confirm(int id, const char *request,
814 enum confirm_action action)
794{ 815{
795 struct channel_reply_ctx *cr = xmalloc(sizeof(*cr)); 816 struct channel_reply_ctx *cr = xmalloc(sizeof(*cr));
796 817
797 cr->request_type = request; 818 cr->request_type = request;
798 cr->do_close = do_close; 819 cr->action = action;
799 820
800 channel_register_status_confirm(id, client_status_confirm, 821 channel_register_status_confirm(id, client_status_confirm,
801 client_abandon_status_confirm, cr); 822 client_abandon_status_confirm, cr);
@@ -835,7 +856,7 @@ process_cmdline(void)
835 bzero(&fwd, sizeof(fwd)); 856 bzero(&fwd, sizeof(fwd));
836 fwd.listen_host = fwd.connect_host = NULL; 857 fwd.listen_host = fwd.connect_host = NULL;
837 858
838 leave_raw_mode(force_tty_flag); 859 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
839 handler = signal(SIGINT, SIG_IGN); 860 handler = signal(SIGINT, SIG_IGN);
840 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); 861 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
841 if (s == NULL) 862 if (s == NULL)
@@ -939,7 +960,7 @@ process_cmdline(void)
939 960
940out: 961out:
941 signal(SIGINT, handler); 962 signal(SIGINT, handler);
942 enter_raw_mode(force_tty_flag); 963 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
943 if (cmd) 964 if (cmd)
944 xfree(cmd); 965 xfree(cmd);
945 if (fwd.listen_host != NULL) 966 if (fwd.listen_host != NULL)
@@ -1058,7 +1079,8 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1058 * more new connections). 1079 * more new connections).
1059 */ 1080 */
1060 /* Restore tty modes. */ 1081 /* Restore tty modes. */
1061 leave_raw_mode(force_tty_flag); 1082 leave_raw_mode(
1083 options.request_tty == REQUEST_TTY_FORCE);
1062 1084
1063 /* Stop listening for new connections. */ 1085 /* Stop listening for new connections. */
1064 channel_stop_listening(); 1086 channel_stop_listening();
@@ -1353,7 +1375,7 @@ client_channel_closed(int id, void *arg)
1353{ 1375{
1354 channel_cancel_cleanup(id); 1376 channel_cancel_cleanup(id);
1355 session_closed = 1; 1377 session_closed = 1;
1356 leave_raw_mode(force_tty_flag); 1378 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
1357} 1379}
1358 1380
1359/* 1381/*
@@ -1424,18 +1446,21 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1424 signal(SIGWINCH, window_change_handler); 1446 signal(SIGWINCH, window_change_handler);
1425 1447
1426 if (have_pty) 1448 if (have_pty)
1427 enter_raw_mode(force_tty_flag); 1449 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
1428 1450
1429 if (compat20) { 1451 if (compat20) {
1430 session_ident = ssh2_chan_id; 1452 session_ident = ssh2_chan_id;
1431 if (escape_char_arg != SSH_ESCAPECHAR_NONE) 1453 if (session_ident != -1) {
1432 channel_register_filter(session_ident, 1454 if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
1433 client_simple_escape_filter, NULL, 1455 channel_register_filter(session_ident,
1434 client_filter_cleanup, 1456 client_simple_escape_filter, NULL,
1435 client_new_escape_filter_ctx(escape_char_arg)); 1457 client_filter_cleanup,
1436 if (session_ident != -1) 1458 client_new_escape_filter_ctx(
1459 escape_char_arg));
1460 }
1437 channel_register_cleanup(session_ident, 1461 channel_register_cleanup(session_ident,
1438 client_channel_closed, 0); 1462 client_channel_closed, 0);
1463 }
1439 } else { 1464 } else {
1440 /* Check if we should immediately send eof on stdin. */ 1465 /* Check if we should immediately send eof on stdin. */
1441 client_check_initial_eof_on_stdin(); 1466 client_check_initial_eof_on_stdin();
@@ -1574,7 +1599,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1574 channel_free_all(); 1599 channel_free_all();
1575 1600
1576 if (have_pty) 1601 if (have_pty)
1577 leave_raw_mode(force_tty_flag); 1602 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
1578 1603
1579 /* restore blocking io */ 1604 /* restore blocking io */
1580 if (!isatty(fileno(stdin))) 1605 if (!isatty(fileno(stdin)))
@@ -2002,7 +2027,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2002 memset(&ws, 0, sizeof(ws)); 2027 memset(&ws, 0, sizeof(ws));
2003 2028
2004 channel_request_start(id, "pty-req", 1); 2029 channel_request_start(id, "pty-req", 1);
2005 client_expect_confirm(id, "PTY allocation", 1); 2030 client_expect_confirm(id, "PTY allocation", CONFIRM_TTY);
2006 packet_put_cstring(term != NULL ? term : ""); 2031 packet_put_cstring(term != NULL ? term : "");
2007 packet_put_int((u_int)ws.ws_col); 2032 packet_put_int((u_int)ws.ws_col);
2008 packet_put_int((u_int)ws.ws_row); 2033 packet_put_int((u_int)ws.ws_row);
@@ -2061,18 +2086,18 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2061 debug("Sending subsystem: %.*s", 2086 debug("Sending subsystem: %.*s",
2062 len, (u_char*)buffer_ptr(cmd)); 2087 len, (u_char*)buffer_ptr(cmd));
2063 channel_request_start(id, "subsystem", 1); 2088 channel_request_start(id, "subsystem", 1);
2064 client_expect_confirm(id, "subsystem", 1); 2089 client_expect_confirm(id, "subsystem", CONFIRM_CLOSE);
2065 } else { 2090 } else {
2066 debug("Sending command: %.*s", 2091 debug("Sending command: %.*s",
2067 len, (u_char*)buffer_ptr(cmd)); 2092 len, (u_char*)buffer_ptr(cmd));
2068 channel_request_start(id, "exec", 1); 2093 channel_request_start(id, "exec", 1);
2069 client_expect_confirm(id, "exec", 1); 2094 client_expect_confirm(id, "exec", CONFIRM_CLOSE);
2070 } 2095 }
2071 packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); 2096 packet_put_string(buffer_ptr(cmd), buffer_len(cmd));
2072 packet_send(); 2097 packet_send();
2073 } else { 2098 } else {
2074 channel_request_start(id, "shell", 1); 2099 channel_request_start(id, "shell", 1);
2075 client_expect_confirm(id, "shell", 1); 2100 client_expect_confirm(id, "shell", CONFIRM_CLOSE);
2076 packet_send(); 2101 packet_send();
2077 } 2102 }
2078} 2103}
@@ -2142,11 +2167,26 @@ client_init_dispatch(void)
2142 client_init_dispatch_15(); 2167 client_init_dispatch_15();
2143} 2168}
2144 2169
2170void
2171client_stop_mux(void)
2172{
2173 if (options.control_path != NULL && muxserver_sock != -1)
2174 unlink(options.control_path);
2175 /*
2176 * If we are in persist mode, signal that we should close when all
2177 * active channels are closed.
2178 */
2179 if (options.control_persist) {
2180 session_closed = 1;
2181 setproctitle("[stopped mux]");
2182 }
2183}
2184
2145/* client specific fatal cleanup */ 2185/* client specific fatal cleanup */
2146void 2186void
2147cleanup_exit(int i) 2187cleanup_exit(int i)
2148{ 2188{
2149 leave_raw_mode(force_tty_flag); 2189 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
2150 leave_non_blocking(); 2190 leave_non_blocking();
2151 if (options.control_path != NULL && muxserver_sock != -1) 2191 if (options.control_path != NULL && muxserver_sock != -1)
2152 unlink(options.control_path); 2192 unlink(options.control_path);