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:
parent
b4e1110892
commit
e9e6c03c6e
70
sesschan.c
70
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(
|
||||
|
15
sshserver.c
15
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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user