From e533097e1566fb1029e14c3b9808e8aaee1b8a85 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Tue, 12 May 2015 14:48:32 +0100 Subject: [PATCH] Unix Pageant: provide public-key extraction options. I've decided against implementing an option exactly analogous to 'ssh-add -L' (printing the full public key of everything in the agent). Instead, you can identify a specific key to display in full, by any of the same means -d lets you use, and then print it in either of the public key formats we support. --- pageant.c | 4 ++++ pageant.h | 1 + unix/uxpgnt.c | 37 +++++++++++++++++++++++++++++++++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/pageant.c b/pageant.c index c249a3b7..e3928cde 100644 --- a/pageant.c +++ b/pageant.c @@ -1624,6 +1624,7 @@ int pageant_enum_keys(pageant_key_enum_fn_t callback, void *callback_ctx, 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); @@ -1694,6 +1695,7 @@ int pageant_enum_keys(pageant_key_enum_fn_t callback, void *callback_ctx, p += n, keylistlen -= n; cbkey.ssh_version = 2; + cbkey.comment = comment; callback(callback_ctx, fingerprint, comment, &cbkey); sfree(fingerprint); sfree(comment); @@ -1751,12 +1753,14 @@ struct pageant_pubkey *pageant_pubkey_copy(struct pageant_pubkey *key) 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); } diff --git a/pageant.h b/pageant.h index 4a26ad93..451fe7e5 100644 --- a/pageant.h +++ b/pageant.h @@ -127,6 +127,7 @@ struct pageant_pubkey { * later */ void *blob; int bloblen; + char *comment; int ssh_version; }; struct pageant_pubkey *pageant_pubkey_copy(struct pageant_pubkey *key); diff --git a/unix/uxpgnt.c b/unix/uxpgnt.c index 6e5923c2..4a46b657 100644 --- a/unix/uxpgnt.c +++ b/unix/uxpgnt.c @@ -240,7 +240,8 @@ typedef enum { KEYACT_CLIENT_DEL, KEYACT_CLIENT_DEL_ALL, KEYACT_CLIENT_LIST, - KEYACT_CLIENT_LIST_FULL, + KEYACT_CLIENT_PUBLIC_OPENSSH, + KEYACT_CLIENT_PUBLIC } keyact; struct cmdline_key_action { struct cmdline_key_action *next; @@ -564,8 +565,34 @@ void run_client(void) if (key) pageant_pubkey_free(key); break; + case KEYACT_CLIENT_PUBLIC_OPENSSH: + case KEYACT_CLIENT_PUBLIC: + key = NULL; + if (!(key = find_key(act->filename, &retstr))) { + fprintf(stderr, "pageant: finding key '%s': %s\n", + act->filename, retstr); + sfree(retstr); + errors = TRUE; + } else { + FILE *fp = stdout; /* FIXME: add a -o option? */ + + if (key->ssh_version == 1) { + struct RSAKey rkey; + memset(&rkey, 0, sizeof(rkey)); + rkey.comment = dupstr(key->comment); + makekey(key->blob, key->bloblen, &rkey, NULL, 0); + ssh1_write_pubkey(fp, &rkey); + freersakey(&rkey); + } else { + ssh2_write_pubkey(fp, key->comment, key->blob,key->bloblen, + (act->action == KEYACT_CLIENT_PUBLIC ? + SSH_KEYTYPE_SSH2_PUBLIC_RFC4716 : + SSH_KEYTYPE_SSH2_PUBLIC_OPENSSH)); + } + pageant_pubkey_free(key); + } + break; case KEYACT_CLIENT_DEL_ALL: - case KEYACT_CLIENT_LIST_FULL: fprintf(stderr, "NYI\n"); errors = TRUE; break; @@ -892,8 +919,10 @@ int main(int argc, char **argv) add_keyact(KEYACT_CLIENT_DEL_ALL, NULL); } else if (!strcmp(p, "-l")) { add_keyact(KEYACT_CLIENT_LIST, NULL); - } else if (!strcmp(p, "-L")) { - add_keyact(KEYACT_CLIENT_LIST_FULL, NULL); + } else if (!strcmp(p, "--public")) { + curr_keyact = KEYACT_CLIENT_PUBLIC; + } else if (!strcmp(p, "--public-openssh")) { + curr_keyact = KEYACT_CLIENT_PUBLIC_OPENSSH; } else if (!strcmp(p, "-X")) { life = LIFE_X11; } else if (!strcmp(p, "-T")) { -- 2.45.2