diff --git a/src/command/command.c b/src/command/command.c index afcfe546..ba976023 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -570,14 +570,16 @@ static struct cmd_t command_defs[] = { "/otr", cmd_otr, parse_args, 1, 2, NULL, - { "/otr gen|myfp|theirfp|start|end", "Off The Record encryption commands.", - { "/otr gen|myfp|theirfp|start|end", - "-------------------------------", + { "/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", @@ -989,6 +991,8 @@ cmd_init(void) 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(); } diff --git a/src/command/commands.c b/src/command/commands.c index 660ec572..69e80414 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -2359,6 +2359,32 @@ cmd_otr(gchar **args, struct cmd_help_t help) 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); diff --git a/src/otr.c b/src/otr.c index ab4b79cd..95fd7bca 100644 --- a/src/otr.c +++ b/src/otr.c @@ -145,7 +145,7 @@ static void cb_gone_secure(void *opdata, ConnContext *context) { // cons_debug("cb_gone_secure"); - ui_gone_secure(context->username); + ui_gone_secure(context->username, otr_is_trusted(context->username)); } static void @@ -376,6 +376,72 @@ otr_is_secure(const char * const recipient) } } +gboolean +otr_is_trusted(const char * const recipient) +{ + ConnContext *context = otrl_context_find(user_state, recipient, jid, "xmpp", + 0, NULL, NULL, NULL); + + if (context == NULL) { + return FALSE; + } + + if (context->msgstate != OTRL_MSGSTATE_ENCRYPTED) { + return TRUE; + } + + if (context->active_fingerprint && + g_strcmp0(context->active_fingerprint->trust, "trusted") == 0) { + return TRUE; + } + + return FALSE; +} + +void +otr_trust(const char * const recipient) +{ + ConnContext *context = otrl_context_find(user_state, recipient, jid, "xmpp", + 0, NULL, NULL, NULL); + + if (context == NULL) { + return; + } + + if (context->msgstate != OTRL_MSGSTATE_ENCRYPTED) { + return; + } + + if (context->active_fingerprint) { + context->active_fingerprint->trust = "trusted"; + cb_write_fingerprints(NULL); + } + + return; +} + +void +otr_untrust(const char * const recipient) +{ + ConnContext *context = otrl_context_find(user_state, recipient, jid, "xmpp", + 0, NULL, NULL, NULL); + + if (context == NULL) { + return; + } + + if (context->msgstate != OTRL_MSGSTATE_ENCRYPTED) { + return; + } + + if (context->active_fingerprint) { + context->active_fingerprint->trust = NULL; + cb_write_fingerprints(NULL); + } + + return; +} + void otr_end_session(const char * const recipient) { diff --git a/src/otr.h b/src/otr.h index ad89359c..ff1ad5a5 100644 --- a/src/otr.h +++ b/src/otr.h @@ -32,6 +32,10 @@ void otr_keygen(ProfAccount *account); gboolean otr_key_loaded(void); gboolean otr_is_secure(const char * const recipient); +gboolean otr_is_trusted(const char * const recipient); +void otr_trust(const char * const recipient); +void otr_untrust(const char * const recipient); + void otr_end_session(const char * const recipient); char * otr_get_my_fingerprint(void); diff --git a/src/ui/core.c b/src/ui/core.c index fc6ca40e..e0b934ae 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -593,11 +593,12 @@ _ui_next_win(void) } static void -_ui_gone_secure(const char * const recipient) +_ui_gone_secure(const char * const recipient, gboolean trusted) { ProfWin *window = wins_get_by_recipient(recipient); if (window != NULL) { window->is_otr = TRUE; + window->is_trusted = trusted; win_vprint_line(window, '!', 0, "OTR session started."); if (wins_is_current(window)) { @@ -616,6 +617,7 @@ _ui_gone_insecure(const char * const recipient) ProfWin *window = wins_get_by_recipient(recipient); if (window != NULL) { window->is_otr = FALSE; + window->is_trusted = FALSE; win_vprint_line(window, '!', 0, "OTR session ended."); if (wins_is_current(window)) { @@ -628,6 +630,42 @@ _ui_gone_insecure(const char * const recipient) } } +static void +_ui_trust(const char * const recipient) +{ + ProfWin *window = wins_get_by_recipient(recipient); + if (window != NULL) { + window->is_otr = TRUE; + window->is_trusted = TRUE; + + if (wins_is_current(window)) { + GString *recipient_str = _get_recipient_string(window); + title_bar_set_recipient(recipient_str->str); + g_string_free(recipient_str, TRUE); + title_bar_draw(); + wins_refresh_current(); + } + } +} + +static void +_ui_untrust(const char * const recipient) +{ + ProfWin *window = wins_get_by_recipient(recipient); + if (window != NULL) { + window->is_otr = TRUE; + window->is_trusted = FALSE; + + if (wins_is_current(window)) { + GString *recipient_str = _get_recipient_string(window); + title_bar_set_recipient(recipient_str->str); + g_string_free(recipient_str, TRUE); + title_bar_draw(); + wins_refresh_current(); + } + } +} + static void _ui_previous_win(void) { @@ -1688,4 +1726,6 @@ ui_init_module(void) ui_current_set_otr = _ui_current_set_otr; ui_gone_secure = _ui_gone_secure; ui_gone_insecure = _ui_gone_insecure; + ui_trust = _ui_trust; + ui_untrust = _ui_untrust; } diff --git a/src/ui/ui.h b/src/ui/ui.h index 88be3fbb..240f6b4b 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -61,8 +61,10 @@ void (*ui_handle_special_keys)(const wint_t * const ch, const char * const inp, void (*ui_switch_win)(const int i); void (*ui_next_win)(void); void (*ui_previous_win)(void); -void (*ui_gone_secure)(const char * const recipient); +void (*ui_gone_secure)(const char * const recipient, gboolean trusted); void (*ui_gone_insecure)(const char * const recipient); +void (*ui_trust)(const char * const recipient); +void (*ui_untrust)(const char * const recipient); unsigned long (*ui_get_idle_time)(void); void (*ui_reset_idle_time)(void); void (*ui_new_chat_win)(const char * const to);