summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c145
1 files changed, 100 insertions, 45 deletions
diff --git a/clientloop.c b/clientloop.c
index 5b76b9893..1a16b2525 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.240 2012/06/20 04:42:58 djm Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.248 2013/01/02 00:32:07 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
@@ -977,9 +977,9 @@ process_cmdline(void)
977 goto out; 977 goto out;
978 } 978 }
979 if (local || dynamic) { 979 if (local || dynamic) {
980 if (channel_setup_local_fwd_listener(fwd.listen_host, 980 if (!channel_setup_local_fwd_listener(fwd.listen_host,
981 fwd.listen_port, fwd.connect_host, 981 fwd.listen_port, fwd.connect_host,
982 fwd.connect_port, options.gateway_ports) < 0) { 982 fwd.connect_port, options.gateway_ports)) {
983 logit("Port forwarding failed."); 983 logit("Port forwarding failed.");
984 goto out; 984 goto out;
985 } 985 }
@@ -1005,6 +1005,63 @@ out:
1005 xfree(fwd.connect_host); 1005 xfree(fwd.connect_host);
1006} 1006}
1007 1007
1008/* reasons to suppress output of an escape command in help output */
1009#define SUPPRESS_NEVER 0 /* never suppress, always show */
1010#define SUPPRESS_PROTO1 1 /* don't show in protocol 1 sessions */
1011#define SUPPRESS_MUXCLIENT 2 /* don't show in mux client sessions */
1012#define SUPPRESS_MUXMASTER 4 /* don't show in mux master sessions */
1013#define SUPPRESS_SYSLOG 8 /* don't show when logging to syslog */
1014struct escape_help_text {
1015 const char *cmd;
1016 const char *text;
1017 unsigned int flags;
1018};
1019static struct escape_help_text esc_txt[] = {
1020 {".", "terminate session", SUPPRESS_MUXMASTER},
1021 {".", "terminate connection (and any multiplexed sessions)",
1022 SUPPRESS_MUXCLIENT},
1023 {"B", "send a BREAK to the remote system", SUPPRESS_PROTO1},
1024 {"C", "open a command line", SUPPRESS_MUXCLIENT},
1025 {"R", "request rekey", SUPPRESS_PROTO1},
1026 {"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT},
1027 {"^Z", "suspend ssh", SUPPRESS_MUXCLIENT},
1028 {"#", "list forwarded connections", SUPPRESS_NEVER},
1029 {"&", "background ssh (when waiting for connections to terminate)",
1030 SUPPRESS_MUXCLIENT},
1031 {"?", "this message", SUPPRESS_NEVER},
1032};
1033
1034static void
1035print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client,
1036 int using_stderr)
1037{
1038 unsigned int i, suppress_flags;
1039 char string[1024];
1040
1041 snprintf(string, sizeof string, "%c?\r\n"
1042 "Supported escape sequences:\r\n", escape_char);
1043 buffer_append(b, string, strlen(string));
1044
1045 suppress_flags = (protocol2 ? 0 : SUPPRESS_PROTO1) |
1046 (mux_client ? SUPPRESS_MUXCLIENT : 0) |
1047 (mux_client ? 0 : SUPPRESS_MUXMASTER) |
1048 (using_stderr ? 0 : SUPPRESS_SYSLOG);
1049
1050 for (i = 0; i < sizeof(esc_txt)/sizeof(esc_txt[0]); i++) {
1051 if (esc_txt[i].flags & suppress_flags)
1052 continue;
1053 snprintf(string, sizeof string, " %c%-3s - %s\r\n",
1054 escape_char, esc_txt[i].cmd, esc_txt[i].text);
1055 buffer_append(b, string, strlen(string));
1056 }
1057
1058 snprintf(string, sizeof string,
1059 " %c%c - send the escape character by typing it twice\r\n"
1060 "(Note that escapes are only recognized immediately after "
1061 "newline.)\r\n", escape_char, escape_char);
1062 buffer_append(b, string, strlen(string));
1063}
1064
1008/* 1065/*
1009 * Process the characters one by one, call with c==NULL for proto1 case. 1066 * Process the characters one by one, call with c==NULL for proto1 case.
1010 */ 1067 */
@@ -1055,6 +1112,8 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1055 if (c && c->ctl_chan != -1) { 1112 if (c && c->ctl_chan != -1) {
1056 chan_read_failed(c); 1113 chan_read_failed(c);
1057 chan_write_failed(c); 1114 chan_write_failed(c);
1115 mux_master_session_cleanup_cb(c->self,
1116 NULL);
1058 return 0; 1117 return 0;
1059 } else 1118 } else
1060 quit_pending = 1; 1119 quit_pending = 1;
@@ -1063,11 +1122,16 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1063 case 'Z' - 64: 1122 case 'Z' - 64:
1064 /* XXX support this for mux clients */ 1123 /* XXX support this for mux clients */
1065 if (c && c->ctl_chan != -1) { 1124 if (c && c->ctl_chan != -1) {
1125 char b[16];
1066 noescape: 1126 noescape:
1127 if (ch == 'Z' - 64)
1128 snprintf(b, sizeof b, "^Z");
1129 else
1130 snprintf(b, sizeof b, "%c", ch);
1067 snprintf(string, sizeof string, 1131 snprintf(string, sizeof string,
1068 "%c%c escape not available to " 1132 "%c%s escape not available to "
1069 "multiplexed sessions\r\n", 1133 "multiplexed sessions\r\n",
1070 escape_char, ch); 1134 escape_char, b);
1071 buffer_append(berr, string, 1135 buffer_append(berr, string,
1072 strlen(string)); 1136 strlen(string));
1073 continue; 1137 continue;
@@ -1106,6 +1170,31 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1106 } 1170 }
1107 continue; 1171 continue;
1108 1172
1173 case 'V':
1174 /* FALLTHROUGH */
1175 case 'v':
1176 if (c && c->ctl_chan != -1)
1177 goto noescape;
1178 if (!log_is_on_stderr()) {
1179 snprintf(string, sizeof string,
1180 "%c%c [Logging to syslog]\r\n",
1181 escape_char, ch);
1182 buffer_append(berr, string,
1183 strlen(string));
1184 continue;
1185 }
1186 if (ch == 'V' && options.log_level >
1187 SYSLOG_LEVEL_QUIET)
1188 log_change_level(--options.log_level);
1189 if (ch == 'v' && options.log_level <
1190 SYSLOG_LEVEL_DEBUG3)
1191 log_change_level(++options.log_level);
1192 snprintf(string, sizeof string,
1193 "%c%c [LogLevel %s]\r\n", escape_char, ch,
1194 log_level_name(options.log_level));
1195 buffer_append(berr, string, strlen(string));
1196 continue;
1197
1109 case '&': 1198 case '&':
1110 if (c && c->ctl_chan != -1) 1199 if (c && c->ctl_chan != -1)
1111 goto noescape; 1200 goto noescape;
@@ -1159,43 +1248,9 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1159 continue; 1248 continue;
1160 1249
1161 case '?': 1250 case '?':
1162 if (c && c->ctl_chan != -1) { 1251 print_escape_help(berr, escape_char, compat20,
1163 snprintf(string, sizeof string, 1252 (c && c->ctl_chan != -1),
1164"%c?\r\n\ 1253 log_is_on_stderr());
1165Supported escape sequences:\r\n\
1166 %c. - terminate session\r\n\
1167 %cB - send a BREAK to the remote system\r\n\
1168 %cR - Request rekey (SSH protocol 2 only)\r\n\
1169 %c# - list forwarded connections\r\n\
1170 %c? - this message\r\n\
1171 %c%c - send the escape character by typing it twice\r\n\
1172(Note that escapes are only recognized immediately after newline.)\r\n",
1173 escape_char, escape_char,
1174 escape_char, escape_char,
1175 escape_char, escape_char,
1176 escape_char, escape_char);
1177 } else {
1178 snprintf(string, sizeof string,
1179"%c?\r\n\
1180Supported escape sequences:\r\n\
1181 %c. - terminate connection (and any multiplexed sessions)\r\n\
1182 %cB - send a BREAK to the remote system\r\n\
1183 %cC - open a command line\r\n\
1184 %cR - Request rekey (SSH protocol 2 only)\r\n\
1185 %c^Z - suspend ssh\r\n\
1186 %c# - list forwarded connections\r\n\
1187 %c& - background ssh (when waiting for connections to terminate)\r\n\
1188 %c? - this message\r\n\
1189 %c%c - send the escape character by typing it twice\r\n\
1190(Note that escapes are only recognized immediately after newline.)\r\n",
1191 escape_char, escape_char,
1192 escape_char, escape_char,
1193 escape_char, escape_char,
1194 escape_char, escape_char,
1195 escape_char, escape_char,
1196 escape_char);
1197 }
1198 buffer_append(berr, string, strlen(string));
1199 continue; 1254 continue;
1200 1255
1201 case '#': 1256 case '#':
@@ -2209,10 +2264,10 @@ client_stop_mux(void)
2209 if (options.control_path != NULL && muxserver_sock != -1) 2264 if (options.control_path != NULL && muxserver_sock != -1)
2210 unlink(options.control_path); 2265 unlink(options.control_path);
2211 /* 2266 /*
2212 * If we are in persist mode, signal that we should close when all 2267 * If we are in persist mode, or don't have a shell, signal that we
2213 * active channels are closed. 2268 * should close when all active channels are closed.
2214 */ 2269 */
2215 if (options.control_persist) { 2270 if (options.control_persist || no_shell_flag) {
2216 session_closed = 1; 2271 session_closed = 1;
2217 setproctitle("[stopped mux]"); 2272 setproctitle("[stopped mux]");
2218 } 2273 }