2006-04-23 18:26:03 +00:00
|
|
|
/*
|
|
|
|
* SSH port forwarding.
|
|
|
|
*/
|
|
|
|
|
2018-05-30 21:36:20 +00:00
|
|
|
#include <assert.h>
|
2001-08-08 20:53:27 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "putty.h"
|
|
|
|
#include "ssh.h"
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
#include "sshchan.h"
|
2001-08-08 20:53:27 +00:00
|
|
|
|
2018-09-14 16:04:39 +00:00
|
|
|
static void logeventf(Frontend *frontend, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
char *buf;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
buf = dupvprintf(fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
logevent(frontend, buf);
|
|
|
|
sfree(buf);
|
|
|
|
}
|
|
|
|
|
2018-05-30 21:36:20 +00:00
|
|
|
/*
|
|
|
|
* Enumeration of values that live in the 'socks_state' field of
|
|
|
|
* struct PortForwarding.
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
SOCKS_NONE, /* direct connection (no SOCKS, or SOCKS already done) */
|
|
|
|
SOCKS_INITIAL, /* don't know if we're SOCKS 4 or 5 yet */
|
|
|
|
SOCKS_4, /* expect a SOCKS 4 (or 4A) connection message */
|
|
|
|
SOCKS_5_INITIAL, /* expect a SOCKS 5 preliminary message */
|
|
|
|
SOCKS_5_CONNECT /* expect a SOCKS 5 connection message */
|
|
|
|
} SocksState;
|
|
|
|
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
typedef struct PortForwarding {
|
2018-09-17 11:14:00 +00:00
|
|
|
SshChannel *c; /* channel structure held by SSH connection layer */
|
|
|
|
ConnectionLayer *cl; /* the connection layer itself */
|
2018-09-11 14:33:10 +00:00
|
|
|
/* Note that ssh need not be filled in if c is non-NULL */
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
Socket *s;
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
int input_wanted;
|
2001-08-08 20:53:27 +00:00
|
|
|
int ready;
|
2018-05-30 21:36:20 +00:00
|
|
|
SocksState socks_state;
|
2003-04-05 11:45:21 +00:00
|
|
|
/*
|
|
|
|
* `hostname' and `port' are the real hostname and port, once
|
2013-07-11 17:23:56 +00:00
|
|
|
* we know what we're connecting to.
|
2003-04-05 11:45:21 +00:00
|
|
|
*/
|
2013-07-11 17:23:56 +00:00
|
|
|
char *hostname;
|
2003-04-05 11:45:21 +00:00
|
|
|
int port;
|
2013-07-11 17:23:56 +00:00
|
|
|
/*
|
2018-05-30 21:36:20 +00:00
|
|
|
* `socksbuf' is the buffer we use to accumulate the initial SOCKS
|
|
|
|
* segment of the incoming data, plus anything after that that we
|
|
|
|
* receive before we're ready to send data to the SSH server.
|
2013-07-11 17:23:56 +00:00
|
|
|
*/
|
2018-05-30 21:36:20 +00:00
|
|
|
strbuf *socksbuf;
|
|
|
|
size_t socksbuf_consumed;
|
2018-05-27 08:29:33 +00:00
|
|
|
|
2018-10-05 06:24:16 +00:00
|
|
|
Plug plug;
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
Channel chan;
|
|
|
|
} PortForwarding;
|
2001-08-08 20:53:27 +00:00
|
|
|
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
struct PortListener {
|
2018-09-17 11:14:00 +00:00
|
|
|
ConnectionLayer *cl;
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
Socket *s;
|
2018-05-30 21:36:20 +00:00
|
|
|
int is_dynamic;
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
/*
|
|
|
|
* `hostname' and `port' are the real hostname and port, for
|
|
|
|
* ordinary forwardings.
|
|
|
|
*/
|
|
|
|
char *hostname;
|
|
|
|
int port;
|
2018-05-27 08:29:33 +00:00
|
|
|
|
2018-10-05 06:24:16 +00:00
|
|
|
Plug plug;
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct PortForwarding *new_portfwd_state(void)
|
2013-07-11 17:23:56 +00:00
|
|
|
{
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
struct PortForwarding *pf = snew(struct PortForwarding);
|
|
|
|
pf->hostname = NULL;
|
|
|
|
pf->socksbuf = NULL;
|
|
|
|
return pf;
|
2013-07-11 17:23:56 +00:00
|
|
|
}
|
|
|
|
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
static void free_portfwd_state(struct PortForwarding *pf)
|
2013-07-11 17:23:56 +00:00
|
|
|
{
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
if (!pf)
|
2013-07-11 17:23:56 +00:00
|
|
|
return;
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
sfree(pf->hostname);
|
2018-05-30 21:36:20 +00:00
|
|
|
if (pf->socksbuf)
|
|
|
|
strbuf_free(pf->socksbuf);
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
sfree(pf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct PortListener *new_portlistener_state(void)
|
|
|
|
{
|
|
|
|
struct PortListener *pl = snew(struct PortListener);
|
|
|
|
pl->hostname = NULL;
|
|
|
|
return pl;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_portlistener_state(struct PortListener *pl)
|
|
|
|
{
|
|
|
|
if (!pl)
|
|
|
|
return;
|
|
|
|
sfree(pl->hostname);
|
|
|
|
sfree(pl);
|
2013-07-11 17:23:56 +00:00
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static void pfd_log(Plug *plug, int type, SockAddr *addr, int port,
|
2005-01-16 14:29:34 +00:00
|
|
|
const char *error_msg, int error_code)
|
|
|
|
{
|
|
|
|
/* we have to dump these since we have no interface to logging.c */
|
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static void pfl_log(Plug *plug, int type, SockAddr *addr, int port,
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
const char *error_msg, int error_code)
|
|
|
|
{
|
|
|
|
/* we have to dump these since we have no interface to logging.c */
|
|
|
|
}
|
|
|
|
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
static void pfd_close(struct PortForwarding *pf);
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static void pfd_closing(Plug *plug, const char *error_msg, int error_code,
|
2016-06-02 22:03:24 +00:00
|
|
|
int calling_back)
|
2001-08-08 20:53:27 +00:00
|
|
|
{
|
2018-10-05 06:24:16 +00:00
|
|
|
struct PortForwarding *pf = FROMFIELD(plug, struct PortForwarding, plug);
|
2001-08-08 20:53:27 +00:00
|
|
|
|
2011-12-08 19:15:58 +00:00
|
|
|
if (error_msg) {
|
|
|
|
/*
|
|
|
|
* Socket error. Slam the connection instantly shut.
|
|
|
|
*/
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
if (pf->c) {
|
|
|
|
sshfwd_unclean_close(pf->c, error_msg);
|
2013-08-15 06:42:36 +00:00
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* We might not have an SSH channel, if a socket error
|
|
|
|
* occurred during SOCKS negotiation. If not, we must
|
|
|
|
* clean ourself up without sshfwd_unclean_close's call
|
|
|
|
* back to pfd_close.
|
|
|
|
*/
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
pfd_close(pf);
|
2013-08-15 06:42:36 +00:00
|
|
|
}
|
2011-12-08 19:15:58 +00:00
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Ordinary EOF received on socket. Send an EOF on the SSH
|
|
|
|
* channel.
|
|
|
|
*/
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
if (pf->c)
|
|
|
|
sshfwd_write_eof(pf->c);
|
2011-12-08 19:15:58 +00:00
|
|
|
}
|
2001-08-08 20:53:27 +00:00
|
|
|
}
|
|
|
|
|
2018-09-14 16:04:39 +00:00
|
|
|
static void pfl_terminate(struct PortListener *pl);
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static void pfl_closing(Plug *plug, const char *error_msg, int error_code,
|
2016-06-02 22:03:24 +00:00
|
|
|
int calling_back)
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
{
|
|
|
|
struct PortListener *pl = (struct PortListener *) plug;
|
|
|
|
pfl_terminate(pl);
|
|
|
|
}
|
|
|
|
|
2018-09-17 11:14:00 +00:00
|
|
|
static SshChannel *wrap_lportfwd_open(
|
|
|
|
ConnectionLayer *cl, const char *hostname, int port,
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
Socket *s, Channel *chan)
|
2015-05-18 12:57:45 +00:00
|
|
|
{
|
|
|
|
char *peerinfo, *description;
|
2018-09-14 12:47:13 +00:00
|
|
|
SshChannel *toret;
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
|
2015-05-18 12:57:45 +00:00
|
|
|
peerinfo = sk_peer_info(s);
|
|
|
|
if (peerinfo) {
|
|
|
|
description = dupprintf("forwarding from %s", peerinfo);
|
|
|
|
sfree(peerinfo);
|
|
|
|
} else {
|
|
|
|
description = dupstr("forwarding");
|
|
|
|
}
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
|
2018-09-17 11:14:00 +00:00
|
|
|
toret = ssh_lportfwd_open(cl, hostname, port, description, chan);
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
|
2015-05-18 12:57:45 +00:00
|
|
|
sfree(description);
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
return toret;
|
2015-05-18 12:57:45 +00:00
|
|
|
}
|
|
|
|
|
2018-05-30 21:36:20 +00:00
|
|
|
static char *ipv4_to_string(unsigned ipv4)
|
|
|
|
{
|
|
|
|
return dupprintf("%u.%u.%u.%u",
|
|
|
|
(ipv4 >> 24) & 0xFF, (ipv4 >> 16) & 0xFF,
|
|
|
|
(ipv4 >> 8) & 0xFF, (ipv4 ) & 0xFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *ipv6_to_string(ptrlen ipv6)
|
|
|
|
{
|
|
|
|
const unsigned char *addr = ipv6.ptr;
|
|
|
|
assert(ipv6.len == 16);
|
|
|
|
return dupprintf("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
|
|
|
|
(unsigned)GET_16BIT_MSB_FIRST(addr + 0),
|
|
|
|
(unsigned)GET_16BIT_MSB_FIRST(addr + 2),
|
|
|
|
(unsigned)GET_16BIT_MSB_FIRST(addr + 4),
|
|
|
|
(unsigned)GET_16BIT_MSB_FIRST(addr + 6),
|
|
|
|
(unsigned)GET_16BIT_MSB_FIRST(addr + 8),
|
|
|
|
(unsigned)GET_16BIT_MSB_FIRST(addr + 10),
|
|
|
|
(unsigned)GET_16BIT_MSB_FIRST(addr + 12),
|
|
|
|
(unsigned)GET_16BIT_MSB_FIRST(addr + 14));
|
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static void pfd_receive(Plug *plug, int urgent, char *data, int len)
|
2001-08-08 20:53:27 +00:00
|
|
|
{
|
2018-10-05 06:24:16 +00:00
|
|
|
struct PortForwarding *pf = FROMFIELD(plug, struct PortForwarding, plug);
|
2018-05-30 21:36:20 +00:00
|
|
|
|
|
|
|
if (len == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (pf->socks_state != SOCKS_NONE) {
|
|
|
|
BinarySource src[1];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Store all the data we've got in socksbuf.
|
|
|
|
*/
|
|
|
|
put_data(pf->socksbuf, data, len);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check the start of socksbuf to see if it's a valid and
|
|
|
|
* complete message in the SOCKS exchange.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (pf->socks_state == SOCKS_INITIAL) {
|
|
|
|
/* Preliminary: check the first byte of the data (which we
|
|
|
|
* _must_ have by now) to find out which SOCKS major
|
|
|
|
* version we're speaking. */
|
|
|
|
switch (pf->socksbuf->u[0]) {
|
|
|
|
case 4:
|
|
|
|
pf->socks_state = SOCKS_4;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
pf->socks_state = SOCKS_5_INITIAL;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pfd_close(pf); /* unrecognised version */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BinarySource_BARE_INIT(src, pf->socksbuf->u, pf->socksbuf->len);
|
|
|
|
get_data(src, pf->socksbuf_consumed);
|
|
|
|
|
|
|
|
while (pf->socks_state != SOCKS_NONE) {
|
|
|
|
unsigned socks_version, message_type, reserved_byte;
|
|
|
|
unsigned reply_code, port, ipv4, method;
|
|
|
|
ptrlen methods;
|
|
|
|
const char *socks4_hostname;
|
|
|
|
strbuf *output;
|
|
|
|
|
|
|
|
switch (pf->socks_state) {
|
|
|
|
case SOCKS_INITIAL:
|
|
|
|
case SOCKS_NONE:
|
|
|
|
assert(0 && "These case values cannot appear");
|
|
|
|
|
|
|
|
case SOCKS_4:
|
|
|
|
/* SOCKS 4/4A connect message */
|
|
|
|
socks_version = get_byte(src);
|
|
|
|
message_type = get_byte(src);
|
|
|
|
|
|
|
|
if (get_err(src) == BSE_OUT_OF_DATA)
|
|
|
|
return;
|
|
|
|
if (socks_version == 4 && message_type == 1) {
|
|
|
|
/* CONNECT message */
|
|
|
|
int name_based = FALSE;
|
|
|
|
|
|
|
|
port = get_uint16(src);
|
|
|
|
ipv4 = get_uint32(src);
|
|
|
|
if (ipv4 > 0x00000000 && ipv4 < 0x00000100) {
|
|
|
|
/*
|
|
|
|
* Addresses in this range indicate the SOCKS 4A
|
|
|
|
* extension to specify a hostname, which comes
|
|
|
|
* after the username.
|
|
|
|
*/
|
|
|
|
name_based = TRUE;
|
|
|
|
}
|
|
|
|
get_asciz(src); /* skip username */
|
|
|
|
socks4_hostname = name_based ? get_asciz(src) : NULL;
|
|
|
|
|
|
|
|
if (get_err(src) == BSE_OUT_OF_DATA)
|
|
|
|
return;
|
|
|
|
if (get_err(src))
|
|
|
|
goto socks4_reject;
|
|
|
|
|
|
|
|
pf->port = port;
|
|
|
|
if (name_based) {
|
|
|
|
pf->hostname = dupstr(socks4_hostname);
|
|
|
|
} else {
|
|
|
|
pf->hostname = ipv4_to_string(ipv4);
|
|
|
|
}
|
|
|
|
|
|
|
|
output = strbuf_new();
|
|
|
|
put_byte(output, 0); /* reply version */
|
|
|
|
put_byte(output, 90); /* SOCKS 4 'request granted' */
|
|
|
|
put_uint16(output, 0); /* null port field */
|
|
|
|
put_uint32(output, 0); /* null address field */
|
|
|
|
sk_write(pf->s, output->u, output->len);
|
|
|
|
strbuf_free(output);
|
|
|
|
|
|
|
|
pf->socks_state = SOCKS_NONE;
|
|
|
|
pf->socksbuf_consumed = src->pos;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
socks4_reject:
|
|
|
|
output = strbuf_new();
|
|
|
|
put_byte(output, 0); /* reply version */
|
|
|
|
put_byte(output, 91); /* SOCKS 4 'request rejected' */
|
|
|
|
put_uint16(output, 0); /* null port field */
|
|
|
|
put_uint32(output, 0); /* null address field */
|
|
|
|
sk_write(pf->s, output->u, output->len);
|
|
|
|
strbuf_free(output);
|
|
|
|
pfd_close(pf);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case SOCKS_5_INITIAL:
|
|
|
|
/* SOCKS 5 initial method list */
|
|
|
|
socks_version = get_byte(src);
|
|
|
|
methods = get_pstring(src);
|
|
|
|
|
|
|
|
method = 0xFF; /* means 'no usable method found' */
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < methods.len; i++) {
|
|
|
|
if (((const unsigned char *)methods.ptr)[i] == 0 ) {
|
|
|
|
method = 0; /* no auth */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (get_err(src) == BSE_OUT_OF_DATA)
|
|
|
|
return;
|
|
|
|
if (get_err(src))
|
|
|
|
method = 0xFF;
|
|
|
|
|
|
|
|
output = strbuf_new();
|
|
|
|
put_byte(output, 5); /* SOCKS version */
|
|
|
|
put_byte(output, method); /* selected auth method */
|
|
|
|
sk_write(pf->s, output->u, output->len);
|
|
|
|
strbuf_free(output);
|
|
|
|
|
|
|
|
if (method == 0xFF) {
|
|
|
|
pfd_close(pf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pf->socks_state = SOCKS_5_CONNECT;
|
|
|
|
pf->socksbuf_consumed = src->pos;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOCKS_5_CONNECT:
|
|
|
|
/* SOCKS 5 connect message */
|
|
|
|
socks_version = get_byte(src);
|
|
|
|
message_type = get_byte(src);
|
|
|
|
reserved_byte = get_byte(src);
|
|
|
|
|
|
|
|
if (socks_version == 5 && message_type == 1 &&
|
|
|
|
reserved_byte == 0) {
|
|
|
|
|
|
|
|
reply_code = 0; /* success */
|
|
|
|
|
|
|
|
switch (get_byte(src)) {
|
|
|
|
case 1: /* IPv4 */
|
|
|
|
pf->hostname = ipv4_to_string(get_uint32(src));
|
|
|
|
break;
|
|
|
|
case 4: /* IPv6 */
|
|
|
|
pf->hostname = ipv6_to_string(get_data(src, 16));
|
|
|
|
break;
|
|
|
|
case 3: /* unresolved domain name */
|
|
|
|
pf->hostname = mkstr(get_pstring(src));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pf->hostname = NULL;
|
|
|
|
reply_code = 8; /* address type not supported */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
pf->port = get_uint16(src);
|
|
|
|
} else {
|
|
|
|
reply_code = 7; /* command not supported */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (get_err(src) == BSE_OUT_OF_DATA)
|
|
|
|
return;
|
|
|
|
if (get_err(src))
|
|
|
|
reply_code = 1; /* general server failure */
|
|
|
|
|
|
|
|
output = strbuf_new();
|
|
|
|
put_byte(output, 5); /* SOCKS version */
|
|
|
|
put_byte(output, reply_code);
|
|
|
|
put_byte(output, 0); /* reserved */
|
|
|
|
put_byte(output, 1); /* IPv4 address follows */
|
|
|
|
put_uint32(output, 0); /* bound IPv4 address (unused) */
|
|
|
|
put_uint16(output, 0); /* bound port number (unused) */
|
|
|
|
sk_write(pf->s, output->u, output->len);
|
|
|
|
strbuf_free(output);
|
|
|
|
|
|
|
|
if (reply_code != 0) {
|
|
|
|
pfd_close(pf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pf->socks_state = SOCKS_NONE;
|
|
|
|
pf->socksbuf_consumed = src->pos;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-04-05 11:45:21 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We come here when we're ready to make an actual
|
|
|
|
* connection.
|
|
|
|
*/
|
|
|
|
|
2009-04-23 17:33:42 +00:00
|
|
|
/*
|
|
|
|
* Freeze the socket until the SSH server confirms the
|
|
|
|
* connection.
|
|
|
|
*/
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
sk_set_frozen(pf->s, 1);
|
2009-04-23 17:33:42 +00:00
|
|
|
|
2018-09-17 11:14:00 +00:00
|
|
|
pf->c = wrap_lportfwd_open(pf->cl, pf->hostname, pf->port, pf->s,
|
|
|
|
&pf->chan);
|
2001-08-25 17:09:23 +00:00
|
|
|
}
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
if (pf->ready)
|
|
|
|
sshfwd_write(pf->c, data, len);
|
2001-08-08 20:53:27 +00:00
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static void pfd_sent(Plug *plug, int bufsize)
|
2001-08-25 17:09:23 +00:00
|
|
|
{
|
2018-10-05 06:24:16 +00:00
|
|
|
struct PortForwarding *pf = FROMFIELD(plug, struct PortForwarding, plug);
|
2001-08-25 17:09:23 +00:00
|
|
|
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
if (pf->c)
|
|
|
|
sshfwd_unthrottle(pf->c, bufsize);
|
2001-08-25 17:09:23 +00:00
|
|
|
}
|
|
|
|
|
2018-10-05 06:03:46 +00:00
|
|
|
static const PlugVtable PortForwarding_plugvt = {
|
2018-05-27 08:29:33 +00:00
|
|
|
pfd_log,
|
|
|
|
pfd_closing,
|
|
|
|
pfd_receive,
|
|
|
|
pfd_sent,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
static void pfd_chan_free(Channel *chan);
|
|
|
|
static void pfd_open_confirmation(Channel *chan);
|
|
|
|
static void pfd_open_failure(Channel *chan, const char *errtext);
|
|
|
|
static int pfd_send(Channel *chan, int is_stderr, const void *data, int len);
|
|
|
|
static void pfd_send_eof(Channel *chan);
|
|
|
|
static void pfd_set_input_wanted(Channel *chan, int wanted);
|
|
|
|
static char *pfd_log_close_msg(Channel *chan);
|
|
|
|
|
|
|
|
static const struct ChannelVtable PortForwarding_channelvt = {
|
|
|
|
pfd_chan_free,
|
|
|
|
pfd_open_confirmation,
|
|
|
|
pfd_open_failure,
|
|
|
|
pfd_send,
|
|
|
|
pfd_send_eof,
|
|
|
|
pfd_set_input_wanted,
|
|
|
|
pfd_log_close_msg,
|
|
|
|
chan_no_eager_close,
|
|
|
|
};
|
|
|
|
|
2001-08-08 20:53:27 +00:00
|
|
|
/*
|
|
|
|
called when someone connects to the local port
|
|
|
|
*/
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
static int pfl_accepting(Plug *p, accept_fn_t constructor, accept_ctx_t ctx)
|
2001-08-08 20:53:27 +00:00
|
|
|
{
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
struct PortForwarding *pf;
|
|
|
|
struct PortListener *pl;
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
Socket *s;
|
2003-05-04 14:18:18 +00:00
|
|
|
const char *err;
|
2001-08-08 20:53:27 +00:00
|
|
|
|
2018-10-05 06:24:16 +00:00
|
|
|
pl = FROMFIELD(p, struct PortListener, plug);
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
pf = new_portfwd_state();
|
2018-10-05 06:24:16 +00:00
|
|
|
pf->plug.vt = &PortForwarding_plugvt;
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
pf->chan.initial_fixed_window_size = 0;
|
|
|
|
pf->chan.vt = &PortForwarding_channelvt;
|
|
|
|
pf->input_wanted = TRUE;
|
2001-08-08 20:53:27 +00:00
|
|
|
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
pf->c = NULL;
|
2018-09-17 11:14:00 +00:00
|
|
|
pf->cl = pl->cl;
|
2001-08-08 20:53:27 +00:00
|
|
|
|
2018-10-05 06:24:16 +00:00
|
|
|
pf->s = s = constructor(ctx, &pf->plug);
|
2003-01-05 13:04:04 +00:00
|
|
|
if ((err = sk_socket_error(s)) != NULL) {
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
free_portfwd_state(pf);
|
2001-08-08 20:53:27 +00:00
|
|
|
return err != NULL;
|
|
|
|
}
|
|
|
|
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
pf->input_wanted = TRUE;
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
pf->ready = 0;
|
2001-08-08 20:53:27 +00:00
|
|
|
|
2018-05-30 21:36:20 +00:00
|
|
|
if (pl->is_dynamic) {
|
|
|
|
pf->socks_state = SOCKS_INITIAL;
|
|
|
|
pf->socksbuf = strbuf_new();
|
|
|
|
pf->socksbuf_consumed = 0;
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
pf->port = 0; /* "hostname" buffer is so far empty */
|
2003-04-05 11:45:21 +00:00
|
|
|
sk_set_frozen(s, 0); /* we want to receive SOCKS _now_! */
|
2001-08-08 20:53:27 +00:00
|
|
|
} else {
|
2018-05-30 21:36:20 +00:00
|
|
|
pf->socks_state = SOCKS_NONE;
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
pf->hostname = dupstr(pl->hostname);
|
|
|
|
pf->port = pl->port;
|
2018-09-17 11:14:00 +00:00
|
|
|
pf->c = wrap_lportfwd_open(pl->cl, pf->hostname, pf->port,
|
|
|
|
s, &pf->chan);
|
2001-08-08 20:53:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-05 06:03:46 +00:00
|
|
|
static const PlugVtable PortListener_plugvt = {
|
2018-05-27 08:29:33 +00:00
|
|
|
pfl_log,
|
|
|
|
pfl_closing,
|
|
|
|
NULL, /* recv */
|
|
|
|
NULL, /* send */
|
|
|
|
pfl_accepting
|
|
|
|
};
|
2001-08-08 20:53:27 +00:00
|
|
|
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
/*
|
|
|
|
* Add a new port-forwarding listener from srcaddr:port -> desthost:destport.
|
|
|
|
*
|
2018-09-14 16:04:39 +00:00
|
|
|
* desthost == NULL indicates dynamic SOCKS port forwarding.
|
|
|
|
*
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
* On success, returns NULL and fills in *pl_ret. On error, returns a
|
|
|
|
* dynamically allocated error message string.
|
2001-08-08 20:53:27 +00:00
|
|
|
*/
|
2018-09-14 16:04:39 +00:00
|
|
|
static char *pfl_listen(char *desthost, int destport, char *srcaddr,
|
2018-09-17 11:14:00 +00:00
|
|
|
int port, ConnectionLayer *cl, Conf *conf,
|
2018-09-14 16:04:39 +00:00
|
|
|
struct PortListener **pl_ret, int address_family)
|
2001-08-08 20:53:27 +00:00
|
|
|
{
|
2003-05-04 14:18:18 +00:00
|
|
|
const char *err;
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
struct PortListener *pl;
|
2001-08-08 20:53:27 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Open socket.
|
|
|
|
*/
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
pl = *pl_ret = new_portlistener_state();
|
2018-10-05 06:24:16 +00:00
|
|
|
pl->plug.vt = &PortListener_plugvt;
|
2003-04-05 11:45:21 +00:00
|
|
|
if (desthost) {
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
pl->hostname = dupstr(desthost);
|
|
|
|
pl->port = destport;
|
2018-05-30 21:36:20 +00:00
|
|
|
pl->is_dynamic = FALSE;
|
2003-04-05 11:45:21 +00:00
|
|
|
} else
|
2018-05-30 21:36:20 +00:00
|
|
|
pl->is_dynamic = TRUE;
|
2018-09-17 11:14:00 +00:00
|
|
|
pl->cl = cl;
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
|
2018-10-05 06:24:16 +00:00
|
|
|
pl->s = new_listener(srcaddr, port, &pl->plug,
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
!conf_get_int(conf, CONF_lport_acceptall),
|
|
|
|
conf, address_family);
|
|
|
|
if ((err = sk_socket_error(pl->s)) != NULL) {
|
|
|
|
char *err_ret = dupstr(err);
|
|
|
|
sk_close(pl->s);
|
|
|
|
free_portlistener_state(pl);
|
|
|
|
*pl_ret = NULL;
|
|
|
|
return err_ret;
|
2001-08-08 20:53:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
static char *pfd_log_close_msg(Channel *chan)
|
|
|
|
{
|
|
|
|
return dupstr("Forwarded port closed");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pfd_close(struct PortForwarding *pf)
|
2001-08-08 20:53:27 +00:00
|
|
|
{
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
if (!pf)
|
2001-08-08 20:53:27 +00:00
|
|
|
return;
|
|
|
|
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
sk_close(pf->s);
|
|
|
|
free_portfwd_state(pf);
|
2001-08-08 20:53:27 +00:00
|
|
|
}
|
|
|
|
|
2004-12-28 14:07:05 +00:00
|
|
|
/*
|
|
|
|
* Terminate a listener.
|
|
|
|
*/
|
2018-09-14 16:04:39 +00:00
|
|
|
static void pfl_terminate(struct PortListener *pl)
|
2004-12-28 14:07:05 +00:00
|
|
|
{
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
if (!pl)
|
|
|
|
return;
|
|
|
|
|
|
|
|
sk_close(pl->s);
|
|
|
|
free_portlistener_state(pl);
|
2004-12-28 14:07:05 +00:00
|
|
|
}
|
|
|
|
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
static void pfd_set_input_wanted(Channel *chan, int wanted)
|
2001-08-25 17:09:23 +00:00
|
|
|
{
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
assert(chan->vt == &PortForwarding_channelvt);
|
|
|
|
PortForwarding *pf = FROMFIELD(chan, PortForwarding, chan);
|
|
|
|
pf->input_wanted = wanted;
|
|
|
|
sk_set_frozen(pf->s, !pf->input_wanted);
|
2001-08-25 17:09:23 +00:00
|
|
|
}
|
|
|
|
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
static void pfd_chan_free(Channel *chan)
|
2001-08-25 17:09:23 +00:00
|
|
|
{
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
assert(chan->vt == &PortForwarding_channelvt);
|
|
|
|
PortForwarding *pf = FROMFIELD(chan, PortForwarding, chan);
|
|
|
|
pfd_close(pf);
|
2001-08-25 17:09:23 +00:00
|
|
|
}
|
|
|
|
|
2001-08-08 20:53:27 +00:00
|
|
|
/*
|
|
|
|
* Called to send data down the raw connection.
|
|
|
|
*/
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
static int pfd_send(Channel *chan, int is_stderr, const void *data, int len)
|
2001-08-08 20:53:27 +00:00
|
|
|
{
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
assert(chan->vt == &PortForwarding_channelvt);
|
|
|
|
PortForwarding *pf = FROMFIELD(chan, PortForwarding, chan);
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
return sk_write(pf->s, data, len);
|
2001-08-08 20:53:27 +00:00
|
|
|
}
|
|
|
|
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
static void pfd_send_eof(Channel *chan)
|
2011-09-13 11:44:03 +00:00
|
|
|
{
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
assert(chan->vt == &PortForwarding_channelvt);
|
|
|
|
PortForwarding *pf = FROMFIELD(chan, PortForwarding, chan);
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
sk_write_eof(pf->s);
|
2011-09-13 11:44:03 +00:00
|
|
|
}
|
2001-08-08 20:53:27 +00:00
|
|
|
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
static void pfd_open_confirmation(Channel *chan)
|
2001-08-08 20:53:27 +00:00
|
|
|
{
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
assert(chan->vt == &PortForwarding_channelvt);
|
|
|
|
PortForwarding *pf = FROMFIELD(chan, PortForwarding, chan);
|
2001-08-08 20:53:27 +00:00
|
|
|
|
Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.
However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.
[originally from svn r10074]
2013-11-17 14:04:41 +00:00
|
|
|
pf->ready = 1;
|
|
|
|
sk_set_frozen(pf->s, 0);
|
|
|
|
sk_write(pf->s, NULL, 0);
|
2018-05-30 21:36:20 +00:00
|
|
|
if (pf->socksbuf) {
|
|
|
|
sshfwd_write(pf->c, pf->socksbuf->u + pf->socksbuf_consumed,
|
|
|
|
pf->socksbuf->len - pf->socksbuf_consumed);
|
|
|
|
strbuf_free(pf->socksbuf);
|
|
|
|
pf->socksbuf = NULL;
|
2003-04-05 11:45:21 +00:00
|
|
|
}
|
2001-08-08 20:53:27 +00:00
|
|
|
}
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
|
|
|
|
static void pfd_open_failure(Channel *chan, const char *errtext)
|
|
|
|
{
|
|
|
|
assert(chan->vt == &PortForwarding_channelvt);
|
|
|
|
PortForwarding *pf = FROMFIELD(chan, PortForwarding, chan);
|
|
|
|
|
2018-09-17 11:14:00 +00:00
|
|
|
logeventf(pf->cl->frontend,
|
2018-09-14 16:04:39 +00:00
|
|
|
"Forwarded connection refused by server%s%s",
|
|
|
|
errtext ? ": " : "", errtext ? errtext : "");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
* Code to manage the complete set of currently active port
|
|
|
|
* forwardings, and update it from Conf.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct PortFwdRecord {
|
|
|
|
enum { DESTROY, KEEP, CREATE } status;
|
|
|
|
int type;
|
|
|
|
unsigned sport, dport;
|
|
|
|
char *saddr, *daddr;
|
|
|
|
char *sserv, *dserv;
|
|
|
|
struct ssh_rportfwd *remote;
|
|
|
|
int addressfamily;
|
|
|
|
struct PortListener *local;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pfr_cmp(void *av, void *bv)
|
|
|
|
{
|
|
|
|
PortFwdRecord *a = (PortFwdRecord *) av;
|
|
|
|
PortFwdRecord *b = (PortFwdRecord *) bv;
|
|
|
|
int i;
|
|
|
|
if (a->type > b->type)
|
|
|
|
return +1;
|
|
|
|
if (a->type < b->type)
|
|
|
|
return -1;
|
|
|
|
if (a->addressfamily > b->addressfamily)
|
|
|
|
return +1;
|
|
|
|
if (a->addressfamily < b->addressfamily)
|
|
|
|
return -1;
|
|
|
|
if ( (i = nullstrcmp(a->saddr, b->saddr)) != 0)
|
|
|
|
return i < 0 ? -1 : +1;
|
|
|
|
if (a->sport > b->sport)
|
|
|
|
return +1;
|
|
|
|
if (a->sport < b->sport)
|
|
|
|
return -1;
|
|
|
|
if (a->type != 'D') {
|
|
|
|
if ( (i = nullstrcmp(a->daddr, b->daddr)) != 0)
|
|
|
|
return i < 0 ? -1 : +1;
|
|
|
|
if (a->dport > b->dport)
|
|
|
|
return +1;
|
|
|
|
if (a->dport < b->dport)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfr_free(PortFwdRecord *pfr)
|
|
|
|
{
|
|
|
|
/* Dispose of any listening socket. */
|
|
|
|
if (pfr->local)
|
|
|
|
pfl_terminate(pfr->local);
|
|
|
|
|
|
|
|
sfree(pfr->saddr);
|
|
|
|
sfree(pfr->daddr);
|
|
|
|
sfree(pfr->sserv);
|
|
|
|
sfree(pfr->dserv);
|
|
|
|
sfree(pfr);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct PortFwdManager {
|
2018-09-17 11:14:00 +00:00
|
|
|
ConnectionLayer *cl;
|
2018-09-14 16:04:39 +00:00
|
|
|
Conf *conf;
|
|
|
|
tree234 *forwardings;
|
|
|
|
};
|
|
|
|
|
2018-09-17 11:14:00 +00:00
|
|
|
PortFwdManager *portfwdmgr_new(ConnectionLayer *cl)
|
2018-09-14 16:04:39 +00:00
|
|
|
{
|
|
|
|
PortFwdManager *mgr = snew(PortFwdManager);
|
|
|
|
|
2018-09-17 11:14:00 +00:00
|
|
|
mgr->cl = cl;
|
2018-09-14 16:04:39 +00:00
|
|
|
mgr->conf = NULL;
|
|
|
|
mgr->forwardings = newtree234(pfr_cmp);
|
|
|
|
|
|
|
|
return mgr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void portfwdmgr_close(PortFwdManager *mgr, PortFwdRecord *pfr)
|
|
|
|
{
|
|
|
|
PortFwdRecord *realpfr = del234(mgr->forwardings, pfr);
|
|
|
|
if (realpfr == pfr)
|
|
|
|
pfr_free(pfr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void portfwdmgr_close_all(PortFwdManager *mgr)
|
|
|
|
{
|
|
|
|
PortFwdRecord *pfr;
|
|
|
|
|
|
|
|
while ((pfr = delpos234(mgr->forwardings, 0)) != NULL)
|
|
|
|
pfr_free(pfr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void portfwdmgr_free(PortFwdManager *mgr)
|
|
|
|
{
|
|
|
|
portfwdmgr_close_all(mgr);
|
|
|
|
freetree234(mgr->forwardings);
|
|
|
|
if (mgr->conf)
|
|
|
|
conf_free(mgr->conf);
|
|
|
|
sfree(mgr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void portfwdmgr_config(PortFwdManager *mgr, Conf *conf)
|
|
|
|
{
|
|
|
|
PortFwdRecord *pfr;
|
|
|
|
int i;
|
|
|
|
char *key, *val;
|
|
|
|
|
|
|
|
if (mgr->conf)
|
|
|
|
conf_free(mgr->conf);
|
|
|
|
mgr->conf = conf_copy(conf);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Go through the existing port forwardings and tag them
|
|
|
|
* with status==DESTROY. Any that we want to keep will be
|
|
|
|
* re-enabled (status==KEEP) as we go through the
|
|
|
|
* configuration and find out which bits are the same as
|
|
|
|
* they were before.
|
|
|
|
*/
|
|
|
|
for (i = 0; (pfr = index234(mgr->forwardings, i)) != NULL; i++)
|
|
|
|
pfr->status = DESTROY;
|
|
|
|
|
|
|
|
for (val = conf_get_str_strs(conf, CONF_portfwd, NULL, &key);
|
|
|
|
val != NULL;
|
|
|
|
val = conf_get_str_strs(conf, CONF_portfwd, key, &key)) {
|
|
|
|
char *kp, *kp2, *vp, *vp2;
|
|
|
|
char address_family, type;
|
|
|
|
int sport, dport, sserv, dserv;
|
|
|
|
char *sports, *dports, *saddr, *host;
|
|
|
|
|
|
|
|
kp = key;
|
|
|
|
|
|
|
|
address_family = 'A';
|
|
|
|
type = 'L';
|
|
|
|
if (*kp == 'A' || *kp == '4' || *kp == '6')
|
|
|
|
address_family = *kp++;
|
|
|
|
if (*kp == 'L' || *kp == 'R')
|
|
|
|
type = *kp++;
|
|
|
|
|
|
|
|
if ((kp2 = host_strchr(kp, ':')) != NULL) {
|
|
|
|
/*
|
|
|
|
* There's a colon in the middle of the source port
|
|
|
|
* string, which means that the part before it is
|
|
|
|
* actually a source address.
|
|
|
|
*/
|
|
|
|
char *saddr_tmp = dupprintf("%.*s", (int)(kp2 - kp), kp);
|
|
|
|
saddr = host_strduptrim(saddr_tmp);
|
|
|
|
sfree(saddr_tmp);
|
|
|
|
sports = kp2+1;
|
|
|
|
} else {
|
|
|
|
saddr = NULL;
|
|
|
|
sports = kp;
|
|
|
|
}
|
|
|
|
sport = atoi(sports);
|
|
|
|
sserv = 0;
|
|
|
|
if (sport == 0) {
|
|
|
|
sserv = 1;
|
|
|
|
sport = net_service_lookup(sports);
|
|
|
|
if (!sport) {
|
2018-09-17 11:14:00 +00:00
|
|
|
logeventf(mgr->cl->frontend, "Service lookup failed for source"
|
2018-09-14 16:04:39 +00:00
|
|
|
" port \"%s\"", sports);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (type == 'L' && !strcmp(val, "D")) {
|
|
|
|
/* dynamic forwarding */
|
|
|
|
host = NULL;
|
|
|
|
dports = NULL;
|
|
|
|
dport = -1;
|
|
|
|
dserv = 0;
|
|
|
|
type = 'D';
|
|
|
|
} else {
|
|
|
|
/* ordinary forwarding */
|
|
|
|
vp = val;
|
|
|
|
vp2 = vp + host_strcspn(vp, ":");
|
|
|
|
host = dupprintf("%.*s", (int)(vp2 - vp), vp);
|
|
|
|
if (*vp2)
|
|
|
|
vp2++;
|
|
|
|
dports = vp2;
|
|
|
|
dport = atoi(dports);
|
|
|
|
dserv = 0;
|
|
|
|
if (dport == 0) {
|
|
|
|
dserv = 1;
|
|
|
|
dport = net_service_lookup(dports);
|
|
|
|
if (!dport) {
|
2018-09-17 11:14:00 +00:00
|
|
|
logeventf(mgr->cl->frontend,
|
2018-09-14 16:04:39 +00:00
|
|
|
"Service lookup failed for destination"
|
|
|
|
" port \"%s\"", dports);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sport && dport) {
|
|
|
|
/* Set up a description of the source port. */
|
|
|
|
pfr = snew(PortFwdRecord);
|
|
|
|
pfr->type = type;
|
|
|
|
pfr->saddr = saddr;
|
|
|
|
pfr->sserv = sserv ? dupstr(sports) : NULL;
|
|
|
|
pfr->sport = sport;
|
|
|
|
pfr->daddr = host;
|
|
|
|
pfr->dserv = dserv ? dupstr(dports) : NULL;
|
|
|
|
pfr->dport = dport;
|
|
|
|
pfr->local = NULL;
|
|
|
|
pfr->remote = NULL;
|
|
|
|
pfr->addressfamily = (address_family == '4' ? ADDRTYPE_IPV4 :
|
|
|
|
address_family == '6' ? ADDRTYPE_IPV6 :
|
|
|
|
ADDRTYPE_UNSPEC);
|
|
|
|
|
|
|
|
PortFwdRecord *existing = add234(mgr->forwardings, pfr);
|
|
|
|
if (existing != pfr) {
|
|
|
|
if (existing->status == DESTROY) {
|
|
|
|
/*
|
|
|
|
* We already have a port forwarding up and running
|
|
|
|
* with precisely these parameters. Hence, no need
|
|
|
|
* to do anything; simply re-tag the existing one
|
|
|
|
* as KEEP.
|
|
|
|
*/
|
|
|
|
existing->status = KEEP;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Anything else indicates that there was a duplicate
|
|
|
|
* in our input, which we'll silently ignore.
|
|
|
|
*/
|
|
|
|
pfr_free(pfr);
|
|
|
|
} else {
|
|
|
|
pfr->status = CREATE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
sfree(saddr);
|
|
|
|
sfree(host);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now go through and destroy any port forwardings which were
|
|
|
|
* not re-enabled.
|
|
|
|
*/
|
|
|
|
for (i = 0; (pfr = index234(mgr->forwardings, i)) != NULL; i++) {
|
|
|
|
if (pfr->status == DESTROY) {
|
|
|
|
char *message;
|
|
|
|
|
|
|
|
message = dupprintf("%s port forwarding from %s%s%d",
|
|
|
|
pfr->type == 'L' ? "local" :
|
|
|
|
pfr->type == 'R' ? "remote" : "dynamic",
|
|
|
|
pfr->saddr ? pfr->saddr : "",
|
|
|
|
pfr->saddr ? ":" : "",
|
|
|
|
pfr->sport);
|
|
|
|
|
|
|
|
if (pfr->type != 'D') {
|
|
|
|
char *msg2 = dupprintf("%s to %s:%d", message,
|
|
|
|
pfr->daddr, pfr->dport);
|
|
|
|
sfree(message);
|
|
|
|
message = msg2;
|
|
|
|
}
|
|
|
|
|
2018-09-17 11:14:00 +00:00
|
|
|
logeventf(mgr->cl->frontend, "Cancelling %s", message);
|
2018-09-14 16:04:39 +00:00
|
|
|
sfree(message);
|
|
|
|
|
|
|
|
/* pfr->remote or pfr->local may be NULL if setting up a
|
|
|
|
* forwarding failed. */
|
|
|
|
if (pfr->remote) {
|
|
|
|
/*
|
|
|
|
* Cancel the port forwarding at the server
|
|
|
|
* end.
|
|
|
|
*
|
|
|
|
* Actually closing the listening port on the server
|
|
|
|
* side may fail - because in SSH-1 there's no message
|
|
|
|
* in the protocol to request it!
|
|
|
|
*
|
|
|
|
* Instead, we simply remove the record of the
|
|
|
|
* forwarding from our local end, so that any
|
|
|
|
* connections the server tries to make on it are
|
|
|
|
* rejected.
|
|
|
|
*/
|
2018-09-17 11:14:00 +00:00
|
|
|
ssh_rportfwd_remove(mgr->cl, pfr->remote);
|
2018-09-14 16:04:39 +00:00
|
|
|
} else if (pfr->local) {
|
|
|
|
pfl_terminate(pfr->local);
|
|
|
|
}
|
|
|
|
|
|
|
|
delpos234(mgr->forwardings, i);
|
|
|
|
pfr_free(pfr);
|
|
|
|
i--; /* so we don't skip one in the list */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* And finally, set up any new port forwardings (status==CREATE).
|
|
|
|
*/
|
|
|
|
for (i = 0; (pfr = index234(mgr->forwardings, i)) != NULL; i++) {
|
|
|
|
if (pfr->status == CREATE) {
|
|
|
|
char *sportdesc, *dportdesc;
|
|
|
|
sportdesc = dupprintf("%s%s%s%s%d%s",
|
|
|
|
pfr->saddr ? pfr->saddr : "",
|
|
|
|
pfr->saddr ? ":" : "",
|
|
|
|
pfr->sserv ? pfr->sserv : "",
|
|
|
|
pfr->sserv ? "(" : "",
|
|
|
|
pfr->sport,
|
|
|
|
pfr->sserv ? ")" : "");
|
|
|
|
if (pfr->type == 'D') {
|
|
|
|
dportdesc = NULL;
|
|
|
|
} else {
|
|
|
|
dportdesc = dupprintf("%s:%s%s%d%s",
|
|
|
|
pfr->daddr,
|
|
|
|
pfr->dserv ? pfr->dserv : "",
|
|
|
|
pfr->dserv ? "(" : "",
|
|
|
|
pfr->dport,
|
|
|
|
pfr->dserv ? ")" : "");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pfr->type == 'L') {
|
|
|
|
char *err = pfl_listen(pfr->daddr, pfr->dport,
|
|
|
|
pfr->saddr, pfr->sport,
|
2018-09-17 11:14:00 +00:00
|
|
|
mgr->cl, conf, &pfr->local,
|
2018-09-14 16:04:39 +00:00
|
|
|
pfr->addressfamily);
|
|
|
|
|
2018-09-17 11:14:00 +00:00
|
|
|
logeventf(mgr->cl->frontend,
|
2018-09-14 16:04:39 +00:00
|
|
|
"Local %sport %s forwarding to %s%s%s",
|
|
|
|
pfr->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " :
|
|
|
|
pfr->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "",
|
|
|
|
sportdesc, dportdesc,
|
|
|
|
err ? " failed: " : "", err ? err : "");
|
|
|
|
if (err)
|
|
|
|
sfree(err);
|
|
|
|
} else if (pfr->type == 'D') {
|
|
|
|
char *err = pfl_listen(NULL, -1, pfr->saddr, pfr->sport,
|
2018-09-17 11:14:00 +00:00
|
|
|
mgr->cl, conf, &pfr->local,
|
2018-09-14 16:04:39 +00:00
|
|
|
pfr->addressfamily);
|
|
|
|
|
2018-09-17 11:14:00 +00:00
|
|
|
logeventf(mgr->cl->frontend,
|
2018-09-14 16:04:39 +00:00
|
|
|
"Local %sport %s SOCKS dynamic forwarding%s%s",
|
|
|
|
pfr->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " :
|
|
|
|
pfr->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "",
|
|
|
|
sportdesc,
|
|
|
|
err ? " failed: " : "", err ? err : "");
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
sfree(err);
|
|
|
|
} else {
|
|
|
|
const char *shost;
|
|
|
|
|
|
|
|
if (pfr->saddr) {
|
|
|
|
shost = pfr->saddr;
|
|
|
|
} else if (conf_get_int(conf, CONF_rport_acceptall)) {
|
|
|
|
shost = "";
|
|
|
|
} else {
|
|
|
|
shost = "localhost";
|
|
|
|
}
|
|
|
|
|
|
|
|
pfr->remote = ssh_rportfwd_alloc(
|
2018-09-17 11:14:00 +00:00
|
|
|
mgr->cl, shost, pfr->sport, pfr->daddr, pfr->dport,
|
2018-09-14 16:04:39 +00:00
|
|
|
pfr->addressfamily, sportdesc, pfr, NULL);
|
|
|
|
|
|
|
|
if (!pfr->remote) {
|
2018-09-17 11:14:00 +00:00
|
|
|
logeventf(mgr->cl->frontend,
|
2018-09-14 16:04:39 +00:00
|
|
|
"Duplicate remote port forwarding to %s:%d",
|
|
|
|
pfr->daddr, pfr->dport);
|
|
|
|
pfr_free(pfr);
|
|
|
|
} else {
|
2018-09-17 11:14:00 +00:00
|
|
|
logeventf(mgr->cl->frontend, "Requesting remote port %s"
|
2018-09-14 16:04:39 +00:00
|
|
|
" forward to %s", sportdesc, dportdesc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sfree(sportdesc);
|
|
|
|
sfree(dportdesc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Called when receiving a PORT OPEN from the server to make a
|
|
|
|
* connection to a destination host.
|
|
|
|
*
|
|
|
|
* On success, returns NULL and fills in *pf_ret. On error, returns a
|
|
|
|
* dynamically allocated error message string.
|
|
|
|
*/
|
|
|
|
char *portfwdmgr_connect(PortFwdManager *mgr, Channel **chan_ret,
|
|
|
|
char *hostname, int port, SshChannel *c,
|
|
|
|
int addressfamily)
|
|
|
|
{
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 18:10:23 +00:00
|
|
|
SockAddr *addr;
|
2018-09-14 16:04:39 +00:00
|
|
|
const char *err;
|
|
|
|
char *dummy_realhost = NULL;
|
|
|
|
struct PortForwarding *pf;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Try to find host.
|
|
|
|
*/
|
|
|
|
addr = name_lookup(hostname, port, &dummy_realhost, mgr->conf,
|
|
|
|
addressfamily, NULL, NULL);
|
|
|
|
if ((err = sk_addr_error(addr)) != NULL) {
|
|
|
|
char *err_ret = dupstr(err);
|
|
|
|
sk_addr_free(addr);
|
|
|
|
sfree(dummy_realhost);
|
|
|
|
return err_ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Open socket.
|
|
|
|
*/
|
|
|
|
pf = new_portfwd_state();
|
|
|
|
*chan_ret = &pf->chan;
|
2018-10-05 06:24:16 +00:00
|
|
|
pf->plug.vt = &PortForwarding_plugvt;
|
2018-09-14 16:04:39 +00:00
|
|
|
pf->chan.initial_fixed_window_size = 0;
|
|
|
|
pf->chan.vt = &PortForwarding_channelvt;
|
|
|
|
pf->input_wanted = TRUE;
|
|
|
|
pf->ready = 1;
|
|
|
|
pf->c = c;
|
2018-09-17 11:14:00 +00:00
|
|
|
pf->cl = mgr->cl;
|
2018-09-14 16:04:39 +00:00
|
|
|
pf->socks_state = SOCKS_NONE;
|
|
|
|
|
|
|
|
pf->s = new_connection(addr, dummy_realhost, port,
|
2018-10-05 06:24:16 +00:00
|
|
|
0, 1, 0, 0, &pf->plug, mgr->conf);
|
2018-09-14 16:04:39 +00:00
|
|
|
sfree(dummy_realhost);
|
|
|
|
if ((err = sk_socket_error(pf->s)) != NULL) {
|
|
|
|
char *err_ret = dupstr(err);
|
|
|
|
sk_close(pf->s);
|
|
|
|
free_portfwd_state(pf);
|
|
|
|
*chan_ret = NULL;
|
|
|
|
return err_ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.
Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.
I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-12 14:03:47 +00:00
|
|
|
}
|