1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-09-22 19:45:54 -04: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 * _bookmark_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 * _statuses_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 } } },
{ "/pgp",
cmd_pgp, parse_args, 1, 1, NULL,
{ "/pgp keys|libver", "Open PGP.",
{ "/pgp keys|libver",
"----------------",
cmd_pgp, parse_args, 1, 3, NULL,
{ "/pgp keys|libver|fps|start [contact]", "Open PGP.",
{ "/pgp keys|libver|fps|start [contact]",
"------------------------------------",
"Open PGP.",
"keys : List private keys."
"libver : Show which version of the libgpgme library is being used.",
"keys : List private keys."
"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 } } },
{ "/otr",
@ -1597,6 +1600,7 @@ cmd_init(void)
autocomplete_add(pgp_ac, "keys");
autocomplete_add(pgp_ac, "fps");
autocomplete_add(pgp_ac, "libver");
autocomplete_add(pgp_ac, "start");
}
void
@ -2017,8 +2021,8 @@ _cmd_complete_parameters(ProfWin *window, const char * const input)
}
}
gchar *cmds[] = { "/help", "/prefs", "/disco", "/close", "/wins", "/subject", "/room", "/pgp" };
Autocomplete completers[] = { help_ac, prefs_ac, disco_ac, close_ac, wins_ac, subject_ac, room_ac, pgp_ac };
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 };
for (i = 0; i < ARRAY_SIZE(cmds); i++) {
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, "/autoconnect", _autoconnect_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, "/statuses", _statuses_autocomplete);
g_hash_table_insert(ac_funcs, "/alias", _alias_autocomplete);
@ -2468,6 +2473,24 @@ _otr_autocomplete(ProfWin *window, const char * const input)
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 *
_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) {
cons_show("Usage: %s", help.usage);
return TRUE;
} else if (g_strcmp0(args[0], "keys") == 0) {
}
if (g_strcmp0(args[0], "keys") == 0) {
GSList *keys = p_gpg_list_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 {
if (!keys) {
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);
} 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();
if (conn_status != JABBER_CONNECTED) {
cons_show("You are not currently connected.");
} else {
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);
return TRUE;
}
} 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();
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 {
if (!libver) {
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();
if (conn_status != JABBER_CONNECTED) {
cons_show("You must be connected to start PGP encrpytion.");
} else if (window->type != WIN_CHAT && args[1] == NULL) {
cons_show("You must be in a regular chat window to start PGP encrpytion.");
return TRUE;
}
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;

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
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);
GSList* p_gpg_list_keys(void);
GHashTable* p_gpg_fingerprints(void);
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);

View File

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

View File

@ -91,7 +91,8 @@ typedef enum {
typedef enum {
PROF_ENC_NONE,
PROF_ENC_OTR
PROF_ENC_OTR,
PROF_ENC_PGP
} prof_enc_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;
}
gboolean p_gpg_available(const char * const barejid)
{
return FALSE;
}