mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-08 08:58:00 +00:00
Relax criteria for accepting agent-forwarding channel-opens.
Previously, the instant at which we send to the server a request to enable agent forwarding (the "auth-agent-req@openssh.com" channel request, or SSH1_CMSG_AGENT_REQUEST_FORWARDING) was also the instant at which we set a flag indicating that we're prepared to accept attempts from the server to open a channel to talk to the forwarded agent. If the server attempts that when we haven't sent a forwarding request, we treat it with suspicion, and reject it. But it turns out that at least one SSH server does this, for what seems to be a _somewhat_ sensible purpose, and OpenSSH accepts it. So, on the basis that the @openssh.com domain suffix makes them the arbiters of this part of the spec, I'm following their practice. I've removed the 'agent_fwd_enabled' flag from both connection layer implementations, together with the ConnectionLayer method that sets it; now agent-forwarding CHANNEL_OPENs are gated only on the questions of whether agent forwarding was permitted in the configuration and whether an agent actually exists to talk to, and not also whether we had previously sent a message to the server announcing it. (The change to this condition is also applied in the SSH-1 agent forwarding code, mostly for the sake of keeping things parallel where possible. I think it doesn't actually make a difference in SSH-1, because in SSH-1, it's not _possible_ for the server to try to open an agent channel before the main channel is set up, due to the entirely separate setup phase of the protocol.) The use case is a proxy host which makes a secondary SSH connection to a real destination host. A user has run into one of these recently, announcing a version banner of "SSH-2.0-FudoSSH", which relies on agent forwarding to authenticate the secondary connection. You connect to the proxy host and authenticate with a username string of the form "realusername#real.destination.host", and then, at the start of the connection protocol, the server immediately opens a channel back to your SSH agent which it uses to authenticate to the destination host. And it delays answering any CHANNEL_OPEN requests from the client until that's all done. For example (seen from the client's POV, although the server's CHANNEL_OPEN may well have been _sent_ up front rather than in response to the client's): client: SSH2_MSG_CHANNEL_OPEN "session" server: SSH2_MSG_CHANNEL_OPEN "auth-agent@openssh.com" client: SSH2_MSG_CHANNEL_OPEN_CONFIRMATION to the auth-agent request <- data is exchanged on the agent channel; proxy host uses that signature to log in to the destination host -> server: SSH2_MSG_CHANNEL_OPEN_CONFIRMATION to the session request With PuTTY, this wasn't working, because at the point when the server sends the auth-agent CHANNEL_OPEN, we had not yet had any opportunity to send auth-agent-req (because that has to wait until we've had a CHANNEL_OPEN_CONFIRMATION). So we were rejecting the server's CHANNEL_OPEN, which broke this workflow: client: SSH2_MSG_CHANNEL_OPEN "session" server: SSH2_MSG_CHANNEL_OPEN "auth-agent@openssh.com" client: SSH2_MSG_CHANNEL_OPEN_FAILURE to the auth-agent request (hey, I haven't told you you can do that yet!) server: SSH2_MSG_CHANNEL_OPEN_FAILURE to the session request (in that case, no shell session for you!)
This commit is contained in:
parent
04c50b6cfd
commit
b4e1110892
@ -236,7 +236,6 @@ static void mainchan_request_response(Channel *chan, bool success)
|
||||
|
||||
if (success) {
|
||||
ppl_logevent("Agent forwarding enabled");
|
||||
ssh_enable_agent_fwd(mc->cl);
|
||||
} else {
|
||||
ppl_logevent("Agent forwarding refused");
|
||||
}
|
||||
|
9
ssh.h
9
ssh.h
@ -294,11 +294,10 @@ struct ConnectionLayerVtable {
|
||||
* channel) what its preference for line-discipline options is. */
|
||||
void (*set_ldisc_option)(ConnectionLayer *cl, int option, bool value);
|
||||
|
||||
/* Communicate to the connection layer whether X and agent
|
||||
* forwarding were successfully enabled (for purposes of
|
||||
* knowing whether to accept subsequent channel-opens). */
|
||||
/* Communicate to the connection layer whether X forwarding was
|
||||
* successfully enabled (for purposes of knowing whether to accept
|
||||
* subsequent channel-opens). */
|
||||
void (*enable_x_fwd)(ConnectionLayer *cl);
|
||||
void (*enable_agent_fwd)(ConnectionLayer *cl);
|
||||
|
||||
/* Communicate to the connection layer whether the main session
|
||||
* channel currently wants user input. */
|
||||
@ -370,8 +369,6 @@ static inline void ssh_set_ldisc_option(ConnectionLayer *cl, int opt, bool val)
|
||||
{ cl->vt->set_ldisc_option(cl, opt, val); }
|
||||
static inline void ssh_enable_x_fwd(ConnectionLayer *cl)
|
||||
{ cl->vt->enable_x_fwd(cl); }
|
||||
static inline void ssh_enable_agent_fwd(ConnectionLayer *cl)
|
||||
{ cl->vt->enable_agent_fwd(cl); }
|
||||
static inline void ssh_set_wants_user_input(ConnectionLayer *cl, bool wanted)
|
||||
{ cl->vt->set_wants_user_input(cl, wanted); }
|
||||
|
||||
|
@ -151,7 +151,7 @@ bool ssh1_handle_direction_specific_packet(
|
||||
remid = get_uint32(pktin);
|
||||
|
||||
/* Refuse if agent forwarding is disabled. */
|
||||
if (!s->agent_fwd_enabled) {
|
||||
if (!ssh_agent_forwarding_permitted(&s->cl)) {
|
||||
pktout = ssh_bpp_new_pktout(
|
||||
s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_FAILURE);
|
||||
put_uint32(pktout, remid);
|
||||
|
@ -62,7 +62,6 @@ static void ssh1_throttle_all_channels(ConnectionLayer *cl, bool throttled);
|
||||
static bool ssh1_ldisc_option(ConnectionLayer *cl, int option);
|
||||
static void ssh1_set_ldisc_option(ConnectionLayer *cl, int option, bool value);
|
||||
static void ssh1_enable_x_fwd(ConnectionLayer *cl);
|
||||
static void ssh1_enable_agent_fwd(ConnectionLayer *cl);
|
||||
static void ssh1_set_wants_user_input(ConnectionLayer *cl, bool wanted);
|
||||
|
||||
static const ConnectionLayerVtable ssh1_connlayer_vtable = {
|
||||
@ -81,7 +80,6 @@ static const ConnectionLayerVtable ssh1_connlayer_vtable = {
|
||||
.ldisc_option = ssh1_ldisc_option,
|
||||
.set_ldisc_option = ssh1_set_ldisc_option,
|
||||
.enable_x_fwd = ssh1_enable_x_fwd,
|
||||
.enable_agent_fwd = ssh1_enable_agent_fwd,
|
||||
.set_wants_user_input = ssh1_set_wants_user_input,
|
||||
/* other methods are NULL */
|
||||
};
|
||||
@ -770,14 +768,6 @@ static void ssh1_enable_x_fwd(ConnectionLayer *cl)
|
||||
s->X11_fwd_enabled = true;
|
||||
}
|
||||
|
||||
static void ssh1_enable_agent_fwd(ConnectionLayer *cl)
|
||||
{
|
||||
struct ssh1_connection_state *s =
|
||||
container_of(cl, struct ssh1_connection_state, cl);
|
||||
|
||||
s->agent_fwd_enabled = true;
|
||||
}
|
||||
|
||||
static void ssh1_set_wants_user_input(ConnectionLayer *cl, bool wanted)
|
||||
{
|
||||
struct ssh1_connection_state *s =
|
||||
|
@ -31,8 +31,6 @@ struct ssh1_connection_state {
|
||||
struct X11FakeAuth *x11auth;
|
||||
tree234 *x11authtree;
|
||||
|
||||
bool agent_fwd_enabled;
|
||||
|
||||
tree234 *rportfwds;
|
||||
PortFwdManager *portfwdmgr;
|
||||
bool portfwdmgr_configured;
|
||||
|
@ -89,7 +89,7 @@ static ChanopenResult chan_open_forwarded_tcpip(
|
||||
static ChanopenResult chan_open_auth_agent(
|
||||
struct ssh2_connection_state *s, SshChannel *sc)
|
||||
{
|
||||
if (!s->agent_fwd_enabled) {
|
||||
if (!ssh_agent_forwarding_permitted(&s->cl)) {
|
||||
CHANOPEN_RETURN_FAILURE(
|
||||
SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED,
|
||||
("Agent forwarding is not enabled"));
|
||||
|
@ -62,7 +62,6 @@ static void ssh2_throttle_all_channels(ConnectionLayer *cl, bool throttled);
|
||||
static bool ssh2_ldisc_option(ConnectionLayer *cl, int option);
|
||||
static void ssh2_set_ldisc_option(ConnectionLayer *cl, int option, bool value);
|
||||
static void ssh2_enable_x_fwd(ConnectionLayer *cl);
|
||||
static void ssh2_enable_agent_fwd(ConnectionLayer *cl);
|
||||
static void ssh2_set_wants_user_input(ConnectionLayer *cl, bool wanted);
|
||||
|
||||
static const ConnectionLayerVtable ssh2_connlayer_vtable = {
|
||||
@ -88,7 +87,6 @@ static const ConnectionLayerVtable ssh2_connlayer_vtable = {
|
||||
.ldisc_option = ssh2_ldisc_option,
|
||||
.set_ldisc_option = ssh2_set_ldisc_option,
|
||||
.enable_x_fwd = ssh2_enable_x_fwd,
|
||||
.enable_agent_fwd = ssh2_enable_agent_fwd,
|
||||
.set_wants_user_input = ssh2_set_wants_user_input,
|
||||
};
|
||||
|
||||
@ -1694,14 +1692,6 @@ static void ssh2_enable_x_fwd(ConnectionLayer *cl)
|
||||
s->X11_fwd_enabled = true;
|
||||
}
|
||||
|
||||
static void ssh2_enable_agent_fwd(ConnectionLayer *cl)
|
||||
{
|
||||
struct ssh2_connection_state *s =
|
||||
container_of(cl, struct ssh2_connection_state, cl);
|
||||
|
||||
s->agent_fwd_enabled = true;
|
||||
}
|
||||
|
||||
static void ssh2_set_wants_user_input(ConnectionLayer *cl, bool wanted)
|
||||
{
|
||||
struct ssh2_connection_state *s =
|
||||
|
@ -29,7 +29,6 @@ struct ssh2_connection_state {
|
||||
tree234 *x11authtree;
|
||||
|
||||
bool got_pty;
|
||||
bool agent_fwd_enabled;
|
||||
|
||||
tree234 *rportfwds;
|
||||
PortFwdManager *portfwdmgr;
|
||||
|
Loading…
Reference in New Issue
Block a user