Assume that Alice and Bob have a private chat and that Bob's OTR state suddenly reverts to plain text (e.g. Bob's pidgin crashed). In this case, Alice will not be notified of Bob's state change and she can still send messages to Bob. However, the first message will be silently dropped and the following messages cannot be decrypted by Bob. Unless Bob notifies Alice of this, Alice will remain unaware of the problem. With this patch, an error message will be sent to Alice and that hopefully refreshes the OTR session (depending on the policy). --- src/message.c | 61 +++++++++++++++++++++++++---------------------------------- 1 file changed, 26 insertions(+), 35 deletions(-)
diff --git a/src/message.c b/src/message.c index 1dff951..c3a9389 100644 --- a/src/message.c +++ b/src/message.c @@ -1099,12 +1099,17 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops, m_context->context_priv->may_retransmit = 0; } - if (msgtype == OTRL_MSGTYPE_DH_KEY) { - otrl_auth_copy_on_key(&(m_context->auth), &(context->auth)); - } else if (msgtype != OTRL_MSGTYPE_DH_COMMIT) { - edata.ignore_message = 1; - goto end; - } + if (msgtype == OTRL_MSGTYPE_DH_KEY) { + otrl_auth_copy_on_key(&m_context->auth, &context->auth); + } else if (msgtype != OTRL_MSGTYPE_DH_COMMIT) { + if (msgtype == OTRL_MSGTYPE_DATA && + context->msgstate == OTRL_MSGSTATE_PLAINTEXT) { + report_error(ops, opdata, OTRL_MSGEVENT_RCVDMSG_NOT_IN_PRIVATE, + OTRL_ERRCODE_MSG_UNREADABLE, context); + } + edata.ignore_message = 1; + goto end; + } /* Update the context list */ if (ops->update_context_list) { @@ -1313,35 +1318,21 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops, case OTRL_MSGSTATE_PLAINTEXT: case OTRL_MSGSTATE_FINISHED: - /* See if we're supposed to ignore this message in - * the event it's unreadable. */ - err = otrl_proto_data_read_flags(message, &flags); - if ((flags & OTRL_MSGFLAGS_IGNORE_UNREADABLE)) { - edata.ignore_message = 1; - break; - } - - if(best_context && best_context != context && - best_context->msgstate == OTRL_MSGSTATE_ENCRYPTED) { - - if (ops->handle_msg_event) { - ops->handle_msg_event(opdata, - OTRL_MSGEVENT_RCVDMSG_FOR_OTHER_INSTANCE, - m_context, NULL, - gcry_error(GPG_ERR_NO_ERROR)); - } - } else if (ops->handle_msg_event) { - ops->handle_msg_event(opdata, - OTRL_MSGEVENT_RCVDMSG_NOT_IN_PRIVATE, - context, NULL, - gcry_error(GPG_ERR_NO_ERROR)); - } - edata.ignore_message = 1; - - /* We don't actually want to send anything in this case, - since this could just be a message intended for another - v2 instance. We still notify the local user though */ - break; + /* See if we're supposed to ignore this message in + * the event it's unreadable. */ + edata.ignore_message = 1; + err = otrl_proto_data_read_flags(message, &flags); + if (!err && flags & OTRL_MSGFLAGS_IGNORE_UNREADABLE) { + break; + } + if (version >= 3) { + report_error(ops, opdata, OTRL_MSGEVENT_RCVDMSG_NOT_IN_PRIVATE, + OTRL_ERRCODE_MSG_UNREADABLE, context); + } + /* We don't actually want to send anything in this case, + * since this could just be a message intended for another + * v2 instance. We still notify the local user though */ + break; case OTRL_MSGSTATE_ENCRYPTED: extrakey = gcry_malloc_secure(OTRL_EXTRAKEY_BYTES); -- 2.1.2 _______________________________________________ OTR-dev mailing list OTR-dev@lists.cypherpunks.ca http://lists.cypherpunks.ca/mailman/listinfo/otr-dev