diff options
author | Damien Miller <djm@mindrot.org> | 2005-12-31 16:22:32 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2005-12-31 16:22:32 +1100 |
commit | 077b23864f567551dc7147db8ccd69559617976e (patch) | |
tree | 0544f3e7e7b1f28d627272c760eb18d8dda9b75f | |
parent | 5eb137c6d11be7db14dc03ea12a74884bebea3e3 (diff) |
- 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@
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | channels.c | 35 | ||||
-rw-r--r-- | channels.h | 12 | ||||
-rw-r--r-- | clientloop.c | 4 |
4 files changed, 39 insertions, 18 deletions
@@ -3,6 +3,10 @@ | |||
3 | - stevesk@cvs.openbsd.org 2005/12/28 22:46:06 | 3 | - stevesk@cvs.openbsd.org 2005/12/28 22:46:06 |
4 | [canohost.c channels.c clientloop.c] | 4 | [canohost.c channels.c clientloop.c] |
5 | use 'break-in' for consistency; ok deraadt@ ok and input jmc@ | 5 | use 'break-in' for consistency; ok deraadt@ ok and input jmc@ |
6 | - reyk@cvs.openbsd.org 2005/12/30 15:56:37 | ||
7 | [channels.c channels.h clientloop.c] | ||
8 | add channel output filter interface. | ||
9 | ok djm@, suggested by markus@ | ||
6 | 10 | ||
7 | 20051229 | 11 | 20051229 |
8 | - (tim) [buildpkg.sh.in] grep for $SSHDUID instead of $SSHDGID on /etc/passwd | 12 | - (tim) [buildpkg.sh.in] grep for $SSHDUID instead of $SSHDGID on /etc/passwd |
@@ -3558,4 +3562,4 @@ | |||
3558 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 3562 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
3559 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 3563 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
3560 | 3564 | ||
3561 | $Id: ChangeLog,v 1.4053 2005/12/31 05:19:53 djm Exp $ | 3565 | $Id: ChangeLog,v 1.4054 2005/12/31 05:22:32 djm Exp $ |
diff --git a/channels.c b/channels.c index b431532a3..ed5903f6f 100644 --- a/channels.c +++ b/channels.c | |||
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: channels.c,v 1.230 2005/12/28 22:46:06 stevesk Exp $"); | 42 | RCSID("$OpenBSD: channels.c,v 1.231 2005/12/30 15:56:36 reyk Exp $"); |
43 | 43 | ||
44 | #include "ssh.h" | 44 | #include "ssh.h" |
45 | #include "ssh1.h" | 45 | #include "ssh1.h" |
@@ -58,8 +58,6 @@ RCSID("$OpenBSD: channels.c,v 1.230 2005/12/28 22:46:06 stevesk Exp $"); | |||
58 | 58 | ||
59 | /* -- channel core */ | 59 | /* -- channel core */ |
60 | 60 | ||
61 | #define CHAN_RBUF 16*1024 | ||
62 | |||
63 | /* | 61 | /* |
64 | * Pointer to an array containing all allocated channels. The array is | 62 | * Pointer to an array containing all allocated channels. The array is |
65 | * dynamically extended as needed. | 63 | * dynamically extended as needed. |
@@ -301,6 +299,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, | |||
301 | c->confirm = NULL; | 299 | c->confirm = NULL; |
302 | c->confirm_ctx = NULL; | 300 | c->confirm_ctx = NULL; |
303 | c->input_filter = NULL; | 301 | c->input_filter = NULL; |
302 | c->output_filter = NULL; | ||
304 | debug("channel %d: new [%s]", found, remote_name); | 303 | debug("channel %d: new [%s]", found, remote_name); |
305 | return c; | 304 | return c; |
306 | } | 305 | } |
@@ -681,7 +680,8 @@ channel_cancel_cleanup(int id) | |||
681 | c->detach_close = 0; | 680 | c->detach_close = 0; |
682 | } | 681 | } |
683 | void | 682 | void |
684 | channel_register_filter(int id, channel_filter_fn *fn) | 683 | channel_register_filter(int id, channel_infilter_fn *ifn, |
684 | channel_outfilter_fn *ofn) | ||
685 | { | 685 | { |
686 | Channel *c = channel_lookup(id); | 686 | Channel *c = channel_lookup(id); |
687 | 687 | ||
@@ -689,7 +689,8 @@ channel_register_filter(int id, channel_filter_fn *fn) | |||
689 | logit("channel_register_filter: %d: bad id", id); | 689 | logit("channel_register_filter: %d: bad id", id); |
690 | return; | 690 | return; |
691 | } | 691 | } |
692 | c->input_filter = fn; | 692 | c->input_filter = ifn; |
693 | c->output_filter = ofn; | ||
693 | } | 694 | } |
694 | 695 | ||
695 | void | 696 | void |
@@ -1454,7 +1455,7 @@ static int | |||
1454 | channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) | 1455 | channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) |
1455 | { | 1456 | { |
1456 | struct termios tio; | 1457 | struct termios tio; |
1457 | u_char *data; | 1458 | u_char *data = NULL, *buf; |
1458 | u_int dlen; | 1459 | u_int dlen; |
1459 | int len; | 1460 | int len; |
1460 | 1461 | ||
@@ -1462,11 +1463,22 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) | |||
1462 | if (c->wfd != -1 && | 1463 | if (c->wfd != -1 && |
1463 | FD_ISSET(c->wfd, writeset) && | 1464 | FD_ISSET(c->wfd, writeset) && |
1464 | buffer_len(&c->output) > 0) { | 1465 | buffer_len(&c->output) > 0) { |
1466 | if (c->output_filter != NULL) { | ||
1467 | if ((buf = c->output_filter(c, &data, &dlen)) == NULL) { | ||
1468 | debug2("channel %d: filter stops", c->self); | ||
1469 | chan_read_failed(c); | ||
1470 | } | ||
1471 | } else if (c->datagram) { | ||
1472 | buf = data = buffer_get_string(&c->output, &dlen); | ||
1473 | } else { | ||
1474 | buf = data = buffer_ptr(&c->output); | ||
1475 | dlen = buffer_len(&c->output); | ||
1476 | } | ||
1477 | |||
1465 | if (c->datagram) { | 1478 | if (c->datagram) { |
1466 | data = buffer_get_string(&c->output, &dlen); | ||
1467 | /* ignore truncated writes, datagrams might get lost */ | 1479 | /* ignore truncated writes, datagrams might get lost */ |
1468 | c->local_consumed += dlen + 4; | 1480 | c->local_consumed += dlen + 4; |
1469 | len = write(c->wfd, data, dlen); | 1481 | len = write(c->wfd, buf, dlen); |
1470 | xfree(data); | 1482 | xfree(data); |
1471 | if (len < 0 && (errno == EINTR || errno == EAGAIN)) | 1483 | if (len < 0 && (errno == EINTR || errno == EAGAIN)) |
1472 | return 1; | 1484 | return 1; |
@@ -1486,7 +1498,8 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) | |||
1486 | if (compat20 && c->wfd_isatty) | 1498 | if (compat20 && c->wfd_isatty) |
1487 | dlen = MIN(dlen, 8*1024); | 1499 | dlen = MIN(dlen, 8*1024); |
1488 | #endif | 1500 | #endif |
1489 | len = write(c->wfd, data, dlen); | 1501 | |
1502 | len = write(c->wfd, buf, dlen); | ||
1490 | if (len < 0 && (errno == EINTR || errno == EAGAIN)) | 1503 | if (len < 0 && (errno == EINTR || errno == EAGAIN)) |
1491 | return 1; | 1504 | return 1; |
1492 | if (len <= 0) { | 1505 | if (len <= 0) { |
@@ -1503,14 +1516,14 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) | |||
1503 | } | 1516 | } |
1504 | return -1; | 1517 | return -1; |
1505 | } | 1518 | } |
1506 | if (compat20 && c->isatty && dlen >= 1 && data[0] != '\r') { | 1519 | if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') { |
1507 | if (tcgetattr(c->wfd, &tio) == 0 && | 1520 | if (tcgetattr(c->wfd, &tio) == 0 && |
1508 | !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { | 1521 | !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { |
1509 | /* | 1522 | /* |
1510 | * Simulate echo to reduce the impact of | 1523 | * Simulate echo to reduce the impact of |
1511 | * traffic analysis. We need to match the | 1524 | * traffic analysis. We need to match the |
1512 | * size of a SSH2_MSG_CHANNEL_DATA message | 1525 | * size of a SSH2_MSG_CHANNEL_DATA message |
1513 | * (4 byte channel id + data) | 1526 | * (4 byte channel id + buf) |
1514 | */ | 1527 | */ |
1515 | packet_send_ignore(4 + len); | 1528 | packet_send_ignore(4 + len); |
1516 | packet_send(); | 1529 | packet_send(); |
diff --git a/channels.h b/channels.h index 7990fe147..a97dd9007 100644 --- a/channels.h +++ b/channels.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: channels.h,v 1.82 2005/12/12 13:46:18 markus Exp $ */ | 1 | /* $OpenBSD: channels.h,v 1.83 2005/12/30 15:56:37 reyk Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -63,7 +63,8 @@ struct Channel; | |||
63 | typedef struct Channel Channel; | 63 | typedef struct Channel Channel; |
64 | 64 | ||
65 | typedef void channel_callback_fn(int, void *); | 65 | typedef void channel_callback_fn(int, void *); |
66 | typedef int channel_filter_fn(struct Channel *, char *, int); | 66 | typedef int channel_infilter_fn(struct Channel *, char *, int); |
67 | typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *); | ||
67 | 68 | ||
68 | struct Channel { | 69 | struct Channel { |
69 | int type; /* channel type/state */ | 70 | int type; /* channel type/state */ |
@@ -111,7 +112,8 @@ struct Channel { | |||
111 | int detach_close; | 112 | int detach_close; |
112 | 113 | ||
113 | /* filter */ | 114 | /* filter */ |
114 | channel_filter_fn *input_filter; | 115 | channel_infilter_fn *input_filter; |
116 | channel_outfilter_fn *output_filter; | ||
115 | 117 | ||
116 | int datagram; /* keep boundaries */ | 118 | int datagram; /* keep boundaries */ |
117 | }; | 119 | }; |
@@ -145,6 +147,8 @@ struct Channel { | |||
145 | #define CHAN_EOF_SENT 0x04 | 147 | #define CHAN_EOF_SENT 0x04 |
146 | #define CHAN_EOF_RCVD 0x08 | 148 | #define CHAN_EOF_RCVD 0x08 |
147 | 149 | ||
150 | #define CHAN_RBUF 16*1024 | ||
151 | |||
148 | /* check whether 'efd' is still in use */ | 152 | /* check whether 'efd' is still in use */ |
149 | #define CHANNEL_EFD_INPUT_ACTIVE(c) \ | 153 | #define CHANNEL_EFD_INPUT_ACTIVE(c) \ |
150 | (compat20 && c->extended_usage == CHAN_EXTENDED_READ && \ | 154 | (compat20 && c->extended_usage == CHAN_EXTENDED_READ && \ |
@@ -169,7 +173,7 @@ void channel_send_open(int); | |||
169 | void channel_request_start(int, char *, int); | 173 | void channel_request_start(int, char *, int); |
170 | void channel_register_cleanup(int, channel_callback_fn *, int); | 174 | void channel_register_cleanup(int, channel_callback_fn *, int); |
171 | void channel_register_confirm(int, channel_callback_fn *, void *); | 175 | void channel_register_confirm(int, channel_callback_fn *, void *); |
172 | void channel_register_filter(int, channel_filter_fn *); | 176 | void channel_register_filter(int, channel_infilter_fn *, channel_outfilter_fn *); |
173 | void channel_cancel_cleanup(int); | 177 | void channel_cancel_cleanup(int); |
174 | int channel_close_fd(int *); | 178 | int channel_close_fd(int *); |
175 | void channel_send_window_changes(void); | 179 | void channel_send_window_changes(void); |
diff --git a/clientloop.c b/clientloop.c index a71552cad..b76f7cfe0 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -59,7 +59,7 @@ | |||
59 | */ | 59 | */ |
60 | 60 | ||
61 | #include "includes.h" | 61 | #include "includes.h" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.148 2005/12/28 22:46:06 stevesk Exp $"); | 62 | RCSID("$OpenBSD: clientloop.c,v 1.149 2005/12/30 15:56:37 reyk Exp $"); |
63 | 63 | ||
64 | #include "ssh.h" | 64 | #include "ssh.h" |
65 | #include "ssh1.h" | 65 | #include "ssh1.h" |
@@ -1386,7 +1386,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1386 | session_ident = ssh2_chan_id; | 1386 | session_ident = ssh2_chan_id; |
1387 | if (escape_char != SSH_ESCAPECHAR_NONE) | 1387 | if (escape_char != SSH_ESCAPECHAR_NONE) |
1388 | channel_register_filter(session_ident, | 1388 | channel_register_filter(session_ident, |
1389 | simple_escape_filter); | 1389 | simple_escape_filter, NULL); |
1390 | if (session_ident != -1) | 1390 | if (session_ident != -1) |
1391 | channel_register_cleanup(session_ident, | 1391 | channel_register_cleanup(session_ident, |
1392 | client_channel_closed, 0); | 1392 | client_channel_closed, 0); |