Bugzilla – Attachment 1512 Details for
Bug 1331
ControlClient escape sequences non-functional
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Process escapes from multiplex slave sessions
ssh-mux-escapes.diff (text/plain), 15.46 KB, created by
Damien Miller
on 2008-06-12 11:41:23 AEST
(
hide
)
Description:
Process escapes from multiplex slave sessions
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2008-06-12 11:41:23 AEST
Size:
15.46 KB
patch
obsolete
>? r >? sftp-server.c.xxx >? ssh-proctitle-size.diff >? ssh-signal-close.broken.diff >Index: channels.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/channels.c,v >retrieving revision 1.278 >diff -u -p -r1.278 channels.c >--- channels.c 10 Jun 2008 04:50:25 -0000 1.278 >+++ channels.c 12 Jun 2008 01:27:00 -0000 >@@ -726,7 +726,7 @@ channel_cancel_cleanup(int id) > > void > channel_register_filter(int id, channel_infilter_fn *ifn, >- channel_outfilter_fn *ofn) >+ channel_outfilter_fn *ofn, void *ctx) > { > Channel *c = channel_lookup(id); > >@@ -736,6 +736,7 @@ channel_register_filter(int id, channel_ > } > c->input_filter = ifn; > c->output_filter = ofn; >+ c->filter_ctx = ctx; > } > > void >Index: channels.h >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/channels.h,v >retrieving revision 1.93 >diff -u -p -r1.93 channels.h >--- channels.h 10 Jun 2008 04:50:25 -0000 1.93 >+++ channels.h 12 Jun 2008 01:27:00 -0000 >@@ -130,6 +130,7 @@ struct Channel { > /* filter */ > channel_infilter_fn *input_filter; > channel_outfilter_fn *output_filter; >+ void *filter_ctx; > > /* keep boundaries */ > int datagram; >@@ -194,7 +195,7 @@ void channel_request_start(int, char *, > void channel_register_cleanup(int, channel_callback_fn *, int); > void channel_register_open_confirm(int, channel_callback_fn *, void *); > void channel_register_filter(int, channel_infilter_fn *, >- channel_outfilter_fn *); >+ channel_outfilter_fn *, void *); > void channel_register_status_confirm(int, channel_confirm_cb *, > channel_confirm_abandon_cb *, void *); > void channel_cancel_cleanup(int); >Index: clientloop.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/clientloop.c,v >retrieving revision 1.194 >diff -u -p -r1.194 clientloop.c >--- clientloop.c 19 May 2008 20:53:52 -0000 1.194 >+++ clientloop.c 12 Jun 2008 01:27:00 -0000 >@@ -136,8 +136,8 @@ static int in_non_blocking_mode = 0; > > /* Common data for the client loop code. */ > static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ >-static int escape_char; /* Escape character. */ >-static int escape_pending; /* Last character was the escape character */ >+static int escape_char1; /* Escape character. (proto1 only) */ >+static int escape_pending1; /* Last character was an escape (proto1 only) */ > static int last_was_cr; /* Last character was a newline. */ > static int exit_status; /* Used to store the exit status of the command. */ > static int stdin_eof; /* EOF has been encountered on standard error. */ >@@ -154,6 +154,13 @@ static int session_closed = 0; /* In SSH > static void client_init_dispatch(void); > int session_ident = -1; > >+/* Track escape per proto2 channel */ >+struct escape_filter_ctx { >+ int escape_pending; >+ int escape_char; >+}; >+ >+/* Context for channel confirmation replies */ > struct channel_reply_ctx { > const char *request_type; > int id, do_close; >@@ -377,8 +384,8 @@ client_check_initial_eof_on_stdin(void) > * and also process it as an escape character if > * appropriate. > */ >- if ((u_char) buf[0] == escape_char) >- escape_pending = 1; >+ if ((u_char) buf[0] == escape_char1) >+ escape_pending1 = 1; > else > buffer_append(&stdin_buffer, buf, 1); > } >@@ -805,9 +812,12 @@ out: > xfree(fwd.connect_host); > } > >-/* process the characters one by one */ >+/* >+ * Process the characters one by one, call with c==NULL for proto1 case. >+ */ > static int >-process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) >+process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, >+ char *buf, int len) > { > char string[1024]; > pid_t pid; >@@ -815,7 +825,20 @@ process_escapes(Buffer *bin, Buffer *bou > u_int i; > u_char ch; > char *s; >+ int *escape_pendingp, escape_char; >+ struct escape_filter_ctx *efc; > >+ if (c == NULL) { >+ escape_pendingp = &escape_pending1; >+ escape_char = escape_char1; >+ } else { >+ if (c->filter_ctx == NULL) >+ return 0; >+ efc = (struct escape_filter_ctx *)c->filter_ctx; >+ escape_pendingp = &efc->escape_pending; >+ escape_char = efc->escape_char; >+ } >+ > if (len <= 0) > return (0); > >@@ -823,25 +846,42 @@ process_escapes(Buffer *bin, Buffer *bou > /* Get one character at a time. */ > ch = buf[i]; > >- if (escape_pending) { >+ if (*escape_pendingp) { > /* We have previously seen an escape character. */ > /* Clear the flag now. */ >- escape_pending = 0; >+ *escape_pendingp = 0; > > /* Process the escaped character. */ > switch (ch) { > case '.': > /* Terminate the connection. */ >- snprintf(string, sizeof string, "%c.\r\n", escape_char); >+ snprintf(string, sizeof string, "%c.\r\n", >+ escape_char); > buffer_append(berr, string, strlen(string)); > >- quit_pending = 1; >+ if (c && c->ctl_fd != -1) { >+ chan_read_failed(c); >+ chan_write_failed(c); >+ } else >+ quit_pending = 1; > return -1; > > case 'Z' - 64: >+ /* XXX support this for mux clients */ >+ if (c && c->ctl_fd != -1) { >+ noescape: >+ snprintf(string, sizeof string, >+ "%c%c escape not available to " >+ "multiplexed sessions\r\n", >+ escape_char, ch); >+ buffer_append(berr, string, >+ strlen(string)); >+ continue; >+ } > /* Suspend the program. */ > /* Print a message to that effect to the user. */ >- snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char); >+ snprintf(string, sizeof string, >+ "%c^Z [suspend ssh]\r\n", escape_char); > buffer_append(berr, string, strlen(string)); > > /* Restore terminal modes and suspend. */ >@@ -873,6 +913,8 @@ process_escapes(Buffer *bin, Buffer *bou > continue; > > case '&': >+ if (c && c->ctl_fd != -1) >+ goto noescape; > /* > * Detach the program (continue to serve connections, > * but put in background and no more new connections). >@@ -921,27 +963,50 @@ process_escapes(Buffer *bin, Buffer *bou > continue; > > case '?': >- snprintf(string, sizeof string, >+ if (c && c->ctl_fd != -1) { >+ snprintf(string, sizeof string, >+"%c?\r\n\ >+Supported escape sequences:\r\n\ >+ %c. - terminate session\r\n\ >+ %cB - send a BREAK to the remote system\r\n\ >+ %cC - open a command line\r\n\ >+ %cR - Request rekey (SSH protocol 2 only)\r\n\ >+ %c# - list forwarded connections\r\n\ >+ %c? - this message\r\n\ >+ %c%c - send the escape character by typing it twice\r\n\ >+(Note that escapes are only recognized immediately after newline.)\r\n", >+ escape_char, escape_char, >+ escape_char, escape_char, >+ escape_char, escape_char, >+ escape_char, escape_char, >+ escape_char); >+ } else { >+ snprintf(string, sizeof string, > "%c?\r\n\ > Supported escape sequences:\r\n\ >-%c. - terminate connection\r\n\ >-%cB - send a BREAK to the remote system\r\n\ >-%cC - open a command line\r\n\ >-%cR - Request rekey (SSH protocol 2 only)\r\n\ >-%c^Z - suspend ssh\r\n\ >-%c# - list forwarded connections\r\n\ >-%c& - background ssh (when waiting for connections to terminate)\r\n\ >-%c? - this message\r\n\ >-%c%c - send the escape character by typing it twice\r\n\ >+ %c. - terminate connection (and any multiplexed sessions)\r\n\ >+ %cB - send a BREAK to the remote system\r\n\ >+ %cC - open a command line\r\n\ >+ %cR - Request rekey (SSH protocol 2 only)\r\n\ >+ %c^Z - suspend ssh\r\n\ >+ %c# - list forwarded connections\r\n\ >+ %c& - background ssh (when waiting for connections to terminate)\r\n\ >+ %c? - this message\r\n\ >+ %c%c - send the escape character by typing it twice\r\n\ > (Note that escapes are only recognized immediately after newline.)\r\n", >- escape_char, escape_char, escape_char, escape_char, >- escape_char, escape_char, escape_char, escape_char, >- escape_char, escape_char, escape_char); >+ escape_char, escape_char, >+ escape_char, escape_char, >+ escape_char, escape_char, >+ escape_char, escape_char, >+ escape_char, escape_char, >+ escape_char); >+ } > buffer_append(berr, string, strlen(string)); > continue; > > case '#': >- snprintf(string, sizeof string, "%c#\r\n", escape_char); >+ snprintf(string, sizeof string, "%c#\r\n", >+ escape_char); > buffer_append(berr, string, strlen(string)); > s = channel_open_message(); > buffer_append(berr, s, strlen(s)); >@@ -967,7 +1032,7 @@ Supported escape sequences:\r\n\ > */ > if (last_was_cr && ch == escape_char) { > /* It is. Set the flag and continue to next character. */ >- escape_pending = 1; >+ *escape_pendingp = 1; > continue; > } > } >@@ -1018,7 +1083,7 @@ client_process_input(fd_set *readset) > packet_start(SSH_CMSG_EOF); > packet_send(); > } >- } else if (escape_char == SSH_ESCAPECHAR_NONE) { >+ } else if (escape_char1 == SSH_ESCAPECHAR_NONE) { > /* > * Normal successful read, and no escape character. > * Just append the data to buffer. >@@ -1029,8 +1094,8 @@ client_process_input(fd_set *readset) > * Normal, successful read. But we have an escape character > * and have to process the characters one by one. > */ >- if (process_escapes(&stdin_buffer, &stdout_buffer, >- &stderr_buffer, buf, len) == -1) >+ if (process_escapes(NULL, &stdin_buffer, >+ &stdout_buffer, &stderr_buffer, buf, len) == -1) > return; > } > } >@@ -1105,13 +1170,26 @@ client_process_buffered_input_packets(vo > > /* scan buf[] for '~' before sending data to the peer */ > >-static int >-simple_escape_filter(Channel *c, char *buf, int len) >+/* Helper: allocate a new escape_filter_ctx and fill in its escape char */ >+void * >+client_new_escape_filter_ctx(int escape_char) >+{ >+ struct escape_filter_ctx *ret; >+ >+ ret = xmalloc(sizeof(*ret)); >+ ret->escape_pending = 0; >+ ret->escape_char = escape_char; >+ return (void *)ret; >+} >+ >+int >+client_simple_escape_filter(Channel *c, char *buf, int len) > { > if (c->extended_usage != CHAN_EXTENDED_WRITE) > return 0; > >- return process_escapes(&c->input, &c->output, &c->extended, buf, len); >+ return process_escapes(c, &c->input, &c->output, &c->extended, >+ buf, len); > } > > static void >@@ -1143,7 +1221,7 @@ client_loop(int have_pty, int escape_cha > start_time = get_current_time(); > > /* Initialize variables. */ >- escape_pending = 0; >+ escape_pending1 = 0; > last_was_cr = 1; > exit_status = -1; > stdin_eof = 0; >@@ -1170,7 +1248,7 @@ client_loop(int have_pty, int escape_cha > stdout_bytes = 0; > stderr_bytes = 0; > quit_pending = 0; >- escape_char = escape_char_arg; >+ escape_char1 = escape_char_arg; > > /* Initialize buffers. */ > buffer_init(&stdin_buffer); >@@ -1198,9 +1276,10 @@ client_loop(int have_pty, int escape_cha > > if (compat20) { > session_ident = ssh2_chan_id; >- if (escape_char != SSH_ESCAPECHAR_NONE) >+ if (escape_char_arg != SSH_ESCAPECHAR_NONE) > channel_register_filter(session_ident, >- simple_escape_filter, NULL); >+ client_simple_escape_filter, NULL, >+ client_new_escape_filter_ctx(escape_char_arg)); > if (session_ident != -1) > channel_register_cleanup(session_ident, > client_channel_closed, 0); >Index: clientloop.h >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/clientloop.h,v >retrieving revision 1.19 >diff -u -p -r1.19 clientloop.h >--- clientloop.h 9 May 2008 14:18:44 -0000 1.19 >+++ clientloop.h 12 Jun 2008 01:27:00 -0000 >@@ -46,8 +46,12 @@ void client_session2_setup(int, int, in > int, Buffer *, char **); > int client_request_tun_fwd(int, int, int); > >+/* Escape filter for protocol 2 sessions */ >+void *client_new_escape_filter_ctx(int); >+int client_simple_escape_filter(Channel *, char *, int); >+ > /* Multiplexing protocol version */ >-#define SSHMUX_VER 1 >+#define SSHMUX_VER 2 > > /* Multiplexing control protocol flags */ > #define SSHMUX_COMMAND_OPEN 1 /* Open new connection */ >@@ -59,20 +63,6 @@ int client_request_tun_fwd(int, int, in > #define SSHMUX_FLAG_X11_FWD (1<<2) /* Request X11 forwarding */ > #define SSHMUX_FLAG_AGENT_FWD (1<<3) /* Request agent forwarding */ > >-/* Multiplexing routines */ >- >-struct mux_session_confirm_ctx { >- int want_tty; >- int want_subsys; >- int want_x_fwd; >- int want_agent_fwd; >- Buffer cmd; >- char *term; >- struct termios tio; >- char **env; >-}; >- >-/* mux.c */ > void muxserver_listen(void); > int muxserver_accept_control(void); > void muxclient(const char *); >Index: mux.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/mux.c,v >retrieving revision 1.1 >diff -u -p -r1.1 mux.c >--- mux.c 9 May 2008 14:18:44 -0000 1.1 >+++ mux.c 12 Jun 2008 01:27:00 -0000 >@@ -60,6 +60,18 @@ extern char *host; > int subsystem_flag; > extern Buffer command; > >+/* Context for session open confirmation callback */ >+struct mux_session_confirm_ctx { >+ int want_tty; >+ int want_subsys; >+ int want_x_fwd; >+ int want_agent_fwd; >+ Buffer cmd; >+ char *term; >+ struct termios tio; >+ char **env; >+}; >+ > /* fd to control socket */ > int muxserver_sock = -1; > >@@ -178,7 +190,7 @@ muxserver_accept_control(void) > struct sockaddr_storage addr; > struct mux_session_confirm_ctx *cctx; > char *cmd; >- u_int i, j, len, env_len, mux_command, flags; >+ u_int i, j, len, env_len, mux_command, flags, escape_char; > uid_t euid; > gid_t egid; > int start_close = 0; >@@ -305,6 +317,7 @@ muxserver_accept_control(void) > cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; > cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0; > cctx->term = buffer_get_string(&m, &len); >+ escape_char = buffer_get_int(&m); > > cmd = buffer_get_string(&m, &len); > buffer_init(&cctx->cmd); >@@ -390,8 +403,12 @@ muxserver_accept_control(void) > new_fd[0], new_fd[1], new_fd[2], window, packetmax, > CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); > >- /* XXX */ > c->ctl_fd = client_fd; >+ if (cctx->want_tty && escape_char != 0xffffffff) { >+ channel_register_filter(c->self, >+ client_simple_escape_filter, NULL, >+ client_new_escape_filter_ctx((int)escape_char)); >+ } > > debug3("%s: channel_new: %d", __func__, c->self); > >@@ -549,33 +566,34 @@ muxclient(const char *path) > fprintf(stderr, "Exit request sent.\r\n"); > exit(0); > case SSHMUX_COMMAND_OPEN: >- /* continue below */ >+ buffer_put_cstring(&m, term ? term : ""); >+ if (options.escape_char == SSH_ESCAPECHAR_NONE) >+ buffer_put_int(&m, 0xffffffff); >+ else >+ buffer_put_int(&m, options.escape_char); >+ buffer_append(&command, "\0", 1); >+ buffer_put_cstring(&m, buffer_ptr(&command)); >+ >+ if (options.num_send_env == 0 || environ == NULL) { >+ buffer_put_int(&m, 0); >+ } else { >+ /* Pass environment */ >+ num_env = 0; >+ for (i = 0; environ[i] != NULL; i++) { >+ if (env_permitted(environ[i])) >+ num_env++; /* Count */ >+ } >+ buffer_put_int(&m, num_env); >+ for (i = 0; environ[i] != NULL && num_env >= 0; i++) { >+ if (env_permitted(environ[i])) { >+ num_env--; >+ buffer_put_cstring(&m, environ[i]); >+ } >+ } >+ } > break; > default: >- fatal("silly muxclient_command %d", muxclient_command); >- } >- >- /* SSHMUX_COMMAND_OPEN */ >- buffer_put_cstring(&m, term ? term : ""); >- buffer_append(&command, "\0", 1); >- buffer_put_cstring(&m, buffer_ptr(&command)); >- >- if (options.num_send_env == 0 || environ == NULL) { >- buffer_put_int(&m, 0); >- } else { >- /* Pass environment */ >- num_env = 0; >- for (i = 0; environ[i] != NULL; i++) >- if (env_permitted(environ[i])) >- num_env++; /* Count */ >- >- buffer_put_int(&m, num_env); >- >- for (i = 0; environ[i] != NULL && num_env >= 0; i++) >- if (env_permitted(environ[i])) { >- num_env--; >- buffer_put_cstring(&m, environ[i]); >- } >+ fatal("unrecognised muxclient_command %d", muxclient_command); > } > > if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1331
: 1512 |
1854