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 7bb63c73b..2ef816ab3 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
@@ -972,9 +972,9 @@ process_cmdline(void)
972 goto out; 972 goto out;
973 } 973 }
974 if (local || dynamic) { 974 if (local || dynamic) {
975 if (channel_setup_local_fwd_listener(fwd.listen_host, 975 if (!channel_setup_local_fwd_listener(fwd.listen_host,
976 fwd.listen_port, fwd.connect_host, 976 fwd.listen_port, fwd.connect_host,
977 fwd.connect_port, options.gateway_ports) < 0) { 977 fwd.connect_port, options.gateway_ports)) {
978 logit("Port forwarding failed."); 978 logit("Port forwarding failed.");
979 goto out; 979 goto out;
980 } 980 }
@@ -1000,6 +1000,63 @@ out:
1000 xfree(fwd.connect_host); 1000 xfree(fwd.connect_host);
1001} 1001}
1002 1002
1003/* reasons to suppress output of an escape command in help output */
1004#define SUPPRESS_NEVER 0 /* never suppress, always show */
1005#define SUPPRESS_PROTO1 1 /* don't show in protocol 1 sessions */
1006#define SUPPRESS_MUXCLIENT 2 /* don't show in mux client sessions */
1007#define SUPPRESS_MUXMASTER 4 /* don't show in mux master sessions */
1008#define SUPPRESS_SYSLOG 8 /* don't show when logging to syslog */
1009struct escape_help_text {
1010 const char *cmd;
1011 const char *text;
1012 unsigned int flags;
1013};
1014static struct escape_help_text esc_txt[] = {
1015 {".", "terminate session", SUPPRESS_MUXMASTER},
1016 {".", "terminate connection (and any multiplexed sessions)",
1017 SUPPRESS_MUXCLIENT},
1018 {"B", "send a BREAK to the remote system", SUPPRESS_PROTO1},
1019 {"C", "open a command line", SUPPRESS_MUXCLIENT},
1020 {"R", "request rekey", SUPPRESS_PROTO1},
1021 {"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT},
1022 {"^Z", "suspend ssh", SUPPRESS_MUXCLIENT},
1023 {"#", "list forwarded connections", SUPPRESS_NEVER},
1024 {"&", "background ssh (when waiting for connections to terminate)",
1025 SUPPRESS_MUXCLIENT},
1026 {"?", "this message", SUPPRESS_NEVER},
1027};
1028
1029static void
1030print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client,
1031 int using_stderr)
1032{
1033 unsigned int i, suppress_flags;
1034 char string[1024];
1035
1036 snprintf(string, sizeof string, "%c?\r\n"
1037 "Supported escape sequences:\r\n", escape_char);
1038 buffer_append(b, string, strlen(string));
1039
1040 suppress_flags = (protocol2 ? 0 : SUPPRESS_PROTO1) |
1041 (mux_client ? SUPPRESS_MUXCLIENT : 0) |
1042 (mux_client ? 0 : SUPPRESS_MUXMASTER) |
1043 (using_stderr ? 0 : SUPPRESS_SYSLOG);
1044
1045 for (i = 0; i < sizeof(esc_txt)/sizeof(esc_txt[0]); i++) {
1046 if (esc_txt[i].flags & suppress_flags)
1047 continue;
1048 snprintf(string, sizeof string, " %c%-3s - %s\r\n",
1049 escape_char, esc_txt[i].cmd, esc_txt[i].text);
1050 buffer_append(b, string, strlen(string));
1051 }
1052
1053 snprintf(string, sizeof string,
1054 " %c%c - send the escape character by typing it twice\r\n"
1055 "(Note that escapes are only recognized immediately after "
1056 "newline.)\r\n", escape_char, escape_char);
1057 buffer_append(b, string, strlen(string));
1058}
1059
1003/* 1060/*
1004 * Process the characters one by one, call with c==NULL for proto1 case. 1061 * Process the characters one by one, call with c==NULL for proto1 case.
1005 */ 1062 */
@@ -1050,6 +1107,8 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1050 if (c && c->ctl_chan != -1) { 1107 if (c && c->ctl_chan != -1) {
1051 chan_read_failed(c); 1108 chan_read_failed(c);
1052 chan_write_failed(c); 1109 chan_write_failed(c);
1110 mux_master_session_cleanup_cb(c->self,
1111 NULL);
1053 return 0; 1112 return 0;
1054 } else 1113 } else
1055 quit_pending = 1; 1114 quit_pending = 1;
@@ -1058,11 +1117,16 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1058 case 'Z' - 64: 1117 case 'Z' - 64:
1059 /* XXX support this for mux clients */ 1118 /* XXX support this for mux clients */
1060 if (c && c->ctl_chan != -1) { 1119 if (c && c->ctl_chan != -1) {
1120 char b[16];
1061 noescape: 1121 noescape:
1122 if (ch == 'Z' - 64)
1123 snprintf(b, sizeof b, "^Z");
1124 else
1125 snprintf(b, sizeof b, "%c", ch);
1062 snprintf(string, sizeof string, 1126 snprintf(string, sizeof string,
1063 "%c%c escape not available to " 1127 "%c%s escape not available to "
1064 "multiplexed sessions\r\n", 1128 "multiplexed sessions\r\n",
1065 escape_char, ch); 1129 escape_char, b);
1066 buffer_append(berr, string, 1130 buffer_append(berr, string,
1067 strlen(string)); 1131 strlen(string));
1068 continue; 1132 continue;
@@ -1101,6 +1165,31 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1101 } 1165 }
1102 continue; 1166 continue;
1103 1167
1168 case 'V':
1169 /* FALLTHROUGH */
1170 case 'v':
1171 if (c && c->ctl_chan != -1)
1172 goto noescape;
1173 if (!log_is_on_stderr()) {
1174 snprintf(string, sizeof string,
1175 "%c%c [Logging to syslog]\r\n",
1176 escape_char, ch);
1177 buffer_append(berr, string,
1178 strlen(string));
1179 continue;
1180 }
1181 if (ch == 'V' && options.log_level >
1182 SYSLOG_LEVEL_QUIET)
1183 log_change_level(--options.log_level);
1184 if (ch == 'v' && options.log_level <
1185 SYSLOG_LEVEL_DEBUG3)
1186 log_change_level(++options.log_level);
1187 snprintf(string, sizeof string,
1188 "%c%c [LogLevel %s]\r\n", escape_char, ch,
1189 log_level_name(options.log_level));
1190 buffer_append(berr, string, strlen(string));
1191 continue;
1192
1104 case '&': 1193 case '&':
1105 if (c && c->ctl_chan != -1) 1194 if (c && c->ctl_chan != -1)
1106 goto noescape; 1195 goto noescape;
@@ -1154,43 +1243,9 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1154 continue; 1243 continue;
1155 1244
1156 case '?': 1245 case '?':
1157 if (c && c->ctl_chan != -1) { 1246 print_escape_help(berr, escape_char, compat20,
1158 snprintf(string, sizeof string, 1247 (c && c->ctl_chan != -1),
1159"%c?\r\n\ 1248 log_is_on_stderr());
1160Supported escape sequences:\r\n\
1161 %c. - terminate session\r\n\
1162 %cB - send a BREAK to the remote system\r\n\
1163 %cR - Request rekey (SSH protocol 2 only)\r\n\
1164 %c# - list forwarded connections\r\n\
1165 %c? - this message\r\n\
1166 %c%c - send the escape character by typing it twice\r\n\
1167(Note that escapes are only recognized immediately after newline.)\r\n",
1168 escape_char, escape_char,
1169 escape_char, escape_char,
1170 escape_char, escape_char,
1171 escape_char, escape_char);
1172 } else {
1173 snprintf(string, sizeof string,
1174"%c?\r\n\
1175Supported escape sequences:\r\n\
1176 %c. - terminate connection (and any multiplexed sessions)\r\n\
1177 %cB - send a BREAK to the remote system\r\n\
1178 %cC - open a command line\r\n\
1179 %cR - Request rekey (SSH protocol 2 only)\r\n\
1180 %c^Z - suspend ssh\r\n\
1181 %c# - list forwarded connections\r\n\
1182 %c& - background ssh (when waiting for connections to terminate)\r\n\
1183 %c? - this message\r\n\
1184 %c%c - send the escape character by typing it twice\r\n\
1185(Note that escapes are only recognized immediately after newline.)\r\n",
1186 escape_char, escape_char,
1187 escape_char, escape_char,
1188 escape_char, escape_char,
1189 escape_char, escape_char,
1190 escape_char, escape_char,
1191 escape_char);
1192 }
1193 buffer_append(berr, string, strlen(string));
1194 continue; 1249 continue;
1195 1250
1196 case '#': 1251 case '#':
@@ -2202,10 +2257,10 @@ client_stop_mux(void)
2202 if (options.control_path != NULL && muxserver_sock != -1) 2257 if (options.control_path != NULL && muxserver_sock != -1)
2203 unlink(options.control_path); 2258 unlink(options.control_path);
2204 /* 2259 /*
2205 * If we are in persist mode, signal that we should close when all 2260 * If we are in persist mode, or don't have a shell, signal that we
2206 * active channels are closed. 2261 * should close when all active channels are closed.
2207 */ 2262 */
2208 if (options.control_persist) { 2263 if (options.control_persist || no_shell_flag) {
2209 session_closed = 1; 2264 session_closed = 1;
2210 setproctitle("[stopped mux]"); 2265 setproctitle("[stopped mux]");
2211 } 2266 }