about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2015-06-20 23:49:24 +0100
committerJames Booth <boothj5@gmail.com>2015-06-20 23:49:24 +0100
commit6617bb5a2b432d9c4178984386855f30be76ecf3 (patch)
tree2ff69c01e8d01013e377cec841317becd3d3267a /src
parent16999a396497c90778ef6bdbab11a419a570aa0f (diff)
downloadprofani-tty-6617bb5a2b432d9c4178984386855f30be76ecf3.tar.gz
Added window encyption mode for PGP
Diffstat (limited to 'src')
-rw-r--r--src/command/command.c39
-rw-r--r--src/command/commands.c139
-rw-r--r--src/pgp/gpg.c7
-rw-r--r--src/pgp/gpg.h1
-rw-r--r--src/ui/titlebar.c97
-rw-r--r--src/ui/win_types.h3
6 files changed, 198 insertions, 88 deletions
diff --git a/src/command/command.c b/src/command/command.c
index fbb9f29d..5e38a7be 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -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);
@@ -2469,6 +2474,24 @@ _otr_autocomplete(ProfWin *window, const char * const input)
 }
 
 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)
 {
     char *result = NULL;
diff --git a/src/command/commands.c b/src/command/commands.c
index 113532a5..6717157e 100644
--- a/src/command/commands.c
+++ b/src/command/commands.c
@@ -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) {
+            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;
diff --git a/src/pgp/gpg.c b/src/pgp/gpg.c
index 1cc96bfb..ce40690f 100644
--- a/src/pgp/gpg.c
+++ b/src/pgp/gpg.c
@@ -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)
 {
diff --git a/src/pgp/gpg.h b/src/pgp/gpg.h
index fb1f0f6b..74d86568 100644
--- a/src/pgp/gpg.h
+++ b/src/pgp/gpg.h
@@ -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);
diff --git a/src/ui/titlebar.c b/src/ui/titlebar.c
index 746d2782..81e1f33a 100644
--- a/src/ui/titlebar.c
+++ b/src/ui/titlebar.c
@@ -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);
+
+    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;
 
-    if (chatwin->enc_mode == PROF_ENC_NONE) {
-        if (prefs_get_boolean(PREF_OTR_WARN)) {
-            int unencrypted_attrs = theme_attrs(THEME_TITLE_UNENCRYPTED);
+        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);
-            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 {
-            int untrusted_attrs = theme_attrs(THEME_TITLE_UNTRUSTED);
+            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, untrusted_attrs);
-            wprintw(win, "untrusted");
-            wattroff(win, untrusted_attrs);
+            wattron(win, encrypted_attrs);
+            wprintw(win, "PGP");
+            wattroff(win, encrypted_attrs);
             wattron(win, bracket_attrs);
             wprintw(win, "]");
             wattroff(win, bracket_attrs);
-        }
+            break;
     }
 }
-#endif
 
 static void
 _show_contact_presence(ProfChatWin *chatwin)
diff --git a/src/ui/win_types.h b/src/ui/win_types.h
index 7e757b88..3214fa94 100644
--- a/src/ui/win_types.h
+++ b/src/ui/win_types.h
@@ -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 {