unsigned char msglen[4];
unsigned lensofar, totallen;
int outstanding_requests;
+ agent_pending_query *pending;
} a;
struct ssh_x11_channel {
struct X11Connection *xconn;
* with a newly cross-certified host key.
*/
int cross_certifying;
+
+ /*
+ * Any asynchronous query to our SSH agent that we might have in
+ * flight from the main authentication loop. (Queries from
+ * agent-forwarding channels live in their channel structure.)
+ */
+ agent_pending_query *auth_agent_query;
};
static const char *ssh_pkt_type(Ssh ssh, int type)
{
Ssh ssh = (Ssh) sshv;
+ ssh->auth_agent_query = NULL;
+
ssh->agent_response = reply;
ssh->agent_response_len = replylen;
struct ssh_channel *c = (struct ssh_channel *)cv;
const void *sentreply = reply;
+ c->u.a.pending = NULL;
c->u.a.outstanding_requests--;
if (!sentreply) {
/* Fake SSH_AGENT_FAILURE. */
/* Request the keys held by the agent. */
PUT_32BIT(s->request, 1);
s->request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES;
- if (!agent_query(s->request, 5, &r, &s->responselen,
- ssh_agent_callback, ssh)) {
+ ssh->auth_agent_query = agent_query(
+ s->request, 5, &r, &s->responselen, ssh_agent_callback, ssh);
+ if (ssh->auth_agent_query) {
do {
crReturn(0);
if (pktin) {
memcpy(q, s->session_id, 16);
q += 16;
PUT_32BIT(q, 1); /* response format */
- if (!agent_query(agentreq, len + 4, &vret, &retlen,
- ssh_agent_callback, ssh)) {
+ ssh->auth_agent_query = agent_query(
+ agentreq, len + 4, &vret, &retlen,
+ ssh_agent_callback, ssh);
+ if (ssh->auth_agent_query) {
sfree(agentreq);
do {
crReturn(0);
c->type = CHAN_AGENT; /* identify channel type */
c->u.a.lensofar = 0;
c->u.a.message = NULL;
+ c->u.a.pending = NULL;
c->u.a.outstanding_requests = 0;
send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
PKT_INT, c->remoteid, PKT_INT, c->localid,
void *reply;
int replylen;
c->u.a.outstanding_requests++;
- if (agent_query(c->u.a.message, c->u.a.totallen, &reply, &replylen,
- ssh_agentf_callback, c))
- ssh_agentf_callback(c, reply, replylen);
+ c->u.a.pending = agent_query(
+ c->u.a.message, c->u.a.totallen, &reply, &replylen,
+ ssh_agentf_callback, c);
+ if (!c->u.a.pending)
+ ssh_agentf_callback(c, reply, replylen);
sfree(c->u.a.message);
c->u.a.message = NULL;
c->u.a.lensofar = 0;
msg = "Forwarded X11 connection terminated";
break;
case CHAN_AGENT:
+ if (c->u.a.pending)
+ agent_cancel_query(c->u.a.pending);
sfree(c->u.a.message);
break;
case CHAN_SOCKDATA:
c->type = CHAN_AGENT; /* identify channel type */
c->u.a.lensofar = 0;
c->u.a.message = NULL;
+ c->u.a.pending = NULL;
c->u.a.outstanding_requests = 0;
}
} else {
/* Request the keys held by the agent. */
PUT_32BIT(s->agent_request, 1);
s->agent_request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
- if (!agent_query(s->agent_request, 5, &r, &s->agent_responselen,
- ssh_agent_callback, ssh)) {
+ ssh->auth_agent_query = agent_query(
+ s->agent_request, 5, &r, &s->agent_responselen,
+ ssh_agent_callback, ssh);
+ if (ssh->auth_agent_query) {
do {
crReturnV;
if (pktin) {
s->q += s->pktout->length - 5;
/* And finally the (zero) flags word. */
PUT_32BIT(s->q, 0);
- if (!agent_query(s->agentreq, s->len + 4,
- &vret, &s->retlen,
- ssh_agent_callback, ssh)) {
+ ssh->auth_agent_query = agent_query(
+ s->agentreq, s->len + 4, &vret, &s->retlen,
+ ssh_agent_callback, ssh);
+ if (ssh->auth_agent_query) {
do {
crReturnV;
if (pktin) {
CONF_ssh_rekey_data));
ssh->kex_in_progress = FALSE;
+ ssh->auth_agent_query = NULL;
+
#ifndef NO_GSSAPI
ssh->gsslibs = NULL;
#endif
bufchain_clear(&ssh->queued_incoming_data);
sfree(ssh->username);
conf_free(ssh->conf);
+
+ if (ssh->auth_agent_query)
+ agent_cancel_query(ssh->auth_agent_query);
+
#ifndef NO_GSSAPI
if (ssh->gsslibs)
ssh_gss_cleanup(ssh->gsslibs);