1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-12-04 14:46:46 -05:00

Send SMP init message with /otr secret

This commit is contained in:
James Booth 2014-04-26 22:08:53 +01:00
parent f44cf86f23
commit 06d81ed9ce
6 changed files with 98 additions and 2 deletions

View File

@ -1066,6 +1066,7 @@ 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");

View File

@ -2788,7 +2788,23 @@ 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_init_secret(recipient, secret);
ui_current_print_formatted_line('!', 0, "OTR secret entered", secret);
}
}
return TRUE;
} else {
cons_show("Usage: %s", help.usage);
return TRUE;

View File

@ -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"
@ -387,6 +388,22 @@ _otr_untrust(const char * const recipient)
return;
}
static void
_otr_smp_init_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;
}
otrl_message_initiate_smp(user_state, &ops, NULL, context, (const unsigned char*)secret, strlen(secret));
}
static void
_otr_end_session(const char * const recipient)
{
@ -441,15 +458,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);
return NULL;
// message was decrypted, return to user
@ -489,4 +512,5 @@ otr_init_module(void)
otr_encrypt_message = _otr_encrypt_message;
otr_decrypt_message = _otr_decrypt_message;
otr_free_message = _otr_free_message;
otr_smp_init_secret = _otr_smp_init_secret;
}

View File

@ -40,6 +40,8 @@ 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_init_secret)(const char * const recipient, const char *secret);
void (*otr_end_session)(const char * const recipient);
char * (*otr_get_my_fingerprint)(void);

View File

@ -39,4 +39,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);
#endif

View File

@ -106,3 +106,54 @@ 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)
{
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 {
cons_debug("%s initiated SMP", context->username);
// [get secret from user and continue SMP];
}
}
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 {
// If we received TLV2, we will send TLV3 and expect TLV4
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 {
// If we received TLV3, we will send TLV4
// We will not expect more messages, so prepare for next SMP
context->smstate->nextExpected = OTRL_SMP_EXPECT1;
// Report result to user
}
}
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 {
// We will not expect more messages, so prepare for next SMP
context->smstate->nextExpected = OTRL_SMP_EXPECT1;
// Report result to user
}
}
tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT);
if (tlv) {
// The message we are waiting for will not arrive, so reset
// and prepare for the next SMP
context->smstate->nextExpected = OTRL_SMP_EXPECT1;
}
}