about summary refs log tree commit diff stats
path: root/src/command
diff options
context:
space:
mode:
Diffstat (limited to 'src/command')
-rw-r--r--src/command/command.c62
-rw-r--r--src/command/commands.c134
-rw-r--r--src/command/commands.h1
3 files changed, 193 insertions, 4 deletions
diff --git a/src/command/command.c b/src/command/command.c
index 6d7aa627..ba976023 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -41,6 +41,7 @@
 #include "jid.h"
 #include "log.h"
 #include "muc.h"
+#include "otr.h"
 #include "profanity.h"
 #include "tools/autocomplete.h"
 #include "tools/parser.h"
@@ -567,6 +568,20 @@ static struct cmd_t command_defs[] =
           "Such as whether you have become inactive, or have closed the chat window.",
           NULL } } },
 
+    { "/otr",
+        cmd_otr, parse_args, 1, 2, NULL,
+        { "/otr gen|myfp|theirfp|start|end|trust|untrust", "Off The Record encryption commands.",
+        { "/otr gen|myfp|theirfp|start|end|trust|untrust",
+          "---------------------------------------------",
+          "gen - Generate your private key.",
+          "myfp - Show your fingerprint.",
+          "theirfp - Show contacts fingerprint.",
+          "start - Start an OTR session with the current recipient.",
+          "end - End the current OTR session,",
+          "trust - Indicate that you have verified the contact's fingerprint.",
+          "untrust - Indicate the the contact's fingerprint is not verified,",
+          NULL } } },
+
     { "/outtype",
         cmd_outtype, parse_args, 1, 1, &cons_outtype_setting,
         { "/outtype on|off", "Send typing notification to recipient.",
@@ -817,6 +832,7 @@ static Autocomplete wins_ac;
 static Autocomplete roster_ac;
 static Autocomplete group_ac;
 static Autocomplete bookmark_ac;
+static Autocomplete otr_ac;
 
 /*
  * Initialise command autocompleter and history
@@ -969,6 +985,15 @@ cmd_init(void)
     autocomplete_add(bookmark_ac, "list");
     autocomplete_add(bookmark_ac, "remove");
 
+    otr_ac = autocomplete_new();
+    autocomplete_add(otr_ac, "gen");
+    autocomplete_add(otr_ac, "start");
+    autocomplete_add(otr_ac, "end");
+    autocomplete_add(otr_ac, "myfp");
+    autocomplete_add(otr_ac, "theirfp");
+    autocomplete_add(otr_ac, "trust");
+    autocomplete_add(otr_ac, "untrust");
+
     cmd_history_init();
 }
 
@@ -999,6 +1024,7 @@ cmd_uninit(void)
     autocomplete_free(roster_ac);
     autocomplete_free(group_ac);
     autocomplete_free(bookmark_ac);
+    autocomplete_free(otr_ac);
 }
 
 // Command autocompletion functions
@@ -1072,6 +1098,7 @@ cmd_reset_autocomplete()
     autocomplete_reset(roster_ac);
     autocomplete_reset(group_ac);
     autocomplete_reset(bookmark_ac);
+    autocomplete_reset(otr_ac);
     bookmark_autocomplete_reset();
 }
 
@@ -1129,8 +1156,36 @@ cmd_execute_default(const char * const inp)
             if (status != JABBER_CONNECTED) {
                 ui_current_print_line("You are not currently connected.");
             } else {
+#ifdef HAVE_LIBOTR
+                if (otr_is_secure(recipient)) {
+                    char *encrypted = otr_encrypt_message(recipient, inp);
+                    if (encrypted != NULL) {
+                        message_send(encrypted, recipient);
+                        otr_free_message(encrypted);
+                        if (prefs_get_boolean(PREF_CHLOG)) {
+                            const char *jid = jabber_get_fulljid();
+                            Jid *jidp = jid_create(jid);
+                            chat_log_chat(jidp->barejid, recipient, inp, PROF_OUT_LOG, NULL);
+                            jid_destroy(jidp);
+                        }
+
+                        ui_outgoing_msg("me", recipient, inp);
+                    } else {
+                        cons_show_error("Failed to send message.");
+                    }
+                } else {
+                    message_send(inp, recipient);
+                    if (prefs_get_boolean(PREF_CHLOG)) {
+                        const char *jid = jabber_get_fulljid();
+                        Jid *jidp = jid_create(jid);
+                        chat_log_chat(jidp->barejid, recipient, inp, PROF_OUT_LOG, NULL);
+                        jid_destroy(jidp);
+                    }
+
+                    ui_outgoing_msg("me", recipient, inp);
+                }
+#else
                 message_send(inp, recipient);
-
                 if (prefs_get_boolean(PREF_CHLOG)) {
                     const char *jid = jabber_get_fulljid();
                     Jid *jidp = jid_create(jid);
@@ -1139,6 +1194,7 @@ cmd_execute_default(const char * const inp)
                 }
 
                 ui_outgoing_msg("me", recipient, inp);
+#endif
             }
             break;
 
@@ -1267,8 +1323,8 @@ _cmd_complete_parameters(char *input, int *size)
         return;
     }
 
-    gchar *cmds[] = { "/help", "/prefs", "/log", "/disco", "/close", "/wins" };
-    Autocomplete completers[] = { help_ac, prefs_ac, log_ac, disco_ac, close_ac, wins_ac };
+    gchar *cmds[] = { "/help", "/prefs", "/log", "/disco", "/close", "/wins", "/otr" };
+    Autocomplete completers[] = { help_ac, prefs_ac, log_ac, disco_ac, close_ac, wins_ac, otr_ac };
 
     for (i = 0; i < ARRAY_SIZE(cmds); i++) {
         result = autocomplete_param_with_ac(input, size, cmds[i], completers[i]);
diff --git a/src/command/commands.c b/src/command/commands.c
index e6588c11..d7ce2742 100644
--- a/src/command/commands.c
+++ b/src/command/commands.c
@@ -36,11 +36,14 @@
 #include "jid.h"
 #include "log.h"
 #include "muc.h"
+#include "otr.h"
 #include "profanity.h"
 #include "tools/autocomplete.h"
 #include "tools/parser.h"
 #include "tools/tinyurl.h"
 #include "ui/ui.h"
+#include "ui/window.h"
+#include "ui/windows.h"
 #include "xmpp/xmpp.h"
 #include "xmpp/bookmark.h"
 
@@ -915,6 +918,36 @@ cmd_msg(gchar **args, struct cmd_help_t help)
             usr_jid = usr;
         }
         if (msg != NULL) {
+#ifdef HAVE_LIBOTR
+            if (otr_is_secure(usr_jid)) {
+                char *encrypted = otr_encrypt_message(usr_jid, msg);
+                if (encrypted != NULL) {
+                    message_send(encrypted, usr_jid);
+                    otr_free_message(encrypted);
+                    ui_outgoing_msg("me", usr_jid, msg);
+
+                    if (((win_type == WIN_CHAT) || (win_type == WIN_CONSOLE)) && prefs_get_boolean(PREF_CHLOG)) {
+                        const char *jid = jabber_get_fulljid();
+                        Jid *jidp = jid_create(jid);
+                        chat_log_chat(jidp->barejid, usr_jid, msg, PROF_OUT_LOG, NULL);
+                        jid_destroy(jidp);
+                    }
+                } else {
+                    cons_show_error("Failed to encrypt and send message,");
+                }
+            } else {
+                message_send(msg, usr_jid);
+                ui_outgoing_msg("me", usr_jid, msg);
+
+                if (((win_type == WIN_CHAT) || (win_type == WIN_CONSOLE)) && prefs_get_boolean(PREF_CHLOG)) {
+                    const char *jid = jabber_get_fulljid();
+                    Jid *jidp = jid_create(jid);
+                    chat_log_chat(jidp->barejid, usr_jid, msg, PROF_OUT_LOG, NULL);
+                    jid_destroy(jidp);
+                }
+            }
+            return TRUE;
+#else
             message_send(msg, usr_jid);
             ui_outgoing_msg("me", usr_jid, msg);
 
@@ -924,8 +957,9 @@ cmd_msg(gchar **args, struct cmd_help_t help)
                 chat_log_chat(jidp->barejid, usr_jid, msg, PROF_OUT_LOG, NULL);
                 jid_destroy(jidp);
             }
-
             return TRUE;
+#endif
+
         } else {
             const char * jid = NULL;
 
@@ -2264,6 +2298,104 @@ cmd_xa(gchar **args, struct cmd_help_t help)
     return TRUE;
 }
 
+gboolean
+cmd_otr(gchar **args, struct cmd_help_t help)
+{
+#ifdef HAVE_LIBOTR
+    if (jabber_get_connection_status() != JABBER_CONNECTED) {
+        cons_show("You must be connected with an account to load OTR information.");
+        return TRUE;
+    }
+
+    if (strcmp(args[0], "gen") == 0) {
+        ProfAccount *account = accounts_get_account(jabber_get_account_name());
+        otr_keygen(account);
+        return TRUE;
+    } else if (strcmp(args[0], "myfp") == 0) {
+        char *fingerprint = otr_get_my_fingerprint();
+        ui_current_print_line("Your OTR fingerprint: %s", fingerprint);
+        free(fingerprint);
+        return TRUE;
+    } else if (strcmp(args[0], "theirfp") == 0) {
+        win_type_t win_type = ui_current_win_type();
+
+        if (win_type != WIN_CHAT) {
+            ui_current_print_line("You must be in a regular chat window to view a recipient's fingerprint.");
+        } else if (!ui_current_win_is_otr()) {
+            ui_current_print_line("You not currently in an OTR session with this recipient.");
+        } else {
+            char *recipient = ui_current_recipient();
+            char *fingerprint = otr_get_their_fingerprint(recipient);
+            ui_current_print_line("OTR fingerprint for %s: %s", recipient, fingerprint);
+            free(fingerprint);
+        }
+        return TRUE;
+    } else if (strcmp(args[0], "start") == 0) {
+        win_type_t win_type = ui_current_win_type();
+
+        if (win_type != WIN_CHAT) {
+            ui_current_print_line("You must be in a regular chat window to start an OTR session.");
+        } else if (ui_current_win_is_otr()) {
+            ui_current_print_line("You are already in an OTR session.");
+        } else {
+            if (!otr_key_loaded()) {
+                ui_current_print_line("You have not generated or loaded a private key, use '/otr gen'");
+            } else {
+                char *recipient = ui_current_recipient();
+                message_send("?OTR?", recipient);
+            }
+        }
+        return TRUE;
+    } else if (strcmp(args[0], "end") == 0) {
+        win_type_t win_type = ui_current_win_type();
+
+        if (win_type != WIN_CHAT) {
+            ui_current_print_line("You must be in a regular chat window to use OTR.");
+        } else if (!ui_current_win_is_otr()) {
+            ui_current_print_line("You are not currently in an OTR session.");
+        } else {
+            char *recipient = ui_current_recipient();
+            ui_gone_insecure(recipient);
+            otr_end_session(recipient);
+        }
+        return TRUE;
+    } else if (strcmp(args[0], "trust") == 0) {
+        win_type_t win_type = ui_current_win_type();
+
+        if (win_type != WIN_CHAT) {
+            ui_current_print_line("You must be in an OTR session to trust a recipient.");
+        } else if (!ui_current_win_is_otr()) {
+            ui_current_print_line("You are not currently in an OTR session.");
+        } else {
+            char *recipient = ui_current_recipient();
+            ui_trust(recipient);
+            otr_trust(recipient);
+        }
+        return TRUE;
+    } else if (strcmp(args[0], "untrust") == 0) {
+        win_type_t win_type = ui_current_win_type();
+
+        if (win_type != WIN_CHAT) {
+            ui_current_print_line("You must be in an OTR session to untrust a recipient.");
+        } else if (!ui_current_win_is_otr()) {
+            ui_current_print_line("You are not currently in an OTR session.");
+        } else {
+            char *recipient = ui_current_recipient();
+            ui_untrust(recipient);
+            otr_untrust(recipient);
+        }
+        return TRUE;
+
+    } else {
+        cons_show("Usage: %s", help.usage);
+        return TRUE;
+    }
+#else
+    cons_show("This version of Profanity has not been built with OTR support enabled");
+    return TRUE;
+#endif
+}
+
 // helper function for status change commands
 static void
 _update_presence(const resource_presence_t resource_presence,
diff --git a/src/command/commands.h b/src/command/commands.h
index 27a02249..741ab638 100644
--- a/src/command/commands.h
+++ b/src/command/commands.h
@@ -86,6 +86,7 @@ gboolean cmd_msg(gchar **args, struct cmd_help_t help);
 gboolean cmd_nick(gchar **args, struct cmd_help_t help);
 gboolean cmd_notify(gchar **args, struct cmd_help_t help);
 gboolean cmd_online(gchar **args, struct cmd_help_t help);
+gboolean cmd_otr(gchar **args, struct cmd_help_t help);
 gboolean cmd_outtype(gchar **args, struct cmd_help_t help);
 gboolean cmd_prefs(gchar **args, struct cmd_help_t help);
 gboolean cmd_priority(gchar **args, struct cmd_help_t help);