mirror of
https://github.com/irssi/irssi.git
synced 2026-08-20 09:02:13 +02:00
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.
This commit is contained in:
parent
ad4324d242
commit
016b42baea
25 changed files with 3262 additions and 41 deletions
344
src/otr/otr-fe.c
Normal file
344
src/otr/otr-fe.c
Normal file
|
|
@ -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");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue