On Thu, Aug 15, 2013 at 01:43:50PM +0200, Stefan Sperling wrote:
> On Thu, Aug 15, 2013 at 01:25:27PM +0200, Pascal Stumpf wrote:
> > climm works fine for me so far with Pidgin on the other side. The only
> > regression I've noticed is that the message prompt does not change
> > anymore from ">>>/<<<" for plaintext to "&>>/<<&" for OTR. This should
> > be handled by OTRMsg{In,Out} setting msg->otrencrypted, but apparently
> > that doesn't happen. Maybe ctx->msgstate is not properly set (though
> > that would be bad, so I hope not). Anyway, it's probably just cosmetic.
>
> Thanks, I'll take a look.
There was a bug in context selection.
With this patch it sets msg->otrencrypted to 1 (observed in gdb,
don't know wether the UI looks any better now).
Also fixes the 'otr trust' command, which kept complaining that
no active fingerprint was selected.
Index: Makefile
===================================================================
RCS file: /cvs/ports/net/climm/Makefile,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile
--- Makefile 11 Mar 2013 11:35:45 -0000 1.2
+++ Makefile 15 Aug 2013 10:28:04 -0000
@@ -3,6 +3,7 @@
COMMENT = simple, command-line multi messenger
DISTNAME = climm-0.7.1
+REVISION = 0
CATEGORIES = net
@@ -27,7 +28,8 @@ LIB_DEPENDS = security/libotr \
USE_GMAKE = Yes
-CONFIGURE_STYLE = gnu
+AUTOCONF_VERSION = 2.65
+CONFIGURE_STYLE = autoconf
CONFIGURE_ARGS += --enable-ssl=gnutls
CONFIGURE_ENV = CPPFLAGS="-I${LOCALBASE}/include" \
LDFLAGS="-L${LOCALBASE}/lib"
Index: patches/patch-m4_libotr_m4
===================================================================
RCS file: patches/patch-m4_libotr_m4
diff -N patches/patch-m4_libotr_m4
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-m4_libotr_m4 14 Aug 2013 17:14:03 -0000
@@ -0,0 +1,12 @@
+$OpenBSD$
+--- m4/libotr.m4.orig Wed Aug 14 19:12:40 2013
++++ m4/libotr.m4 Wed Aug 14 19:13:23 2013
+@@ -68,7 +68,7 @@ LIBS="$LIBOTR_LIBS $LIBS"
+ AC_MSG_RESULT($LIBOTR_LIBS)
+
+ dnl Check for a working version of libotr that is of the right version.
+-min_libotr_version=ifelse([$1], ,3.0.0,$1)
++min_libotr_version=ifelse([$1], ,4.0.0,$1)
+ no_libotr=""
+ libotr_min_major_version=`echo $min_libotr_version | \
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
Index: patches/patch-src_util_otr_c
===================================================================
RCS file: patches/patch-src_util_otr_c
diff -N patches/patch-src_util_otr_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_util_otr_c 15 Aug 2013 10:58:20 -0000
@@ -0,0 +1,324 @@
+$OpenBSD$
+libotr-4.0.0 support
+--- src/util_otr.c.orig Sat Mar 20 15:13:15 2010
++++ src/util_otr.c Thu Aug 15 12:58:15 2013
+@@ -36,6 +36,8 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <assert.h>
++#include <signal.h>
++#include <sys/time.h>
+
+ #include <libotr/proto.h>
+ #include <libotr/userstate.h>
+@@ -54,13 +56,16 @@
+
+ /* Holds private keys + known fingerprints + context */
+ static OtrlUserState userstate = NULL;
++struct itimerval otr_timer;
+
+ /* filename for private keys / fingerprints / logfile */
+ #define KEYFILENAME ("otr.key")
+ #define FPRFILENAME ("otr.fpr")
+ #define LOGFILENAME ("otr.log")
++#define INSFILENAME ("otr.ins")
+ static str_s keyfile = {0, 0, 0};
+ static str_s fprfile = {0, 0, 0};
++static str_s insfile = {0, 0, 0};
+ static FILE *log_file = NULL;
+
+ /* callback prototypes */
+@@ -69,20 +74,14 @@ static void cb_create_privkey (void *opdata, const cha
+ static int cb_is_logged_in (void *opdata, const char *accountname, const char
*protocol, const char *recipient);
+ static void cb_inject_message (void *opdata, const char *accountname, const
char *protocol,
+ const char *recipient, const char *message);
+-static void cb_notify (void *opdata, OtrlNotifyLevel level, const char
*accountname, const char *protocol,
+- const char *username, const char *title, const char *primary, const char
*secondary);
+-static int cb_display_otr_message (void *opdata, const char *accountname,
+- const char *protocol, const char *username, const char *msg);
+ static void cb_update_context_list (void *opdata);
+-static const char *cb_protocol_name (void *opdata, const char *protocol);
+-static void cb_protocol_name_free (void *opdata, const char *protocol_name);
+ static void cb_new_fingerprint (void *opdata, OtrlUserState us, const char
*accountname,
+ const char *protocol, const char *username, unsigned char
fingerprint[20]);
+ static void cb_write_fingerprints (void *opdata);
+ static void cb_gone_secure (void *opdata, ConnContext *context);
+ static void cb_gone_insecure (void *opdata, ConnContext *context);
+ static void cb_still_secure (void *opdata, ConnContext *context, int
is_reply);
+-static void cb_log_message (void *opdata, const char *message);
++static void cb_create_instag(void *opdata, const char *accountname, const
char *protocol);
+
+ /* Callback structure */
+ static OtrlMessageAppOps ops =
+@@ -91,17 +90,23 @@ static OtrlMessageAppOps ops =
+ .create_privkey = cb_create_privkey,
+ .is_logged_in = cb_is_logged_in,
+ .inject_message = cb_inject_message,
+- .notify = cb_notify,
+- .display_otr_message = cb_display_otr_message,
+ .update_context_list = cb_update_context_list,
+- .protocol_name = cb_protocol_name,
+- .protocol_name_free = cb_protocol_name_free,
+ .new_fingerprint = cb_new_fingerprint,
+ .write_fingerprints = cb_write_fingerprints,
+ .gone_secure = cb_gone_secure,
+ .gone_insecure = cb_gone_insecure,
+ .still_secure = cb_still_secure,
+- .log_message = cb_log_message
++ .received_symkey = NULL,
++ .otr_error_message = NULL,
++ .otr_error_message_free= NULL,
++ .resent_msg_prefix = NULL,
++ .resent_msg_prefix_free= NULL,
++ .handle_smp_event = NULL,
++ .create_instag = cb_create_instag,
++ .convert_msg = NULL,
++ .convert_free = NULL,
++ .timer_control = NULL,
++
+ };
+
+ /* connection type to protocol name mapping */
+@@ -175,12 +180,15 @@ static ConnContext *find_context (Contact *cont, int c
+ {
+ ConnContext *ctx;
+ int created = 0;
++ OtrlInsTag *instagp;
+
+ if (!cont || !userstate || !uiG.conn)
+ return NULL;
+
++ instagp = otrl_instag_find(userstate, cont->screen, proto_name
(cont->serv->type));
+ ctx = otrl_context_find (userstate, cont->screen, cont->serv->screen,
+- proto_name (cont->serv->type), create, &created,
add_app_data_find, cont);
++ proto_name (cont->serv->type), instagp ? instagp->instag :
OTRL_INSTAG_BEST,
++ create, &created, add_app_data_find, cont);
+ if (ctx)
+ assert (ctx->app_data == cont);
+ return ctx;
+@@ -264,10 +272,17 @@ static void print_context (ConnContext *ctx)
+ else if (p == (OTRL_POLICY_ALWAYS & ~OTRL_POLICY_ALLOW_V1))
+ policy = i18n (2681, "always");
+ else policy = i18n (2682, "unknown");
++
++ if (ctx->protocol_version >= 3)
++ rl_printf ("%s[%x]/%s/%s[%x]: %s%s%s (%s) [%s]\n",
++ ctx->accountname, ctx->our_instance,
++ ctx->protocol, ctx->username, ctx->their_instance,
++ COLQUOTE, state, COLNONE, auth, policy);
++ else
++ rl_printf ("%s/%s/%s: %s%s%s (%s) [%s]\n",
++ ctx->accountname, ctx->protocol, ctx->username,
++ COLQUOTE, state, COLNONE, auth, policy);
+
+- rl_printf ("%s/%s/%s: %s%s%s (%s) [%s]\n",
+- ctx->accountname, ctx->protocol, ctx->username, COLQUOTE,
+- state, COLNONE, auth, policy);
+ if (ctx->active_fingerprint && ctx->active_fingerprint->fingerprint)
+ {
+ char fpr[45], *tr;
+@@ -278,8 +293,8 @@ static void print_context (ConnContext *ctx)
+ if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
+ {
+ char *sid = readable_sid (ctx->sessionid, ctx->sessionid_len,
ctx->sessionid_half);
+- rl_printf (" V%u/%u: %s%s%s\n",
+- ctx->protocol_version, ctx->generation, COLQUOTE, sid,
COLNONE);
++ rl_printf (" V%u: %s%s%s\n",
++ ctx->protocol_version, COLQUOTE, sid, COLNONE);
+ free (sid);
+ }
+ }
+@@ -316,6 +331,11 @@ static void print_keys ()
+ }
+ }
+
++void otr_timer_alarm(int i)
++{
++ otrl_message_poll(userstate, &ops, NULL);
++}
++
+ /* Initialize OTR library, create user state
+ * and read private key/fingerprint lists */
+ void OTRInit ()
+@@ -326,7 +346,7 @@ void OTRInit ()
+
+ if (!libotr_is_present)
+ {
+- rl_printf (i18n (2634, "Install libOTR 3.0.0 or newer and enjoy
off-the-record encrypted messages!\n"));
++ rl_printf (i18n (2634, "Install libOTR 4.0.0 or newer and enjoy
off-the-record encrypted messages!\n"));
+ return;
+ }
+
+@@ -334,12 +354,28 @@ void OTRInit ()
+
+ assert (!userstate);
+ userstate = otrl_userstate_create ();
++ otr_timer.it_interval.tv_sec =
otrl_message_poll_get_default_interval(userstate);
++ otr_timer.it_interval.tv_usec = 0;
++ otr_timer.it_value.tv_sec = otr_timer.it_interval.tv_sec;
++ otr_timer.it_value.tv_usec = 0;
++ setitimer(ITIMER_REAL, &otr_timer, NULL);
++ signal(SIGALRM, otr_timer_alarm);
+
+ /* build filename strings */
+ s_init (&keyfile, PrefUserDirReal (prG), strlen (KEYFILENAME));
+ s_cat (&keyfile, KEYFILENAME);
+ s_init (&fprfile, PrefUserDirReal (prG), strlen (FPRFILENAME));
+ s_cat (&fprfile, FPRFILENAME);
++ s_init (&insfile, PrefUserDirReal (prG), strlen (INSFILENAME));
++ s_cat (&insfile, INSFILENAME);
++
++ /* get or create instance tag */
++ ret = otrl_instag_read (userstate, insfile.txt);
++ if (ret)
++ {
++ for (i = 0; (serv = ServerNr (i)); i++)
++ otrl_instag_generate (userstate, insfile.txt, serv->screen,
proto_name (serv->type));
++ }
+
+ /* get privat keys */
+ ret = otrl_privkey_read (userstate, keyfile.txt);
+@@ -379,9 +415,11 @@ void OTREnd ()
+ if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
+ {
+ otrl_message_disconnect (userstate, &ops, ctx->app_data,
+- ctx->accountname, ctx->protocol, ctx->username);
++ ctx->accountname, ctx->protocol, ctx->username,
++ OTRL_INSTAG_BEST);
+ }
+
++ timerclear(&otr_timer.it_value);
+ otrl_userstate_free (userstate);
+ userstate = NULL;
+
+@@ -419,7 +457,7 @@ int OTRMsgIn (Contact *cont, fat_srv_msg_t *msg)
+ #endif
+
+ ret = otrl_message_receiving (userstate, &ops, pcont, pcont->serv->screen,
+- proto_name (pcont->serv->type), pcont->screen, msg->msgtext,
&otr_text, NULL, add_app_data_find, pcont);
++ proto_name (pcont->serv->type), pcont->screen, msg->msgtext,
&otr_text, NULL, NULL, add_app_data_find, pcont);
+
+ if (ret)
+ {
+@@ -481,7 +519,8 @@ Message *OTRMsgOut (Message *msg)
+ #endif
+
+ ret = otrl_message_sending (userstate, &ops, cont, cont->serv->screen,
proto_name (cont->serv->type),
+- cont->screen, msg->send_message, NULL, &otr_text,
add_app_data_find, cont);
++ cont->screen, OTRL_INSTAG_BEST, msg->send_message, NULL,
&otr_text,
++ OTRL_FRAGMENT_SEND_SKIP, NULL, add_app_data_find, cont);
+
+ if (ret)
+ {
+@@ -546,7 +585,7 @@ void OTRStart (Contact *cont, UBYTE start)
+ return;
+
+ if (start && ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
+- otrl_message_disconnect (userstate, &ops, cont, ctx->accountname,
ctx->protocol, ctx->username);
++ otrl_message_disconnect (userstate, &ops, cont, ctx->accountname,
ctx->protocol, ctx->username, OTRL_INSTAG_BEST);
+
+ if (start)
+ {
+@@ -563,7 +602,7 @@ void OTRStart (Contact *cont, UBYTE start)
+ free (msg);
+ }
+ else
+- otrl_message_disconnect (userstate, &ops, cont, ctx->accountname,
ctx->protocol, ctx->username);
++ otrl_message_disconnect (userstate, &ops, cont, ctx->accountname,
ctx->protocol, ctx->username, OTRL_INSTAG_BEST);
+ }
+
+ void OTRSetTrust (Contact *cont, UBYTE trust)
+@@ -731,47 +770,6 @@ static void cb_inject_message (void *opdata, const cha
+ }
+ }
+
+-/* Display a notification message for a particular accountname /
+- * protocol / username conversation. */
+-static void cb_notify (void *opdata, OtrlNotifyLevel level, const char
*accountname, const char *protocol,
+- const char *username, const char *title, const char *primary, const
char *secondary)
+-{
+- Contact *cont = (Contact *)opdata;
+- const char *type;
+-
+- assert (cont);
+- assert (cont == find_contact (accountname, protocol, username));
+-
+- switch (level)
+- {
+- case OTRL_NOTIFY_ERROR: type = "Error"; break;
+- case OTRL_NOTIFY_WARNING: type = "Warning"; break;
+- case OTRL_NOTIFY_INFO: type = "Info"; break;
+- default: type = "Notify";
+- }
+-
+- rl_log_for (cont->nick, COLCONTACT);
+- rl_printf ("%sOTR %s:%s %s\n %s\n %s\n", COLERROR, type, COLNONE,
+- title, primary, secondary);
+-}
+-
+-/* Display an OTR control message for a particular accountname /
+- * protocol / username conversation. Return 0 if you are able to
+- * successfully display it. If you return non-0 (or if this
+- * function is NULL), the control message will be displayed inline,
+- * as a received message, or else by using the above notify()
+- * callback. */
+-static int cb_display_otr_message (void *opdata, const char *accountname,
+- const char *protocol, const char *username, const char *msg)
+-{
+- Contact *cont = (Contact *)opdata;
+- assert (cont);
+- assert (cont == find_contact (accountname, protocol, username));
+- rl_log_for (cont->nick, COLCONTACT);
+- rl_printf ("%sOTR%s: %s\n", COLERROR, COLNONE, msg);
+- return 0;
+-}
+-
+ /* When the list of ConnContexts changes (including a change in
+ * state), this is called so the UI can be updated. */
+ static void cb_update_context_list (void *opdata)
+@@ -780,19 +778,11 @@ static void cb_update_context_list (void *opdata)
+ /* print_all_context (); */
+ }
+
+-/* Return a newly-allocated string containing a human-friendly name
+- * for the given protocol id */
+-static const char *cb_protocol_name (void *opdata, const char *protocol)
++static void cb_create_instag(void *opdata, const char *accountname, const
char *protocol)
+ {
+- /* is this function used anywhere? */
+- return strdup (protocol);
++ otrl_instag_generate(userstate, insfile.txt, accountname, protocol);
+ }
+
+-/* Deallocate a string allocated by protocol_name */
+-static void cb_protocol_name_free (void *opdata, const char *protocol_name) {
+- free ((char *) protocol_name);
+-}
+-
+ /* A new fingerprint for the given user has been received. */
+ static void cb_new_fingerprint (void *opdata, OtrlUserState us, const char
*accountname,
+ const char *protocol, const char *username, unsigned char
fingerprint[20])
+@@ -844,23 +834,5 @@ static void cb_still_secure (void *opdata, ConnContext
+ rl_printf (i18n (2663, "secure OTR channel reestablished.\n"));
+ else
+ rl_printf (i18n (2664, "reestablished secure OTR channel.\n"));
+-}
+-
+-/* Log a message. The passed message will end in "\n". */
+-static void cb_log_message (void *opdata, const char *message)
+-{
+- if (!OTR_ENABLE_LOG)
+- return;
+-
+- if (log_file == NULL)
+- {
+- str_s logname = {0, 0, 0};
+- s_init (&logname, PrefUserDirReal (prG), strlen (LOGFILENAME));
+- s_cat (&logname, LOGFILENAME);
+- log_file = fopen (logname.txt, "a");
+- s_done (&logname);
+- }
+- if (log_file != NULL)
+- fputs (message, log_file);
+ }
+ #endif /* ENABLE_OTR */