1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Pageant: new PuTTY-specific ext request, 'list-extended'.

This is an extended version of SSH2_AGENTC_REQUEST_IDENTITIES, which
augments each entry in the returned key list with an extra field
containing additional data about the key.

The initial contents of that extra field are a pair of flags
indicating whether the key is currently stored in the agent encrypted,
decrypted or both.

The idea is that this will permit a Pageant-aware client to make
decisions based on that. For a start, the output key list can mention
it to the user; also, if you try to add a key unencrypted when it's
already present, we can discriminate based on whether it's already
present _unencrypted_
This commit is contained in:
Simon Tatham 2020-12-15 13:25:45 +00:00
parent 3687df73a8
commit 39ec2837c8
2 changed files with 58 additions and 3 deletions

View File

@ -266,7 +266,7 @@ static void remove_all_keys(int ssh_version)
}
}
static void list_keys(BinarySink *bs, int ssh_version)
static void list_keys(BinarySink *bs, int ssh_version, bool extended)
{
int i;
PageantKey *pk;
@ -283,11 +283,33 @@ static void list_keys(BinarySink *bs, int ssh_version)
put_datapl(bs, pk->sort.public_blob); /* no header */
put_stringpl(bs, ptrlen_from_asciz(pk->comment));
if (extended) {
/*
* Append to each key entry a string containing extension
* data. This string begins with a flags word, and may in
* future contain further data if flag bits are set saying
* that it does. Hence, it's wrapped in a containing
* string, so that clients that only partially understand
* it can still find the parts they do understand.
*/
strbuf *sb = strbuf_new();
uint32_t flags = 0;
if (!pk->skey)
flags |= LIST_EXTENDED_FLAG_HAS_NO_CLEARTEXT_KEY;
if (pk->encrypted_key_file)
flags |= LIST_EXTENDED_FLAG_HAS_ENCRYPTED_KEY_FILE;
put_uint32(sb, flags);
put_stringsb(bs, sb);
}
}
}
void pageant_make_keylist1(BinarySink *bs) { list_keys(bs, 1); }
void pageant_make_keylist2(BinarySink *bs) { list_keys(bs, 2); }
void pageant_make_keylist1(BinarySink *bs) { list_keys(bs, 1, false); }
void pageant_make_keylist2(BinarySink *bs) { list_keys(bs, 2, false); }
void pageant_make_keylist_extended(BinarySink *bs) { list_keys(bs, 2, true); }
void pageant_register_client(PageantClient *pc)
{
@ -1264,6 +1286,35 @@ static PageantAsyncOp *pageant_make_op(
}
break;
}
case EXT_LIST_EXTENDED: {
/*
* Return a key list like SSH2_AGENTC_REQUEST_IDENTITIES,
* except that each key is annotated with extra
* information such as whether it's currently encrypted.
*
* The return message type is AGENT_SUCCESS with auxiliary
* data, which is more like other extension messages. I
* think it would be confusing to reuse IDENTITIES_ANSWER
* for a reply message with an incompatible format.
*/
put_byte(sb, SSH_AGENT_SUCCESS);
pageant_make_keylist_extended(BinarySink_UPCAST(sb));
pageant_client_log(pc, reqid,
"reply: SSH2_AGENT_SUCCESS + key list");
if (!pc->suppress_logging) {
int i;
ssh2_userkey *skey;
for (i = 0; NULL != (skey = pageant_nth_ssh2_key(i)); i++) {
char *fingerprint = ssh2_fingerprint(skey->key);
pageant_client_log(pc, reqid, "returned key: %s %s",
fingerprint, skey->comment);
sfree(fingerprint);
}
}
break;
}
}
break;
}

View File

@ -253,4 +253,8 @@ int pageant_sign(struct pageant_pubkey *key, ptrlen message, strbuf *out,
X(EXT_ADD_PPK, PUTTYEXT("add-ppk")) \
X(EXT_REENCRYPT, PUTTYEXT("reencrypt")) \
X(EXT_REENCRYPT_ALL, PUTTYEXT("reencrypt-all")) \
X(EXT_LIST_EXTENDED, PUTTYEXT("list-extended")) \
/* end of list */
#define LIST_EXTENDED_FLAG_HAS_ENCRYPTED_KEY_FILE 1
#define LIST_EXTENDED_FLAG_HAS_NO_CLEARTEXT_KEY 2