mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-25 01:02:24 +00:00
Auth plugin: fix early socket closure.
My correspondent on the new authentication-plugin feature reports that their plugin is not reliably receiving the final PLUGIN_AUTH_SUCCESS message on Windows. I _think_ this is because the whole userauth layer is being dismissed, leading to sk_close() of the Socket talking to the plugin, before the data has actually been written to the outgoing pipe. This should fix it: track the Socket's backlog, and immediately after sending that message, wait until we receive a notification that the backlog has decreased to size 0. That stops us from terminating the userauth layer until the message has left our process.
This commit is contained in:
parent
fbb979aa98
commit
1d75ad4c93
@ -96,6 +96,7 @@ struct ssh2_userauth_state {
|
|||||||
Plug authplugin_plug;
|
Plug authplugin_plug;
|
||||||
bufchain authplugin_bc;
|
bufchain authplugin_bc;
|
||||||
strbuf *authplugin_incoming_msg;
|
strbuf *authplugin_incoming_msg;
|
||||||
|
size_t authplugin_backlog;
|
||||||
bool authplugin_eof;
|
bool authplugin_eof;
|
||||||
bool authplugin_ki_active;
|
bool authplugin_ki_active;
|
||||||
|
|
||||||
@ -335,11 +336,19 @@ static void authplugin_plug_receive(
|
|||||||
queue_idempotent_callback(&s->ppl.ic_process_queue);
|
queue_idempotent_callback(&s->ppl.ic_process_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void authplugin_plug_sent(Plug *plug, size_t bufsize)
|
||||||
|
{
|
||||||
|
struct ssh2_userauth_state *s = container_of(
|
||||||
|
plug, struct ssh2_userauth_state, authplugin_plug);
|
||||||
|
s->authplugin_backlog = bufsize;
|
||||||
|
queue_idempotent_callback(&s->ppl.ic_process_queue);
|
||||||
|
}
|
||||||
|
|
||||||
static const PlugVtable authplugin_plugvt = {
|
static const PlugVtable authplugin_plugvt = {
|
||||||
.log = authplugin_plug_log,
|
.log = authplugin_plug_log,
|
||||||
.closing = authplugin_plug_closing,
|
.closing = authplugin_plug_closing,
|
||||||
.receive = authplugin_plug_receive,
|
.receive = authplugin_plug_receive,
|
||||||
.sent = nullplug_sent,
|
.sent = authplugin_plug_sent,
|
||||||
};
|
};
|
||||||
|
|
||||||
static strbuf *authplugin_newmsg(uint8_t type)
|
static strbuf *authplugin_newmsg(uint8_t type)
|
||||||
@ -354,7 +363,7 @@ static void authplugin_send_free(struct ssh2_userauth_state *s, strbuf *amsg)
|
|||||||
{
|
{
|
||||||
PUT_32BIT_MSB_FIRST(amsg->u, amsg->len - 4);
|
PUT_32BIT_MSB_FIRST(amsg->u, amsg->len - 4);
|
||||||
assert(s->authplugin);
|
assert(s->authplugin);
|
||||||
sk_write(s->authplugin, amsg->u, amsg->len);
|
s->authplugin_backlog = sk_write(s->authplugin, amsg->u, amsg->len);
|
||||||
strbuf_free(amsg);
|
strbuf_free(amsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1789,6 +1798,12 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
|
|||||||
if (plugin_msg >= 0) {
|
if (plugin_msg >= 0) {
|
||||||
strbuf *amsg = authplugin_newmsg(plugin_msg);
|
strbuf *amsg = authplugin_newmsg(plugin_msg);
|
||||||
authplugin_send_free(s, amsg);
|
authplugin_send_free(s, amsg);
|
||||||
|
|
||||||
|
/* Wait until we've actually sent it, in case
|
||||||
|
* we close the connection to the plugin
|
||||||
|
* before that outgoing message has left our
|
||||||
|
* own buffers */
|
||||||
|
crMaybeWaitUntilV(s->authplugin_backlog == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (s->can_passwd) {
|
} else if (s->can_passwd) {
|
||||||
|
Loading…
Reference in New Issue
Block a user