Commit c276bfa7 authored by Rob Smits's avatar Rob Smits
Browse files

2012-04-30

	* gtk-dialog.c:
	* gtk-ui.c:
	* otr-plugin.c:
	* otr-plugin.h:
	* ui.c: More changes for instance tags. Some logging-
	related changes too (output whether pidgin is logging,
	change default not to log otr conversations). -- Rob
	Smits

2009-06-11

	* gtk-dialog.c:
	* otr-plugin.c:
	* otr-plugin.h: Initial instance tags implementation
	from Lisa Du
parent 1a7b6e27
......@@ -2,7 +2,7 @@ Off-the-Record Messaging plugin for pidgin
Authors:
Ian Goldberg, Rob Smits, Chris Alexander, Willy Lew, Nikita Borisov
Ian Goldberg, Rob Smits, Chris Alexander, Willy Lew, Lisa Du, Nikita Borisov
<otr@cypherpunks.ca>
See the README file for mailing list information
2012-04-30
* gtk-dialog.c:
* gtk-ui.c:
* otr-plugin.c:
* otr-plugin.h:
* ui.c: More changes for instance tags. Some logging-
related changes too (output whether pidgin is logging,
change default not to log otr conversations). -- Rob
Smits
2010-03-02
* po/vi.po: Vietnamese translation from Lyndon Johnson
......@@ -9,6 +20,13 @@
the fingerprints in the manual authentication dialog
selectable (but not selected by default).
2009-06-11
* gtk-dialog.c:
* otr-plugin.c:
* otr-plugin.h: Initial instance tags implementation
from Lisa Du
2009-08-24
* po/fr.po: Fixed \n errors
......
......@@ -51,6 +51,8 @@ Use the provided Makefile.mingw:
make -f Makefile.mingw
See Makefile.mingw.notes for a few hints.
INSTALLATION
You should be able to simply do "make install". If you want to install
......
WIN32=1
# The version number to put in the plugin info
PIDGIN_OTR_VERSION = 3.2.0
PIDGIN_OTR_VERSION = 4.0.0
# Name of the gettext domain
GETTEXT_PACKAGE = pidgin-otr
# Replace this with the path to the pidgin and purple headers
PIDGIN_HEADERS ?= /usr/i586-mingw32msvc/include/pidgin
PURPLE_HEADERS ?= /usr/i586-mingw32msvc/include/libpurple
PIDGIN_HEADERS ?= -I/usr/i586-mingw32msvc/include/pidgin \
-I/usr/i586-mingw32msvc/include/pidgin/win32
PURPLE_HEADERS ?= -I/usr/i586-mingw32msvc/include/libpurple \
-I/usr/i586-mingw32msvc/include/libpurple/win32
# If you don't have pkg-config, put the appropriate -I entry on the next line
# Replace this with the path to the extracted GTK+ "all-in-one" win32 bundle
GTK_WIN32_BUNDLE ?= /usr/i586-mingw32msvc/misc/gtk_bundle
# Replace this with the to path DLL files from a Win32 Pidgin distributable
# (i.e. pidgin.dll and libpurple.dll)
PIDGIN_WIN32_LIBS ?= /usr/i586-mingw32msvc/misc/pidgin_dlls
# If you don't have pkg-config, uncomment the -I lines below
GTK_HDRS ?= `pkg-config --cflags glib-2.0 gtk+-2.0`
#GTK_HDRS ?= -I$(GTK_WIN32_BUNDLE)/include/gtk-2.0 \
# -I$(GTK_WIN32_BUNDLE)/include/glib-2.0 \
# -I$(GTK_WIN32_BUNDLE)/include/cairo \
# -I$(GTK_WIN32_BUNDLE)/include/pango-1.0 \
# -I$(GTK_WIN32_BUNDLE)/include/atk-1.0 \
# -I$(GTK_WIN32_BUNDLE)/include/gdk-pixbuf-2.0 \
# -I$(GTK_WIN32_BUNDLE)/lib/glib-2.0/include \
# -I$(GTK_WIN32_BUNDLE)/lib/gtk-2.0/include
# The location of the libotr include files. Note that if, for example,
# the full path of message.h is /usr/include/libotr/message.h, you
......@@ -41,12 +59,13 @@ ZIPFILE = pidgin-otr-$(PIDGIN_OTR_VERSION).zip
CC = i586-mingw32msvc-gcc
LDFLAGS = -Wl,--enable-auto-image-base
LDLIBS = $(LIBOTRLIBDIR)/libotr.a -lgtk-win32-2.0 -lglib-2.0 -lgdk_pixbuf-2.0 \
-lgobject-2.0 -lpidgin -llibpurple -lgcrypt -lgpg-error \
-L$(LIBINTLLIBDIR) -lintl
LDLIBS = $(LIBOTRLIBDIR)/libotr.a -L$(GTK_WIN32_BUNDLE)/lib \
-L$(PIDGIN_WIN32_LIBS) -lgtk-win32-2.0 -lglib-2.0 \
-lgdk_pixbuf-2.0 -lgobject-2.0 -lpidgin -llibpurple \
-lgcrypt -lgpg-error -L$(LIBINTLLIBDIR) -lintl
CC ?= gcc
override CFLAGS += -g -O2 -Wall -I$(PIDGIN_HEADERS) -I$(PURPLE_HEADERS) \
override CFLAGS += -g -O2 -Wall $(PIDGIN_HEADERS) $(PURPLE_HEADERS) \
$(GTK_HDRS) -I$(LIBOTRINCDIR) $(FPIC) -DUSING_GTK -DPURPLE_PLUGINS \
-DPIDGIN_OTR_VERSION=\"$(PIDGIN_OTR_VERSION)\" \
-DPIDGIN_NAME=\"Pidgin\" -I$(LIBINTLINCDIR) -DENABLE_NLS \
......@@ -66,8 +85,8 @@ clean:
distclean: clean
$(MAKE) -C po -f Makefile.mingw distclean
## Package up all the pieces needed to build the installer
zip: all
## Prepare the win32_export directory
prepare_win32_export: all
mkdir win32_export
# Copy pieces over from the libotr source dir
for f in otr_mackey.exe otr_parse.exe otr_remac.exe otr_modify.exe \
......@@ -90,8 +109,16 @@ zip: all
i586-mingw32msvc-strip *.exe *.dll; \
perl -pi -e 's/$$/\r/' README.Toolkit.txt Protocol-v2.html \
COPYING.txt COPYING.LIB.txt README.txt; \
installer: prepare_win32_export
makensis packaging/windows/pidgin-otr-rob.nsi
rm -rf win32_export
## Package up all the pieces needed to build the installer
zip: prepare_win32_export
rm -f ../$(ZIPFILE); \
zip -r ../$(ZIPFILE) README.txt \
README.Toolkit.txt Protocol-v2.html COPYING.txt \
COPYING.LIB.txt *.exe *.dll *.nsi locale
rm -rf win32_export
Here are some rough notes that might help you create a pidgin-otr Win32 build on
a Linux system with mingw32. These have been tested on Ubuntu 11.04.
I am listing packages and their build instructions in the order they should be
built. Good luck!
libgpg-error-1.0:
(before configure)
HOST_CC=gcc
DLLTOOL=i586-mingw32msvc-dlltool
AS=i586-mingw32msvc-as
export HOST_CC DLLTOOL AS
./configure --with-pic --build=`./config.guess` --host=i586-mingw32msvc --prefix=/usr/i586-mingw32msvc
make
sudo make install
gcrypt-1.2.1:
w32root=i586-mingw32msvc ./autogen.sh --build-w32
Then append #undef HAVE_GETTIMEOFDAY to libgcrypt config.h
Apply windows slow random fix (patch on otr website, listed as "Note that if you're compiling from source on win32...")
make
sudo make install
libotr:
./configure --with-pic --build=`./config.guess` --host=i586-mingw32msvc --prefix=/usr/i586-mingw32msvc --with-libgcrypt-prefix=/usr/i586-mingw32msvc
make
sudo make install
pidgin-otr:
You will need: Pidgin source code distributable, Pidgin Win32 distributable, and an "all-in-one bundle" of the GTK+ stack 2.14.7 or greater (e.g., gtk+-bundle_2.24.10-20120208_win32.zip).
In Makefile.mingw, specify the location of PIDGIN_HEADERS, PURPLE_HEADERS, GTK_WIN32_BUNDLE, and PIDGIN_WIN32_LIBS
Ensure either pkg-config will correctly resolve all the dependencies for glib-2.0 and gtk+-2.0 (there is a README in the GTK+ bundle about this), or uncomment (and perhaps revise) the hardcoded list of includes for GTK_HDRS
make -f Makefile.mingw
nsis:
sudo apt-get install nsis
Locate the "nsisunz" plugin (a google search for "nsisunz.zip" should be sufficient)
Extract the DLL to /usr/local/share/nsis/Plugins (yes it's a DLL extension, but it will still work for GNU/Linux nsis)
make -f Makefile.mingw installer <-- This should now build the nsis installer
Off-the-Record Messaging plugin for pidgin
v3.2.0, 15 Jun 2008
v4.0.0, 2012
This is a pidgin plugin which implements Off-the-Record (OTR) Messaging.
It is known to work (at least) under the Linux and Windows versions of
......@@ -300,9 +300,9 @@ The Off-the-Record Messaging plugin for pidgin is covered by the following
(GPL) license:
Off-the-Record Messaging plugin for pidgin
Copyright (C) 2004-2009 Ian Goldberg, Rob Smits,
Copyright (C) 2004-2012 Ian Goldberg, Rob Smits,
Chris Alexander, Willy Lew,
Nikita Borisov
Lisa Du, Nikita Borisov
<otr@cypherpunks.ca>
......@@ -325,7 +325,7 @@ CONTACT
To report problems, comments, suggestions, patches, etc., you can email
the authors:
Ian Goldberg, Rob Smits, Chris Alexander, and Nikita Borisov
Ian Goldberg, Rob Smits, Chris Alexander, Willy Lew, Lisa Du, Nikita Borisov
<otr@cypherpunks.ca>
For more information on Off-the-Record Messaging, visit
......
/*
* Off-the-Record Messaging plugin for pidgin
* Copyright (C) 2004-2009 Ian Goldberg, Rob Smits,
* Copyright (C) 2004-2012 Ian Goldberg, Rob Smits,
* Chris Alexander, Willy Lew,
* Nikita Borisov
* <otr@cypherpunks.ca>
......@@ -109,7 +109,7 @@ int otrg_dialog_display_otr_message( const char *accountname,
int force_create)
{
return ui_ops->display_otr_message(accountname, protocol, username, msg,
force_create);
force_create);
}
/* Put up a Please Wait dialog. This dialog can not be cancelled.
......
/*
* Off-the-Record Messaging plugin for pidgin
* Copyright (C) 2004-2009 Ian Goldberg, Rob Smits,
* Copyright (C) 2004-2012 Ian Goldberg, Rob Smits,
* Chris Alexander, Willy Lew,
* Nikita Borisov
* <otr@cypherpunks.ca>
......
/*
* Off-the-Record Messaging plugin for pidgin
* Copyright (C) 2004-2009 Ian Goldberg, Rob Smits,
* Copyright (C) 2004-2012 Ian Goldberg, Rob Smits,
* Chris Alexander, Willy Lew,
* Nikita Borisov
* Lisa Du, Nikita Borisov
* <otr@cypherpunks.ca>
*
* This program is free software; you can redistribute it and/or modify
......@@ -56,6 +56,7 @@
#include <libotr/proto.h>
#include <libotr/message.h>
#include <libotr/userstate.h>
#include <libotr/instag.h>
/* purple-otr headers */
#include "otr-plugin.h"
......@@ -75,11 +76,13 @@ static int img_id_finished = 0;
typedef struct {
ConnContext *context; /* The context used to fire library code */
GtkEntry* question_entry; /* The text entry field containing the user question */
GtkEntry* question_entry; /* The text entry field containing the user
* question */
GtkEntry *entry; /* The text entry field containing the secret */
int smp_type; /* Whether the SMP type is based on question challenge (0) or shared secret (1) */
int smp_type; /* Whether the SMP type is based on question
* challenge (0) or shared secret (1) */
gboolean responder; /* Whether or not this is the first side to give
their secret */
* their secret */
} SmpResponsePair;
/* Information used by the plugin that is specific to both the
......@@ -90,6 +93,7 @@ typedef struct dialog_context_data {
GtkWidget *smp_progress_dialog;
GtkWidget *smp_progress_bar;
GtkWidget *smp_progress_label;
otrl_instag_t their_instance;
} SMPData;
typedef struct {
......@@ -99,6 +103,39 @@ typedef struct {
GtkWidget *notebook;
} AuthSignalData;
typedef struct {
enum {
convctx_none,
convctx_conv,
convctx_ctx
} convctx_type;
PurpleConversation *conv;
ConnContext *context;
} ConvOrContext;
gint get_new_instance_index(PurpleConversation *conv) {
gint max_index = (gint) purple_conversation_get_data(conv, "otr-max_idx");
max_index++;
purple_conversation_set_data(conv, "otr-max_idx", (gpointer) max_index);
return max_index;
}
gint get_context_instance_to_index(PurpleConversation *conv,
ConnContext *context) {
GHashTable * conv_to_idx_map =
purple_conversation_get_data(conv, "otr-conv_to_idx");
gint index = 0;
gpointer key = NULL;
if (!g_hash_table_lookup_extended(conv_to_idx_map, context, &key,
(void**)&index)) {
index = get_new_instance_index(conv);
g_hash_table_replace(conv_to_idx_map, context, (gpointer)index);
}
return index;
}
static void close_progress_window(SMPData *smp_data)
{
if (smp_data->smp_progress_dialog) {
......@@ -137,6 +174,9 @@ static void otrg_gtk_dialog_add_smp_data(PurpleConversation *conv)
smp_data->smp_progress_dialog = NULL;
smp_data->smp_progress_bar = NULL;
smp_data->smp_progress_label = NULL;
/* Chosen as initialized value since libotr should never allow
* this as a "their_instance" value */
smp_data->their_instance = OTRL_INSTAG_BEST;
purple_conversation_set_data(conv, "otr-smpdata", smp_data);
}
......@@ -180,7 +220,8 @@ static void message_response_cb(GtkDialog *dialog, gint id, GtkWidget *widget)
gtk_widget_destroy(GTK_WIDGET(widget));
}
/* Forward declarations for the benefit of smp_message_response_cb/redraw authvbox */
/* Forward declarations for the benefit of smp_message_response_cb/redraw
* authvbox */
static void verify_fingerprint(GtkWindow *parent, Fingerprint *fprint);
static void add_vrfy_fingerprint(GtkWidget *vbox, void *data);
static struct vrfy_fingerprint_data* vrfy_fingerprint_data_new(
......@@ -198,7 +239,7 @@ static void smp_progress_response_cb(GtkDialog *dialog, gint response,
{
PurpleConversation *conv = otrg_plugin_context_to_conv(context, 0);
SMPData *smp_data = NULL;
if (conv) {
gdouble frac;
......@@ -235,58 +276,58 @@ static void smp_secret_response_cb(GtkDialog *dialog, gint response,
SmpResponsePair *smppair;
if (!auth_opt_data) return;
smppair = auth_opt_data->smppair;
if (!smppair) return;
context = smppair->context;
if (response == GTK_RESPONSE_ACCEPT && smppair->entry) {
GtkEntry* entry = smppair->entry;
char *secret;
size_t secret_len;
GtkEntry* question_entry = smppair->question_entry;
const char *user_question = NULL;
if (context == NULL || context->msgstate != OTRL_MSGSTATE_ENCRYPTED) {
return;
}
secret = g_strdup(gtk_entry_get_text(entry));
secret_len = strlen(secret);
if (smppair->responder) {
otrg_plugin_continue_smp(context, (const unsigned char *)secret,
secret_len);
} else {
if (smppair->smp_type == 0) {
if (!question_entry) {
return;
}
user_question = gtk_entry_get_text(question_entry);
if (user_question == NULL || strlen(user_question) == 0) {
return;
}
}
/* pass user question here */
otrg_plugin_start_smp(context, user_question,
(const unsigned char *)secret, secret_len);
}
g_free(secret);
/* launch progress bar window */
create_smp_progress_dialog(GTK_WINDOW(dialog), context);
GtkEntry* entry = smppair->entry;
char *secret;
size_t secret_len;
GtkEntry* question_entry = smppair->question_entry;
const char *user_question = NULL;
if (context == NULL || context->msgstate != OTRL_MSGSTATE_ENCRYPTED) {
return;
}
secret = g_strdup(gtk_entry_get_text(entry));
secret_len = strlen(secret);
if (smppair->responder) {
otrg_plugin_continue_smp(context, (const unsigned char *)secret,
secret_len);
} else {
if (smppair->smp_type == 0) {
if (!question_entry) {
return;
}
user_question = gtk_entry_get_text(question_entry);
if (user_question == NULL || strlen(user_question) == 0) {
return;
}
}
/* pass user question here */
otrg_plugin_start_smp(context, user_question,
(const unsigned char *)secret, secret_len);
}
g_free(secret);
/* launch progress bar window */
create_smp_progress_dialog(GTK_WINDOW(dialog), context);
} else if (response == GTK_RESPONSE_HELP) {
char *helpurl = g_strdup_printf("%s%s&context=%s",
AUTHENTICATE_HELPURL, _("?lang=en"),
......@@ -307,19 +348,19 @@ static void smp_secret_response_cb(GtkDialog *dialog, gint response,
/* Don't destroy the window */
return;
} else {
otrg_plugin_abort_smp(context);
otrg_plugin_abort_smp(context);
}
/* In all cases except HELP, destroy the current window */
gtk_widget_destroy(GTK_WIDGET(dialog));
/* Clean up references to this window */
conv = otrg_plugin_context_to_conv(smppair->context, 0);
smp_data = purple_conversation_get_data(conv, "otr-smpdata");
if (smp_data) {
smp_data->smp_secret_dialog = NULL;
smp_data->smp_secret_smppair = NULL;
smp_data->smp_secret_dialog = NULL;
smp_data->smp_secret_smppair = NULL;
}
/* Free memory */
......@@ -382,7 +423,7 @@ static GtkWidget *create_dialog(GtkWindow *parent,
gtk_window_set_role(GTK_WINDOW(dialog), "notify_dialog");
g_signal_connect(G_OBJECT(dialog), "response",
G_CALLBACK(message_response_cb), dialog);
G_CALLBACK(message_response_cb), dialog);
gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT,
sensitive);
......@@ -401,10 +442,10 @@ static GtkWidget *create_dialog(GtkWindow *parent,
}
label_text = g_strdup_printf(
"<span weight=\"bold\" size=\"larger\">%s</span>%s%s",
(primary ? primary : ""),
(primary ? "\n\n" : ""),
(secondary ? secondary : ""));
"<span weight=\"bold\" size=\"larger\">%s</span>%s%s",
(primary ? primary : ""),
(primary ? "\n\n" : ""),
(secondary ? secondary : ""));
label = gtk_label_new(NULL);
......@@ -431,19 +472,19 @@ static void add_to_vbox_init_one_way_auth(GtkWidget *vbox,
GtkWidget *entry;
GtkWidget *label;
GtkWidget *label2;
char *label_text;
char *label_text;
SmpResponsePair* smppair = auth_opt_data->smppair;
if (smppair->responder) {
label_text = g_strdup_printf("<small><i>\n%s\n</i></small>",
label_text = g_strdup_printf("<small><i>\n%s\n</i></small>",
_("Your buddy is attempting to determine if he or she is really "
"talking to you, or if it's someone pretending to be you. "
"Your buddy has asked a question, indicated below. "
"To authenticate to your buddy, enter the answer and "
"click OK."));
} else {
label_text = g_strdup_printf("<small><i>\n%s\n</i></small>",
label_text = g_strdup_printf("<small><i>\n%s\n</i></small>",
_("To authenticate using a question, pick a question whose "
"answer is known only to you and your buddy. Enter this "
"question and this answer, then wait for your buddy to "
......@@ -459,57 +500,58 @@ static void add_to_vbox_init_one_way_auth(GtkWidget *vbox,
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
if (smppair->responder) {
label_text = g_strdup_printf(_("This is the question asked by "
"your buddy:"));
label_text = g_strdup_printf(_("This is the question asked by "
"your buddy:"));
} else {
label_text = g_strdup_printf(_("Enter question here:"));
label_text = g_strdup_printf(_("Enter question here:"));
}
label = gtk_label_new(label_text);
gtk_label_set_selectable(GTK_LABEL(label), FALSE);
g_free(label_text);
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
if (smppair->responder && question) {
label_text = g_markup_printf_escaped("<span background=\"white\" foreground=\"black\" weight=\"bold\">%s</span>", question);
label = gtk_label_new(NULL);
gtk_label_set_markup (GTK_LABEL(label), label_text);
gtk_label_set_selectable(GTK_LABEL(label), FALSE);
g_free(label_text);
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
smppair->question_entry = NULL;
label_text = g_markup_printf_escaped("<span background=\"white\" "
"foreground=\"black\" weight=\"bold\">%s</span>", question);
label = gtk_label_new(NULL);
gtk_label_set_markup (GTK_LABEL(label), label_text);
gtk_label_set_selectable(GTK_LABEL(label), FALSE);
g_free(label_text);
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
smppair->question_entry = NULL;
} else {
/* Create the text view where the user enters their question */
question_entry = gtk_entry_new ();
smppair->question_entry = GTK_ENTRY(question_entry);
gtk_box_pack_start(GTK_BOX(vbox), question_entry, FALSE, FALSE, 0);
/* Create the text view where the user enters their question */
question_entry = gtk_entry_new ();
smppair->question_entry = GTK_ENTRY(question_entry);
gtk_box_pack_start(GTK_BOX(vbox), question_entry, FALSE, FALSE, 0);
}
if (context->active_fingerprint->trust &&
context->active_fingerprint->trust[0] && !(smppair->responder)) {
label2 = gtk_label_new(_("This buddy is already authenticated."));
context->active_fingerprint->trust[0] && !(smppair->responder)) {
label2 = gtk_label_new(_("This buddy is already authenticated."));
} else {
label2 = NULL;
label2 = NULL;
}
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
/* Leave a blank line */
gtk_box_pack_start(GTK_BOX(vbox), gtk_label_new(NULL), FALSE,
FALSE, 0);
FALSE, 0);
label_text = g_strdup_printf(_("Enter secret answer here "
"(case sensitive):"));
"(case sensitive):"));
label = gtk_label_new(NULL);
......@@ -529,15 +571,15 @@ static void add_to_vbox_init_one_way_auth(GtkWidget *vbox,
gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
/* Leave a blank line */
gtk_box_pack_start(GTK_BOX(vbox), gtk_label_new(NULL), FALSE,
FALSE, 0);
FALSE, 0);
if (label2) {
gtk_box_pack_start(GTK_BOX(vbox), label2, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), gtk_label_new(NULL), FALSE,
FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), label2, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), gtk_label_new(NULL), FALSE,
FALSE, 0);
}
}
......@@ -546,13 +588,13 @@ static void add_to_vbox_init_two_way_auth(GtkWidget *vbox,
GtkWidget *entry;
GtkWidget *label;
GtkWidget *label2;
char *label_text;
char *label_text;
label_text = g_strdup_printf("<small><i>\n%s\n</i></small>",
_("To authenticate, pick a secret known "