mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 18:07:59 +00:00
Hiroshi Oota points out that PuTTY's agent forwarding sockets can get
confused if they receive a request followed by immediate EOF, since we currently send outgoing EOF as soon as we see the incoming one - and then, when the response comes back from the real SSH agent, we send it along anyway as channel data in spite of having sent EOF. To fix this, I introduce a new field for each agent channel which counts the number of calls to ssh_agentf_callback that are currently expected, and we don't send EOF on an agent channel until we've both received EOF and that value drops to zero. [originally from svn r9651]
This commit is contained in:
parent
33c58dd91b
commit
14539a7719
18
ssh.c
18
ssh.c
@ -666,6 +666,7 @@ struct ssh_channel {
|
|||||||
unsigned char *message;
|
unsigned char *message;
|
||||||
unsigned char msglen[4];
|
unsigned char msglen[4];
|
||||||
unsigned lensofar, totallen;
|
unsigned lensofar, totallen;
|
||||||
|
int outstanding_requests;
|
||||||
} a;
|
} a;
|
||||||
struct ssh_x11_channel {
|
struct ssh_x11_channel {
|
||||||
Socket s;
|
Socket s;
|
||||||
@ -3201,6 +3202,7 @@ static void ssh_agentf_callback(void *cv, void *reply, int replylen)
|
|||||||
Ssh ssh = c->ssh;
|
Ssh ssh = c->ssh;
|
||||||
void *sentreply = reply;
|
void *sentreply = reply;
|
||||||
|
|
||||||
|
c->u.a.outstanding_requests--;
|
||||||
if (!sentreply) {
|
if (!sentreply) {
|
||||||
/* Fake SSH_AGENT_FAILURE. */
|
/* Fake SSH_AGENT_FAILURE. */
|
||||||
sentreply = "\0\0\0\1\5";
|
sentreply = "\0\0\0\1\5";
|
||||||
@ -3220,6 +3222,12 @@ static void ssh_agentf_callback(void *cv, void *reply, int replylen)
|
|||||||
}
|
}
|
||||||
if (reply)
|
if (reply)
|
||||||
sfree(reply);
|
sfree(reply);
|
||||||
|
/*
|
||||||
|
* If we've already seen an incoming EOF but haven't sent an
|
||||||
|
* outgoing one, this may be the moment to send it.
|
||||||
|
*/
|
||||||
|
if (c->u.a.outstanding_requests == 0 && (c->closes & CLOSES_RCVD_EOF))
|
||||||
|
sshfwd_write_eof(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4827,6 +4835,7 @@ static void ssh1_smsg_agent_open(Ssh ssh, struct Packet *pktin)
|
|||||||
c->type = CHAN_AGENT; /* identify channel type */
|
c->type = CHAN_AGENT; /* identify channel type */
|
||||||
c->u.a.lensofar = 0;
|
c->u.a.lensofar = 0;
|
||||||
c->u.a.message = NULL;
|
c->u.a.message = NULL;
|
||||||
|
c->u.a.outstanding_requests = 0;
|
||||||
add234(ssh->channels, c);
|
add234(ssh->channels, c);
|
||||||
send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
|
send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
|
||||||
PKT_INT, c->remoteid, PKT_INT, c->localid,
|
PKT_INT, c->remoteid, PKT_INT, c->localid,
|
||||||
@ -5052,6 +5061,7 @@ static void ssh1_msg_channel_data(Ssh ssh, struct Packet *pktin)
|
|||||||
if (c->u.a.lensofar == c->u.a.totallen) {
|
if (c->u.a.lensofar == c->u.a.totallen) {
|
||||||
void *reply;
|
void *reply;
|
||||||
int replylen;
|
int replylen;
|
||||||
|
c->u.a.outstanding_requests++;
|
||||||
if (agent_query(c->u.a.message,
|
if (agent_query(c->u.a.message,
|
||||||
c->u.a.totallen,
|
c->u.a.totallen,
|
||||||
&reply, &replylen,
|
&reply, &replylen,
|
||||||
@ -6847,6 +6857,7 @@ static void ssh2_msg_channel_data(Ssh ssh, struct Packet *pktin)
|
|||||||
if (c->u.a.lensofar == c->u.a.totallen) {
|
if (c->u.a.lensofar == c->u.a.totallen) {
|
||||||
void *reply;
|
void *reply;
|
||||||
int replylen;
|
int replylen;
|
||||||
|
c->u.a.outstanding_requests++;
|
||||||
if (agent_query(c->u.a.message,
|
if (agent_query(c->u.a.message,
|
||||||
c->u.a.totallen,
|
c->u.a.totallen,
|
||||||
&reply, &replylen,
|
&reply, &replylen,
|
||||||
@ -6985,8 +6996,10 @@ static void ssh2_channel_got_eof(struct ssh_channel *c)
|
|||||||
if (c->type == CHAN_X11) {
|
if (c->type == CHAN_X11) {
|
||||||
x11_send_eof(c->u.x11.s);
|
x11_send_eof(c->u.x11.s);
|
||||||
} else if (c->type == CHAN_AGENT) {
|
} else if (c->type == CHAN_AGENT) {
|
||||||
/* Manufacture an outgoing EOF in response to the incoming one. */
|
if (c->u.a.outstanding_requests == 0) {
|
||||||
sshfwd_write_eof(c);
|
/* Manufacture an outgoing EOF in response to the incoming one. */
|
||||||
|
sshfwd_write_eof(c);
|
||||||
|
}
|
||||||
} else if (c->type == CHAN_SOCKDATA) {
|
} else if (c->type == CHAN_SOCKDATA) {
|
||||||
pfd_send_eof(c->u.pfd.s);
|
pfd_send_eof(c->u.pfd.s);
|
||||||
} else if (c->type == CHAN_MAINSESSION) {
|
} else if (c->type == CHAN_MAINSESSION) {
|
||||||
@ -7408,6 +7421,7 @@ static void ssh2_msg_channel_open(Ssh ssh, struct Packet *pktin)
|
|||||||
else {
|
else {
|
||||||
c->type = CHAN_AGENT; /* identify channel type */
|
c->type = CHAN_AGENT; /* identify channel type */
|
||||||
c->u.a.lensofar = 0;
|
c->u.a.lensofar = 0;
|
||||||
|
c->u.a.outstanding_requests = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error = "Unsupported channel type requested";
|
error = "Unsupported channel type requested";
|
||||||
|
Loading…
Reference in New Issue
Block a user