]> andersk Git - openssh.git/commitdiff
- reyk@cvs.openbsd.org 2005/12/30 15:56:37
authordjm <djm>
Sat, 31 Dec 2005 05:22:32 +0000 (05:22 +0000)
committerdjm <djm>
Sat, 31 Dec 2005 05:22:32 +0000 (05:22 +0000)
     [channels.c channels.h clientloop.c]
     add channel output filter interface.
     ok djm@, suggested by markus@

ChangeLog
channels.c
channels.h
clientloop.c

index 375bdf9c8ca875d712a5b9f1a93d1d274fcf59cf..e5419488ece2e263a337a070218020abacdb1b44 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,10 @@
    - stevesk@cvs.openbsd.org 2005/12/28 22:46:06
      [canohost.c channels.c clientloop.c]
      use 'break-in' for consistency; ok deraadt@ ok and input jmc@
+   - reyk@cvs.openbsd.org 2005/12/30 15:56:37
+     [channels.c channels.h clientloop.c]
+     add channel output filter interface.
+     ok djm@, suggested by markus@
 
 20051229
  - (tim) [buildpkg.sh.in] grep for $SSHDUID instead of $SSHDGID on /etc/passwd
index b431532a3c9aeda6e8f7dba7ffaf74b8115e018d..ed5903f6fd3dbf5cbd4e9367446ae69d1305fc91 100644 (file)
@@ -39,7 +39,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.230 2005/12/28 22:46:06 stevesk Exp $");
+RCSID("$OpenBSD: channels.c,v 1.231 2005/12/30 15:56:36 reyk Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -58,8 +58,6 @@ RCSID("$OpenBSD: channels.c,v 1.230 2005/12/28 22:46:06 stevesk Exp $");
 
 /* -- channel core */
 
-#define CHAN_RBUF      16*1024
-
 /*
  * Pointer to an array containing all allocated channels.  The array is
  * dynamically extended as needed.
@@ -301,6 +299,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
        c->confirm = NULL;
        c->confirm_ctx = NULL;
        c->input_filter = NULL;
+       c->output_filter = NULL;
        debug("channel %d: new [%s]", found, remote_name);
        return c;
 }
@@ -681,7 +680,8 @@ channel_cancel_cleanup(int id)
        c->detach_close = 0;
 }
 void
-channel_register_filter(int id, channel_filter_fn *fn)
+channel_register_filter(int id, channel_infilter_fn *ifn,
+    channel_outfilter_fn *ofn)
 {
        Channel *c = channel_lookup(id);
 
@@ -689,7 +689,8 @@ channel_register_filter(int id, channel_filter_fn *fn)
                logit("channel_register_filter: %d: bad id", id);
                return;
        }
-       c->input_filter = fn;
+       c->input_filter = ifn;
+       c->output_filter = ofn;
 }
 
 void
@@ -1454,7 +1455,7 @@ static int
 channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
 {
        struct termios tio;
-       u_char *data;
+       u_char *data = NULL, *buf;
        u_int dlen;
        int len;
 
@@ -1462,11 +1463,22 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
        if (c->wfd != -1 &&
            FD_ISSET(c->wfd, writeset) &&
            buffer_len(&c->output) > 0) {
+               if (c->output_filter != NULL) {
+                       if ((buf = c->output_filter(c, &data, &dlen)) == NULL) {
+                               debug2("channel %d: filter stops", c->self);
+                               chan_read_failed(c);
+                       }
+               } else if (c->datagram) {
+                       buf = data = buffer_get_string(&c->output, &dlen);
+               } else {
+                       buf = data = buffer_ptr(&c->output);
+                       dlen = buffer_len(&c->output);
+               }
+
                if (c->datagram) {
-                       data = buffer_get_string(&c->output, &dlen);
                        /* ignore truncated writes, datagrams might get lost */
                        c->local_consumed += dlen + 4;
-                       len = write(c->wfd, data, dlen);
+                       len = write(c->wfd, buf, dlen);
                        xfree(data);
                        if (len < 0 && (errno == EINTR || errno == EAGAIN))
                                return 1;
@@ -1486,7 +1498,8 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
                if (compat20 && c->wfd_isatty)
                        dlen = MIN(dlen, 8*1024);
 #endif
-               len = write(c->wfd, data, dlen);
+
+               len = write(c->wfd, buf, dlen);
                if (len < 0 && (errno == EINTR || errno == EAGAIN))
                        return 1;
                if (len <= 0) {
@@ -1503,14 +1516,14 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
                        }
                        return -1;
                }
-               if (compat20 && c->isatty && dlen >= 1 && data[0] != '\r') {
+               if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') {
                        if (tcgetattr(c->wfd, &tio) == 0 &&
                            !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
                                /*
                                 * Simulate echo to reduce the impact of
                                 * traffic analysis. We need to match the
                                 * size of a SSH2_MSG_CHANNEL_DATA message
-                                * (4 byte channel id + data)
+                                * (4 byte channel id + buf)
                                 */
                                packet_send_ignore(4 + len);
                                packet_send();
index 7990fe147880c5d24f7a280fa08847d1e973b3fe..a97dd90071292fc6b8a6943033c78ae0d836dcce 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: channels.h,v 1.82 2005/12/12 13:46:18 markus Exp $    */
+/*     $OpenBSD: channels.h,v 1.83 2005/12/30 15:56:37 reyk Exp $      */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -63,7 +63,8 @@ struct Channel;
 typedef struct Channel Channel;
 
 typedef void channel_callback_fn(int, void *);
-typedef int channel_filter_fn(struct Channel *, char *, int);
+typedef int channel_infilter_fn(struct Channel *, char *, int);
+typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *);
 
 struct Channel {
        int     type;           /* channel type/state */
@@ -111,7 +112,8 @@ struct Channel {
        int                     detach_close;
 
        /* filter */
-       channel_filter_fn       *input_filter;
+       channel_infilter_fn     *input_filter;
+       channel_outfilter_fn    *output_filter;
 
        int     datagram;       /* keep boundaries */
 };
@@ -145,6 +147,8 @@ struct Channel {
 #define CHAN_EOF_SENT                  0x04
 #define CHAN_EOF_RCVD                  0x08
 
+#define CHAN_RBUF      16*1024
+
 /* check whether 'efd' is still in use */
 #define CHANNEL_EFD_INPUT_ACTIVE(c) \
        (compat20 && c->extended_usage == CHAN_EXTENDED_READ && \
@@ -169,7 +173,7 @@ void         channel_send_open(int);
 void    channel_request_start(int, char *, int);
 void    channel_register_cleanup(int, channel_callback_fn *, int);
 void    channel_register_confirm(int, channel_callback_fn *, void *);
-void    channel_register_filter(int, channel_filter_fn *);
+void    channel_register_filter(int, channel_infilter_fn *, channel_outfilter_fn *);
 void    channel_cancel_cleanup(int);
 int     channel_close_fd(int *);
 void    channel_send_window_changes(void);
index a71552cad7b20341941603f5529f8ecdbc39a7c7..b76f7cfe05369cd11661ead9d068ecf913915066 100644 (file)
@@ -59,7 +59,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.148 2005/12/28 22:46:06 stevesk Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.149 2005/12/30 15:56:37 reyk Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -1386,7 +1386,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
                session_ident = ssh2_chan_id;
                if (escape_char != SSH_ESCAPECHAR_NONE)
                        channel_register_filter(session_ident,
-                           simple_escape_filter);
+                           simple_escape_filter, NULL);
                if (session_ident != -1)
                        channel_register_cleanup(session_ident,
                            client_channel_closed, 0);
This page took 0.183989 seconds and 5 git commands to generate.