[OTR-dev] [PATCH 4/9] Don't ignore an encrypted message that can't be decrypted.

Andreas Schlick ninox+otr at posteo.net
Wed Oct 22 14:39:22 EDT 2014


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



More information about the OTR-dev mailing list