Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
/*
|
|
|
|
* Platform-independent parts of a standalone SOCKS server program
|
|
|
|
* based on the PuTTY SOCKS code.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include "putty.h"
|
2022-09-03 10:43:46 +00:00
|
|
|
#include "storage.h"
|
2021-04-08 00:45:03 +00:00
|
|
|
#include "misc.h"
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
#include "ssh.h"
|
2021-04-22 16:58:40 +00:00
|
|
|
#include "ssh/channel.h"
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
#include "psocks.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Possible later TODOs:
|
|
|
|
*
|
|
|
|
* - verbosity setting for log messages
|
|
|
|
*
|
|
|
|
* - could import proxy.c and use name_lookup rather than
|
|
|
|
* sk_namelookup, to allow forwarding via some other proxy type
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define BUFLIMIT 16384
|
|
|
|
|
|
|
|
#define LOGBITS(X) \
|
|
|
|
X(CONNSTATUS) \
|
|
|
|
X(DIALOGUE) \
|
|
|
|
/* end of list */
|
|
|
|
|
|
|
|
#define BITINDEX_ENUM(x) LOG_##x##_bitindex,
|
|
|
|
enum { LOGBITS(BITINDEX_ENUM) };
|
|
|
|
#define BITFLAG_ENUM(x) LOG_##x = 1 << LOG_##x##_bitindex,
|
|
|
|
enum { LOGBITS(BITFLAG_ENUM) };
|
|
|
|
|
|
|
|
typedef struct psocks_connection psocks_connection;
|
|
|
|
|
|
|
|
typedef enum RecordDestination {
|
|
|
|
REC_NONE, REC_FILE, REC_PIPE
|
|
|
|
} RecordDestination;
|
|
|
|
|
|
|
|
struct psocks_state {
|
|
|
|
const PsocksPlatform *platform;
|
|
|
|
int listen_port;
|
|
|
|
bool acceptall;
|
|
|
|
PortFwdManager *portfwdmgr;
|
|
|
|
uint64_t next_conn_index;
|
|
|
|
FILE *logging_fp;
|
|
|
|
unsigned log_flags;
|
|
|
|
RecordDestination rec_dest;
|
|
|
|
char *rec_cmd;
|
New abstraction for command-line arguments.
This begins the process of enabling our Windows applications to handle
Unicode characters on their command lines which don't fit in the
system code page.
Instead of passing plain strings to cmdline_process_param, we now pass
a partially opaque and platform-specific thing called a CmdlineArg.
This has a method that extracts the argument word as a default-encoded
string, and another one that tries to extract it as UTF-8 (though it
may fail if the UTF-8 isn't available).
On Windows, the command line is now constructed by calling
split_into_argv_w on the Unicode command line returned by
GetCommandLineW(), and the UTF-8 method returns text converted
directly from that wide-character form, not going via the system code
page. So it _can_ include UTF-8 characters that wouldn't have
round-tripped via CP_ACP.
This commit introduces the abstraction and switches over the
cross-platform and Windows argv-handling code to use it, with minimal
functional change. Nothing yet tries to call cmdline_arg_get_utf8().
I say 'cross-platform and Windows' because on the Unix side there's
still a lot of use of plain old argv which I haven't converted. That
would be a much larger project, and isn't currently needed: the
_current_ aim of this abstraction is to get the right things to happen
relating to Unicode on Windows, so for code that doesn't run on
Windows anyway, it's not adding value. (Also there's a tension with
GTK, which wants to talk to standard argv and extract arguments _it_
knows about, so at the very least we'd have to let it munge argv
before importing it into this new system.)
2024-09-25 09:18:38 +00:00
|
|
|
bool got_subcmd;
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
|
|
|
|
ConnectionLayer cl;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct psocks_connection {
|
|
|
|
psocks_state *ps;
|
|
|
|
Channel *chan;
|
|
|
|
char *host, *realhost;
|
|
|
|
int port;
|
|
|
|
SockAddr *addr;
|
|
|
|
Socket *socket;
|
|
|
|
bool connecting, eof_pfmgr_to_socket, eof_socket_to_pfmgr;
|
|
|
|
uint64_t index;
|
|
|
|
PsocksDataSink *rec_sink;
|
|
|
|
|
|
|
|
Plug plug;
|
|
|
|
SshChannel sc;
|
|
|
|
};
|
|
|
|
|
|
|
|
static SshChannel *psocks_lportfwd_open(
|
|
|
|
ConnectionLayer *cl, const char *hostname, int port,
|
2024-06-26 05:35:40 +00:00
|
|
|
const char *description, const SocketEndpointInfo *pi, Channel *chan);
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
|
Change vtable defs to use C99 designated initialisers.
This is a sweeping change applied across the whole code base by a spot
of Emacs Lisp. Now, everywhere I declare a vtable filled with function
pointers (and the occasional const data member), all the members of
the vtable structure are initialised by name using the '.fieldname =
value' syntax introduced in C99.
We were already using this syntax for a handful of things in the new
key-generation progress report system, so it's not new to the code
base as a whole.
The advantage is that now, when a vtable only declares a subset of the
available fields, I can initialise the rest to NULL or zero just by
leaving them out. This is most dramatic in a couple of the outlying
vtables in things like psocks (which has a ConnectionLayerVtable
containing only one non-NULL method), but less dramatically, it means
that the new 'flags' field in BackendVtable can be completely left out
of every backend definition except for the SUPDUP one which defines it
to a nonzero value. Similarly, the test_for_upstream method only used
by SSH doesn't have to be mentioned in the rest of the backends;
network Plugs for listening sockets don't have to explicitly null out
'receive' and 'sent', and vice versa for 'accepting', and so on.
While I'm at it, I've normalised the declarations so they don't use
the unnecessarily verbose 'struct' keyword. Also a handful of them
weren't const; now they are.
2020-03-10 21:06:29 +00:00
|
|
|
static const ConnectionLayerVtable psocks_clvt = {
|
|
|
|
.lportfwd_open = psocks_lportfwd_open,
|
|
|
|
/* everything else is NULL */
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static size_t psocks_sc_write(SshChannel *sc, bool is_stderr, const void *,
|
|
|
|
size_t);
|
|
|
|
static void psocks_sc_write_eof(SshChannel *sc);
|
|
|
|
static void psocks_sc_initiate_close(SshChannel *sc, const char *err);
|
|
|
|
static void psocks_sc_unthrottle(SshChannel *sc, size_t bufsize);
|
|
|
|
|
Change vtable defs to use C99 designated initialisers.
This is a sweeping change applied across the whole code base by a spot
of Emacs Lisp. Now, everywhere I declare a vtable filled with function
pointers (and the occasional const data member), all the members of
the vtable structure are initialised by name using the '.fieldname =
value' syntax introduced in C99.
We were already using this syntax for a handful of things in the new
key-generation progress report system, so it's not new to the code
base as a whole.
The advantage is that now, when a vtable only declares a subset of the
available fields, I can initialise the rest to NULL or zero just by
leaving them out. This is most dramatic in a couple of the outlying
vtables in things like psocks (which has a ConnectionLayerVtable
containing only one non-NULL method), but less dramatically, it means
that the new 'flags' field in BackendVtable can be completely left out
of every backend definition except for the SUPDUP one which defines it
to a nonzero value. Similarly, the test_for_upstream method only used
by SSH doesn't have to be mentioned in the rest of the backends;
network Plugs for listening sockets don't have to explicitly null out
'receive' and 'sent', and vice versa for 'accepting', and so on.
While I'm at it, I've normalised the declarations so they don't use
the unnecessarily verbose 'struct' keyword. Also a handful of them
weren't const; now they are.
2020-03-10 21:06:29 +00:00
|
|
|
static const SshChannelVtable psocks_scvt = {
|
|
|
|
.write = psocks_sc_write,
|
|
|
|
.write_eof = psocks_sc_write_eof,
|
|
|
|
.initiate_close = psocks_sc_initiate_close,
|
|
|
|
.unthrottle = psocks_sc_unthrottle,
|
|
|
|
/* all the rest are NULL */
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
};
|
|
|
|
|
2024-06-26 07:29:39 +00:00
|
|
|
static void psocks_plug_log(Plug *p, Socket *s, PlugLogType type,
|
|
|
|
SockAddr *addr, int port,
|
|
|
|
const char *error_msg, int error_code);
|
New API for plug_closing() with a custom type enum.
Passing an operating-system-specific error code to plug_closing(),
such as errno or GetLastError(), was always a bit weird, given that it
generally had to be handled by cross-platform receiving code in
backends. I had the platform.h implementations #define any error
values that the cross-platform code would have to handle specially,
but that's still not a great system, because it also doesn't leave
freedom to invent error representations of my own that don't
correspond to any OS code. (For example, the ones I just removed from
proxy.h.)
So now, the OS error code is gone from the plug_closing API, and in
its place is a custom enumeration of closure types: normal, error, and
the special case BROKEN_PIPE which is the only OS error code we have
so far needed to handle specially. (All others just mean 'abandon the
connection and print the textual message'.)
Having already centralised the handling of OS error codes in the
previous commit, we've now got a convenient place to add any further
type codes for errors needing special handling: each of Unix
plug_closing_errno(), Windows plug_closing_system_error(), and Windows
plug_closing_winsock_error() can easily grow extra special cases if
need be, and each one will only have to live in one place.
2021-11-06 13:28:32 +00:00
|
|
|
static void psocks_plug_closing(Plug *p, PlugCloseType, const char *error_msg);
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
static void psocks_plug_receive(Plug *p, int urgent,
|
|
|
|
const char *data, size_t len);
|
|
|
|
static void psocks_plug_sent(Plug *p, size_t bufsize);
|
|
|
|
|
|
|
|
static const PlugVtable psocks_plugvt = {
|
Change vtable defs to use C99 designated initialisers.
This is a sweeping change applied across the whole code base by a spot
of Emacs Lisp. Now, everywhere I declare a vtable filled with function
pointers (and the occasional const data member), all the members of
the vtable structure are initialised by name using the '.fieldname =
value' syntax introduced in C99.
We were already using this syntax for a handful of things in the new
key-generation progress report system, so it's not new to the code
base as a whole.
The advantage is that now, when a vtable only declares a subset of the
available fields, I can initialise the rest to NULL or zero just by
leaving them out. This is most dramatic in a couple of the outlying
vtables in things like psocks (which has a ConnectionLayerVtable
containing only one non-NULL method), but less dramatically, it means
that the new 'flags' field in BackendVtable can be completely left out
of every backend definition except for the SUPDUP one which defines it
to a nonzero value. Similarly, the test_for_upstream method only used
by SSH doesn't have to be mentioned in the rest of the backends;
network Plugs for listening sockets don't have to explicitly null out
'receive' and 'sent', and vice versa for 'accepting', and so on.
While I'm at it, I've normalised the declarations so they don't use
the unnecessarily verbose 'struct' keyword. Also a handful of them
weren't const; now they are.
2020-03-10 21:06:29 +00:00
|
|
|
.log = psocks_plug_log,
|
|
|
|
.closing = psocks_plug_closing,
|
|
|
|
.receive = psocks_plug_receive,
|
|
|
|
.sent = psocks_plug_sent,
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void psocks_conn_log(psocks_connection *conn, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if (!conn->ps->logging_fp)
|
|
|
|
return;
|
|
|
|
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
char *msg = dupvprintf(fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
fprintf(conn->ps->logging_fp, "c#%"PRIu64": %s\n", conn->index, msg);
|
|
|
|
sfree(msg);
|
|
|
|
fflush(conn->ps->logging_fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void psocks_conn_log_data(psocks_connection *conn, PsocksDirection dir,
|
|
|
|
const void *vdata, size_t len)
|
|
|
|
{
|
|
|
|
if ((conn->ps->log_flags & LOG_DIALOGUE) && conn->ps->logging_fp) {
|
|
|
|
const char *data = vdata;
|
|
|
|
while (len > 0) {
|
|
|
|
const char *nl = memchr(data, '\n', len);
|
|
|
|
size_t thislen = nl ? (nl+1) - data : len;
|
|
|
|
const char *thisdata = data;
|
|
|
|
data += thislen;
|
|
|
|
len -= thislen;
|
|
|
|
|
|
|
|
static const char *const direction_names[2] = {
|
|
|
|
[UP] = "send", [DN] = "recv" };
|
|
|
|
|
|
|
|
fprintf(conn->ps->logging_fp, "c#%"PRIu64": %s \"", conn->index,
|
|
|
|
direction_names[dir]);
|
2021-04-08 00:45:03 +00:00
|
|
|
write_c_string_literal(conn->ps->logging_fp,
|
|
|
|
make_ptrlen(thisdata, thislen));
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
fprintf(conn->ps->logging_fp, "\"\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
fflush(conn->ps->logging_fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (conn->rec_sink)
|
|
|
|
put_data(conn->rec_sink->s[dir], vdata, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void psocks_connection_establish(void *vctx);
|
|
|
|
|
|
|
|
static SshChannel *psocks_lportfwd_open(
|
|
|
|
ConnectionLayer *cl, const char *hostname, int port,
|
2024-06-26 05:35:40 +00:00
|
|
|
const char *description, const SocketEndpointInfo *pi, Channel *chan)
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
{
|
|
|
|
psocks_state *ps = container_of(cl, psocks_state, cl);
|
|
|
|
psocks_connection *conn = snew(psocks_connection);
|
|
|
|
memset(conn, 0, sizeof(*conn));
|
|
|
|
conn->ps = ps;
|
|
|
|
conn->sc.vt = &psocks_scvt;
|
|
|
|
conn->plug.vt = &psocks_plugvt;
|
|
|
|
conn->chan = chan;
|
|
|
|
conn->host = dupstr(hostname);
|
|
|
|
conn->port = port;
|
|
|
|
conn->index = ps->next_conn_index++;
|
|
|
|
if (conn->ps->log_flags & LOG_CONNSTATUS)
|
|
|
|
psocks_conn_log(conn, "request from %s for %s port %d",
|
|
|
|
pi->log_text, hostname, port);
|
|
|
|
switch (conn->ps->rec_dest) {
|
|
|
|
case REC_FILE:
|
|
|
|
{
|
|
|
|
char *fnames[2];
|
|
|
|
FILE *fp[2];
|
|
|
|
bool ok = true;
|
|
|
|
|
|
|
|
static const char *const direction_names[2] = {
|
|
|
|
[UP] = "sockout", [DN] = "sockin" };
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 2; i++) {
|
|
|
|
fnames[i] = dupprintf("%s.%"PRIu64, direction_names[i],
|
|
|
|
conn->index);
|
|
|
|
fp[i] = fopen(fnames[i], "wb");
|
|
|
|
if (!fp[i]) {
|
|
|
|
psocks_conn_log(conn, "cannot log this connection: "
|
|
|
|
"creating file '%s': %s",
|
|
|
|
fnames[i], strerror(errno));
|
|
|
|
ok = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ok) {
|
|
|
|
if (conn->ps->log_flags & LOG_CONNSTATUS)
|
|
|
|
psocks_conn_log(conn, "logging to '%s' / '%s'",
|
|
|
|
fnames[0], fnames[1]);
|
|
|
|
conn->rec_sink = pds_stdio(fp);
|
|
|
|
} else {
|
|
|
|
for (size_t i = 0; i < 2; i++) {
|
|
|
|
if (fp[i]) {
|
|
|
|
remove(fnames[i]);
|
|
|
|
fclose(fp[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (size_t i = 0; i < 2; i++)
|
|
|
|
sfree(fnames[i]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case REC_PIPE:
|
|
|
|
{
|
|
|
|
static const char *const direction_args[2] = {
|
|
|
|
[UP] = "out", [DN] = "in" };
|
|
|
|
char *index_arg = dupprintf("%"PRIu64, conn->index);
|
|
|
|
char *err;
|
|
|
|
conn->rec_sink = conn->ps->platform->open_pipes(
|
|
|
|
conn->ps->rec_cmd, direction_args, index_arg, &err);
|
|
|
|
if (!conn->rec_sink) {
|
|
|
|
psocks_conn_log(conn, "cannot log this connection: "
|
|
|
|
"creating pipes: %s", err);
|
|
|
|
sfree(err);
|
|
|
|
}
|
|
|
|
sfree(index_arg);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
queue_toplevel_callback(psocks_connection_establish, conn);
|
|
|
|
return &conn->sc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void psocks_conn_free(psocks_connection *conn)
|
|
|
|
{
|
|
|
|
if (conn->ps->log_flags & LOG_CONNSTATUS)
|
|
|
|
psocks_conn_log(conn, "closed");
|
|
|
|
|
|
|
|
sfree(conn->host);
|
|
|
|
sfree(conn->realhost);
|
|
|
|
if (conn->socket)
|
|
|
|
sk_close(conn->socket);
|
|
|
|
if (conn->chan)
|
|
|
|
chan_free(conn->chan);
|
|
|
|
if (conn->rec_sink)
|
|
|
|
pds_free(conn->rec_sink);
|
|
|
|
delete_callbacks_for_context(conn);
|
|
|
|
sfree(conn);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void psocks_connection_establish(void *vctx)
|
|
|
|
{
|
|
|
|
psocks_connection *conn = (psocks_connection *)vctx;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Look up destination host name.
|
|
|
|
*/
|
|
|
|
conn->addr = sk_namelookup(conn->host, &conn->realhost, ADDRTYPE_UNSPEC);
|
|
|
|
|
|
|
|
const char *err = sk_addr_error(conn->addr);
|
|
|
|
if (err) {
|
|
|
|
char *msg = dupprintf("name lookup failed: %s", err);
|
|
|
|
chan_open_failed(conn->chan, msg);
|
|
|
|
sfree(msg);
|
|
|
|
|
|
|
|
psocks_conn_free(conn);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make the connection.
|
|
|
|
*/
|
|
|
|
conn->connecting = true;
|
|
|
|
conn->socket = sk_new(conn->addr, conn->port, false, false, false, false,
|
|
|
|
&conn->plug);
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t psocks_sc_write(SshChannel *sc, bool is_stderr,
|
|
|
|
const void *data, size_t len)
|
|
|
|
{
|
|
|
|
psocks_connection *conn = container_of(sc, psocks_connection, sc);
|
|
|
|
if (!conn->socket) return 0;
|
|
|
|
|
|
|
|
psocks_conn_log_data(conn, UP, data, len);
|
|
|
|
|
|
|
|
return sk_write(conn->socket, data, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void psocks_check_close(void *vctx)
|
|
|
|
{
|
|
|
|
psocks_connection *conn = (psocks_connection *)vctx;
|
|
|
|
if (chan_want_close(conn->chan, conn->eof_pfmgr_to_socket,
|
|
|
|
conn->eof_socket_to_pfmgr))
|
|
|
|
psocks_conn_free(conn);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void psocks_sc_write_eof(SshChannel *sc)
|
|
|
|
{
|
|
|
|
psocks_connection *conn = container_of(sc, psocks_connection, sc);
|
|
|
|
if (!conn->socket) return;
|
|
|
|
sk_write_eof(conn->socket);
|
|
|
|
conn->eof_pfmgr_to_socket = true;
|
|
|
|
|
|
|
|
if (conn->ps->log_flags & LOG_DIALOGUE)
|
|
|
|
psocks_conn_log(conn, "send eof");
|
|
|
|
|
|
|
|
queue_toplevel_callback(psocks_check_close, conn);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void psocks_sc_initiate_close(SshChannel *sc, const char *err)
|
|
|
|
{
|
|
|
|
psocks_connection *conn = container_of(sc, psocks_connection, sc);
|
|
|
|
sk_close(conn->socket);
|
|
|
|
conn->socket = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void psocks_sc_unthrottle(SshChannel *sc, size_t bufsize)
|
|
|
|
{
|
|
|
|
psocks_connection *conn = container_of(sc, psocks_connection, sc);
|
|
|
|
if (bufsize < BUFLIMIT)
|
|
|
|
sk_set_frozen(conn->socket, false);
|
|
|
|
}
|
|
|
|
|
2024-06-26 07:29:39 +00:00
|
|
|
static void psocks_plug_log(Plug *plug, Socket *s, PlugLogType type,
|
|
|
|
SockAddr *addr, int port,
|
|
|
|
const char *error_msg, int error_code)
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
{
|
|
|
|
psocks_connection *conn = container_of(plug, psocks_connection, plug);
|
|
|
|
char addrbuf[256];
|
|
|
|
|
|
|
|
if (!(conn->ps->log_flags & LOG_CONNSTATUS))
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case PLUGLOG_CONNECT_TRYING:
|
|
|
|
sk_getaddr(addr, addrbuf, sizeof(addrbuf));
|
|
|
|
if (sk_addr_needs_port(addr))
|
|
|
|
psocks_conn_log(conn, "trying to connect to %s port %d",
|
|
|
|
addrbuf, port);
|
|
|
|
else
|
|
|
|
psocks_conn_log(conn, "trying to connect to %s", addrbuf);
|
|
|
|
break;
|
|
|
|
case PLUGLOG_CONNECT_FAILED:
|
|
|
|
psocks_conn_log(conn, "connection attempt failed: %s", error_msg);
|
|
|
|
break;
|
|
|
|
case PLUGLOG_CONNECT_SUCCESS:
|
|
|
|
psocks_conn_log(conn, "connection established", error_msg);
|
|
|
|
if (conn->connecting) {
|
|
|
|
chan_open_confirmation(conn->chan);
|
|
|
|
conn->connecting = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PLUGLOG_PROXY_MSG:
|
|
|
|
psocks_conn_log(conn, "connection setup: %s", error_msg);
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
New API for plug_closing() with a custom type enum.
Passing an operating-system-specific error code to plug_closing(),
such as errno or GetLastError(), was always a bit weird, given that it
generally had to be handled by cross-platform receiving code in
backends. I had the platform.h implementations #define any error
values that the cross-platform code would have to handle specially,
but that's still not a great system, because it also doesn't leave
freedom to invent error representations of my own that don't
correspond to any OS code. (For example, the ones I just removed from
proxy.h.)
So now, the OS error code is gone from the plug_closing API, and in
its place is a custom enumeration of closure types: normal, error, and
the special case BROKEN_PIPE which is the only OS error code we have
so far needed to handle specially. (All others just mean 'abandon the
connection and print the textual message'.)
Having already centralised the handling of OS error codes in the
previous commit, we've now got a convenient place to add any further
type codes for errors needing special handling: each of Unix
plug_closing_errno(), Windows plug_closing_system_error(), and Windows
plug_closing_winsock_error() can easily grow extra special cases if
need be, and each one will only have to live in one place.
2021-11-06 13:28:32 +00:00
|
|
|
static void psocks_plug_closing(Plug *plug, PlugCloseType type,
|
|
|
|
const char *error_msg)
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
{
|
|
|
|
psocks_connection *conn = container_of(plug, psocks_connection, plug);
|
|
|
|
if (conn->connecting) {
|
|
|
|
if (conn->ps->log_flags & LOG_CONNSTATUS)
|
|
|
|
psocks_conn_log(conn, "unable to connect: %s", error_msg);
|
|
|
|
|
|
|
|
chan_open_failed(conn->chan, error_msg);
|
|
|
|
conn->eof_socket_to_pfmgr = true;
|
|
|
|
conn->eof_pfmgr_to_socket = true;
|
|
|
|
conn->connecting = false;
|
|
|
|
} else {
|
|
|
|
if (conn->ps->log_flags & LOG_DIALOGUE)
|
|
|
|
psocks_conn_log(conn, "recv eof");
|
|
|
|
|
|
|
|
chan_send_eof(conn->chan);
|
|
|
|
conn->eof_socket_to_pfmgr = true;
|
|
|
|
}
|
|
|
|
queue_toplevel_callback(psocks_check_close, conn);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void psocks_plug_receive(Plug *plug, int urgent,
|
|
|
|
const char *data, size_t len)
|
|
|
|
{
|
|
|
|
psocks_connection *conn = container_of(plug, psocks_connection, plug);
|
|
|
|
size_t bufsize = chan_send(conn->chan, false, data, len);
|
|
|
|
sk_set_frozen(conn->socket, bufsize > BUFLIMIT);
|
|
|
|
|
|
|
|
psocks_conn_log_data(conn, DN, data, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void psocks_plug_sent(Plug *plug, size_t bufsize)
|
|
|
|
{
|
|
|
|
psocks_connection *conn = container_of(plug, psocks_connection, plug);
|
|
|
|
sk_set_frozen(conn->socket, bufsize > BUFLIMIT);
|
|
|
|
}
|
|
|
|
|
|
|
|
psocks_state *psocks_new(const PsocksPlatform *platform)
|
|
|
|
{
|
|
|
|
psocks_state *ps = snew(psocks_state);
|
|
|
|
memset(ps, 0, sizeof(*ps));
|
|
|
|
|
|
|
|
ps->listen_port = 1080;
|
|
|
|
ps->acceptall = false;
|
|
|
|
|
|
|
|
ps->cl.vt = &psocks_clvt;
|
|
|
|
ps->portfwdmgr = portfwdmgr_new(&ps->cl);
|
|
|
|
|
|
|
|
ps->logging_fp = stderr; /* could make this configurable later */
|
|
|
|
ps->log_flags = LOG_CONNSTATUS;
|
|
|
|
ps->rec_dest = REC_NONE;
|
|
|
|
ps->platform = platform;
|
|
|
|
|
|
|
|
return ps;
|
|
|
|
}
|
|
|
|
|
|
|
|
void psocks_free(psocks_state *ps)
|
|
|
|
{
|
|
|
|
portfwdmgr_free(ps->portfwdmgr);
|
|
|
|
sfree(ps->rec_cmd);
|
|
|
|
sfree(ps);
|
|
|
|
}
|
|
|
|
|
New abstraction for command-line arguments.
This begins the process of enabling our Windows applications to handle
Unicode characters on their command lines which don't fit in the
system code page.
Instead of passing plain strings to cmdline_process_param, we now pass
a partially opaque and platform-specific thing called a CmdlineArg.
This has a method that extracts the argument word as a default-encoded
string, and another one that tries to extract it as UTF-8 (though it
may fail if the UTF-8 isn't available).
On Windows, the command line is now constructed by calling
split_into_argv_w on the Unicode command line returned by
GetCommandLineW(), and the UTF-8 method returns text converted
directly from that wide-character form, not going via the system code
page. So it _can_ include UTF-8 characters that wouldn't have
round-tripped via CP_ACP.
This commit introduces the abstraction and switches over the
cross-platform and Windows argv-handling code to use it, with minimal
functional change. Nothing yet tries to call cmdline_arg_get_utf8().
I say 'cross-platform and Windows' because on the Unix side there's
still a lot of use of plain old argv which I haven't converted. That
would be a much larger project, and isn't currently needed: the
_current_ aim of this abstraction is to get the right things to happen
relating to Unicode on Windows, so for code that doesn't run on
Windows anyway, it's not adding value. (Also there's a tension with
GTK, which wants to talk to standard argv and extract arguments _it_
knows about, so at the very least we'd have to let it munge argv
before importing it into this new system.)
2024-09-25 09:18:38 +00:00
|
|
|
void psocks_cmdline(psocks_state *ps, CmdlineArgList *arglist)
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
{
|
|
|
|
bool doing_opts = true;
|
New abstraction for command-line arguments.
This begins the process of enabling our Windows applications to handle
Unicode characters on their command lines which don't fit in the
system code page.
Instead of passing plain strings to cmdline_process_param, we now pass
a partially opaque and platform-specific thing called a CmdlineArg.
This has a method that extracts the argument word as a default-encoded
string, and another one that tries to extract it as UTF-8 (though it
may fail if the UTF-8 isn't available).
On Windows, the command line is now constructed by calling
split_into_argv_w on the Unicode command line returned by
GetCommandLineW(), and the UTF-8 method returns text converted
directly from that wide-character form, not going via the system code
page. So it _can_ include UTF-8 characters that wouldn't have
round-tripped via CP_ACP.
This commit introduces the abstraction and switches over the
cross-platform and Windows argv-handling code to use it, with minimal
functional change. Nothing yet tries to call cmdline_arg_get_utf8().
I say 'cross-platform and Windows' because on the Unix side there's
still a lot of use of plain old argv which I haven't converted. That
would be a much larger project, and isn't currently needed: the
_current_ aim of this abstraction is to get the right things to happen
relating to Unicode on Windows, so for code that doesn't run on
Windows anyway, it's not adding value. (Also there's a tension with
GTK, which wants to talk to standard argv and extract arguments _it_
knows about, so at the very least we'd have to let it munge argv
before importing it into this new system.)
2024-09-25 09:18:38 +00:00
|
|
|
size_t arglistpos = 0;
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
size_t args_seen = 0;
|
|
|
|
|
New abstraction for command-line arguments.
This begins the process of enabling our Windows applications to handle
Unicode characters on their command lines which don't fit in the
system code page.
Instead of passing plain strings to cmdline_process_param, we now pass
a partially opaque and platform-specific thing called a CmdlineArg.
This has a method that extracts the argument word as a default-encoded
string, and another one that tries to extract it as UTF-8 (though it
may fail if the UTF-8 isn't available).
On Windows, the command line is now constructed by calling
split_into_argv_w on the Unicode command line returned by
GetCommandLineW(), and the UTF-8 method returns text converted
directly from that wide-character form, not going via the system code
page. So it _can_ include UTF-8 characters that wouldn't have
round-tripped via CP_ACP.
This commit introduces the abstraction and switches over the
cross-platform and Windows argv-handling code to use it, with minimal
functional change. Nothing yet tries to call cmdline_arg_get_utf8().
I say 'cross-platform and Windows' because on the Unix side there's
still a lot of use of plain old argv which I haven't converted. That
would be a much larger project, and isn't currently needed: the
_current_ aim of this abstraction is to get the right things to happen
relating to Unicode on Windows, so for code that doesn't run on
Windows anyway, it's not adding value. (Also there's a tension with
GTK, which wants to talk to standard argv and extract arguments _it_
knows about, so at the very least we'd have to let it munge argv
before importing it into this new system.)
2024-09-25 09:18:38 +00:00
|
|
|
while (arglist->args[arglistpos]) {
|
|
|
|
CmdlineArg *arg = arglist->args[arglistpos++];
|
|
|
|
const char *p = cmdline_arg_to_str(arg);
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
|
|
|
|
if (doing_opts && p[0] == '-' && p[1]) {
|
|
|
|
if (!strcmp(p, "--")) {
|
|
|
|
doing_opts = false;
|
|
|
|
} else if (!strcmp(p, "-g")) {
|
|
|
|
ps->acceptall = true;
|
|
|
|
} else if (!strcmp(p, "-d")) {
|
|
|
|
ps->log_flags |= LOG_DIALOGUE;
|
|
|
|
} else if (!strcmp(p, "-f")) {
|
|
|
|
ps->rec_dest = REC_FILE;
|
|
|
|
} else if (!strcmp(p, "-p")) {
|
|
|
|
if (!ps->platform->open_pipes) {
|
|
|
|
fprintf(stderr, "psocks: '-p' is not supported on this "
|
|
|
|
"platform\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
New abstraction for command-line arguments.
This begins the process of enabling our Windows applications to handle
Unicode characters on their command lines which don't fit in the
system code page.
Instead of passing plain strings to cmdline_process_param, we now pass
a partially opaque and platform-specific thing called a CmdlineArg.
This has a method that extracts the argument word as a default-encoded
string, and another one that tries to extract it as UTF-8 (though it
may fail if the UTF-8 isn't available).
On Windows, the command line is now constructed by calling
split_into_argv_w on the Unicode command line returned by
GetCommandLineW(), and the UTF-8 method returns text converted
directly from that wide-character form, not going via the system code
page. So it _can_ include UTF-8 characters that wouldn't have
round-tripped via CP_ACP.
This commit introduces the abstraction and switches over the
cross-platform and Windows argv-handling code to use it, with minimal
functional change. Nothing yet tries to call cmdline_arg_get_utf8().
I say 'cross-platform and Windows' because on the Unix side there's
still a lot of use of plain old argv which I haven't converted. That
would be a much larger project, and isn't currently needed: the
_current_ aim of this abstraction is to get the right things to happen
relating to Unicode on Windows, so for code that doesn't run on
Windows anyway, it's not adding value. (Also there's a tension with
GTK, which wants to talk to standard argv and extract arguments _it_
knows about, so at the very least we'd have to let it munge argv
before importing it into this new system.)
2024-09-25 09:18:38 +00:00
|
|
|
if (arglist->args[arglistpos] > 0) {
|
|
|
|
ps->rec_cmd = dupstr(
|
|
|
|
cmdline_arg_to_str(arglist->args[arglistpos++]));
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
} else {
|
|
|
|
fprintf(stderr, "psocks: expected an argument to '-p'\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
ps->rec_dest = REC_PIPE;
|
|
|
|
} else if (!strcmp(p, "--exec")) {
|
|
|
|
if (!ps->platform->start_subcommand) {
|
|
|
|
fprintf(stderr, "psocks: running a subcommand is not "
|
|
|
|
"supported on this platform\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
New abstraction for command-line arguments.
This begins the process of enabling our Windows applications to handle
Unicode characters on their command lines which don't fit in the
system code page.
Instead of passing plain strings to cmdline_process_param, we now pass
a partially opaque and platform-specific thing called a CmdlineArg.
This has a method that extracts the argument word as a default-encoded
string, and another one that tries to extract it as UTF-8 (though it
may fail if the UTF-8 isn't available).
On Windows, the command line is now constructed by calling
split_into_argv_w on the Unicode command line returned by
GetCommandLineW(), and the UTF-8 method returns text converted
directly from that wide-character form, not going via the system code
page. So it _can_ include UTF-8 characters that wouldn't have
round-tripped via CP_ACP.
This commit introduces the abstraction and switches over the
cross-platform and Windows argv-handling code to use it, with minimal
functional change. Nothing yet tries to call cmdline_arg_get_utf8().
I say 'cross-platform and Windows' because on the Unix side there's
still a lot of use of plain old argv which I haven't converted. That
would be a much larger project, and isn't currently needed: the
_current_ aim of this abstraction is to get the right things to happen
relating to Unicode on Windows, so for code that doesn't run on
Windows anyway, it's not adding value. (Also there's a tension with
GTK, which wants to talk to standard argv and extract arguments _it_
knows about, so at the very least we'd have to let it munge argv
before importing it into this new system.)
2024-09-25 09:18:38 +00:00
|
|
|
if (!arglist->args[arglistpos]) {
|
|
|
|
fprintf(stderr, "psocks: --exec requires a command\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
/* Now consume all further argv words for the
|
|
|
|
* subcommand, even if they look like options */
|
New abstraction for command-line arguments.
This begins the process of enabling our Windows applications to handle
Unicode characters on their command lines which don't fit in the
system code page.
Instead of passing plain strings to cmdline_process_param, we now pass
a partially opaque and platform-specific thing called a CmdlineArg.
This has a method that extracts the argument word as a default-encoded
string, and another one that tries to extract it as UTF-8 (though it
may fail if the UTF-8 isn't available).
On Windows, the command line is now constructed by calling
split_into_argv_w on the Unicode command line returned by
GetCommandLineW(), and the UTF-8 method returns text converted
directly from that wide-character form, not going via the system code
page. So it _can_ include UTF-8 characters that wouldn't have
round-tripped via CP_ACP.
This commit introduces the abstraction and switches over the
cross-platform and Windows argv-handling code to use it, with minimal
functional change. Nothing yet tries to call cmdline_arg_get_utf8().
I say 'cross-platform and Windows' because on the Unix side there's
still a lot of use of plain old argv which I haven't converted. That
would be a much larger project, and isn't currently needed: the
_current_ aim of this abstraction is to get the right things to happen
relating to Unicode on Windows, so for code that doesn't run on
Windows anyway, it's not adding value. (Also there's a tension with
GTK, which wants to talk to standard argv and extract arguments _it_
knows about, so at the very least we'd have to let it munge argv
before importing it into this new system.)
2024-09-25 09:18:38 +00:00
|
|
|
ps->platform->found_subcommand(arglist->args[arglistpos]);
|
|
|
|
ps->got_subcmd = true;
|
|
|
|
break;
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
} else if (!strcmp(p, "--help")) {
|
2021-04-08 00:06:06 +00:00
|
|
|
printf("usage: psocks [ -d ] [ -f");
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
if (ps->platform->open_pipes)
|
|
|
|
printf(" | -p pipe-cmd");
|
|
|
|
printf(" ] [ -g ] port-number");
|
|
|
|
printf("\n");
|
|
|
|
printf("where: -d log all connection contents to"
|
|
|
|
" standard output\n");
|
|
|
|
printf(" -f record each half-connection to "
|
|
|
|
"a file sockin.N/sockout.N\n");
|
|
|
|
if (ps->platform->open_pipes)
|
|
|
|
printf(" -p pipe-cmd pipe each half-connection"
|
|
|
|
" to 'pipe-cmd [in|out] N'\n");
|
|
|
|
printf(" -g accept connections from anywhere,"
|
|
|
|
" not just localhost\n");
|
|
|
|
if (ps->platform->start_subcommand)
|
|
|
|
printf(" --exec subcmd [args...] run command, and "
|
|
|
|
"terminate when it exits\n");
|
|
|
|
printf(" port-number listen on this port"
|
|
|
|
" (default 1080)\n");
|
|
|
|
printf("also: psocks --help display this help text\n");
|
|
|
|
exit(0);
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "psocks: unrecognised option '%s'\n", p);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
} else {
|
New abstraction for command-line arguments.
This begins the process of enabling our Windows applications to handle
Unicode characters on their command lines which don't fit in the
system code page.
Instead of passing plain strings to cmdline_process_param, we now pass
a partially opaque and platform-specific thing called a CmdlineArg.
This has a method that extracts the argument word as a default-encoded
string, and another one that tries to extract it as UTF-8 (though it
may fail if the UTF-8 isn't available).
On Windows, the command line is now constructed by calling
split_into_argv_w on the Unicode command line returned by
GetCommandLineW(), and the UTF-8 method returns text converted
directly from that wide-character form, not going via the system code
page. So it _can_ include UTF-8 characters that wouldn't have
round-tripped via CP_ACP.
This commit introduces the abstraction and switches over the
cross-platform and Windows argv-handling code to use it, with minimal
functional change. Nothing yet tries to call cmdline_arg_get_utf8().
I say 'cross-platform and Windows' because on the Unix side there's
still a lot of use of plain old argv which I haven't converted. That
would be a much larger project, and isn't currently needed: the
_current_ aim of this abstraction is to get the right things to happen
relating to Unicode on Windows, so for code that doesn't run on
Windows anyway, it's not adding value. (Also there's a tension with
GTK, which wants to talk to standard argv and extract arguments _it_
knows about, so at the very least we'd have to let it munge argv
before importing it into this new system.)
2024-09-25 09:18:38 +00:00
|
|
|
switch (args_seen++) {
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
case 0:
|
|
|
|
ps->listen_port = atoi(p);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fprintf(stderr, "psocks: unexpected extra argument '%s'\n", p);
|
|
|
|
exit(1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void psocks_start(psocks_state *ps)
|
|
|
|
{
|
|
|
|
Conf *conf = conf_new();
|
|
|
|
conf_set_bool(conf, CONF_lport_acceptall, ps->acceptall);
|
|
|
|
char *key = dupprintf("AL%d", ps->listen_port);
|
|
|
|
conf_set_str_str(conf, CONF_portfwd, key, "D");
|
|
|
|
sfree(key);
|
|
|
|
|
|
|
|
portfwdmgr_config(ps->portfwdmgr, conf);
|
|
|
|
|
New abstraction for command-line arguments.
This begins the process of enabling our Windows applications to handle
Unicode characters on their command lines which don't fit in the
system code page.
Instead of passing plain strings to cmdline_process_param, we now pass
a partially opaque and platform-specific thing called a CmdlineArg.
This has a method that extracts the argument word as a default-encoded
string, and another one that tries to extract it as UTF-8 (though it
may fail if the UTF-8 isn't available).
On Windows, the command line is now constructed by calling
split_into_argv_w on the Unicode command line returned by
GetCommandLineW(), and the UTF-8 method returns text converted
directly from that wide-character form, not going via the system code
page. So it _can_ include UTF-8 characters that wouldn't have
round-tripped via CP_ACP.
This commit introduces the abstraction and switches over the
cross-platform and Windows argv-handling code to use it, with minimal
functional change. Nothing yet tries to call cmdline_arg_get_utf8().
I say 'cross-platform and Windows' because on the Unix side there's
still a lot of use of plain old argv which I haven't converted. That
would be a much larger project, and isn't currently needed: the
_current_ aim of this abstraction is to get the right things to happen
relating to Unicode on Windows, so for code that doesn't run on
Windows anyway, it's not adding value. (Also there's a tension with
GTK, which wants to talk to standard argv and extract arguments _it_
knows about, so at the very least we'd have to let it munge argv
before importing it into this new system.)
2024-09-25 09:18:38 +00:00
|
|
|
if (ps->got_subcmd)
|
|
|
|
ps->platform->start_subcommand();
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
|
|
|
|
conf_free(conf);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Some stubs that are needed to link against PuTTY modules.
|
|
|
|
*/
|
|
|
|
|
Reorganise host key checking and confirmation.
Previously, checking the host key against the persistent cache managed
by the storage.h API was done as part of the seat_verify_ssh_host_key
method, i.e. separately by each Seat.
Now that check is done by verify_ssh_host_key(), which is a new
function in ssh/common.c that centralises all the parts of host key
checking that don't need an interactive prompt. It subsumes the
previous verify_ssh_manual_host_key() that checked against the Conf,
and it does the check against the storage API that each Seat was
previously doing separately. If it can't confirm or definitively
reject the host key by itself, _then_ it calls out to the Seat, once
an interactive prompt is definitely needed.
The main point of doing this is so that when SshProxy forwards a Seat
call from the proxy SSH connection to the primary Seat, it won't print
an announcement of which connection is involved unless it's actually
going to do something interactive. (Not that we're printing those
announcements _yet_ anyway, but this is a piece of groundwork that
works towards doing so.)
But while I'm at it, I've also taken the opportunity to clean things
up a bit by renaming functions sensibly. Previously we had three very
similarly named functions verify_ssh_manual_host_key(), SeatVtable's
'verify_ssh_host_key' method, and verify_host_key() in storage.h. Now
the Seat method is called 'confirm' rather than 'verify' (since its
job is now always to print an interactive prompt, so it looks more
like the other confirm_foo methods), and the storage.h function is
called check_stored_host_key(), which goes better with store_host_key
and avoids having too many functions with similar names. And the
'manual' function is subsumed into the new centralised code, so
there's now just *one* host key function with 'verify' in the name.
Several functions are reindented in this commit. Best viewed with
whitespace changes ignored.
2021-10-25 17:12:17 +00:00
|
|
|
int check_stored_host_key(const char *hostname, int port,
|
|
|
|
const char *keytype, const char *key)
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
{
|
|
|
|
unreachable("host keys not handled in this tool");
|
|
|
|
}
|
|
|
|
|
2022-09-13 07:49:38 +00:00
|
|
|
void store_host_key(Seat *seat, const char *hostname, int port,
|
Auxiliary application: 'psocks', a simple SOCKS server.
This is built more or less entirely out of pieces I already had. The
SOCKS server code is provided by the dynamic forwarding code in
portfwd.c. When that accepts a connection request, it wants to talk to
an SSH ConnectionLayer, which is already a trait with interchangeable
implementations - so I just provide one of my own which only supports
the lportfwd_open() method. And that in turn returns an SshChannel
object, with a special trait implementation all of whose methods
just funnel back to an ordinary Socket.
Result: you get a Socket-to-Socket SOCKS implementation with no SSH
anywhere, and even a minimal amount of need to _pretend_ internally to
be an SSH implementation.
Additional features include the ability to log all the traffic in the
form of diagnostics to standard error, or log each direction of each
connection separately to a file, or for anything more general, to log
each direction of each connection through a pipe to a subcommand that
can filter out whatever you think are the interesting parts. Also, you
can spawn a subcommand after the SOCKS server is set up, and terminate
automatically when that subcommand does - e.g. you might use this to
wrap the execution of a single SOCKS-using program.
This is a modernisation of a diagnostic utility I've had kicking
around out-of-tree for a long time. With all of last year's
refactorings, it now becomes feasible to keep it in-tree without
needing huge amounts of scaffolding. Also, this version runs on
Windows, which is more than the old one did. (On Windows I haven't
implemented the subprocess parts, although there's no reason I
_couldn't_.)
As well as diagnostic uses, this may also be useful in some situations
as a thing to forward ports to: PuTTY doesn't currently support
reverse dynamic port forwarding (in which the remote listening port
acts as a SOCKS server), but you could get the same effect by
forwarding a remote port to a local instance of this. (Although, of
course, that's nothing you couldn't achieve using any other SOCKS
server.)
2020-02-23 16:27:04 +00:00
|
|
|
const char *keytype, const char *key)
|
|
|
|
{
|
|
|
|
unreachable("host keys not handled in this tool");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* stdio-targeted PsocksDataSink.
|
|
|
|
*/
|
|
|
|
typedef struct PsocksDataSinkStdio {
|
|
|
|
stdio_sink sink[2];
|
|
|
|
PsocksDataSink pds;
|
|
|
|
} PsocksDataSinkStdio;
|
|
|
|
|
|
|
|
static void stdio_free(PsocksDataSink *pds)
|
|
|
|
{
|
|
|
|
PsocksDataSinkStdio *pdss = container_of(pds, PsocksDataSinkStdio, pds);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 2; i++)
|
|
|
|
fclose(pdss->sink[i].fp);
|
|
|
|
|
|
|
|
sfree(pdss);
|
|
|
|
}
|
|
|
|
|
|
|
|
PsocksDataSink *pds_stdio(FILE *fp[2])
|
|
|
|
{
|
|
|
|
PsocksDataSinkStdio *pdss = snew(PsocksDataSinkStdio);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 2; i++) {
|
|
|
|
setvbuf(fp[i], NULL, _IONBF, 0);
|
|
|
|
stdio_sink_init(&pdss->sink[i], fp[i]);
|
|
|
|
pdss->pds.s[i] = BinarySink_UPCAST(&pdss->sink[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
pdss->pds.free = stdio_free;
|
|
|
|
|
|
|
|
return &pdss->pds;
|
|
|
|
}
|