mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-25 23:05:21 +02:00
- djm@cvs.openbsd.org 2011/09/09 22:46:44
[channels.c channels.h clientloop.h mux.c ssh.c] support for cancelling local and remote port forwards via the multiplex socket. Use ssh -O cancel -L xx:xx:xx -R yy:yy:yy user@host" to request the cancellation of the specified forwardings; ok markus@
This commit is contained in:
parent
9ee2c606c1
commit
f6dff7cd2f
@ -51,6 +51,11 @@
|
|||||||
[sshd.c]
|
[sshd.c]
|
||||||
kill the preauth privsep child on fatal errors in the monitor;
|
kill the preauth privsep child on fatal errors in the monitor;
|
||||||
ok markus@
|
ok markus@
|
||||||
|
- djm@cvs.openbsd.org 2011/09/09 22:46:44
|
||||||
|
[channels.c channels.h clientloop.h mux.c ssh.c]
|
||||||
|
support for cancelling local and remote port forwards via the multiplex
|
||||||
|
socket. Use ssh -O cancel -L xx:xx:xx -R yy:yy:yy user@host" to request
|
||||||
|
the cancellation of the specified forwardings; ok markus@
|
||||||
|
|
||||||
20110909
|
20110909
|
||||||
- (dtucker) [entropy.h] Bug #1932: remove old definition of init_rng. From
|
- (dtucker) [entropy.h] Bug #1932: remove old definition of init_rng. From
|
||||||
|
164
channels.c
164
channels.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: channels.c,v 1.311 2011/06/22 22:08:42 djm Exp $ */
|
/* $OpenBSD: channels.c,v 1.312 2011/09/09 22:46:44 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -302,6 +302,8 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
|
|||||||
buffer_init(&c->output);
|
buffer_init(&c->output);
|
||||||
buffer_init(&c->extended);
|
buffer_init(&c->extended);
|
||||||
c->path = NULL;
|
c->path = NULL;
|
||||||
|
c->listening_addr = NULL;
|
||||||
|
c->listening_port = 0;
|
||||||
c->ostate = CHAN_OUTPUT_OPEN;
|
c->ostate = CHAN_OUTPUT_OPEN;
|
||||||
c->istate = CHAN_INPUT_OPEN;
|
c->istate = CHAN_INPUT_OPEN;
|
||||||
c->flags = 0;
|
c->flags = 0;
|
||||||
@ -411,6 +413,10 @@ channel_free(Channel *c)
|
|||||||
xfree(c->path);
|
xfree(c->path);
|
||||||
c->path = NULL;
|
c->path = NULL;
|
||||||
}
|
}
|
||||||
|
if (c->listening_addr) {
|
||||||
|
xfree(c->listening_addr);
|
||||||
|
c->listening_addr = NULL;
|
||||||
|
}
|
||||||
while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) {
|
while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) {
|
||||||
if (cc->abandon_cb != NULL)
|
if (cc->abandon_cb != NULL)
|
||||||
cc->abandon_cb(c, cc->ctx);
|
cc->abandon_cb(c, cc->ctx);
|
||||||
@ -2634,6 +2640,46 @@ channel_set_af(int af)
|
|||||||
IPv4or6 = af;
|
IPv4or6 = af;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine whether or not a port forward listens to loopback, the
|
||||||
|
* specified address or wildcard. On the client, a specified bind
|
||||||
|
* address will always override gateway_ports. On the server, a
|
||||||
|
* gateway_ports of 1 (``yes'') will override the client's specification
|
||||||
|
* and force a wildcard bind, whereas a value of 2 (``clientspecified'')
|
||||||
|
* will bind to whatever address the client asked for.
|
||||||
|
*
|
||||||
|
* Special-case listen_addrs are:
|
||||||
|
*
|
||||||
|
* "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR
|
||||||
|
* "" (empty string), "*" -> wildcard v4/v6
|
||||||
|
* "localhost" -> loopback v4/v6
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
channel_fwd_bind_addr(const char *listen_addr, int *wildcardp,
|
||||||
|
int is_client, int gateway_ports)
|
||||||
|
{
|
||||||
|
const char *addr = NULL;
|
||||||
|
int wildcard = 0;
|
||||||
|
|
||||||
|
if (listen_addr == NULL) {
|
||||||
|
/* No address specified: default to gateway_ports setting */
|
||||||
|
if (gateway_ports)
|
||||||
|
wildcard = 1;
|
||||||
|
} else if (gateway_ports || is_client) {
|
||||||
|
if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
|
||||||
|
strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) ||
|
||||||
|
*listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
|
||||||
|
(!is_client && gateway_ports == 1))
|
||||||
|
wildcard = 1;
|
||||||
|
else if (strcmp(listen_addr, "localhost") != 0)
|
||||||
|
addr = listen_addr;
|
||||||
|
}
|
||||||
|
if (wildcardp != NULL)
|
||||||
|
*wildcardp = wildcard;
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
channel_setup_fwd_listener(int type, const char *listen_addr,
|
channel_setup_fwd_listener(int type, const char *listen_addr,
|
||||||
u_short listen_port, int *allocated_listen_port,
|
u_short listen_port, int *allocated_listen_port,
|
||||||
@ -2659,36 +2705,9 @@ channel_setup_fwd_listener(int type, const char *listen_addr,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Determine the bind address, cf. channel_fwd_bind_addr() comment */
|
||||||
* Determine whether or not a port forward listens to loopback,
|
addr = channel_fwd_bind_addr(listen_addr, &wildcard,
|
||||||
* specified address or wildcard. On the client, a specified bind
|
is_client, gateway_ports);
|
||||||
* address will always override gateway_ports. On the server, a
|
|
||||||
* gateway_ports of 1 (``yes'') will override the client's
|
|
||||||
* specification and force a wildcard bind, whereas a value of 2
|
|
||||||
* (``clientspecified'') will bind to whatever address the client
|
|
||||||
* asked for.
|
|
||||||
*
|
|
||||||
* Special-case listen_addrs are:
|
|
||||||
*
|
|
||||||
* "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR
|
|
||||||
* "" (empty string), "*" -> wildcard v4/v6
|
|
||||||
* "localhost" -> loopback v4/v6
|
|
||||||
*/
|
|
||||||
addr = NULL;
|
|
||||||
if (listen_addr == NULL) {
|
|
||||||
/* No address specified: default to gateway_ports setting */
|
|
||||||
if (gateway_ports)
|
|
||||||
wildcard = 1;
|
|
||||||
} else if (gateway_ports || is_client) {
|
|
||||||
if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
|
|
||||||
strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) ||
|
|
||||||
*listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
|
|
||||||
(!is_client && gateway_ports == 1))
|
|
||||||
wildcard = 1;
|
|
||||||
else if (strcmp(listen_addr, "localhost") != 0)
|
|
||||||
addr = listen_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s",
|
debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s",
|
||||||
type, wildcard, (addr == NULL) ? "NULL" : addr);
|
type, wildcard, (addr == NULL) ? "NULL" : addr);
|
||||||
|
|
||||||
@ -2793,6 +2812,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr,
|
|||||||
c->path = xstrdup(host);
|
c->path = xstrdup(host);
|
||||||
c->host_port = port_to_connect;
|
c->host_port = port_to_connect;
|
||||||
c->listening_port = listen_port;
|
c->listening_port = listen_port;
|
||||||
|
c->listening_addr = addr == NULL ? NULL : xstrdup(addr);
|
||||||
success = 1;
|
success = 1;
|
||||||
}
|
}
|
||||||
if (success == 0)
|
if (success == 0)
|
||||||
@ -2810,9 +2830,36 @@ channel_cancel_rport_listener(const char *host, u_short port)
|
|||||||
|
|
||||||
for (i = 0; i < channels_alloc; i++) {
|
for (i = 0; i < channels_alloc; i++) {
|
||||||
Channel *c = channels[i];
|
Channel *c = channels[i];
|
||||||
|
if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER)
|
||||||
|
continue;
|
||||||
|
if (strcmp(c->path, host) == 0 && c->listening_port == port) {
|
||||||
|
debug2("%s: close channel %d", __func__, i);
|
||||||
|
channel_free(c);
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
|
return (found);
|
||||||
strcmp(c->path, host) == 0 && c->listening_port == port) {
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
channel_cancel_lport_listener(const char *lhost, u_short lport,
|
||||||
|
u_short cport, int gateway_ports)
|
||||||
|
{
|
||||||
|
u_int i;
|
||||||
|
int found = 0;
|
||||||
|
const char *addr = channel_fwd_bind_addr(lhost, NULL, 1, gateway_ports);
|
||||||
|
|
||||||
|
for (i = 0; i < channels_alloc; i++) {
|
||||||
|
Channel *c = channels[i];
|
||||||
|
if (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER)
|
||||||
|
continue;
|
||||||
|
if (c->listening_port != lport || c->host_port != cport)
|
||||||
|
continue;
|
||||||
|
if ((c->listening_addr == NULL && addr != NULL) ||
|
||||||
|
(c->listening_addr != NULL && addr == NULL))
|
||||||
|
continue;
|
||||||
|
if (addr == NULL || strcmp(c->listening_addr, addr) == 0) {
|
||||||
debug2("%s: close channel %d", __func__, i);
|
debug2("%s: close channel %d", __func__, i);
|
||||||
channel_free(c);
|
channel_free(c);
|
||||||
found = 1;
|
found = 1;
|
||||||
@ -2842,11 +2889,31 @@ channel_setup_remote_fwd_listener(const char *listen_address,
|
|||||||
NULL, 0, gateway_ports);
|
NULL, 0, gateway_ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate the requested rfwd listen host to something usable for
|
||||||
|
* this server.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
channel_rfwd_bind_host(const char *listen_host)
|
||||||
|
{
|
||||||
|
if (listen_host == NULL) {
|
||||||
|
if (datafellows & SSH_BUG_RFWD_ADDR)
|
||||||
|
return "127.0.0.1";
|
||||||
|
else
|
||||||
|
return "localhost";
|
||||||
|
} else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) {
|
||||||
|
if (datafellows & SSH_BUG_RFWD_ADDR)
|
||||||
|
return "0.0.0.0";
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
} else
|
||||||
|
return listen_host;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initiate forwarding of connections to port "port" on remote host through
|
* Initiate forwarding of connections to port "port" on remote host through
|
||||||
* the secure channel to host:port from local side.
|
* the secure channel to host:port from local side.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
|
channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
|
||||||
const char *host_to_connect, u_short port_to_connect)
|
const char *host_to_connect, u_short port_to_connect)
|
||||||
@ -2855,25 +2922,10 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
|
|||||||
|
|
||||||
/* Send the forward request to the remote side. */
|
/* Send the forward request to the remote side. */
|
||||||
if (compat20) {
|
if (compat20) {
|
||||||
const char *address_to_bind;
|
|
||||||
if (listen_host == NULL) {
|
|
||||||
if (datafellows & SSH_BUG_RFWD_ADDR)
|
|
||||||
address_to_bind = "127.0.0.1";
|
|
||||||
else
|
|
||||||
address_to_bind = "localhost";
|
|
||||||
} else if (*listen_host == '\0' ||
|
|
||||||
strcmp(listen_host, "*") == 0) {
|
|
||||||
if (datafellows & SSH_BUG_RFWD_ADDR)
|
|
||||||
address_to_bind = "0.0.0.0";
|
|
||||||
else
|
|
||||||
address_to_bind = "";
|
|
||||||
} else
|
|
||||||
address_to_bind = listen_host;
|
|
||||||
|
|
||||||
packet_start(SSH2_MSG_GLOBAL_REQUEST);
|
packet_start(SSH2_MSG_GLOBAL_REQUEST);
|
||||||
packet_put_cstring("tcpip-forward");
|
packet_put_cstring("tcpip-forward");
|
||||||
packet_put_char(1); /* boolean: want reply */
|
packet_put_char(1); /* boolean: want reply */
|
||||||
packet_put_cstring(address_to_bind);
|
packet_put_cstring(channel_rfwd_bind_host(listen_host));
|
||||||
packet_put_int(listen_port);
|
packet_put_int(listen_port);
|
||||||
packet_send();
|
packet_send();
|
||||||
packet_write_wait();
|
packet_write_wait();
|
||||||
@ -2917,13 +2969,13 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
|
|||||||
* Request cancellation of remote forwarding of connection host:port from
|
* Request cancellation of remote forwarding of connection host:port from
|
||||||
* local side.
|
* local side.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
channel_request_rforward_cancel(const char *host, u_short port)
|
channel_request_rforward_cancel(const char *host, u_short port)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!compat20)
|
if (!compat20)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
for (i = 0; i < num_permitted_opens; i++) {
|
for (i = 0; i < num_permitted_opens; i++) {
|
||||||
if (permitted_opens[i].host_to_connect != NULL &&
|
if (permitted_opens[i].host_to_connect != NULL &&
|
||||||
@ -2932,12 +2984,12 @@ channel_request_rforward_cancel(const char *host, u_short port)
|
|||||||
}
|
}
|
||||||
if (i >= num_permitted_opens) {
|
if (i >= num_permitted_opens) {
|
||||||
debug("%s: requested forward not found", __func__);
|
debug("%s: requested forward not found", __func__);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
packet_start(SSH2_MSG_GLOBAL_REQUEST);
|
packet_start(SSH2_MSG_GLOBAL_REQUEST);
|
||||||
packet_put_cstring("cancel-tcpip-forward");
|
packet_put_cstring("cancel-tcpip-forward");
|
||||||
packet_put_char(0);
|
packet_put_char(0);
|
||||||
packet_put_cstring(host == NULL ? "" : host);
|
packet_put_cstring(channel_rfwd_bind_host(host));
|
||||||
packet_put_int(port);
|
packet_put_int(port);
|
||||||
packet_send();
|
packet_send();
|
||||||
|
|
||||||
@ -2945,6 +2997,8 @@ channel_request_rforward_cancel(const char *host, u_short port)
|
|||||||
permitted_opens[i].port_to_connect = 0;
|
permitted_opens[i].port_to_connect = 0;
|
||||||
xfree(permitted_opens[i].host_to_connect);
|
xfree(permitted_opens[i].host_to_connect);
|
||||||
permitted_opens[i].host_to_connect = NULL;
|
permitted_opens[i].host_to_connect = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: channels.h,v 1.105 2011/06/22 22:08:42 djm Exp $ */
|
/* $OpenBSD: channels.h,v 1.106 2011/09/09 22:46:44 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -116,6 +116,7 @@ struct Channel {
|
|||||||
char *path;
|
char *path;
|
||||||
/* path for unix domain sockets, or host name for forwards */
|
/* path for unix domain sockets, or host name for forwards */
|
||||||
int listening_port; /* port being listened for forwards */
|
int listening_port; /* port being listened for forwards */
|
||||||
|
char *listening_addr; /* addr being listened for forwards */
|
||||||
int host_port; /* remote port to connect for forwards */
|
int host_port; /* remote port to connect for forwards */
|
||||||
char *remote_name; /* remote hostname */
|
char *remote_name; /* remote hostname */
|
||||||
|
|
||||||
@ -261,9 +262,10 @@ int channel_request_remote_forwarding(const char *, u_short,
|
|||||||
const char *, u_short);
|
const char *, u_short);
|
||||||
int channel_setup_local_fwd_listener(const char *, u_short,
|
int channel_setup_local_fwd_listener(const char *, u_short,
|
||||||
const char *, u_short, int);
|
const char *, u_short, int);
|
||||||
void channel_request_rforward_cancel(const char *host, u_short port);
|
int channel_request_rforward_cancel(const char *host, u_short port);
|
||||||
int channel_setup_remote_fwd_listener(const char *, u_short, int *, int);
|
int channel_setup_remote_fwd_listener(const char *, u_short, int *, int);
|
||||||
int channel_cancel_rport_listener(const char *, u_short);
|
int channel_cancel_rport_listener(const char *, u_short);
|
||||||
|
int channel_cancel_lport_listener(const char *, u_short, u_short, int);
|
||||||
|
|
||||||
/* x11 forwarding */
|
/* x11 forwarding */
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: clientloop.h,v 1.28 2011/06/22 22:08:42 djm Exp $ */
|
/* $OpenBSD: clientloop.h,v 1.29 2011/09/09 22:46:44 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -70,6 +70,7 @@ void client_expect_confirm(int, const char *, enum confirm_action);
|
|||||||
#define SSHMUX_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */
|
#define SSHMUX_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */
|
||||||
#define SSHMUX_COMMAND_FORWARD 5 /* Forward only, no command */
|
#define SSHMUX_COMMAND_FORWARD 5 /* Forward only, no command */
|
||||||
#define SSHMUX_COMMAND_STOP 6 /* Disable mux but not conn */
|
#define SSHMUX_COMMAND_STOP 6 /* Disable mux but not conn */
|
||||||
|
#define SSHMUX_COMMAND_CANCEL_FWD 7 /* Cancel forwarding(s) */
|
||||||
|
|
||||||
void muxserver_listen(void);
|
void muxserver_listen(void);
|
||||||
void muxclient(const char *);
|
void muxclient(const char *);
|
||||||
|
104
mux.c
104
mux.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: mux.c,v 1.29 2011/06/22 22:08:42 djm Exp $ */
|
/* $OpenBSD: mux.c,v 1.30 2011/09/09 22:46:44 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
|
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
|
||||||
*
|
*
|
||||||
@ -777,10 +777,11 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||||||
static int
|
static int
|
||||||
process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||||
{
|
{
|
||||||
Forward fwd;
|
Forward fwd, *found_fwd;
|
||||||
char *fwd_desc = NULL;
|
char *fwd_desc = NULL;
|
||||||
|
const char *error_reason = NULL;
|
||||||
u_int ftype;
|
u_int ftype;
|
||||||
int ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
fwd.listen_host = fwd.connect_host = NULL;
|
fwd.listen_host = fwd.connect_host = NULL;
|
||||||
if (buffer_get_int_ret(&ftype, m) != 0 ||
|
if (buffer_get_int_ret(&ftype, m) != 0 ||
|
||||||
@ -802,14 +803,66 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||||||
fwd.connect_host = NULL;
|
fwd.connect_host = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug2("%s: channel %d: request %s", __func__, c->self,
|
debug2("%s: channel %d: request cancel %s", __func__, c->self,
|
||||||
(fwd_desc = format_forward(ftype, &fwd)));
|
(fwd_desc = format_forward(ftype, &fwd)));
|
||||||
|
|
||||||
/* XXX implement this */
|
/* make sure this has been requested */
|
||||||
buffer_put_int(r, MUX_S_FAILURE);
|
found_fwd = NULL;
|
||||||
buffer_put_int(r, rid);
|
switch (ftype) {
|
||||||
buffer_put_cstring(r, "unimplemented");
|
case MUX_FWD_LOCAL:
|
||||||
|
case MUX_FWD_DYNAMIC:
|
||||||
|
for (i = 0; i < options.num_local_forwards; i++) {
|
||||||
|
if (compare_forward(&fwd,
|
||||||
|
options.local_forwards + i)) {
|
||||||
|
found_fwd = options.local_forwards + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MUX_FWD_REMOTE:
|
||||||
|
for (i = 0; i < options.num_remote_forwards; i++) {
|
||||||
|
if (compare_forward(&fwd,
|
||||||
|
options.remote_forwards + i)) {
|
||||||
|
found_fwd = options.remote_forwards + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_fwd == NULL)
|
||||||
|
error_reason = "port not forwarded";
|
||||||
|
else if (ftype == MUX_FWD_REMOTE) {
|
||||||
|
/*
|
||||||
|
* This shouldn't fail unless we confused the host/port
|
||||||
|
* between options.remote_forwards and permitted_opens.
|
||||||
|
*/
|
||||||
|
if (channel_request_rforward_cancel(fwd.listen_host,
|
||||||
|
fwd.listen_port) == -1)
|
||||||
|
error_reason = "port not in permitted opens";
|
||||||
|
} else { /* local and dynamic forwards */
|
||||||
|
/* Ditto */
|
||||||
|
if (channel_cancel_lport_listener(fwd.listen_host,
|
||||||
|
fwd.listen_port, fwd.connect_port,
|
||||||
|
options.gateway_ports) == -1)
|
||||||
|
error_reason = "port not found";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_reason == NULL) {
|
||||||
|
buffer_put_int(r, MUX_S_OK);
|
||||||
|
buffer_put_int(r, rid);
|
||||||
|
|
||||||
|
if (found_fwd->listen_host != NULL)
|
||||||
|
xfree(found_fwd->listen_host);
|
||||||
|
if (found_fwd->connect_host != NULL)
|
||||||
|
xfree(found_fwd->connect_host);
|
||||||
|
found_fwd->listen_host = found_fwd->connect_host = NULL;
|
||||||
|
found_fwd->listen_port = found_fwd->connect_port = 0;
|
||||||
|
} else {
|
||||||
|
buffer_put_int(r, MUX_S_FAILURE);
|
||||||
|
buffer_put_int(r, rid);
|
||||||
|
buffer_put_cstring(r, error_reason);
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
if (fwd_desc != NULL)
|
if (fwd_desc != NULL)
|
||||||
xfree(fwd_desc);
|
xfree(fwd_desc);
|
||||||
@ -1537,18 +1590,19 @@ mux_client_request_terminate(int fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
|
mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd)
|
||||||
{
|
{
|
||||||
Buffer m;
|
Buffer m;
|
||||||
char *e, *fwd_desc;
|
char *e, *fwd_desc;
|
||||||
u_int type, rid;
|
u_int type, rid;
|
||||||
|
|
||||||
fwd_desc = format_forward(ftype, fwd);
|
fwd_desc = format_forward(ftype, fwd);
|
||||||
debug("Requesting %s", fwd_desc);
|
debug("Requesting %s %s",
|
||||||
|
cancel_flag ? "cancellation of" : "forwarding of", fwd_desc);
|
||||||
xfree(fwd_desc);
|
xfree(fwd_desc);
|
||||||
|
|
||||||
buffer_init(&m);
|
buffer_init(&m);
|
||||||
buffer_put_int(&m, MUX_C_OPEN_FWD);
|
buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD);
|
||||||
buffer_put_int(&m, muxclient_request_id);
|
buffer_put_int(&m, muxclient_request_id);
|
||||||
buffer_put_int(&m, ftype);
|
buffer_put_int(&m, ftype);
|
||||||
buffer_put_cstring(&m,
|
buffer_put_cstring(&m,
|
||||||
@ -1577,6 +1631,8 @@ mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
|
|||||||
case MUX_S_OK:
|
case MUX_S_OK:
|
||||||
break;
|
break;
|
||||||
case MUX_S_REMOTE_PORT:
|
case MUX_S_REMOTE_PORT:
|
||||||
|
if (cancel_flag)
|
||||||
|
fatal("%s: got MUX_S_REMOTE_PORT for cancel", __func__);
|
||||||
fwd->allocated_port = buffer_get_int(&m);
|
fwd->allocated_port = buffer_get_int(&m);
|
||||||
logit("Allocated port %u for remote forward to %s:%d",
|
logit("Allocated port %u for remote forward to %s:%d",
|
||||||
fwd->allocated_port,
|
fwd->allocated_port,
|
||||||
@ -1606,27 +1662,28 @@ mux_client_request_forward(int fd, u_int ftype, Forward *fwd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mux_client_request_forwards(int fd)
|
mux_client_forwards(int fd, int cancel_flag)
|
||||||
{
|
{
|
||||||
int i;
|
int i, ret = 0;
|
||||||
|
|
||||||
debug3("%s: requesting forwardings: %d local, %d remote", __func__,
|
debug3("%s: %s forwardings: %d local, %d remote", __func__,
|
||||||
|
cancel_flag ? "cancel" : "request",
|
||||||
options.num_local_forwards, options.num_remote_forwards);
|
options.num_local_forwards, options.num_remote_forwards);
|
||||||
|
|
||||||
/* XXX ExitOnForwardingFailure */
|
/* XXX ExitOnForwardingFailure */
|
||||||
for (i = 0; i < options.num_local_forwards; i++) {
|
for (i = 0; i < options.num_local_forwards; i++) {
|
||||||
if (mux_client_request_forward(fd,
|
if (mux_client_forward(fd, cancel_flag,
|
||||||
options.local_forwards[i].connect_port == 0 ?
|
options.local_forwards[i].connect_port == 0 ?
|
||||||
MUX_FWD_DYNAMIC : MUX_FWD_LOCAL,
|
MUX_FWD_DYNAMIC : MUX_FWD_LOCAL,
|
||||||
options.local_forwards + i) != 0)
|
options.local_forwards + i) != 0)
|
||||||
return -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < options.num_remote_forwards; i++) {
|
for (i = 0; i < options.num_remote_forwards; i++) {
|
||||||
if (mux_client_request_forward(fd, MUX_FWD_REMOTE,
|
if (mux_client_forward(fd, cancel_flag, MUX_FWD_REMOTE,
|
||||||
options.remote_forwards + i) != 0)
|
options.remote_forwards + i) != 0)
|
||||||
return -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -2014,11 +2071,11 @@ muxclient(const char *path)
|
|||||||
fprintf(stderr, "Exit request sent.\r\n");
|
fprintf(stderr, "Exit request sent.\r\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
case SSHMUX_COMMAND_FORWARD:
|
case SSHMUX_COMMAND_FORWARD:
|
||||||
if (mux_client_request_forwards(sock) != 0)
|
if (mux_client_forwards(sock, 0) != 0)
|
||||||
fatal("%s: master forward request failed", __func__);
|
fatal("%s: master forward request failed", __func__);
|
||||||
exit(0);
|
exit(0);
|
||||||
case SSHMUX_COMMAND_OPEN:
|
case SSHMUX_COMMAND_OPEN:
|
||||||
if (mux_client_request_forwards(sock) != 0) {
|
if (mux_client_forwards(sock, 0) != 0) {
|
||||||
error("%s: master forward request failed", __func__);
|
error("%s: master forward request failed", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2031,6 +2088,11 @@ muxclient(const char *path)
|
|||||||
mux_client_request_stop_listening(sock);
|
mux_client_request_stop_listening(sock);
|
||||||
fprintf(stderr, "Stop listening request sent.\r\n");
|
fprintf(stderr, "Stop listening request sent.\r\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
case SSHMUX_COMMAND_CANCEL_FWD:
|
||||||
|
if (mux_client_forwards(sock, 1) != 0)
|
||||||
|
error("%s: master cancel forward request failed",
|
||||||
|
__func__);
|
||||||
|
exit(0);
|
||||||
default:
|
default:
|
||||||
fatal("unrecognised muxclient_command %d", muxclient_command);
|
fatal("unrecognised muxclient_command %d", muxclient_command);
|
||||||
}
|
}
|
||||||
|
4
ssh.c
4
ssh.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssh.c,v 1.364 2011/08/02 23:15:03 djm Exp $ */
|
/* $OpenBSD: ssh.c,v 1.365 2011/09/09 22:46:44 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -377,6 +377,8 @@ main(int ac, char **av)
|
|||||||
muxclient_command = SSHMUX_COMMAND_TERMINATE;
|
muxclient_command = SSHMUX_COMMAND_TERMINATE;
|
||||||
else if (strcmp(optarg, "stop") == 0)
|
else if (strcmp(optarg, "stop") == 0)
|
||||||
muxclient_command = SSHMUX_COMMAND_STOP;
|
muxclient_command = SSHMUX_COMMAND_STOP;
|
||||||
|
else if (strcmp(optarg, "cancel") == 0)
|
||||||
|
muxclient_command = SSHMUX_COMMAND_CANCEL_FWD;
|
||||||
else
|
else
|
||||||
fatal("Invalid multiplex command.");
|
fatal("Invalid multiplex command.");
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user