1
1
mirror of https://github.com/profanity-im/profanity.git synced 2025-02-02 15:08:15 -05:00

Added window encyption mode for PGP

This commit is contained in:
James Booth 2015-06-20 23:49:24 +01:00
parent 16999a3964
commit 6617bb5a2b
7 changed files with 204 additions and 89 deletions

View File

@ -83,6 +83,7 @@ static char * _roster_autocomplete(ProfWin *window, const char * const input);
static char * _group_autocomplete(ProfWin *window, const char * const input); static char * _group_autocomplete(ProfWin *window, const char * const input);
static char * _bookmark_autocomplete(ProfWin *window, const char * const input); static char * _bookmark_autocomplete(ProfWin *window, const char * const input);
static char * _otr_autocomplete(ProfWin *window, const char * const input); static char * _otr_autocomplete(ProfWin *window, const char * const input);
static char * _pgp_autocomplete(ProfWin *window, const char * const input);
static char * _connect_autocomplete(ProfWin *window, const char * const input); static char * _connect_autocomplete(ProfWin *window, const char * const input);
static char * _statuses_autocomplete(ProfWin *window, const char * const input); static char * _statuses_autocomplete(ProfWin *window, const char * const input);
static char * _alias_autocomplete(ProfWin *window, const char * const input); static char * _alias_autocomplete(ProfWin *window, const char * const input);
@ -860,13 +861,15 @@ static struct cmd_t command_defs[] =
NULL } } }, NULL } } },
{ "/pgp", { "/pgp",
cmd_pgp, parse_args, 1, 1, NULL, cmd_pgp, parse_args, 1, 3, NULL,
{ "/pgp keys|libver", "Open PGP.", { "/pgp keys|libver|fps|start [contact]", "Open PGP.",
{ "/pgp keys|libver", { "/pgp keys|libver|fps|start [contact]",
"----------------", "------------------------------------",
"Open PGP.", "Open PGP.",
"keys : List private keys." "keys : List private keys."
"libver : Show which version of the libgpgme library is being used.", "libver : Show which version of the libgpgme library is being used.",
"fps : Show received fingerprints.",
"start [contact] : Start PGP encrypted chat, current contact will be used if not specified.",
NULL } } }, NULL } } },
{ "/otr", { "/otr",
@ -1597,6 +1600,7 @@ cmd_init(void)
autocomplete_add(pgp_ac, "keys"); autocomplete_add(pgp_ac, "keys");
autocomplete_add(pgp_ac, "fps"); autocomplete_add(pgp_ac, "fps");
autocomplete_add(pgp_ac, "libver"); autocomplete_add(pgp_ac, "libver");
autocomplete_add(pgp_ac, "start");
} }
void void
@ -2017,8 +2021,8 @@ _cmd_complete_parameters(ProfWin *window, const char * const input)
} }
} }
gchar *cmds[] = { "/help", "/prefs", "/disco", "/close", "/wins", "/subject", "/room", "/pgp" }; gchar *cmds[] = { "/help", "/prefs", "/disco", "/close", "/wins", "/subject", "/room" };
Autocomplete completers[] = { help_ac, prefs_ac, disco_ac, close_ac, wins_ac, subject_ac, room_ac, pgp_ac }; Autocomplete completers[] = { help_ac, prefs_ac, disco_ac, close_ac, wins_ac, subject_ac, room_ac };
for (i = 0; i < ARRAY_SIZE(cmds); i++) { for (i = 0; i < ARRAY_SIZE(cmds); i++) {
result = autocomplete_param_with_ac(input, cmds[i], completers[i], TRUE); result = autocomplete_param_with_ac(input, cmds[i], completers[i], TRUE);
@ -2040,6 +2044,7 @@ _cmd_complete_parameters(ProfWin *window, const char * const input)
g_hash_table_insert(ac_funcs, "/bookmark", _bookmark_autocomplete); g_hash_table_insert(ac_funcs, "/bookmark", _bookmark_autocomplete);
g_hash_table_insert(ac_funcs, "/autoconnect", _autoconnect_autocomplete); g_hash_table_insert(ac_funcs, "/autoconnect", _autoconnect_autocomplete);
g_hash_table_insert(ac_funcs, "/otr", _otr_autocomplete); g_hash_table_insert(ac_funcs, "/otr", _otr_autocomplete);
g_hash_table_insert(ac_funcs, "/pgp", _pgp_autocomplete);
g_hash_table_insert(ac_funcs, "/connect", _connect_autocomplete); g_hash_table_insert(ac_funcs, "/connect", _connect_autocomplete);
g_hash_table_insert(ac_funcs, "/statuses", _statuses_autocomplete); g_hash_table_insert(ac_funcs, "/statuses", _statuses_autocomplete);
g_hash_table_insert(ac_funcs, "/alias", _alias_autocomplete); g_hash_table_insert(ac_funcs, "/alias", _alias_autocomplete);
@ -2468,6 +2473,24 @@ _otr_autocomplete(ProfWin *window, const char * const input)
return NULL; return NULL;
} }
static char *
_pgp_autocomplete(ProfWin *window, const char * const input)
{
char *found = NULL;
found = autocomplete_param_with_func(input, "/pgp start", roster_contact_autocomplete);
if (found) {
return found;
}
found = autocomplete_param_with_ac(input, "/pgp", pgp_ac, TRUE);
if (found) {
return found;
}
return NULL;
}
static char * static char *
_theme_autocomplete(ProfWin *window, const char * const input) _theme_autocomplete(ProfWin *window, const char * const input)
{ {

View File

@ -4143,59 +4143,124 @@ cmd_pgp(ProfWin *window, gchar **args, struct cmd_help_t help)
if (args[0] == NULL) { if (args[0] == NULL) {
cons_show("Usage: %s", help.usage); cons_show("Usage: %s", help.usage);
return TRUE; return TRUE;
} else if (g_strcmp0(args[0], "keys") == 0) { }
if (g_strcmp0(args[0], "keys") == 0) {
GSList *keys = p_gpg_list_keys(); GSList *keys = p_gpg_list_keys();
if (keys) { if (!keys) {
cons_show("PGP keys:");
while (keys) {
ProfPGPKey *key = keys->data;
cons_show(" %s", key->name);
cons_show(" ID : %s", key->id);
cons_show(" Fingerprint : %s", key->fp);
keys = g_slist_next(keys);
}
} else {
cons_show("No keys found"); cons_show("No keys found");
return TRUE;
}
cons_show("PGP keys:");
GSList *curr = keys;
while (curr) {
ProfPGPKey *key = curr->data;
cons_show(" %s", key->name);
cons_show(" ID : %s", key->id);
cons_show(" Fingerprint : %s", key->fp);
curr = g_slist_next(curr);
} }
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) { return TRUE;
}
if (g_strcmp0(args[0], "fps") == 0) {
jabber_conn_status_t conn_status = jabber_get_connection_status(); jabber_conn_status_t conn_status = jabber_get_connection_status();
if (conn_status != JABBER_CONNECTED) { if (conn_status != JABBER_CONNECTED) {
cons_show("You are not currently connected."); cons_show("You are not currently connected.");
} else { return TRUE;
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) { GHashTable *fingerprints = p_gpg_fingerprints();
GList *jids = g_hash_table_get_keys(fingerprints);
if (!jids) {
cons_show("No PGP fingerprints received.");
return TRUE;
}
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);
}
g_list_free(jids);
return TRUE;
}
if (g_strcmp0(args[0], "libver") == 0) {
const char *libver = p_gpg_libver(); const char *libver = p_gpg_libver();
if (libver) { if (!libver) {
GString *fullstr = g_string_new("Using libgpgme version ");
g_string_append(fullstr, libver);
cons_show("%s", fullstr->str);
g_string_free(fullstr, TRUE);
} else {
cons_show("Could not get libgpgme version"); cons_show("Could not get libgpgme version");
return TRUE;
} }
} else if (g_strcmp0(args[0], "start") == 0) {
GString *fullstr = g_string_new("Using libgpgme version ");
g_string_append(fullstr, libver);
cons_show("%s", fullstr->str);
g_string_free(fullstr, TRUE);
return TRUE;
}
if (g_strcmp0(args[0], "start") == 0) {
jabber_conn_status_t conn_status = jabber_get_connection_status(); jabber_conn_status_t conn_status = jabber_get_connection_status();
if (conn_status != JABBER_CONNECTED) { if (conn_status != JABBER_CONNECTED) {
cons_show("You must be connected to start PGP encrpytion."); cons_show("You must be connected to start PGP encrpytion.");
} else if (window->type != WIN_CHAT && args[1] == NULL) { return TRUE;
cons_show("You must be in a regular chat window to start PGP encrpytion.");
} }
if (window->type != WIN_CHAT && args[1] == NULL) {
cons_show("You must be in a regular chat window to start PGP encrpytion.");
return TRUE;
}
ProfChatWin *chatwin = NULL;
if (args[1]) {
char *contact = args[1];
char *barejid = roster_barejid_from_name(contact);
if (barejid == NULL) {
barejid = contact;
}
chatwin = wins_get_chat(barejid);
if (!chatwin) {
chatwin = ui_ev_new_chat_win(barejid);
}
ui_ev_focus_win((ProfWin*)chatwin);
} else {
chatwin = (ProfChatWin*)window;
assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
}
if (chatwin->enc_mode == PROF_ENC_OTR) {
ui_current_print_formatted_line('!', 0, "You must end the OTR session to start PGP encryption.");
return TRUE;
}
if (chatwin->enc_mode == PROF_ENC_PGP) {
ui_current_print_formatted_line('!', 0, "You have already started PGP encryption.");
return TRUE;
}
ProfAccount *account = accounts_get_account(jabber_get_account_name());
if (!account->pgp_keyid) {
ui_current_print_formatted_line('!', 0, "You must specify a PGP key ID for this account to start PGP encryption.");
account_free(account);
return TRUE;
}
account_free(account);
if (!p_gpg_available(chatwin->barejid)) {
ui_current_print_formatted_line('!', 0, "No PGP key found for %s.", chatwin->barejid);
return TRUE;
}
chatwin->enc_mode = PROF_ENC_PGP;
ui_current_print_formatted_line('!', 0, "PGP encyption enabled.");
} }
return TRUE; return TRUE;

View File

@ -132,6 +132,13 @@ p_gpg_free_key(ProfPGPKey *key)
} }
} }
gboolean
p_gpg_available(const char * const barejid)
{
char *fp = g_hash_table_lookup(fingerprints, barejid);
return (fp != NULL);
}
void void
p_gpg_verify(const char * const barejid, const char *const sign) p_gpg_verify(const char * const barejid, const char *const sign)
{ {

View File

@ -45,6 +45,7 @@ void p_gpg_init(void);
void p_gpg_close(void); void p_gpg_close(void);
GSList* p_gpg_list_keys(void); GSList* p_gpg_list_keys(void);
GHashTable* p_gpg_fingerprints(void); GHashTable* p_gpg_fingerprints(void);
gboolean p_gpg_available(const char * const barejid);
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(const char * const str, const char * const fp); char* p_gpg_sign(const char * const str, const char * const fp);

View File

@ -174,10 +174,7 @@ _title_bar_draw(void)
ProfChatWin *chatwin = (ProfChatWin*) current; ProfChatWin *chatwin = (ProfChatWin*) current;
assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
_show_contact_presence(chatwin); _show_contact_presence(chatwin);
#ifdef HAVE_LIBOTR
_show_privacy(chatwin); _show_privacy(chatwin);
#endif
if (typing) { if (typing) {
wprintw(win, " (typing...)"); wprintw(win, " (typing...)");
@ -246,66 +243,82 @@ _show_self_presence(void)
wattroff(win, bracket_attrs); wattroff(win, bracket_attrs);
} }
#ifdef HAVE_LIBOTR
static void static void
_show_privacy(ProfChatWin *chatwin) _show_privacy(ProfChatWin *chatwin)
{ {
int bracket_attrs = theme_attrs(THEME_TITLE_BRACKET); int bracket_attrs = theme_attrs(THEME_TITLE_BRACKET);
int encrypted_attrs = theme_attrs(THEME_TITLE_ENCRYPTED);
int unencrypted_attrs = theme_attrs(THEME_TITLE_UNENCRYPTED);
int trusted_attrs = theme_attrs(THEME_TITLE_TRUSTED);
int untrusted_attrs = theme_attrs(THEME_TITLE_UNTRUSTED);
if (chatwin->enc_mode == PROF_ENC_NONE) { switch (chatwin->enc_mode) {
if (prefs_get_boolean(PREF_OTR_WARN)) { case PROF_ENC_NONE:
int unencrypted_attrs = theme_attrs(THEME_TITLE_UNENCRYPTED); // TODO generalise to PROF_ENC_WARN
if (prefs_get_boolean(PREF_OTR_WARN)) {
wprintw(win, " ");
wattron(win, bracket_attrs);
wprintw(win, "[");
wattroff(win, bracket_attrs);
wattron(win, unencrypted_attrs);
wprintw(win, "unencrypted");
wattroff(win, unencrypted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
}
break;
case PROF_ENC_OTR:
wprintw(win, " "); wprintw(win, " ");
wattron(win, bracket_attrs); wattron(win, bracket_attrs);
wprintw(win, "["); wprintw(win, "[");
wattroff(win, bracket_attrs); wattroff(win, bracket_attrs);
wattron(win, unencrypted_attrs); wattron(win, encrypted_attrs);
wprintw(win, "unencrypted"); wprintw(win, "OTR");
wattroff(win, unencrypted_attrs); wattroff(win, encrypted_attrs);
wattron(win, bracket_attrs); wattron(win, bracket_attrs);
wprintw(win, "]"); wprintw(win, "]");
wattroff(win, bracket_attrs); wattroff(win, bracket_attrs);
} if (chatwin->otr_is_trusted) {
} else { wprintw(win, " ");
int encrypted_attrs = theme_attrs(THEME_TITLE_ENCRYPTED); wattron(win, bracket_attrs);
wprintw(win, " "); wprintw(win, "[");
wattron(win, bracket_attrs); wattroff(win, bracket_attrs);
wprintw(win, "["); wattron(win, trusted_attrs);
wattroff(win, bracket_attrs); wprintw(win, "trusted");
wattron(win, encrypted_attrs); wattroff(win, trusted_attrs);
wprintw(win, "OTR"); wattron(win, bracket_attrs);
wattroff(win, encrypted_attrs); wprintw(win, "]");
wattron(win, bracket_attrs); wattroff(win, bracket_attrs);
wprintw(win, "]"); } else {
wattroff(win, bracket_attrs); wprintw(win, " ");
if (chatwin->otr_is_trusted) { wattron(win, bracket_attrs);
int trusted_attrs = theme_attrs(THEME_TITLE_TRUSTED); wprintw(win, "[");
wattroff(win, bracket_attrs);
wattron(win, untrusted_attrs);
wprintw(win, "untrusted");
wattroff(win, untrusted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
}
break;
case PROF_ENC_PGP:
wprintw(win, " "); wprintw(win, " ");
wattron(win, bracket_attrs); wattron(win, bracket_attrs);
wprintw(win, "["); wprintw(win, "[");
wattroff(win, bracket_attrs); wattroff(win, bracket_attrs);
wattron(win, trusted_attrs); wattron(win, encrypted_attrs);
wprintw(win, "trusted"); wprintw(win, "PGP");
wattroff(win, trusted_attrs); wattroff(win, encrypted_attrs);
wattron(win, bracket_attrs); wattron(win, bracket_attrs);
wprintw(win, "]"); wprintw(win, "]");
wattroff(win, bracket_attrs); wattroff(win, bracket_attrs);
} else { break;
int untrusted_attrs = theme_attrs(THEME_TITLE_UNTRUSTED);
wprintw(win, " ");
wattron(win, bracket_attrs);
wprintw(win, "[");
wattroff(win, bracket_attrs);
wattron(win, untrusted_attrs);
wprintw(win, "untrusted");
wattroff(win, untrusted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
}
} }
} }
#endif
static void static void
_show_contact_presence(ProfChatWin *chatwin) _show_contact_presence(ProfChatWin *chatwin)

View File

@ -91,7 +91,8 @@ typedef enum {
typedef enum { typedef enum {
PROF_ENC_NONE, PROF_ENC_NONE,
PROF_ENC_OTR PROF_ENC_OTR,
PROF_ENC_PGP
} prof_enc_t; } prof_enc_t;
typedef struct prof_win_t { typedef struct prof_win_t {

View File

@ -30,3 +30,8 @@ char* p_gpg_sign(const char * const str, const char * const fp)
return NULL; return NULL;
} }
gboolean p_gpg_available(const char * const barejid)
{
return FALSE;
}