diff options
-rw-r--r-- | src/command/commands.c | 19 | ||||
-rw-r--r-- | src/pgp/gpg.c | 102 | ||||
-rw-r--r-- | src/pgp/gpg.h | 9 | ||||
-rw-r--r-- | tests/unittests/pgp/stub_gpg.c | 6 |
4 files changed, 101 insertions, 35 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); diff --git a/tests/unittests/pgp/stub_gpg.c b/tests/unittests/pgp/stub_gpg.c index 79ff8933..bb5a9eca 100644 --- a/tests/unittests/pgp/stub_gpg.c +++ b/tests/unittests/pgp/stub_gpg.c @@ -5,7 +5,7 @@ void p_gpg_init(void) {} void p_gpg_close(void) {} -GSList* p_gpg_list_keys(void) +GHashTable* p_gpg_list_keys(void) { return NULL; } @@ -21,8 +21,6 @@ const char* p_gpg_libver(void) return NULL; } -void p_gpg_free_key(ProfPGPKey *key) {} - void p_gpg_verify(const char * const barejid, const char *const sign) {} char* p_gpg_sign(const char * const str, const char * const fp) @@ -54,3 +52,5 @@ gboolean p_gpg_addkey(const char * const jid, const char * const keyid) void p_gpg_free_decrypted(char *decrypted) {} +void p_gpg_free_keys(GHashTable *keys) {} + |