325 lines
13 KiB
Plaintext
325 lines
13 KiB
Plaintext
$OpenBSD: patch-src_util_otr_c,v 1.1 2013/08/15 16:34:24 stsp Exp $
|
|
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 */
|