diff --git a/sesschan.c b/sesschan.c index 7e735ddc..0cf85b3b 100644 --- a/sesschan.c +++ b/sesschan.c @@ -13,6 +13,12 @@ #include "sshserver.h" #include "sftp.h" +struct agentfwd { + ConnectionLayer *cl; + Socket *socket; + Plug plug; +}; + typedef struct sesschan { SshChannel *c; @@ -35,8 +41,7 @@ typedef struct sesschan { int n_x11_sockets; Socket *x11_sockets[MAX_X11_SOCKETS]; - Plug agentfwd_plug; - Socket *agentfwd_socket; + agentfwd *agent; Backend *backend; @@ -248,8 +253,8 @@ static void sesschan_free(Channel *chan) sftpsrv_free(sess->sftpsrv); for (i = 0; i < sess->n_x11_sockets; i++) sk_close(sess->x11_sockets[i]); - if (sess->agentfwd_socket) - sk_close(sess->agentfwd_socket); + if (sess->agent) + agentfwd_free(sess->agent); sfree(sess); } @@ -437,19 +442,19 @@ bool sesschan_enable_x11_forwarding( static int agentfwd_accepting( Plug *p, accept_fn_t constructor, accept_ctx_t ctx) { - sesschan *sess = container_of(p, sesschan, agentfwd_plug); + agentfwd *agent = container_of(p, agentfwd, plug); Plug *plug; Channel *chan; Socket *s; const char *err; - chan = portfwd_raw_new(sess->c->cl, &plug, false); + chan = portfwd_raw_new(agent->cl, &plug, false); s = constructor(ctx, plug); if ((err = sk_socket_error(s)) != NULL) { portfwd_raw_free(chan); return 1; } - portfwd_raw_setup(chan, s, ssh_serverside_agent_open(sess->c->cl, chan)); + portfwd_raw_setup(chan, s, ssh_serverside_agent_open(agent->cl, chan)); return 0; } @@ -460,28 +465,51 @@ static const PlugVtable agentfwd_plugvt = { .accepting = agentfwd_accepting, }; +agentfwd *agentfwd_new(ConnectionLayer *cl, char **socketname_out) +{ + agentfwd *agent = snew(agentfwd); + agent->cl = cl; + agent->plug.vt = &agentfwd_plugvt; + + char *dir_prefix = dupprintf("/tmp/%s-agentfwd", appname); + char *error = NULL, *socketname = NULL; + agent->socket = platform_make_agent_socket( + &agent->plug, dir_prefix, &error, &socketname); + sfree(dir_prefix); + sfree(error); + + if (!agent->socket) { + sfree(agent); + sfree(socketname); + return NULL; + } + + *socketname_out = socketname; + return agent; +} + +void agentfwd_free(agentfwd *agent) +{ + if (agent->socket) + sk_close(agent->socket); + sfree(agent); +} + bool sesschan_enable_agent_forwarding(Channel *chan) { sesschan *sess = container_of(chan, sesschan, chan); - char *error, *socketname, *dir_prefix; + char *socketname; - dir_prefix = dupprintf("/tmp/%s-agentfwd", appname); + assert(!sess->agent); - sess->agentfwd_plug.vt = &agentfwd_plugvt; - sess->agentfwd_socket = platform_make_agent_socket( - &sess->agentfwd_plug, dir_prefix, &error, &socketname); + sess->agent = agentfwd_new(sess->c->cl, &socketname); - sfree(dir_prefix); + if (!sess->agent) + return false; - if (sess->agentfwd_socket) { - conf_set_str_str(sess->conf, CONF_environmt, - "SSH_AUTH_SOCK", socketname); - } - - sfree(error); + conf_set_str_str(sess->conf, CONF_environmt, "SSH_AUTH_SOCK", socketname); sfree(socketname); - - return sess->agentfwd_socket != NULL; + return true; } bool sesschan_allocate_pty( diff --git a/sshserver.c b/sshserver.c index d196ab70..cc1c880d 100644 --- a/sshserver.c +++ b/sshserver.c @@ -46,6 +46,8 @@ struct server { LogPolicy *logpolicy; const SftpServerVtable *sftpserver_vt; + agentfwd *stunt_agentfwd; + Seat seat; Ssh ssh; struct ssh_version_receiver version_receiver; @@ -320,6 +322,9 @@ static void ssh_server_free_callback(void *vsrv) if (srv->socket) sk_close(srv->socket); + if (srv->stunt_agentfwd) + agentfwd_free(srv->stunt_agentfwd); + if (srv->base_layer) ssh_ppl_free(srv->base_layer); if (srv->bpp) @@ -569,6 +574,16 @@ static void server_got_ssh_version(struct ssh_version_receiver *rcv, srv->pinger = pinger_new(srv->conf, &srv->backend); #endif + if (srv->ssc->stunt_open_unconditional_agent_socket) { + char *socketname; + srv->stunt_agentfwd = agentfwd_new(srv->cl, &socketname); + if (srv->stunt_agentfwd) { + logeventf(srv->logctx, "opened unconditional agent socket at %s\n", + socketname); + sfree(socketname); + } + } + queue_idempotent_callback(&srv->bpp->ic_in_raw); ssh_ppl_process_queue(srv->base_layer); diff --git a/sshserver.h b/sshserver.h index 358f24af..5cc393df 100644 --- a/sshserver.h +++ b/sshserver.h @@ -20,6 +20,7 @@ struct SshServerConfig { bool bare_connection; bool stunt_pretend_to_accept_any_pubkey; + bool stunt_open_unconditional_agent_socket; }; Plug *ssh_server_plug( @@ -136,3 +137,7 @@ Conf *make_ssh_server_conf(void); /* Provided by Unix front end programs to uxsftpserver.c */ void make_unix_sftp_filehandle_key(void *data, size_t size); + +typedef struct agentfwd agentfwd; +agentfwd *agentfwd_new(ConnectionLayer *cl, char **socketname_out); +void agentfwd_free(agentfwd *agent); diff --git a/unix/uxserver.c b/unix/uxserver.c index 3ff01409..448c6515 100644 --- a/unix/uxserver.c +++ b/unix/uxserver.c @@ -783,6 +783,8 @@ int main(int argc, char **argv) conf_set_int(conf, CONF_logxfovr, LGXF_OVR); } else if (!strcmp(arg, "--pretend-to-accept-any-pubkey")) { ssc.stunt_pretend_to_accept_any_pubkey = true; + } else if (!strcmp(arg, "--open-unconditional-agent-socket")) { + ssc.stunt_open_unconditional_agent_socket = true; } else { fprintf(stderr, "%s: unrecognised option '%s'\n", appname, arg); exit(1);