From d3d0fa15588c8515751eb5a29f105b30318e9441 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 3 Oct 2005 18:03:05 +1000 Subject: - markus@cvs.openbsd.org 2005/09/07 08:53:53 [channels.c] enforce chanid != NULL; ok djm --- channels.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'channels.c') diff --git a/channels.c b/channels.c index 8c7b2b369..af858b4a5 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.223 2005/07/17 07:17:54 djm Exp $"); +RCSID("$OpenBSD: channels.c,v 1.224 2005/09/07 08:53:53 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -2668,6 +2668,9 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, char strport[NI_MAXSERV]; int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; + if (chanids == NULL) + return -1; + for (display_number = x11_display_offset; display_number < MAX_DISPLAYS; display_number++) { @@ -2749,8 +2752,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, } /* Allocate a channel for each socket. */ - if (chanids != NULL) - *chanids = xmalloc(sizeof(**chanids) * (num_socks + 1)); + *chanids = xmalloc(sizeof(**chanids) * (num_socks + 1)); for (n = 0; n < num_socks; n++) { sock = socks[n]; nc = channel_new("x11 listener", @@ -2758,11 +2760,9 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "X11 inet listener", 1); nc->single_connection = single_connection; - if (*chanids != NULL) - (*chanids)[n] = nc->self; + (*chanids)[n] = nc->self; } - if (*chanids != NULL) - (*chanids)[n] = -1; + (*chanids)[n] = -1; /* Return the display number for the DISPLAY environment variable. */ *display_numberp = display_number; -- cgit v1.2.3 From 39eda6eb6a8364e8df6779e71e0b434eaae3edd5 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 5 Nov 2005 14:52:50 +1100 Subject: - djm@cvs.openbsd.org 2005/10/10 10:23:08 [channels.c channels.h clientloop.c serverloop.c session.c] fix regression I introduced in 4.2: X11 forwardings initiated after a session has exited (e.g. "(sleep 5; xterm) &") would not start. bz #1086 reported by t8m AT centrum.cz; ok markus@ dtucker@ --- ChangeLog | 7 ++++++- channels.c | 9 ++++++--- channels.h | 7 ++++--- clientloop.c | 4 ++-- serverloop.c | 4 ++-- session.c | 37 +++++++++++++++++++++++-------------- 6 files changed, 43 insertions(+), 25 deletions(-) (limited to 'channels.c') diff --git a/ChangeLog b/ChangeLog index 10c031042..221301eb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,11 @@ in order to improve the security of DSA you need to change more components of DSA key generation (e.g. the internal SHA1 hash); ok deraadt + - djm@cvs.openbsd.org 2005/10/10 10:23:08 + [channels.c channels.h clientloop.c serverloop.c session.c] + fix regression I introduced in 4.2: X11 forwardings initiated after + a session has exited (e.g. "(sleep 5; xterm) &") would not start. + bz #1086 reported by t8m AT centrum.cz; ok markus@ dtucker@ 20051102 - (dtucker) [openbsd-compat/bsd-misc.c] Bug #1108: fix broken strdup(). @@ -3140,4 +3145,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3927 2005/11/05 03:52:18 djm Exp $ +$Id: ChangeLog,v 1.3928 2005/11/05 03:52:50 djm Exp $ diff --git a/channels.c b/channels.c index af858b4a5..b0bc77901 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.224 2005/09/07 08:53:53 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.225 2005/10/10 10:23:08 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -269,6 +269,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->force_drain = 0; c->single_connection = 0; c->detach_user = NULL; + c->detach_close = 0; c->confirm = NULL; c->confirm_ctx = NULL; c->input_filter = NULL; @@ -628,7 +629,7 @@ channel_register_confirm(int id, channel_callback_fn *fn, void *ctx) c->confirm_ctx = ctx; } void -channel_register_cleanup(int id, channel_callback_fn *fn) +channel_register_cleanup(int id, channel_callback_fn *fn, int do_close) { Channel *c = channel_lookup(id); @@ -637,6 +638,7 @@ channel_register_cleanup(int id, channel_callback_fn *fn) return; } c->detach_user = fn; + c->detach_close = do_close; } void channel_cancel_cleanup(int id) @@ -648,6 +650,7 @@ channel_cancel_cleanup(int id) return; } c->detach_user = NULL; + c->detach_close = 0; } void channel_register_filter(int id, channel_filter_fn *fn) @@ -1666,7 +1669,7 @@ channel_garbage_collect(Channel *c) if (c == NULL) return; if (c->detach_user != NULL) { - if (!chan_is_dead(c, 0)) + if (!chan_is_dead(c, c->detach_close)) return; debug2("channel %d: gc: notify user", c->self); c->detach_user(c->self, NULL); diff --git a/channels.h b/channels.h index 1cb2c3a34..7e1cc7c5a 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.79 2005/07/17 06:49:04 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.80 2005/10/10 10:23:08 djm Exp $ */ /* * Author: Tatu Ylonen @@ -106,8 +106,9 @@ struct Channel { /* callback */ channel_callback_fn *confirm; - channel_callback_fn *detach_user; void *confirm_ctx; + channel_callback_fn *detach_user; + int detach_close; /* filter */ channel_filter_fn *input_filter; @@ -163,7 +164,7 @@ void channel_stop_listening(void); void channel_send_open(int); void channel_request_start(int, char *, int); -void channel_register_cleanup(int, channel_callback_fn *); +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_cancel_cleanup(int); diff --git a/clientloop.c b/clientloop.c index da5bfd7bd..fed684956 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.142 2005/09/09 19:18:05 markus Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.143 2005/10/10 10:23:08 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -1379,7 +1379,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) simple_escape_filter); if (session_ident != -1) channel_register_cleanup(session_ident, - client_channel_closed); + client_channel_closed, 0); } else { /* Check if we should immediately send eof on stdin. */ client_check_initial_eof_on_stdin(); diff --git a/serverloop.c b/serverloop.c index d2eff170a..17608c238 100644 --- a/serverloop.c +++ b/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.118 2005/07/17 07:17:55 djm Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.119 2005/10/10 10:23:08 djm Exp $"); #include "xmalloc.h" #include "packet.h" @@ -900,7 +900,7 @@ server_request_session(void) channel_free(c); return NULL; } - channel_register_cleanup(c->self, session_close_by_channel); + channel_register_cleanup(c->self, session_close_by_channel, 0); return c; } diff --git a/session.c b/session.c index 2a1a25ac4..5e6627cb0 100644 --- a/session.c +++ b/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.186 2005/07/25 11:59:40 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.187 2005/10/10 10:23:08 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -2156,7 +2156,6 @@ static void session_exit_message(Session *s, int status) { Channel *c; - u_int i; if ((c = channel_lookup(s->chanid)) == NULL) fatal("session_exit_message: session %d: no channel %d", @@ -2186,7 +2185,15 @@ session_exit_message(Session *s, int status) /* disconnect channel */ debug("session_exit_message: release channel %d", s->chanid); - channel_cancel_cleanup(s->chanid); + s->pid = 0; + + /* + * Adjust cleanup callback attachment to send close messages when + * the channel gets EOF. The session will be then be closed + * by session_close_by_channel when the childs close their fds. + */ + channel_register_cleanup(c->self, session_close_by_channel, 1); + /* * emulate a write failure with 'chan_write_failed', nobody will be * interested in data we write. @@ -2195,15 +2202,6 @@ session_exit_message(Session *s, int status) */ if (c->ostate != CHAN_OUTPUT_CLOSED) chan_write_failed(c); - s->chanid = -1; - - /* Close any X11 listeners associated with this session */ - if (s->x11_chanids != NULL) { - for (i = 0; s->x11_chanids[i] != -1; i++) { - session_close_x11(s->x11_chanids[i]); - s->x11_chanids[i] = -1; - } - } } void @@ -2247,7 +2245,8 @@ session_close_by_pid(pid_t pid, int status) } if (s->chanid != -1) session_exit_message(s, status); - session_close(s); + if (s->ttyfd != -1) + session_pty_cleanup(s); } /* @@ -2258,6 +2257,7 @@ void session_close_by_channel(int id, void *arg) { Session *s = session_by_channel(id); + u_int i; if (s == NULL) { debug("session_close_by_channel: no session for id %d", id); @@ -2277,6 +2277,15 @@ session_close_by_channel(int id, void *arg) } /* detach by removing callback */ channel_cancel_cleanup(s->chanid); + + /* Close any X11 listeners associated with this session */ + if (s->x11_chanids != NULL) { + for (i = 0; s->x11_chanids[i] != -1; i++) { + session_close_x11(s->x11_chanids[i]); + s->x11_chanids[i] = -1; + } + } + s->chanid = -1; session_close(s); } @@ -2371,7 +2380,7 @@ session_setup_x11fwd(Session *s) } for (i = 0; s->x11_chanids[i] != -1; i++) { channel_register_cleanup(s->x11_chanids[i], - session_close_single_x11); + session_close_single_x11, 0); } /* Set up a suitable value for the DISPLAY variable. */ -- cgit v1.2.3 From 5e7fd076f517e01cbab0549cbb43245f66c1ac70 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 5 Nov 2005 14:53:39 +1100 Subject: - djm@cvs.openbsd.org 2005/10/11 23:37:37 [channels.c] bz #1076 set SO_REUSEADDR on X11 forwarding listner sockets, preventing bind() failure when a previous connection's listeners are in TIME_WAIT, reported by plattner AT inf.ethz.ch; ok dtucker@ --- ChangeLog | 7 ++++++- channels.c | 27 ++++++++++++++++++--------- 2 files changed, 24 insertions(+), 10 deletions(-) (limited to 'channels.c') diff --git a/ChangeLog b/ChangeLog index 221301eb9..f70f40f36 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,11 @@ fix regression I introduced in 4.2: X11 forwardings initiated after a session has exited (e.g. "(sleep 5; xterm) &") would not start. bz #1086 reported by t8m AT centrum.cz; ok markus@ dtucker@ + - djm@cvs.openbsd.org 2005/10/11 23:37:37 + [channels.c] + bz #1076 set SO_REUSEADDR on X11 forwarding listner sockets, preventing + bind() failure when a previous connection's listeners are in TIME_WAIT, + reported by plattner AT inf.ethz.ch; ok dtucker@ 20051102 - (dtucker) [openbsd-compat/bsd-misc.c] Bug #1108: fix broken strdup(). @@ -3145,4 +3150,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3928 2005/11/05 03:52:50 djm Exp $ +$Id: ChangeLog,v 1.3929 2005/11/05 03:53:39 djm Exp $ diff --git a/channels.c b/channels.c index b0bc77901..175b59e44 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.225 2005/10/10 10:23:08 djm Exp $"); +RCSID("$OpenBSD: channels.c,v 1.226 2005/10/11 23:37:37 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -1230,6 +1230,19 @@ port_open_helper(Channel *c, char *rtype) xfree(remote_ipaddr); } +static void +channel_set_reuseaddr(int fd) +{ + int on = 1; + + /* + * Set socket options. + * Allow local port reuse in TIME_WAIT. + */ + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) + error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno)); +} + /* * This socket is listening for connections to a forwarded TCP/IP port. */ @@ -2191,7 +2204,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por const char *host_to_connect, u_short port_to_connect, int gateway_ports) { Channel *c; - int sock, r, success = 0, on = 1, wildcard = 0, is_client; + int sock, r, success = 0, wildcard = 0, is_client; struct addrinfo hints, *ai, *aitop; const char *host, *addr; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; @@ -2278,13 +2291,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por verbose("socket: %.100s", strerror(errno)); continue; } - /* - * Set socket options. - * Allow local port reuse in TIME_WAIT. - */ - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, - sizeof(on)) == -1) - error("setsockopt SO_REUSEADDR: %s", strerror(errno)); + + channel_set_reuseaddr(sock); debug("Local forwarding listening on %s port %s.", ntop, strport); @@ -2710,6 +2718,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno)); } #endif + channel_set_reuseaddr(sock); if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { debug2("bind port %d: %.100s", port, strerror(errno)); close(sock); -- cgit v1.2.3 From 0a0176e9f3853528c4a2af999fc58ad1fb2027a3 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 5 Nov 2005 15:07:59 +1100 Subject: - stevesk@cvs.openbsd.org 2005/10/14 02:29:37 [channels.c clientloop.c] free()->xfree(); ok djm@ --- ChangeLog | 5 ++++- channels.c | 4 ++-- clientloop.c | 8 ++++---- 3 files changed, 10 insertions(+), 7 deletions(-) (limited to 'channels.c') diff --git a/ChangeLog b/ChangeLog index 82b793f89..3081c80f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,6 +36,9 @@ - stevesk@cvs.openbsd.org 2005/10/14 02:17:59 [ssh-keygen.c ssh.c sshconnect2.c] no trailing "\n" for log functions; ok djm@ + - stevesk@cvs.openbsd.org 2005/10/14 02:29:37 + [channels.c clientloop.c] + free()->xfree(); ok djm@ 20051102 - (dtucker) [openbsd-compat/bsd-misc.c] Bug #1108: fix broken strdup(). @@ -3169,4 +3172,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3935 2005/11/05 04:07:33 djm Exp $ +$Id: ChangeLog,v 1.3936 2005/11/05 04:07:59 djm Exp $ diff --git a/channels.c b/channels.c index 175b59e44..9607717cc 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.226 2005/10/11 23:37:37 djm Exp $"); +RCSID("$OpenBSD: channels.c,v 1.227 2005/10/14 02:29:37 stevesk Exp $"); #include "ssh.h" #include "ssh1.h" @@ -2464,7 +2464,7 @@ channel_request_rforward_cancel(const char *host, u_short port) permitted_opens[i].listen_port = 0; permitted_opens[i].port_to_connect = 0; - free(permitted_opens[i].host_to_connect); + xfree(permitted_opens[i].host_to_connect); permitted_opens[i].host_to_connect = NULL; } diff --git a/clientloop.c b/clientloop.c index fed684956..b267fa142 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.143 2005/10/10 10:23:08 djm Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.144 2005/10/14 02:29:37 stevesk Exp $"); #include "ssh.h" #include "ssh1.h" @@ -1880,7 +1880,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem, /* Split */ name = xstrdup(env[i]); if ((val = strchr(name, '=')) == NULL) { - free(name); + xfree(name); continue; } *val++ = '\0'; @@ -1894,7 +1894,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem, } if (!matched) { debug3("Ignored env %s", name); - free(name); + xfree(name); continue; } @@ -1903,7 +1903,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem, packet_put_cstring(name); packet_put_cstring(val); packet_send(); - free(name); + xfree(name); } } -- cgit v1.2.3 From d27b947178df3689bfb7fdfb62a5f1337ef73481 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 13 Dec 2005 19:29:02 +1100 Subject: - reyk@cvs.openbsd.org 2005/12/06 22:38:28 [auth-options.c auth-options.h channels.c channels.h clientloop.c] [misc.c misc.h readconf.c readconf.h scp.c servconf.c servconf.h] [serverloop.c sftp.c ssh.1 ssh.c ssh_config ssh_config.5 sshconnect.c] [sshconnect.h sshd.8 sshd_config sshd_config.5] Add support for tun(4) forwarding over OpenSSH, based on an idea and initial channel code bits by markus@. This is a simple and easy way to use OpenSSH for ad hoc virtual private network connections, e.g. administrative tunnels or secure wireless access. It's based on a new ssh channel and works similar to the existing TCP forwarding support, except that it depends on the tun(4) network interface on both ends of the connection for layer 2 or layer 3 tunneling. This diff also adds support for LocalCommand in the ssh(1) client. ok djm@, markus@, jmc@ (manpages), tested and discussed with others --- ChangeLog | 17 ++++++++++++++++- auth-options.c | 41 ++++++++++++++++++++++++++++++++++++++++- auth-options.h | 3 ++- channels.c | 42 ++++++++++++++++++++++++++++++++++++++++-- channels.h | 4 +++- clientloop.c | 11 ++++++++++- misc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- misc.h | 4 +++- readconf.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- readconf.h | 10 +++++++++- scp.c | 3 ++- servconf.c | 12 ++++++++++-- servconf.h | 5 ++++- serverloop.c | 34 +++++++++++++++++++++++++++++++++- sftp.c | 3 ++- ssh.1 | 20 +++++++++++++++++++- ssh.c | 39 ++++++++++++++++++++++++++++++++++++--- ssh_config | 5 ++++- ssh_config.5 | 38 +++++++++++++++++++++++++++++++++++++- sshconnect.c | 38 +++++++++++++++++++++++++++++++++++++- sshconnect.h | 4 ++-- sshd.8 | 10 +++++++++- sshd_config | 3 ++- sshd_config.5 | 8 +++++++- 24 files changed, 433 insertions(+), 31 deletions(-) (limited to 'channels.c') diff --git a/ChangeLog b/ChangeLog index d187f2aa0..96ed9a05d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,21 @@ [ssh.1] avoid ambiguities in describing TZ; ok djm@ + - reyk@cvs.openbsd.org 2005/12/06 22:38:28 + [auth-options.c auth-options.h channels.c channels.h clientloop.c] + [misc.c misc.h readconf.c readconf.h scp.c servconf.c servconf.h] + [serverloop.c sftp.c ssh.1 ssh.c ssh_config ssh_config.5 sshconnect.c] + [sshconnect.h sshd.8 sshd_config sshd_config.5] + Add support for tun(4) forwarding over OpenSSH, based on an idea and + initial channel code bits by markus@. This is a simple and easy way to + use OpenSSH for ad hoc virtual private network connections, e.g. + administrative tunnels or secure wireless access. It's based on a new + ssh channel and works similar to the existing TCP forwarding support, + except that it depends on the tun(4) network interface on both ends of + the connection for layer 2 or layer 3 tunneling. This diff also adds + support for LocalCommand in the ssh(1) client. + + ok djm@, markus@, jmc@ (manpages), tested and discussed with others 20051201 - (djm) [envpass.sh] Remove regress script that was accidentally committed @@ -3399,4 +3414,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.4018 2005/12/13 08:25:43 djm Exp $ +$Id: ChangeLog,v 1.4019 2005/12/13 08:29:02 djm Exp $ diff --git a/auth-options.c b/auth-options.c index a85e40835..54798d9ad 100644 --- a/auth-options.c +++ b/auth-options.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-options.c,v 1.31 2005/03/10 22:40:38 deraadt Exp $"); +RCSID("$OpenBSD: auth-options.c,v 1.32 2005/12/06 22:38:27 reyk Exp $"); #include "xmalloc.h" #include "match.h" @@ -35,6 +35,9 @@ char *forced_command = NULL; /* "environment=" options. */ struct envstring *custom_environment = NULL; +/* "tunnel=" option. */ +int forced_tun_device = -1; + extern ServerOptions options; void @@ -54,6 +57,7 @@ auth_clear_options(void) xfree(forced_command); forced_command = NULL; } + forced_tun_device = -1; channel_clear_permitted_opens(); auth_debug_reset(); } @@ -269,6 +273,41 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) xfree(patterns); goto next_option; } + cp = "tunnel=\""; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + char *tun = NULL; + opts += strlen(cp); + tun = xmalloc(strlen(opts) + 1); + i = 0; + while (*opts) { + if (*opts == '"') + break; + tun[i++] = *opts++; + } + if (!*opts) { + debug("%.100s, line %lu: missing end quote", + file, linenum); + auth_debug_add("%.100s, line %lu: missing end quote", + file, linenum); + xfree(tun); + forced_tun_device = -1; + goto bad_option; + } + tun[i] = 0; + forced_tun_device = a2tun(tun, NULL); + xfree(tun); + if (forced_tun_device < -1) { + debug("%.100s, line %lu: invalid tun device", + file, linenum); + auth_debug_add("%.100s, line %lu: invalid tun device", + file, linenum); + forced_tun_device = -1; + goto bad_option; + } + auth_debug_add("Forced tun device: %d", forced_tun_device); + opts++; + goto next_option; + } next_option: /* * Skip the comma, and move to the next option diff --git a/auth-options.h b/auth-options.h index 15fb21255..3cd02a71f 100644 --- a/auth-options.h +++ b/auth-options.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.h,v 1.12 2002/07/21 18:34:43 stevesk Exp $ */ +/* $OpenBSD: auth-options.h,v 1.13 2005/12/06 22:38:27 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -28,6 +28,7 @@ extern int no_x11_forwarding_flag; extern int no_pty_flag; extern char *forced_command; extern struct envstring *custom_environment; +extern int forced_tun_device; int auth_parse_options(struct passwd *, char *, char *, u_long); void auth_clear_options(void); diff --git a/channels.c b/channels.c index 9607717cc..b4fd89f96 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.227 2005/10/14 02:29:37 stevesk Exp $"); +RCSID("$OpenBSD: channels.c,v 1.228 2005/12/06 22:38:27 reyk Exp $"); #include "ssh.h" #include "ssh1.h" @@ -1414,6 +1414,8 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) debug2("channel %d: filter stops", c->self); chan_read_failed(c); } + } else if (c->datagram) { + buffer_put_string(&c->input, buf, len); } else { buffer_append(&c->input, buf, len); } @@ -1432,6 +1434,23 @@ 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->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); + xfree(data); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + if (c->type != SSH_CHANNEL_OPEN) + chan_mark_dead(c); + else + chan_write_failed(c); + return -1; + } + return 1; + } data = buffer_ptr(&c->output); dlen = buffer_len(&c->output); #ifdef _AIX @@ -1792,6 +1811,22 @@ channel_output_poll(void) if ((c->istate == CHAN_INPUT_OPEN || c->istate == CHAN_INPUT_WAIT_DRAIN) && (len = buffer_len(&c->input)) > 0) { + if (c->datagram) { + if (len > 0) { + u_char *data; + u_int dlen; + + data = buffer_get_string(&c->input, + &dlen); + packet_start(SSH2_MSG_CHANNEL_DATA); + packet_put_int(c->remote_id); + packet_put_string(data, dlen); + packet_send(); + c->remote_window -= dlen + 4; + xfree(data); + } + continue; + } /* * Send some data for the other side over the secure * connection. @@ -1914,7 +1949,10 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) c->local_window -= data_len; } packet_check_eom(); - buffer_append(&c->output, data, data_len); + if (c->datagram) + buffer_put_string(&c->output, data, data_len); + else + buffer_append(&c->output, data, data_len); xfree(data); } diff --git a/channels.h b/channels.h index 7e1cc7c5a..743a2065e 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.80 2005/10/10 10:23:08 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.81 2005/12/06 22:38:27 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -112,6 +112,8 @@ struct Channel { /* filter */ channel_filter_fn *input_filter; + + int datagram; /* keep boundaries */ }; #define CHAN_EXTENDED_IGNORE 0 diff --git a/clientloop.c b/clientloop.c index 001c8f119..a97734c3f 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.145 2005/10/30 08:52:17 djm Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.146 2005/12/06 22:38:27 reyk Exp $"); #include "ssh.h" #include "ssh1.h" @@ -914,6 +914,15 @@ process_cmdline(void) logit(" -Lport:host:hostport Request local forward"); logit(" -Rport:host:hostport Request remote forward"); logit(" -KRhostport Cancel remote forward"); + if (!options.permit_local_command) + goto out; + logit(" !args Execute local command"); + goto out; + } + + if (*s == '!' && options.permit_local_command) { + s++; + ssh_local_cmd(s); goto out; } diff --git a/misc.c b/misc.c index 27b947f0c..9b23e2c37 100644 --- a/misc.c +++ b/misc.c @@ -24,7 +24,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: misc.c,v 1.35 2005/09/13 23:40:07 djm Exp $"); +RCSID("$OpenBSD: misc.c,v 1.36 2005/12/06 22:38:27 reyk Exp $"); #include "misc.h" #include "log.h" @@ -194,6 +194,37 @@ a2port(const char *s) return port; } +int +a2tun(const char *s, int *remote) +{ + const char *errstr = NULL; + char *sp, *ep; + int tun; + + if (remote != NULL) { + *remote = -1; + sp = xstrdup(s); + if ((ep = strchr(sp, ':')) == NULL) { + xfree(sp); + return (a2tun(s, NULL)); + } + ep[0] = '\0'; ep++; + *remote = a2tun(ep, NULL); + tun = a2tun(sp, NULL); + xfree(sp); + return (tun); + } + + if (strcasecmp(s, "any") == 0) + return (-1); + + tun = strtonum(s, 0, INT_MAX, &errstr); + if (errstr != NULL || tun < -1) + return (-2); + + return (tun); +} + #define SECONDS 1 #define MINUTES (SECONDS * 60) #define HOURS (MINUTES * 60) @@ -507,6 +538,31 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz, return -1; } +int +tun_open(int tun) +{ + char name[100]; + int i, fd; + + if (tun > -1) { + snprintf(name, sizeof(name), "/dev/tun%d", tun); + if ((fd = open(name, O_RDWR)) >= 0) { + debug("%s: %s: %d", __func__, name, fd); + return (fd); + } + } else { + for (i = 100; i >= 0; i--) { + snprintf(name, sizeof(name), "/dev/tun%d", i); + if ((fd = open(name, O_RDWR)) >= 0) { + debug("%s: %s: %d", __func__, name, fd); + return (fd); + } + } + } + debug("%s: %s failed: %s", __func__, name, strerror(errno)); + return (-1); +} + void sanitise_stdfd(void) { diff --git a/misc.h b/misc.h index 51541336c..ff2ba1b5a 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.26 2005/09/13 23:40:07 djm Exp $ */ +/* $OpenBSD: misc.h,v 1.27 2005/12/06 22:38:27 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -20,6 +20,7 @@ int set_nonblock(int); int unset_nonblock(int); void set_nodelay(int); int a2port(const char *); +int a2tun(const char *, int *); char *hpdelim(char **); char *cleanhostname(char *); char *colon(char *); @@ -49,3 +50,4 @@ void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3))); char *read_passphrase(const char *, int); int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); +int tun_open(int); diff --git a/readconf.c b/readconf.c index cf27a9f41..b6aad9d8d 100644 --- a/readconf.c +++ b/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.143 2005/07/30 02:03:47 djm Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.144 2005/12/06 22:38:27 reyk Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -70,6 +70,10 @@ RCSID("$OpenBSD: readconf.c,v 1.143 2005/07/30 02:03:47 djm Exp $"); Cipher none PasswordAuthentication no + Host vpn.fake.com + Tunnel yes + TunnelDevice 3 + # Defaults for various options Host * ForwardAgent no @@ -107,6 +111,7 @@ typedef enum { oAddressFamily, oGssAuthentication, oGssDelegateCreds, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, + oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oDeprecated, oUnsupported } OpCodes; @@ -198,6 +203,10 @@ static struct { { "controlpath", oControlPath }, { "controlmaster", oControlMaster }, { "hashknownhosts", oHashKnownHosts }, + { "tunnel", oTunnel }, + { "tunneldevice", oTunnelDevice }, + { "localcommand", oLocalCommand }, + { "permitlocalcommand", oPermitLocalCommand }, { NULL, oBadOption } }; @@ -264,6 +273,7 @@ clear_forwardings(Options *options) xfree(options->remote_forwards[i].connect_host); } options->num_remote_forwards = 0; + options->tun_open = 0; } /* @@ -296,7 +306,7 @@ process_config_line(Options *options, const char *host, int *activep) { char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; - int opcode, *intptr, value; + int opcode, *intptr, value, value2; size_t len; Forward fwd; @@ -553,9 +563,10 @@ parse_string: goto parse_string; case oProxyCommand: + charptr = &options->proxy_command; +parse_command: if (s == NULL) fatal("%.200s line %d: Missing argument.", filename, linenum); - charptr = &options->proxy_command; len = strspn(s, WHITESPACE "="); if (*activep && *charptr == NULL) *charptr = xstrdup(s + len); @@ -822,6 +833,31 @@ parse_int: intptr = &options->hash_known_hosts; goto parse_flag; + case oTunnel: + intptr = &options->tun_open; + goto parse_flag; + + case oTunnelDevice: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + value = a2tun(arg, &value2); + if (value < -1) + fatal("%.200s line %d: Bad tun device.", filename, linenum); + if (*activep) { + options->tun_local = value; + options->tun_remote = value2; + } + break; + + case oLocalCommand: + charptr = &options->local_command; + goto parse_command; + + case oPermitLocalCommand: + intptr = &options->permit_local_command; + goto parse_flag; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -966,6 +1002,11 @@ initialize_options(Options * options) options->control_path = NULL; options->control_master = -1; options->hash_known_hosts = -1; + options->tun_open = -1; + options->tun_local = -1; + options->tun_remote = -1; + options->local_command = NULL; + options->permit_local_command = -1; } /* @@ -1090,6 +1131,11 @@ fill_default_options(Options * options) options->control_master = 0; if (options->hash_known_hosts == -1) options->hash_known_hosts = 0; + if (options->tun_open == -1) + options->tun_open = 0; + if (options->permit_local_command == -1) + options->permit_local_command = 0; + /* options->local_command should not be set by default */ /* options->proxy_command should not be set by default */ /* options->user will be set in the main program if appropriate */ /* options->hostname will be set in the main program if appropriate */ diff --git a/readconf.h b/readconf.h index 2b9deb9db..4565b2c2c 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.67 2005/06/08 11:25:09 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.68 2005/12/06 22:38:27 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -114,6 +114,14 @@ typedef struct { int control_master; int hash_known_hosts; + + int tun_open; /* tun(4) */ + int tun_local; /* force tun device (optional) */ + int tun_remote; /* force tun device (optional) */ + + char *local_command; + int permit_local_command; + } Options; #define SSHCTL_MASTER_NO 0 diff --git a/scp.c b/scp.c index a19021f85..5dced6ce4 100644 --- a/scp.c +++ b/scp.c @@ -71,7 +71,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.127 2005/11/12 18:38:15 deraadt Exp $"); +RCSID("$OpenBSD: scp.c,v 1.128 2005/12/06 22:38:27 reyk Exp $"); #include "xmalloc.h" #include "atomicio.h" @@ -231,6 +231,7 @@ main(int argc, char **argv) addargs(&args, "ssh"); /* overwritten with ssh_program */ addargs(&args, "-x"); addargs(&args, "-oForwardAgent no"); + addargs(&args, "-oPermitLocalCommand no"); addargs(&args, "-oClearAllForwardings yes"); fflag = tflag = 0; diff --git a/servconf.c b/servconf.c index 9e420a527..91a0ced29 100644 --- a/servconf.c +++ b/servconf.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.144 2005/08/06 10:03:12 dtucker Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.145 2005/12/06 22:38:27 reyk Exp $"); #include "ssh.h" #include "log.h" @@ -101,6 +101,7 @@ initialize_server_options(ServerOptions *options) options->authorized_keys_file = NULL; options->authorized_keys_file2 = NULL; options->num_accept_env = 0; + options->permit_tun = -1; /* Needs to be accessable in many places */ use_privsep = -1; @@ -229,6 +230,8 @@ fill_default_server_options(ServerOptions *options) } if (options->authorized_keys_file == NULL) options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; + if (options->permit_tun == -1) + options->permit_tun = 0; /* Turn privilege separation on by default */ if (use_privsep == -1) @@ -270,7 +273,7 @@ typedef enum { sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, - sGssAuthentication, sGssCleanupCreds, sAcceptEnv, + sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sUsePrivilegeSeparation, sDeprecated, sUnsupported } ServerOpCodes; @@ -373,6 +376,7 @@ static struct { { "authorizedkeysfile2", sAuthorizedKeysFile2 }, { "useprivilegeseparation", sUsePrivilegeSeparation}, { "acceptenv", sAcceptEnv }, + { "permittunnel", sPermitTunnel }, { NULL, sBadOption } }; @@ -962,6 +966,10 @@ parse_flag: } break; + case sPermitTunnel: + intptr = &options->permit_tun; + goto parse_flag; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); diff --git a/servconf.h b/servconf.h index f7e56d521..ab82c8f57 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.71 2004/12/23 23:11:00 djm Exp $ */ +/* $OpenBSD: servconf.h,v 1.72 2005/12/06 22:38:27 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -133,7 +133,10 @@ typedef struct { char *authorized_keys_file; /* File containing public keys */ char *authorized_keys_file2; + int use_pam; /* Enable auth via PAM */ + + int permit_tun; } ServerOptions; void initialize_server_options(ServerOptions *); diff --git a/serverloop.c b/serverloop.c index 03376bacf..199f7696d 100644 --- a/serverloop.c +++ b/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.121 2005/10/31 11:48:29 djm Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.122 2005/12/06 22:38:27 reyk Exp $"); #include "xmalloc.h" #include "packet.h" @@ -913,6 +913,36 @@ server_request_direct_tcpip(void) return c; } +static Channel * +server_request_tun(void) +{ + Channel *c = NULL; + int sock, tun; + + if (!options.permit_tun) { + packet_send_debug("Server has disabled tunnel device forwarding."); + return NULL; + } + + tun = packet_get_int(); + if (forced_tun_device != -1) { + if (tun != -1 && forced_tun_device != tun) + goto done; + tun = forced_tun_device; + } + sock = tun_open(tun); + if (sock < 0) + goto done; + c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); + c->datagram = 1; + + done: + if (c == NULL) + packet_send_debug("Failed to open the tunnel device."); + return c; +} + static Channel * server_request_session(void) { @@ -958,6 +988,8 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt) c = server_request_session(); } else if (strcmp(ctype, "direct-tcpip") == 0) { c = server_request_direct_tcpip(); + } else if (strcmp(ctype, "tun@openssh.com") == 0) { + c = server_request_tun(); } if (c != NULL) { debug("server_input_channel_open: confirm %s", ctype); diff --git a/sftp.c b/sftp.c index ff3223ad2..24f6dc538 100644 --- a/sftp.c +++ b/sftp.c @@ -16,7 +16,7 @@ #include "includes.h" -RCSID("$OpenBSD: sftp.c,v 1.68 2005/10/31 06:15:04 dtucker Exp $"); +RCSID("$OpenBSD: sftp.c,v 1.69 2005/12/06 22:38:27 reyk Exp $"); #ifdef USE_LIBEDIT #include @@ -1457,6 +1457,7 @@ main(int argc, char **argv) addargs(&args, "ssh"); /* overwritten with ssh_program */ addargs(&args, "-oForwardX11 no"); addargs(&args, "-oForwardAgent no"); + addargs(&args, "-oPermitLocalCommand no"); addargs(&args, "-oClearAllForwardings yes"); ll = SYSLOG_LEVEL_INFO; diff --git a/ssh.1 b/ssh.1 index dd97a8995..8a55c2f64 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.214 2005/11/30 11:45:20 jmc Exp $ +.\" $OpenBSD: ssh.1,v 1.215 2005/12/06 22:38:27 reyk Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -77,6 +77,7 @@ .Sm on .Oc .Op Fl S Ar ctl_path +.Op Fl w Ar tunnel : tunnel .Oo Ar user Ns @ Oc Ns Ar hostname .Op Ar command .Sh DESCRIPTION @@ -301,6 +302,12 @@ options (see below). It also allows the cancellation of existing remote port-forwardings using .Fl KR Ar hostport . +The +.Ic ! Ar command +allows the user to execute a local command if the +.Ic PermitLocalCommand +option is enabled in +.Xr ssh_config 5 . Basic help is available, using the .Fl h option. @@ -747,12 +754,14 @@ For full details of the options listed below, and their possible values, see .It IdentityFile .It IdentitiesOnly .It KbdInteractiveDevices +.It LocalCommand .It LocalForward .It LogLevel .It MACs .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts .It PasswordAuthentication +.It PermitLocalCommand .It Port .It PreferredAuthentications .It Protocol @@ -767,6 +776,8 @@ For full details of the options listed below, and their possible values, see .It SmartcardDevice .It StrictHostKeyChecking .It TCPKeepAlive +.It Tunnel +.It TunnelDevice .It UsePrivilegedPort .It User .It UserKnownHostsFile @@ -866,6 +877,13 @@ Multiple .Fl v options increase the verbosity. The maximum is 3. +.It Fl w +Requests a +.Xr tun 4 +device on the client and server like the +.Cm Tunnel +directive in +.Xr ssh_config 5 . .It Fl X Enables X11 forwarding. This can also be specified on a per-host basis in a configuration file. diff --git a/ssh.c b/ssh.c index 2227755cd..8a4a0e4c9 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.254 2005/10/30 08:52:18 djm Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.255 2005/12/06 22:38:27 reyk Exp $"); #include #include @@ -162,7 +162,7 @@ usage(void) " [-i identity_file] [-L [bind_address:]port:host:hostport]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" -" [user@]hostname [command]\n" +" [-w tunnel:tunnel] [user@]hostname [command]\n" ); exit(1); } @@ -244,7 +244,7 @@ main(int ac, char **av) again: while ((opt = getopt(ac, av, - "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVXY")) != -1) { + "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -340,6 +340,14 @@ again: if (opt == 'V') exit(0); break; + case 'w': + options.tun_open = 1; + options.tun_local = a2tun(optarg, &options.tun_remote); + if (options.tun_local < -1) { + fprintf(stderr, "Bad tun device '%s'\n", optarg); + exit(1); + } + break; case 'q': options.log_level = SYSLOG_LEVEL_QUIET; break; @@ -1059,6 +1067,26 @@ ssh_session2_setup(int id, void *arg) packet_send(); } + if (options.tun_open) { + Channel *c; + int fd; + + debug("Requesting tun."); + if ((fd = tun_open(options.tun_local)) >= 0) { + c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + 0, "tun", 1); + c->datagram = 1; + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring("tun@openssh.com"); + packet_put_int(c->self); + packet_put_int(c->local_window_max); + packet_put_int(c->local_maxpacket); + packet_put_int(options.tun_remote); + packet_send(); + } + } + client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply); @@ -1123,6 +1151,11 @@ ssh_session2(void) if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) id = ssh_session2_open(); + /* Execute a local command */ + if (options.local_command != NULL && + options.permit_local_command) + ssh_local_cmd(options.local_command); + /* If requested, let ssh continue in the background. */ if (fork_after_authentication_flag) if (daemon(1, 1) < 0) diff --git a/ssh_config b/ssh_config index f41bee0a2..7bc8762d6 100644 --- a/ssh_config +++ b/ssh_config @@ -1,4 +1,4 @@ -# $OpenBSD: ssh_config,v 1.20 2005/01/28 09:45:53 dtucker Exp $ +# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $ # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for @@ -37,3 +37,6 @@ # Cipher 3des # Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc # EscapeChar ~ +# Tunnel no +# TunnelDevice any:any +# PermitLocalCommand no diff --git a/ssh_config.5 b/ssh_config.5 index 13cdee88b..d1930baab 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.64 2005/10/30 08:43:47 jmc Exp $ +.\" $OpenBSD: ssh_config.5,v 1.65 2005/12/06 22:38:27 reyk Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -556,6 +556,14 @@ The default is Specifies the list of methods to use in keyboard-interactive authentication. Multiple method names must be comma-separated. The default is to use the server specified list. +.It Cm LocalCommand +Specifies a command to execute on the local machine after successfully +connecting to the server. +The command string extends to the end of the line, and is executed with +.Pa /bin/sh . +This directive is ignored unless +.Cm PermitLocalCommand +has been enabled. .It Cm LocalForward Specifies that a TCP/IP port on the local machine be forwarded over the secure channel to the specified host and port from the remote machine. @@ -628,6 +636,19 @@ The default is .It Cm Port Specifies the port number to connect on the remote host. Default is 22. +.It Cm PermitLocalCommand +Allow local command execution via the +.Ic LocalCommand +option or using the +.Ic ! Ar command +escape sequence in +.Xr ssh 1 . +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . .It Cm PreferredAuthentications Specifies the order in which the client should try protocol 2 authentication methods. @@ -887,6 +908,21 @@ Note that this option must be set to for .Cm RhostsRSAAuthentication with older servers. +.It Cm Tunnel +Request starting +.Xr tun 4 +device forwarding between the client and the server. +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +.It Cm TunnelDevice +Force a specified +.Xr tun 4 +device on the client. +Without this option, the next available device will be used. .It Cm User Specifies the user to log in as. This can be useful when a different user name is used on different machines. diff --git a/sshconnect.c b/sshconnect.c index 2245a8af6..64ffec240 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.170 2005/10/30 08:52:18 djm Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.171 2005/12/06 22:38:27 reyk Exp $"); #include @@ -1034,3 +1034,39 @@ warn_changed_key(Key *host_key) xfree(fp); } + +/* + * Execute a local command + */ +int +ssh_local_cmd(const char *args) +{ + char *shell; + pid_t pid; + int status; + + if (!options.permit_local_command || + args == NULL || !*args) + return (1); + + if ((shell = getenv("SHELL")) == NULL) + shell = _PATH_BSHELL; + + pid = fork(); + if (pid == 0) { + debug3("Executing %s -c \"%s\"", shell, args); + execl(shell, shell, "-c", args, (char *)NULL); + error("Couldn't execute %s -c \"%s\": %s", + shell, args, strerror(errno)); + _exit(1); + } else if (pid == -1) + fatal("fork failed: %.100s", strerror(errno)); + while (waitpid(pid, &status, 0) == -1) + if (errno != EINTR) + fatal("Couldn't wait for child: %s", strerror(errno)); + + if (!WIFEXITED(status)) + return (1); + + return (WEXITSTATUS(status)); +} diff --git a/sshconnect.h b/sshconnect.h index 0be30fe69..e7c7a2b34 100644 --- a/sshconnect.h +++ b/sshconnect.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.h,v 1.17 2002/06/19 00:27:55 deraadt Exp $ */ +/* $OpenBSD: sshconnect.h,v 1.18 2005/12/06 22:38:28 reyk Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -49,7 +49,7 @@ void ssh_userauth1(const char *, const char *, char *, Sensitive *); void ssh_userauth2(const char *, const char *, char *, Sensitive *); void ssh_put_password(char *); - +int ssh_local_cmd(const char *); /* * Macros to raise/lower permissions. diff --git a/sshd.8 b/sshd.8 index c610f47b8..53eddcdfb 100644 --- a/sshd.8 +++ b/sshd.8 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.208 2005/06/08 03:50:00 djm Exp $ +.\" $OpenBSD: sshd.8,v 1.209 2005/12/06 22:38:28 reyk Exp $ .Dd September 25, 1999 .Dt SSHD 8 .Os @@ -518,6 +518,12 @@ Multiple options may be applied separated by commas. No pattern matching is performed on the specified hostnames, they must be literal domains or addresses. +.It Cm tunnel="n" +Force a +.Xr tun 4 +device on the server. +Without this option, the next available device will be used if +the client requests a tunnel. .El .Ss Examples 1024 33 12121...312314325 ylo@foo.bar @@ -527,6 +533,8 @@ from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backup.hut.fi .Pp permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23...2323 +.Pp +tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...== reyk@openbsd.org .Sh SSH_KNOWN_HOSTS FILE FORMAT The .Pa /etc/ssh/ssh_known_hosts diff --git a/sshd_config b/sshd_config index 1440c05ff..4957dd1a6 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.72 2005/07/25 11:59:40 markus Exp $ +# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -96,6 +96,7 @@ #UseDNS yes #PidFile /var/run/sshd.pid #MaxStartups 10 +#PermitTunnel no # no default banner path #Banner /some/path diff --git a/sshd_config.5 b/sshd_config.5 index 45c1c0131..3835fcd62 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.45 2005/09/21 23:36:54 djm Exp $ +.\" $OpenBSD: sshd_config.5,v 1.46 2005/12/06 22:38:28 reyk Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -502,6 +502,12 @@ All other authentication methods are disabled for root. If this option is set to .Dq no root is not allowed to log in. +.It Cm PermitTunnel +Specifies whether +.Xr tun 4 +device forwarding is allowed. +The default is +.Dq no . .It Cm PermitUserEnvironment Specifies whether .Pa ~/.ssh/environment -- cgit v1.2.3 From d47c62a714c2c3e6a564aa498e3ef0445c9f9ea3 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 13 Dec 2005 19:33:57 +1100 Subject: - markus@cvs.openbsd.org 2005/12/12 13:46:18 [channels.c channels.h session.c] make sure protocol messages for internal channels are ignored. allow adjust messages for non-open channels; with and ok djm@ --- ChangeLog | 6 +++++- channels.c | 45 ++++++++++++++++++++++++++++++++++++--------- channels.h | 3 ++- session.c | 4 ++-- 4 files changed, 45 insertions(+), 13 deletions(-) (limited to 'channels.c') diff --git a/ChangeLog b/ChangeLog index b16ff26ef..00791e326 100644 --- a/ChangeLog +++ b/ChangeLog @@ -51,6 +51,10 @@ - jmc@cvs.openbsd.org 2005/12/08 21:37:50 [ssh_config.5] new sentence, new line; + - markus@cvs.openbsd.org 2005/12/12 13:46:18 + [channels.c channels.h session.c] + make sure protocol messages for internal channels are ignored. + allow adjust messages for non-open channels; with and ok djm@ 20051201 - (djm) [envpass.sh] Remove regress script that was accidentally committed @@ -3443,4 +3447,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.4025 2005/12/13 08:33:37 djm Exp $ +$Id: ChangeLog,v 1.4026 2005/12/13 08:33:57 djm Exp $ diff --git a/channels.c b/channels.c index b4fd89f96..e73dc247d 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.228 2005/12/06 22:38:27 reyk Exp $"); +RCSID("$OpenBSD: channels.c,v 1.229 2005/12/12 13:46:18 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -142,22 +142,50 @@ static void port_open_helper(Channel *c, char *rtype); /* -- channel core */ Channel * -channel_lookup(int id) +channel_by_id(int id) { Channel *c; if (id < 0 || (u_int)id >= channels_alloc) { - logit("channel_lookup: %d: bad id", id); + logit("channel_by_id: %d: bad id", id); return NULL; } c = channels[id]; if (c == NULL) { - logit("channel_lookup: %d: bad id: channel free", id); + logit("channel_by_id: %d: bad id: channel free", id); return NULL; } return c; } +/* + * Returns the channel if it is allowed to receive protocol messages. + * Private channels, like listening sockets, may not receive messages. + */ +Channel * +channel_lookup(int id) +{ + Channel *c; + + if ((c = channel_by_id(id)) == NULL) + return (NULL); + + switch(c->type) { + case SSH_CHANNEL_X11_OPEN: + case SSH_CHANNEL_LARVAL: + case SSH_CHANNEL_CONNECTING: + case SSH_CHANNEL_DYNAMIC: + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + return (c); + break; + } + logit("Non-public channel %d, type %d.", id, c->type); + return (NULL); +} + /* * Register filedescriptors for a channel, used when allocating a channel or * when the channel consumer/producer is ready, e.g. shell exec'd @@ -631,7 +659,7 @@ channel_register_confirm(int id, channel_callback_fn *fn, void *ctx) void channel_register_cleanup(int id, channel_callback_fn *fn, int do_close) { - Channel *c = channel_lookup(id); + Channel *c = channel_by_id(id); if (c == NULL) { logit("channel_register_cleanup: %d: bad id", id); @@ -643,7 +671,7 @@ channel_register_cleanup(int id, channel_callback_fn *fn, int do_close) void channel_cancel_cleanup(int id) { - Channel *c = channel_lookup(id); + Channel *c = channel_by_id(id); if (c == NULL) { logit("channel_cancel_cleanup: %d: bad id", id); @@ -2183,9 +2211,8 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) id = packet_get_int(); c = channel_lookup(id); - if (c == NULL || c->type != SSH_CHANNEL_OPEN) { - logit("Received window adjust for " - "non-open channel %d.", id); + if (c == NULL) { + logit("Received window adjust for non-open channel %d.", id); return; } adjust = packet_get_int(); diff --git a/channels.h b/channels.h index 743a2065e..7990fe147 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.81 2005/12/06 22:38:27 reyk Exp $ */ +/* $OpenBSD: channels.h,v 1.82 2005/12/12 13:46:18 markus Exp $ */ /* * Author: Tatu Ylonen @@ -157,6 +157,7 @@ struct Channel { /* channel management */ +Channel *channel_by_id(int); Channel *channel_lookup(int); Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int); void channel_set_fds(int, int, int, int, int, int, u_int); diff --git a/session.c b/session.c index 7863aa15f..8d186dd7d 100644 --- a/session.c +++ b/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.188 2005/10/30 08:52:17 djm Exp $"); +RCSID("$OpenBSD: session.c,v 1.189 2005/12/12 13:46:18 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -2101,7 +2101,7 @@ session_close_x11(int id) { Channel *c; - if ((c = channel_lookup(id)) == NULL) { + if ((c = channel_by_id(id)) == NULL) { debug("session_close_x11: x11 channel %d missing", id); } else { /* Detach X11 listener */ -- cgit v1.2.3 From 5eb137c6d11be7db14dc03ea12a74884bebea3e3 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 31 Dec 2005 16:19:53 +1100 Subject: - (djm) OpenBSD CVS Sync - 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@ --- ChangeLog | 8 +++++++- canohost.c | 6 +++--- channels.c | 4 ++-- clientloop.c | 6 +++--- 4 files changed, 15 insertions(+), 9 deletions(-) (limited to 'channels.c') diff --git a/ChangeLog b/ChangeLog index f86d4090c..451f1b323 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20051229 + - (djm) OpenBSD CVS Sync + - 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@ + 20051229 - (tim) [buildpkg.sh.in] grep for $SSHDUID instead of $SSHDGID on /etc/passwd @@ -3552,4 +3558,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.4052 2005/12/28 22:28:08 tim Exp $ +$Id: ChangeLog,v 1.4053 2005/12/31 05:19:53 djm Exp $ diff --git a/canohost.c b/canohost.c index bd7f830de..6ca60e6b4 100644 --- a/canohost.c +++ b/canohost.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: canohost.c,v 1.47 2005/11/03 13:38:29 dtucker Exp $"); +RCSID("$OpenBSD: canohost.c,v 1.48 2005/12/28 22:46:06 stevesk Exp $"); #include "packet.h" #include "xmalloc.h" @@ -102,7 +102,7 @@ get_remote_hostname(int sock, int use_dns) hints.ai_socktype = SOCK_STREAM; if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { logit("reverse mapping checking getaddrinfo for %.700s " - "failed - POSSIBLE BREAKIN ATTEMPT!", name); + "failed - POSSIBLE BREAK-IN ATTEMPT!", name); return xstrdup(ntop); } /* Look for the address from the list of addresses. */ @@ -117,7 +117,7 @@ get_remote_hostname(int sock, int use_dns) if (!ai) { /* Address not found for the host name. */ logit("Address %.100s maps to %.600s, but this does not " - "map back to the address - POSSIBLE BREAKIN ATTEMPT!", + "map back to the address - POSSIBLE BREAK-IN ATTEMPT!", ntop, name); return xstrdup(ntop); } diff --git a/channels.c b/channels.c index e73dc247d..b431532a3 100644 --- a/channels.c +++ b/channels.c @@ -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.230 2005/12/28 22:46:06 stevesk Exp $"); #include "ssh.h" #include "ssh1.h" @@ -3025,7 +3025,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(); diff --git a/clientloop.c b/clientloop.c index 04f2d11be..a71552cad 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.147 2005/12/07 03:52:22 djm Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.148 2005/12/28 22:46:06 stevesk Exp $"); #include "ssh.h" #include "ssh1.h" @@ -1688,7 +1688,7 @@ client_request_x11(const char *request_type, int rchan) if (!options.forward_x11) { error("Warning: ssh server tried X11 forwarding."); - 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."); return NULL; } originator = packet_get_string(NULL); @@ -1721,7 +1721,7 @@ client_request_agent(const char *request_type, int rchan) if (!options.forward_agent) { error("Warning: ssh server tried agent forwarding."); - 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."); return NULL; } sock = ssh_get_authentication_socket(); -- cgit v1.2.3 From 077b23864f567551dc7147db8ccd69559617976e Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 31 Dec 2005 16:22:32 +1100 Subject: - 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@ --- ChangeLog | 6 +++++- channels.c | 35 ++++++++++++++++++++++++----------- channels.h | 12 ++++++++---- clientloop.c | 4 ++-- 4 files changed, 39 insertions(+), 18 deletions(-) (limited to 'channels.c') diff --git a/ChangeLog b/ChangeLog index 451f1b323..3c522ea36 100644 --- 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 @@ -3558,4 +3562,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.4053 2005/12/31 05:19:53 djm Exp $ +$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 @@ */ #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(); diff --git a/channels.h b/channels.h index 7990fe147..a97dd9007 100644 --- a/channels.h +++ b/channels.h @@ -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 @@ -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); diff --git a/clientloop.c b/clientloop.c index a71552cad..b76f7cfe0 100644 --- a/clientloop.c +++ b/clientloop.c @@ -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); -- cgit v1.2.3 From a969437645550a8f7595ba017c7658c4341d77d1 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 4 Jan 2006 07:27:50 +1100 Subject: - (djm) [channels.c] clean up harmless merge error, from reyk@ --- ChangeLog | 5 ++++- channels.c | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'channels.c') diff --git a/ChangeLog b/ChangeLog index 60ea75fd4..f5e287dc4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +20060103 + - (djm) [channels.c] clean up harmless merge error, from reyk@ + 20060103 - (djm) OpenBSD CVS Sync - jmc@cvs.openbsd.org 2006/01/02 17:09:49 @@ -3628,4 +3631,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.4072 2006/01/03 07:47:31 djm Exp $ +$Id: ChangeLog,v 1.4073 2006/01/03 20:27:50 djm Exp $ diff --git a/channels.c b/channels.c index ed5903f6f..5fa80fbad 100644 --- a/channels.c +++ b/channels.c @@ -1491,8 +1491,6 @@ 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) -- cgit v1.2.3 From e204f6aa0dc399dfb709f3def13b9c4f8ab35357 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 31 Jan 2006 21:47:15 +1100 Subject: - reyk@cvs.openbsd.org 2006/01/30 12:22:22 [channels.c] mark channel as write failed or dead instead of read failed on error of the channel output filter. ok markus@ --- ChangeLog | 7 ++++++- channels.c | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'channels.c') diff --git a/ChangeLog b/ChangeLog index f38e515fd..879ac1065 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,11 @@ written with a lot of help from jakob; feedback dtucker/markus; ok markus + - reyk@cvs.openbsd.org 2006/01/30 12:22:22 + [channels.c] + mark channel as write failed or dead instead of read failed on error + of the channel output filter. + ok markus@ 20060129 - (dtucker) [configure.ac opensshd.init.in] Bug #1144: Use /bin/sh for the @@ -3743,4 +3748,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.4098 2006/01/31 10:46:51 djm Exp $ +$Id: ChangeLog,v 1.4099 2006/01/31 10:47:15 djm Exp $ diff --git a/channels.c b/channels.c index 5fa80fbad..1252f3446 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.231 2005/12/30 15:56:36 reyk Exp $"); +RCSID("$OpenBSD: channels.c,v 1.232 2006/01/30 12:22:22 reyk Exp $"); #include "ssh.h" #include "ssh1.h" @@ -1466,7 +1466,11 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) 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); + 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); -- cgit v1.2.3