if (i < 0) {
freebn(reqkey.exponent);
freebn(reqkey.modulus);
+ freebn(challenge);
fail_reason = "request truncated before challenge";
goto failure;
}
}
bloblen = msgend - p;
- key->data = key->alg->openssh_createkey(&p, &bloblen);
+ key->data = key->alg->openssh_createkey(key->alg, &p, &bloblen);
if (!key->data) {
sfree(key);
fail_reason = "key setup failed";
struct pageant_listen_state *pl = (struct pageant_listen_state *)plug;
struct pageant_conn_state *pc;
const char *err;
+ char *peerinfo;
pc = snew(struct pageant_conn_state);
pc->fn = &connection_fn_table;
sk_set_frozen(pc->connsock, 0);
- /* FIXME: can we get any useful peer id info? */
- plog(pl->logctx, pl->logfn, "%p: new connection", pc);
+ peerinfo = sk_peer_info(pc->connsock);
+ if (peerinfo) {
+ plog(pl->logctx, pl->logfn, "%p: new connection from %s",
+ pc, peerinfo);
+ } else {
+ plog(pl->logctx, pl->logfn, "%p: new connection", pc);
+ }
return 0;
}
*/
void pageant_forget_passphrases(void)
{
+ if (!passphrases) /* in case we never set it up at all */
+ return;
+
while (count234(passphrases) > 0) {
char *pp = index234(passphrases, 0);
smemclr(pp, strlen(pp));
if (!pageant_local) {
unsigned char request[5], *response;
void *vresponse;
- int resplen, retval;
+ int resplen;
+
request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES;
PUT_32BIT(request, 1);
- retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
- assert(retval == 1);
+ agent_query_synchronous(request, 5, &vresponse, &resplen);
response = vresponse;
if (resplen < 5 || response[4] != SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
sfree(response);
if (!pageant_local) {
unsigned char request[5], *response;
void *vresponse;
- int resplen, retval;
+ int resplen;
request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
PUT_32BIT(request, 1);
- retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
- assert(retval == 1);
+ agent_query_synchronous(request, 5, &vresponse, &resplen);
response = vresponse;
if (resplen < 5 || response[4] != SSH2_AGENT_IDENTITIES_ANSWER) {
sfree(response);
if (keylist) {
if (keylistlen < 4) {
*retstr = dupstr("Received broken key list from agent");
+ sfree(keylist);
+ sfree(blob);
return PAGEANT_ACTION_FAILURE;
}
nkeys = toint(GET_32BIT(keylist));
if (nkeys < 0) {
*retstr = dupstr("Received broken key list from agent");
+ sfree(keylist);
+ sfree(blob);
return PAGEANT_ACTION_FAILURE;
}
p = keylist + 4;
int n = rsa_public_blob_len(p, keylistlen);
if (n < 0) {
*retstr = dupstr("Received broken key list from agent");
+ sfree(keylist);
+ sfree(blob);
return PAGEANT_ACTION_FAILURE;
}
p += n;
int n;
if (keylistlen < 4) {
*retstr = dupstr("Received broken key list from agent");
+ sfree(keylist);
+ sfree(blob);
return PAGEANT_ACTION_FAILURE;
}
- n = toint(4 + GET_32BIT(p));
- if (n < 0 || keylistlen < n) {
+ n = GET_32BIT(p);
+ p += 4;
+ keylistlen -= 4;
+
+ if (n < 0 || n > keylistlen) {
*retstr = dupstr("Received broken key list from agent");
+ sfree(keylist);
+ sfree(blob);
return PAGEANT_ACTION_FAILURE;
}
p += n;
int n;
if (keylistlen < 4) {
*retstr = dupstr("Received broken key list from agent");
+ sfree(keylist);
+ sfree(blob);
return PAGEANT_ACTION_FAILURE;
}
- n = toint(4 + GET_32BIT(p));
- if (n < 0 || keylistlen < n) {
+ n = GET_32BIT(p);
+ p += 4;
+ keylistlen -= 4;
+
+ if (n < 0 || n > keylistlen) {
*retstr = dupstr("Received broken key list from agent");
+ sfree(keylist);
+ sfree(blob);
return PAGEANT_ACTION_FAILURE;
}
p += n;
* Run out of passphrases to try.
*/
*retstr = comment;
+ sfree(rkey);
return PAGEANT_ACTION_NEED_PP;
}
} else
* a bad passphrase.
*/
*retstr = dupstr(error);
+ sfree(rkey);
return PAGEANT_ACTION_FAILURE;
} else if (ret == 1) {
/*
if (!pageant_local) {
unsigned char *request, *response;
void *vresponse;
- int reqlen, clen, resplen, ret;
+ int reqlen, clen, resplen;
clen = strlen(rkey->comment);
reqlen += 4 + clen;
PUT_32BIT(request, reqlen - 4);
- ret = agent_query(request, reqlen, &vresponse, &resplen,
- NULL, NULL);
- assert(ret == 1);
+ agent_query_synchronous(request, reqlen, &vresponse, &resplen);
response = vresponse;
if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) {
*retstr = dupstr("The already running Pageant "
"refused to add the key.");
+ freersakey(rkey);
+ sfree(rkey);
+ sfree(request);
+ sfree(response);
return PAGEANT_ACTION_FAILURE;
}
+ freersakey(rkey);
+ sfree(rkey);
sfree(request);
sfree(response);
} else {
if (!pageant_add_ssh1_key(rkey)) {
+ freersakey(rkey);
sfree(rkey); /* already present, don't waste RAM */
}
}
if (!pageant_local) {
unsigned char *request, *response;
void *vresponse;
- int reqlen, alglen, clen, keybloblen, resplen, ret;
+ int reqlen, alglen, clen, keybloblen, resplen;
alglen = strlen(skey->alg->name);
clen = strlen(skey->comment);
reqlen += clen + 4;
PUT_32BIT(request, reqlen - 4);
- ret = agent_query(request, reqlen, &vresponse, &resplen,
- NULL, NULL);
- assert(ret == 1);
+ agent_query_synchronous(request, reqlen, &vresponse, &resplen);
response = vresponse;
if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) {
*retstr = dupstr("The already running Pageant "
"refused to add the key.");
+ sfree(request);
+ sfree(response);
return PAGEANT_ACTION_FAILURE;
}
p += n, keylistlen -= n;
cbkey.blob = rsa_public_blob(&rkey, &cbkey.bloblen);
+ cbkey.comment = comment;
cbkey.ssh_version = 1;
callback(callback_ctx, fingerprint, comment, &cbkey);
sfree(cbkey.blob);
p += n, keylistlen -= n;
cbkey.ssh_version = 2;
+ cbkey.comment = comment;
callback(callback_ctx, fingerprint, comment, &cbkey);
sfree(fingerprint);
sfree(comment);
memcpy(request + 9, key->blob, key->bloblen);
}
- ret = agent_query(request, reqlen, &vresponse, &resplen, NULL, NULL);
- assert(ret == 1);
+ agent_query_synchronous(request, reqlen, &vresponse, &resplen);
response = vresponse;
if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) {
*retstr = dupstr("Agent failed to delete key");
return ret;
}
+int pageant_delete_all_keys(char **retstr)
+{
+ unsigned char request[5], *response;
+ int reqlen, resplen, success;
+ void *vresponse;
+
+ PUT_32BIT(request, 1);
+ request[4] = SSH2_AGENTC_REMOVE_ALL_IDENTITIES;
+ reqlen = 5;
+ agent_query_synchronous(request, reqlen, &vresponse, &resplen);
+ response = vresponse;
+ success = (resplen >= 4 && response[4] == SSH_AGENT_SUCCESS);
+ sfree(response);
+ if (!success) {
+ *retstr = dupstr("Agent failed to delete SSH-2 keys");
+ return PAGEANT_ACTION_FAILURE;
+ }
+
+ PUT_32BIT(request, 1);
+ request[4] = SSH1_AGENTC_REMOVE_ALL_RSA_IDENTITIES;
+ reqlen = 5;
+ agent_query_synchronous(request, reqlen, &vresponse, &resplen);
+ response = vresponse;
+ success = (resplen >= 4 && response[4] == SSH_AGENT_SUCCESS);
+ sfree(response);
+ if (!success) {
+ *retstr = dupstr("Agent failed to delete SSH-1 keys");
+ return PAGEANT_ACTION_FAILURE;
+ }
+
+ *retstr = NULL;
+ return PAGEANT_ACTION_OK;
+}
+
struct pageant_pubkey *pageant_pubkey_copy(struct pageant_pubkey *key)
{
struct pageant_pubkey *ret = snew(struct pageant_pubkey);
ret->blob = snewn(key->bloblen, unsigned char);
memcpy(ret->blob, key->blob, key->bloblen);
ret->bloblen = key->bloblen;
+ ret->comment = key->comment ? dupstr(key->comment) : NULL;
ret->ssh_version = key->ssh_version;
return ret;
}
void pageant_pubkey_free(struct pageant_pubkey *key)
{
+ sfree(key->comment);
sfree(key->blob);
sfree(key);
}