1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Add exec/subsystem versions of SSH proxying.

This is a simple tweak to the existing in-process SSH jump host
support, where instead of opening a direct-tcpip channel to the
destination host, we open a session channel and run a process in it to
make the connection to the destination.

So, where the existing jump host support replaced a local proxy
command along the lines of "plink %proxyhost -nc %host %port", this
one replaces "plink %proxyhost run-some-command".

Also added a corresponding option to use a subsystem to make the
connection. (Someone could configure an SSH server to support specific
subsystem names for particular destinations, or a general schema of
subsystem names that include the destination address in some standard
format.)

To avoid overflowing the already-full Proxy config panel with an extra
subtype selector, I've put these in as additional top-level proxy
types, so that instead of just PROXY_SSH we now have three
PROXY_SSH_foo.
This commit is contained in:
Simon Tatham 2022-04-22 14:12:15 +01:00
parent 2a26ebd0d5
commit 6f7c52dcce
4 changed files with 50 additions and 9 deletions

View File

@ -1738,7 +1738,9 @@ void proxy_type_handler(union control *ctrl, dlgparam *dlg,
ADD(PROXY_SOCKS4, "SOCKS 4");
ADD(PROXY_HTTP, "HTTP CONNECT");
if (ssh_proxy_supported) {
ADD(PROXY_SSH, "SSH to proxy and use port forwarding");
ADD(PROXY_SSH_TCPIP, "SSH to proxy and use port forwarding");
ADD(PROXY_SSH_EXEC, "SSH to proxy and execute a command");
ADD(PROXY_SSH_SUBSYSTEM, "SSH to proxy and invoke a subsystem");
}
if (ctrl->generic.context.i & PROXY_UI_FLAG_LOCAL) {
ADD(PROXY_CMD, "Local (run a subprogram to connect)");

View File

@ -499,7 +499,9 @@ Socket *new_connection(SockAddr *addr, const char *hostname,
char *proxy_canonical_name;
Socket *sret;
if (type == PROXY_SSH &&
if ((type == PROXY_SSH_TCPIP ||
type == PROXY_SSH_EXEC ||
type == PROXY_SSH_SUBSYSTEM) &&
(sret = sshproxy_new_connection(addr, hostname, port, privport,
oobinline, nodelay, keepalive,
plug, conf, itr)) != NULL)

View File

@ -10,6 +10,7 @@
#include "ssh.h"
#include "network.h"
#include "storage.h"
#include "proxy.h"
const bool ssh_proxy_supported = true;
@ -636,12 +637,47 @@ Socket *sshproxy_new_connection(SockAddr *addr, const char *hostname,
*/
conf_set_bool(sp->conf, CONF_ssh_simple, true);
/*
* Configure the main channel of this SSH session to be a
* direct-tcpip connection to the destination host/port.
*/
conf_set_str(sp->conf, CONF_ssh_nc_host, hostname);
conf_set_int(sp->conf, CONF_ssh_nc_port, port);
int proxy_type = conf_get_int(clientconf, CONF_proxy_type);
switch (proxy_type) {
case PROXY_SSH_TCPIP:
/*
* Configure the main channel of this SSH session to be a
* direct-tcpip connection to the destination host/port.
*/
conf_set_str(sp->conf, CONF_ssh_nc_host, hostname);
conf_set_int(sp->conf, CONF_ssh_nc_port, port);
break;
case PROXY_SSH_SUBSYSTEM:
case PROXY_SSH_EXEC: {
Conf *cmd_conf = conf_copy(clientconf);
/*
* Unlike the Telnet and Local proxy types, we don't use the
* proxy username and password fields in the formatted
* command, because if we use them at all, it's for
* authenticating to the proxy SSH server.
*/
conf_set_str(cmd_conf, CONF_proxy_username, "");
conf_set_str(cmd_conf, CONF_proxy_password, "");
char *cmd = format_telnet_command(sp->addr, sp->port, cmd_conf, NULL);
conf_free(cmd_conf);
conf_set_str(sp->conf, CONF_remote_cmd, cmd);
sfree(cmd);
conf_set_bool(sp->conf, CONF_nopty, true);
if (proxy_type == PROXY_SSH_SUBSYSTEM)
conf_set_bool(sp->conf, CONF_ssh_subsys, true);
break;
}
default:
unreachable("bad SSH proxy type");
}
sp->logctx = log_init(&sp->logpolicy, sp->conf);

View File

@ -475,7 +475,8 @@ enum {
* Proxy types.
*/
PROXY_NONE, PROXY_SOCKS4, PROXY_SOCKS5,
PROXY_HTTP, PROXY_TELNET, PROXY_CMD, PROXY_SSH,
PROXY_HTTP, PROXY_TELNET, PROXY_CMD, PROXY_SSH_TCPIP,
PROXY_SSH_EXEC, PROXY_SSH_SUBSYSTEM,
PROXY_FUZZ
};