pkgsrc-ng/chat/mcabber/patches/patch-mcabber_otr.c
2014-08-11 13:27:10 +02:00

542 lines
20 KiB
C

$NetBSD: patch-mcabber_otr.c,v 1.1 2014/01/10 09:50:42 wiz Exp $
Fix libotr>=4 build.
--- mcabber/otr.c.orig 2012-12-02 13:27:32.000000000 +0000
+++ mcabber/otr.c
@@ -56,6 +56,20 @@ static void cb_inject_message
const char *protocol,
const char *recipient,
const char *message);
+static void cb_update_context_list(void *opdata);
+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 int cb_max_message_size (void *opdata, ConnContext *context);
+
+#ifdef HAVE_LIBOTR3
static void cb_notify (void *opdata,
OtrlNotifyLevel level,
const char *accountname,
@@ -69,22 +83,26 @@ static int cb_display_otr_message
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 int cb_max_message_size (void *opdata, ConnContext *context);
+
+static void otr_handle_smp_tlvs (OtrlTLV *tlvs, ConnContext *ctx);
+#else /* HAVE_LIBOTR3 */
+static char *tagfile = NULL;
+static guint otr_timer_source = 0;
+
+static void cb_handle_smp_event (void *opdata, OtrlSMPEvent event,
+ ConnContext *context, unsigned short percent,
+ char *question);
+static void cb_handle_msg_event (void *opdata, OtrlMessageEvent event,
+ ConnContext *context, const char *message,
+ gcry_error_t err);
+static void cb_create_instag (void *opdata, const char *accountname,
+ const char *protocol);
+static void cb_timer_control (void *opdata, unsigned int interval);
+#endif /* HAVE_LIBOTR3 */
static OtrlMessageAppOps ops =
{
@@ -92,26 +110,44 @@ static OtrlMessageAppOps ops =
cb_create_privkey,
cb_is_logged_in,
cb_inject_message,
+#ifdef HAVE_LIBOTR3
cb_notify,
cb_display_otr_message,
+#endif
cb_update_context_list,
+#ifdef HAVE_LIBOTR3
cb_protocol_name,
cb_protocol_name_free,
+#endif
cb_new_fingerprint,
cb_write_fingerprints,
cb_gone_secure,
cb_gone_insecure,
cb_still_secure,
+#ifdef HAVE_LIBOTR3
cb_log_message,
+#endif
cb_max_message_size,
- NULL, /*account_name*/
- NULL /*account_name_free*/
+ NULL, /* account_name */
+ NULL, /* account_name_free */
+#ifndef HAVE_LIBOTR3
+ NULL, /* received_symkey */
+ NULL, /* otr_error_message */
+ NULL, /* otr_error_message_free */
+ NULL, /* resent_msg_prefix */
+ NULL, /* resent_msg_prefix_free */
+ cb_handle_smp_event,
+ cb_handle_msg_event,
+ cb_create_instag,
+ NULL, /* convert_msg */
+ NULL, /* convert_free */
+ cb_timer_control,
+#endif
};
static void otr_message_disconnect(ConnContext *ctx);
static ConnContext *otr_get_context(const char *buddy);
static void otr_startstop(const char *buddy, int start);
-static void otr_handle_smp_tlvs(OtrlTLV *tlvs, ConnContext *ctx);
static char *otr_get_dir(void);
@@ -135,7 +171,6 @@ void otr_init(const char *fjid)
account = jidtodisp(fjid);
keyfile = g_strdup_printf("%s%s.key", root, account);
fprfile = g_strdup_printf("%s%s.fpr", root, account);
- g_free(root);
if (otrl_privkey_read(userstate, keyfile)){
scr_LogPrint(LPRINT_LOGNORM, "Could not read OTR key from %s", keyfile);
@@ -145,6 +180,14 @@ void otr_init(const char *fjid)
scr_LogPrint(LPRINT_LOGNORM, "Could not read OTR fingerprints from %s",
fprfile);
}
+#ifndef HAVE_LIBOTR3
+ tagfile = g_strdup_printf("%s%s.tag", root, account);
+ if (otrl_instag_read(userstate, tagfile)) {
+ scr_LogPrint(LPRINT_LOGNORM, "Could not read OTR instance tag from %s", tagfile);
+ cb_create_instag(NULL, account, OTR_PROTOCOL_NAME);
+ }
+#endif
+ g_free(root);
}
void otr_terminate(void)
@@ -154,6 +197,13 @@ void otr_terminate(void)
if (!otr_is_enabled)
return;
+#ifndef HAVE_LIBOTR3
+ if (otr_timer_source > 0) {
+ g_source_remove (otr_timer_source);
+ otr_timer_source = 0;
+ }
+#endif
+
for (ctx = userstate->context_root; ctx; ctx = ctx->next)
if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
otr_message_disconnect(ctx);
@@ -175,6 +225,12 @@ void otr_terminate(void)
userstate = NULL;
g_free(keyfile);
keyfile = NULL;
+ g_free(fprfile);
+ fprfile = NULL;
+#ifndef HAVE_LIBOTR3
+ g_free(tagfile);
+ tagfile = NULL;
+#endif
}
static char *otr_get_dir(void)
@@ -206,7 +262,12 @@ static ConnContext *otr_get_context(cons
mc_strtolower(lowcasebuddy);
ctx = otrl_context_find(userstate, lowcasebuddy, account, OTR_PROTOCOL_NAME,
+#ifdef HAVE_LIBOTR3
1, &null, NULL, NULL);
+#else
+ // INSTAG XXX
+ OTRL_INSTAG_BEST, 1, &null, NULL, NULL);
+#endif
g_free(lowcasebuddy);
return ctx;
}
@@ -216,7 +277,12 @@ static void otr_message_disconnect(ConnC
if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
cb_gone_insecure(NULL, ctx);
otrl_message_disconnect(userstate, &ops, NULL, ctx->accountname,
+#ifdef HAVE_LIBOTR3
ctx->protocol, ctx->username);
+#else
+ // INSTAG XXX
+ ctx->protocol, ctx->username, OTRL_INSTAG_BEST);
+#endif
}
static void otr_startstop(const char *buddy, int start)
@@ -283,6 +349,8 @@ void otr_fingerprint(const char *buddy,
cb_write_fingerprints(NULL);
}
+#ifdef HAVE_LIBOTR3
+
static void otr_handle_smp_tlvs(OtrlTLV *tlvs, ConnContext *ctx)
{
OtrlTLV *tlv = NULL;
@@ -354,6 +422,130 @@ static void otr_handle_smp_tlvs(OtrlTLV
}
}
+#else /* HAVE_LIBOTR3 */
+
+static void cb_handle_smp_event(void *opdata, OtrlSMPEvent event,
+ ConnContext *context, unsigned short percent,
+ char *question)
+{
+ const char *msg = NULL;
+ char *freeme = NULL;
+ switch (event) {
+ case OTRL_SMPEVENT_ASK_FOR_SECRET:
+ msg = freeme = g_strdup_printf("OTR: Socialist Millionaires' Protocol: "
+ "Received SMP Initiation.\n"
+ "Answer with /otr smpr %s $secret",
+ context->username);
+ break;
+ case OTRL_SMPEVENT_ASK_FOR_ANSWER:
+ msg = freeme = g_strdup_printf("OTR: Socialist Millionaires' Protocol: "
+ "Received SMP Initiation.\n"
+ "Answer with /otr smpr %s $secret\n"
+ "Question: %s", context->username,
+ question);
+ break;
+ case OTRL_SMPEVENT_CHEATED:
+ msg = "OTR: Socialist Millionaires' Protocol: Correspondent cancelled negotiation!";
+ otrl_message_abort_smp(userstate, &ops, opdata, context);
+ break;
+ case OTRL_SMPEVENT_IN_PROGRESS:
+ scr_log_print(LPRINT_DEBUG, "OTR: Socialist Millionaires' Protocol: "
+ "Negotiation is in pogress...");
+ break;
+ case OTRL_SMPEVENT_SUCCESS:
+ msg = "OTR: Socialist Millionaires' Protocol: Success!";
+ break;
+ case OTRL_SMPEVENT_FAILURE:
+ msg = "OTR: Socialist Millionaires' Protocol: Failure.";
+ break;
+ case OTRL_SMPEVENT_ABORT:
+ msg = "OTR: Socialist Millionaires' Protocol: Aborted.";
+ break;
+ case OTRL_SMPEVENT_ERROR:
+ msg = "OTR: Socialist Millionaires' Protocol: Error occured, aborting negotiations!";
+ otrl_message_abort_smp(userstate, &ops, opdata, context);
+ break;
+ default:
+ break;
+ }
+
+ if (msg) {
+ scr_WriteIncomingMessage(context->username, msg, 0, HBB_PREFIX_INFO, 0);
+ g_free(freeme);
+ }
+}
+
+static void cb_handle_msg_event(void *opdata, OtrlMessageEvent event,
+ ConnContext *context, const char *message,
+ gcry_error_t err)
+{
+ const char *msg = NULL;
+ char *freeme = NULL;
+ switch (event) {
+ case OTRL_MSGEVENT_ENCRYPTION_REQUIRED:
+ msg = "OTR: Policy requires encryption on message!";
+ break;
+ case OTRL_MSGEVENT_ENCRYPTION_ERROR:
+ msg = "OTR: Encryption error! Message not sent.";
+ break;
+ case OTRL_MSGEVENT_CONNECTION_ENDED:
+ msg = "OTR: Connection closed by remote end, message lost. "
+ "Close or refresh connection.";
+ break;
+ case OTRL_MSGEVENT_SETUP_ERROR:
+ // FIXME
+ msg = freeme = g_strdup_printf("OTR: Error setting up private conversation: %u",
+ err);
+ break;
+ case OTRL_MSGEVENT_MSG_REFLECTED:
+ msg = "OTR: Received own OTR message!";
+ break;
+ case OTRL_MSGEVENT_MSG_RESENT:
+ msg = "OTR: Previous message was resent.";
+ break;
+ case OTRL_MSGEVENT_RCVDMSG_NOT_IN_PRIVATE:
+ msg = "OTR: Received encrypted message, but connection is not established " \
+ "yet! Message lost.";
+ break;
+ case OTRL_MSGEVENT_RCVDMSG_UNREADABLE:
+ msg = "OTR: Unable to read incoming message!";
+ break;
+ case OTRL_MSGEVENT_RCVDMSG_MALFORMED:
+ msg = "OTR: Malformed incoming message!";
+ break;
+ case OTRL_MSGEVENT_LOG_HEARTBEAT_RCVD:
+ scr_log_print(LPRINT_DEBUG, "OTR: Received heartbeat.");
+ break;
+ case OTRL_MSGEVENT_LOG_HEARTBEAT_SENT:
+ scr_log_print(LPRINT_DEBUG, "OTR: Sent heartbeat.");
+ break;
+ case OTRL_MSGEVENT_RCVDMSG_GENERAL_ERR:
+ msg = freeme = g_strdup_printf("OTR: Received general otr error: %s",
+ message);
+ break;
+ case OTRL_MSGEVENT_RCVDMSG_UNENCRYPTED:
+ msg = freeme = g_strdup_printf("OTR: Received unencrypted message: %s",
+ message);
+ break;
+ case OTRL_MSGEVENT_RCVDMSG_UNRECOGNIZED:
+ msg = "OTR: Unable to determine type of received OTR message!";
+ break;
+ case OTRL_MSGEVENT_RCVDMSG_FOR_OTHER_INSTANCE:
+ // XXX
+ scr_log_print(LPRINT_DEBUG, "OTR: Received message for other instance.");
+ break;
+ default:
+ break;
+ }
+
+ if (msg) {
+ scr_WriteIncomingMessage(context->username, msg, 0, HBB_PREFIX_INFO, 0);
+ g_free(freeme);
+ }
+}
+
+#endif /* HAVE_LIBOTR3 */
+
/*
* returns whether a otr_message was received
* sets *otr_data to NULL, when it was an internal otr message
@@ -362,8 +554,10 @@ int otr_receive(char **otr_data, const c
{
int ignore_message;
char *newmessage = NULL;
+#ifdef HAVE_LIBOTR3
OtrlTLV *tlvs = NULL;
OtrlTLV *tlv = NULL;
+#endif
ConnContext *ctx;
ctx = otr_get_context(buddy);
@@ -371,8 +565,8 @@ int otr_receive(char **otr_data, const c
ignore_message = otrl_message_receiving(userstate, &ops, NULL,
ctx->accountname, ctx->protocol,
ctx->username, *otr_data,
- &newmessage, &tlvs,NULL, NULL);
-
+#ifdef HAVE_LIBOTR3
+ &newmessage, &tlvs, NULL, NULL);
tlv = otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED);
if (tlv) {
@@ -387,6 +581,9 @@ int otr_receive(char **otr_data, const c
if (tlvs != NULL)
otrl_tlv_free(tlvs);
+#else
+ &newmessage, NULL, NULL, NULL, NULL);
+#endif
if (ignore_message)
*otr_data = NULL;
@@ -410,13 +607,27 @@ int otr_send(char **msg, const char *bud
if (ctx->msgstate == OTRL_MSGSTATE_PLAINTEXT)
err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname,
+#ifdef HAVE_LIBOTR3
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,
+ NULL, NULL, NULL);
+#endif
else {
htmlmsg = html_escape(*msg);
err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname,
+#ifdef HAVE_LIBOTR3
ctx->protocol, ctx->username, htmlmsg, NULL,
&newmessage, NULL, NULL);
+#else
+ // INSTAG XXX
+ ctx->protocol, ctx->username, OTRL_INSTAG_BEST,
+ htmlmsg, NULL, &newmessage, OTRL_FRAGMENT_SEND_SKIP,
+ NULL, NULL, NULL);
+#endif
g_free(htmlmsg);
}
@@ -648,6 +859,59 @@ static void cb_inject_message(void *opda
LM_MESSAGE_SUB_TYPE_NOT_SET, NULL);
}
+/* 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)
+{
+ /*maybe introduce new status characters for mcabber,
+ * then use this function (?!)*/
+}
+
+/* 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])
+{
+ char *sbuf = NULL;
+ char readable[45];
+
+ otrl_privkey_hash_to_human(readable, fingerprint);
+ sbuf = g_strdup_printf("OTR: new fingerprint: %s", readable);
+ scr_WriteIncomingMessage(username, sbuf, 0, HBB_PREFIX_INFO, 0);
+ g_free(sbuf);
+}
+
+/* The list of known fingerprints has changed. Write them to disk. */
+static void cb_write_fingerprints(void *opdata)
+{
+ otrl_privkey_write_fingerprints(userstate, fprfile);
+}
+
+/* A ConnContext has entered a secure state. */
+static void cb_gone_secure(void *opdata, ConnContext *context)
+{
+ scr_WriteIncomingMessage(context->username, "OTR: channel established", 0,
+ HBB_PREFIX_INFO, 0);
+}
+
+/* A ConnContext has left a secure state. */
+static void cb_gone_insecure(void *opdata, ConnContext *context)
+{
+ scr_WriteIncomingMessage(context->username, "OTR: channel closed", 0,
+ HBB_PREFIX_INFO, 0);
+}
+
+/* We have completed an authentication, using the D-H keys we
+ * already knew. is_reply indicates whether we initiated the AKE. */
+static void cb_still_secure(void *opdata, ConnContext *context, int is_reply)
+{
+ scr_WriteIncomingMessage(context->username, "OTR: channel reestablished", 0,
+ HBB_PREFIX_INFO, 0);
+}
+
+#ifdef HAVE_LIBOTR3
+
/* Display a notification message for a particular
* accountname / protocol / username conversation. */
static void cb_notify(void *opdata, OtrlNotifyLevel level,
@@ -684,14 +948,6 @@ static int cb_display_otr_message(void *
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)
-{
- /*maybe introduce new status characters for mcabber,
- * then use this function (?!)*/
-}
-
/* 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)
@@ -705,54 +961,40 @@ static void cb_protocol_name_free (void
/* We didn't allocated memory, so we don't have to free anything :p */
}
-/* 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])
+/* Log a message. The passed message will end in "\n". */
+static void cb_log_message(void *opdata, const char *message)
{
- char *sbuf = NULL;
- char readable[45];
-
- otrl_privkey_hash_to_human(readable, fingerprint);
- sbuf = g_strdup_printf("OTR: new fingerprint: %s", readable);
- scr_WriteIncomingMessage(username, sbuf, 0, HBB_PREFIX_INFO, 0);
- g_free(sbuf);
+ scr_LogPrint(LPRINT_DEBUG, "OTR: %s", message);
}
-/* The list of known fingerprints has changed. Write them to disk. */
-static void cb_write_fingerprints(void *opdata)
-{
- otrl_privkey_write_fingerprints(userstate, fprfile);
-}
+#else /* HAVE_LIBOTR3 */
-/* A ConnContext has entered a secure state. */
-static void cb_gone_secure(void *opdata, ConnContext *context)
+/* Generate unique instance tag for account. */
+static void cb_create_instag(void *opdata, const char *accountname,
+ const char *protocol)
{
- scr_WriteIncomingMessage(context->username, "OTR: channel established", 0,
- HBB_PREFIX_INFO, 0);
+ if (otrl_instag_generate(userstate, tagfile, accountname, protocol)) {
+ scr_LogPrint(LPRINT_LOGNORM, "OTR instance tag generation failed!");
+ }
}
-/* A ConnContext has left a secure state. */
-static void cb_gone_insecure(void *opdata, ConnContext *context)
+static gboolean otr_timer_cb(gpointer userdata)
{
- scr_WriteIncomingMessage(context->username, "OTR: channel closed", 0,
- HBB_PREFIX_INFO, 0);
+ otrl_message_poll(userstate, &ops, userdata);
+ return TRUE;
}
-/* We have completed an authentication, using the D-H keys we
- * already knew. is_reply indicates whether we initiated the AKE. */
-static void cb_still_secure(void *opdata, ConnContext *context, int is_reply)
+static void cb_timer_control(void *opdata, unsigned int interval)
{
- scr_WriteIncomingMessage(context->username, "OTR: channel reestablished", 0,
- HBB_PREFIX_INFO, 0);
+ if (otr_timer_source > 0) {
+ g_source_remove(otr_timer_source);
+ otr_timer_source = 0;
+ }
+ if (interval > 0)
+ otr_timer_source = g_timeout_add_seconds(interval, otr_timer_cb, opdata);
}
-/* Log a message. The passed message will end in "\n". */
-static void cb_log_message(void *opdata, const char *message)
-{
- scr_LogPrint(LPRINT_DEBUG, "OTR: %s", message);
-}
+#endif /* HAVE_LIBOTR3 */
/* Find the maximum message size supported by this protocol. */
static int cb_max_message_size(void *opdata, ConnContext *context)