diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ssh/channels.c | 22 | ||||
-rw-r--r-- | usr.bin/ssh/channels.h | 7 | ||||
-rw-r--r-- | usr.bin/ssh/clientloop.c | 40 | ||||
-rw-r--r-- | usr.bin/ssh/ssh.c | 21 | ||||
-rw-r--r-- | usr.bin/ssh/ssh.h | 4 |
5 files changed, 80 insertions, 14 deletions
diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c index 37b40347fb9..3ecceb639b4 100644 --- a/usr.bin/ssh/channels.c +++ b/usr.bin/ssh/channels.c @@ -17,7 +17,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.64 2000/07/16 08:27:21 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.65 2000/08/19 18:48:10 markus Exp $"); #include "ssh.h" #include "packet.h" @@ -244,6 +244,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->cb_arg = NULL; c->cb_event = 0; c->dettach_user = NULL; + c->input_filter = NULL; debug("channel %d: new [%s]", found, remote_name); return found; } @@ -665,7 +666,14 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) } return -1; } - buffer_append(&c->input, buf, len); + if(c->input_filter != NULL) { + if (c->input_filter(&c->input, buf, len) == -1) { + debug("filter stops channel %d", c->self); + chan_read_failed(c); + } + } else { + buffer_append(&c->input, buf, len); + } } return 1; } @@ -2253,6 +2261,16 @@ channel_cancel_cleanup(int id) } c->dettach_user = NULL; } +void +channel_register_filter(int id, channel_filter_fn *fn) +{ + Channel *c = channel_lookup(id); + if (c == NULL) { + log("channel_register_filter: %d: bad id", id); + return; + } + c->input_filter = fn; +} void channel_set_fds(int id, int rfd, int wfd, int efd, int extusage) diff --git a/usr.bin/ssh/channels.h b/usr.bin/ssh/channels.h index 9629124b968..10ba934a733 100644 --- a/usr.bin/ssh/channels.h +++ b/usr.bin/ssh/channels.h @@ -1,4 +1,4 @@ -/* RCSID("$OpenBSD: channels.h,v 1.14 2000/06/20 01:39:40 markus Exp $"); */ +/* RCSID("$OpenBSD: channels.h,v 1.15 2000/08/19 18:48:11 markus Exp $"); */ #ifndef CHANNELS_H #define CHANNELS_H @@ -22,6 +22,7 @@ * and cleared in channel_free. */ typedef void channel_callback_fn(int id, void *arg); +typedef int channel_filter_fn(Buffer *b, char *buf, int len); typedef struct Channel { int type; /* channel type/state */ @@ -61,6 +62,9 @@ typedef struct Channel { void *cb_arg; int cb_event; channel_callback_fn *dettach_user; + + /* filter */ + channel_filter_fn *input_filter; } Channel; #define CHAN_EXTENDED_IGNORE 0 @@ -73,6 +77,7 @@ void channel_request(int id, char *service, int wantconfirm); void channel_request_start(int id, char *service, int wantconfirm); void channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg); void channel_register_cleanup(int id, channel_callback_fn *fn); +void channel_register_filter(int id, channel_filter_fn *fn); void channel_cancel_cleanup(int id); Channel *channel_lookup(int id); diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index 67fa36d911a..4d2fda1418e 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -16,7 +16,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.29 2000/07/16 08:27:21 markus Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.30 2000/08/19 18:48:11 markus Exp $"); #include "xmalloc.h" #include "ssh.h" @@ -29,6 +29,9 @@ RCSID("$OpenBSD: clientloop.c,v 1.29 2000/07/16 08:27:21 markus Exp $"); #include "channels.h" #include "dispatch.h" +#include "buffer.h" +#include "bufaux.h" + /* Flag indicating that stdin should be redirected from /dev/null. */ extern int stdin_null_flag; @@ -722,6 +725,35 @@ client_process_buffered_input_packets() dispatch_run(DISPATCH_NONBLOCK, &quit_pending); } +/* scan stdin buf[] for '~' before sending data to the peer */ + +int +simple_escape_filter(Buffer *bin, char *buf, int len) +{ + unsigned int i; + unsigned char ch; + for (i = 0; i < len; i++) { + ch = buf[i]; + if (escape_pending) { + escape_pending = 0; + if (ch == '.') { + quit_pending = 1; + return -1; + } + if (ch != escape_char) + buffer_put_char(bin, escape_char); + } else { + if (last_was_cr && ch == escape_char) { + escape_pending = 1; + continue; + } + } + last_was_cr = (ch == '\n' || ch == '\r'); + buffer_put_char(bin, ch); + } + return 0; +} + /* * Implements the interactive session with the server. This is called after * the user has been authenticated, and a command has been started on the @@ -730,7 +762,7 @@ client_process_buffered_input_packets() */ int -client_loop(int have_pty, int escape_char_arg) +client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) { extern Options options; double start_time, total_time; @@ -780,6 +812,9 @@ client_loop(int have_pty, int escape_char_arg) if (!compat20) client_check_initial_eof_on_stdin(); + if (compat20 && escape_char != -1) + channel_register_filter(ssh2_chan_id, simple_escape_filter); + /* Main loop of the client for the interactive session mode. */ while (!quit_pending) { fd_set readset, writeset; @@ -989,6 +1024,7 @@ client_input_channel_open(int type, int plen) /* XXX move to channels.c */ sock = x11_connect_display(); if (sock >= 0) { +/*XXX MAXPACK */ id = channel_new("x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, 4*1024, 32*1024, 0, xstrdup("x11")); diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c index f28504fdbb7..19b0875577a 100644 --- a/usr.bin/ssh/ssh.c +++ b/usr.bin/ssh/ssh.c @@ -11,7 +11,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.59 2000/08/19 02:07:23 deraadt Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.60 2000/08/19 18:48:11 markus Exp $"); #include <openssl/evp.h> #include <openssl/dsa.h> @@ -861,7 +861,7 @@ ssh_session(void) } /* Enter the interactive session. */ - return client_loop(have_tty, tty_flag ? options.escape_char : -1); + return client_loop(have_tty, tty_flag ? options.escape_char : -1, 0); } void @@ -944,9 +944,16 @@ int ssh_session2(void) { int window, packetmax, id; - int in = dup(STDIN_FILENO); - int out = dup(STDOUT_FILENO); - int err = dup(STDERR_FILENO); + int in, out, err; + + /* If requested, let ssh continue in the background. */ + if (fork_after_authentication_flag) + if (daemon(1, 1) < 0) + fatal("daemon() failed: %.200s", strerror(errno)); + + in = dup(STDIN_FILENO); + out = dup(STDOUT_FILENO); + err = dup(STDERR_FILENO); if (in < 0 || out < 0 || err < 0) fatal("dump in/out/err failed"); @@ -962,13 +969,13 @@ ssh_session2(void) packetmax = window/2; } +/*XXX MAXPACK */ id = channel_new( "session", SSH_CHANNEL_OPENING, in, out, err, window, packetmax, CHAN_EXTENDED_WRITE, xstrdup("client-session")); - channel_open(id); channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0); - return client_loop(tty_flag, tty_flag ? options.escape_char : -1); + return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id); } diff --git a/usr.bin/ssh/ssh.h b/usr.bin/ssh/ssh.h index 94e75e98191..599280595f4 100644 --- a/usr.bin/ssh/ssh.h +++ b/usr.bin/ssh/ssh.h @@ -13,7 +13,7 @@ * */ -/* RCSID("$OpenBSD: ssh.h,v 1.48 2000/07/13 22:53:21 provos Exp $"); */ +/* RCSID("$OpenBSD: ssh.h,v 1.49 2000/08/19 18:48:11 markus Exp $"); */ #ifndef SSH_H #define SSH_H @@ -467,7 +467,7 @@ void server_loop(pid_t pid, int fdin, int fdout, int fderr); void server_loop2(void); /* Client side main loop for the interactive session. */ -int client_loop(int have_pty, int escape_char); +int client_loop(int have_pty, int escape_char, int id); /* Linked list of custom environment strings (see auth-rsa.c). */ struct envstring { |