]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Unix Pageant: first draft of -l key list option.
authorSimon Tatham <anakin@pobox.com>
Mon, 11 May 2015 17:34:45 +0000 (18:34 +0100)
committerSimon Tatham <anakin@pobox.com>
Mon, 11 May 2015 17:45:34 +0000 (18:45 +0100)
It doesn't look very pretty at the moment, but it lists the keys and
gets the fingerprints right.

pageant.c
pageant.h
unix/uxpgnt.c

index 51baab02fd434edd4c301e6a19f38b9200c45a75..8f0747cbe20b7aa44fc9241c22a29850b34cc6e2 100644 (file)
--- a/pageant.c
+++ b/pageant.c
@@ -1582,3 +1582,140 @@ int pageant_add_keyfile(Filename *filename, const char *passphrase,
     }
     return PAGEANT_ACTION_OK;
 }
+
+int pageant_enum_keys(pageant_key_enum_fn_t callback, void *callback_ctx,
+                      char **retstr)
+{
+    unsigned char *keylist, *p;
+    int i, nkeys, keylistlen;
+    char *comment;
+
+    keylist = pageant_get_keylist1(&keylistlen);
+    if (keylistlen < 4) {
+        *retstr = dupstr("Received broken SSH-1 key list from agent");
+        sfree(keylist);
+        return PAGEANT_ACTION_FAILURE;
+    }
+    nkeys = toint(GET_32BIT(keylist));
+    if (nkeys < 0) {
+        *retstr = dupstr("Received broken SSH-1 key list from agent");
+        sfree(keylist);
+        return PAGEANT_ACTION_FAILURE;
+    }
+    p = keylist + 4;
+    keylistlen -= 4;
+
+    for (i = 0; i < nkeys; i++) {
+        struct RSAKey rkey;
+        char fingerprint[128];
+        int n;
+
+        /* public blob and fingerprint */
+        memset(&rkey, 0, sizeof(rkey));
+        n = makekey(p, keylistlen, &rkey, NULL, 0);
+        if (n < 0 || n > keylistlen) {
+            freersakey(&rkey);
+            *retstr = dupstr("Received broken SSH-1 key list from agent");
+            sfree(keylist);
+            return PAGEANT_ACTION_FAILURE;
+        }
+        p += n, keylistlen -= n;
+        rsa_fingerprint(fingerprint, sizeof(fingerprint), &rkey);
+
+        /* comment */
+        if (keylistlen < 4) {
+            *retstr = dupstr("Received broken SSH-1 key list from agent");
+            freersakey(&rkey);
+            sfree(keylist);
+            return PAGEANT_ACTION_FAILURE;
+        }
+        n = toint(GET_32BIT(p));
+        p += 4, keylistlen -= 4;
+        if (n < 0 || keylistlen < n) {
+            *retstr = dupstr("Received broken SSH-1 key list from agent");
+            freersakey(&rkey);
+            sfree(keylist);
+            return PAGEANT_ACTION_FAILURE;
+        }
+        comment = dupprintf("%.*s", (int)n, (const char *)p);
+        p += n, keylistlen -= n;
+
+        callback(callback_ctx, fingerprint, comment);
+        freersakey(&rkey);
+        sfree(comment);
+    }
+
+    sfree(keylist);
+
+    if (keylistlen != 0) {
+        *retstr = dupstr("Received broken SSH-1 key list from agent");
+        return PAGEANT_ACTION_FAILURE;
+    }
+
+    keylist = pageant_get_keylist2(&keylistlen);
+    if (keylistlen < 4) {
+        *retstr = dupstr("Received broken SSH-2 key list from agent");
+        sfree(keylist);
+        return PAGEANT_ACTION_FAILURE;
+    }
+    nkeys = toint(GET_32BIT(keylist));
+    if (nkeys < 0) {
+        *retstr = dupstr("Received broken SSH-2 key list from agent");
+        sfree(keylist);
+        return PAGEANT_ACTION_FAILURE;
+    }
+    p = keylist + 4;
+    keylistlen -= 4;
+
+    for (i = 0; i < nkeys; i++) {
+        char *fingerprint;
+        int n;
+
+        /* public blob */
+        if (keylistlen < 4) {
+            *retstr = dupstr("Received broken SSH-2 key list from agent");
+            sfree(keylist);
+            return PAGEANT_ACTION_FAILURE;
+        }
+        n = toint(GET_32BIT(p));
+        p += 4, keylistlen -= 4;
+        if (n < 0 || keylistlen < n) {
+            *retstr = dupstr("Received broken SSH-2 key list from agent");
+            sfree(keylist);
+            return PAGEANT_ACTION_FAILURE;
+        }
+        fingerprint = fingerprint_ssh2_blob(p, n);
+        p += n, keylistlen -= n;
+
+        /* comment */
+        if (keylistlen < 4) {
+            *retstr = dupstr("Received broken SSH-2 key list from agent");
+            sfree(fingerprint);
+            sfree(keylist);
+            return PAGEANT_ACTION_FAILURE;
+        }
+        n = toint(GET_32BIT(p));
+        p += 4, keylistlen -= 4;
+        if (n < 0 || keylistlen < n) {
+            *retstr = dupstr("Received broken SSH-2 key list from agent");
+            sfree(fingerprint);
+            sfree(keylist);
+            return PAGEANT_ACTION_FAILURE;
+        }
+        comment = dupprintf("%.*s", (int)n, (const char *)p);
+        p += n, keylistlen -= n;
+
+        callback(callback_ctx, fingerprint, comment);
+        sfree(fingerprint);
+        sfree(comment);
+    }
+
+    sfree(keylist);
+
+    if (keylistlen != 0) {
+        *retstr = dupstr("Received broken SSH-1 key list from agent");
+        return PAGEANT_ACTION_FAILURE;
+    }
+
+    return PAGEANT_ACTION_OK;
+}
index c1bc854ebe2e315693271d797f2357bc3363782f..ec94a50c9961b81603ddc141e3f590a941acdd50 100644 (file)
--- a/pageant.h
+++ b/pageant.h
@@ -120,3 +120,8 @@ enum {
 int pageant_add_keyfile(Filename *filename, const char *passphrase,
                         char **retstr);
 void pageant_forget_passphrases(void);
+typedef void (*pageant_key_enum_fn_t)(void *ctx,
+                                      const char *fingerprint,
+                                      const char *comment);
+int pageant_enum_keys(pageant_key_enum_fn_t callback, void *callback_ctx,
+                      char **retstr);
index 6151709747476d2711b19309427500912866399a..4d2aa08eb1a5ba587d23c215240d887d5edc16bf 100644 (file)
@@ -354,10 +354,16 @@ static int unix_add_keyfile(const char *filename_str)
     return ret;
 }
 
+void key_list_callback(void *ctx, const char *fingerprint, const char *comment)
+{
+    printf("%s %s\n", fingerprint, comment);
+}
+
 void run_client(void)
 {
     const struct cmdline_key_action *act;
     int errors = FALSE;
+    char *retstr;
 
     if (!agent_exists()) {
         fprintf(stderr, "pageant: no agent running to talk to\n");
@@ -370,9 +376,16 @@ void run_client(void)
             if (!unix_add_keyfile(act->filename))
                 errors = TRUE;
             break;
+          case KEYACT_CLIENT_LIST:
+            if (pageant_enum_keys(key_list_callback, NULL, &retstr) ==
+                PAGEANT_ACTION_FAILURE) {
+                fprintf(stderr, "pageant: listing keys: %s\n", retstr);
+                sfree(retstr);
+                errors = TRUE;
+            }
+            break;
           case KEYACT_CLIENT_DEL:
           case KEYACT_CLIENT_DEL_ALL:
-          case KEYACT_CLIENT_LIST:
           case KEYACT_CLIENT_LIST_FULL:
             fprintf(stderr, "NYI\n");
             errors = TRUE;