summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2011-05-15 08:48:05 +1000
committerDamien Miller <djm@mindrot.org>2011-05-15 08:48:05 +1000
commit555f3b856f2681b46870a66386396b49426b9719 (patch)
tree88756b47f05c76c5afd5ce739aa26a7b3f124809 /clientloop.c
parentf4b32aad05cb65caa6eabe09049750b3c8a29cf3 (diff)
- djm@cvs.openbsd.org 2011/05/08 12:52:01
[PROTOCOL.mux clientloop.c clientloop.h mux.c] improve our behaviour when TTY allocation fails: if we are in RequestTTY=auto mode (the default), then do not treat at TTY allocation error as fatal but rather just restore the local TTY to cooked mode and continue. This is more graceful on devices that never allocate TTYs. If RequestTTY is set to "yes" or "force", then failure to allocate a TTY is fatal. ok markus@
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/clientloop.c b/clientloop.c
index 5bd757dfb..ed1d8a238 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.233 2011/05/06 21:34:32 djm Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.234 2011/05/08 12:52:01 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
@@ -174,9 +174,11 @@ struct escape_filter_ctx {
174}; 174};
175 175
176/* Context for channel confirmation replies */ 176/* Context for channel confirmation replies */
177enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY };
177struct channel_reply_ctx { 178struct channel_reply_ctx {
178 const char *request_type; 179 const char *request_type;
179 int id, do_close; 180 int id;
181 enum confirm_action action;
180}; 182};
181 183
182/* Global request success/failure callbacks */ 184/* Global request success/failure callbacks */
@@ -739,6 +741,15 @@ client_status_confirm(int type, Channel *c, void *ctx)
739 char errmsg[256]; 741 char errmsg[256];
740 int tochan; 742 int tochan;
741 743
744 /*
745 * If a TTY was explicitly requested, then a failure to allocate
746 * one is fatal.
747 */
748 if (cr->action == CONFIRM_TTY &&
749 (options.request_tty == REQUEST_TTY_FORCE ||
750 options.request_tty == REQUEST_TTY_YES))
751 cr->action = CONFIRM_CLOSE;
752
742 /* XXX supress on mux _client_ quietmode */ 753 /* XXX supress on mux _client_ quietmode */
743 tochan = options.log_level >= SYSLOG_LEVEL_ERROR && 754 tochan = options.log_level >= SYSLOG_LEVEL_ERROR &&
744 c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; 755 c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
@@ -756,14 +767,27 @@ client_status_confirm(int type, Channel *c, void *ctx)
756 cr->request_type, c->self); 767 cr->request_type, c->self);
757 } 768 }
758 /* If error occurred on primary session channel, then exit */ 769 /* If error occurred on primary session channel, then exit */
759 if (cr->do_close && c->self == session_ident) 770 if (cr->action == CONFIRM_CLOSE && c->self == session_ident)
760 fatal("%s", errmsg); 771 fatal("%s", errmsg);
761 /* If error occurred on mux client, append to their stderr */ 772 /*
762 if (tochan) 773 * If error occurred on mux client, append to
763 buffer_append(&c->extended, errmsg, strlen(errmsg)); 774 * their stderr.
764 else 775 */
776 if (tochan) {
777 buffer_append(&c->extended, errmsg,
778 strlen(errmsg));
779 } else
765 error("%s", errmsg); 780 error("%s", errmsg);
766 if (cr->do_close) { 781 if (cr->action == CONFIRM_TTY) {
782 /*
783 * If a TTY allocation error occurred, then arrange
784 * for the correct TTY to leave raw mode.
785 */
786 if (c->self == session_ident)
787 leave_raw_mode(0);
788 else
789 mux_tty_alloc_failed(c);
790 } else if (cr->action == CONFIRM_CLOSE) {
767 chan_read_failed(c); 791 chan_read_failed(c);
768 chan_write_failed(c); 792 chan_write_failed(c);
769 } 793 }
@@ -778,12 +802,13 @@ client_abandon_status_confirm(Channel *c, void *ctx)
778} 802}
779 803
780static void 804static void
781client_expect_confirm(int id, const char *request, int do_close) 805client_expect_confirm(int id, const char *request,
806 enum confirm_action action)
782{ 807{
783 struct channel_reply_ctx *cr = xmalloc(sizeof(*cr)); 808 struct channel_reply_ctx *cr = xmalloc(sizeof(*cr));
784 809
785 cr->request_type = request; 810 cr->request_type = request;
786 cr->do_close = do_close; 811 cr->action = action;
787 812
788 channel_register_status_confirm(id, client_status_confirm, 813 channel_register_status_confirm(id, client_status_confirm,
789 client_abandon_status_confirm, cr); 814 client_abandon_status_confirm, cr);
@@ -1983,7 +2008,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
1983 memset(&ws, 0, sizeof(ws)); 2008 memset(&ws, 0, sizeof(ws));
1984 2009
1985 channel_request_start(id, "pty-req", 1); 2010 channel_request_start(id, "pty-req", 1);
1986 client_expect_confirm(id, "PTY allocation", 1); 2011 client_expect_confirm(id, "PTY allocation", CONFIRM_TTY);
1987 packet_put_cstring(term != NULL ? term : ""); 2012 packet_put_cstring(term != NULL ? term : "");
1988 packet_put_int((u_int)ws.ws_col); 2013 packet_put_int((u_int)ws.ws_col);
1989 packet_put_int((u_int)ws.ws_row); 2014 packet_put_int((u_int)ws.ws_row);
@@ -2042,18 +2067,18 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2042 debug("Sending subsystem: %.*s", 2067 debug("Sending subsystem: %.*s",
2043 len, (u_char*)buffer_ptr(cmd)); 2068 len, (u_char*)buffer_ptr(cmd));
2044 channel_request_start(id, "subsystem", 1); 2069 channel_request_start(id, "subsystem", 1);
2045 client_expect_confirm(id, "subsystem", 1); 2070 client_expect_confirm(id, "subsystem", CONFIRM_CLOSE);
2046 } else { 2071 } else {
2047 debug("Sending command: %.*s", 2072 debug("Sending command: %.*s",
2048 len, (u_char*)buffer_ptr(cmd)); 2073 len, (u_char*)buffer_ptr(cmd));
2049 channel_request_start(id, "exec", 1); 2074 channel_request_start(id, "exec", 1);
2050 client_expect_confirm(id, "exec", 1); 2075 client_expect_confirm(id, "exec", CONFIRM_CLOSE);
2051 } 2076 }
2052 packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); 2077 packet_put_string(buffer_ptr(cmd), buffer_len(cmd));
2053 packet_send(); 2078 packet_send();
2054 } else { 2079 } else {
2055 channel_request_start(id, "shell", 1); 2080 channel_request_start(id, "shell", 1);
2056 client_expect_confirm(id, "shell", 1); 2081 client_expect_confirm(id, "shell", CONFIRM_CLOSE);
2057 packet_send(); 2082 packet_send();
2058 } 2083 }
2059} 2084}