summaryrefslogtreecommitdiffstats
path: root/usr.bin/ssh/channels.c
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2005-12-30 15:56:36 +0000
committerreyk <reyk@openbsd.org>2005-12-30 15:56:36 +0000
commita1bcc0815ed72437eab4dcf5622c7593d99035ea (patch)
tree7fce1d084e81f0b930a1f55ddfccf6c9009d62e1 /usr.bin/ssh/channels.c
parentUse sys/hash.h instead of own built functions that work similar. (diff)
downloadwireguard-openbsd-a1bcc0815ed72437eab4dcf5622c7593d99035ea.tar.xz
wireguard-openbsd-a1bcc0815ed72437eab4dcf5622c7593d99035ea.zip
add channel output filter interface.
ok djm@, suggested by markus@
Diffstat (limited to 'usr.bin/ssh/channels.c')
-rw-r--r--usr.bin/ssh/channels.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c
index 50ca56293fd..778ddec23e7 100644
--- a/usr.bin/ssh/channels.c
+++ b/usr.bin/ssh/channels.c
@@ -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.
@@ -300,6 +298,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;
}
@@ -680,7 +679,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);
@@ -688,7 +688,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
@@ -1453,7 +1454,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;
@@ -1461,11 +1462,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;
@@ -1478,9 +1490,8 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
}
return 1;
}
- data = buffer_ptr(&c->output);
- dlen = buffer_len(&c->output);
- len = write(c->wfd, data, dlen);
+
+ len = write(c->wfd, buf, dlen);
if (len < 0 && (errno == EINTR || errno == EAGAIN))
return 1;
if (len <= 0) {
@@ -1497,14 +1508,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();