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 ProfChatWin *chatwin = wins_get_chat(recipient); if (g_hash_table_contains(smp_initiators, recipient)) { otrl_message_respond_smp(user_state, &ops, NULL, context, (const unsigned char*)secret, strlen(secret)); if (chatwin) { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_AUTH, NULL); } g_hash_table_remove(smp_initiators, context->username); } else { otrl_message_initiate_smp(user_state, &ops, NULL, context, (const unsigned char*)secret, strlen(secret)); if (chatwin) { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_AUTH_WAIT, NULL); } } }
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)); ProfChatWin *chatwin = wins_get_chat(recipient); if (chatwin) { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_AUTH_WAIT, 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 { ProfChatWin *chatwin = wins_get_chat(context->username); if (chatwin) { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_INIT, NULL); } 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 { ProfChatWin *chatwin = wins_get_chat(context->username); if (chatwin) { char *question = (char *)tlv->data; char *eoq = memchr(question, '\0', tlv->len); if (eoq) { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_INIT_Q, 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; ProfChatWin *chatwin = wins_get_chat(context->username); if (chatwin) { if (context->smstate->received_question == 0) { if (context->active_fingerprint->trust && (context->active_fingerprint->trust[0] != '\0')) { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_SUCCESS, NULL); chatwin_otr_trust(chatwin); } else { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_SENDER_FAIL, NULL); chatwin_otr_untrust(chatwin); } } else { if (context->smstate->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED) { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_SUCCESS_Q, NULL); } else { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_FAIL_Q, NULL); } } } } } 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; ProfChatWin *chatwin = wins_get_chat(context->username); if (chatwin) { if (context->active_fingerprint->trust && (context->active_fingerprint->trust[0] != '\0')) { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_SUCCESS, NULL); chatwin_otr_trust(chatwin); } else { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_RECEIVER_FAIL, NULL); chatwin_otr_untrust(chatwin); } } } } tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT); if (tlv) { context->smstate->nextExpected = OTRL_SMP_EXPECT1; ProfChatWin *chatwin = wins_get_chat(context->username); if (chatwin) { chatwin_otr_smp_event(chatwin, PROF_OTR_SMP_ABORT, NULL); chatwin_otr_untrust(chatwin); } otr_untrust(context->username); } }