1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-08 08:58:00 +00:00

Uppity: add stunt for unauthorised agent forwarding attempts.

With the new --open-unconditional-agent-socket option, every time
Uppity receives an SSH connection, it will immediately open a Unix-
domain socket and attempt to do agent forwarding on it, in the sense
that any connection to that socket will be turned into an
"auth-agent@openssh.com" CHANNEL_OPEN request on whichever SSH
connection it was associated with.

That connection-global socket is independent of any that are created
as part of setting up a session channel. The pathname of the socket
file is written to the server's event log (there being no other
sensible place to send it).

The aim is that this allows me to test the behaviour of an SSH client
if the server tries to open an agent-forwarding channel outside the
usual context. In particular, it allows me to test the change I just
made in the previous commit, that if you enable agent forwarding in
the client configuration, then auth-agent channels opened by the
server are accepted even if no session channel opened by the client
has sent an auth-agent-req. More importantly, it allows me to check
that I _haven't_ accidentally arranged that those channels are
accepted even when agent forwarding is _not_ permitted by the client
configuration!

Implementation details: the agent forwarding socket was previously
implemented as part of the internal sesschan structure. I've moved it
out into a little sub-struct of its own which can be created
independently of a sesschan.
This commit is contained in:
Simon Tatham 2020-12-23 22:26:44 +00:00
parent b4e1110892
commit e9e6c03c6e
4 changed files with 71 additions and 21 deletions

View File

@ -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(

View File

@ -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);

View File

@ -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);

View File

@ -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);