diff options
author | Michael Vetter <jubalh@iodoru.org> | 2019-04-11 10:58:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-11 10:58:22 +0200 |
commit | 61df0c8e8513a1aa9912e37019a63778ec3ed06c (patch) | |
tree | a52850f2f5fc225759c2287d1672ed22b5ef7f0a /src/command | |
parent | 6b064cfde4456c25bd9dbcbfe0a79262ebcb3599 (diff) | |
parent | f75e1d7a7b05c68f03b6b13163ac9f2b8824e7df (diff) | |
download | profani-tty-61df0c8e8513a1aa9912e37019a63778ec3ed06c.tar.gz |
Merge pull request #1039 from paulfariello/feature/omemo
Add basic OMEMO support.
Diffstat (limited to 'src/command')
-rw-r--r-- | src/command/cmd_ac.c | 82 | ||||
-rw-r--r-- | src/command/cmd_defs.c | 51 | ||||
-rw-r--r-- | src/command/cmd_funcs.c | 493 | ||||
-rw-r--r-- | src/command/cmd_funcs.h | 10 |
4 files changed, 633 insertions, 3 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index 58ad758a..0cc28bb3 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -57,6 +57,10 @@ #include "pgp/gpg.h" #endif +#ifdef HAVE_OMEMO +#include "omemo/omemo.h" +#endif + static char* _sub_autocomplete(ProfWin *window, const char *const input, gboolean previous); static char* _notify_autocomplete(ProfWin *window, const char *const input, gboolean previous); static char* _theme_autocomplete(ProfWin *window, const char *const input, gboolean previous); @@ -69,6 +73,7 @@ static char* _group_autocomplete(ProfWin *window, const char *const input, gbool static char* _bookmark_autocomplete(ProfWin *window, const char *const input, gboolean previous); static char* _otr_autocomplete(ProfWin *window, const char *const input, gboolean previous); static char* _pgp_autocomplete(ProfWin *window, const char *const input, gboolean previous); +static char* _omemo_autocomplete(ProfWin *window, const char *const input, gboolean previous); static char* _connect_autocomplete(ProfWin *window, const char *const input, gboolean previous); static char* _alias_autocomplete(ProfWin *window, const char *const input, gboolean previous); static char* _join_autocomplete(ProfWin *window, const char *const input, gboolean previous); @@ -157,6 +162,8 @@ static Autocomplete bookmark_property_ac; static Autocomplete otr_ac; static Autocomplete otr_log_ac; static Autocomplete otr_policy_ac; +static Autocomplete omemo_ac; +static Autocomplete omemo_log_ac; static Autocomplete connect_property_ac; static Autocomplete tls_property_ac; static Autocomplete alias_ac; @@ -237,6 +244,7 @@ cmd_ac_init(void) autocomplete_add(prefs_ac, "presence"); autocomplete_add(prefs_ac, "otr"); autocomplete_add(prefs_ac, "pgp"); + autocomplete_add(prefs_ac, "omemo"); notify_ac = autocomplete_new(); autocomplete_add(notify_ac, "chat"); @@ -574,6 +582,21 @@ cmd_ac_init(void) autocomplete_add(otr_policy_ac, "opportunistic"); autocomplete_add(otr_policy_ac, "always"); + omemo_ac = autocomplete_new(); + autocomplete_add(omemo_ac, "gen"); + autocomplete_add(omemo_ac, "log"); + autocomplete_add(omemo_ac, "start"); + autocomplete_add(omemo_ac, "end"); + autocomplete_add(omemo_ac, "trust"); + autocomplete_add(omemo_ac, "untrust"); + autocomplete_add(omemo_ac, "fingerprint"); + autocomplete_add(omemo_ac, "clear_device_list"); + + omemo_log_ac = autocomplete_new(); + autocomplete_add(omemo_log_ac, "on"); + autocomplete_add(omemo_log_ac, "off"); + autocomplete_add(omemo_log_ac, "redact"); + connect_property_ac = autocomplete_new(); autocomplete_add(connect_property_ac, "server"); autocomplete_add(connect_property_ac, "port"); @@ -983,6 +1006,9 @@ cmd_ac_reset(ProfWin *window) #ifdef HAVE_LIBGPGME p_gpg_autocomplete_key_reset(); #endif +#ifdef HAVE_OMEMO + omemo_fingerprint_autocomplete_reset(); +#endif autocomplete_reset(help_ac); autocomplete_reset(help_commands_ac); autocomplete_reset(notify_ac); @@ -1052,6 +1078,8 @@ cmd_ac_reset(ProfWin *window) autocomplete_reset(otr_ac); autocomplete_reset(otr_log_ac); autocomplete_reset(otr_policy_ac); + autocomplete_reset(omemo_ac); + autocomplete_reset(omemo_log_ac); autocomplete_reset(connect_property_ac); autocomplete_reset(tls_property_ac); autocomplete_reset(alias_ac); @@ -1179,6 +1207,8 @@ cmd_ac_uninit(void) autocomplete_free(otr_ac); autocomplete_free(otr_log_ac); autocomplete_free(otr_policy_ac); + autocomplete_free(omemo_ac); + autocomplete_free(omemo_log_ac); autocomplete_free(connect_property_ac); autocomplete_free(tls_property_ac); autocomplete_free(alias_ac); @@ -1438,6 +1468,7 @@ _cmd_ac_complete_params(ProfWin *window, const char *const input, gboolean previ 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, "/omemo", _omemo_autocomplete); g_hash_table_insert(ac_funcs, "/connect", _connect_autocomplete); g_hash_table_insert(ac_funcs, "/alias", _alias_autocomplete); g_hash_table_insert(ac_funcs, "/join", _join_autocomplete); @@ -2118,6 +2149,57 @@ _pgp_autocomplete(ProfWin *window, const char *const input, gboolean previous) } static char* +_omemo_autocomplete(ProfWin *window, const char *const input, gboolean previous) +{ + char *found = NULL; + + jabber_conn_status_t conn_status = connection_get_status(); + + if (conn_status == JABBER_CONNECTED) { + found = autocomplete_param_with_func(input, "/omemo start", roster_contact_autocomplete, previous); + if (found) { + return found; + } + } + + found = autocomplete_param_with_func(input, "/omemo fingerprint", roster_contact_autocomplete, previous); + if (found) { + return found; + } + +#ifdef HAVE_OMEMO + if (window->type == WIN_CHAT) { + found = autocomplete_param_with_func(input, "/omemo trust", omemo_fingerprint_autocomplete, previous); + if (found) { + return found; + } + } else { + found = autocomplete_param_with_func(input, "/omemo trust", roster_contact_autocomplete, previous); + if (found) { + return found; + } + + found = autocomplete_param_no_with_func(input, "/omemo trust", 4, omemo_fingerprint_autocomplete, previous); + if (found) { + return found; + } + } +#endif + + found = autocomplete_param_with_ac(input, "/omemo log", omemo_log_ac, TRUE, previous); + if (found) { + return found; + } + + found = autocomplete_param_with_ac(input, "/omemo", omemo_ac, TRUE, previous); + if (found) { + return found; + } + + return NULL; +} + +static char* _plugins_autocomplete(ProfWin *window, const char *const input, gboolean previous) { char *result = NULL; diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 4447020b..ee86aaba 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -2134,7 +2134,7 @@ static struct cmd_t command_defs[] = CMD_MAINFUNC(cmd_prefs) CMD_NOTAGS CMD_SYN( - "/prefs [ui|desktop|chat|log|conn|presence|otr|pgp]") + "/prefs [ui|desktop|chat|log|conn|presence|otr|pgp|omemo]") CMD_DESC( "Show preferences for different areas of functionality. " "Passing no arguments shows all preferences.") @@ -2146,7 +2146,8 @@ static struct cmd_t command_defs[] = { "conn", "Connection handling preferences." }, { "presence", "Chat presence preferences." }, { "otr", "Off The Record preferences." }, - { "pgp", "OpenPGP preferences." }) + { "pgp", "OpenPGP preferences." }, + { "omemo", "OMEMO preferences." }) CMD_NOEXAMPLES }, @@ -2328,7 +2329,51 @@ static struct cmd_t command_defs[] = CMD_EXAMPLES( "/cmd list", "/cmd exec ping") - } + }, + + { "/omemo", + parse_args, 1, 3, NULL, + CMD_SUBFUNCS( + { "gen", cmd_omemo_gen }, + { "log", cmd_omemo_log }, + { "start", cmd_omemo_start }, + { "end", cmd_omemo_end }, + { "trust", cmd_omemo_trust }, + { "untrust", cmd_omemo_untrust }, + { "fingerprint", cmd_omemo_fingerprint }, + { "char", cmd_omemo_char }, + { "clear_device_list", cmd_omemo_clear_device_list }) + CMD_NOMAINFUNC + CMD_TAGS( + CMD_TAG_CHAT, + CMD_TAG_UI) + CMD_SYN( + "/omemo gen", + "/omemo log on|off|redact", + "/omemo start [<contact>]", + "/omemo trust [<contact>] <fingerprint>", + "/omemo end", + "/omemo fingerprint [<contact>]", + "/omemo char <char>", + "/omemo clear_device_list") + CMD_DESC( + "OMEMO commands to manage keys, and perform encryption during chat sessions.") + CMD_ARGS( + { "gen", "Generate OMEMO crytographic materials for current account." }, + { "start [<contact>]", "Start an OMEMO session with contact, or current recipient if omitted." }, + { "end", "End the current OMEMO session." }, + { "log on|off", "Enable or disable plaintext logging of OMEMO encrypted messages." }, + { "log redact", "Log OMEMO encrypted messages, but replace the contents with [redacted]. This is the default." }, + { "fingerprint [<contact>]", "Show contact fingerprints, or current recipient if omitted." }, + { "char <char>", "Set the character to be displayed next to OMEMO encrypted messages." }, + { "clear_device_list", "Clear your own device list on server side. Each client will reannounce itself when connected back."}) + CMD_EXAMPLES( + "/omemo gen", + "/omemo start buddy@buddychat.org", + "/omemo trust c4f9c875-144d7a3b-0c4a05b6-ca3be51a-a037f329-0bd3ae62-07f99719-55559d2a", + "/omemo untrust buddy@buddychat.org c4f9c875-144d7a3b-0c4a05b6-ca3be51a-a037f329-0bd3ae62-07f99719-55559d2a", + "/omemo char *") + }, }; static GHashTable *search_index; diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index b2f0ee7f..fe289f0b 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -85,6 +85,11 @@ #include "pgp/gpg.h" #endif +#ifdef HAVE_OMEMO +#include "omemo/omemo.h" +#include "xmpp/omemo.h" +#endif + #ifdef HAVE_GTK #include "ui/tray.h" #endif @@ -1674,6 +1679,10 @@ cmd_prefs(ProfWin *window, const char *const command, gchar **args) cons_show(""); cons_show_pgp_prefs(); cons_show(""); + } else if (strcmp(args[0], "omemo") == 0) { + cons_show(""); + cons_show_omemo_prefs(); + cons_show(""); } else { cons_bad_cmd_usage(command); } @@ -2141,17 +2150,67 @@ cmd_msg(ProfWin *window, const char *const command, gchar **args) } ui_focus_win((ProfWin*)chatwin); +#ifdef HAVE_OMEMO +#ifndef HAVE_LIBOTR + if (omemo_is_trusted_jid(barejid)) { + omemo_start_session(barejid); + chatwin->is_omemo = TRUE; + } + + if (msg) { + cl_ev_send_msg(chatwin, msg, NULL); + } + + return TRUE; +#endif +#endif + +#ifdef HAVE_OMEMO +#ifdef HAVE_LIBOTR + if (omemo_is_trusted_jid(barejid) && otr_is_secure(barejid)) { + win_println(window, THEME_DEFAULT, '!', "Chat could be either OMEMO or OTR encrypted. Use '/omemo start %s' or '/otr start %s' to start a session.", usr, usr); + return TRUE; + } else if (omemo_is_trusted_jid(barejid)) { + omemo_start_session(barejid); + chatwin->is_omemo = TRUE; + } + if (msg) { cl_ev_send_msg(chatwin, msg, NULL); } else { + if (otr_is_secure(barejid)) { + chatwin_otr_secured(chatwin, otr_is_trusted(barejid)); + } + } + + return TRUE; +#endif +#endif + +#ifndef HAVE_OMEMO #ifdef HAVE_LIBOTR + if (msg) { + cl_ev_send_msg(chatwin, msg, NULL); + } else { if (otr_is_secure(barejid)) { chatwin_otr_secured(chatwin, otr_is_trusted(barejid)); } + } + + return TRUE; #endif +#endif + +#ifndef HAVE_OMEMO +#ifndef HAVE_LIBOTR + if (msg) { + cl_ev_send_msg(chatwin, msg, NULL); } return TRUE; +#endif +#endif + } } @@ -7304,6 +7363,11 @@ cmd_otr_start(ProfWin *window, const char *const command, gchar **args) return TRUE; } + if (chatwin->is_omemo) { + win_println(window, THEME_DEFAULT, '!', "You must disable OMEMO before starting an OTR session."); + return TRUE; + } + if (chatwin->is_otr) { win_println(window, THEME_DEFAULT, '!', "You are already in an OTR session."); return TRUE; @@ -7872,3 +7936,432 @@ _cmd_set_boolean_preference(gchar *arg, const char *const command, g_string_free(enabled, TRUE); g_string_free(disabled, TRUE); } + +gboolean +cmd_omemo_gen(ProfWin *window, const char *const command, gchar **args) +{ +#ifdef HAVE_OMEMO + if (connection_get_status() != JABBER_CONNECTED) { + cons_show("You must be connected with an account to initialize OMEMO."); + return TRUE; + } + + if (omemo_loaded()) { + cons_show("OMEMO crytographic materials have already been generated."); + return TRUE; + } + + ProfAccount *account = accounts_get_account(session_get_account_name()); + omemo_generate_crypto_materials(account); + cons_show("OMEMO crytographic materials generated."); + return TRUE; +#else + cons_show("This version of Profanity has not been built with OMEMO support enabled"); + return TRUE; +#endif +} + +gboolean +cmd_omemo_start(ProfWin *window, const char *const command, gchar **args) +{ +#ifdef HAVE_OMEMO + if (connection_get_status() != JABBER_CONNECTED) { + cons_show("You must be connected with an account to load OMEMO information."); + return TRUE; + } + + if (!omemo_loaded()) { + win_println(window, THEME_DEFAULT, '!', "You have not generated or loaded a cryptographic materials, use '/omemo gen'"); + return TRUE; + } + + // recipient supplied + if (args[1]) { + char *contact = args[1]; + char *barejid = roster_barejid_from_name(contact); + if (barejid == NULL) { + barejid = contact; + } + + ProfChatWin *chatwin = wins_get_chat(barejid); + if (!chatwin) { + chatwin = chatwin_new(barejid); + } + ui_focus_win((ProfWin*)chatwin); + + if (chatwin->pgp_send) { + win_println(window, THEME_DEFAULT, '!', "You must disable PGP encryption before starting an OMEMO session."); + return TRUE; + } + + if (chatwin->is_otr) { + win_println(window, THEME_DEFAULT, '!', "You must disable OTR encryption before starting an OMEMO session."); + return TRUE; + } + + if (chatwin->is_omemo) { + win_println(window, THEME_DEFAULT, '!', "You are already in an OMEMO session."); + return TRUE; + } + + omemo_start_session(barejid); + chatwin->is_omemo = TRUE; + } else { + if (window->type == WIN_CHAT) { + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + if (chatwin->pgp_send) { + win_println(window, THEME_DEFAULT, '!', "You must disable PGP encryption before starting an OMEMO session."); + return TRUE; + } + + if (chatwin->is_otr) { + win_println(window, THEME_DEFAULT, '!', "You must disable OTR encryption before starting an OMEMO session."); + return TRUE; + } + + if (chatwin->is_omemo) { + win_println(window, THEME_DEFAULT, '!', "You are already in an OMEMO session."); + return TRUE; + } + + omemo_start_session(chatwin->barejid); + chatwin->is_omemo = TRUE; + } else if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); + + /* TODO: Check room is configured correctly, no anonymous and access to + * full jid */ + omemo_start_muc_sessions(mucwin->roomjid); + + mucwin->is_omemo = TRUE; + } else { + win_println(window, THEME_DEFAULT, '-', "You must be in a regular chat window to start an OMEMO session."); + return TRUE; + } + + } + + return TRUE; +#else + cons_show("This version of Profanity has not been built with OMEMO support enabled"); + return TRUE; +#endif +} + +gboolean +cmd_omemo_char(ProfWin *window, const char *const command, gchar **args) +{ +#ifdef HAVE_OMEMO + if (args[1] == NULL) { + cons_bad_cmd_usage(command); + } else if (strlen(args[1]) != 1) { + cons_bad_cmd_usage(command); + } else { + prefs_set_omemo_char(args[1][0]); + cons_show("OMEMO char set to %c.", args[1][0]); + } + return TRUE; +#else + cons_show("This version of Profanity has not been built with OMEMO support enabled"); + return TRUE; +#endif +} + +gboolean +cmd_omemo_log(ProfWin *window, const char *const command, gchar **args) +{ +#ifdef HAVE_OMEMO + char *choice = args[1]; + if (g_strcmp0(choice, "on") == 0) { + prefs_set_string(PREF_OMEMO_LOG, "on"); + cons_show("OMEMO messages will be logged as plaintext."); + if (!prefs_get_boolean(PREF_CHLOG)) { + cons_show("Chat logging is currently disabled, use '/chlog on' to enable."); + } + } else if (g_strcmp0(choice, "off") == 0) { + prefs_set_string(PREF_OMEMO_LOG, "off"); + cons_show("OMEMO message logging disabled."); + } else if (g_strcmp0(choice, "redact") == 0) { + prefs_set_string(PREF_OMEMO_LOG, "redact"); + cons_show("OMEMO messages will be logged as '[redacted]'."); + if (!prefs_get_boolean(PREF_CHLOG)) { + cons_show("Chat logging is currently disabled, use '/chlog on' to enable."); + } + } else { + cons_bad_cmd_usage(command); + } + return TRUE; +#else + cons_show("This version of Profanity has not been built with OMEMO support enabled"); + return TRUE; +#endif +} + +gboolean +cmd_omemo_end(ProfWin *window, const char *const command, gchar **args) +{ +#ifdef HAVE_OMEMO + if (connection_get_status() != JABBER_CONNECTED) { + cons_show("You must be connected with an account to load OMEMO information."); + return TRUE; + } + + if (window->type == WIN_CHAT) { + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + + if (!chatwin->is_omemo) { + win_println(window, THEME_DEFAULT, '!', "You are not currently in an OMEMO session."); + return TRUE; + } + + chatwin->is_omemo = FALSE; + } else if (window->type == WIN_MUC) { + ProfMucWin *mucwin = (ProfMucWin*)window; + assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); + + if (!mucwin->is_omemo) { + win_println(window, THEME_DEFAULT, '!', "You are not currently in an OMEMO session."); + return TRUE; + } + + mucwin->is_omemo = FALSE; + } else { + win_println(window, THEME_DEFAULT, '-', "You must be in a regular chat window to start an OMEMO session."); + return TRUE; + } + + return TRUE; +#else + cons_show("This version of Profanity has not been built with OMEMO support enabled"); + return TRUE; +#endif +} + +gboolean +cmd_omemo_fingerprint(ProfWin *window, const char *const command, gchar **args) +{ +#ifdef HAVE_OMEMO + if (connection_get_status() != JABBER_CONNECTED) { + cons_show("You must be connected with an account to load OMEMO information."); + return TRUE; + } + + if (!omemo_loaded()) { + win_println(window, THEME_DEFAULT, '!', "You have not generated or loaded a cryptographic materials, use '/omemo gen'"); + return TRUE; + } + + Jid *jid; + if (!args[1]) { + if (window->type == WIN_CONSOLE) { + char *fingerprint = omemo_own_fingerprint(TRUE); + cons_show("Your OMEMO fingerprint: %s", fingerprint); + free(fingerprint); + jid = jid_create(connection_get_fulljid()); + } else if (window->type == WIN_CHAT) { + ProfChatWin *chatwin = (ProfChatWin*)window; + jid = jid_create(chatwin->barejid); + } else { + win_println(window, THEME_DEFAULT, '-', "You must be in a regular chat window to print fingerprint without providing the contact."); + return TRUE; + } + } else { + char *barejid = roster_barejid_from_name(args[1]); + if (barejid) { + jid = jid_create(barejid); + } else { + jid = jid_create(args[1]); + if (!jid) { + cons_show("%s is not a valid jid", args[1]); + return TRUE; + } + } + } + + GList *fingerprints = omemo_known_device_identities(jid->barejid); + GList *fingerprint; + + if (!fingerprints) { + win_println(window, THEME_DEFAULT, '-', "There is no known fingerprints for %s", jid->barejid); + return TRUE; + } + + for (fingerprint = fingerprints; fingerprint != NULL; fingerprint = fingerprint->next) { + char *formatted_fingerprint = omemo_format_fingerprint(fingerprint->data); + gboolean trusted = omemo_is_trusted_identity(jid->barejid, fingerprint->data); + + win_println(window, THEME_DEFAULT, '-', "%s's OMEMO fingerprint: %s%s", jid->barejid, formatted_fingerprint, trusted ? " (trusted)" : ""); + + free(formatted_fingerprint); + } + + g_list_free(fingerprints); + + win_println(window, THEME_DEFAULT, '-', "You can trust it with '/omemo trust <fingerprint>'"); + win_println(window, THEME_DEFAULT, '-', "You can untrust it with '/omemo untrust <fingerprint>'"); + + return TRUE; +#else + cons_show("This version of Profanity has not been built with OMEMO support enabled"); + return TRUE; +#endif +} + +gboolean +cmd_omemo_trust(ProfWin *window, const char *const command, gchar **args) +{ +#ifdef HAVE_OMEMO + if (connection_get_status() != JABBER_CONNECTED) { + cons_show("You must be connected with an account to load OMEMO information."); + return TRUE; + } + + if (!args[1]) { + cons_bad_cmd_usage(command); + return TRUE; + } + + if (!omemo_loaded()) { + win_println(window, THEME_DEFAULT, '!', "You have not generated or loaded a cryptographic materials, use '/omemo gen'"); + return TRUE; + } + + char *fingerprint; + char *barejid; + + /* Contact not provided */ + if (!args[2]) { + fingerprint = args[1]; + + if (window->type != WIN_CHAT) { + win_println(window, THEME_DEFAULT, '-', "You must be in a regular chat window to trust a device without providing the contact."); + return TRUE; + } + + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + barejid = chatwin->barejid; + } else { + fingerprint = args[2]; + char *contact = args[1]; + barejid = roster_barejid_from_name(contact); + if (barejid == NULL) { + barejid = contact; + } + } + + omemo_trust(barejid, fingerprint); + + char *unformatted_fingerprint = malloc(strlen(fingerprint)); + int i; + int j; + for (i = 0, j = 0; fingerprint[i] != '\0'; i++) { + if (!g_ascii_isxdigit(fingerprint[i])) { + continue; + } + unformatted_fingerprint[j++] = fingerprint[i]; + } + + unformatted_fingerprint[j] = '\0'; + gboolean trusted = omemo_is_trusted_identity(barejid, unformatted_fingerprint); + + win_println(window, THEME_DEFAULT, '-', "%s's OMEMO fingerprint: %s%s", barejid, fingerprint, trusted ? " (trusted)" : ""); + + free(unformatted_fingerprint); + + return TRUE; +#else + cons_show("This version of Profanity has not been built with OMEMO support enabled"); + return TRUE; +#endif +} + +gboolean +cmd_omemo_untrust(ProfWin *window, const char *const command, gchar **args) +{ +#ifdef HAVE_OMEMO + if (connection_get_status() != JABBER_CONNECTED) { + cons_show("You must be connected with an account to load OMEMO information."); + return TRUE; + } + + if (!args[1]) { + cons_bad_cmd_usage(command); + return TRUE; + } + + if (!omemo_loaded()) { + win_println(window, THEME_DEFAULT, '!', "You have not generated or loaded a cryptographic materials, use '/omemo gen'"); + return TRUE; + } + + char *fingerprint; + char *barejid; + + /* Contact not provided */ + if (!args[2]) { + fingerprint = args[1]; + + if (window->type != WIN_CHAT) { + win_println(window, THEME_DEFAULT, '-', "You must be in a regular chat window to trust a device without providing the contact."); + return TRUE; + } + + ProfChatWin *chatwin = (ProfChatWin*)window; + assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); + barejid = chatwin->barejid; + } else { + fingerprint = args[2]; + char *contact = args[1]; + barejid = roster_barejid_from_name(contact); + if (barejid == NULL) { + barejid = contact; + } + } + + omemo_untrust(barejid, fingerprint); + + char *unformatted_fingerprint = malloc(strlen(fingerprint)); + int i; + int j; + for (i = 0, j = 0; fingerprint[i] != '\0'; i++) { + if (!g_ascii_isxdigit(fingerprint[i])) { + continue; + } + unformatted_fingerprint[j++] = fingerprint[i]; + } + + unformatted_fingerprint[j] = '\0'; + gboolean trusted = omemo_is_trusted_identity(barejid, unformatted_fingerprint); + + win_println(window, THEME_DEFAULT, '-', "%s's OMEMO fingerprint: %s%s", barejid, fingerprint, trusted ? " (trusted)" : ""); + + free(unformatted_fingerprint); + + return TRUE; +#else + cons_show("This version of Profanity has not been built with OMEMO support enabled"); + return TRUE; +#endif +} + +gboolean +cmd_omemo_clear_device_list(ProfWin *window, const char *const command, gchar **args) +{ +#ifdef HAVE_OMEMO + if (connection_get_status() != JABBER_CONNECTED) { + cons_show("You must be connected with an account to initialize OMEMO."); + return TRUE; + } + + omemo_devicelist_publish(NULL); + cons_show("Cleared OMEMO device list"); + return TRUE; +#else + cons_show("This version of Profanity has not been built with OMEMO support enabled"); + return TRUE; +#endif +} diff --git a/src/command/cmd_funcs.h b/src/command/cmd_funcs.h index 89166ba1..249b50fe 100644 --- a/src/command/cmd_funcs.h +++ b/src/command/cmd_funcs.h @@ -214,4 +214,14 @@ gboolean cmd_wins_swap(ProfWin *window, const char *const command, gchar **args) gboolean cmd_form_field(ProfWin *window, char *tag, gchar **args); +gboolean cmd_omemo_gen(ProfWin *window, const char *const command, gchar **args); +gboolean cmd_omemo_char(ProfWin *window, const char *const command, gchar **args); +gboolean cmd_omemo_log(ProfWin *window, const char *const command, gchar **args); +gboolean cmd_omemo_start(ProfWin *window, const char *const command, gchar **args); +gboolean cmd_omemo_end(ProfWin *window, const char *const command, gchar **args); +gboolean cmd_omemo_fingerprint(ProfWin *window, const char *const command, gchar **args); +gboolean cmd_omemo_trust(ProfWin *window, const char *const command, gchar **args); +gboolean cmd_omemo_untrust(ProfWin *window, const char *const command, gchar **args); +gboolean cmd_omemo_clear_device_list(ProfWin *window, const char *const command, gchar **args); + #endif |