mirror of
https://github.com/profanity-im/profanity.git
synced 2025-01-03 14:57:42 -05:00
Added signature verification, /pgp fps command
This commit is contained in:
parent
b87130b601
commit
551f7df1f7
@ -1579,6 +1579,7 @@ cmd_init(void)
|
|||||||
|
|
||||||
pgp_ac = autocomplete_new();
|
pgp_ac = autocomplete_new();
|
||||||
autocomplete_add(pgp_ac, "keys");
|
autocomplete_add(pgp_ac, "keys");
|
||||||
|
autocomplete_add(pgp_ac, "fps");
|
||||||
autocomplete_add(pgp_ac, "libver");
|
autocomplete_add(pgp_ac, "libver");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4093,6 +4093,22 @@ cmd_pgp(gchar **args, struct cmd_help_t help)
|
|||||||
cons_show("No keys found");
|
cons_show("No keys found");
|
||||||
}
|
}
|
||||||
g_slist_free_full(keys, (GDestroyNotify)p_gpg_free_key);
|
g_slist_free_full(keys, (GDestroyNotify)p_gpg_free_key);
|
||||||
|
} else if (g_strcmp0(args[0], "fps") == 0) {
|
||||||
|
GHashTable *fingerprints = p_gpg_fingerprints();
|
||||||
|
GList *jids = g_hash_table_get_keys(fingerprints);
|
||||||
|
if (jids) {
|
||||||
|
cons_show("Received PGP fingerprints:");
|
||||||
|
GList *curr = jids;
|
||||||
|
while (curr) {
|
||||||
|
char *jid = curr->data;
|
||||||
|
char *fingerprint = g_hash_table_lookup(fingerprints, jid);
|
||||||
|
cons_show(" %s: %s", jid, fingerprint);
|
||||||
|
curr = g_list_next(curr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cons_show("No PGP fingerprints received.");
|
||||||
|
}
|
||||||
|
g_list_free(jids);
|
||||||
} else if (g_strcmp0(args[0], "libver") == 0) {
|
} else if (g_strcmp0(args[0], "libver") == 0) {
|
||||||
const char *libver = p_gpg_libver();
|
const char *libver = p_gpg_libver();
|
||||||
if (libver) {
|
if (libver) {
|
||||||
|
@ -42,11 +42,14 @@
|
|||||||
#include "pgp/gpg.h"
|
#include "pgp/gpg.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#define PGP_HEADER "-----BEGIN PGP SIGNATURE-----"
|
||||||
#define PGP_FOOTER "-----END PGP SIGNATURE-----"
|
#define PGP_FOOTER "-----END PGP SIGNATURE-----"
|
||||||
|
|
||||||
static const char *libversion;
|
static const char *libversion;
|
||||||
|
static GHashTable *fingerprints;
|
||||||
|
|
||||||
static char* _remove_header_footer(char *str);
|
static char* _remove_header_footer(char *str);
|
||||||
|
static char* _add_header_footer(const char * const str);
|
||||||
|
|
||||||
void
|
void
|
||||||
p_gpg_init(void)
|
p_gpg_init(void)
|
||||||
@ -54,6 +57,15 @@ p_gpg_init(void)
|
|||||||
libversion = gpgme_check_version(NULL);
|
libversion = gpgme_check_version(NULL);
|
||||||
log_debug("GPG: Found gpgme version: %s", libversion);
|
log_debug("GPG: Found gpgme version: %s", libversion);
|
||||||
gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
|
gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
|
||||||
|
|
||||||
|
// TODO add close function to clean up
|
||||||
|
fingerprints = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
p_gpg_close(void)
|
||||||
|
{
|
||||||
|
g_hash_table_destroy(fingerprints);
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList *
|
GSList *
|
||||||
@ -96,6 +108,12 @@ p_gpg_list_keys(void)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GHashTable *
|
||||||
|
p_gpg_fingerprints(void)
|
||||||
|
{
|
||||||
|
return fingerprints;
|
||||||
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
p_gpg_libver(void)
|
p_gpg_libver(void)
|
||||||
{
|
{
|
||||||
@ -113,6 +131,45 @@ p_gpg_free_key(ProfPGPKey *key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
p_gpg_verify(const char * const barejid, const char *const sign)
|
||||||
|
{
|
||||||
|
if (!sign) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpgme_ctx_t ctx;
|
||||||
|
gpgme_error_t error = gpgme_new(&ctx);
|
||||||
|
if (error) {
|
||||||
|
log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpgme_data_t sign_data;
|
||||||
|
gpgme_data_t plain_data;
|
||||||
|
char *sign_with_header_footer = _add_header_footer(sign);
|
||||||
|
gpgme_data_new_from_mem(&sign_data, sign_with_header_footer, strlen(sign_with_header_footer), 1);
|
||||||
|
gpgme_data_new(&plain_data);
|
||||||
|
|
||||||
|
error = gpgme_op_verify(ctx, sign_data, NULL, plain_data);
|
||||||
|
if (error) {
|
||||||
|
log_error("GPG: Failed to verify. %s %s", gpgme_strsource(error), gpgme_strerror(error));
|
||||||
|
gpgme_release(ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpgme_verify_result_t result = gpgme_op_verify_result(ctx);
|
||||||
|
if (result) {
|
||||||
|
if (result->signatures) {
|
||||||
|
log_debug("Fingerprint found for %s: %s ", barejid, result->signatures->fpr);
|
||||||
|
g_hash_table_replace(fingerprints, strdup(barejid), strdup(result->signatures->fpr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gpgme_data_release(sign_data);
|
||||||
|
gpgme_data_release(plain_data);
|
||||||
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
p_gpg_sign_str(const char * const str, const char * const fp)
|
p_gpg_sign_str(const char * const str, const char * const fp)
|
||||||
{
|
{
|
||||||
@ -196,4 +253,21 @@ _remove_header_footer(char *str)
|
|||||||
stripped[strlen(pointer)-strlen(PGP_FOOTER)] = '\0';
|
stripped[strlen(pointer)-strlen(PGP_FOOTER)] = '\0';
|
||||||
|
|
||||||
return stripped;
|
return stripped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char*
|
||||||
|
_add_header_footer(const char * const str)
|
||||||
|
{
|
||||||
|
GString *result_str = g_string_new("");
|
||||||
|
|
||||||
|
g_string_append(result_str, PGP_HEADER);
|
||||||
|
g_string_append(result_str, "\n\n");
|
||||||
|
g_string_append(result_str, str);
|
||||||
|
g_string_append(result_str, "\n");
|
||||||
|
g_string_append(result_str, PGP_FOOTER);
|
||||||
|
|
||||||
|
char *result = result_str->str;
|
||||||
|
g_string_free(result_str, FALSE);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -42,9 +42,12 @@ typedef struct pgp_key_t {
|
|||||||
} ProfPGPKey;
|
} ProfPGPKey;
|
||||||
|
|
||||||
void p_gpg_init(void);
|
void p_gpg_init(void);
|
||||||
|
void p_gpg_close(void);
|
||||||
GSList* p_gpg_list_keys(void);
|
GSList* p_gpg_list_keys(void);
|
||||||
|
GHashTable* p_gpg_fingerprints(void);
|
||||||
const char* p_gpg_libver(void);
|
const char* p_gpg_libver(void);
|
||||||
void p_gpg_free_key(ProfPGPKey *key);
|
void p_gpg_free_key(ProfPGPKey *key);
|
||||||
char* p_gpg_sign_str(const char * const str, const char * const fp);
|
char* p_gpg_sign_str(const char * const str, const char * const fp);
|
||||||
|
void p_gpg_verify(const char * const barejid, const char *const sign);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -270,6 +270,9 @@ _shutdown(void)
|
|||||||
ui_close();
|
ui_close();
|
||||||
#ifdef HAVE_LIBOTR
|
#ifdef HAVE_LIBOTR
|
||||||
otr_shutdown();
|
otr_shutdown();
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_LIBGPGME
|
||||||
|
p_gpg_close();
|
||||||
#endif
|
#endif
|
||||||
chat_log_close();
|
chat_log_close();
|
||||||
prefs_close();
|
prefs_close();
|
||||||
|
@ -232,20 +232,21 @@ presence_update(const resource_presence_t presence_type, const char * const msg,
|
|||||||
char *account_name = jabber_get_account_name();
|
char *account_name = jabber_get_account_name();
|
||||||
ProfAccount *account = accounts_get_account(account_name);
|
ProfAccount *account = accounts_get_account(account_name);
|
||||||
if (account->pgp_keyid) {
|
if (account->pgp_keyid) {
|
||||||
xmpp_stanza_t *x = xmpp_stanza_new(ctx);
|
|
||||||
xmpp_stanza_set_name(x, STANZA_NAME_X);
|
|
||||||
xmpp_stanza_set_ns(x, STANZA_NS_SIGNED);
|
|
||||||
xmpp_stanza_t *signed_text = xmpp_stanza_new(ctx);
|
|
||||||
|
|
||||||
char *signed_status = p_gpg_sign_str(msg, account->pgp_keyid);
|
char *signed_status = p_gpg_sign_str(msg, account->pgp_keyid);
|
||||||
|
|
||||||
xmpp_stanza_set_text(signed_text, signed_status);
|
if (signed_status) {
|
||||||
xmpp_stanza_add_child(x, signed_text);
|
xmpp_stanza_t *x = xmpp_stanza_new(ctx);
|
||||||
xmpp_stanza_release(signed_text);
|
xmpp_stanza_set_name(x, STANZA_NAME_X);
|
||||||
xmpp_stanza_add_child(presence, x);
|
xmpp_stanza_set_ns(x, STANZA_NS_SIGNED);
|
||||||
xmpp_stanza_release(x);
|
xmpp_stanza_t *signed_text = xmpp_stanza_new(ctx);
|
||||||
|
xmpp_stanza_set_text(signed_text, signed_status);
|
||||||
|
xmpp_stanza_add_child(x, signed_text);
|
||||||
|
xmpp_stanza_release(signed_text);
|
||||||
|
xmpp_stanza_add_child(presence, x);
|
||||||
|
xmpp_stanza_release(x);
|
||||||
|
|
||||||
free(signed_status);
|
free(signed_status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -606,6 +607,16 @@ _available_handler(xmpp_conn_t * const conn,
|
|||||||
log_debug("Presence available handler fired for: %s", jid);
|
log_debug("Presence available handler fired for: %s", jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGPGME
|
||||||
|
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_SIGNED);
|
||||||
|
if (x) {
|
||||||
|
char *sign = xmpp_stanza_get_text(x);
|
||||||
|
if (sign) {
|
||||||
|
p_gpg_verify(xmpp_presence->jid->barejid, sign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *my_jid_str = xmpp_conn_get_jid(conn);
|
const char *my_jid_str = xmpp_conn_get_jid(conn);
|
||||||
Jid *my_jid = jid_create(my_jid_str);
|
Jid *my_jid = jid_create(my_jid_str);
|
||||||
|
|
||||||
|
@ -3,13 +3,21 @@
|
|||||||
#include "pgp/gpg.h"
|
#include "pgp/gpg.h"
|
||||||
|
|
||||||
void p_gpg_init(void) {}
|
void p_gpg_init(void) {}
|
||||||
|
void p_gpg_close(void) {}
|
||||||
|
|
||||||
GSList* p_gpg_list_keys(void)
|
GSList* p_gpg_list_keys(void)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* p_gpg_libver(void) {
|
GHashTable*
|
||||||
|
p_gpg_fingerprints(void)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* p_gpg_libver(void)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user