changeset 2213:0c78d31c753d

Change otr_send() prototype This patch updates otr_send() in order to differenciate original and encrypted messages. It should also fix a memory leak of OTR-encrypted messages.
author Mikael Berthe <mikael@lilotux.net>
date Thu, 05 Nov 2015 19:46:09 +0100
parents 778280b01bcb
children ae1cb5b25e51
files mcabber/mcabber/api.h mcabber/mcabber/otr.c mcabber/mcabber/otr.h mcabber/mcabber/xmpp.c
diffstat 4 files changed, 46 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/mcabber/api.h	Thu Nov 05 15:08:47 2015 +0100
+++ b/mcabber/mcabber/api.h	Thu Nov 05 19:46:09 2015 +0100
@@ -4,8 +4,8 @@
 #include <glib.h>
 #include <mcabber/config.h> // For MCABBER_BRANCH
 
-#define MCABBER_API_VERSION 40
-#define MCABBER_API_MIN     38
+#define MCABBER_API_VERSION 41
+#define MCABBER_API_MIN     41
 
 #define MCABBER_BRANCH_DEV  1
 
--- a/mcabber/mcabber/otr.c	Thu Nov 05 15:08:47 2015 +0100
+++ b/mcabber/mcabber/otr.c	Thu Nov 05 19:46:09 2015 +0100
@@ -598,26 +598,31 @@
   return 0;
 }
 
-int otr_send(char **msg, const char *buddy)
+char *otr_send(const char *msg, const char *buddy, int *encryption_status)
 {
   gcry_error_t err;
   char *newmessage = NULL;
-  char *htmlmsg;
+  char *htmlmsg, *rmsg;
   ConnContext *ctx = otr_get_context(buddy);
 
+  *encryption_status = 0;
+
+  if (!msg || !buddy || !encryption_status)
+    return NULL;
+
   if (ctx->msgstate == OTRL_MSGSTATE_PLAINTEXT)
     err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname,
 #ifdef HAVE_LIBOTR3
-                               ctx->protocol, ctx->username, *msg, NULL,
+                               ctx->protocol, ctx->username, msg, NULL,
                                &newmessage, NULL, NULL);
 #else
                                // INSTAG XXX
                                ctx->protocol, ctx->username, OTRL_INSTAG_BEST,
-                               *msg, NULL, &newmessage, OTRL_FRAGMENT_SEND_SKIP,
+                               msg, NULL, &newmessage, OTRL_FRAGMENT_SEND_SKIP,
                                NULL, NULL, NULL);
 #endif
   else {
-    htmlmsg = html_escape(*msg);
+    htmlmsg = html_escape(msg);
     err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname,
 #ifdef HAVE_LIBOTR3
                                ctx->protocol, ctx->username, htmlmsg, NULL,
@@ -631,17 +636,23 @@
     g_free(htmlmsg);
   }
 
-  if (err)
-    *msg = NULL; /*something went wrong, don't send the plain-message! */
+  if (err || !newmessage)
+    return NULL; /* something went wrong, don't send the plain-message! */
+
+  if (cb_policy(NULL, ctx) & OTRL_POLICY_REQUIRE_ENCRYPTION ||
+      ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
+    *encryption_status = 1;
 
-  if (!err && newmessage) {
-    *msg = g_strdup(newmessage);
-    otrl_message_free(newmessage);
-    if (cb_policy(NULL, ctx) & OTRL_POLICY_REQUIRE_ENCRYPTION ||
-        ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
-      return 1;
+  /* Check the new message is not empty */
+  if (newmessage[0] || !msg[0]) {
+    rmsg = g_strdup(newmessage);
+  } else {
+    rmsg = NULL;
+    *encryption_status = 0;
   }
-  return 0;
+
+  otrl_message_free(newmessage);
+  return rmsg;
 }
 
 /* Prints OTR connection state */
--- a/mcabber/mcabber/otr.h	Thu Nov 05 15:08:47 2015 +0100
+++ b/mcabber/mcabber/otr.h	Thu Nov 05 19:46:09 2015 +0100
@@ -33,8 +33,8 @@
 
 void otr_key        (void);
 
-int  otr_receive    (char **otr_data, const char * buddy, int * free_msg);
-int  otr_send       (char **msg, const char *buddy);
+int   otr_receive   (char **otr_data,  const char * buddy, int * free_msg);
+char *otr_send      (const char * msg, const char * buddy, int * status);
 
 #endif /* HAVE_LIBOTR */
 
--- a/mcabber/mcabber/xmpp.c	Thu Nov 05 15:08:47 2015 +0100
+++ b/mcabber/mcabber/xmpp.c	Thu Nov 05 19:46:09 2015 +0100
@@ -299,10 +299,12 @@
 }
 
 //  xmpp_send_msg(jid, text, type, subject,
-//                otrinject, *encrypted, type_overwrite)
+//                otrinject, *encrypted, type_overwrite, *xep184)
 // When encrypted is not NULL, the function set *encrypted to 1 if the
-// message has been PGP-encrypted.  If encryption enforcement is set and
-// encryption fails, *encrypted is set to -1.
+// message has been PGP (or OTR) -encrypted.  If encryption enforcement is set
+// and encryption fails, *encrypted is set to -1.
+// otrinject should be set to FALSE (unless the message already has an OTR
+// payload, i.e. if the function is called from an otr.c routine).
 void xmpp_send_msg(const char *fjid, const char *text, int type,
                    const char *subject, gboolean otrinject, gint *encrypted,
                    LmMessageSubType type_overwrite, gpointer *xep184)
@@ -311,6 +313,7 @@
   LmMessageSubType subtype;
 #ifdef HAVE_LIBOTR
   int otr_msg = 0;
+  char *otr_msg_string = NULL;
 #endif
   char *barejid;
 #if defined HAVE_GPGME || defined XEP0085
@@ -354,13 +357,13 @@
 #ifdef HAVE_LIBOTR
   if (otr_enabled() && !otrinject) {
     if (type == ROSTER_TYPE_USER) {
-      otr_msg = otr_send((char **)&text, barejid);
-      if (!text) {
-        g_free(barejid);
+      otr_msg_string = otr_send(text, barejid, &otr_msg);
+      if (!otr_msg_string) {
         if (encrypted)
           *encrypted = -1;
-        return;
+        goto xmpp_send_msg_return;
       }
+      text = otr_msg_string;
     }
     if (otr_msg && encrypted)
       *encrypted = ENCRYPTED_OTR;
@@ -394,8 +397,7 @@
         if (!enc && force) {
           if (encrypted)
             *encrypted = -1;
-          g_free(barejid);
-          return;
+          goto xmpp_send_msg_return;
         }
       }
     }
@@ -436,7 +438,6 @@
                                   "xmlns", NS_RECEIPTS);
     *xep184 = g_strdup(lm_message_get_id(x));
   }
-  g_free(barejid);
 
 #ifdef XEP0085
   // If typing notifications are disabled, we can skip all this stuff...
@@ -470,6 +471,12 @@
     update_last_use();
   lm_connection_send(lconnection, x, NULL);
   lm_message_unref(x);
+
+xmpp_send_msg_return:
+#ifdef HAVE_LIBOTR
+  g_free(otr_msg_string);
+#endif
+  g_free(barejid);
 }
 
 #ifdef XEP0085