зеркало из https://github.com/github/putty.git
Low-level API to open nonstandard port forwardings.
The new portfwdmgr_connect_socket() works basically like the existing portfwdmgr_connect(), in that it opens an SSH forwarding channel and gateways it to a Socket. But where portfwdmgr_connect() started from a (hostname,port) pair and used mgr->conf to inform name lookup and proxy settings, portfwdmgr_connect_socket() simply takes a callback that it will call when it wants you to make a Socket for a given Plug, and that callback can make any kind of Socket it likes. The idea is that this way you can make port forwardings that talk to things other than genuine TCP connections, by simply providing an appropriate callback. My immediate use case for this is for agent forwarding, and will appear in the next commit. But it's easy to imagine other purposes you might use a thing like this for, such as forwarding SSH channels to AF_UNIX sockets in general.
This commit is contained in:
Родитель
e5107478f3
Коммит
09954a87c2
58
portfwd.c
58
portfwd.c
|
@ -1120,6 +1120,19 @@ bool portfwdmgr_unlisten(PortFwdManager *mgr, const char *host, int port)
|
|||
return true;
|
||||
}
|
||||
|
||||
struct portfwdmgr_connect_ctx {
|
||||
SockAddr *addr;
|
||||
int port;
|
||||
char *canonical_hostname;
|
||||
Conf *conf;
|
||||
};
|
||||
static Socket *portfwdmgr_connect_helper(void *vctx, Plug *plug)
|
||||
{
|
||||
struct portfwdmgr_connect_ctx *ctx = (struct portfwdmgr_connect_ctx *)vctx;
|
||||
return new_connection(ctx->addr, ctx->canonical_hostname, ctx->port,
|
||||
false, true, false, false, plug, ctx->conf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when receiving a PORT OPEN from the server to make a
|
||||
* connection to a destination host.
|
||||
|
@ -1131,26 +1144,39 @@ char *portfwdmgr_connect(PortFwdManager *mgr, Channel **chan_ret,
|
|||
char *hostname, int port, SshChannel *c,
|
||||
int addressfamily)
|
||||
{
|
||||
SockAddr *addr;
|
||||
const char *err;
|
||||
char *dummy_realhost = NULL;
|
||||
struct PortForwarding *pf;
|
||||
struct portfwdmgr_connect_ctx ctx[1];
|
||||
const char *err_retd;
|
||||
char *err_toret;
|
||||
|
||||
/*
|
||||
* Try to find host.
|
||||
*/
|
||||
addr = name_lookup(hostname, port, &dummy_realhost, mgr->conf,
|
||||
addressfamily, NULL, NULL);
|
||||
if ((err = sk_addr_error(addr)) != NULL) {
|
||||
char *err_ret = dupstr(err);
|
||||
sk_addr_free(addr);
|
||||
sfree(dummy_realhost);
|
||||
return err_ret;
|
||||
ctx->addr = name_lookup(hostname, port, &ctx->canonical_hostname,
|
||||
mgr->conf, addressfamily, NULL, NULL);
|
||||
if ((err_retd = sk_addr_error(ctx->addr)) != NULL) {
|
||||
err_toret = dupstr(err_retd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open socket.
|
||||
*/
|
||||
ctx->conf = mgr->conf;
|
||||
ctx->port = port;
|
||||
|
||||
err_toret = portfwdmgr_connect_socket(
|
||||
mgr, chan_ret, portfwdmgr_connect_helper, ctx, c);
|
||||
|
||||
out:
|
||||
sk_addr_free(ctx->addr);
|
||||
sfree(ctx->canonical_hostname);
|
||||
return err_toret;
|
||||
}
|
||||
|
||||
char *portfwdmgr_connect_socket(PortFwdManager *mgr, Channel **chan_ret,
|
||||
Socket *(*connect)(void *, Plug *), void *ctx,
|
||||
SshChannel *c)
|
||||
{
|
||||
struct PortForwarding *pf;
|
||||
const char *err;
|
||||
|
||||
pf = new_portfwd_state();
|
||||
*chan_ret = &pf->chan;
|
||||
pf->plug.vt = &PortForwarding_plugvt;
|
||||
|
@ -1162,9 +1188,7 @@ char *portfwdmgr_connect(PortFwdManager *mgr, Channel **chan_ret,
|
|||
pf->cl = mgr->cl;
|
||||
pf->socks_state = SOCKS_NONE;
|
||||
|
||||
pf->s = new_connection(addr, dummy_realhost, port,
|
||||
false, true, false, false, &pf->plug, mgr->conf);
|
||||
sfree(dummy_realhost);
|
||||
pf->s = connect(ctx, &pf->plug);
|
||||
if ((err = sk_socket_error(pf->s)) != NULL) {
|
||||
char *err_ret = dupstr(err);
|
||||
sk_close(pf->s);
|
||||
|
|
3
ssh.h
3
ssh.h
|
@ -380,6 +380,9 @@ void portfwdmgr_close_all(PortFwdManager *mgr);
|
|||
char *portfwdmgr_connect(PortFwdManager *mgr, Channel **chan_ret,
|
||||
char *hostname, int port, SshChannel *c,
|
||||
int addressfamily);
|
||||
char *portfwdmgr_connect_socket(PortFwdManager *mgr, Channel **chan_ret,
|
||||
Socket *(*connect)(void *, Plug *), void *ctx,
|
||||
SshChannel *c);
|
||||
bool portfwdmgr_listen(PortFwdManager *mgr, const char *host, int port,
|
||||
const char *keyhost, int keyport, Conf *conf);
|
||||
bool portfwdmgr_unlisten(PortFwdManager *mgr, const char *host, int port);
|
||||
|
|
Загрузка…
Ссылка в новой задаче