[Pkg-privacy-commits] [irssi-plugin-otr] 115/267: Reengineering part of the module
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 12:41:34 UTC 2015
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch debian
in repository irssi-plugin-otr.
commit 82c2cfec8c93d49e505c3feacd4804925c47d5c3
Author: David Goulet <dgoulet at ev0ke.net>
Date: Wed Nov 7 18:18:28 2012 -0500
Reengineering part of the module
This is a *big* commmit but was needed. The context data is no longer
used.
Rename a bunch of data structure to respect name space and have more
meaning to the human eye.
Fix the status bar redraw but still have a problem with the state of the
authentication. This should actually be done in the otr ops callback but
irssi is not helping much about that needing to send a signal to redraw
the status bar...
There is a bunch of other fixes but it's for the best. There is still
features to fix and test so we are still in heavy development mode.
Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
src/cmd.c | 28 ++--
src/cmd.h | 9 +-
src/irssi_otr.h | 22 ++-
src/key.c | 164 ++++++++++--------
src/key.h | 13 +-
src/module.c | 42 +++--
src/otr-formats.c | 6 +-
src/otr-ops.c | 110 +++++-------
src/otr.c | 487 +++++++++++++++++++++++++++++++-----------------------
src/otr.h | 131 ++++++++-------
10 files changed, 555 insertions(+), 457 deletions(-)
diff --git a/src/cmd.c b/src/cmd.c
index 053fca9..068d77f 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -24,7 +24,7 @@
/*
* /otr debug
*/
-static void _cmd_debug(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
+static void _cmd_debug(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
char *argv_eol[], char *target, const char *orig_args)
{
debug = !debug;
@@ -34,7 +34,7 @@ static void _cmd_debug(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv
/*
* /otr version
*/
-static void _cmd_version(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
+static void _cmd_version(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
char *argv_eol[], char *target, const char *orig_args)
{
otr_noticest(TXT_CMD_VERSION, IRCOTR_VERSION);
@@ -43,7 +43,7 @@ static void _cmd_version(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *ar
/*
* /otr help
*/
-static void _cmd_help(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
+static void _cmd_help(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
char *argv_eol[], char *target, const char *orig_args)
{
otr_log(ircctx, target, MSGLEVEL_CRAP, otr_help);
@@ -52,7 +52,7 @@ static void _cmd_help(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[
/*
* /otr finish
*/
-static void _cmd_finish(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
+static void _cmd_finish(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
char *argv_eol[], char *target, const char *orig_args)
{
if (argc) {
@@ -67,7 +67,7 @@ static void _cmd_finish(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *arg
/*
* /otr trust
*/
-static void _cmd_trust(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
+static void _cmd_trust(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
char *argv_eol[], char *target, const char *orig_args)
{
if (argc) {
@@ -82,7 +82,7 @@ static void _cmd_trust(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv
/*
* /otr authabort
*/
-static void _cmd_authabort(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc,
+static void _cmd_authabort(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc,
char *argv[], char *argv_eol[], char *target, const char *orig_args)
{
if (argc) {
@@ -97,7 +97,7 @@ static void _cmd_authabort(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc,
/*
* /otr genkey
*/
-static void _cmd_genkey(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
+static void _cmd_genkey(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
char *argv_eol[], char *target, const char *orig_args)
{
if (argc) {
@@ -116,7 +116,7 @@ static void _cmd_genkey(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *arg
/*
* Generic internal function for /otr auth command.
*/
-static void _auth(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc,
+static void _auth(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc,
char *argv[], char *argv_eol[], char *target, int qanda,
const char *orig_args)
{
@@ -166,7 +166,7 @@ end:
/*
* /otr authq (Authentication with a question)
*/
-static void _cmd_authq(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc,
+static void _cmd_authq(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc,
char *argv[], char *argv_eol[], char *target, const char *orig_args)
{
_auth(ioustate, ircctx, argc, argv, argv_eol, target, TRUE, orig_args);
@@ -175,7 +175,7 @@ static void _cmd_authq(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc,
/*
* /otr auth
*/
-static void _cmd_auth(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
+static void _cmd_auth(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
char *argv_eol[], char *target, const char *orig_args)
{
_auth(ioustate, ircctx, argc, argv, argv_eol, target, FALSE, orig_args);
@@ -184,7 +184,7 @@ static void _cmd_auth(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[
/*
* /otr contexts
*/
-static void _cmd_contexts(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc,
+static void _cmd_contexts(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc,
char *argv[], char *argv_eol[], char *target, const char *orig_args)
{
struct ctxlist_ *ctxlist = otr_contexts(ioustate), *ctxnext = ctxlist;
@@ -217,7 +217,7 @@ static void _cmd_contexts(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc,
}
}
-static void _cmd_init(IOUSTATE *ioustate, SERVER_REC *irssi, int argc,
+static void _cmd_init(struct otr_user_state *ioustate, SERVER_REC *irssi, int argc,
char *argv[], char *argv_eol[], char *target, const char *orig_args)
{
char *msg;
@@ -234,7 +234,7 @@ static void _cmd_init(IOUSTATE *ioustate, SERVER_REC *irssi, int argc,
}
msg = otrl_proto_default_query_msg(target, OTRL_POLICY_DEFAULT);
- irc_send_message(irssi, target, msg ? msg : "?OTRv23?");
+ irssi_send_message(irssi, target, msg ? msg : "?OTRv23?");
free(msg);
end:
@@ -262,7 +262,7 @@ static struct irssi_commands cmds[] = {
*
* Return TRUE if command exist and is executed else FALSE.
*/
-int cmd_generic(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
+int cmd_generic(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
char *argv_eol[], char *target, const char *orig_args)
{
char *cmd;
diff --git a/src/cmd.h b/src/cmd.h
index e9e411e..fa02f28 100644
--- a/src/cmd.h
+++ b/src/cmd.h
@@ -25,11 +25,12 @@
struct irssi_commands {
const char *name;
- void (*func)(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
- char *argv_eol[], char *target, const char *orig_args);
+ void (*func)(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc,
+ char *argv[], char *argv_eol[], char *target,
+ const char *orig_args);
};
-int cmd_generic(IOUSTATE *ioustate, IRC_CTX *ircctx, int argc, char *argv[],
- char *argv_eol[], char *target, const char *orig_args);
+int cmd_generic(struct otr_user_state *ioustate, IRC_CTX *ircctx, int argc,
+ char *argv[], char *argv_eol[], char *target, const char *orig_args);
#endif /* IRSSI_OTR_CMD_H */
diff --git a/src/irssi_otr.h b/src/irssi_otr.h
index 3870673..d2c1907 100644
--- a/src/irssi_otr.h
+++ b/src/irssi_otr.h
@@ -59,8 +59,6 @@ void otr_query_create(IRC_CTX *ircctx, const char *nick);
#define IRSSI_CONN_ADDR(i) i->connrec->address
#define IRSSI_NICK(i) i->nick
#define IRSSI_ACCNAME(accname, i) sprintf(accname, "%s@%s", i->nick, IRSSI_CONN_ADDR(i))
-#define IRSSI_IO_US(i) (&ioustate_uniq)
-#define IO_CREATE_US(user) (&ioustate_uniq)
#define otr_noticest(formatnum,...) \
printformat(NULL,NULL,MSGLEVEL_MSGS, formatnum, ## __VA_ARGS__)
@@ -84,13 +82,21 @@ void otr_query_create(IRC_CTX *ircctx, const char *nick);
/*
* Irssi macros for printing text to console.
*/
-#define IRSSI_NOTICE(irssi, username, fmt, ...) \
- printtext(irssi, username, MSGLEVEL_MSGS, fmt, ## __VA_ARGS__);
-#define IRSSI_WARN(irssi, username, fmt, ...) \
- printtext(irssi, username, MSGLEVEL_HILIGHT, fmt, ## __VA_ARGS__);
-#define IRSSI_DEBUG(irssi, username, fmt, ...) \
+#define IRSSI_MSG(fmt, ...) \
+ do { \
+ printtext(NULL, NULL, MSGLEVEL_MSGS, fmt, ## __VA_ARGS__); \
+ } while (0)
+#define IRSSI_NOTICE(irssi, username, fmt, ...) \
+ do { \
+ printtext(irssi, username, MSGLEVEL_MSGS, fmt, ## __VA_ARGS__); \
+ } while (0)
+#define IRSSI_WARN(irssi, username, fmt, ...) \
+ do { \
+ printtext(irssi, username, MSGLEVEL_HILIGHT, fmt, ## __VA_ARGS__); \
+ } while (0)
+#define IRSSI_DEBUG(fmt, ...) \
do { \
if (debug) { \
- printtext(irssi, username, MSGLEVEL_MSGS, fmt, ## __VA_ARGS__); \
+ printtext(NULL, NULL, MSGLEVEL_MSGS, fmt, ## __VA_ARGS__); \
} \
} while (0)
diff --git a/src/key.c b/src/key.c
index e2fc9dc..0e353d3 100644
--- a/src/key.c
+++ b/src/key.c
@@ -18,12 +18,14 @@
*/
#define _GNU_SOURCE
+#include <assert.h>
#include <glib/gstdio.h>
#include <libgen.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/poll.h>
#include <signal.h>
+#include <unistd.h>
#include "key.h"
@@ -36,9 +38,22 @@ static struct {
guint cpid;
guint cwid;
pid_t pid;
- IOUSTATE *ioustate;
+ struct otr_user_state *ustate;
} kg_st = { .status = KEYGEN_NO };
+static char *file_path_build(const char *path)
+{
+ char *filename = NULL;
+
+ if (!path) {
+ path = "";
+ }
+
+ /* Either NULL or the filename is returned here which is valid. */
+ (void) asprintf(&filename, "%s%s", get_client_config_dir(), path);
+
+ return filename;
+}
static void keygen_childwatch(GPid pid, gint status, gpointer data)
{
@@ -79,7 +94,7 @@ static void keygen_childwatch(GPid pid, gint status, gpointer data)
otr_noticest(TXT_KG_POLLERR, kg_st.accountname, strerror(errno));
}
- key_generation_abort(kg_st.ioustate, FALSE);
+ key_generation_abort(kg_st.ustate, FALSE);
end:
return;
@@ -114,7 +129,7 @@ static gboolean keygen_complete(GIOChannel *source, GIOCondition condition,
time(NULL) - kg_st.started);
rename(tmpfilename, filename);
//otrl_privkey_forget_all(otr_state); <-- done by lib
- key_load(kg_st.ioustate);
+ key_load(kg_st.ustate);
}
g_source_remove(kg_st.cwid);
@@ -134,14 +149,10 @@ static gboolean keygen_complete(GIOChannel *source, GIOCondition condition,
* will rewrite the key file, we shouldn't change anything till it's done and
* we've reloaded the keys.
*/
-void key_generation_run(IOUSTATE *ioustate, const char *accname)
-{
- gcry_error_t err;
- int ret;
- int fds[2];
- char *filename = g_strconcat(get_client_config_dir(), OTR_TMP_KEYFILE, NULL);
- char *filenamedup = g_strdup(filename);
- char *dir = dirname(filenamedup);
+void key_generation_run(struct otr_user_state *ustate, const char *accname) { gcry_error_t
+ err; int ret; int fds[2]; char *filename =
+ g_strconcat(get_client_config_dir(), OTR_TMP_KEYFILE, NULL); char
+ *filenamedup = g_strdup(filename); char *dir = dirname(filenamedup);
if (kg_st.status != KEYGEN_NO) {
if (strncmp(accname, kg_st.accountname, strlen(accname)) != 0) {
@@ -174,7 +185,7 @@ void key_generation_run(IOUSTATE *ioustate, const char *accname)
kg_st.ch[1] = g_io_channel_unix_new(fds[1]);
kg_st.accountname = g_strdup(accname);
- kg_st.ioustate = ioustate;
+ kg_st.ustate = ustate;
kg_st.protocol = OTR_PROTOCOL_ID;
kg_st.started = time(NULL);
@@ -198,7 +209,7 @@ void key_generation_run(IOUSTATE *ioustate, const char *accname)
/* child */
- err = otrl_privkey_generate(ioustate->otr_state, filename, accname,
+ err = otrl_privkey_generate(ustate->otr_state, filename, accname,
OTR_PROTOCOL_ID);
(void) write(fds[1], &err, sizeof(err));
@@ -214,7 +225,7 @@ end:
/*
* Abort ongoing key generation.
*/
-void key_generation_abort(IOUSTATE *ioustate, int ignoreidle)
+void key_generation_abort(struct otr_user_state *ustate, int ignoreidle)
{
if (kg_st.status != KEYGEN_RUNNING) {
if (!ignoreidle) {
@@ -243,115 +254,128 @@ end:
/*
* Write fingerprints to file.
*/
-void key_write_fingerprints(IOUSTATE *ioustate)
+void key_write_fingerprints(struct otr_user_state *ustate)
{
gcry_error_t err;
- char *filename = g_strconcat(get_client_config_dir(), OTR_FINGERPRINTS_FILE, NULL);
+ char *filename;
+
+ assert(ustate);
+
+ filename = file_path_build(OTR_FINGERPRINTS_FILE);
+ if (!filename) {
+ goto error_filename;
+ }
- err = otrl_privkey_write_fingerprints(ioustate->otr_state, filename);
+ err = otrl_privkey_write_fingerprints(ustate->otr_state, filename);
if (err == GPG_ERR_NO_ERROR) {
- otr_noticest(TXT_FP_SAVED);
+ IRSSI_DEBUG("%9OTR%9: Fingerprints saved to %9%s%9", filename);
} else {
- otr_noticest(TXT_FP_SAVE_ERROR, gcry_strerror(err),
- gcry_strsource(err));
+ IRSSI_DEBUG("%9OTR%9: Error writing fingerprints: %d (%d)",
+ gcry_strerror(err), gcry_strsource(err));
}
- g_free(filename);
+ free(filename);
+error_filename:
+ return;
}
/*
* Write instance tags to file.
*/
-void otr_writeinstags(IOUSTATE *ioustate)
+void otr_writeinstags(struct otr_user_state *ustate)
{
gcry_error_t err;
- char *filename = g_strconcat(get_client_config_dir(), OTR_INSTAG_FILE, NULL);
+ char *filename;
+
+ assert(ustate);
+
+ filename = file_path_build(OTR_INSTAG_FILE);
+ if (!filename) {
+ goto error_filename;
+ }
- err = otrl_instag_write(ioustate->otr_state, filename);
+ err = otrl_instag_write(ustate->otr_state, filename);
if (err == GPG_ERR_NO_ERROR) {
- otr_noticest(TXT_INSTAG_SAVED);
+ IRSSI_DEBUG("%9OTR%9: Instance tags saved in %9%s%9", filename);
} else {
- otr_noticest(TXT_INSTAG_SAVE_ERROR, gcry_strerror(err),
- gcry_strsource(err));
+ IRSSI_DEBUG("%9OTR%9: Error saving instance tags: %d (%d)",
+ gcry_strerror(err), gcry_strsource(err));
}
- g_free(filename);
+ free(filename);
+error_filename:
+ return;
}
/*
* Load private keys.
*/
-void key_load(IOUSTATE *ioustate)
+void key_load(struct otr_user_state *ustate)
{
+ int ret;
gcry_error_t err;
- char *filename = g_strconcat(get_client_config_dir(), OTR_KEYFILE, NULL);
+ char *filename;
- if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
- otr_noticest(TXT_KEY_NOT_FOUND);
- goto end;
- }
+ assert(ustate);
- err = otrl_privkey_read(ioustate->otr_state, filename);
- if (err == GPG_ERR_NO_ERROR) {
- otr_noticest(TXT_KEY_LOADED);
- } else {
- otr_noticest(TXT_KEY_LOAD_ERROR, gcry_strerror(err),
- gcry_strsource(err));
+ filename = file_path_build(OTR_KEYFILE);
+ if (!filename) {
+ goto error_filename;
}
-end:
- g_free(filename);
- return;
-}
-
-/*
- * Load fingerprints.
- */
-void key_load_fingerprints(IOUSTATE *ioustate)
-{
- gcry_error_t err;
- char *filename = g_strconcat(get_client_config_dir(), OTR_FINGERPRINTS_FILE, NULL);
- if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
- otr_noticest(TXT_FP_NOT_FOUND);
+ ret = access(filename, F_OK);
+ if (ret < 0) {
+ IRSSI_DEBUG("%9OTR%9: No private keys found in %9%s%9", filename);
goto end;
}
- err = otrl_privkey_read_fingerprints(ioustate->otr_state, filename, NULL,
- NULL);
+ err = otrl_privkey_read(ustate->otr_state, filename);
if (err == GPG_ERR_NO_ERROR) {
- otr_noticest(TXT_FP_LOADED);
+ IRSSI_DEBUG("%9OTR%9: Private keys loaded from %9%s%9", filename);
} else {
- otr_noticest(TXT_FP_LOAD_ERROR, gcry_strerror(err),
- gcry_strsource(err));
+ IRSSI_DEBUG("%9OTR%9: Error loading private keys: %d (%d)",
+ gcry_strerror(err), gcry_strsource(err));
}
end:
- g_free(filename);
+ free(filename);
+error_filename:
return;
}
/*
- * Load instance tags.
+ * Load fingerprints.
*/
-void instag_load(IOUSTATE *ioustate)
+void key_load_fingerprints(struct otr_user_state *ustate)
{
+ int ret;
gcry_error_t err;
- char *filename = g_strconcat(get_client_config_dir(), OTR_INSTAG_FILE, NULL);
+ char *filename;
- if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
- otr_noticest(TXT_INSTAG_NOT_FOUND);
+ assert(ustate);
+
+ filename = file_path_build(OTR_FINGERPRINTS_FILE);
+ if (!filename) {
+ goto error_filename;
+ }
+
+ ret = access(filename, F_OK);
+ if (ret < 0) {
+ IRSSI_DEBUG("%9OTR%9: No fingerprints found in %9%s%9", filename);
goto end;
}
- err = otrl_instag_read(ioustate->otr_state, filename);
+ err = otrl_privkey_read_fingerprints(ustate->otr_state, filename, NULL,
+ NULL);
if (err == GPG_ERR_NO_ERROR) {
- otr_noticest(TXT_INSTAG_LOADED);
+ IRSSI_DEBUG("%9OTR%9: Fingerprints loaded from %9%s%9", filename);
} else {
- otr_noticest(TXT_INSTAG_LOAD_ERROR, gcry_strerror(err),
- gcry_strsource(err));
+ IRSSI_DEBUG("%9OTR%9: Error loading fingerprints: %d (%d)",
+ gcry_strerror(err), gcry_strsource(err));
}
end:
- g_free(filename);
+ free(filename);
+error_filename:
return;
}
diff --git a/src/key.h b/src/key.h
index ae89382..70d3d42 100644
--- a/src/key.h
+++ b/src/key.h
@@ -23,12 +23,11 @@
typedef enum { KEYGEN_NO, KEYGEN_RUNNING } keygen_status_t;
-void key_generation_abort(IOUSTATE *ioustate, int ignoreidle);
-void key_generation_run(IOUSTATE *ioustate, const char *accname);
-void key_load(IOUSTATE *ioustate);
-void key_load_fingerprints(IOUSTATE *ioustate);
-void key_write_fingerprints(IOUSTATE *ioustate);
-void otr_writeinstags(IOUSTATE *ioustate);
-void instag_load(IOUSTATE *ioustate);
+void key_generation_abort(struct otr_user_state *ustate, int ignoreidle);
+void key_generation_run(struct otr_user_state *ustate, const char *accname);
+void key_load(struct otr_user_state *ustate);
+void key_load_fingerprints(struct otr_user_state *ustate);
+void key_write_fingerprints(struct otr_user_state *ustate);
+void otr_writeinstags(struct otr_user_state *ustate);
#endif /* IRSSI_OTR_KEY_H */
diff --git a/src/module.c b/src/module.c
index 847a332..886fa1f 100644
--- a/src/module.c
+++ b/src/module.c
@@ -40,7 +40,10 @@ GRegex *regex_nickignore = NULL;
* install perl/perl-signals.h which is where this definition comes from? */
void perl_signal_register(const char *signal, const char **args);
-static IOUSTATE *ioustate;
+/*
+ * Global state for the user.
+ */
+struct otr_user_state *user_state_global;
/*
* Pipes all outgoing private messages through OTR
@@ -142,10 +145,10 @@ static void cmd_otr(const char *data, void *server, WI_ITEM_REC *item)
utils_io_explode_args(data, &argv, &argv_eol, &argc);
if (query && query->server && query->server->connrec) {
- cmd_generic(ioustate, query->server, argc, argv, argv_eol, query->name,
- data);
+ cmd_generic(user_state_global, query->server, argc, argv, argv_eol,
+ query->name, data);
} else {
- cmd_generic(ioustate, NULL, argc, argv, argv_eol, NULL, data);
+ cmd_generic(user_state_global, NULL, argc, argv, argv_eol, NULL, data);
}
statusbar_items_redraw("otr");
@@ -165,7 +168,7 @@ end:
static void cmd_quit(const char *data, void *server, WI_ITEM_REC *item)
{
if (settings_get_bool("otr_finishonunload")) {
- otr_finishall(ioustate);
+ otr_finishall(user_state_global);
}
}
@@ -188,8 +191,8 @@ static void otr_statusbar(struct SBAR_ITEM_REC *item, int get_size_only)
static void read_settings(void)
{
- otr_setpolicies(ioustate, settings_get_str("otr_policy"), FALSE);
- otr_setpolicies(ioustate, settings_get_str("otr_policy_known"), TRUE);
+ otr_setpolicies(user_state_global, settings_get_str("otr_policy"), FALSE);
+ otr_setpolicies(user_state_global, settings_get_str("otr_policy_known"), TRUE);
#ifdef HAVE_GREGEX_H
if (regex_nickignore) {
@@ -200,10 +203,14 @@ static void read_settings(void)
#endif
}
-void irc_send_message(IRC_CTX *ircctx, const char *recipient, char *msg)
+void irssi_send_message(SERVER_REC *irssi, const char *recipient,
+ const char *msg)
{
- ircctx->send_message(ircctx, recipient, msg,
- GPOINTER_TO_INT(SEND_TARGET_NICK));
+ /* XXX: Maybe an assert here. Code flow error? */
+ if (irssi) {
+ irssi->send_message(irssi, recipient, msg,
+ GPOINTER_TO_INT(SEND_TARGET_NICK));
+ }
}
void otr_query_create(SERVER_REC *server, const char *nick)
@@ -227,7 +234,14 @@ void otr_init(void)
otr_lib_init();
- ioustate = otr_init_user("one to rule them all");
+ /*
+ * Username does not really matter here since well... we got only one :).
+ */
+ user_state_global = otr_init_user("one to rule them all");
+ if (!user_state_global) {
+ IRSSI_MSG("Unable to allocate user global state");
+ return;
+ }
signal_add_first("server sendmsg", (SIGNAL_FUNC) sig_server_sendmsg);
signal_add_first("message private", (SIGNAL_FUNC) sig_message_private);
@@ -273,17 +287,17 @@ void otr_deinit(void)
statusbar_item_unregister("otr");
if (settings_get_bool("otr_finishonunload")) {
- otr_finishall(ioustate);
+ otr_finishall(user_state_global);
}
- otr_free_user(ioustate);
+ otr_free_user(user_state_global);
otr_lib_uninit();
theme_unregister();
}
-IRC_CTX *ircctx_by_peername(const char *peername, char *nick)
+SERVER_REC *find_irssi_ctx_by_peername(const char *peername, char *nick)
{
GSList *tmp;
char pname[256];
diff --git a/src/otr-formats.c b/src/otr-formats.c
index c9ca398..e8127d1 100644
--- a/src/otr-formats.c
+++ b/src/otr-formats.c
@@ -111,9 +111,9 @@ FORMAT_REC formats[] = {
{ "st_untrusted", "{sb %GOTR%n (%runverified%n)}", 0},
{ "st_trust_smp", "{sb %GOTR%n}", 0},
{ "st_trust_manual", "{sb %GOTR%n}", 0},
- { "st_smp_incoming", "{sb {hilight incoming auth request...}}", 0},
- { "st_smp_outgoing", "{sb {hilight awaiting auth reply...}}", 0},
- { "st_smp_finalize", "{sb {hilight finalizing auth...}}", 0},
+ { "st_smp_incoming", "{sb {%GOTR%n %9Auth requested%9}}", 0},
+ { "st_smp_outgoing", "{sb {%GOTR%n %9Waiting auth reply%9}}", 0},
+ { "st_smp_finalize", "{sb {%GOTR%n %9Finalizing auth%9}}", 0},
{ "st_smp_unknown", "{sb {hilight unknown auth state!}}", 0},
{ "st_finished", "{sb %yfinished%n}", 0},
{ "st_unknown", "{sb {hilight state unknown (BUG!)}}", 0},
diff --git a/src/otr-ops.c b/src/otr-ops.c
index 25390c8..a7441db 100644
--- a/src/otr-ops.c
+++ b/src/otr-ops.c
@@ -30,12 +30,10 @@ OtrlPolicy IO_DEFAULT_OTR_POLICY =
static OtrlPolicy ops_policy(void *opdata, ConnContext *context)
{
int ret;
- struct irssi_otr_context *ioc = context->app_data;
char *server = strchr(context->accountname, '@') + 1;
OtrlPolicy op = IO_DEFAULT_OTR_POLICY;
GSList *pl;
char fullname[1024];
- IOUSTATE *ioustate = IRSSI_IO_US(ioc->irssi);
ret = snprintf(fullname, sizeof(fullname), "%s@%s", context->username,
server);
@@ -45,8 +43,8 @@ static OtrlPolicy ops_policy(void *opdata, ConnContext *context)
}
/* Unknown policy */
- if (ioustate->plistunknown) {
- pl = ioustate->plistunknown;
+ if (user_state_global->policy_unknown_list) {
+ pl = user_state_global->policy_unknown_list;
do {
struct plistentry *ple = pl->data;
@@ -57,8 +55,8 @@ static OtrlPolicy ops_policy(void *opdata, ConnContext *context)
}
/* Known policy */
- if (ioustate->plistknown && context->fingerprint_root.next) {
- pl = ioustate->plistknown;
+ if (user_state_global->policy_known_list && context->fingerprint_root.next) {
+ pl = user_state_global->policy_known_list;
do {
struct plistentry *ple = pl->data;
@@ -69,7 +67,7 @@ static OtrlPolicy ops_policy(void *opdata, ConnContext *context)
} while ((pl = g_slist_next(pl)));
}
- if (ioc && context->msgstate == OTRL_MSGSTATE_FINISHED &&
+ if (context->msgstate == OTRL_MSGSTATE_FINISHED &&
(op == OTRL_POLICY_OPPORTUNISTIC || op == OTRL_POLICY_ALWAYS)) {
op = OTRL_POLICY_MANUAL | OTRL_POLICY_WHITESPACE_START_AKE;
}
@@ -88,9 +86,7 @@ error:
static void ops_create_privkey(void *opdata, const char *accountname,
const char *protocol)
{
- IRC_CTX *irssi __attribute__((unused)) = opdata;
-
- key_generation_run(IRSSI_IO_US(irssi), accountname);
+ key_generation_run(user_state_global, accountname);
}
/*
@@ -102,26 +98,10 @@ static void ops_create_privkey(void *opdata, const char *accountname,
static void ops_inject_msg(void *opdata, const char *accountname,
const char *protocol, const char *recipient, const char *message)
{
- IRC_CTX *a_serv;
- char *msgcopy = g_strdup(message);
-
- /* OTR sometimes gives us multiple lines
- * (e.g. the default query (a.k.a. "better") message) */
- g_strdelimit(msgcopy, "\n", ' ');
- a_serv = opdata;
- if (!a_serv) {
- char nick[256];
- a_serv = ircctx_by_peername(accountname, nick);
- }
+ SERVER_REC *irssi = opdata;
- if (!a_serv) {
- otr_notice(a_serv, recipient, TXT_OPS_INJECT, accountname,
- recipient, message);
- } else {
- otr_logst(MSGLEVEL_CRAP, "%d: INJECT %s", time(NULL), msgcopy);
- irc_send_message(a_serv, recipient, msgcopy);
- }
- g_free(msgcopy);
+ IRSSI_DEBUG("%9OTR%9: Inject msg:\n[%s]", message);
+ irssi_send_message(irssi, recipient, message);
}
/*
@@ -130,18 +110,16 @@ static void ops_inject_msg(void *opdata, const char *accountname,
static void ops_secure(void *opdata, ConnContext *context)
{
int ret;
- struct irssi_otr_context *ioc;
char ownfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN];
char peerfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN];
+ SERVER_REC *irssi = opdata;
assert(context);
/* This should *really* not happened */
assert(context->msgstate == OTRL_MSGSTATE_ENCRYPTED);
- ioc = context->app_data;
-
- IRSSI_NOTICE(ioc->irssi, context->username, "%9OTR%9: Gone %9secure%9");
- otr_status_change(ioc->irssi, context->username, IO_STC_GONE_SECURE);
+ IRSSI_NOTICE(irssi, context->username, "%9OTR%9: Gone %9secure%9");
+ otr_status_change(irssi, context->username, OTR_STATUS_GONE_SECURE);
ret = otrl_context_is_fingerprint_trusted(context->active_fingerprint);
if (ret) {
@@ -152,17 +130,17 @@ static void ops_secure(void *opdata, ConnContext *context)
/* Not authenticated. Let's print out the fingerprints for comparison. */
otrl_privkey_hash_to_human(peerfp,
context->active_fingerprint->fingerprint);
- otrl_privkey_fingerprint(ioustate_uniq.otr_state, ownfp,
+ otrl_privkey_fingerprint(user_state_global->otr_state, ownfp,
context->accountname, OTR_PROTOCOL_ID);
- IRSSI_NOTICE(ioc->irssi, context->username, "%9OTR%9: Your peer is not "
+ IRSSI_NOTICE(irssi, context->username, "%9OTR%9: Your peer is not "
"authenticated. To make sure you're talking to the right guy you can "
"either agree on a secret and use the authentication described in "
"%9/otr auth%9, or, recommended, use %9/otr authq [QUESTION] SECRET%9 "
"or use the traditional way and compare fingerprints "
"(e.g. telephone) and subsequently enter %9/otr trust%9.");
- IRSSI_NOTICE(ioc->irssi, context->username,
+ IRSSI_NOTICE(irssi, context->username,
"%9OTR%9: Your fingerprint is: %y%s\%n.\n"
"%9OTR%9: %9%s's%9 fingerprint is: %r%s\%n", ownfp,
context->username, peerfp);
@@ -176,9 +154,10 @@ end:
*/
static void ops_insecure(void *opdata, ConnContext *context)
{
- struct irssi_otr_context *ioc = context->app_data;
- otr_notice(ioc->irssi, context->username, TXT_OPS_INSEC);
- otr_status_change(ioc->irssi, context->username, IO_STC_GONE_INSECURE);
+ SERVER_REC *irssi = opdata;
+
+ otr_notice(irssi, context->username, TXT_OPS_INSEC);
+ otr_status_change(irssi, context->username, OTR_STATUS_GONE_INSECURE);
}
/*
@@ -186,8 +165,9 @@ static void ops_insecure(void *opdata, ConnContext *context)
*/
static void ops_still_secure(void *opdata, ConnContext *context, int is_reply)
{
- struct irssi_otr_context *ioc = context->app_data;
- otr_notice(ioc->irssi, context->username,
+ SERVER_REC *irssi = opdata;
+
+ otr_notice(irssi, context->username,
is_reply ? TXT_OPS_STILL_REPLY : TXT_OPS_STILL_NO_REPLY);
}
@@ -203,7 +183,7 @@ static int ops_max_msg(void *opdata, ConnContext *context)
static void ops_handle_msg_event(void *opdata, OtrlMessageEvent msg_event,
ConnContext *context, const char *message, gcry_error_t err)
{
- IRC_CTX *server = opdata;
+ SERVER_REC *server = opdata;
char *username = context->username;
switch (msg_event) {
@@ -258,12 +238,10 @@ static void ops_handle_msg_event(void *opdata, OtrlMessageEvent msg_event,
"message from %s.", username);
break;
case OTRL_MSGEVENT_LOG_HEARTBEAT_RCVD:
- IRSSI_DEBUG(server, username, "%9OTR:%9 Heartbeat received from %s.",
- username);
+ IRSSI_DEBUG("%9OTR:%9 Heartbeat received from %s.", username);
break;
case OTRL_MSGEVENT_LOG_HEARTBEAT_SENT:
- IRSSI_DEBUG(server, username, "%9OTR:%9 Heartbeat sent to %s.",
- username);
+ IRSSI_DEBUG("%9OTR:%9 Heartbeat sent to %s.", username);
break;
case OTRL_MSGEVENT_RCVDMSG_GENERAL_ERR:
IRSSI_WARN(server, username, "%9OTR:%9 OTR Error: %s.", message);
@@ -277,8 +255,8 @@ static void ops_handle_msg_event(void *opdata, OtrlMessageEvent msg_event,
"received from %s.", username);
break;
case OTRL_MSGEVENT_RCVDMSG_FOR_OTHER_INSTANCE:
- IRSSI_DEBUG(server, username, "%9OTR:%9 %s has sent a message for "
- "a different instance.", username);
+ IRSSI_DEBUG("%9OTR:%9 %s has sent a message for a different instance.",
+ username);
break;
}
}
@@ -288,7 +266,7 @@ static void ops_handle_msg_event(void *opdata, OtrlMessageEvent msg_event,
*/
static void ops_up_ctx_list(void *opdata)
{
- otr_status_change(opdata, NULL, IO_STC_CTX_UPDATE);
+ otr_status_change(opdata, NULL, OTR_STATUS_CTX_UPDATE);
}
/*
@@ -296,9 +274,7 @@ static void ops_up_ctx_list(void *opdata)
*/
static void ops_write_fingerprints(void *data)
{
- IRC_CTX *irssi __attribute__((unused)) = data;
-
- key_write_fingerprints(IRSSI_IO_US(irssi));
+ key_write_fingerprints(user_state_global);
}
static int ops_is_logged_in(void *opdata, const char *accountname,
@@ -313,48 +289,50 @@ static int ops_is_logged_in(void *opdata, const char *accountname,
static void ops_create_instag(void *opdata, const char *accountname,
const char *protocol)
{
- otrl_instag_generate(IRSSI_IO_US(irssi)->otr_state, "/dev/null",
+ otrl_instag_generate(user_state_global->otr_state, "/dev/null",
accountname, protocol);
- otr_writeinstags(IRSSI_IO_US(irssi));
+ otr_writeinstags(user_state_global);
}
static void ops_smp_event(void *opdata, OtrlSMPEvent smp_event,
ConnContext *context, unsigned short progress_percent, char *question)
{
- IRC_CTX *irssi = (IRC_CTX *) opdata;
+ SERVER_REC *irssi = opdata;
const char *from = context->username;
- struct irssi_otr_context *ioc = context->app_data;
- ioc->received_smp_init =
- (smp_event == OTRL_SMPEVENT_ASK_FOR_SECRET) ||
- (smp_event == OTRL_SMPEVENT_ASK_FOR_ANSWER);
+ if (context->app_data) {
+ struct otr_peer_context *opc = context->app_data;
+ opc->received_smp_init =
+ (smp_event == OTRL_SMPEVENT_ASK_FOR_SECRET) ||
+ (smp_event == OTRL_SMPEVENT_ASK_FOR_ANSWER);
+ }
switch (smp_event) {
case OTRL_SMPEVENT_ASK_FOR_SECRET:
otr_notice(irssi, from, TXT_AUTH_PEER, from);
- otr_status_change(irssi, from, IO_STC_SMP_INCOMING);
+ otr_status_change(irssi, from, OTR_STATUS_SMP_INCOMING);
break;
case OTRL_SMPEVENT_ASK_FOR_ANSWER:
otr_notice(irssi, from, TXT_AUTH_PEER_QA, from, question);
- otr_status_change(irssi, from, IO_STC_SMP_INCOMING);
+ otr_status_change(irssi, from, OTR_STATUS_SMP_INCOMING);
break;
case OTRL_SMPEVENT_IN_PROGRESS:
otr_notice(irssi, from, TXT_AUTH_PEER_REPLIED, from);
- otr_status_change(irssi, from, IO_STC_SMP_FINALIZE);
+ otr_status_change(irssi, from, OTR_STATUS_SMP_FINALIZE);
break;
case OTRL_SMPEVENT_SUCCESS:
otr_notice(irssi, from, TXT_AUTH_SUCCESSFUL);
- otr_status_change(irssi, from, IO_STC_SMP_SUCCESS);
+ otr_status_change(irssi, from, OTR_STATUS_SMP_SUCCESS);
break;
case OTRL_SMPEVENT_ABORT:
otr_abort_auth(context, irssi, from);
- otr_status_change(irssi, from, IO_STC_SMP_ABORTED);
+ otr_status_change(irssi, from, OTR_STATUS_SMP_ABORTED);
break;
case OTRL_SMPEVENT_FAILURE:
case OTRL_SMPEVENT_CHEATED:
case OTRL_SMPEVENT_ERROR:
otr_notice(irssi, from, TXT_AUTH_FAILED);
- otr_status_change(irssi, from, IO_STC_SMP_FAILED);
+ otr_status_change(irssi, from, OTR_STATUS_SMP_FAILED);
break;
default:
otr_logst(MSGLEVEL_CRAP, "Received unknown SMP event");
diff --git a/src/otr.c b/src/otr.c
index 5480410..9eda374 100644
--- a/src/otr.c
+++ b/src/otr.c
@@ -19,9 +19,12 @@
* Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA
*/
-#include "key.h"
-
+#define _GNU_SOURCE
+#include <assert.h>
#include <gcrypt.h>
+#include <unistd.h>
+
+#include "key.h"
static const char *statusbar_txt[] = {
"FINISHED",
@@ -41,109 +44,138 @@ static const char *statusbar_txt[] = {
"CTX_UPDATE"
};
-IOUSTATE ioustate_uniq = { 0, 0, 0 };
-
#ifdef HAVE_GREGEX_H
GRegex *regex_policies;
#endif
-IOUSTATE *otr_init_user(char *user)
+static char *create_account_name(SERVER_REC *irssi)
{
- IOUSTATE *ioustate = IO_CREATE_US(user);
-
- ioustate->otr_state = otrl_userstate_create();
+ char *accname = NULL;
- instag_load(ioustate);
+ assert(irssi);
- /* Load keys and fingerprints. */
- key_load(ioustate);
- key_load_fingerprints(ioustate);
+ /* Valid or NULL, the caller should handle this */
+ (void) asprintf(&accname, "%s@%s", IRSSI_NICK(irssi),
+ IRSSI_CONN_ADDR(irssi));
- return ioustate;
+ return accname;
}
-void otr_free_user(IOUSTATE *ioustate)
+/*
+ * Load instance tags.
+ */
+static void instag_load(struct otr_user_state *ustate)
{
- key_generation_abort(ioustate, TRUE);
+ int ret;
+ char *filename;
+ gcry_error_t err;
+
+ assert(ustate);
- if (ioustate->otr_state) {
- key_write_fingerprints(ioustate);
- otrl_userstate_free(ioustate->otr_state);
- ioustate->otr_state = NULL;
+ /* Getting the otr instance filename path */
+ ret = asprintf(&filename, "%s%s", get_client_config_dir(),
+ OTR_INSTAG_FILE);
+ if (ret < 0) {
+ goto error_filename;
}
- otr_setpolicies(ioustate, "", FALSE);
- otr_setpolicies(ioustate, "", TRUE);
-}
+ ret = access(filename, F_OK);
+ if (ret < 0) {
+ IRSSI_DEBUG("%9OTR%9: no instance tags found at %9%s%9", filename);
+ goto end;
+ }
-/*
- * init otr lib.
- */
-void otr_lib_init()
-{
- OTRL_INIT;
+ err = otrl_instag_read(ustate->otr_state, filename);
+ if (err == GPG_ERR_NO_ERROR) {
+ IRSSI_DEBUG("%9OTR%9: Instance tags loaded from %9%s%9", filename);
+ } else {
+ IRSSI_DEBUG("%9OTR%9: Error loading instance tags: %d (%d)",
+ gcry_strerror(err), gcry_strsource(err));
+ }
-#ifdef HAVE_GREGEX_H
- regex_policies = g_regex_new(
- "([^,]+) (never|manual|handlews|opportunistic|always)(,|$)",
- 0, 0, NULL);
-#endif
+end:
+ free(filename);
+error_filename:
+ return;
}
/*
- * deinit otr lib.
+ * Get a context from a pair.
*/
-void otr_lib_uninit()
+static ConnContext *get_otrl_context(const char *accname, const char *nick,
+ int create, SERVER_REC *irssi)
{
-#ifdef HAVE_GREGEX_H
- g_regex_unref(regex_policies);
-#endif
+ ConnContext *ctx = otrl_context_find(user_state_global->otr_state,
+ nick, accname, OTR_PROTOCOL_ID, OTRL_INSTAG_BEST, create, NULL,
+ NULL, NULL);
+
+ return ctx;
}
/*
- * Free our app data.
+ * Return a newly allocated OTR user state for the given username.
*/
-static void context_free_app_info(void *data)
+struct otr_user_state *otr_init_user(const char *user)
{
- struct irssi_otr_context *ioc = data;
- if (ioc->irssi) {
- IRSSI_FREE(ioc->irssi);
+ struct otr_user_state *ous = NULL;
+
+ assert(user);
+
+ ous = zmalloc(sizeof(*ous));
+ if (!ous) {
+ goto error;
}
+
+ ous->otr_state = otrl_userstate_create();
+
+ instag_load(ous);
+
+ /* Load keys and fingerprints. */
+ key_load(ous);
+ key_load_fingerprints(ous);
+
+error:
+ return ous;
}
-/*
- * Add app data to context. See struct irssi_otr_context for details.
- */
-static void context_add_app_info(void *data, ConnContext *co)
+void otr_free_user(struct otr_user_state *ustate)
{
- IRC_CTX *irssi = IRSSI_DUP(data);
- struct irssi_otr_context *ioc;
+ key_generation_abort(ustate, TRUE);
- ioc = g_malloc0(sizeof(struct irssi_otr_context));
- if (ioc == NULL) {
- goto end;
+ if (ustate->otr_state) {
+ key_write_fingerprints(ustate);
+ otrl_userstate_free(ustate->otr_state);
+ ustate->otr_state = NULL;
}
- co->app_data = ioc;
- co->app_data_free = context_free_app_info;
+ otr_setpolicies(ustate, "", FALSE);
+ otr_setpolicies(ustate, "", TRUE);
- ioc->irssi = irssi;
-
-end:
- return;
+ free(ustate);
}
/*
- * Get a context from a pair.
+ * init otr lib.
*/
-static ConnContext *get_otrl_context(const char *accname, const char *nick,
- int create, IRC_CTX *irssi_ctx)
+void otr_lib_init()
{
- ConnContext *ctx = otrl_context_find(IRSSI_IO_US(irssi_ctx)->otr_state,
- nick, accname, OTR_PROTOCOL_ID, OTRL_INSTAG_BEST, create, NULL,
- context_add_app_info, irssi_ctx);
+ OTRL_INIT;
- return ctx;
+#ifdef HAVE_GREGEX_H
+ regex_policies = g_regex_new(
+ "([^,]+) (never|manual|handlews|opportunistic|always)(,|$)",
+ 0, 0, NULL);
+#endif
+}
+
+/*
+ * deinit otr lib.
+ */
+void otr_lib_uninit()
+{
+#ifdef HAVE_GREGEX_H
+ g_regex_unref(regex_policies);
+#endif
}
/*
@@ -151,32 +183,39 @@ static ConnContext *get_otrl_context(const char *accname, const char *nick,
*
* Return 0 if the message was successfully handled or else a negative value.
*/
-int otr_send(IRC_CTX *irssi, const char *msg, const char *to, char **otr_msg)
+int otr_send(SERVER_REC *irssi, const char *msg, const char *to, char **otr_msg)
{
gcry_error_t err;
- char accname[256];
+ char *accname = NULL;
- IRSSI_ACCNAME(accname, irssi);
+ assert(irssi);
+
+ accname = create_account_name(irssi);
+ if (!accname) {
+ goto error;
+ }
- otr_logst(MSGLEVEL_CRAP, "%d: sending msg", time(NULL));
+ IRSSI_DEBUG("%9OTR%9: Sending message...");
- err = otrl_message_sending(IRSSI_IO_US(irssi)->otr_state, &otr_ops,
+ err = otrl_message_sending(user_state_global->otr_state, &otr_ops,
irssi, accname, OTR_PROTOCOL_ID, to, OTRL_INSTAG_BEST, msg, NULL, otr_msg,
- OTRL_FRAGMENT_SEND_ALL_BUT_LAST, NULL, context_add_app_info, irssi);
+ OTRL_FRAGMENT_SEND_ALL_BUT_LAST, NULL, NULL, NULL);
if (err) {
- otr_notice(irssi, to, TXT_SEND_FAILED, msg);
+ IRSSI_NOTICE(irssi, to, "%9OTR:%9 Send failed.");
goto error;
}
- otr_logst(MSGLEVEL_CRAP, "%d: sent", time(NULL));
+ IRSSI_DEBUG("%9OTR%9: Message sent...");
+ free(accname);
return 0;
error:
+ free(accname);
return -1;
}
-struct ctxlist_ *otr_contexts(IOUSTATE *ioustate)
+struct ctxlist_ *otr_contexts(struct otr_user_state *ustate)
{
ConnContext *context;
Fingerprint *fprint;
@@ -186,7 +225,7 @@ struct ctxlist_ *otr_contexts(IOUSTATE *ioustate)
char *trust;
int i;
- for (context = ioustate->otr_state->context_root; context;
+ for (context = ustate->otr_state->context_root; context;
context = context->next) {
if (!ctxlist) {
ctxhead = ctxlist = g_malloc0(sizeof(struct ctxlist_));
@@ -243,85 +282,26 @@ struct ctxlist_ *otr_contexts(IOUSTATE *ioustate)
}
/*
- * Get the OTR status of this conversation.
- */
-int otr_getstatus(IRC_CTX *irssi, const char *nick)
-{
- int ret, code = 0;
- ConnContext *ctx;
- char accname[128];
-
- IRSSI_ACCNAME(accname, irssi);
-
- if (!(ctx = get_otrl_context(accname, nick, FALSE, irssi))) {
- code = IO_ST_PLAINTEXT;
- goto end;
- }
-
- switch (ctx->msgstate) {
- case OTRL_MSGSTATE_PLAINTEXT:
- code = IO_ST_PLAINTEXT;
- break;
- case OTRL_MSGSTATE_ENCRYPTED:
- {
- int ex = ctx->smstate->nextExpected;
- struct irssi_otr_context *ioc = ctx->app_data;
-
- switch (ex) {
- case OTRL_SMP_EXPECT1:
- if (ioc->received_smp_init) {
- code = IO_ST_SMP_INCOMING;
- }
- break;
- case OTRL_SMP_EXPECT2:
- code = IO_ST_SMP_OUTGOING;
- break;
- case OTRL_SMP_EXPECT3:
- case OTRL_SMP_EXPECT4:
- code = IO_ST_SMP_FINALIZE;
- break;
- }
-
- ret = otrl_context_is_fingerprint_trusted(ctx->active_fingerprint);
- if (ret) {
- code |= IO_ST_TRUST_SMP;
- } else {
- code |= IO_ST_UNTRUSTED;
- }
- break;
- }
- case OTRL_MSGSTATE_FINISHED:
- code = IO_ST_FINISHED;
- break;
- default:
- otr_logst(MSGLEVEL_CRAP,
- "BUG Found! Please write us a mail and describe how you got here");
- code = IO_ST_UNKNOWN;
- break;
- }
-
-end:
- return code;
-}
-
-/*
* Finish the conversation.
*/
-void otr_finish(IRC_CTX *irssi, char *nick, const char *peername, int inquery)
+void otr_finish(SERVER_REC *irssi, char *nick, const char *peername, int inquery)
{
ConnContext *co;
- char accname[128];
+ char *accname = NULL;
char nickbuf[128];
if (peername) {
nick = nickbuf;
- irssi = ircctx_by_peername(peername, nick);
+ irssi = find_irssi_ctx_by_peername(peername, nick);
if (!irssi) {
goto end;
}
}
- IRSSI_ACCNAME(accname, irssi);
+ accname = create_account_name(irssi);
+ if (!accname) {
+ goto end;
+ }
if (!(co = get_otrl_context(accname, nick, FALSE, irssi))) {
if (inquery) {
@@ -330,10 +310,10 @@ void otr_finish(IRC_CTX *irssi, char *nick, const char *peername, int inquery)
goto end;
}
- otrl_message_disconnect(IRSSI_IO_US(irssi)->otr_state, &otr_ops, irssi,
+ otrl_message_disconnect(user_state_global->otr_state, &otr_ops, irssi,
accname, OTR_PROTOCOL_ID, nick, co->their_instance);
- otr_status_change(irssi, nick, IO_STC_FINISHED);
+ otr_status_change(irssi, nick, OTR_STATUS_FINISHED);
if (inquery) {
otr_info(irssi, nick, TXT_CMD_FINISH, nick, IRSSI_CONN_ADDR(irssi));
@@ -342,29 +322,36 @@ void otr_finish(IRC_CTX *irssi, char *nick, const char *peername, int inquery)
}
end:
+ free(accname);
return;
}
-void otr_finishall(IOUSTATE *ioustate)
+void otr_finishall(struct otr_user_state *ustate)
{
ConnContext *context;
int finished = 0;
+ SERVER_REC *irssi;
- for (context = ioustate->otr_state->context_root; context;
+ for (context = ustate->otr_state->context_root; context;
context = context->next) {
- struct irssi_otr_context *ioc = context->app_data;
-
if (context->msgstate != OTRL_MSGSTATE_ENCRYPTED) {
continue;
}
- otrl_message_disconnect(ioustate->otr_state, &otr_ops, ioc->irssi,
+ irssi = find_irssi_ctx_by_peername(context->accountname,
+ context->username);
+ if (!irssi) {
+ IRSSI_DEBUG("%9OTR%9: Unable to find context on /otr finishall "
+ "for username %s", context->username);
+ continue;
+ }
+
+ otrl_message_disconnect(ustate->otr_state, &otr_ops, irssi,
context->accountname, OTR_PROTOCOL_ID, context->username,
context->their_instance);
- otr_status_change(ioc->irssi, context->username, IO_STC_FINISHED);
+ otr_status_change(irssi, context->username, OTR_STATUS_FINISHED);
- otr_infost(TXT_CMD_FINISH, context->username,
- IRSSI_CONN_ADDR(ioc->irssi));
+ otr_infost(TXT_CMD_FINISH, context->username, IRSSI_CONN_ADDR(irssi));
finished++;
}
@@ -376,7 +363,7 @@ void otr_finishall(IOUSTATE *ioustate)
/*
* Trust our peer.
*/
-void otr_trust(IRC_CTX *irssi, char *nick, const char *peername)
+void otr_trust(SERVER_REC *irssi, char *nick, const char *peername)
{
ConnContext *co;
char accname[128];
@@ -384,7 +371,7 @@ void otr_trust(IRC_CTX *irssi, char *nick, const char *peername)
if (peername) {
nick = nickbuf;
- irssi = ircctx_by_peername(peername, nick);
+ irssi = find_irssi_ctx_by_peername(peername, nick);
if (!irssi) {
goto end;
}
@@ -398,7 +385,7 @@ void otr_trust(IRC_CTX *irssi, char *nick, const char *peername)
}
otrl_context_set_trust(co->active_fingerprint, "manual");
- otr_status_change(irssi, nick, IO_STC_TRUST_MANUAL);
+ otr_status_change(irssi, nick, OTR_STATUS_TRUST_MANUAL);
otr_notice(irssi, nick, TXT_FP_TRUST, nick);
end:
@@ -408,21 +395,21 @@ end:
/*
* Abort any ongoing SMP authentication.
*/
-void otr_abort_auth(ConnContext *co, IRC_CTX *irssi, const char *nick)
+void otr_abort_auth(ConnContext *co, SERVER_REC *irssi, const char *nick)
{
otr_notice(irssi, nick,
co->smstate->nextExpected != OTRL_SMP_EXPECT1 ?
TXT_AUTH_ABORTED_ONGOING : TXT_AUTH_ABORTED);
- otrl_message_abort_smp(IRSSI_IO_US(irssi)->otr_state, &otr_ops,
+ otrl_message_abort_smp(user_state_global->otr_state, &otr_ops,
irssi, co);
- otr_status_change(irssi, nick, IO_STC_SMP_ABORT);
+ otr_status_change(irssi, nick, OTR_STATUS_SMP_ABORT);
}
/*
* implements /otr authabort
*/
-void otr_authabort(IRC_CTX *irssi, char *nick, const char *peername)
+void otr_authabort(SERVER_REC *irssi, char *nick, const char *peername)
{
ConnContext *co;
char accname[128];
@@ -430,7 +417,7 @@ void otr_authabort(IRC_CTX *irssi, char *nick, const char *peername)
if (peername) {
nick = nickbuf;
- irssi = ircctx_by_peername(peername, nick);
+ irssi = find_irssi_ctx_by_peername(peername, nick);
if (!irssi) {
goto end;
}
@@ -452,68 +439,70 @@ end:
/*
* Initiate or respond to SMP authentication.
*/
-void otr_auth(IRC_CTX *irssi, char *nick, const char *peername,
+void otr_auth(SERVER_REC *irssi, char *nick, const char *peername,
const char *question, const char *secret)
{
- ConnContext *co;
- struct irssi_otr_context *ioc;
- char accname[128];
+ int ret;
+ ConnContext *ctx;
+ char *accname = NULL;
char nickbuf[128];
if (peername) {
nick = nickbuf;
- irssi = ircctx_by_peername(peername, nick);
+ irssi = find_irssi_ctx_by_peername(peername, nick);
if (!irssi) {
goto end;
}
}
- IRSSI_ACCNAME(accname, irssi);
+ accname = create_account_name(irssi);
+ if (!accname) {
+ goto end;
+ }
- if (!(co = get_otrl_context(accname, nick, FALSE, irssi))) {
+ ctx = get_otrl_context(accname, nick, FALSE, irssi);
+ if (!ctx) {
otr_noticest(TXT_CTX_NOT_FOUND, accname, nick);
goto end;
}
- if (co->msgstate != OTRL_MSGSTATE_ENCRYPTED) {
+ if (ctx->msgstate != OTRL_MSGSTATE_ENCRYPTED) {
otr_notice(irssi, nick, TXT_AUTH_NEEDENC);
goto end;
}
- ioc = co->app_data;
-
/* Aborting an ongoing auth */
- if (co->smstate->nextExpected != OTRL_SMP_EXPECT1) {
- otr_abort_auth(co, irssi, nick);
+ if (ctx->smstate->nextExpected != OTRL_SMP_EXPECT1) {
+ otr_abort_auth(ctx, irssi, nick);
}
/* reset trust level */
- if (co->active_fingerprint) {
- char *trust = co->active_fingerprint->trust;
- if (trust && (*trust != '\0')) {
- otrl_context_set_trust(co->active_fingerprint, "");
- key_write_fingerprints(IRSSI_IO_US(irssi));
+ if (ctx->active_fingerprint) {
+ ret = otrl_context_is_fingerprint_trusted(ctx->active_fingerprint);
+ if (!ret) {
+ otrl_context_set_trust(ctx->active_fingerprint, "");
+ key_write_fingerprints(user_state_global);
}
}
- if (!ioc->received_smp_init) {
+ if (ctx->auth.initiated) {
if (question) {
- otrl_message_initiate_smp_q(IRSSI_IO_US(irssi)->otr_state,
- &otr_ops, irssi, co, question, (unsigned char *) secret,
+ otrl_message_initiate_smp_q(user_state_global->otr_state,
+ &otr_ops, irssi, ctx, question, (unsigned char *) secret,
strlen(secret));
} else {
- otrl_message_initiate_smp(IRSSI_IO_US(irssi)->otr_state,
- &otr_ops, irssi, co, (unsigned char *) secret,
+ otrl_message_initiate_smp(user_state_global->otr_state,
+ &otr_ops, irssi, ctx, (unsigned char *) secret,
strlen(secret));
}
- otr_status_change(irssi, nick, IO_STC_SMP_STARTED);
+ otr_status_change(irssi, nick, OTR_STATUS_SMP_STARTED);
} else {
- otrl_message_respond_smp(IRSSI_IO_US(irssi)->otr_state, &otr_ops,
- irssi, co, (unsigned char *) secret, strlen(secret));
- otr_status_change(irssi, nick, IO_STC_SMP_RESPONDED);
+ otrl_message_respond_smp(user_state_global->otr_state, &otr_ops,
+ irssi, ctx, (unsigned char *) secret, strlen(secret));
+ otr_status_change(irssi, nick, OTR_STATUS_SMP_RESPONDED);
}
- otr_notice(irssi, nick, ioc->received_smp_init ? TXT_AUTH_RESPONDING :
+ otr_notice(irssi, nick, ctx->auth.initiated ? TXT_AUTH_RESPONDING :
TXT_AUTH_INITIATED);
end:
@@ -525,47 +514,55 @@ end:
*
* Returns 0 if its an OTR protocol message or else negative value.
*/
-int otr_receive(IRC_CTX *irssi, const char *msg, const char *from,
+int otr_receive(SERVER_REC *irssi, const char *msg, const char *from,
char **new_msg)
{
int ret = -1;
- char accname[256];
+ char *accname = NULL;
OtrlTLV *tlvs;
- IRSSI_ACCNAME(accname, irssi);
+ accname = create_account_name(irssi);
+ if (!accname) {
+ goto error;
+ }
- otr_logst(MSGLEVEL_CRAP, "%d: receiving...", time(NULL));
+ IRSSI_DEBUG("%9OTR%9: Receiving message...");
- ret = otrl_message_receiving(IRSSI_IO_US(irssi)->otr_state,
+ ret = otrl_message_receiving(user_state_global->otr_state,
&otr_ops, irssi, accname, OTR_PROTOCOL_ID, from, msg, new_msg, &tlvs,
- NULL, context_add_app_info, irssi);
+ NULL, NULL, NULL);
if (ret) {
- otr_debug(irssi, from, TXT_RECEIVE_IGNORE, strlen(msg), accname, from,
- msg);
+ IRSSI_DEBUG("%9OTR%9: Ignoring message of length %d from %s to %s.\n"
+ "[%s]", strlen(msg), from, accname, msg);
} else {
if (*new_msg) {
- otr_debug(irssi, from, TXT_RECEIVE_CONVERTED);
+ IRSSI_DEBUG("%9OTR%9: Converted received message.");
}
}
OtrlTLV *tlv = otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED);
if (tlv) {
- otr_status_change(irssi, from, IO_STC_PEER_FINISHED);
- otr_notice(irssi, from, TXT_PEER_FINISHED, from);
+ otr_status_change(irssi, from, OTR_STATUS_PEER_FINISHED);
+ IRSSI_NOTICE(irssi, from, "%9OTR%9: %s has finished the OTR "
+ "conversation. If you want to continue talking enter "
+ "%9/otr finish%9 for plaintext or %9/otr init%9 to restart.",
+ from);
}
otrl_tlv_free(tlvs);
- otr_logst(MSGLEVEL_CRAP, "%d: received", time(NULL));
+ IRSSI_DEBUG("%9OTR%9: Message received.");
+error:
+ free(accname);
return ret;
}
-void otr_setpolicies(IOUSTATE *ioustate, const char *policies, int known)
+void otr_setpolicies(struct otr_user_state *ustate, const char *policies, int known)
{
#ifdef HAVE_GREGEX_H
GMatchInfo *match_info;
- GSList *plist = known ? ioustate->plistknown : ioustate->plistunknown;
+ GSList *plist = known ? ustate->policy_known_list : ustate->policy_unknown_list;
if (plist) {
GSList *p = plist;
@@ -616,24 +613,94 @@ void otr_setpolicies(IOUSTATE *ioustate, const char *policies, int known)
g_match_info_free(match_info);
if (known)
- ioustate->plistknown = plist;
+ ustate->policy_known_list = plist;
else
- ioustate->plistunknown = plist;
+ ustate->policy_unknown_list = plist;
#endif
}
/*
- * Get a format describing the OTR status of this conversation.
+ * Get the OTR status of this conversation.
*/
-int otr_getstatus_format(IRC_CTX *irssi, const char *nick)
+int otr_getstatus(SERVER_REC *irssi, const char *nick)
{
- int status = otr_getstatus(irssi, nick);
+ int ret, code = 0;
+ ConnContext *ctx = NULL;
+ char *accname = NULL;
+
+ assert(irssi);
+
+ accname = create_account_name(irssi);
+ if (!accname) {
+ goto end;
+ }
- if (status & (IO_ST_SMP_ONGOING)) {
- /* we don't care about the trust level in that case */
- status = status & IO_ST_SMP_ONGOING;
+ ctx = get_otrl_context(accname, nick, FALSE, irssi);
+ if (!ctx) {
+ code = IO_ST_PLAINTEXT;
+ goto end;
}
+ switch (ctx->msgstate) {
+ case OTRL_MSGSTATE_PLAINTEXT:
+ code = IO_ST_PLAINTEXT;
+ break;
+ case OTRL_MSGSTATE_ENCRYPTED:
+ /* Begin by checking trust. */
+ ret = otrl_context_is_fingerprint_trusted(ctx->active_fingerprint);
+ if (ret) {
+ code = IO_ST_TRUST_SMP;
+ } else {
+ code = IO_ST_UNTRUSTED;
+ }
+
+ /* Are we in a authentication mode ? */
+ if (ctx->auth.authstate != OTRL_AUTHSTATE_NONE) {
+ /* Check for the current auth state */
+ switch (ctx->smstate->nextExpected) {
+ case OTRL_SMP_EXPECT1:
+ if (ctx->auth.initiated) {
+ code = IO_ST_SMP_INCOMING;
+ }
+ break;
+ case OTRL_SMP_EXPECT2:
+ code = IO_ST_SMP_OUTGOING;
+ break;
+ case OTRL_SMP_EXPECT3:
+ case OTRL_SMP_EXPECT4:
+ case OTRL_SMP_EXPECT5:
+ code = IO_ST_SMP_FINALIZE;
+ break;
+ }
+ }
+ break;
+ case OTRL_MSGSTATE_FINISHED:
+ code = IO_ST_FINISHED;
+ break;
+ default:
+ otr_logst(MSGLEVEL_CRAP,
+ "BUG Found! Please write us a mail and describe how you got here");
+ code = IO_ST_UNKNOWN;
+ break;
+ }
+
+end:
+ if (ctx) {
+ IRSSI_DEBUG("Code: %d, state: %d, sm_prog_state: %d, auth state: %d",
+ code, ctx->msgstate, ctx->smstate->sm_prog_state,
+ ctx->auth.authstate);
+ }
+ return code;
+}
+
+
+/*
+ * Get a format describing the OTR status of this conversation.
+ */
+int otr_getstatus_format(SERVER_REC *irssi, const char *nick)
+{
+ int status = otr_getstatus(irssi, nick);
+
switch (status) {
case IO_ST_PLAINTEXT:
return TXT_ST_PLAINTEXT;
@@ -659,8 +726,8 @@ int otr_getstatus_format(IRC_CTX *irssi, const char *nick)
/*
* Change status bar text for a given nickname.
*/
-void otr_status_change(IRC_CTX *irssi, const char *nick,
- enum statusbar_event event)
+void otr_status_change(SERVER_REC *irssi, const char *nick,
+ enum otr_status_event event)
{
statusbar_items_redraw("otr");
signal_emit("otr event", 3, irssi, nick, statusbar_txt[event]);
diff --git a/src/otr.h b/src/otr.h
index b75898b..f71b0d8 100644
--- a/src/otr.h
+++ b/src/otr.h
@@ -63,18 +63,23 @@
#define IRCACTIONMARK "/me "
#define IRCACTIONMARKLEN 4
-/* user state */
+/*
+ * Memory allocation zeroed. Really useful!
+ */
+#define zmalloc(x) calloc(1, x)
-typedef struct {
+/* Irssi otr user state */
+struct otr_user_state {
OtrlUserState otr_state;
- GSList *plistunknown;
- GSList *plistknown;
-} IOUSTATE;
-
-/* one for each OTR context (=communication pair) */
-struct irssi_otr_context {
- SERVER_REC *irssi; /* Irssi server object for this peer */
- unsigned int received_smp_init; /* Do the SMP auth was received ? */
+ GSList *policy_unknown_list;
+ GSList *policy_known_list;
+};
+
+/*
+ * Peer OTR internal context.
+ */
+struct otr_peer_context {
+ int received_smp_init;
};
/* these are returned by /otr contexts */
@@ -95,36 +100,34 @@ struct ctxlist_ {
/* returned by otr_getstatus */
enum otr_status {
- IO_ST_PLAINTEXT,
- IO_ST_FINISHED,
- IO_ST_SMP_INCOMING,
- IO_ST_SMP_OUTGOING,
- IO_ST_SMP_FINALIZE,
- IO_ST_UNKNOWN,
- IO_ST_UNTRUSTED=32,
- IO_ST_TRUST_MANUAL=64,
- IO_ST_TRUST_SMP=128,
- IO_ST_SMP_ONGOING=
- IO_ST_SMP_INCOMING | IO_ST_SMP_OUTGOING | IO_ST_SMP_FINALIZE
+ IO_ST_PLAINTEXT = 0,
+ IO_ST_FINISHED = 1,
+ IO_ST_SMP_INCOMING = 2,
+ IO_ST_SMP_OUTGOING = 3,
+ IO_ST_SMP_FINALIZE = 4,
+ IO_ST_UNKNOWN = 5,
+ IO_ST_UNTRUSTED = 6,
+ IO_ST_TRUST_MANUAL = 7,
+ IO_ST_TRUST_SMP = 8,
};
/* given to otr_status_change */
-enum statusbar_event {
- IO_STC_FINISHED,
- IO_STC_TRUST_MANUAL,
- IO_STC_TRUST_SMP,
- IO_STC_SMP_ABORT,
- IO_STC_SMP_STARTED,
- IO_STC_SMP_RESPONDED,
- IO_STC_SMP_INCOMING,
- IO_STC_SMP_FINALIZE,
- IO_STC_SMP_ABORTED,
- IO_STC_PEER_FINISHED,
- IO_STC_SMP_FAILED,
- IO_STC_SMP_SUCCESS,
- IO_STC_GONE_SECURE,
- IO_STC_GONE_INSECURE,
- IO_STC_CTX_UPDATE
+enum otr_status_event {
+ OTR_STATUS_FINISHED,
+ OTR_STATUS_TRUST_MANUAL,
+ OTR_STATUS_TRUST_SMP,
+ OTR_STATUS_SMP_ABORT,
+ OTR_STATUS_SMP_STARTED,
+ OTR_STATUS_SMP_RESPONDED,
+ OTR_STATUS_SMP_INCOMING,
+ OTR_STATUS_SMP_FINALIZE,
+ OTR_STATUS_SMP_ABORTED,
+ OTR_STATUS_PEER_FINISHED,
+ OTR_STATUS_SMP_FAILED,
+ OTR_STATUS_SMP_SUCCESS,
+ OTR_STATUS_GONE_SECURE,
+ OTR_STATUS_GONE_INSECURE,
+ OTR_STATUS_CTX_UPDATE
};
/* policy list generated from /set otr_policy */
@@ -135,50 +138,56 @@ struct plistentry {
};
/* there can be only one */
-extern IOUSTATE ioustate_uniq;
+extern struct otr_user_state *user_state_global;
+/* Libotr ops functions */
extern OtrlMessageAppOps otr_ops;
+/* Active debug or not */
extern int debug;
-void irc_send_message(IRC_CTX *ircctx, const char *recipient, char *msg);
-void otr_status_change(IRC_CTX *ircctx, const char *nick,
- enum statusbar_event event);
+void irssi_send_message(SERVER_REC *irssi, const char *recipient,
+ const char *message);
+void otr_status_change(SERVER_REC *irssi, const char *nick,
+ enum otr_status_event event);
-IRC_CTX *ircctx_by_peername(const char *peername, char *nick);
+SERVER_REC *find_irssi_ctx_by_peername(const char *peername, char *nick);
/* init stuff */
-IOUSTATE *otr_init_user(char *user);
-void otr_free_user(IOUSTATE *ioustate);
+struct otr_user_state *otr_init_user(const char *user);
+void otr_free_user(struct otr_user_state *ustate);
void otr_lib_init();
void otr_lib_uninit();
-void otr_setpolicies(IOUSTATE *ioustate, const char *policies, int known);
+void otr_setpolicies(struct otr_user_state *ustate, const char *policies,
+ int known);
/* basic send/receive/status stuff */
-int otr_send(IRC_CTX *server, const char *msg, const char *to, char **otr_msg);
-int otr_receive(IRC_CTX *server, const char *msg, const char *from,
- char **new_msg);
+int otr_send(SERVER_REC *irssi, const char *msg, const char *to,
+ char **otr_msg);
+int otr_receive(SERVER_REC *irssi, const char *msg,
+ const char *from, char **new_msg);
-int otr_getstatus(IRC_CTX *ircctx, const char *nick);
-ConnContext *otr_getcontext(const char *accname, const char *nick, int create,
- IRC_CTX *ircctx);
+int otr_getstatus(SERVER_REC *irssi, const char *nick);
/* user interaction */
-void otr_trust(IRC_CTX *server, char *nick, const char *peername);
-void otr_finish(IRC_CTX *server, char *nick, const char *peername,
- int inquery);
-void otr_auth(IRC_CTX *server, char *nick, const char *peername,
+void otr_trust(SERVER_REC *irssi, char *nick,
+ const char *peername);
+void otr_finish(SERVER_REC *irssi, char *nick,
+ const char *peername, int inquery);
+void otr_auth(SERVER_REC *irssi, char *nick, const char *peername,
const char *question, const char *secret);
-void otr_authabort(IRC_CTX *server, char *nick, const char *peername);
-void otr_abort_auth(ConnContext *co, IRC_CTX *ircctx, const char *nick);
-struct ctxlist_ *otr_contexts(IOUSTATE *ioustate);
-void otr_finishall(IOUSTATE *ioustate);
-
-int otr_getstatus_format(IRC_CTX *ircctx, const char *nick);
+void otr_authabort(SERVER_REC *irssi, char *nick,
+ const char *peername);
+void otr_abort_auth(ConnContext *co, SERVER_REC *irssi,
+ const char *nick);
+struct ctxlist_ *otr_contexts(struct otr_user_state *ustate);
+void otr_finishall(struct otr_user_state *ustate);
+
+int otr_getstatus_format(SERVER_REC *irssi, const char *nick);
#endif /* IRSSI_OTR_OTR_H */
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/irssi-plugin-otr.git
More information about the Pkg-privacy-commits
mailing list