diff options
author | James Booth <boothj5@gmail.com> | 2015-08-25 00:21:49 +0100 |
---|---|---|
committer | James Booth <boothj5@gmail.com> | 2015-08-25 00:21:49 +0100 |
commit | f6a91145b60ce924daaee6b2d5b9449c6170d9f9 (patch) | |
tree | 98f6fc96549928caca38276459dcbdaa7d7802b6 /src | |
parent | d6ff72cf48bddf64e0e7e4b77929d0996770b2e6 (diff) | |
download | profani-tty-f6a91145b60ce924daaee6b2d5b9449c6170d9f9.tar.gz |
Show public/private indicator when listing PGP keys
Diffstat (limited to 'src')
-rw-r--r-- | src/command/commands.c | 19 | ||||
-rw-r--r-- | src/pgp/gpg.c | 102 | ||||
-rw-r--r-- | src/pgp/gpg.h | 9 |
3 files changed, 98 insertions, 32 deletions
diff --git a/src/command/commands.c b/src/command/commands.c index 082b1bf8..f3911aad 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -4211,22 +4211,29 @@ cmd_pgp(ProfWin *window, const char * const command, gchar **args) } if (g_strcmp0(args[0], "keys") == 0) { - GSList *keys = p_gpg_list_keys(); - if (!keys) { + GHashTable *keys = p_gpg_list_keys(); + if (!keys || g_hash_table_size(keys) == 0) { cons_show("No keys found"); return TRUE; } cons_show("PGP keys:"); - GSList *curr = keys; + GList *keylist = g_hash_table_get_keys(keys); + GList *curr = keylist; while (curr) { - ProfPGPKey *key = curr->data; + ProfPGPKey *key = g_hash_table_lookup(keys, curr->data); cons_show(" %s", key->name); cons_show(" ID : %s", key->id); cons_show(" Fingerprint : %s", key->fp); - curr = g_slist_next(curr); + if (key->secret) { + cons_show(" Type : PUBLIC, PRIVATE"); + } else { + cons_show(" Type : PUBLIC"); + } + curr = g_list_next(curr); } - g_slist_free_full(keys, (GDestroyNotify)p_gpg_free_key); + g_list_free(keylist); + p_gpg_free_keys(keys); return TRUE; } diff --git a/src/pgp/gpg.c b/src/pgp/gpg.c index 6edab8d1..9d594be4 100644 --- a/src/pgp/gpg.c +++ b/src/pgp/gpg.c @@ -215,11 +215,38 @@ p_gpg_addkey(const char * const jid, const char * const keyid) return TRUE; } -GSList * +static ProfPGPKey * +_p_gpg_key_new(void) +{ + ProfPGPKey *p_pgpkey = malloc(sizeof(ProfPGPKey)); + p_pgpkey->id = NULL; + p_pgpkey->name = NULL; + p_pgpkey->fp = NULL; + p_pgpkey->encrypt = FALSE; + p_pgpkey->sign = FALSE; + p_pgpkey->certify = FALSE; + p_pgpkey->authenticate = FALSE; + p_pgpkey->secret = FALSE; + + return p_pgpkey; +} + +static void +_p_gpg_free_key(ProfPGPKey *key) +{ + if (key) { + free(key->id); + free(key->name); + free(key->fp); + free(key); + } +} + +GHashTable * p_gpg_list_keys(void) { gpgme_error_t error; - GSList *result = NULL; + GHashTable *result = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_p_gpg_free_key); gpgme_ctx_t ctx; error = gpgme_new(&ctx); @@ -231,25 +258,56 @@ p_gpg_list_keys(void) error = gpgme_op_keylist_start(ctx, NULL, 0); if (error == GPG_ERR_NO_ERROR) { + gpgme_key_t key; + error = gpgme_op_keylist_next(ctx, &key); while (!error) { - gpgme_key_t key; - error = gpgme_op_keylist_next(ctx, &key); + gpgme_subkey_t sub = key->subkeys; - if (error) { - break; + ProfPGPKey *p_pgpkey = _p_gpg_key_new(); + p_pgpkey->id = strdup(sub->keyid); + p_pgpkey->name = strdup(key->uids->uid); + p_pgpkey->fp = strdup(sub->fpr); + if (sub->can_encrypt) p_pgpkey->encrypt = TRUE; + if (sub->can_authenticate) p_pgpkey->authenticate = TRUE; + if (sub->can_certify) p_pgpkey->certify = TRUE; + if (sub->can_sign) p_pgpkey->sign = TRUE; + + sub = sub->next; + while (sub) { + if (sub->can_encrypt) p_pgpkey->encrypt = TRUE; + if (sub->can_authenticate) p_pgpkey->authenticate = TRUE; + if (sub->can_certify) p_pgpkey->certify = TRUE; + if (sub->can_sign) p_pgpkey->sign = TRUE; + + sub = sub->next; } - ProfPGPKey *p_pgpkey = malloc(sizeof(ProfPGPKey)); - p_pgpkey->id = strdup(key->subkeys->keyid); - p_pgpkey->name = strdup(key->uids->uid); - p_pgpkey->fp = strdup(key->subkeys->fpr); + g_hash_table_insert(result, strdup(p_pgpkey->name), p_pgpkey); - result = g_slist_append(result, p_pgpkey); + gpgme_key_unref(key); + error = gpgme_op_keylist_next(ctx, &key); + } + } + + error = gpgme_op_keylist_start(ctx, NULL, 1); + if (error == GPG_ERR_NO_ERROR) { + gpgme_key_t key; + error = gpgme_op_keylist_next(ctx, &key); + while (!error) { + gpgme_subkey_t sub = key->subkeys; + while (sub) { + if (sub->secret) { + ProfPGPKey *p_pgpkey = g_hash_table_lookup(result, key->uids->uid); + if (p_pgpkey) { + p_pgpkey->secret = TRUE; + } + } + sub = sub->next; + } gpgme_key_unref(key); + error = gpgme_op_keylist_next(ctx, &key); } - } else { - log_error("GPG: Could not list keys. %s %s", gpgme_strsource(error), gpgme_strerror(error)); } gpgme_release(ctx); @@ -257,6 +315,13 @@ p_gpg_list_keys(void) return result; } +void +p_gpg_free_keys(GHashTable *keys) +{ + g_hash_table_destroy(keys); +} + + GHashTable * p_gpg_fingerprints(void) { @@ -269,17 +334,6 @@ p_gpg_libver(void) return libversion; } -void -p_gpg_free_key(ProfPGPKey *key) -{ - if (key) { - free(key->id); - free(key->name); - free(key->fp); - free(key); - } -} - gboolean p_gpg_valid_key(const char * const keyid) { diff --git a/src/pgp/gpg.h b/src/pgp/gpg.h index 3bdae37e..f4c3f4a2 100644 --- a/src/pgp/gpg.h +++ b/src/pgp/gpg.h @@ -39,19 +39,24 @@ typedef struct pgp_key_t { char *id; char *name; char *fp; + gboolean encrypt; + gboolean sign; + gboolean certify; + gboolean authenticate; + gboolean secret; } ProfPGPKey; void p_gpg_init(void); void p_gpg_close(void); void p_gpg_on_connect(const char * const barejid); void p_gpg_on_disconnect(void); -GSList* p_gpg_list_keys(void); +GHashTable* p_gpg_list_keys(void); +void p_gpg_free_keys(GHashTable *keys); gboolean p_gpg_addkey(const char * const jid, const char * const keyid); GHashTable* p_gpg_fingerprints(void); gboolean p_gpg_valid_key(const char * const keyid); gboolean p_gpg_available(const char * const barejid); const char* p_gpg_libver(void); -void p_gpg_free_key(ProfPGPKey *key); char* p_gpg_sign(const char * const str, const char * const fp); void p_gpg_verify(const char * const barejid, const char *const sign); char* p_gpg_encrypt(const char * const barejid, const char * const message); |