On Thu, 15 Aug 2013 13:59:02 +0200, Stefan Sperling wrote: > 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.
Works great for me, thanks. > 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 */ > >