diff options
-rwxr-xr-x | install-all.sh | 6 | ||||
-rw-r--r-- | src/command/command.c | 5 | ||||
-rw-r--r-- | src/command/commands.c | 50 | ||||
-rw-r--r-- | src/otr/otr.c | 119 | ||||
-rw-r--r-- | src/otr/otr.h | 12 | ||||
-rw-r--r-- | src/otr/otrlib.h | 5 | ||||
-rw-r--r-- | src/otr/otrlibv3.c | 90 | ||||
-rw-r--r-- | src/otr/otrlibv4.c | 96 | ||||
-rw-r--r-- | src/profanity.c | 3 | ||||
-rw-r--r-- | src/ui/core.c | 134 | ||||
-rw-r--r-- | src/ui/ui.h | 12 |
11 files changed, 523 insertions, 9 deletions
diff --git a/install-all.sh b/install-all.sh index 2653d24c..5717ddb0 100755 --- a/install-all.sh +++ b/install-all.sh @@ -24,7 +24,7 @@ debian_prepare() echo echo Profanity installer... installing dependencies echo - sudo apt-get -y install git automake autoconf libssl-dev libexpat1-dev libncursesw5-dev libglib2.0-dev libnotify-dev libcurl3-dev libxss-dev libotr2-dev libgnutls-dev + sudo apt-get -y install git automake autoconf libssl-dev libexpat1-dev libncursesw5-dev libglib2.0-dev libnotify-dev libcurl3-dev libxss-dev libotr5-dev libgnutls-dev } @@ -73,7 +73,9 @@ install_lib_strophe() echo echo Profanity installer... installing libstrophe echo - git clone git://github.com/strophe/libstrophe.git + #clone fork so as to not pick up any breaking changes + #git clone git://github.com/strophe/libstrophe.git + git clone git://github.com/boothj5/libstrophe.git cd libstrophe ./bootstrap.sh ./configure diff --git a/src/command/command.c b/src/command/command.c index 95a6158e..d7a60495 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -594,7 +594,7 @@ static struct cmd_t command_defs[] = NULL } } }, { "/otr", - cmd_otr, parse_args, 1, 2, NULL, + cmd_otr, parse_args, 1, 3, NULL, { "/otr gen|myfp|theirfp|start|end|trust|untrust|log|warn|libver|policy", "Off The Record encryption commands.", { "/otr gen|myfp|theirfp|start|end|trust|untrust|log|warn|libver|policy", "--------------------------------------------------------------------", @@ -1066,10 +1066,13 @@ cmd_init(void) autocomplete_add(otr_ac, "theirfp"); autocomplete_add(otr_ac, "trust"); autocomplete_add(otr_ac, "untrust"); + autocomplete_add(otr_ac, "secret"); autocomplete_add(otr_ac, "log"); autocomplete_add(otr_ac, "warn"); autocomplete_add(otr_ac, "libver"); autocomplete_add(otr_ac, "policy"); + autocomplete_add(otr_ac, "question"); + autocomplete_add(otr_ac, "answer"); otr_log_ac = autocomplete_new(); autocomplete_add(otr_log_ac, "on"); diff --git a/src/command/commands.c b/src/command/commands.c index 940a7f5a..ad508cc7 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -2788,7 +2788,57 @@ cmd_otr(gchar **args, struct cmd_help_t help) otr_untrust(recipient); } return TRUE; + } else if (strcmp(args[0], "secret") == 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_formatted_line('!', 0, "You are not currently in an OTR session."); + } else { + char *secret = args[1]; + if (secret == NULL) { + cons_show("Usage: %s", help.usage); + } else { + char *recipient = ui_current_recipient(); + otr_smp_secret(recipient, secret); + } + } + return TRUE; + } else if (strcmp(args[0], "question") == 0) { + char *question = args[1]; + char *answer = args[2]; + if (question == NULL || answer == NULL) { + cons_show("Usage: %s", help.usage); + return TRUE; + } else { + 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_formatted_line('!', 0, "You are not currently in an OTR session."); + } else { + char *recipient = ui_current_recipient(); + otr_smp_question(recipient, question, answer); + } + return TRUE; + } + } else if (strcmp(args[0], "answer") == 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_formatted_line('!', 0, "You are not currently in an OTR session."); + } else { + char *answer = args[1]; + if (answer == NULL) { + cons_show("Usage: %s", help.usage); + } else { + char *recipient = ui_current_recipient(); + otr_smp_answer(recipient, answer); + } + } + return TRUE; } else { cons_show("Usage: %s", help.usage); return TRUE; diff --git a/src/otr/otr.c b/src/otr/otr.c index e80086af..043dc30f 100644 --- a/src/otr/otr.c +++ b/src/otr/otr.c @@ -23,6 +23,7 @@ #include <libotr/proto.h> #include <libotr/privkey.h> #include <libotr/message.h> +#include <libotr/sm.h> #include <glib.h> #include "otr/otr.h" @@ -40,6 +41,25 @@ static OtrlUserState user_state; static OtrlMessageAppOps ops; static char *jid; static gboolean data_loaded; +static GHashTable *smp_initiators; + +OtrlUserState +otr_userstate(void) +{ + return user_state; +} + +OtrlMessageAppOps * +otr_messageops(void) +{ + return &ops; +} + +GHashTable * +otr_smpinitators(void) +{ + return smp_initiators; +} // ops callbacks static OtrlPolicy @@ -134,10 +154,18 @@ _otr_init(void) ops.gone_secure = cb_gone_secure; otrlib_init_ops(&ops); + otrlib_init_timer(); + smp_initiators = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); data_loaded = FALSE; } +void +_otr_poll(void) +{ + otrlib_poll(); +} + static void _otr_on_connect(ProfAccount *account) { @@ -337,9 +365,14 @@ _otr_is_trusted(const char * const recipient) return TRUE; } - if (context->active_fingerprint && - g_strcmp0(context->active_fingerprint->trust, "trusted") == 0) { - return TRUE; + if (context->active_fingerprint) { + if (context->active_fingerprint->trust == NULL) { + return FALSE; + } else if (context->active_fingerprint->trust[0] == '\0') { + return FALSE; + } else { + return TRUE; + } } return FALSE; @@ -359,7 +392,10 @@ _otr_trust(const char * const recipient) } if (context->active_fingerprint) { - context->active_fingerprint->trust = "trusted"; + if (context->active_fingerprint->trust != NULL) { + free(context->active_fingerprint->trust); + } + context->active_fingerprint->trust = strdup("trusted"); cb_write_fingerprints(NULL); } @@ -380,6 +416,9 @@ _otr_untrust(const char * const recipient) } if (context->active_fingerprint) { + if (context->active_fingerprint->trust != NULL) { + free(context->active_fingerprint->trust); + } context->active_fingerprint->trust = NULL; cb_write_fingerprints(NULL); } @@ -388,6 +427,64 @@ _otr_untrust(const char * const recipient) } static void +_otr_smp_secret(const char * const recipient, const char *secret) +{ + ConnContext *context = otrlib_context_find(user_state, recipient, jid); + + if (context == NULL) { + return; + } + + if (context->msgstate != OTRL_MSGSTATE_ENCRYPTED) { + return; + } + + // if recipient initiated SMP, send response, else initialise + if (g_hash_table_contains(smp_initiators, recipient)) { + otrl_message_respond_smp(user_state, &ops, NULL, context, (const unsigned char*)secret, strlen(secret)); + ui_otr_authenticating(recipient); + g_hash_table_remove(smp_initiators, context->username); + } else { + otrl_message_initiate_smp(user_state, &ops, NULL, context, (const unsigned char*)secret, strlen(secret)); + ui_otr_authetication_waiting(recipient); + } +} + +static void +_otr_smp_question(const char * const recipient, const char *question, const char *answer) +{ + ConnContext *context = otrlib_context_find(user_state, recipient, jid); + + if (context == NULL) { + return; + } + + if (context->msgstate != OTRL_MSGSTATE_ENCRYPTED) { + return; + } + + otrl_message_initiate_smp_q(user_state, &ops, NULL, context, question, (const unsigned char*)answer, strlen(answer)); + ui_otr_authetication_waiting(recipient); +} + +static void +_otr_smp_answer(const char * const recipient, const char *answer) +{ + ConnContext *context = otrlib_context_find(user_state, recipient, jid); + + if (context == NULL) { + return; + } + + if (context->msgstate != OTRL_MSGSTATE_ENCRYPTED) { + return; + } + + // if recipient initiated SMP, send response, else initialise + otrl_message_respond_smp(user_state, &ops, NULL, context, (const unsigned char*)answer, strlen(answer)); +} + +static void _otr_end_session(const char * const recipient) { otrlib_end_session(user_state, recipient, jid, &ops); @@ -424,7 +521,7 @@ _otr_encrypt_message(const char * const to, const char * const message) char *newmessage = NULL; gcry_error_t err = otrlib_encrypt_message(user_state, &ops, jid, to, message, &newmessage); - if (!err == GPG_ERR_NO_ERROR) { + if (err != 0) { return NULL; } else { return newmessage; @@ -441,15 +538,21 @@ _otr_decrypt_message(const char * const from, const char * const message, gboole // internal libotr message if (result == 1) { + ConnContext *context = otrlib_context_find(user_state, from, jid); + + // common tlv handling OtrlTLV *tlv = otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED); if (tlv) { - ConnContext *context = otrlib_context_find(user_state, from, jid); if (context != NULL) { otrl_context_force_plaintext(context); ui_gone_insecure(from); } } + + // library version specific tlv handling + otrlib_handle_tlvs(user_state, &ops, context, tlvs, smp_initiators); + return NULL; // message was decrypted, return to user @@ -476,6 +579,7 @@ otr_init_module(void) otr_init = _otr_init; otr_libotr_version = _otr_libotr_version; otr_start_query = _otr_start_query; + otr_poll = _otr_poll; otr_on_connect = _otr_on_connect; otr_keygen = _otr_keygen; otr_key_loaded = _otr_key_loaded; @@ -489,4 +593,7 @@ otr_init_module(void) otr_encrypt_message = _otr_encrypt_message; otr_decrypt_message = _otr_decrypt_message; otr_free_message = _otr_free_message; + otr_smp_secret = _otr_smp_secret; + otr_smp_question = _otr_smp_question; + otr_smp_answer = _otr_smp_answer; } diff --git a/src/otr/otr.h b/src/otr/otr.h index 5239c033..87b34b45 100644 --- a/src/otr/otr.h +++ b/src/otr/otr.h @@ -23,13 +23,21 @@ #ifndef OTR_H #define OTR_H +#include <libotr/proto.h> +#include <libotr/message.h> + #include "config/accounts.h" void otr_init_module(void); +OtrlUserState otr_userstate(void); +OtrlMessageAppOps* otr_messageops(void); +GHashTable* otr_smpinitators(void); + void (*otr_init)(void); char* (*otr_libotr_version)(void); char* (*otr_start_query)(void); +void (*otr_poll)(void); void (*otr_on_connect)(ProfAccount *account); void (*otr_keygen)(ProfAccount *account); @@ -40,6 +48,10 @@ gboolean (*otr_is_trusted)(const char * const recipient); void (*otr_trust)(const char * const recipient); void (*otr_untrust)(const char * const recipient); +void (*otr_smp_secret)(const char * const recipient, const char *secret); +void (*otr_smp_question)(const char * const recipient, const char *question, const char *answer); +void (*otr_smp_answer)(const char * const recipient, const char *answer); + void (*otr_end_session)(const char * const recipient); char * (*otr_get_my_fingerprint)(void); diff --git a/src/otr/otrlib.h b/src/otr/otrlib.h index 0986c59b..c0ca518f 100644 --- a/src/otr/otrlib.h +++ b/src/otr/otrlib.h @@ -29,6 +29,9 @@ char* otrlib_start_query(void); void otrlib_init_ops(OtrlMessageAppOps *ops); +void otrlib_init_timer(void); +void otrlib_poll(void); + ConnContext * otrlib_context_find(OtrlUserState user_state, const char * const recipient, char *jid); void otrlib_end_session(OtrlUserState user_state, const char * const recipient, char *jid, OtrlMessageAppOps *ops); @@ -39,4 +42,6 @@ gcry_error_t otrlib_encrypt_message(OtrlUserState user_state, OtrlMessageAppOps int otrlib_decrypt_message(OtrlUserState user_state, OtrlMessageAppOps *ops, char *jid, const char * const from, const char * const message, char **decrypted, OtrlTLV **tlvs); +void otrlib_handle_tlvs(OtrlUserState user_state, OtrlMessageAppOps *ops, ConnContext *context, OtrlTLV *tlvs, GHashTable *smp_initiators); + #endif diff --git a/src/otr/otrlibv3.c b/src/otr/otrlibv3.c index d1495c9a..92ca3602 100644 --- a/src/otr/otrlibv3.c +++ b/src/otr/otrlibv3.c @@ -24,6 +24,8 @@ #include <libotr/message.h> #include "ui/ui.h" +#include "otr/otr.h" +#include "otr/otrlib.h" OtrlPolicy otrlib_policy(void) @@ -31,6 +33,16 @@ otrlib_policy(void) return OTRL_POLICY_ALLOW_V1 | OTRL_POLICY_ALLOW_V2 ; } +void +otrlib_init_timer(void) +{ +} + +void +otrlib_poll(void) +{ +} + char * otrlib_start_query(void) { @@ -106,3 +118,81 @@ otrlib_decrypt_message(OtrlUserState user_state, OtrlMessageAppOps *ops, char *j NULL, NULL); } + +void +otrlib_handle_tlvs(OtrlUserState user_state, OtrlMessageAppOps *ops, ConnContext *context, OtrlTLV *tlvs, GHashTable *smp_initiators) +{ + NextExpectedSMP nextMsg = context->smstate->nextExpected; + OtrlTLV *tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1); + if (tlv) { + if (nextMsg != OTRL_SMP_EXPECT1) { + otrl_message_abort_smp(user_state, ops, NULL, context); + } else { + ui_smp_recipient_initiated(context->username); + g_hash_table_insert(smp_initiators, strdup(context->username), strdup(context->username)); + } + } + tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1Q); + if (tlv) { + if (nextMsg != OTRL_SMP_EXPECT1) { + otrl_message_abort_smp(user_state, ops, NULL, context); + } else { + char *question = (char *)tlv->data; + char *eoq = memchr(question, '\0', tlv->len); + if (eoq) { + ui_smp_recipient_initiated_q(context->username, question); + } + } + } + tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP2); + if (tlv) { + if (nextMsg != OTRL_SMP_EXPECT2) { + otrl_message_abort_smp(user_state, ops, NULL, context); + } else { + context->smstate->nextExpected = OTRL_SMP_EXPECT4; + } + } + tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP3); + if (tlv) { + if (nextMsg != OTRL_SMP_EXPECT3) { + otrl_message_abort_smp(user_state, ops, NULL, context); + } else { + context->smstate->nextExpected = OTRL_SMP_EXPECT1; + if (context->smstate->received_question == 0) { + if ((context->active_fingerprint->trust != NULL) && (context->active_fingerprint->trust[0] != '\0')) { + ui_smp_successful(context->username); + ui_trust(context->username); + otr_trust(context->username); + } else { + ui_smp_unsuccessful_sender(context->username); + ui_untrust(context->username); + otr_untrust(context->username); + } + } + } + } + tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP4); + if (tlv) { + if (nextMsg != OTRL_SMP_EXPECT4) { + otrl_message_abort_smp(user_state, ops, NULL, context); + } else { + context->smstate->nextExpected = OTRL_SMP_EXPECT1; + if ((context->active_fingerprint->trust != NULL) && (context->active_fingerprint->trust[0] != '\0')) { + ui_smp_successful(context->username); + ui_trust(context->username); + otr_trust(context->username); + } else { + ui_smp_unsuccessful_receiver(context->username); + ui_untrust(context->username); + otr_untrust(context->username); + } + } + } + tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT); + if (tlv) { + context->smstate->nextExpected = OTRL_SMP_EXPECT1; + ui_smp_aborted(context->username); + ui_untrust(context->username); + otr_untrust(context->username); + } +} diff --git a/src/otr/otrlibv4.c b/src/otr/otrlibv4.c index c55d2972..d9e7ce01 100644 --- a/src/otr/otrlibv4.c +++ b/src/otr/otrlibv4.c @@ -25,6 +25,12 @@ #include <libotr/message.h> #include "ui/ui.h" +#include "log.h" +#include "otr/otr.h" +#include "otr/otrlib.h" + +static GTimer *timer; +static unsigned int current_interval; OtrlPolicy otrlib_policy(void) @@ -32,6 +38,27 @@ otrlib_policy(void) return OTRL_POLICY_ALLOW_V1 | OTRL_POLICY_ALLOW_V2; } +void +otrlib_init_timer(void) +{ + OtrlUserState user_state = otr_userstate(); + timer = g_timer_new(); + current_interval = otrl_message_poll_get_default_interval(user_state); +} + +void +otrlib_poll(void) +{ + gdouble elapsed = g_timer_elapsed(timer, NULL); + + if (current_interval != 0 && elapsed > current_interval) { + OtrlUserState user_state = otr_userstate(); + OtrlMessageAppOps *ops = otr_messageops(); + otrl_message_poll(user_state, ops, NULL); + g_timer_start(timer); + } +} + char * otrlib_start_query(void) { @@ -64,6 +91,12 @@ cb_otr_error_message_free(void *opdata, const char *err_msg) } static void +cb_timer_control(void *opdata, unsigned int interval) +{ + current_interval = interval; +} + +static void cb_handle_msg_event(void *opdata, OtrlMessageEvent msg_event, ConnContext *context, const char *message, gcry_error_t err) @@ -77,12 +110,70 @@ cb_handle_msg_event(void *opdata, OtrlMessageEvent msg_event, } } +static void +cb_handle_smp_event(void *opdata, OtrlSMPEvent smp_event, + ConnContext *context, unsigned short progress_percent, + char *question) +{ + NextExpectedSMP nextMsg = context->smstate->nextExpected; + OtrlUserState user_state = otr_userstate(); + OtrlMessageAppOps *ops = otr_messageops(); + GHashTable *smp_initiators = otr_smpinitators(); + + switch(smp_event) + { + case OTRL_SMPEVENT_ASK_FOR_SECRET: + ui_smp_recipient_initiated(context->username); + g_hash_table_insert(smp_initiators, strdup(context->username), strdup(context->username)); + break; + + case OTRL_SMPEVENT_SUCCESS: + ui_smp_successful(context->username); + ui_trust(context->username); + break; + + case OTRL_SMPEVENT_FAILURE: + if (nextMsg == OTRL_SMP_EXPECT3) { + ui_smp_unsuccessful_sender(context->username); + ui_untrust(context->username); + } else if (nextMsg == OTRL_SMP_EXPECT4) { + ui_smp_unsuccessful_receiver(context->username); + ui_untrust(context->username); + } + break; + + case OTRL_SMPEVENT_ERROR: + otrl_message_abort_smp(user_state, ops, NULL, context); + break; + + case OTRL_SMPEVENT_CHEATED: + otrl_message_abort_smp(user_state, ops, NULL, context); + break; + + case OTRL_SMPEVENT_ABORT: + ui_smp_aborted(context->username); + ui_untrust(context->username); + break; + + case OTRL_SMPEVENT_ASK_FOR_ANSWER: + break; + + case OTRL_SMPEVENT_IN_PROGRESS: + break; + + default: + break; + } +} + void otrlib_init_ops(OtrlMessageAppOps *ops) { ops->otr_error_message = cb_otr_error_message; ops->otr_error_message_free = cb_otr_error_message_free; ops->handle_msg_event = cb_handle_msg_event; + ops->handle_smp_event = cb_handle_smp_event; + ops->timer_control = cb_timer_control; } ConnContext * @@ -145,3 +236,8 @@ otrlib_decrypt_message(OtrlUserState user_state, OtrlMessageAppOps *ops, char *j NULL, NULL); } + +void +otrlib_handle_tlvs(OtrlUserState user_state, OtrlMessageAppOps *ops, ConnContext *context, OtrlTLV *tlvs, GHashTable *smp_initiators) +{ +} diff --git a/src/profanity.c b/src/profanity.c index 0fb6ebbd..ce0ee431 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -103,6 +103,9 @@ prof_run(const int disable_tls, char *log_level, char *account_name) ui_handle_special_keys(&ch, inp, size); ui_update_screen(); +#ifdef HAVE_LIBOTR + otr_poll(); +#endif jabber_process_events(); ch = ui_get_char(inp, &size); diff --git a/src/ui/core.c b/src/ui/core.c index adebdadd..bc4a9587 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -767,6 +767,7 @@ _ui_gone_secure(const char * const recipient, gboolean trusted) title_bar_set_recipient(recipient_str->str); g_string_free(recipient_str, TRUE); win_update_virtual(window); + ui_current_page_off(); } else { int num = wins_get_num(window); status_bar_new(num); @@ -785,6 +786,98 @@ _ui_gone_secure(const char * const recipient, gboolean trusted) } static void +_ui_smp_recipient_initiated(const char * const recipient) +{ + ProfWin *window = wins_get_by_recipient(recipient); + if (window == NULL) { + return; + } else { + win_vprint_line(window, '!', 0, "%s wants to authenticate your identity, use '/otr secret <secret>'.", recipient); + win_update_virtual(window); + if (wins_is_current(window)) { + ui_current_page_off(); + } + } +} + +static void +_ui_smp_recipient_initiated_q(const char * const recipient, const char *question) +{ + ProfWin *window = wins_get_by_recipient(recipient); + if (window == NULL) { + return; + } else { + win_vprint_line(window, '!', 0, "%s wants to authenticate your identity with the following question:", recipient); + win_vprint_line(window, '!', 0, " %s", question); + win_vprint_line(window, '!', 0, "use '/otr answer <answer>'."); + win_update_virtual(window); + if (wins_is_current(window)) { + ui_current_page_off(); + } + } +} + +static void +_ui_smp_unsuccessful_sender(const char * const recipient) +{ + ProfWin *window = wins_get_by_recipient(recipient); + if (window == NULL) { + return; + } else { + win_vprint_line(window, '!', 0, "Authentication failed, the secret you entered does not match the secret entered by %s.", recipient); + win_update_virtual(window); + if (wins_is_current(window)) { + ui_current_page_off(); + } + } +} + +static void +_ui_smp_unsuccessful_receiver(const char * const recipient) +{ + ProfWin *window = wins_get_by_recipient(recipient); + if (window == NULL) { + return; + } else { + win_vprint_line(window, '!', 0, "Authentication failed, the secret entered by %s does not match yours.", recipient); + win_update_virtual(window); + if (wins_is_current(window)) { + ui_current_page_off(); + } + } +} + +static void +_ui_smp_aborted(const char * const recipient) +{ + ProfWin *window = wins_get_by_recipient(recipient); + if (window == NULL) { + return; + } else { + win_vprint_line(window, '!', 0, "SMP session aborted."); + win_update_virtual(window); + if (wins_is_current(window)) { + ui_current_page_off(); + } + } +} + +static void +_ui_smp_successful(const char * const recipient) +{ + ProfWin *window = wins_get_by_recipient(recipient); + if (window == NULL) { + return; + } else { + win_vprint_line(window, '!', 0, "Authentication successful."); + win_update_virtual(window); + if (wins_is_current(window)) { + ui_current_page_off(); + } + } +} + +static void _ui_gone_insecure(const char * const recipient) { ProfWin *window = wins_get_by_recipient(recipient); @@ -798,6 +891,7 @@ _ui_gone_insecure(const char * const recipient) title_bar_set_recipient(recipient_str->str); g_string_free(recipient_str, TRUE); win_update_virtual(window); + ui_current_page_off(); } } } @@ -816,6 +910,7 @@ _ui_trust(const char * const recipient) title_bar_set_recipient(recipient_str->str); g_string_free(recipient_str, TRUE); win_update_virtual(window); + ui_current_page_off(); } } } @@ -834,6 +929,7 @@ _ui_untrust(const char * const recipient) title_bar_set_recipient(recipient_str->str); g_string_free(recipient_str, TRUE); win_update_virtual(window); + ui_current_page_off(); } } } @@ -976,6 +1072,36 @@ _ui_current_set_otr(gboolean value) current->is_otr = value; } +static void +_ui_otr_authenticating(const char * const recipient) +{ + ProfWin *window = wins_get_by_recipient(recipient); + if (window == NULL) { + return; + } else { + win_vprint_line(window, '!', 0, "Authenticating %s...", recipient); + win_update_virtual(window); + if (wins_is_current(window)) { + ui_current_page_off(); + } + } +} + +static void +_ui_otr_authetication_waiting(const char * const recipient) +{ + ProfWin *window = wins_get_by_recipient(recipient); + if (window == NULL) { + return; + } else { + win_vprint_line(window, '!', 0, "Awaiting authentication from %s...", recipient); + win_update_virtual(window); + if (wins_is_current(window)) { + ui_current_page_off(); + } + } +} + static int _ui_current_win_index(void) { @@ -1974,10 +2100,18 @@ ui_init_module(void) ui_ask_password = _ui_ask_password; ui_current_win_is_otr = _ui_current_win_is_otr; ui_current_set_otr = _ui_current_set_otr; + ui_otr_authenticating = _ui_otr_authenticating; + ui_otr_authetication_waiting = _ui_otr_authetication_waiting; ui_gone_secure = _ui_gone_secure; ui_gone_insecure = _ui_gone_insecure; ui_trust = _ui_trust; ui_untrust = _ui_untrust; + ui_smp_recipient_initiated = _ui_smp_recipient_initiated; + ui_smp_recipient_initiated_q = _ui_smp_recipient_initiated_q; + ui_smp_successful = _ui_smp_successful; + ui_smp_unsuccessful_sender = _ui_smp_unsuccessful_sender; + ui_smp_unsuccessful_receiver = _ui_smp_unsuccessful_receiver; + ui_smp_aborted = _ui_smp_aborted; ui_chat_win_contact_online = _ui_chat_win_contact_online; ui_chat_win_contact_offline = _ui_chat_win_contact_offline; ui_handle_recipient_not_found = _ui_handle_recipient_not_found; diff --git a/src/ui/ui.h b/src/ui/ui.h index d56c8f5d..5e850c6c 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -58,10 +58,19 @@ void (*ui_handle_special_keys)(const wint_t * const ch, const char * const inp, gboolean (*ui_switch_win)(const int i); void (*ui_next_win)(void); void (*ui_previous_win)(void); + 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); +void (*ui_smp_recipient_initiated)(const char * const recipient); +void (*ui_smp_recipient_initiated_q)(const char * const recipient, const char *question); + +void (*ui_smp_successful)(const char * const recipient); +void (*ui_smp_unsuccessful_sender)(const char * const recipient); +void (*ui_smp_unsuccessful_receiver)(const char * const recipient); +void (*ui_smp_aborted)(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); @@ -85,6 +94,9 @@ void (*ui_current_error_line)(const char * const msg); void (*ui_current_page_off)(void); void (*ui_current_update_virtual)(void); +void (*ui_otr_authenticating)(const char * const recipient); +void (*ui_otr_authetication_waiting)(const char * const recipient); + win_type_t (*ui_win_type)(int index); char * (*ui_recipient)(int index); void (*ui_close_win)(int index); |