summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--channels.c67
-rw-r--r--channels.h4
-rw-r--r--clientloop.c84
-rw-r--r--serverloop.c13
-rw-r--r--ssh.113
6 files changed, 153 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 91c9ce5e..0e8f4a55 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,6 +10,11 @@
- markus@cvs.openbsd.org 2004/05/21 08:43:03
[kex.h moduli.c tildexpand.c]
add prototypes for -Wall; ok djm
+ - djm@cvs.openbsd.org 2004/05/21 11:33:11
+ [channels.c channels.h clientloop.c serverloop.c ssh.1]
+ bz #756: add support for the cancel-tcpip-forward request for the server and
+ the client (through the ~C commandline). reported by z3p AT twistedmatrix.com;
+ ok markus@
20040523
- (djm) [sshd_config] Explain consequences of UsePAM=yes a little better in
@@ -1139,4 +1144,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.3361 2004/05/24 00:14:24 dtucker Exp $
+$Id: ChangeLog,v 1.3362 2004/05/24 00:18:05 dtucker Exp $
diff --git a/channels.c b/channels.c
index 55dc6734..2b1ce0e5 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.201 2004/05/11 19:01:43 deraadt Exp $");
+RCSID("$OpenBSD: channels.c,v 1.202 2004/05/21 11:33:11 djm Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -2228,6 +2228,26 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
return success;
}
+int
+channel_cancel_rport_listener(const char *host, u_short port)
+{
+ int i, found = 0;
+
+ for(i = 0; i < channels_alloc; i++) {
+ Channel *c = channels[i];
+
+ if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
+ strncmp(c->path, host, sizeof(c->path)) == 0 &&
+ c->listening_port == port) {
+ debug2("%s: close clannel %d", __func__, i);
+ channel_free(c);
+ found = 1;
+ }
+ }
+
+ return (found);
+}
+
/* protocol local port fwd, used by ssh (and sshd in v1) */
int
channel_setup_local_fwd_listener(u_short listen_port,
@@ -2305,6 +2325,42 @@ channel_request_remote_forwarding(u_short listen_port,
}
/*
+ * Request cancellation of remote forwarding of connection host:port from
+ * local side.
+ */
+
+void
+channel_request_rforward_cancel(u_short port)
+{
+ int i;
+ const char *address_to_bind = "0.0.0.0";
+
+ if (!compat20)
+ return;
+
+ for (i = 0; i < num_permitted_opens; i++) {
+ if (permitted_opens[i].host_to_connect != NULL &&
+ permitted_opens[i].listen_port == port)
+ break;
+ }
+ if (i >= num_permitted_opens) {
+ debug("%s: requested forward not found", __func__);
+ return;
+ }
+ packet_start(SSH2_MSG_GLOBAL_REQUEST);
+ packet_put_cstring("cancel-tcpip-forward");
+ packet_put_char(0);
+ packet_put_cstring(address_to_bind);
+ packet_put_int(port);
+ packet_send();
+
+ permitted_opens[i].listen_port = 0;
+ permitted_opens[i].port_to_connect = 0;
+ free(permitted_opens[i].host_to_connect);
+ permitted_opens[i].host_to_connect = NULL;
+}
+
+/*
* This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
* listening for the port, and sends back a success reply (or disconnect
* message if there was an error). This never returns if there was an error.
@@ -2373,7 +2429,8 @@ channel_clear_permitted_opens(void)
int i;
for (i = 0; i < num_permitted_opens; i++)
- xfree(permitted_opens[i].host_to_connect);
+ if (permitted_opens[i].host_to_connect != NULL)
+ xfree(permitted_opens[i].host_to_connect);
num_permitted_opens = 0;
}
@@ -2441,7 +2498,8 @@ channel_connect_by_listen_address(u_short listen_port)
int i;
for (i = 0; i < num_permitted_opens; i++)
- if (permitted_opens[i].listen_port == listen_port)
+ if (permitted_opens[i].host_to_connect != NULL &&
+ permitted_opens[i].listen_port == listen_port)
return connect_to(
permitted_opens[i].host_to_connect,
permitted_opens[i].port_to_connect);
@@ -2459,7 +2517,8 @@ channel_connect_to(const char *host, u_short port)
permit = all_opens_permitted;
if (!permit) {
for (i = 0; i < num_permitted_opens; i++)
- if (permitted_opens[i].port_to_connect == port &&
+ if (permitted_opens[i].host_to_connect != NULL &&
+ permitted_opens[i].port_to_connect == port &&
strcmp(permitted_opens[i].host_to_connect, host) == 0)
permit = 1;
diff --git a/channels.h b/channels.h
index 7d981479..0a49c55e 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.71 2003/09/23 20:41:11 markus Exp $ */
+/* $OpenBSD: channels.h,v 1.72 2004/05/21 11:33:11 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -200,8 +200,10 @@ void channel_input_port_forward_request(int, int);
int channel_connect_to(const char *, u_short);
int channel_connect_by_listen_address(u_short);
void channel_request_remote_forwarding(u_short, const char *, u_short);
+void channel_request_rforward_cancel(u_short port);
int channel_setup_local_fwd_listener(u_short, const char *, u_short, int);
int channel_setup_remote_fwd_listener(const char *, u_short, int);
+int channel_cancel_rport_listener(const char *, u_short);
/* x11 forwarding */
diff --git a/clientloop.c b/clientloop.c
index 9cbc1b0c..ce627e8b 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.120 2004/05/20 10:58:05 dtucker Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.121 2004/05/21 11:33:11 djm Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -506,6 +506,7 @@ process_cmdline(void)
char *s, *cmd;
u_short fwd_port, fwd_host_port;
char buf[1024], sfwd_port[6], sfwd_host_port[6];
+ int delete = 0;
int local = 0;
leave_raw_mode();
@@ -515,44 +516,77 @@ process_cmdline(void)
goto out;
while (*s && isspace(*s))
s++;
+ if (*s == '-')
+ s++; /* Skip cmdline '-', if any */
if (*s == '\0')
goto out;
- if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) {
+
+ if (*s == '?') {
+ logit("Commands:");
+ logit(" -Lport:host:hostport Request local forward");
+ logit(" -Rport:host:hostport Request remote forward");
+ logit(" -KRhostport Cancel remote forward");
+ goto out;
+ }
+
+ if (*s == 'K') {
+ delete = 1;
+ s++;
+ }
+ if (*s != 'L' && *s != 'R') {
logit("Invalid command.");
goto out;
}
- if (s[1] == 'L')
+ if (*s == 'L')
local = 1;
- if (!local && !compat20) {
+ if (local && delete) {
+ logit("Not supported.");
+ goto out;
+ }
+ if ((!local || delete) && !compat20) {
logit("Not supported for SSH protocol version 1.");
goto out;
}
- s += 2;
+
+ s++;
while (*s && isspace(*s))
s++;
- if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]",
- sfwd_port, buf, sfwd_host_port) != 3 &&
- sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]",
- sfwd_port, buf, sfwd_host_port) != 3) {
- logit("Bad forwarding specification.");
- goto out;
- }
- if ((fwd_port = a2port(sfwd_port)) == 0 ||
- (fwd_host_port = a2port(sfwd_host_port)) == 0) {
- logit("Bad forwarding port(s).");
- goto out;
- }
- if (local) {
- if (channel_setup_local_fwd_listener(fwd_port, buf,
- fwd_host_port, options.gateway_ports) < 0) {
- logit("Port forwarding failed.");
+ if (delete) {
+ if (sscanf(s, "%5[0-9]", sfwd_host_port) != 1) {
+ logit("Bad forwarding specification.");
+ goto out;
+ }
+ if ((fwd_host_port = a2port(sfwd_host_port)) == 0) {
+ logit("Bad forwarding port(s).");
+ goto out;
+ }
+ channel_request_rforward_cancel(fwd_host_port);
+ } else {
+ if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]",
+ sfwd_port, buf, sfwd_host_port) != 3 &&
+ sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]",
+ sfwd_port, buf, sfwd_host_port) != 3) {
+ logit("Bad forwarding specification.");
goto out;
}
- } else
- channel_request_remote_forwarding(fwd_port, buf,
- fwd_host_port);
- logit("Forwarding port.");
+ if ((fwd_port = a2port(sfwd_port)) == 0 ||
+ (fwd_host_port = a2port(sfwd_host_port)) == 0) {
+ logit("Bad forwarding port(s).");
+ goto out;
+ }
+ if (local) {
+ if (channel_setup_local_fwd_listener(fwd_port, buf,
+ fwd_host_port, options.gateway_ports) < 0) {
+ logit("Port forwarding failed.");
+ goto out;
+ }
+ } else
+ channel_request_remote_forwarding(fwd_port, buf,
+ fwd_host_port);
+ logit("Forwarding port.");
+ }
+
out:
signal(SIGINT, handler);
enter_raw_mode();
diff --git a/serverloop.c b/serverloop.c
index a777a048..8d2642d5 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.115 2004/01/19 21:25:15 markus Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.116 2004/05/21 11:33:11 djm Exp $");
#include "xmalloc.h"
#include "packet.h"
@@ -991,6 +991,17 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
listen_address, listen_port, options.gateway_ports);
}
xfree(listen_address);
+ } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
+ char *cancel_address;
+ u_short cancel_port;
+
+ cancel_address = packet_get_string(NULL);
+ cancel_port = (u_short)packet_get_int();
+ debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
+ cancel_address, cancel_port);
+
+ success = channel_cancel_rport_listener(cancel_address,
+ cancel_port);
}
if (want_reply) {
packet_start(success ?
diff --git a/ssh.1 b/ssh.1
index b7b12644..7da143b1 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.185 2004/05/02 11:57:52 dtucker Exp $
+.\" $OpenBSD: ssh.1,v 1.186 2004/05/21 11:33:11 djm Exp $
.Dd September 25, 1999
.Dt SSH 1
.Os
@@ -302,11 +302,18 @@ Display a list of escape characters.
Send a BREAK to the remote system
(only useful for SSH protocol version 2 and if the peer supports it).
.It Cm ~C
-Open command line (only useful for adding port forwardings using the
+Open command line.
+Currently this allows the addition of port forwardings using the
.Fl L
and
.Fl R
-options).
+options (see below).
+It also allows the cancellation of existing remote port-forwardings
+using
+.Fl KR Ar hostport .
+Basic help is available, using the
+.Fl ?
+option.
.It Cm ~R
Request rekeying of the connection
(only useful for SSH protocol version 2 and if the peer supports it).