[Pkg-privacy-commits] [irssi-plugin-otr] 04/267: lots of changes:
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 12:41:21 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 d84a9bf06e2fb9f54aad58e4504052cdc09daf46
Author: Uli Meis <a.sporto+bee at gmail.com>
Date: Sat May 31 00:01:29 2008 +0200
lots of changes:
* moved to cmake. Seems overkill for such a small project but it does make
life easier for developing and also for packaging (should that ever happen).
Autotools never was an option for me.
* implemented socialist millionaire protocol
(some problems with it though, but they seem to be libotr problems)
* put all text into /formats so messages are totally configurable.
Also keeps the code clean.
* moved code around a bit (e.g. only one header now besides formats)
* some other things I dont recall right now ;)
---
.gitignore | 4 +
CMakeLists.txt | 113 +++++++
INSTALL | 10 +
Makefile | 39 ---
README | 36 ++
cmake-extensions/FindLibOTR.cmake | 49 +++
cmake-extensions/cscope.cmake | 17 +
formats.txt | 70 ++++
makeformats.py | 84 +++++
otr.c | 156 ++++++---
otr.h | 117 +++++--
otr_key.c | 224 +++++++++++++
otr_ops.c | 203 ++++++++++++
otrutil.c | 677 ++++++++++++++++++--------------------
otrutil.h | 41 ---
ui.c | 57 ++--
ui.h | 29 --
17 files changed, 1366 insertions(+), 560 deletions(-)
diff --git a/.gitignore b/.gitignore
index c0cd457..886bc2e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,7 @@
term.h
statusbar.h
mainwindows.h
+.exrc
+*.swp
+cscope.files
+cscope.out
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..e7b6100
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,113 @@
+#
+# Off-the-Record Messaging (OTR) module for the irssi IRC client
+# Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
+#
+# 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
+#
+
+PROJECT(IRSSIOTR)
+
+SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake-extensions/)
+INCLUDE(cmake-extensions/cscope.cmake)
+
+# GLIB
+
+FIND_PACKAGE(PkgConfig REQUIRED)
+pkg_check_modules(GLIB REQUIRED glib-2.0)
+
+# LIBOTR
+
+FIND_PACKAGE(LibOTR REQUIRED)
+IF (LIBOTR_VERSION LESS "3.1.0")
+ MESSAGE(FATAL_ERROR "Need libotr version >= 3.1.0 (fragmentation)")
+ENDIF (LIBOTR_VERSION LESS "3.1.0")
+
+# irssi public headers
+
+FIND_PATH(IRSSI_INCLUDE_DIR NAMES irssi/src/core/module.h)
+MARK_AS_ADVANCED(IRSSI_INCLUDE_DIR)
+
+IF(NOT IRSSI_INCLUDE_DIR)
+ MESSAGE(FATAL_ERROR "Couldn't find irssi headers, "
+ "usually installed in /usr/include/irssi")
+ENDIF(NOT IRSSI_INCLUDE_DIR)
+
+# Bad hack for irssi private headers
+
+FIND_PACKAGE(Wget REQUIRED)
+
+IF (NOT EXISTS "mainwindows.h")
+ MESSAGE(STATUS "Need to fetch and patch irssi private headers "
+ "mainwindows.h,statusbar.h,term.h from SVN (see irssi FS#535)")
+ EXECUTE_PROCESS(COMMAND "bash" "-c"
+ "${WGET_EXECUTABLE} '--post-data=revision=4806&root=irssi' \\
+ 'http://svn.irssi.org/cgi-bin/viewvc.cgi/irssi/trunk/src/fe-text/mainwindows.h' \\
+ 'http://svn.irssi.org/cgi-bin/viewvc.cgi/irssi/trunk/src/fe-text/term.h' \\
+ 'http://svn.irssi.org/cgi-bin/viewvc.cgi/irssi/trunk/src/fe-text/statusbar.h' || exit 1
+ patch -p0 mainwindows.h < \"$0/privheaders.patch\" || exit 1"
+ ${PROJECT_SOURCE_DIR} RESULT_VARIABLE IIPRIV_RET)
+ IF(NOT IIPRIV_RET EQUAL 0)
+ MESSAGE(FATAL_ERROR "Couldn't check out irssi private headers from SVN")
+ ENDIF(NOT IIPRIV_RET EQUAL 0)
+ENDIF (NOT EXISTS "mainwindows.h")
+
+# includes
+
+SET(IRSSIOTR_INCLUDE_DIRS
+ ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR} ${GLIB_INCLUDE_DIRS}
+ ${LIBOTR_INCLUDE_DIRS}
+ ${IRSSI_INCLUDE_DIR}/irssi
+ ${IRSSI_INCLUDE_DIR}/irssi/src
+ ${IRSSI_INCLUDE_DIR}/irssi/src/core)
+
+include_directories(${IRSSIOTR_INCLUDE_DIRS})
+
+# defs
+
+ADD_DEFINITIONS(-DHAVE_CONFIG_H -Wall -g)
+
+# generate otr-formats.{c,h}
+
+ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/otr-formats.c
+ DEPENDS makeformats.py formats.txt README
+ COMMAND
+ ${PROJECT_SOURCE_DIR}/makeformats.py
+ ${PROJECT_SOURCE_DIR}/formats.txt
+ ${PROJECT_SOURCE_DIR}/README
+ )
+
+# lib
+
+ADD_LIBRARY(otr SHARED otr.c otrutil.c otr_ops.c otr_key.c ui.c ${PROJECT_BINARY_DIR}/otr-formats.c)
+
+TARGET_LINK_LIBRARIES(otr ${GLIB_LIBRARIES} ${LIBOTR_LIBRARIES})
+
+# Install
+
+EXECUTE_PROCESS(COMMAND "whoami" OUTPUT_VARIABLE WHOAMI)
+IF(WHOAMI STREQUAL "root\n")
+ SET(IRSSIOTR_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/irssi/modules/")
+ MESSAGE(STATUS "Install will be into ${IRSSIOTR_INSTALL_DIR}")
+ELSE(WHOAMI STREQUAL "root\n")
+ SET(IRSSIOTR_INSTALL_DIR "$ENV{HOME}/.irssi/modules/")
+ MESSAGE(STATUS "You're not root. Install will be into ${IRSSIOTR_INSTALL_DIR}")
+ENDIF(WHOAMI STREQUAL "root\n")
+
+INSTALL(TARGETS otr DESTINATION ${IRSSIOTR_INSTALL_DIR})
+
+# cscope
+
+FILE(GLOB CSANDHS *.c *.h)
+ADD_CSCOPE_TARGET(${CSANDHS} ${IRSSIOTR_INCLUDE_DIRS})
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..d372465
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,10 @@
+Usually the following will do:
+
+ $ cmake /path/to/src
+ $ make
+ $ make install
+
+"make install" will install libotr.so either
+
+1. into the system wide irssi modules folder if you're root or
+2. into ~/.irssi/modules if you're not root
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 541377c..0000000
--- a/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-SRCS=otr.c otrutil.c ui.c
-HDRS=otr.h otrutil.h ui.h mainwindows.h
-OBJS=$(SRCS:%.c=%.o)
-
-INCLUDES=-I/usr/include/irssi/ -I/usr/include/irssi/src -I/usr/include/irssi/src/core -I.
-DEFINES=-DHAVE_CONFIG_H
-
-CFLAGS=-Wall -g -fPIC ${INCLUDES} ${DEFINES} `pkg-config --cflags glib-2.0`
-LDFLAGS=-shared -lotr
-
-CC=gcc
-LD=ld
-
-.PHONY: deploy compile
-
-compile: libotr.so
-
-deploy: libotr.so
- cp libotr.so ~/.irssi/modules/libotr.so
-
-
-%.so:
- ${LD} ${LDFLAGS} $^ -o $@
-
-mainwindows.h:
- @echo "**** Fetching headers from irssi svn..."
- @for hdr in mainwindows.h term.h statusbar.h; do \
- svn cat -r 4815 http://svn.irssi.org/repos/irssi/trunk/src/fe-text/$$hdr >$$hdr \
- ;done
- patch -p0 mainwindows.h <privheaders.patch
-
-otr.o: otr.c ${HDRS}
-otrutil.o: otrutil.c ${HDRS}
-ui.o: ui.c ui.h
-
-libotr.so: ${OBJS}
-
-clean:
- rm *.o *.so
diff --git a/README b/README
new file mode 100644
index 0000000..1341e1f
--- /dev/null
+++ b/README
@@ -0,0 +1,36 @@
+Usually, you shouldn't have to do anything besides "/load otr" to have encrypted
+conversations. However, some IRC servers strip off the tabs OTR uses as
+announcement, there you or your buddy will have to type "?OTR?" to get going.
+
+Initially a private key will also have to be generated...that can take two
+minutes or even an hour. You can wait for OTR to trigger key generation or do
+"/otr genkey nick at irc.server.com" yourself.
+
+To make sure that you are actually talking to your buddy, you can agree on a
+secret somehow and then one does "/otr auth <secret>". Shortly afterwards the
+other one will be asked to do the same and you're done. Well, unfortunately the
+world ain't perfect and it seems libotr isn't either (goes for me as well), so
+currently only the responder will be able to authenticate this way. You'll have
+to switch roles and do this twice - sry.
+
+I also strongly recommend to do "/statusbar window add otr" so you're informed
+about what's going on. Status of "manual" means manual authentication was
+performed, "smp" means the above protocol was used (the thing's called
+"socialist millionaire protocol").
+
+In "~/.irssi/otr/otr.{key,fp}" you'll find the fingerprints and your private
+keys(should you at any point be interested).
+
+Commands:
+
+/otr genkey nick at irc.server.com
+ Manually generate a key for the given account(also done on demand)
+/otr auth <secret>
+ Initiate or respond to an authentication challenge
+/otr authabort
+ Abort any ongoing authentication
+/otr trust
+ Trust the fingerprint of the user in the current window blindly.
+ Better use "/otr auth"
+/otr debug
+ Switch debug mode on/off
diff --git a/cmake-extensions/FindLibOTR.cmake b/cmake-extensions/FindLibOTR.cmake
new file mode 100644
index 0000000..63624c9
--- /dev/null
+++ b/cmake-extensions/FindLibOTR.cmake
@@ -0,0 +1,49 @@
+#
+# Uli Meis <a.sporto+bee at gmail.com>
+#
+# Mostly taken from cmake findcurl, version stuff from kopete
+#
+# - Find libotr
+# Find the libotr headers and library.
+#
+# LIBOTR_INCLUDE_DIR
+# LIBOTR_LIBRARIES
+# LIBOTR_FOUND
+
+# Look for the header file.
+FIND_PATH(LIBOTR_INCLUDE_DIR NAMES libotr/version.h)
+MARK_AS_ADVANCED(LIBOTR_INCLUDE_DIR)
+
+# Look for the library.
+FIND_LIBRARY(LIBOTR_LIBRARY NAMES otr)
+MARK_AS_ADVANCED(LIBOTR_LIBRARY)
+
+# Copy the results to the output variables.
+IF(LIBOTR_INCLUDE_DIR AND LIBOTR_LIBRARY)
+ SET(LIBOTR_FOUND 1)
+ SET(LIBOTR_LIBRARIES ${LIBOTR_LIBRARY})
+ SET(LIBOTR_INCLUDE_DIRS ${LIBOTR_INCLUDE_DIR})
+ EXECUTE_PROCESS(COMMAND grep "OTRL_VERSION"
+ "${LIBOTR_INCLUDE_DIR}/libotr/version.h" OUTPUT_VARIABLE output)
+ STRING(REGEX MATCH "OTRL_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+"
+ LIBOTR_VERSION "${output}")
+ STRING(REGEX REPLACE "^OTRL_VERSION \"" "" LIBOTR_VERSION "${LIBOTR_VERSION}")
+ MESSAGE(STATUS " found libotr, version ${LIBOTR_VERSION}" )
+ELSE(LIBOTR_INCLUDE_DIR AND LIBOTR_LIBRARY)
+ SET(LIBOTR_FOUND 0)
+ SET(LIBOTR_LIBRARIES)
+ SET(LIBOTR_INCLUDE_DIRS)
+ENDIF(LIBOTR_INCLUDE_DIR AND LIBOTR_LIBRARY)
+
+# Report the results.
+IF(NOT LIBOTR_FOUND)
+ SET(LIBOTR_DIR_MESSAGE
+ "LIBOTR was not found. Make sure LIBOTR_LIBRARY and LIBOTR_INCLUDE_DIR are set.")
+ IF(NOT LIBOTR_FIND_QUIETLY)
+ MESSAGE(STATUS "${LIBOTR_DIR_MESSAGE}")
+ ELSE(NOT LIBOTR_FIND_QUIETLY)
+ IF(LIBOTR_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "${LIBOTR_DIR_MESSAGE}")
+ ENDIF(LIBOTR_FIND_REQUIRED)
+ ENDIF(NOT LIBOTR_FIND_QUIETLY)
+ENDIF(NOT LIBOTR_FOUND)
diff --git a/cmake-extensions/cscope.cmake b/cmake-extensions/cscope.cmake
new file mode 100644
index 0000000..59594b4
--- /dev/null
+++ b/cmake-extensions/cscope.cmake
@@ -0,0 +1,17 @@
+#
+# Uli Meis <a.sporto+bee at gmail.com>
+#
+# Handy macro for generating the cscope database
+#
+
+MACRO(ADD_CSCOPE_TARGET CSCOPE_SOURCES CSCOPE_INCLUDES)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT cscope.out
+ DEPENDS ${CSCOPE_SOURCES}
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ COMMAND
+ echo '${CSCOPE_SOURCES}' | tr ' ' '\\n' >cscope.files
+ COMMAND
+ cscope -b `echo ${CSCOPE_INCLUDES} | xargs -n1 bash -c 'echo -I$$0'`)
+ ADD_CUSTOM_TARGET(cscope DEPENDS cscope.out)
+ENDMACRO(ADD_CSCOPE_TARGET)
diff --git a/formats.txt b/formats.txt
new file mode 100644
index 0000000..5ce4412
--- /dev/null
+++ b/formats.txt
@@ -0,0 +1,70 @@
+damn {hilight Damn!}
+bumsum One {hilight two}
+whatever One %s hell %s
+kg_failed Key generation for %s: failed: %s (%s)
+kg_completed Key generation for %s: completed in %d seconds. Reloading keys
+kg_aborted_dup Key generation for %s: aborted. Key generation for %s still in progress
+kg_aborted_dir Key generation for %s: aborted, failed creating directory %s: %s
+kg_mkdir created directory %s
+kg_pipe Key generation for %s: error creating pipe: %s
+kg_fork Key generation for %s: fork() error: %s
+kg_initiated Key generation for %s: initiated. This might take several minutes or on some systems even an hour. If you wanna check that something is happening, see if there are two irssi processes.
+fp_saved fingerprints saved
+fp_save_error Error saving fingerprints: %s (%s)
+ops_notify_bug BUG() in ops_notify
+ops_notify title: %s prim: %s sec: %s
+ops_display_bug BUG() in ops_display
+ops_display msg: %s
+ops_sec gone %9secure%9
+ops_insec gone %9insecure%9
+ops_still_reply still %9secure%9 (is reply)
+ops_still_no_reply still %9secure%9 (is not reply)
+ops_log log msg: %s
+key_not_found no private keys found
+key_loaded private keys loaded
+key_load_error Error loading private keys: %s (%s)
+fp_not_found no fingerprints found
+fp_loaded fingerprints loaded
+fp_load_error Error loading fingerprints: %s (%s)
+fp_trust Trusting fingerprint from %s
+send_failed send failed: msg=%s
+send_change couldn't find context also OTR changed the outgoing message(BUG?)
+send_fragment failed to fragment message: msg=%s
+send_converted OTR converted sent message to %s
+ctx_not_found couldn't find context: acc=%s nick=%s
+auth_aborted_ongoing Ongoing authentication aborted
+auth_aborted Authentication aborted
+auth_responding Responding to authentication request...
+auth_initiated Initiated authentication...
+ctx_not_create couldn't create/find context: acc=%s from=%s
+receive_ignore_query ignoring rest of OTR default query msg
+receive_dequeued dequeued msg of length %d
+receive_queued queued msg of length %d
+receive_ignore ignoring protocol message of length %s, acc=%s, from=%s
+receive_converted OTR converted received message
+auth_have_old %s wanted to authenticate but an old authentication was still ongoing. Old authentication will be aborted, please try again.
+auth_peer %s wants to authenticate. Type /otr auth <your-shared-secret> to complete.
+auth_peer_reply_wrong %s replied to an auth we didn't start.
+auth_peer_replied %s replied to our auth request...
+auth_peer_wrong_smp3 %s sent a wrong authentication message (SMP3).
+auth_successful Authentication successful!
+auth_failed Authentication failed!
+otr_better_two <b>%s</b> has requested an <a href=\"http://otr.cypherpunks.ca/\">Off-the-Record private conversation</a>. However, you do not have a plugin to support that.
+otr_better_three See <a href=\"http://otr.cypherpunks.ca/\">http://otr.cypherpunks.ca/</a> for more information.
+cmd_otr We're alive
+cmd_trust failed: Can't get query details
+cmd_auth Please agree on a secret and then run /otr auth <secret>
+cmd_debug_on Debug mode is on
+cmd_debug_off Debug mode is off
+nickignore xmlconsole
+st_plaintext {sb plaintext}
+st_untrusted {sb {hilight encrypted}(untrusted)}
+st_trust_smp {sb {hilight authenticated}(smp)}
+st_trust_manual {sb {hilight authenticated}(manual)}
+st_smp_wait_2 {sb {hilight awaiting auth reply...}}
+st_smp_have_2 {sb {hilight finalizing auth... (won't happen with libotr 3.1(bug), ask the other guy to initiate)}}
+st_smp_failed {sb {hilight auth failed}}
+st_smp_finalize {sb {hilight finalizing auth...}}
+st_smp_unknown {sb {hilight unknown auth state!}}
+st_finished {sb finished}
+st_unknown {sb {hilight state unknown (BUG!)}}
diff --git a/makeformats.py b/makeformats.py
new file mode 100755
index 0000000..d2c3bab
--- /dev/null
+++ b/makeformats.py
@@ -0,0 +1,84 @@
+#!/usr/bin/python
+#
+# Uli Meis <a.sporto+bee at gmail.com>
+#
+# Just a short script to generate our FORMAT_REC
+#
+
+import sys,os,re
+
+lines = map(lambda x: x.strip(),open(sys.argv[1],"r").readlines())
+
+hdr = open("otr-formats.h","w")
+src = open("otr-formats.c","w")
+
+src.write('#include "otr.h"\nFORMAT_REC formats[] = {\n')
+
+src.write('{ MODULE_NAME, "otr", 0},\n')
+
+src.write("""{ "help", "%s", 0 }""" % "\\n".join(
+ ["{hilight - OTR help -}"]+
+ [re.sub('^(/otr.*)$','%_\\1%_',
+ re.sub('"(.*)"','\\"%_\\1%_\\"',
+ x.replace('\n','').replace("\t"," ")
+ ))
+ for x in open(sys.argv[2],"r").readlines()]+
+ ["{hilight - End of OTR help -}"]))
+
+hdr.write("enum {\n")
+
+hdr.write("TXT_OTR_MODULE_NAME,\nTXT_HELP")
+
+for line in lines:
+ src.write(",\n")
+
+ e = line.split("\t")
+
+ params = []
+ fo = e[1]
+ new = ""
+ last=0
+ i=0
+ for m in re.finditer("(^|[^%])%[ds]",fo):
+ if m.group()[-1]=='d':
+ params += ['1']
+ else:
+ params += ['0']
+ new += fo[last:m.start()]+"$%d" % i
+ last = m.end()
+ i += 1
+
+ new += fo[last:]
+
+ e[1] = new
+ e += [len(params)] + params
+
+ #print "Handling line %s with elen %d" % (line,len(e))
+
+ premsg = ""
+ if e[1][0] != "{":
+ premsg = "%9OTR%9: "
+
+ src.write("""{ "%s", "%s%s", %s""" % (e[0],premsg,e[1],e[2]))
+
+ if len(params)>0:
+ src.write(", { %s }" % ", ".join(params))
+
+ src.write("}")
+
+ hdr.write(",\n")
+
+ hdr.write("TXT_%s" % e[0].upper())
+
+hdr.write("""
+};
+
+extern FORMAT_REC formats[];
+""")
+
+src.write("""
+};
+""")
+
+hdr.close()
+src.close()
diff --git a/otr.c b/otr.c
index f2824df..6d2f4ee 100644
--- a/otr.c
+++ b/otr.c
@@ -1,31 +1,32 @@
/*
- Off-the-Record Messaging (OTR) module for the irssi IRC client
- Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
-
- 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
-*/
+ * Off-the-Record Messaging (OTR) module for the irssi IRC client
+ * Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
+ *
+ * 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 "otr.h"
int debug = FALSE;
+GRegex *regex_nickignore;
/*
* Pipes all outgoing private messages through OTR
*/
static void sig_server_sendmsg(SERVER_REC *server, const char *target,
- const char *msg, void *target_type_p)
+ const char *msg, void *target_type_p)
{
if (GPOINTER_TO_INT(target_type_p)==SEND_TARGET_NICK) {
char *otrmsg = otr_send(server,msg,target);
@@ -41,15 +42,13 @@ static void sig_server_sendmsg(SERVER_REC *server, const char *target,
* Pipes all incoming private messages through OTR
*/
static void sig_message_private(SERVER_REC *server, const char *msg,
- const char *nick, const char *address)
+ const char *nick, const char *address)
{
char *newmsg;
- /* hack for bitlbee so we're not too busy
- * with the jabber xml console */
- if (strstr(nick,"xmlconsole"))
+ if (g_regex_match(regex_nickignore,nick,0,NULL))
return;
-
+
newmsg = otr_receive(server,msg,nick);
if (newmsg&&(newmsg!=msg)) {
@@ -62,76 +61,151 @@ static void sig_message_private(SERVER_REC *server, const char *msg,
/*
* /otr
*/
-static void cmd_otr(const char *data,void *server,WI_ITEM_REC *item) {
+static void cmd_otr(const char *data,void *server,WI_ITEM_REC *item)
+{
if (*data == '\0')
- otr_logst(LVL_NOTICE,"We're alive");
+ otr_noticest(TXT_CMD_OTR);
else {
command_runsub("otr", data, server, item);
}
}
-static void cmd_trust(const char *data, void *server, WI_ITEM_REC *item) {
+/*
+ * /otr trust
+ */
+static void cmd_trust(const char *data, void *server, WI_ITEM_REC *item)
+{
QUERY_REC *query = QUERY(item);
if (query&&query->server&&query->server->connrec)
- otr_trust(query->server->nick,query->name,query->server->connrec->address);
+ otr_trust(query->server,query->name);
else
- otr_log(item->server,NULL,query ? query->name : NULL,LVL_NOTICE,
- "failed: Can't get query details");
+ otr_notice(item->server,query ? query->name : NULL,
+ TXT_CMD_TRUST);
+}
+
+/*
+ * /otr genkey nick at irc.server.com
+ */
+static void cmd_genkey(const char *data, void *server, WI_ITEM_REC *item)
+{
+ //TODO check data
+ keygen_run(data);
+}
+
+/*
+ * /otr auth <secret>
+ */
+static void cmd_auth(const char *data, void *server, WI_ITEM_REC *item)
+{
+ WI_ITEM_REC *wi = active_win->active;
+ QUERY_REC *query = QUERY(wi);
+
+ if (query&&query->server&&query->server->connrec) {
+ if (!data||(*data=='\0')) {
+ otr_notice(server,query->name,
+ TXT_CMD_AUTH);
+ return;
+ }
+ otr_auth(query->server,query->name,data);
+ }
+}
+
+/*
+ * /otr authabort
+ */
+static void cmd_authabort(const char *data, void *server, WI_ITEM_REC *item)
+{
+ WI_ITEM_REC *wi = active_win->active;
+ QUERY_REC *query = QUERY(wi);
+
+ if (query&&query->server&&query->server->connrec)
+ otr_authabort(query->server,query->name);
}
/*
* /otr debug
*/
-static void cmd_debug(const char *data, void *server, WI_ITEM_REC *item) {
+static void cmd_debug(const char *data, void *server, WI_ITEM_REC *item)
+{
debug = !debug;
- otr_logst(LVL_NOTICE,"Debug mode %s", debug ? "on" : "off" );
+ otr_noticest(debug ? TXT_CMD_DEBUG_ON : TXT_CMD_DEBUG_OFF);
+}
+
+/*
+ * /otr help
+ */
+static void cmd_help(const char *data, void *server, WI_ITEM_REC *item)
+{
+ printformat(NULL,NULL,MSGLEVEL_CRAP,TXT_HELP);
}
-static void otr_statusbar(SBAR_ITEM_REC *item, int get_size_only) {
+/*
+ * otr statusbar
+ */
+static void otr_statusbar(SBAR_ITEM_REC *item, int get_size_only)
+{
WI_ITEM_REC *wi = active_win->active;
QUERY_REC *query = QUERY(wi);
- char *data = NULL;
+ int formatnum=0;
if (query&&query->server&&query->server->connrec)
- data = otr_getstatus(query->server->nick,query->name,query->server->connrec->address);
-
+ formatnum = otr_getstatus(query->server->nick,query->name,query->server->connrec->address);
+
statusbar_item_default_handler(
item,
get_size_only,
- data ? "{sb Otr: $0-}" : "",data,FALSE);
+ formatnum ? formats[formatnum].def : ""," ",FALSE);
}
/*
* irssi init()
*/
-void otr_init(void) {
+void otr_init(void)
+{
+ regex_nickignore = g_regex_new(formats[TXT_NICKIGNORE].def,0,0,NULL);
+
module_register(MODULE_NAME, "core");
+ theme_register(formats);
+
if (otrlib_init())
return;
signal_add_first("server sendmsg", (SIGNAL_FUNC) sig_server_sendmsg);
signal_add_first("message private", (SIGNAL_FUNC) sig_message_private);
-
+
command_bind("otr", NULL, (SIGNAL_FUNC) cmd_otr);
command_bind("otr debug", NULL, (SIGNAL_FUNC) cmd_debug);
command_bind("otr trust", NULL, (SIGNAL_FUNC) cmd_trust);
+ command_bind("otr genkey", NULL, (SIGNAL_FUNC) cmd_genkey);
+ command_bind("otr auth", NULL, (SIGNAL_FUNC) cmd_auth);
+ command_bind("otr authabort", NULL, (SIGNAL_FUNC) cmd_authabort);
+ command_bind("otr help", NULL, (SIGNAL_FUNC) cmd_help);
statusbar_item_register("otr", NULL, otr_statusbar);
statusbar_items_redraw("window");
- /* use standard irssi style messages */
- theme_register_module(MODULE_NAME,fecommon_core_formats);
+
}
/*
* irssi deinit()
*/
-void otr_deinit(void) {
+void otr_deinit(void)
+{
+ g_regex_unref(regex_nickignore);
signal_remove("server sendmsg", (SIGNAL_FUNC) sig_server_sendmsg);
signal_remove("message private", (SIGNAL_FUNC) sig_message_private);
+ command_unbind("otr", (SIGNAL_FUNC) cmd_otr);
+ command_unbind("otr debug", (SIGNAL_FUNC) cmd_debug);
+ command_unbind("otr trust", (SIGNAL_FUNC) cmd_trust);
+ command_unbind("otr genkey", (SIGNAL_FUNC) cmd_genkey);
+ command_unbind("otr auth", (SIGNAL_FUNC) cmd_auth);
+ command_unbind("otr authabort", (SIGNAL_FUNC) cmd_authabort);
+ command_unbind("otr help", (SIGNAL_FUNC) cmd_help);
+
statusbar_item_unregister("otr");
otrlib_deinit();
diff --git a/otr.h b/otr.h
index 9ba99ae..e7c6ece 100644
--- a/otr.h
+++ b/otr.h
@@ -1,27 +1,28 @@
/*
- Off-the-Record Messaging (OTR) module for the irssi IRC client
- Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
-
- 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
-*/
+ * Off-the-Record Messaging (OTR) module for the irssi IRC client
+ * Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
+ *
+ * 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 <stdlib.h>
/* OTR */
#include <libotr/proto.h>
+#include <libotr/context.h>
#include <libotr/message.h>
#include <libotr/privkey.h>
@@ -50,9 +51,87 @@
/* own */
-#include "otrutil.h"
-#include "ui.h"
+#include "otr-formats.h"
/* irssi module name */
#define MODULE_NAME "otr"
+/*
+ * maybe this should be configurable?
+ * I believe bitlbee has something >500.
+ */
+#define OTR_MAX_MSG_SIZE 400
+
+/* otr protocol id */
+#define PROTOCOLID "IRC"
+
+#define KEYFILE "/otr/otr.key"
+#define FPSFILE "/otr/otr.fp"
+
+/* one for each OTR context (=communication pair) */
+struct co_info {
+ char *msgqueue; /* holds partially reconstructed base64
+ messages */
+ SERVER_REC *server; /* irssi server object for this peer */
+ int received_smp_init; /* received SMP init msg */
+ int received_smp_reply; /* received SMP reply msg */
+ int smp_failed; /* SMP failed */
+ char better_msg_two[256]; /* what the second line of the "better"
+ default query msg should like. Eat it
+ up when it comes in */
+};
+
+extern int debug;
+
+/* init stuff */
+
+int otrlib_init();
+void otrlib_deinit();
+void otr_initops();
+
+/* basic send/receive/status stuff */
+
+char *otr_send(SERVER_REC *server,const char *msg,const char *to);
+char *otr_receive(SERVER_REC *server,const char *msg,const char *from);
+int otr_getstatus(char *mynick, char *nick, char *server);
+ConnContext *otr_getcontext(const char *accname,const char *nick,int create,void *data);
+
+/* user interaction */
+
+void otr_trust(SERVER_REC *server, char *nick);
+void otr_auth(SERVER_REC *server, char *nick, const char *secret);
+void otr_authabort(SERVER_REC *server, char *nick);
+
+
+/* key/fingerprint stuff */
+
+void keygen_run(const char *accname);
+void keygen_abort();
+void key_load();
+void fps_load();
+void otr_writefps();
+
+/* log stuff */
+
+#define LOGMAX 1024
+
+#define LVL_NOTICE 0
+#define LVL_DEBUG 1
+
+#define otr_logst(level,format,...) \
+ otr_log(NULL,NULL,level,format, ## __VA_ARGS__)
+
+#define otr_noticest(formatnum,...) \
+ printformat(NULL,NULL,MSGLEVEL_CRAP, formatnum, ## __VA_ARGS__)
+
+#define otr_notice(server,nick,formatnum,...) \
+ printformat(server,nick,MSGLEVEL_CRAP, formatnum, ## __VA_ARGS__)
+
+#define otr_debug(server,nick,formatnum,...) { \
+ if (debug) \
+ printformat(server,nick, \
+ MSGLEVEL_CRAP, formatnum, ## __VA_ARGS__); \
+}
+
+void otr_log(SERVER_REC *server, const char *to,
+ int level, const char *format, ...);
diff --git a/otr_key.c b/otr_key.c
new file mode 100644
index 0000000..aa355f9
--- /dev/null
+++ b/otr_key.c
@@ -0,0 +1,224 @@
+/*
+ * Off-the-Record Messaging (OTR) module for the irssi IRC client
+ * Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
+ *
+ * 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 "otr.h"
+
+#include <libgen.h>
+
+extern OtrlUserState otr_state;
+
+typedef enum { KEYGEN_NO, KEYGEN_RUNNING } keygen_status_t;
+
+struct {
+ keygen_status_t status;
+ char *accountname;
+ char *protocol;
+ time_t started;
+ GIOChannel *ch[2];
+ guint eid;
+} kg_st = {.status = KEYGEN_NO };
+
+/*
+ * Installed as g_io_watch and called when the key generation
+ * process finishs.
+ */
+gboolean keygen_complete(GIOChannel *source, GIOCondition condition,
+ gpointer data)
+{
+ gcry_error_t err;
+
+ read(g_io_channel_unix_get_fd(kg_st.ch[0]),&err,sizeof(err));
+
+ g_io_channel_shutdown(kg_st.ch[0],FALSE,NULL);
+ g_io_channel_shutdown(kg_st.ch[1],FALSE,NULL);
+ g_io_channel_unref(kg_st.ch[0]);
+ g_io_channel_unref(kg_st.ch[1]);
+
+ if (err)
+ otr_noticest(TXT_KG_FAILED,
+ kg_st.accountname,
+ gcry_strerror(err),
+ gcry_strsource(err));
+ else {
+ /* reload keys */
+ otr_noticest(TXT_KG_COMPLETED,
+ kg_st.accountname,
+ time(NULL)-kg_st.started);
+ //otrl_privkey_forget_all(otr_state); <-- done by lib
+ key_load();
+ }
+
+ kg_st.status = KEYGEN_NO;
+ g_free(kg_st.accountname);
+
+ return FALSE;
+}
+
+/*
+ * Run key generation in a seperate process (takes ages).
+ * The other process will rewrite the key file, we shouldn't
+ * change anything till it's done and we've reloaded the keys.
+ */
+void keygen_run(const char *accname)
+{
+ gcry_error_t err;
+ int ret;
+ int fds[2];
+ char *filename = g_strconcat(get_irssi_dir(),KEYFILE,NULL);
+ char *dir = dirname(g_strdup(filename));
+
+ if (kg_st.status!=KEYGEN_NO) {
+ if (strcmp(accname,kg_st.accountname)!=0)
+ otr_noticest(TXT_KG_ABORTED_DUP,
+ accname,kg_st.accountname);
+ return;
+ }
+
+ if (!g_file_test(dir, G_FILE_TEST_EXISTS)) {
+ if (g_mkdir(dir,S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)) {
+ otr_noticest(TXT_KG_ABORTED_DIR,
+ accname,dir,strerror(errno));
+ g_free(dir);
+ g_free(filename);
+ return;
+ } else
+ otr_noticest(TXT_KG_MKDIR,dir);
+ }
+ g_free(dir);
+
+ if (pipe(fds) != 0) {
+ otr_noticest(TXT_KG_PIPE,
+ accname,strerror(errno));
+ g_free(filename);
+ return;
+ }
+
+ kg_st.ch[0] = g_io_channel_unix_new(fds[0]);
+ kg_st.ch[1] = g_io_channel_unix_new(fds[1]);
+
+ kg_st.accountname = g_strdup(accname);
+ kg_st.protocol = PROTOCOLID;
+ kg_st.started = time(NULL);
+
+ if ((ret = fork())) {
+ g_free(filename);
+ if (ret==-1) {
+ otr_noticest(TXT_KG_FORK,
+ accname,strerror(errno));
+ return;
+ }
+
+ kg_st.status = KEYGEN_RUNNING;
+ otr_noticest(TXT_KG_INITIATED,
+ accname);
+
+ kg_st.eid = g_io_add_watch(kg_st.ch[0], G_IO_IN,
+ (GIOFunc) keygen_complete, NULL);
+ kg_st.started = time(NULL);
+ return;
+ }
+
+ /* child */
+
+ err = otrl_privkey_generate(otr_state,filename,accname,PROTOCOLID);
+ write(fds[1],&err,sizeof(err));
+
+ //g_free(filename);
+ _exit(0);
+}
+
+/*
+ * Abort ongoing key generation.
+ */
+void keygen_abort()
+{
+ if (kg_st.status==KEYGEN_RUNNING)
+ g_source_remove(kg_st.eid);
+}
+
+/*
+ * Write fingerprints to file.
+ */
+void otr_writefps()
+{
+ gcry_error_t err;
+ char *filename = g_strconcat(get_irssi_dir(),FPSFILE,NULL);
+
+ err = otrl_privkey_write_fingerprints(otr_state,filename);
+
+ if (err == GPG_ERR_NO_ERROR) {
+ otr_noticest(TXT_FP_SAVED);
+ } else {
+ otr_noticest(TXT_FP_SAVE_ERROR,
+ gcry_strerror(err),
+ gcry_strsource(err));
+ }
+ g_free(filename);
+}
+
+/*
+ * Load private keys.
+ */
+void key_load()
+{
+ gcry_error_t err;
+ char *filename = g_strconcat(get_irssi_dir(),KEYFILE,NULL);
+
+ if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
+ otr_noticest(TXT_KEY_NOT_FOUND);
+ return;
+ }
+
+ err = otrl_privkey_read(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));
+ }
+ g_free(filename);
+}
+
+/*
+ * Load fingerprints.
+ */
+void fps_load()
+{
+ gcry_error_t err;
+ char *filename = g_strconcat(get_irssi_dir(),FPSFILE,NULL);
+
+ if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
+ otr_noticest(TXT_FP_NOT_FOUND);
+ return;
+ }
+
+ err = otrl_privkey_read_fingerprints(otr_state,filename,NULL,NULL);
+
+ if (err == GPG_ERR_NO_ERROR) {
+ otr_noticest(TXT_FP_LOADED);
+ } else {
+ otr_noticest(TXT_FP_LOAD_ERROR,
+ gcry_strerror(err),
+ gcry_strsource(err));
+ }
+ g_free(filename);
+}
+
diff --git a/otr_ops.c b/otr_ops.c
new file mode 100644
index 0000000..bcc3ca1
--- /dev/null
+++ b/otr_ops.c
@@ -0,0 +1,203 @@
+/*
+ * Off-the-Record Messaging (OTR) module for the irssi IRC client
+ * Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
+ *
+ * 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 "otr.h"
+
+OtrlMessageAppOps otr_ops;
+
+/*
+ * Policy is currently fixed as OTR lib default (meaning opportunistic).
+ */
+OtrlPolicy ops_policy(void *opdata, ConnContext *context)
+{
+ return OTRL_POLICY_DEFAULT;
+}
+
+/*
+ * Request for key generation.
+ * The lib actually expects us to be finished before the call returns.
+ * Since this can take more than an hour on some systems there isn't even
+ * a point in trying...
+ */
+void ops_create_privkey(void *opdata, const char *accountname,
+ const char *protocol)
+{
+ keygen_run(accountname);
+}
+
+/*
+ * Inject OTR message.
+ * Deriving the server is currently a hack,
+ * need to derive the server from accountname.
+ */
+void ops_inject_msg(void *opdata, const char *accountname,
+ const char *protocol, const char *recipient, const char *message)
+{
+ SERVER_REC *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 = active_win->active_server;
+ a_serv->send_message(a_serv, recipient, msgcopy,
+ GPOINTER_TO_INT(SEND_TARGET_NICK));
+ g_free(msgcopy);
+}
+
+/*
+ * OTR notification. Haven't seen one yet.
+ */
+void ops_notify(void *opdata, OtrlNotifyLevel level, const char *accountname,
+ const char *protocol, const char *username,
+ const char *title, const char *primary,
+ const char *secondary)
+{
+ ConnContext *co = otr_getcontext(accountname,username,FALSE,NULL);
+ SERVER_REC *server = active_win->active_server;
+ struct co_info *coi;
+ if (co) {
+ coi = co->app_data;
+ server = coi->server;
+ } else
+ otr_notice(server,username,TXT_OPS_NOTIFY_BUG);
+
+ otr_notice(server,username,TXT_OPS_NOTIFY,
+ title,primary,secondary);
+}
+
+/*
+ * OTR message. E.g. "following has been transmitted in clear: ...".
+ * We're trying to kill the ugly HTML.
+ */
+int ops_display_msg(void *opdata, const char *accountname,
+ const char *protocol, const char *username,
+ const char *msg)
+{
+ ConnContext *co = otr_getcontext(accountname,username,FALSE,NULL);
+ SERVER_REC *server = active_win->active_server;
+ struct co_info *coi;
+ /* This is kind of messy. */
+ GRegex *regex_bold = g_regex_new("</?i([ /][^>]*)?>",0,0,NULL);
+ GRegex *regex_del = g_regex_new("</?b([ /][^>]*)?>",0,0,NULL);
+ gchar *msgnohtml =
+ g_regex_replace_literal(regex_del,msg,-1,0,"",0,NULL);
+ msg = g_regex_replace_literal(regex_bold,msgnohtml,-1,0,"%9",0,NULL);
+
+ if (co) {
+ coi = co->app_data;
+ server = coi->server;
+ } else
+ otr_notice(server,username,TXT_OPS_DISPLAY_BUG);
+
+ otr_notice(server,username,TXT_OPS_DISPLAY,msg);
+
+ g_free(msgnohtml);
+ g_free((char*)msg);
+ g_regex_unref(regex_del);
+ g_regex_unref(regex_bold);
+ return 0;
+}
+
+/*
+ * Gone secure.
+ */
+void ops_secure(void *opdata, ConnContext *context)
+{
+ struct co_info *coi = context->app_data;
+ otr_notice(coi->server,
+ context->username,TXT_OPS_SEC);
+}
+
+/*
+ * Gone insecure.
+ */
+void ops_insecure(void *opdata, ConnContext *context)
+{
+ struct co_info *coi = context->app_data;
+ otr_notice(coi->server,
+ context->username,TXT_OPS_INSEC);
+}
+
+/*
+ * Still secure? Need to find out what that means...
+ */
+void ops_still_secure(void *opdata, ConnContext *context, int is_reply)
+{
+ struct co_info *coi = context->app_data;
+ otr_notice(coi->server,
+ context->username,is_reply ?
+ TXT_OPS_STILL_REPLY :
+ TXT_OPS_STILL_NO_REPLY);
+}
+
+/*
+ * OTR log message. IIRC heartbeats are of this category.
+ */
+void ops_log(void *opdata, const char *message)
+{
+ otr_noticest(TXT_OPS_LOG,message);
+}
+
+/*
+ * Really critical with IRC.
+ * Unfortunately, we can't tell our peer which size to use.
+ * (reminds me of MTU determination...)
+ */
+int ops_max_msg(void *opdata, ConnContext *context)
+{
+ return OTR_MAX_MSG_SIZE;
+}
+
+/*
+ * A context changed.
+ * I believe this is not happening for the SMP expects.
+ */
+void ops_up_ctx_list(void *opdata)
+{
+ statusbar_items_redraw("otr");
+}
+
+/*
+ * Save fingerprint changes.
+ */
+void ops_writefps(void *data)
+{
+ otr_writefps();
+}
+
+/*
+ * Initialize our OtrlMessageAppOps
+ */
+void otr_initops() {
+ memset(&otr_ops,0,sizeof(otr_ops));
+
+ otr_ops.policy = ops_policy;
+ otr_ops.create_privkey = ops_create_privkey;
+ otr_ops.inject_message = ops_inject_msg;
+ otr_ops.notify = ops_notify;
+ otr_ops.display_otr_message = ops_display_msg;
+ otr_ops.gone_secure = ops_secure;
+ otr_ops.gone_insecure = ops_insecure;
+ otr_ops.still_secure = ops_still_secure;
+ otr_ops.log_message = ops_log;
+ otr_ops.max_message_size = ops_max_msg;
+ otr_ops.update_context_list = ops_up_ctx_list;
+ otr_ops.write_fingerprints = ops_writefps;
+}
diff --git a/otrutil.c b/otrutil.c
index d97ed4a..2b9679f 100644
--- a/otrutil.c
+++ b/otrutil.c
@@ -1,268 +1,35 @@
/*
- Off-the-Record Messaging (OTR) module for the irssi IRC client
- Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
-
- 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
-*/
+ * Off-the-Record Messaging (OTR) module for the irssi IRC client
+ * Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
+ *
+ * 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 "otr.h"
-#include <libgen.h>
#include <gcrypt.h>
-static OtrlUserState otr_state = NULL;
-static OtrlMessageAppOps otr_ops;
+OtrlUserState otr_state = NULL;
+extern OtrlMessageAppOps otr_ops;
static int otrinited = FALSE;
-/* Key generation stuff */
-
-typedef enum { KEYGEN_NO, KEYGEN_RUNNING } keygen_status_t;
-
-struct {
- keygen_status_t status;
- char *accountname;
- char *protocol;
- time_t started;
- GIOChannel *ch[2];
- guint eid;
-} kg_st = {.status = KEYGEN_NO };
-
-#define KEYGENMSG "Key generation for %s: "
-
-/*
- * Installed as g_io_watch and called when the key generation
- * process finishs.
- */
-gboolean keygen_complete(GIOChannel *source, GIOCondition condition, gpointer data) {
- gcry_error_t err;
-
- read(g_io_channel_unix_get_fd(kg_st.ch[0]),&err,sizeof(err));
-
- g_io_channel_shutdown(kg_st.ch[0],FALSE,NULL);
- g_io_channel_shutdown(kg_st.ch[1],FALSE,NULL);
- g_io_channel_unref(kg_st.ch[0]);
- g_io_channel_unref(kg_st.ch[1]);
-
- if (err)
- otr_logst(LVL_NOTICE,KEYGENMSG "failed: %s (%s)",
- kg_st.accountname,
- gcry_strerror(err),
- gcry_strsource(err));
- else {
- /* reload keys */
- otr_logst(LVL_NOTICE,KEYGENMSG "completed in %d seconds. Reloading keys",
- kg_st.accountname,
- time(NULL)-kg_st.started);
- //otrl_privkey_forget_all(otr_state); <-- done by lib
- key_load();
- }
-
- kg_st.status = KEYGEN_NO;
- g_free(kg_st.accountname);
-
- return FALSE;
-}
-
-/*
- * Run key generation in a seperate process (takes ages).
- * The other process will rewrite the key file, we shouldn't
- * change anything till it's done and we've reloaded the keys.
- */
-void keygen_run(const char *accname) {
- gcry_error_t err;
- int ret;
- int fds[2];
- char *filename = g_strconcat(get_irssi_dir(),KEYFILE,NULL);
- char *dir = dirname(g_strdup(filename));
-
- if (kg_st.status!=KEYGEN_NO) {
- if (strcmp(accname,kg_st.accountname)!=0)
- otr_logst(LVL_NOTICE,KEYGENMSG
- "aborted. Key generation for %s"
- "still in progress",
- accname,kg_st.accountname);
- return;
- }
-
- if (!g_file_test(dir, G_FILE_TEST_EXISTS)) {
- if (g_mkdir(dir,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
- otr_logst(LVL_NOTICE,KEYGENMSG "aborted, failed creating directory %s: %s",
- accname,dir,strerror(errno));
- g_free(dir);
- g_free(filename);
- return;
- } else
- otr_logst(LVL_NOTICE,KEYGENMSG "created directory %s\n",dir);
- }
- g_free(dir);
-
- if (pipe(fds) != 0) {
- otr_logst(LVL_NOTICE,KEYGENMSG "error creating pipe: %s",accname,strerror(errno));
- g_free(filename);
- return;
- }
-
- kg_st.ch[0] = g_io_channel_unix_new(fds[0]);
- kg_st.ch[1] = g_io_channel_unix_new(fds[1]);
-
- kg_st.accountname = g_strdup(accname);
- kg_st.protocol = PROTOCOLID;
- kg_st.started = time(NULL);
-
- if ((ret = fork())) {
- g_free(filename);
- if (ret==-1) {
- otr_logst(LVL_NOTICE,KEYGENMSG "fork() error: %s",accname,strerror(errno));
- return;
- }
-
- kg_st.status = KEYGEN_RUNNING;
- otr_logst(LVL_NOTICE,KEYGENMSG "initiated. This might take several minutes.",accname);
-
- kg_st.eid = g_io_add_watch(kg_st.ch[0], G_IO_IN, (GIOFunc) keygen_complete, NULL);
- kg_st.started = time(NULL);
- return;
- }
-
- /* child */
-
- err = otrl_privkey_generate(otr_state,filename,accname,PROTOCOLID);
- write(fds[1],&err,sizeof(err));
-
- //g_free(filename);
- _exit(0);
-}
-
-void otr_writefps() {
- gcry_error_t err;
- char *filename = g_strconcat(get_irssi_dir(),FPSFILE,NULL);
-
- err = otrl_privkey_write_fingerprints(otr_state,filename);
-
- if (err == GPG_ERR_NO_ERROR) {
- otr_logst(LVL_NOTICE,"fingerprints saved");
- } else {
- otr_logst(LVL_NOTICE,"Error saving fingerprints: %s (%s)",
- gcry_strerror(err),
- gcry_strsource(err));
- }
- g_free(filename);
-}
-
-/* Callbacks from the OTR lib */
-
-OtrlPolicy ops_policy(void *opdata, ConnContext *context) {
- /* meaning opportunistic */
- return OTRL_POLICY_DEFAULT;
-}
-
-void ops_create_privkey(void *opdata, const char *accountname,
- const char *protocol) {
- keygen_run(accountname);
-}
-
-/*
- * Inject OTR message.
- * Deriving the server is currently a hack,
- * need to derive the server from accountname.
- */
-void ops_inject_msg(void *opdata, const char *accountname,
- const char *protocol, const char *recipient, const char *message) {
- SERVER_REC *a_serv;
- char *msgcopy = g_strdup(message);
-
- /* OTR sometimes gives us multiple lines (e.g. the init message) */
- g_strdelimit (msgcopy,"\n",' ');
- a_serv = active_win->active_server;
- a_serv->send_message(a_serv, recipient, msgcopy,
- GPOINTER_TO_INT(SEND_TARGET_NICK));
- g_free(msgcopy);
-}
-
-/*
- * OTR notification. Haven't seen one yet.
- */
-void ops_notify(void *opdata, OtrlNotifyLevel level, const char *accountname,
- const char *protocol, const char *username,
- const char *title, const char *primary,
- const char *secondary) {
- otr_log(active_win->active_server,accountname,username,LVL_NOTICE,
- "title: %s prim: %s sec: %s",title,primary,secondary);
-}
-
-/*
- * OTR message. E.g. "following has been transmitted in clear: ...".
- * We're trying to kill the ugly HTML.
- */
-int ops_display_msg(void *opdata, const char *accountname,
- const char *protocol, const char *username,
- const char *msg) {
- /* This is kind of messy. */
- GRegex *regex_bold = g_regex_new("</?i([ /][^>]*)?>",0,0,NULL);
- GRegex *regex_del = g_regex_new("</?b([ /][^>]*)?>",0,0,NULL);
- gchar *msgnohtml = g_regex_replace_literal(regex_del,msg,-1,0,"",0,NULL);
- msg = g_regex_replace_literal(regex_bold,msgnohtml,-1,0,"%9",0,NULL);
-
- otr_log(active_win->active_server,accountname,username,LVL_NOTICE,
- "msg: %s",msg);
-
- g_free(msgnohtml);
- g_free((char*)msg);
- g_regex_unref(regex_del);
- g_regex_unref(regex_bold);
- return 0;
-}
-
-void ops_secure(void *opdata, ConnContext *context) {
- otr_log(active_win->active_server,context->accountname,
- context->username,LVL_NOTICE,"gone %s","%9secure%9");
-}
-
-void ops_insecure(void *opdata, ConnContext *context) {
- otr_log(active_win->active_server,context->accountname,
- context->username,LVL_NOTICE,"gone %s","%9insecure%9");
-}
-
-void ops_still_secure(void *opdata, ConnContext *context, int is_reply) {
- otr_log(active_win->active_server,context->accountname,
- context->username,LVL_NOTICE,
- "still %s (%s reply)",
- "%9secure%9",
- is_reply ? "is" : "is not");
-}
-
-void ops_log(void *opdata, const char *message) {
- otr_logst(LVL_NOTICE,"log msg: %s",message);
-}
-
-int ops_max_msg(void *opdata, ConnContext *context) {
- return OTR_MAX_MSG_SIZE;
-}
-
-void ops_up_ctx_list(void *opdata) {
- statusbar_items_redraw("otr");
-}
-
-void ops_writefps(void *data) {
- otr_writefps();
-}
-
/*
* init otr lib.
*/
-int otrlib_init() {
+int otrlib_init()
+{
if (!otrinited) {
OTRL_INIT;
@@ -276,95 +43,75 @@ int otrlib_init() {
key_load();
fps_load();
- //otrl_privkey_generate(otr_state,"/tmp/somekey","jesus at somewhere.com","proto");
-
- /* set otr ops */
- memset(&otr_ops,0,sizeof(otr_ops));
-
- otr_ops.policy = ops_policy;
- otr_ops.create_privkey = ops_create_privkey;
- otr_ops.inject_message = ops_inject_msg;
- otr_ops.notify = ops_notify;
- otr_ops.display_otr_message = ops_display_msg;
- otr_ops.gone_secure = ops_secure;
- otr_ops.gone_insecure = ops_insecure;
- otr_ops.still_secure = ops_still_secure;
- otr_ops.log_message = ops_log;
- otr_ops.max_message_size = ops_max_msg;
- otr_ops.update_context_list = ops_up_ctx_list;
- otr_ops.write_fingerprints = ops_writefps;
+ otr_initops();
+
return otr_state==NULL;
}
-void otrlib_deinit() {
+/*
+ * deinit otr lib.
+ */
+void otrlib_deinit()
+{
if (otr_state) {
otr_writefps();
otrl_userstate_free(otr_state);
otr_state = NULL;
}
- if (kg_st.status==KEYGEN_RUNNING)
- g_source_remove(kg_st.eid);
+
+ keygen_abort();
}
/*
- * load private keys.
+ * Free our app data.
*/
-void key_load() {
- gcry_error_t err;
- char *filename = g_strconcat(get_irssi_dir(),KEYFILE,NULL);
-
- if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
- otr_logst(LVL_NOTICE,"no private keys found");
- return;
- }
-
- err = otrl_privkey_read(otr_state, filename);
-
- if (err == GPG_ERR_NO_ERROR) {
- otr_logst(LVL_NOTICE,"private keys loaded");
- } else {
- otr_logst(LVL_NOTICE,"Error loading private keys: %s (%s)",
- gcry_strerror(err),
- gcry_strsource(err));
+void context_free_app_info(void *data)
+{
+ struct co_info *coi = data;
+ if (coi->msgqueue) {
+ g_free(coi->msgqueue);
}
- g_free(filename);
}
/*
- * load fingerprints.
+ * Add app data to context.
+ * See struct co_info for details.
*/
-void fps_load() {
- gcry_error_t err;
- char *filename = g_strconcat(get_irssi_dir(),FPSFILE,NULL);
-
- if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
- otr_logst(LVL_NOTICE,"no fingerprints found");
- return;
- }
+void context_add_app_info(void *data,ConnContext *co)
+{
+ SERVER_REC *server = data;
+ struct co_info *coi = g_malloc(sizeof(struct co_info));
- err = otrl_privkey_read_fingerprints(otr_state,filename,NULL,NULL);
+ memset(coi,0,sizeof(struct co_info));
+ co->app_data = coi;
+ co->app_data_free = context_free_app_info;
- if (err == GPG_ERR_NO_ERROR) {
- otr_logst(LVL_NOTICE,"fingerprints loaded");
- } else {
- otr_logst(LVL_NOTICE,"Error loading fingerprints: %s (%s)",
- gcry_strerror(err),
- gcry_strsource(err));
- }
- g_free(filename);
+ coi->server = server;
+ sprintf(coi->better_msg_two,formats[TXT_OTR_BETTER_TWO].def,co->accountname);
}
-ConnContext *otr_getcontext(const char *accname,const char *nick,int create) {
- return otrl_context_find(
+/*
+ * Get a context from a pair.
+ */
+ConnContext *otr_getcontext(const char *accname,const char *nick,
+ int create,void *data)
+{
+ ConnContext *co = otrl_context_find(
otr_state,
nick,
accname,
PROTOCOLID,
create,
NULL,
- NULL,
- NULL);
+ context_add_app_info,
+ data);
+
+ /* context came from a fingerprint */
+ if (co&&data&&!co->app_data)
+ context_add_app_info(data,co);
+
+ return co;
}
/*
@@ -393,11 +140,11 @@ char *otr_send(SERVER_REC *server, const char *msg,const char *to)
msg,
NULL,
&newmessage,
- NULL,
- NULL);
+ context_add_app_info,
+ server);
if (err != 0) {
- otr_logst(LVL_NOTICE,"send failed: acc=%s to=%s msg=%s",accname,to,msg);
+ otr_notice(server,to,TXT_SEND_FAILED,msg);
return NULL;
}
@@ -406,8 +153,8 @@ char *otr_send(SERVER_REC *server, const char *msg,const char *to)
/* OTR message. Need to do fragmentation */
- if (!(co = otr_getcontext(accname,to,FALSE))) {
- otr_logst(LVL_NOTICE,"couldn't find context: acc=%s to=%s",accname,to);
+ if (!(co = otr_getcontext(accname,to,FALSE,server))) {
+ otr_notice(server,to,TXT_SEND_CHANGE);
return NULL;
}
@@ -420,52 +167,176 @@ char *otr_send(SERVER_REC *server, const char *msg,const char *to)
NULL);
if (err != 0) {
- otr_logst(LVL_NOTICE,"failed to fragment message: msg=%s",msg);
+ otr_notice(server,to,TXT_SEND_FRAGMENT,msg);
} else
- otr_log(server,accname,to,LVL_DEBUG,"OTR converted sent message to %s",newmessage);
+ otr_debug(server,to,TXT_SEND_CONVERTED,newmessage);
return NULL;
}
-char *otr_getstatus(char *mynick, char *nick, char *server) {
+/*
+ * Get the OTR status of this conversation.
+ * This wouldn't be half as long if the SMP state machine would work better.
+ */
+int otr_getstatus(char *mynick, char *nick, char *server)
+{
ConnContext *co;
char accname[128];
+ struct co_info *coi;
sprintf(accname, "%s@%s", mynick, server);
- if (!(co = otr_getcontext(accname,nick,FALSE))) {
- //otr_logst(LVL_NOTICE,"couldn't find context: acc=%s to=%s",accname,nick);
- return NULL;
+ if (!(co = otr_getcontext(accname,nick,FALSE,NULL))) {
+ return 0;
}
+ coi = co->app_data;
+
switch (co->msgstate) {
- case OTRL_MSGSTATE_PLAINTEXT:
- return "plaintext";
- case OTRL_MSGSTATE_ENCRYPTED:
- {
- char *trust = co->active_fingerprint->trust;
- return trust&&*trust!='\0' ? trust : "encrypted";
- }
- case OTRL_MSGSTATE_FINISHED:
- return "finished";
+ case OTRL_MSGSTATE_PLAINTEXT:
+ return TXT_ST_PLAINTEXT;
+ case OTRL_MSGSTATE_ENCRYPTED: {
+ char *trust = co->active_fingerprint->trust;
+ int ex = co->smstate->nextExpected;
+
+ if (trust&&(*trust!='\0'))
+ return strcmp(trust,"smp")==0 ? TXT_ST_TRUST_SMP : TXT_ST_TRUST_MANUAL;
+
+ switch (ex) {
+ case OTRL_SMP_EXPECT1:
+ return TXT_ST_UNTRUSTED;
+ case OTRL_SMP_EXPECT2:
+ if (!coi->received_smp_reply)
+ return TXT_ST_SMP_WAIT_2;
+ else
+ return TXT_ST_SMP_HAVE_2;
+ case OTRL_SMP_EXPECT3:
+ /* unfortunately, this also covers the case
+ * where authentication failed */
+ return coi->smp_failed ?
+ TXT_ST_SMP_FAILED : TXT_ST_SMP_FINALIZE;
+ case OTRL_SMP_EXPECT4: /* unreachable with libotr 3.1 */
+ return TXT_ST_SMP_FINALIZE;
default:
- return "unknown(BUG)";
+ return TXT_ST_SMP_UNKNOWN;
+ }
+ }
+ case OTRL_MSGSTATE_FINISHED:
+ return TXT_ST_FINISHED;
+ default:
+ return TXT_ST_UNKNOWN;
}
}
-void otr_trust(char *mynick, char *nick, char *server) {
+/*
+ * Trust our peer.
+ */
+void otr_trust(SERVER_REC *server, char *nick)
+{
ConnContext *co;
char accname[128];
- sprintf(accname, "%s@%s", mynick, server);
+ sprintf(accname, "%s@%s", server->nick, server->connrec->address);
- if (!(co = otr_getcontext(accname,nick,FALSE))) {
- otr_logst(LVL_NOTICE,"couldn't find context: acc=%s nick=%s",accname,nick);
+ if (!(co = otr_getcontext(accname,nick,FALSE,NULL))) {
+ otr_noticest(TXT_CTX_NOT_FOUND,
+ accname,nick);
return;
}
- otrl_context_set_trust(co->active_fingerprint,"trusted");
- otr_logst(LVL_NOTICE,"trusting fingerprint from %s",accname);
+ otrl_context_set_trust(co->active_fingerprint,"manual");
+
+ otr_notice(server,nick,TXT_FP_TRUST,accname);
+}
+
+/*
+ * Abort any ongoing SMP authentication.
+ */
+void otr_abort_auth(ConnContext *co, SERVER_REC *server, const char *nick)
+{
+ struct co_info *coi;
+
+ coi = co->app_data;
+
+ coi->received_smp_reply = FALSE;
+ coi->received_smp_init = FALSE;
+ coi->smp_failed = FALSE;
+
+ otrl_message_abort_smp(otr_state,&otr_ops,NULL,co);
+
+ otr_notice(server,nick,
+ co->smstate->nextExpected!=OTRL_SMP_EXPECT1 ?
+ TXT_AUTH_ABORTED_ONGOING :
+ TXT_AUTH_ABORTED);
+}
+
+/*
+ * implements /otr authabort
+ */
+void otr_authabort(SERVER_REC *server, char *nick)
+{
+ ConnContext *co;
+ char accname[128];
+
+ sprintf(accname, "%s@%s", server->nick, server->connrec->address);
+
+ if (!(co = otr_getcontext(accname,nick,FALSE,NULL))) {
+ otr_noticest(TXT_CTX_NOT_FOUND,
+ accname,nick);
+ return;
+ }
+
+ otr_abort_auth(co,server,nick);
+}
+
+/*
+ * Initiate or respond to SMP authentication.
+ */
+void otr_auth(SERVER_REC *server, char *nick, const char *secret)
+{
+ ConnContext *co;
+ char accname[128];
+ struct co_info *coi;
+
+ sprintf(accname, "%s@%s", server->nick, server->connrec->address);
+
+ if (!(co = otr_getcontext(accname,nick,FALSE,NULL))) {
+ otr_noticest(TXT_CTX_NOT_FOUND,
+ accname,nick);
+ return;
+ }
+
+ coi = co->app_data;
+
+ /* Aborting an ongoing auth */
+ if (co->smstate->nextExpected!=OTRL_SMP_EXPECT1)
+ otr_abort_auth(co,server,nick);
+
+ /* reset trust level */
+ otrl_context_set_trust(co->active_fingerprint, "");
+ otr_writefps();
+
+ if (!coi->received_smp_init)
+ otrl_message_initiate_smp(
+ otr_state,
+ &otr_ops,
+ NULL,
+ co,
+ (unsigned char*)secret,
+ strlen(secret));
+ else
+ otrl_message_respond_smp(
+ otr_state,
+ &otr_ops,
+ NULL,
+ co,
+ (unsigned char*)secret,
+ strlen(secret));
+
+ otr_notice(server,nick,coi->received_smp_init ?
+ TXT_AUTH_RESPONDING :
+ TXT_AUTH_INITIATED);
+ statusbar_items_redraw("otr");
}
/*
@@ -477,37 +348,61 @@ char *otr_receive(SERVER_REC *server, const char *msg,const char *from)
{
int ignore_message;
char *newmessage = NULL;
- const char *nick = server->nick;
- const char *address = server->connrec->address;
char accname[256];
char *lastmsg;
ConnContext *co;
+ struct co_info *coi;
+ OtrlTLV *tlvs;
- sprintf(accname, "%s@%s", nick, address);
+ sprintf(accname, "%s@%s", server->nick, server->connrec->address);
- if (!(co = otr_getcontext(accname,from,TRUE))) {
- otr_logst(LVL_NOTICE,"couldn't create/find context: acc=%s from=%s",accname,from);
+ if (!(co = otr_getcontext(accname,from,TRUE,server))) {
+ otr_noticest(TXT_CTX_NOT_CREATE,
+ accname,from);
+ return NULL;
+ }
+
+ coi = co->app_data;
+
+ /* Really lame but I don't see how you could do this in a generic
+ * way unless the IRC server would somehow marks continuation messages.
+ */
+ if ((strcmp(msg,coi->better_msg_two)==0)||
+ (strcmp(msg,formats[TXT_OTR_BETTER_THREE].def)==0)) {
+ otr_debug(server,from,TXT_RECEIVE_IGNORE_QUERY);
return NULL;
}
/* The server might have split lines that were too long
* (bitlbee does that). The heuristic is simple: If we can find ?OTR:
* in the message but it doesn't end with a ".", queue it and wait
- * for the rest. This works if there are only two fragments which
- * (fortunately) seems to be the maximum.
+ * for the rest.
*/
lastmsg = co->app_data;
- if (lastmsg) {
- strcpy(lastmsg+strlen(lastmsg),msg);
- otr_log(server,accname,from,LVL_DEBUG,"dequeued");
- msg = lastmsg;
- co->app_data = NULL;
- } else if (strstr(msg,"?OTR:")&&(strlen(msg)>OTR_MAX_MSG_SIZE)&&msg[strlen(msg)-1]!='.') {
- co->app_data = malloc(1024*sizeof(char));
- strcpy(co->app_data,msg);
- co->app_data_free = g_free;
- otr_log(server,accname,from,LVL_DEBUG,"queued");
+ if (coi->msgqueue) { /* already something in the queue */
+ strcpy(coi->msgqueue+strlen(coi->msgqueue),msg);
+
+ /* wait for more? */
+ if ((strlen(msg)>OTR_MAX_MSG_SIZE)&&msg[strlen(msg)-1]!='.')
+ return NULL;
+
+ otr_debug(server,from,TXT_RECEIVE_DEQUEUED,
+ strlen(coi->msgqueue));
+
+ msg = coi->msgqueue;
+ coi->msgqueue = NULL;
+
+ /* this is freed thru our caller by otrl_message_free.
+ * Currently ok since that just uses free().
+ */
+
+ } else if (strstr(msg,"?OTR:")&&
+ (strlen(msg)>OTR_MAX_MSG_SIZE)&&
+ msg[strlen(msg)-1]!='.') {
+ coi->msgqueue = malloc(4096*sizeof(char));
+ strcpy(coi->msgqueue,msg);
+ otr_debug(server,from,TXT_RECEIVE_QUEUED,strlen(msg));
return NULL;
}
@@ -520,17 +415,75 @@ char *otr_receive(SERVER_REC *server, const char *msg,const char *from)
from,
msg,
&newmessage,
- NULL,
+ &tlvs,
NULL,
NULL);
+ if (tlvs) {
+ OtrlTLV *tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1);
+ int abort = FALSE;
+ if (tlv) {
+ if (co->smstate->nextExpected != OTRL_SMP_EXPECT1) {
+ otr_notice(server,from,TXT_AUTH_HAVE_OLD,
+ accname);
+ abort = TRUE;
+ } else {
+ otr_notice(server,from,TXT_AUTH_PEER,
+ accname);
+ coi->received_smp_init = TRUE;
+ }
+ } else
+ coi->received_smp_init = FALSE;
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP2);
+ if (tlv) {
+ if (co->smstate->nextExpected != OTRL_SMP_EXPECT2) {
+ otr_notice(server,from,
+ TXT_AUTH_PEER_REPLY_WRONG,
+ accname);
+ abort = TRUE;
+ } else {
+ otr_notice(server,from,
+ TXT_AUTH_PEER_REPLIED,
+ accname);
+ coi->received_smp_reply = TRUE;
+ }
+ } else
+ coi->received_smp_reply = FALSE;
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP3);
+ if (tlv) {
+ if (co->smstate->nextExpected != OTRL_SMP_EXPECT3) {
+ otr_notice(server,from,TXT_AUTH_PEER_WRONG_SMP3,accname);
+ abort = TRUE;
+ } else {
+ char *trust = co->active_fingerprint->trust;
+ if (trust&&(*trust!='\0'))
+ otr_notice(server,from,
+ TXT_AUTH_SUCCESSFUL,
+ accname);
+ else {
+ otr_notice(server,from,
+ TXT_AUTH_FAILED,
+ accname);
+ coi->smp_failed = TRUE;
+ }
+ }
+ } else
+ coi->smp_failed = FALSE;
+
+ if (abort)
+ otr_abort_auth(co,server,from);
+
+ statusbar_items_redraw("otr");
+ }
+
if (ignore_message) {
- otr_log(server,accname,from,LVL_DEBUG,"ignoring protocol message of length %zd, acc=%s, from=%s", strlen(msg),accname,from);
+ otr_debug(server,from,
+ TXT_RECEIVE_IGNORE, strlen(msg),accname,from);
return NULL;
}
if (newmessage)
- otr_log(server,accname,from,LVL_DEBUG,"OTR converted received message");
+ otr_notice(server,from,TXT_RECEIVE_CONVERTED);
return newmessage ? : (char*)msg;
}
diff --git a/otrutil.h b/otrutil.h
deleted file mode 100644
index 42afb99..0000000
--- a/otrutil.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- Off-the-Record Messaging (OTR) module for the irssi IRC client
- Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
-
- 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
-*/
-
-
-/*
- * maybe this should be configurable?
- * I believe bitlbee has something >500.
- */
-#define OTR_MAX_MSG_SIZE 400
-
-/* otr protocol id */
-#define PROTOCOLID "IRC"
-
-#define KEYFILE "/otr/otr.key"
-#define FPSFILE "/otr/otr.fp"
-
-int otrlib_init();
-void otrlib_deinit();
-void key_load();
-void fps_load();
-char *otr_send(SERVER_REC *server,const char *msg,const char *to);
-char *otr_receive(SERVER_REC *server,const char *msg,const char *from);
-void keygen_run(const char *accname);
-char *otr_getstatus(char *mynick, char *nick, char *server);
-void otr_trust(char *mynick, char *nick, char *server);
diff --git a/ui.c b/ui.c
index aa9d389..7a3e78f 100644
--- a/ui.c
+++ b/ui.c
@@ -1,40 +1,39 @@
/*
- Off-the-Record Messaging (OTR) module for the irssi IRC client
- Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
-
- 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
-*/
+ * Off-the-Record Messaging (OTR) module for the irssi IRC client
+ * Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
+ *
+ * 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 "otr.h"
char *lvlstring[] = {
- "NOTICE",
- "DEBUG"
+ "NOTICE",
+ "DEBUG"
};
-extern int debug;
-void otr_log(SERVER_REC *server, const char *accname, const char *nick,
- int level, const char *format, ...) {
- va_list params;
- va_start( params, format );
- char msg[LOGMAX], *s = msg;
+void otr_log(SERVER_REC *server, const char *nick,
+ int level, const char *format, ...) {
+ va_list params;
+ va_start( params, format );
+ char msg[LOGMAX], *s = msg;
if ((level==LVL_DEBUG)&&!debug)
return;
-
+
s += sprintf(s,"%s","%9OTR%9");
if (level!=LVL_NOTICE)
@@ -42,9 +41,9 @@ void otr_log(SERVER_REC *server, const char *accname, const char *nick,
s += sprintf(s,": ");
- if( vsnprintf( s, LOGMAX, format, params ) < 0 )
- sprintf( s, "internal error parsing error string (BUG)" );
- va_end( params );
+ if( vsnprintf( s, LOGMAX, format, params ) < 0 )
+ sprintf( s, "internal error parsing error string (BUG)" );
+ va_end( params );
printtext(server, nick, MSGLEVEL_CRAP, msg);
}
diff --git a/ui.h b/ui.h
deleted file mode 100644
index 09cd037..0000000
--- a/ui.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- Off-the-Record Messaging (OTR) module for the irssi IRC client
- Copyright (C) 2008 Uli Meis <a.sporto+bee at gmail.com>
-
- 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
-*/
-
-#define LOGMAX 1024
-
-#define LVL_NOTICE 0
-#define LVL_DEBUG 1
-
-#define otr_logst(level,format,...) otr_log(NULL,NULL,NULL,level,format, \
- ## __VA_ARGS__)
-
-void otr_log(SERVER_REC *server, const char *accname, const char *to,
- int level, const char *format, ...);
--
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