summaryrefslogtreecommitdiff
path: root/src/otr/otr-fe.c
diff options
context:
space:
mode:
authorAlexander Færøy <ahf@0x90.dk>2015-01-04 01:57:21 +0100
committerAlexander Færøy <ahf@irssi.org>2018-02-26 23:32:57 +0100
commit016b42baea9d7dcd2a284f873246c06259c560dd (patch)
tree8c5382398598851bd23b8ca3d439d580f224d684 /src/otr/otr-fe.c
parentad4324d24210f30646575b8bcbae8b50d2149224 (diff)
downloadirssi-016b42baea9d7dcd2a284f873246c06259c560dd.zip
Add OTR support.
This patch adds support for the OTR protocol to irssi. This is an import of the external irssi-otr project that we are now taking over maintership for. Major thanks to the original authors of Irssi-OTR: Uli Meis and David Goulet. Thanks to the OTR community in #OTR on OFTC, thanks to everyone who have helped testing the patches and submitted UI suggestions.
Diffstat (limited to 'src/otr/otr-fe.c')
-rw-r--r--src/otr/otr-fe.c344
1 files changed, 344 insertions, 0 deletions
diff --git a/src/otr/otr-fe.c b/src/otr/otr-fe.c
new file mode 100644
index 00000000..13e37576
--- /dev/null
+++ b/src/otr/otr-fe.c
@@ -0,0 +1,344 @@
+/*
+ * Off-the-Record Messaging (OTR) module for the irssi IRC client
+ *
+ * Copyright (C) 2008 Uli Meis <a.sporto+bee@gmail.com>
+ * 2012 David Goulet <dgoulet@ev0ke.net>
+ * 2014 Alexander Færøy <ahf@0x90.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA
+ */
+
+#include "common.h"
+#include "levels.h"
+#include "printtext.h"
+#include "commands.h"
+#include "irc.h"
+#include "irc-servers.h"
+#include "irc-queries.h"
+#include "statusbar-item.h"
+
+#include "otr.h"
+#include "otr-formats.h"
+#include "key.h"
+
+static void cmd_otr(const char *data, SERVER_REC *server, void *item)
+{
+ if (*data == '\0')
+ data = "info"; // FIXME(ahf): Is this really what we want as default?
+
+ command_runsub("otr", data, server, item);
+
+ // We always redraw the OTR statusbar, just in case.
+ statusbar_items_redraw("otr");
+}
+
+static void cmd_otr_debug(const char *data)
+{
+ otr_debug_toggle();
+
+ if (otr_debug_get())
+ printtext(NULL, NULL, MSGLEVEL_CRAP, "OTR debugging enabled");
+ else
+ printtext(NULL, NULL, MSGLEVEL_CRAP, "OTR debugging disabled");
+}
+
+static void cmd_otr_init(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+{
+ QUERY_REC *query;
+ char *target;
+ ConnContext *ctx;
+
+ g_return_if_fail(server != NULL);
+
+ if (!server->connected)
+ cmd_return_error(CMDERR_NOT_CONNECTED);
+
+ if (!IS_QUERY(item))
+ cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+ query = QUERY(item);
+ target = query->name;
+
+ ctx = otr_find_context(server, target, FALSE);
+ if (ctx && ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
+ printformat(server, target, MSGLEVEL_CRAP, TXT_OTR_SESSION_ALREADY_SECURED, ctx->accountname);
+ return;
+ }
+
+ printformat(server, target, MSGLEVEL_CRAP, TXT_OTR_SESSION_INITIATING);
+
+ /*
+ * Irssi does not handle well the HTML tag in the default OTR query message
+ * so just send the OTR tag instead. Contact me for a better fix! :)
+ */
+ otr_send_message(server, target, "?OTRv23?");
+}
+
+static void cmd_otr_finish(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+{
+ QUERY_REC *query;
+ char *target;
+
+ g_return_if_fail(server != NULL);
+
+ if (!server->connected)
+ cmd_return_error(CMDERR_NOT_CONNECTED);
+
+ if (!IS_QUERY(item))
+ cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+ query = QUERY(item);
+ target = query->name;
+
+ otr_finish(server, target);
+}
+
+static void cmd_otr_trust(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+{
+ QUERY_REC *query;
+ char *target;
+
+ char *fingerprint, *human_fingerprint;
+ void *free_arg;
+
+ g_return_if_fail(server != NULL);
+
+ query = QUERY(item);
+ target = query ? query->name : NULL;
+
+ if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST, &fingerprint))
+ return;
+
+ // We fallback to target if fingerprint isn't specified.
+ if (*fingerprint == '\0' && target == NULL)
+ cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+ human_fingerprint = g_ascii_strup(fingerprint, -1);
+ otr_trust(server, target, human_fingerprint, user_state_global);
+ g_free(human_fingerprint);
+
+ cmd_params_free(free_arg);
+}
+
+static void cmd_otr_distrust(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+{
+ QUERY_REC *query;
+ char *target;
+
+ char *fingerprint, *human_fingerprint;
+ void *free_arg;
+
+ g_return_if_fail(server != NULL);
+
+ query = QUERY(item);
+ target = query ? query->name : NULL;
+
+ if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST, &fingerprint))
+ return;
+
+ // We fallback to target if fingerprint isn't specified.
+ if (*fingerprint == '\0' && target == NULL)
+ cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+ human_fingerprint = g_ascii_strup(fingerprint, -1);
+ otr_distrust(server, target, human_fingerprint, user_state_global);
+ g_free(human_fingerprint);
+
+ cmd_params_free(free_arg);
+}
+
+static void cmd_otr_forget(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+{
+ QUERY_REC *query;
+ char *target;
+
+ char *fingerprint, *human_fingerprint;
+ void *free_arg;
+
+ g_return_if_fail(server != NULL);
+
+ if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_GETREST, &fingerprint))
+ return;
+
+ query = QUERY(item);
+ target = query ? query->name : NULL;
+
+ // We fallback to target if fingerprint isn't specified.
+ if (*fingerprint == '\0' && target == NULL)
+ cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+ human_fingerprint = g_ascii_strup(fingerprint, -1);
+ otr_forget(server, target, human_fingerprint, user_state_global);
+ g_free(human_fingerprint);
+
+ cmd_params_free(free_arg);
+}
+
+static void cmd_otr_authabort(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+{
+ QUERY_REC *query;
+ char *target;
+
+ query = QUERY(item);
+ target = query ? query->name : NULL;
+
+ if (server == NULL || target == NULL)
+ cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+ otr_auth_abort(server, target);
+}
+
+static void cmd_otr_auth(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+{
+ QUERY_REC *query;
+ char *target;
+
+ char *secret;
+ void *free_arg;
+
+ if (!cmd_get_params(data, &free_arg, 1, &secret))
+ return;
+
+ query = QUERY(item);
+ target = query ? query->name : NULL;
+
+ if (server == NULL || target == NULL || *secret == '\0')
+ cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+ if (*secret == '\0')
+ cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+ otr_auth(server, target, NULL, secret);
+
+ cmd_params_free(free_arg);
+}
+
+static void cmd_otr_authq(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+{
+ QUERY_REC *query;
+ char *target;
+
+ char *question, *secret;
+ void *free_arg;
+
+ if (!cmd_get_params(data, &free_arg, 2, &question, &secret))
+ return;
+
+ query = QUERY(item);
+ target = query ? query->name : NULL;
+
+ if (server == NULL || target == NULL || *question == '\0' || *secret == '\0')
+ cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+ otr_auth(server, target, question, secret);
+
+ cmd_params_free(free_arg);
+}
+
+static void cmd_otr_genkey(const char *data)
+{
+ char *account_name;
+ void *free_arg;
+
+ if (!cmd_get_params(data, &free_arg, 1, &account_name))
+ return;
+
+ if (*account_name == '\0')
+ cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+ key_gen_run(user_state_global, account_name);
+
+ cmd_params_free(free_arg);
+}
+
+static void cmd_otr_contexts(const char *data)
+{
+ otr_contexts(user_state_global);
+}
+
+static void cmd_otr_info(const char *data)
+{
+ gboolean empty = TRUE;
+ char ownfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN];
+ OtrlPrivKey *key;
+
+ for (key = user_state_global->otr_state->privkey_root; key != NULL; key = key->next) {
+ otrl_privkey_fingerprint(user_state_global->otr_state, ownfp, key->accountname, OTR_PROTOCOL_ID);
+
+ printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_OTR_FP_NICK, key->accountname, ownfp);
+
+ empty = FALSE;
+ }
+
+ if (empty)
+ printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_OTR_KEYS_UNAVAILABLE);
+}
+
+static void statusbar_otr(struct SBAR_ITEM_REC *item, int get_size_only)
+{
+ WI_ITEM_REC *wi_item = active_win->active;
+ QUERY_REC *query = QUERY(wi_item);
+ enum otr_status_format format = TXT_OTR_MODULE_NAME;
+
+ if (query && query->server && query->server->connrec) {
+ format = otr_get_status_format(query->server, query->name);
+ }
+
+ statusbar_item_default_handler(item, get_size_only,
+ format ? fe_otr_formats[format].def : "", " ", FALSE);
+}
+
+void otr_fe_init(void)
+{
+ theme_register(fe_otr_formats);
+
+ command_bind("otr", NULL, (SIGNAL_FUNC) cmd_otr);
+ command_bind("otr debug", NULL, (SIGNAL_FUNC) cmd_otr_debug);
+ command_bind("otr init", NULL, (SIGNAL_FUNC) cmd_otr_init);
+ command_bind("otr finish", NULL, (SIGNAL_FUNC) cmd_otr_finish);
+ command_bind("otr trust", NULL, (SIGNAL_FUNC) cmd_otr_trust);
+ command_bind("otr distrust", NULL, (SIGNAL_FUNC) cmd_otr_distrust);
+ command_bind("otr forget", NULL, (SIGNAL_FUNC) cmd_otr_forget);
+ command_bind("otr authabort", NULL, (SIGNAL_FUNC) cmd_otr_authabort);
+ command_bind("otr auth", NULL, (SIGNAL_FUNC) cmd_otr_auth);
+ command_bind("otr authq", NULL, (SIGNAL_FUNC) cmd_otr_authq);
+ command_bind("otr genkey", NULL, (SIGNAL_FUNC) cmd_otr_genkey);
+ command_bind("otr contexts", NULL, (SIGNAL_FUNC) cmd_otr_contexts);
+ command_bind("otr info", NULL, (SIGNAL_FUNC) cmd_otr_info);
+
+ statusbar_item_register("otr", NULL, statusbar_otr);
+ statusbar_items_redraw("window");
+}
+
+void otr_fe_deinit(void)
+{
+ theme_unregister();
+
+ command_unbind("otr", (SIGNAL_FUNC) cmd_otr);
+ command_unbind("otr debug", (SIGNAL_FUNC) cmd_otr_debug);
+ command_unbind("otr init", (SIGNAL_FUNC) cmd_otr_init);
+ command_unbind("otr finish", (SIGNAL_FUNC) cmd_otr_finish);
+ command_unbind("otr trust", (SIGNAL_FUNC) cmd_otr_trust);
+ command_unbind("otr distrust", (SIGNAL_FUNC) cmd_otr_distrust);
+ command_unbind("otr forget", (SIGNAL_FUNC) cmd_otr_forget);
+ command_unbind("otr authabort", (SIGNAL_FUNC) cmd_otr_authabort);
+ command_unbind("otr auth", (SIGNAL_FUNC) cmd_otr_auth);
+ command_unbind("otr authq", (SIGNAL_FUNC) cmd_otr_authq);
+ command_unbind("otr genkey", (SIGNAL_FUNC) cmd_otr_genkey);
+ command_unbind("otr contexts", (SIGNAL_FUNC) cmd_otr_contexts);
+ command_unbind("otr info", (SIGNAL_FUNC) cmd_otr_info);
+
+ statusbar_item_unregister("otr");
+}