- 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@
This commit is contained in:
Darren Tucker 2004-05-24 10:18:05 +10:00
parent e4ab1157db
commit e7066dfde3
6 changed files with 153 additions and 35 deletions

View File

@ -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 $

View File

@ -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,
@ -2304,6 +2324,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
@ -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;

View File

@ -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 */

View File

@ -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;
}
} else
channel_request_remote_forwarding(fwd_port, buf,
fwd_host_port);
logit("Forwarding port.");
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;
}
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();

View File

@ -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 ?

13
ssh.1
View File

@ -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).