]> andersk Git - openssh.git/blobdiff - channels.c
- (tim) [configure.ac] Bug #1149. Changes in QNX section only. Patch by
[openssh.git] / channels.c
index e73dc247d6987b08775568ee9cccef10d5627fb5..1252f344673b8e4efb39dc25b7aa4638e8d1633b 100644 (file)
@@ -39,7 +39,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.229 2005/12/12 13:46:18 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.232 2006/01/30 12:22:22 reyk Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -58,8 +58,6 @@ RCSID("$OpenBSD: channels.c,v 1.229 2005/12/12 13:46:18 markus 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,26 @@ 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);
+                               if (c->type != SSH_CHANNEL_OPEN)
+                                       chan_mark_dead(c);
+                               else
+                                       chan_write_failed(c);
+                               return -1;
+                       }
+               } 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;
@@ -1479,14 +1495,13 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
                        }
                        return 1;
                }
-               data = buffer_ptr(&c->output);
-               dlen = buffer_len(&c->output);
 #ifdef _AIX
                /* XXX: Later AIX versions can't push as much data to tty */
                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 +1518,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();
@@ -3025,7 +3040,7 @@ deny_input_open(int type, u_int32_t seq, void *ctxt)
                error("deny_input_open: type %d", type);
                break;
        }
-       error("Warning: this is probably a break in attempt by a malicious server.");
+       error("Warning: this is probably a break-in attempt by a malicious server.");
        packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
        packet_put_int(rchan);
        packet_send();
This page took 0.042172 seconds and 4 git commands to generate.