mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Merge the two low-level portfwd setup systems.
In commit09954a87c
I introduced the portfwdmgr_connect_socket() system, which opened a port forwarding given a callback to create the Socket itself, with the aim of using it to make forwardings to Unix- domain sockets and Windows named pipes (both initially for agent forwarding). But I forgot that a year and a bit ago, in commit834396170
, I already introduced a similar low-level system for creating a PortForwarding around an unusual kind of socket: the portfwd_raw_new() system, which in place of a callback uses a two-phase setup protocol (you create the socket in between the two setup calls, and can roll it back if the socket can't be created). There's really no need to have _both_ these systems! So now I'm merging them, which is to say, I'm enhancing portfwd_raw_new to have the one new feature it needs, and throwing away the newer system completely. The new feature is to be able to control the initial state of the 'ready' flag: portfwd_raw_new was always used for initiating port forwardings in response to an incoming local connection, which means you need to start off with ready=false and set it true when the other end of the SSH connection sends back OPEN_CONFIRMATION. Now it's being used for initiating port forwardings in response to a CHANNEL_OPEN, we need to be able to start with ready=true. This commit reverts09954a87c2
and its followup fix12aa06ccc9
, and simplifies the agent_connect system down to a single trivial function that makes a Socket given a Plug.
This commit is contained in:
parent
600bf247d3
commit
2160205aee
65
portfwd.c
65
portfwd.c
@ -468,7 +468,7 @@ static const struct ChannelVtable PortForwarding_channelvt = {
|
||||
chan_no_request_response,
|
||||
};
|
||||
|
||||
Channel *portfwd_raw_new(ConnectionLayer *cl, Plug **plug)
|
||||
Channel *portfwd_raw_new(ConnectionLayer *cl, Plug **plug, bool start_ready)
|
||||
{
|
||||
struct PortForwarding *pf;
|
||||
|
||||
@ -482,7 +482,7 @@ Channel *portfwd_raw_new(ConnectionLayer *cl, Plug **plug)
|
||||
|
||||
pf->cl = cl;
|
||||
pf->input_wanted = true;
|
||||
pf->ready = false;
|
||||
pf->ready = start_ready;
|
||||
|
||||
pf->socks_state = SOCKS_NONE;
|
||||
pf->hostname = NULL;
|
||||
@ -523,7 +523,7 @@ static int pfl_accepting(Plug *p, accept_fn_t constructor, accept_ctx_t ctx)
|
||||
Socket *s;
|
||||
const char *err;
|
||||
|
||||
chan = portfwd_raw_new(pl->cl, &plug);
|
||||
chan = portfwd_raw_new(pl->cl, &plug, false);
|
||||
s = constructor(ctx, plug);
|
||||
if ((err = sk_socket_error(s)) != NULL) {
|
||||
portfwd_raw_free(chan);
|
||||
@ -1120,20 +1120,6 @@ 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(sk_addr_dup(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.
|
||||
@ -1145,39 +1131,26 @@ char *portfwdmgr_connect(PortFwdManager *mgr, Channel **chan_ret,
|
||||
char *hostname, int port, SshChannel *c,
|
||||
int addressfamily)
|
||||
{
|
||||
struct portfwdmgr_connect_ctx ctx[1];
|
||||
const char *err_retd;
|
||||
char *err_toret;
|
||||
SockAddr *addr;
|
||||
const char *err;
|
||||
char *dummy_realhost = NULL;
|
||||
struct PortForwarding *pf;
|
||||
|
||||
/*
|
||||
* Try to find host.
|
||||
*/
|
||||
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;
|
||||
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->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;
|
||||
|
||||
/*
|
||||
* Open socket.
|
||||
*/
|
||||
pf = new_portfwd_state();
|
||||
*chan_ret = &pf->chan;
|
||||
pf->plug.vt = &PortForwarding_plugvt;
|
||||
@ -1189,7 +1162,9 @@ char *portfwdmgr_connect_socket(PortFwdManager *mgr, Channel **chan_ret,
|
||||
pf->cl = mgr->cl;
|
||||
pf->socks_state = SOCKS_NONE;
|
||||
|
||||
pf->s = connect(ctx, &pf->plug);
|
||||
pf->s = new_connection(addr, dummy_realhost, port,
|
||||
false, true, false, false, &pf->plug, mgr->conf);
|
||||
sfree(dummy_realhost);
|
||||
if ((err = sk_socket_error(pf->s)) != NULL) {
|
||||
char *err_ret = dupstr(err);
|
||||
sk_close(pf->s);
|
||||
|
11
putty.h
11
putty.h
@ -1889,15 +1889,8 @@ void agent_cancel_query(agent_pending_query *);
|
||||
void agent_query_synchronous(strbuf *in, void **out, int *outlen);
|
||||
bool agent_exists(void);
|
||||
|
||||
/* For stream-oriented agent connections, if available: agent_connect
|
||||
* is a callback for use with portfwdmgr_connect_socket, and the
|
||||
* context structure it requires is created and freed by the next two
|
||||
* functions. agent_get_connect_ctx may return NULL if no streaming
|
||||
* agent connection is available at all on this platform. */
|
||||
typedef struct agent_connect_ctx agent_connect_ctx;
|
||||
Socket *agent_connect(void *vctx, Plug *plug);
|
||||
agent_connect_ctx *agent_get_connect_ctx(void);
|
||||
void agent_free_connect_ctx(agent_connect_ctx *ctx);
|
||||
/* For stream-oriented agent connections, if available. */
|
||||
Socket *agent_connect(Plug *plug);
|
||||
|
||||
/*
|
||||
* Exports from wildcard.c
|
||||
|
@ -365,7 +365,7 @@ static int xfwd_accepting(Plug *p, accept_fn_t constructor, accept_ctx_t ctx)
|
||||
SocketPeerInfo *pi;
|
||||
const char *err;
|
||||
|
||||
chan = portfwd_raw_new(sess->c->cl, &plug);
|
||||
chan = portfwd_raw_new(sess->c->cl, &plug, false);
|
||||
s = constructor(ctx, plug);
|
||||
if ((err = sk_socket_error(s)) != NULL) {
|
||||
portfwd_raw_free(chan);
|
||||
@ -441,7 +441,7 @@ static int agentfwd_accepting(
|
||||
Socket *s;
|
||||
const char *err;
|
||||
|
||||
chan = portfwd_raw_new(sess->c->cl, &plug);
|
||||
chan = portfwd_raw_new(sess->c->cl, &plug, false);
|
||||
s = constructor(ctx, plug);
|
||||
if ((err = sk_socket_error(s)) != NULL) {
|
||||
portfwd_raw_free(chan);
|
||||
|
5
ssh.h
5
ssh.h
@ -380,13 +380,10 @@ 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);
|
||||
Channel *portfwd_raw_new(ConnectionLayer *cl, Plug **plug);
|
||||
Channel *portfwd_raw_new(ConnectionLayer *cl, Plug **plug, bool start_ready);
|
||||
void portfwd_raw_free(Channel *pfchan);
|
||||
void portfwd_raw_setup(Channel *pfchan, Socket *s, SshChannel *sc);
|
||||
|
||||
|
@ -168,16 +168,15 @@ bool ssh1_handle_direction_specific_packet(
|
||||
* agent and set up an ordinary port-forwarding type
|
||||
* channel over it.
|
||||
*/
|
||||
agent_connect_ctx *ctx = agent_get_connect_ctx();
|
||||
bool got_stream_connection = false;
|
||||
if (ctx) {
|
||||
char *err = portfwdmgr_connect_socket(
|
||||
s->portfwdmgr, &c->chan, agent_connect, ctx, &c->sc);
|
||||
agent_free_connect_ctx(ctx);
|
||||
if (err == NULL)
|
||||
got_stream_connection = true;
|
||||
}
|
||||
if (!got_stream_connection) {
|
||||
Plug *plug;
|
||||
Channel *ch = portfwd_raw_new(&s->cl, &plug, true);
|
||||
Socket *skt = agent_connect(plug);
|
||||
if (!sk_socket_error(skt)) {
|
||||
portfwd_raw_setup(ch, skt, &c->sc);
|
||||
c->chan = ch;
|
||||
} else {
|
||||
portfwd_raw_free(ch);
|
||||
|
||||
/*
|
||||
* Otherwise, fall back to the old-fashioned system of
|
||||
* parsing the forwarded data stream ourselves for
|
||||
|
@ -99,27 +99,22 @@ static ChanopenResult chan_open_auth_agent(
|
||||
* If possible, make a stream-oriented connection to the agent and
|
||||
* set up an ordinary port-forwarding type channel over it.
|
||||
*/
|
||||
agent_connect_ctx *ctx = agent_get_connect_ctx();
|
||||
if (ctx) {
|
||||
Channel *ch;
|
||||
char *err = portfwdmgr_connect_socket(
|
||||
s->portfwdmgr, &ch, agent_connect, ctx, sc);
|
||||
agent_free_connect_ctx(ctx);
|
||||
Plug *plug;
|
||||
Channel *ch = portfwd_raw_new(&s->cl, &plug, true);
|
||||
Socket *skt = agent_connect(plug);
|
||||
|
||||
if (err == NULL) {
|
||||
CHANOPEN_RETURN_SUCCESS(ch);
|
||||
} else {
|
||||
sfree(err);
|
||||
/* now continue to the fallback case below */
|
||||
}
|
||||
if (!sk_socket_error(skt)) {
|
||||
portfwd_raw_setup(ch, skt, sc);
|
||||
CHANOPEN_RETURN_SUCCESS(ch);
|
||||
} else {
|
||||
portfwd_raw_free(ch);
|
||||
/*
|
||||
* Otherwise, fall back to the old-fashioned system of parsing the
|
||||
* forwarded data stream ourselves for message boundaries, and
|
||||
* passing each individual message to the one-off agent_query().
|
||||
*/
|
||||
CHANOPEN_RETURN_SUCCESS(agentf_new(sc));
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise, fall back to the old-fashioned system of parsing the
|
||||
* forwarded data stream ourselves for message boundaries, and
|
||||
* passing each individual message to the one-off agent_query().
|
||||
*/
|
||||
CHANOPEN_RETURN_SUCCESS(agentf_new(sc));
|
||||
}
|
||||
|
||||
ChanopenResult ssh2_connection_parse_channel_open(
|
||||
|
@ -130,30 +130,12 @@ static const char *agent_socket_path(void)
|
||||
return getenv("SSH_AUTH_SOCK");
|
||||
}
|
||||
|
||||
struct agent_connect_ctx {
|
||||
SockAddr *addr;
|
||||
};
|
||||
|
||||
Socket *agent_connect(void *vctx, Plug *plug)
|
||||
{
|
||||
agent_connect_ctx *ctx = (agent_connect_ctx *)vctx;
|
||||
return sk_new(sk_addr_dup(ctx->addr), 0, false, false, false, false, plug);
|
||||
}
|
||||
|
||||
agent_connect_ctx *agent_get_connect_ctx(void)
|
||||
Socket *agent_connect(Plug *plug)
|
||||
{
|
||||
const char *path = agent_socket_path();
|
||||
if (!path)
|
||||
return NULL;
|
||||
agent_connect_ctx *ctx = snew(agent_connect_ctx);
|
||||
ctx->addr = unix_sock_addr(path);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void agent_free_connect_ctx(agent_connect_ctx *ctx)
|
||||
{
|
||||
sk_addr_free(ctx->addr);
|
||||
sfree(ctx);
|
||||
return new_error_socket_fmt(plug, "SSH_AUTH_SOCK not set");
|
||||
return sk_new(unix_sock_addr(path), 0, false, false, false, false, plug);
|
||||
}
|
||||
|
||||
agent_pending_query *agent_query(
|
||||
|
@ -142,27 +142,12 @@ char *agent_named_pipe_name(void)
|
||||
return pipename;
|
||||
}
|
||||
|
||||
struct agent_connect_ctx {
|
||||
char *pipename;
|
||||
};
|
||||
|
||||
Socket *agent_connect(void *vctx, Plug *plug)
|
||||
Socket *agent_connect(Plug *plug)
|
||||
{
|
||||
agent_connect_ctx *ctx = (agent_connect_ctx *)vctx;
|
||||
return new_named_pipe_client(ctx->pipename, plug);
|
||||
}
|
||||
|
||||
agent_connect_ctx *agent_get_connect_ctx(void)
|
||||
{
|
||||
agent_connect_ctx *ctx = snew(agent_connect_ctx);
|
||||
ctx->pipename = agent_named_pipe_name();
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void agent_free_connect_ctx(agent_connect_ctx *ctx)
|
||||
{
|
||||
sfree(ctx->pipename);
|
||||
sfree(ctx);
|
||||
char *pipename = agent_named_pipe_name();
|
||||
Socket *s = new_named_pipe_client(pipename, plug);
|
||||
sfree(pipename);
|
||||
return s;
|
||||
}
|
||||
|
||||
static bool named_pipe_agent_exists(void)
|
||||
|
Loading…
Reference in New Issue
Block a user