summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am48
-rw-r--r--src/kopete_otr.desktop20
-rw-r--r--src/kopete_otr.kcfg23
-rw-r--r--src/kopete_otr.kcfgc7
-rw-r--r--src/kopete_otr.lsm16
-rw-r--r--src/kopete_otr_config.desktop16
-rw-r--r--src/otrchatui.rc19
-rw-r--r--src/otrguiclient.cpp128
-rw-r--r--src/otrguiclient.h80
-rw-r--r--src/otrlchatinterface.cpp685
-rw-r--r--src/otrlchatinterface.h87
-rw-r--r--src/otrlconfinterface.cpp231
-rw-r--r--src/otrlconfinterface.h66
-rw-r--r--src/otrplugin.cpp344
-rw-r--r--src/otrplugin.h118
-rw-r--r--src/otrpreferences.cpp199
-rw-r--r--src/otrpreferences.h64
-rw-r--r--src/otrprefs.ui295
-rw-r--r--src/otrui.rc12
-rw-r--r--src/pics/Makefile.am4
-rw-r--r--src/pics/cr16-action-otr_disabled.pngbin0 -> 922 bytes
-rw-r--r--src/pics/cr16-action-otr_finished.pngbin0 -> 1165 bytes
-rw-r--r--src/pics/cr16-action-otr_private.pngbin0 -> 749 bytes
-rw-r--r--src/pics/cr16-action-otr_unverified.pngbin0 -> 688 bytes
-rw-r--r--src/pics/cr16-app-kopete_otr.pngbin0 -> 766 bytes
-rw-r--r--src/pics/cr16-app-otr.pngbin0 -> 749 bytes
-rw-r--r--src/pics/cr22-action-otr_disabled.pngbin0 -> 938 bytes
-rw-r--r--src/pics/cr22-action-otr_finished.pngbin0 -> 2083 bytes
-rw-r--r--src/pics/cr22-action-otr_private.pngbin0 -> 3603 bytes
-rw-r--r--src/pics/cr22-action-otr_unverified.pngbin0 -> 881 bytes
-rw-r--r--src/pics/cr32-action-otr_disabled.pngbin0 -> 1623 bytes
-rw-r--r--src/pics/cr32-action-otr_finished.pngbin0 -> 2087 bytes
-rw-r--r--src/pics/cr32-action-otr_private.pngbin0 -> 1582 bytes
-rw-r--r--src/pics/cr32-action-otr_unverified.pngbin0 -> 1417 bytes
-rw-r--r--src/privkeypopup.cpp52
-rw-r--r--src/privkeypopup.h55
-rw-r--r--src/privkeypopupui.ui64
-rw-r--r--src/smppopup.cpp71
-rw-r--r--src/smppopup.h62
-rw-r--r--src/smppopupui.ui191
-rw-r--r--src/verifypopup.cpp69
-rw-r--r--src/verifypopup.h50
-rw-r--r--src/verifypopupui.ui113
43 files changed, 3189 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..f168bd9
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,48 @@
+METASOURCES = AUTO
+
+messages:
+ extractrc `find . -name \*.ui -o -name \*.rc` > rc.cpp
+ $(XGETTEXT) --keyword=i18n *.cpp -o $(top_srcdir)/po/kopete_otr.pot
+
+INCLUDES = $(all_includes) -I$(kde_includes)/kopete -I$(kde_includes)/kopete/ui
+
+kde_module_LTLIBRARIES = kcm_kopete_otr.la kopete_otr.la
+
+kopete_otr_la_SOURCES = kopete_otr.kcfgc otrguiclient.cpp otrplugin.cpp
+
+
+kopete_otr_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries) \
+ -lkopete
+
+kcm_kopete_otr_la_SOURCES = kopete_otr.kcfgc otrpreferences.cpp otrprefs.ui
+
+kcm_kopete_otr_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) \
+ $(all_libraries) -lkopete
+kcm_kopete_otr_la_LIBADD = libkotr.la -lotr $(LIB_KUTILS)
+
+service_DATA = kopete_otr.desktop
+servicedir = $(kde_servicesdir)
+
+kde_kcfg_DATA = kopete_otr.kcfg
+
+kcm_DATA = kopete_otr_config.desktop
+kcmdir = $(kde_servicesdir)/kconfiguredialog
+
+kopete_otr_la_LIBADD = libkotr.la -lotr
+
+noinst_HEADERS = otrguiclient.h otrlchatinterface.h otrlconfinterface.h \
+ otrplugin.h otrpreferences.h otrprefs.h privkeypopup.h smppopup.h verifypopup.h
+
+
+rcdir = $(kde_datadir)/kopete_otr
+rc_DATA = otrchatui.rc otrui.rc
+
+lib_LTLIBRARIES = libkotr.la
+libkotr_la_LDFLAGS = $(all_libraries)
+libkotr_la_SOURCES = otrlchatinterface.cpp otrlconfinterface.cpp \
+ privkeypopup.cpp privkeypopupui.ui smppopup.cpp smppopupui.ui verifypopup.cpp \
+ verifypopupui.ui
+libkotr_la_LIBADD = -lotr
+
+SUBDIRS = pics
+
diff --git a/src/kopete_otr.desktop b/src/kopete_otr.desktop
new file mode 100644
index 0000000..82c6a30
--- /dev/null
+++ b/src/kopete_otr.desktop
@@ -0,0 +1,20 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Service
+X-Kopete-Version=1000900
+Icon=kopete_otr
+ServiceTypes=Kopete/Plugin
+X-KDE-Library=kopete_otr
+X-KDE-PluginInfo-Author=Michael Zanetti
+X-KDE-PluginInfo-Email=michael_zanetti@gmx.net
+X-KDE-PluginInfo-Name=kopete_otr
+X-KDE-PluginInfo-Version=0.7
+X-KDE-PluginInfo-Website=http://kopete-otr.follefuder.org
+X-KDE-PluginInfo-Category=Plugins
+X-KDE-PluginInfo-Depends=
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=false
+Comment=Encrypt chat sessions with Off-The-Record encryption
+Comment[de]=Verschlüsselt Chat-Sitzungen mit Off-The-Record Verschlüsselung
+Name=OTR
+Name[de]=OTR \ No newline at end of file
diff --git a/src/kopete_otr.kcfg b/src/kopete_otr.kcfg
new file mode 100644
index 0000000..1db6935
--- /dev/null
+++ b/src/kopete_otr.kcfg
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE kcfg SYSTEM "http://www.kde.org/standards/kcfg/1.0/kcfg.dtd">
+<kcfg>
+<kcfgfile name="kopete_otr"/>
+ <group name="Policy">
+ <entry name="rbAlways" type="Bool">
+ <label>Always encrypt outgoing messages</label>
+ <default>false</default>
+ </entry>
+ <entry name="rbOpportunistic" type="Bool">
+ <label>Automatically encrypt mesages if the other side supports OTR</label>
+ <default>true</default>
+ </entry>
+ <entry name="rbManual" type="Bool">
+ <label>Encrypt mesages if the other side requests an OTR connection</label>
+ <default>false</default>
+ </entry>
+ <entry name="rbNever" type="Bool">
+ <label>Never encrypt outgoing messages</label>
+ <default>false</default>
+ </entry>
+ </group>
+</kcfg> \ No newline at end of file
diff --git a/src/kopete_otr.kcfgc b/src/kopete_otr.kcfgc
new file mode 100644
index 0000000..71216cf
--- /dev/null
+++ b/src/kopete_otr.kcfgc
@@ -0,0 +1,7 @@
+File=kopete_otr.kcfg
+ClassName=KopeteOtrKcfg
+Singleton=true
+Mutators=true
+MemberVariables=private
+ItemAccessors=true
+GlobalEnums=true
diff --git a/src/kopete_otr.lsm b/src/kopete_otr.lsm
new file mode 100644
index 0000000..2e2aa8f
--- /dev/null
+++ b/src/kopete_otr.lsm
@@ -0,0 +1,16 @@
+Begin3
+Title: kopete-otr -- Some description
+Version: 0.6
+Entered-date:
+Description:
+Keywords: KDE Qt
+Author: Michael Zanetti <michael_zanetti@gmx.net>
+Maintained-by: Michael Zanetti <michael_zanetti@gmx.net>
+Home-page:
+Alternate-site:
+Primary-site: htto://kopete-otr.follefuder.org
+ xxxxxx kopete-otr-0.6.tar.gz
+ xxx kopete_otr-0.6.lsm
+Platform: Linux. Needs KDE
+Copying-policy: GPL
+End
diff --git a/src/kopete_otr_config.desktop b/src/kopete_otr_config.desktop
new file mode 100644
index 0000000..b3ad3ad
--- /dev/null
+++ b/src/kopete_otr_config.desktop
@@ -0,0 +1,16 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Service
+Icon=kopete_otr
+ServiceTypes=KCModule
+
+X-KDE-ModuleType=Library
+X-KDE-Library=kopete_otr
+X-KDE-FactoryName=OTRPreferencesFactory
+X-KDE-ParentApp=kopete_otr
+X-KDE-ParentComponents=kopete_otr
+
+Comment=Encrypt chat sessions with Off-The-Record encryption
+Comment[de]=Verschlüsselt Chat-Sitzungen mit Off-The-Record Verschlüsselung
+Name=OTR
+Name[de]=OTR \ No newline at end of file
diff --git a/src/otrchatui.rc b/src/otrchatui.rc
new file mode 100644
index 0000000..2c3d710
--- /dev/null
+++ b/src/otrchatui.rc
@@ -0,0 +1,19 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="kopete_otr" version="1">
+ <MenuBar>
+ <Menu name="tools"><text>&amp;Tools</text>
+ <Menu name="otr_menu"><text>OTR Encryption</text>
+ <Action name="enable_otr" />
+ <Action name="disable_otr" />
+ <Action name="verify_fingerprint"/>
+ </Menu>
+ </Menu>
+ </MenuBar>
+
+ <ToolBar name="mainToolBar">
+ <text>OTR Encryption</text>
+ <Separator name="separator_0" />
+ <Action name="otr_settings" />
+ <Separator name="separator_0" />
+ </ToolBar>
+</kpartgui>
diff --git a/src/otrguiclient.cpp b/src/otrguiclient.cpp
new file mode 100644
index 0000000..544ae94
--- /dev/null
+++ b/src/otrguiclient.cpp
@@ -0,0 +1,128 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti
+ *
+ * *
+ * 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 <kaction.h>
+#include <klocale.h>
+#include <kactionclasses.h>
+#include <kopetechatsession.h>
+#include <kopeteview.h>
+#include <kopetemessage.h>
+#include <kdebug.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+
+
+#include "otrguiclient.h"
+#include "otrplugin.h"
+
+/**
+ * @author Frank Scheffold
+ * @author Michael Zanetti
+ */
+
+
+OtrGUIClient::OtrGUIClient( Kopete::ChatSession *parent, const char *name )
+: QObject( parent, name ), KXMLGUIClient( parent )
+{
+ setInstance( OTRPlugin::plugin()->instance() );
+
+ connect( OTRPlugin::plugin(),
+ SIGNAL( destroyed( QObject * ) ), this,
+ SLOT( deleteLater() )
+
+ );
+
+ connect(this, SIGNAL( signalOtrChatsession(Kopete::ChatSession*, bool) ), OTRPlugin::plugin(), SLOT(slotEnableOtr(Kopete::ChatSession*, bool)));
+
+ connect( OTRPlugin::plugin(), SIGNAL( goneSecure( Kopete::ChatSession *, int ) ),
+ this, SLOT( encryptionEnabled( Kopete::ChatSession *, int ) ) );
+
+ connect( this, SIGNAL( signalVerifyFingerprint( Kopete::ChatSession * ) ), OTRPlugin::plugin(), SLOT(slotVerifyFingerprint( Kopete::ChatSession * )) );
+
+ m_manager = parent;
+ otrActionMenu = new KActionMenu(i18n("OTR Settings"),"otr_disabled", actionCollection(), "otr_settings");
+ otrActionMenu->setDelayed( false );
+ actionEnableOtr = new KAction(i18n( "Start OTR session" ), "otr_private", 0,this,SLOT(slotEnableOtr()),actionCollection(), "enable_otr");
+ actionDisableOtr = new KAction(i18n("End OTR session"), "otr_disabled",0, this,SLOT(slotDisableOtr()), actionCollection(), "disable_otr");
+ actionVerifyFingerprint = new KAction(i18n("Authenticate Contact"), "signature",0, this,SLOT(slotVerifyFingerprint()), actionCollection(), "verify_fingerprint");
+
+ otrActionMenu->insert(actionEnableOtr);
+ otrActionMenu->insert(actionDisableOtr);
+ otrActionMenu->insert(actionVerifyFingerprint);
+
+ setXMLFile("otrchatui.rc");
+
+ encryptionEnabled( parent, OtrlChatInterface::self()->privState(parent) );
+
+
+}
+
+OtrGUIClient::~OtrGUIClient()
+{
+}
+
+void OtrGUIClient::slotEnableOtr()
+{
+ emit signalOtrChatsession( m_manager, true );
+}
+void OtrGUIClient::slotDisableOtr()
+{
+ emit signalOtrChatsession( m_manager, false );
+}
+
+void OtrGUIClient::slotVerifyFingerprint(){
+ emit signalVerifyFingerprint( m_manager );
+}
+
+void OtrGUIClient::encryptionEnabled(Kopete::ChatSession *session, int state){
+ if( session == m_manager ){
+ switch(state){
+ case 0:
+ otrActionMenu->setIcon("otr_disabled");
+ actionEnableOtr->setText( i18n("Start OTR session") );
+ actionDisableOtr->setEnabled(false);
+ actionVerifyFingerprint->setEnabled(false);
+ break;
+ case 1:
+ otrActionMenu->setIcon("otr_unverified");
+ actionEnableOtr->setText( i18n("Refresh OTR session") );
+ actionDisableOtr->setEnabled(true);
+ actionVerifyFingerprint->setEnabled(true);
+ break;
+ case 2:
+ otrActionMenu->setIcon("otr_private");
+ actionEnableOtr->setText( i18n("Refresh OTR session") );
+ actionDisableOtr->setEnabled(true);
+ actionVerifyFingerprint->setEnabled(true);
+ break;
+ case 3:
+ otrActionMenu->setIcon("otr_finished");
+ actionEnableOtr->setText( i18n("Start OTR session") );
+ actionDisableOtr->setEnabled(true);
+ actionVerifyFingerprint->setEnabled(false);
+ break;
+ }
+ }
+}
+
+#include "otrguiclient.moc"
+
+// vim: set noet ts=4 sts=4 sw=4:
diff --git a/src/otrguiclient.h b/src/otrguiclient.h
new file mode 100644
index 0000000..3776195
--- /dev/null
+++ b/src/otrguiclient.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti
+ *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+
+#ifndef OTRGUICLIENT_H
+#define OTRGUICLIENT_H
+
+#include <qobject.h>
+#include <kxmlguiclient.h>
+
+//#include <kio/job.h>
+
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kiconloader.h>
+
+#include <kopetemessage.h>
+#include <kopeteplugin.h>
+
+
+class KActionMenu;
+class KAction;
+
+namespace Kopete { class ChatSession; }
+
+/**
+ * @author Frank Scheffold
+ */
+
+
+
+
+class OtrGUIClient : public QObject , public KXMLGUIClient
+{
+ Q_OBJECT
+
+public:
+
+ OtrGUIClient( Kopete::ChatSession *parent, const char *name=0L );
+ ~OtrGUIClient();
+
+
+private:
+ Kopete::ChatSession *m_manager;
+ KActionMenu *otrActionMenu;
+ KAction *actionEnableOtr;
+ KAction *actionDisableOtr;
+ KAction *actionVerifyFingerprint;
+
+private slots:
+ void slotEnableOtr();
+ void slotDisableOtr();
+ void encryptionEnabled( Kopete::ChatSession* session, int state );
+ void slotVerifyFingerprint();
+
+signals:
+ void signalOtrChatsession( Kopete::ChatSession* session, bool enable );
+ void signalVerifyFingerprint( Kopete::ChatSession *session );
+
+
+};
+
+#endif
diff --git a/src/otrlchatinterface.cpp b/src/otrlchatinterface.cpp
new file mode 100644
index 0000000..85f1e7f
--- /dev/null
+++ b/src/otrlchatinterface.cpp
@@ -0,0 +1,685 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti
+ *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+
+/**
+ * @author Michael Zanetti
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <kopetechatsession.h>
+#include <kopeteaccount.h>
+#include <kopeteaccountmanager.h>
+#include <kopetemessageevent.h>
+#include <kopetecontactlist.h>
+#include <kopetemetacontact.h>
+#include <kopeteview.h>
+#include <kopeteprotocol.h>
+
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kprogress.h>
+#include <kpassivepopup.h>
+#include <kanimwidget.h>
+#include <kpushbutton.h>
+
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qnamespace.h>
+#include <qeventloop.h>
+#include <qapplication.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qptrlist.h>
+
+#include "otrlchatinterface.h"
+#include "otrguiclient.h"
+#include "otrplugin.h"
+#include "privkeypopup.h"
+#include "smppopup.h"
+
+OtrlChatInterface *OtrlChatInterface::mSelf = 0;
+static OtrlUserState userstate;
+static OtrlPolicy confPolicy;
+static void *updateContextList = 0;
+
+/***************************** Gui_UI_Ops for libotr **********************************/
+static OtrlPolicy policy(void *opdata, ConnContext *context){
+ Kopete::ChatSession *session= ((Kopete::ChatSession*)opdata);
+ bool noerr;
+
+ // Disable OTR for IRC
+ if( session->protocol()->pluginId() == "IRCProtocol" ){
+ kdDebug() << "Disabling OTR for: " << session->protocol()->pluginId() << endl;
+ return OTRL_POLICY_NEVER;
+ }
+ QString policy = session->members().getFirst()->metaContact()->pluginData( OTRPlugin::plugin(), "otr_policy" );
+ switch( policy.toInt( &noerr, 10 ) ){
+ case 1:
+ return OTRL_POLICY_ALWAYS;
+ case 2:
+ return OTRL_POLICY_OPPORTUNISTIC;
+ case 3:
+ return OTRL_POLICY_MANUAL;
+ case 4:
+ return OTRL_POLICY_NEVER;
+ default:
+ return confPolicy;
+ }
+}
+
+static void create_privkey(void *opdata, const char *accountname, const char *protocol){
+
+ Kopete::ChatSession *session= ((Kopete::ChatSession*)opdata);
+
+ PrivKeyPopup *popup = new PrivKeyPopup( session->view()->mainWidget(), i18n("Generating private key"), Qt::WStyle_Dialog | Qt::WStyle_StaysOnTop );
+ KAnimWidget *anim = new KAnimWidget( "kde", 72, popup->animFrame, "kopete" );
+ anim->start();
+ anim->show();
+
+ popup->setCloseLock( true );
+ popup->show();
+ KeyGenThread *keyGenThread = new KeyGenThread( accountname, protocol );
+ keyGenThread->start();
+ while( !keyGenThread->wait(100) ){
+ qApp->eventLoop()->processEvents(QEventLoop::ExcludeUserInput | QEventLoop::ExcludeSocketNotifiers, 100);
+ }
+ popup->setCloseLock( false );
+ popup->close();
+}
+
+static int is_logged_in(void *opdata, const char *accountname, const char *protocol, const char *recipient){
+ Kopete::ChatSession *session= ((Kopete::ChatSession*)opdata);
+ Kopete::ContactPtrList list = session->members();
+ for ( QPtrListIterator<Kopete::Contact> it( list ); Kopete::Contact *contact = it.current(); ++it ){
+ if( contact->contactId().compare( recipient ) == 0 ){
+ Kopete::OnlineStatus status = session->contactOnlineStatus( contact );
+ if( status == Kopete::OnlineStatus::Unknown){
+ return -1;
+ } else if( status == Kopete::OnlineStatus::Offline ){
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+ }
+ return -1;
+}
+
+static void inject_message( void *opdata, const char *accountname, const char *protocol, const char *recipient, const char *message ){
+ //KMessageBox::information( NULL, QString(accountname) + ":" + QString(protocol) + ":" + QString(recipient) + ":" + QString(message) );
+ Kopete::ChatSession *session= ((Kopete::ChatSession*)opdata);
+ Kopete::ContactPtrList list = session->members();
+ for ( QPtrListIterator<Kopete::Contact> it( list ); Kopete::Contact *contact = it.current(); ++it ){
+ if( contact->contactId().compare( recipient ) == 0 ){
+ Kopete::Message msg( session->account()->myself(), contact, QString( message ), Kopete::Message::Outbound );
+ session->sendMessage( msg );
+ return;
+ }
+ }
+}
+
+static void notify(void *opdata, OtrlNotifyLevel level, const char *accountname, const char *protocol, const char *username, const char *title, const char *primary, const char *secondary){
+ KMessageBox::information(NULL, QString( primary ) + QString( secondary ), QString( title ) );
+}
+
+static int display_otr_message( void *opdata, const char *accountname, const char *protocol, const char *username, const char *message ){
+ Kopete::ChatSession *session= ((Kopete::ChatSession*)opdata);
+ Kopete::ContactPtrList list = session->members();
+ for ( QPtrListIterator<Kopete::Contact> it( list ); Kopete::Contact *contact = it.current(); ++it ){
+ if( contact->contactId().compare( username ) == 0 ){
+ Kopete::Message msg( session->members().getFirst(), session->account()->myself(), QString( message ), Kopete::Message::Internal );
+ msg.setBody( QString( message ), Kopete::Message::RichText );
+ session->appendMessage( msg );
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void update_context_list(void *opdata){
+//Not used...
+}
+
+static const char *protocol_name(void *opdata, const char *protocol){
+//Never seen...
+ kdDebug() << "protocol_name called" << endl;
+}
+
+static void protocol_name_free(void *opdata, const char *protocol_name){
+//Never seen...
+ kdDebug() << "protocol_name_free called" << endl;
+}
+
+static void new_fingerprint(void *opdata, OtrlUserState us, const char *accountname, const char *protocol, const char *username, unsigned char fingerprint[20]){
+ kdDebug() << "Received a new Fingerprint" << endl;
+ Kopete::ChatSession *session= ((Kopete::ChatSession*)opdata);
+ Kopete::Message msg( session->members().getFirst(), session->account()->myself(), i18n("<b>Received a new fingerprint from <a>%1</a>. You should authenticate this contact.</b>").arg( session->members().getFirst()->contactId() ), Kopete::Message::Internal, Kopete::Message::RichText );
+ session->appendMessage( msg );
+}
+
+static void write_fingerprints(void *opdata){
+ kdDebug() << "Writing fingerprints" << endl;
+ otrl_privkey_write_fingerprints( userstate, QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "fingerprints" );
+}
+
+static void gone_secure(void *opdata, ConnContext *context){
+ kdDebug() << "gone secure" << endl;
+ Kopete::ChatSession *session= ((Kopete::ChatSession*)opdata);
+
+ if( context->active_fingerprint->trust && context->active_fingerprint->trust[0] ){
+ Kopete::Message msg( session->members().getFirst(), session->account()->myself(), i18n("<b>Private OTR session started.</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ session->appendMessage( msg );
+ OTRPlugin::plugin()->emitGoneSecure( ((Kopete::ChatSession*)opdata), 2 );
+ } else {
+ Kopete::Message msg( session->members().getFirst(), session->account()->myself(), i18n("<b>Unverified OTR session started.</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ session->appendMessage( msg );
+ OTRPlugin::plugin()->emitGoneSecure( ((Kopete::ChatSession*)opdata), 1 );
+ }
+}
+
+/* Actually I've never seen this event but its implemented in case someone should receive it
+ kopete, gaim and miranda send a heartbeat message at disconnect. See log_message.
+ Searching libotr I could not find any call of gone_insecure. */
+static void gone_insecure(void *opdata, ConnContext *context){
+ kdDebug() << "gone insecure" << endl;
+ OTRPlugin::plugin()->emitGoneSecure(((Kopete::ChatSession*)opdata), 0);
+ Kopete::ChatSession *session= ((Kopete::ChatSession*)opdata);
+ Kopete::Message msg( session->members().getFirst(), session->account()->myself(), i18n("<b>OTR Session ended. The conversation is now insecure!</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ session->appendMessage( msg );
+}
+
+static void still_secure(void *opdata, ConnContext *context, int is_reply){
+ kdDebug() << "still secure" << endl;
+ Kopete::ChatSession *session= ((Kopete::ChatSession*)opdata);
+ Kopete::Message msg( session->members().getFirst(), session->account()->myself(), i18n("<b>OTR connection refreshed successfully.</b>") , Kopete::Message::Internal, Kopete::Message::RichText );
+ session->appendMessage( msg );
+
+ if( context->active_fingerprint->trust && context->active_fingerprint->trust[0] ){
+ OTRPlugin::plugin()->emitGoneSecure( session, 2);
+ } else {
+ OTRPlugin::plugin()->emitGoneSecure( session, 1);
+ }
+}
+
+static void log_message(void *opdata, const char *message){
+ kdDebug() << "libotr: "<< message << endl;
+}
+
+static OtrlMessageAppOps ui_ops = {
+ policy,
+ create_privkey,
+ is_logged_in,
+ inject_message,
+ notify,
+ display_otr_message,
+ update_context_list,
+ protocol_name,
+ protocol_name_free,
+ new_fingerprint,
+ write_fingerprints,
+ gone_secure,
+ gone_insecure,
+ still_secure,
+ log_message
+};
+
+/*********************** Gui_UI_Ops finished *************************/
+
+
+/*********************** Constructor/Destructor **********************/
+
+OtrlChatInterface::OtrlChatInterface(){
+ kdDebug() << "Creating OtrlChatInterface" << endl;
+ mSelf = this;
+ OTRL_INIT;
+
+ userstate = otrl_userstate_create();
+
+ otrl_privkey_read( userstate, QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkeys" );
+
+
+
+ otrl_privkey_read_fingerprints(userstate, QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "fingerprints", NULL, NULL);
+
+}
+
+OtrlChatInterface::~ OtrlChatInterface(){
+ otrl_userstate_free(userstate);
+}
+
+
+OtrlChatInterface *OtrlChatInterface::self(){
+ if( !mSelf ){
+ new OtrlChatInterface();
+ }
+ return mSelf;
+}
+
+/********************* Chat section ***************************/
+
+OtrlUserState OtrlChatInterface::getUserstate(){
+ return userstate;
+}
+
+
+int OtrlChatInterface::decryptMessage( QString *msg, QString accountId,
+ QString protocol, QString contactId , Kopete::ChatSession *chatSession){
+
+ int ignoremessage;
+ char *newMessage = NULL;
+ OtrlTLV *tlvs = NULL;
+ OtrlTLV *tlv = NULL;
+ ConnContext *context;
+ NextExpectedSMP nextMsg;
+
+
+ ignoremessage = otrl_message_receiving( userstate, &ui_ops, chatSession, accountId.latin1(), protocol.latin1(), contactId.latin1(), msg->latin1(), &newMessage, &tlvs, NULL, NULL );
+
+
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED);
+ if( tlv ){
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("<b>%1</b> has ended the OTR session. You should do the same.").arg(chatSession->members().getFirst()->contactId()) , Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+
+ OTRPlugin::plugin()->emitGoneSecure( chatSession, 3 );
+ }
+
+ context = otrl_context_find( userstate, contactId.latin1(), accountId.latin1(), protocol.latin1(), 0, NULL, NULL, NULL);
+ if (context) {
+ nextMsg = context->smstate->nextExpected;
+
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1);
+ if (tlv) {
+ if (nextMsg != OTRL_SMP_EXPECT1){
+ abortSMP( context, chatSession );
+ } else {
+ SMPPopup *popup = new SMPPopup( chatSession->view()->mainWidget(), i18n("Enter authentication secret"), Qt::WStyle_Dialog | Qt::WStyle_StaysOnTop, context, chatSession, false );
+ popup->show();
+ }
+ }
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP2);
+ if (tlv) {
+ if (nextMsg != OTRL_SMP_EXPECT2)
+ abortSMP( context, chatSession );
+ else {
+ kdDebug() << "Update SMP state: 2 -> 3" << endl;
+ context->smstate->nextExpected = OTRL_SMP_EXPECT4;
+ }
+ }
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP3);
+ if (tlv) {
+ if (nextMsg != OTRL_SMP_EXPECT3)
+ abortSMP( context, chatSession );
+ else {
+ if (context->active_fingerprint->trust && context->active_fingerprint->trust[0]) {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("<b>Authentication successful. The conversation is now secure!</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ OTRPlugin::plugin()->emitGoneSecure( chatSession, 2 );
+ } else {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("<b>Authentication failed. The conversation is now insecure!</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ OTRPlugin::plugin()->emitGoneSecure( chatSession, 1 );
+ }
+
+ context->smstate->nextExpected = OTRL_SMP_EXPECT1;
+ }
+ }
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP4);
+ if (tlv) {
+ if (nextMsg != OTRL_SMP_EXPECT4)
+ abortSMP( context, chatSession );
+ else {
+ if (context->active_fingerprint->trust && context->active_fingerprint->trust[0]) {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("<b>Authentication successful. The conversation is now secure!</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ OTRPlugin::plugin()->emitGoneSecure( chatSession, 2 );
+ } else {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("<b>Authentication failed. The conversation is now insecure!</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ OTRPlugin::plugin()->emitGoneSecure( chatSession, 1 );
+ }
+ context->smstate->nextExpected = OTRL_SMP_EXPECT1;
+ }
+ }
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT);
+ if (tlv) {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("<b>Authentication error!</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ context->smstate->nextExpected = OTRL_SMP_EXPECT1;
+ }
+
+ otrl_tlv_free(tlvs);
+ }
+
+
+ // message is now decrypted or is a Plaintext message and ready to deliver
+ if( !ignoremessage ){
+ // message is decrypted
+ if( newMessage != NULL ){
+ *msg = QString::fromUtf8(newMessage);
+ otrl_message_free( newMessage );
+ msg->replace( '\n', "<br>", false );
+ }
+ }
+ return ignoremessage;
+}
+
+QString OtrlChatInterface::encryptMessage( QString msg, QString accountId,
+ QString protocol, QString contactId , Kopete::ChatSession *chatSession ){
+ int err;
+ char * newMessage;
+ if( otrl_proto_message_type( msg ) == OTRL_MSGTYPE_NOTOTR ){
+ msg.replace( '<', "&lt;", false );
+ err = otrl_message_sending( userstate, &ui_ops, chatSession, accountId.latin1(), protocol.latin1(), contactId.latin1(), msg.utf8(), NULL, &newMessage, NULL, NULL );
+
+ if( err != 0 ){
+ msg = i18n("Encryption error");
+ } else {
+ if( newMessage != NULL ){
+ msg = QString::fromUtf8( newMessage );
+ otrl_message_free( newMessage );
+ }
+ }
+ }
+ OtrlMessageType type = otrl_proto_message_type( msg );
+ if( type == OTRL_MSGTYPE_NOTOTR | type == OTRL_MSGTYPE_TAGGEDPLAINTEXT ){
+ msg.replace( "&lt;", "<", false );
+ }
+ return msg;
+}
+
+QString OtrlChatInterface::getDefaultQuery( QString accountId ){
+ char *message;
+ message = otrl_proto_default_query_msg( accountId.latin1(), OTRL_POLICY_ALLOW_V2 );
+ QString msg( message );
+ otrl_message_free( message );
+ return msg;
+}
+
+void OtrlChatInterface::disconnectSession( Kopete::ChatSession *chatSession ){
+ otrl_message_disconnect( userstate, &ui_ops, chatSession, chatSession->account()->accountId().latin1(), chatSession->account()->protocol()->displayName().latin1(), chatSession->members().getFirst()->contactId() );
+ OTRPlugin::plugin()->emitGoneSecure( chatSession, false );
+
+ Kopete::Message msg( chatSession->account()->myself(), chatSession->members().getFirst(), i18n("Terminating OTR session."), Kopete::Message::Internal );
+// msg.setBody( QString( message ), Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+
+}
+
+bool OtrlChatInterface::shouldDiscard( QString message ){
+ if( !message.isEmpty() && !message.isNull() ){
+ switch( otrl_proto_message_type( message.latin1() ) ){
+ case OTRL_MSGTYPE_TAGGEDPLAINTEXT:
+ case OTRL_MSGTYPE_UNKNOWN:
+ case OTRL_MSGTYPE_NOTOTR:
+ return false;
+ default:
+ return true;
+ }
+ } else {
+ return false;
+ }
+}
+
+
+void OtrlChatInterface::setPolicy( OtrlPolicy policy ){
+ confPolicy = policy;
+}
+
+
+int OtrlChatInterface::privState( Kopete::ChatSession *session ){
+ ConnContext *context;
+
+ context = otrl_context_find(userstate, session->members().getFirst()->contactId(), session->account()->accountId(), session->account()->protocol()->displayName(), 0, NULL, NULL, NULL);
+
+ if( context ){
+ switch( context->msgstate ){
+ case OTRL_MSGSTATE_PLAINTEXT:
+ return 0;
+ case OTRL_MSGSTATE_ENCRYPTED:
+ if( context->active_fingerprint->trust && context->active_fingerprint->trust[0] != '\0' )
+ return 2;
+ else
+ return 1;
+ case OTRL_MSGSTATE_FINISHED:
+ return 3;
+ }
+ }
+ return 0;
+}
+
+QString OtrlChatInterface::formatContact(QString contactId){
+
+ Kopete::MetaContact *metaContact = Kopete::ContactList::self()->findMetaContactByContactId(contactId);
+ if( metaContact ){
+ QString displayName = metaContact->displayName();
+ if((displayName != contactId) && !displayName.isNull()){
+ return displayName + " (" + contactId+")";
+ }
+ }
+ return contactId;
+}
+
+void OtrlChatInterface::verifyFingerprint( Kopete::ChatSession *session ){
+ ConnContext *context;
+
+ context = otrl_context_find( userstate, session->members().getFirst()->contactId().latin1(), session->account()->accountId().latin1(), session->protocol()->displayName().latin1(), 0, NULL, NULL, NULL);
+
+ SMPPopup *popup = new SMPPopup( session->view()->mainWidget(), i18n("Enter authentication secret"), Qt::WStyle_Dialog | Qt::WStyle_StaysOnTop, context, session, true );
+ popup->show();
+
+
+}
+
+void OtrlChatInterface::setTrust( Kopete::ChatSession *session, bool trust ){
+ Fingerprint *fingerprint;
+
+ fingerprint = findFingerprint( session->members().getFirst()->contactId() );
+ if( fingerprint != 0 ){
+ if( trust ){
+ otrl_context_set_trust( fingerprint, "verified" );
+ } else {
+ otrl_context_set_trust( fingerprint, NULL );
+ }
+ kdDebug() << "Writing fingerprints" << endl;
+ otrl_privkey_write_fingerprints( userstate, QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "fingerprints" );
+ OTRPlugin::plugin()->emitGoneSecure( session, privState( session ) );
+ } else {
+ kdDebug() << "could not find fingerprint" << endl;
+ }
+}
+
+Fingerprint *OtrlChatInterface::findFingerprint( QString account ){
+ ConnContext *context;
+
+ for( context = userstate->context_root; context != NULL; context = context->next ){
+ kdDebug() << context->username << endl;
+ if( strcmp( context->username, account ) == 0 ){
+ kdDebug() << "found Context" << endl;
+ return context->active_fingerprint ? context->active_fingerprint : NULL;
+ }
+ }
+ return NULL;
+}
+
+QString OtrlChatInterface::findActiveFingerprint( Kopete::ChatSession *session ){
+ ConnContext *context;
+ char hash[45];
+
+ for( context = userstate->context_root; context != NULL; context = context->next ){
+ kdDebug() << context->username << endl;
+ if( strcmp( context->username, session->members().getFirst()->contactId() ) == 0 ){
+// otrl_privkey_hash_to_human( hash, context->fingerprint_root.next->fingerprint );
+ otrl_privkey_hash_to_human( hash, context->active_fingerprint->fingerprint );
+ return hash;
+ }
+ }
+ return NULL;
+}
+
+bool OtrlChatInterface::isVerified( Kopete::ChatSession *session ){
+ kdDebug() << "checking for trust" << endl;
+ Fingerprint *fingerprint = findFingerprint( session->members().getFirst()->contactId() );
+
+ if( fingerprint->trust && fingerprint->trust[0] != '\0' ){
+ kdDebug() << "verified" << endl;
+ return true;
+ } else {
+ kdDebug() << "not verified" << endl;
+ return false;
+ }
+}
+
+void OtrlChatInterface::updateKeyfile( Kopete::Account *account ){
+// Updating private keys from <=0.3
+ kdDebug() << "updating keys" << endl;
+ QFile keyfile( QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkeys" );
+ QString line;
+ QString file;
+
+ if( keyfile.open( IO_ReadWrite ) ){
+ kdDebug() << "file open" << endl;
+ while( keyfile.readLine( line, 200 ) != -1){
+ if( line.find( "protocol" ) != -1 ){
+ if( line.find( account->accountLabel() ) != -1 ){
+ line.replace( account->accountLabel(), account->protocol()->displayName() );
+ kdDebug() << "Successfully updated keyfile for account " << account->accountId() << endl;
+ }
+ }
+ file.append( line );
+ }
+ }
+ keyfile.remove();
+ keyfile.open( IO_ReadWrite );
+ keyfile.writeBlock( file.latin1(), file.length() );
+ keyfile.close();
+ otrl_privkey_forget_all( userstate );
+ otrl_privkey_read( userstate, QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkeys" );
+
+ file = "";
+ line = "";
+// Updating fingerprints from <=0.3
+ kdDebug() << "updating fingerprints" << endl;
+ QFile fingerprintfile( QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "fingerprints" );
+
+ if( fingerprintfile.open( IO_ReadWrite ) ){
+ kdDebug() << "file open" << endl;
+ while( fingerprintfile.readLine( line, 200 ) != -1){
+ int pos = line.findRev( account->accountLabel() );
+ if( pos != -1 ){
+ line.replace( pos, account->accountLabel().length(), account->protocol()->displayName() );
+ kdDebug() << "Successfully updated fingerprint for account " << account->accountId() << endl;
+ }
+ file.append( line );
+ }
+ }
+ fingerprintfile.remove();
+ fingerprintfile.open( IO_ReadWrite );
+ fingerprintfile.writeBlock( file.latin1(), file.length() );
+ fingerprintfile.close();
+ otrl_context_forget_all( userstate );
+ otrl_privkey_read_fingerprints(userstate, QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "fingerprints", NULL, NULL);
+
+}
+
+void OtrlChatInterface::checkFilePermissions( QString file ){
+ if( QFile::exists( file ) ){
+ QFile privkeys( file );
+ QFileInfo privkeysInfo( privkeys );
+ if( !privkeysInfo.permission( QFileInfo::ReadOwner | QFileInfo::WriteOwner ) |
+ privkeysInfo.permission( QFileInfo::ReadGroup ) |
+ privkeysInfo.permission( QFileInfo::WriteGroup ) |
+ privkeysInfo.permission( QFileInfo::ExeGroup ) |
+ privkeysInfo.permission( QFileInfo::ReadOther ) |
+ privkeysInfo.permission( QFileInfo::WriteOther ) |
+ privkeysInfo.permission( QFileInfo::ExeOther ) ){
+ kdDebug() << "Permissions of OTR storage file are wrong! Correcting..." << endl;
+ chmod( file, 0600);
+ }
+ }
+
+}
+
+/*bool OtrlChatInterface::verifyQuestion( Kopete::ChatSession *session, QString fingerprint ){
+ kdDebug() << "searching for Fingerprint" << endl;
+
+ if( fingerprint != NULL ){
+ int doVerify = KMessageBox::questionYesNo(
+ NULL,
+ i18n("Please contact %1 via another secure way and verify that the following Fingerprint is correct:").arg( formatContact(session->members().getFirst()->contactId())) + "\n\n" + fingerprint + "\n\n" + i18n("Are you sure you want to trust this fingerprint?"),
+ i18n("Verify fingerprint") );
+ if( doVerify == KMessageBox::Yes ){
+ return true;
+ } else {
+ return false;
+ verifyFingerprint( session, false );
+ }
+ } else {
+ KMessageBox::error( NULL, i18n( "No fingerprint yet received from this contact." ), i18n( "No fingerprint found" ) );
+ }
+ return false;
+}
+*/
+
+/****************** SMP implementations ****************/
+
+void OtrlChatInterface::abortSMP( ConnContext *context, Kopete::ChatSession *session ){
+ otrl_message_abort_smp( userstate, &ui_ops, session, context);
+ if (context->active_fingerprint->trust && !context->active_fingerprint->trust[0]) {
+ OTRPlugin::plugin()->emitGoneSecure( session, 1 );
+ Kopete::Message msg( session->members().getFirst(), session->account()->myself(), i18n("<b>Authentication aborded. The conversation is now insecure!</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ session->appendMessage( msg );
+ }
+}
+
+void OtrlChatInterface::respondSMP( ConnContext *context, Kopete::ChatSession *session, QString secret, bool initiate ){
+ if( initiate ){
+ context = otrl_context_find( userstate, session->members().getFirst()->contactId().latin1(), session->account()->accountId().latin1(), session->protocol()->displayName().latin1(), 0, NULL, NULL, NULL);
+ otrl_message_initiate_smp( userstate, &ui_ops, session, context, (unsigned char*)secret.latin1(), secret.length() );
+
+
+ } else {
+ otrl_message_respond_smp( userstate, &ui_ops, session, context, (unsigned char*)secret.latin1(), secret.length());
+ }
+
+ Kopete::Message msg( session->members().getFirst(), session->account()->myself(), i18n("<b>Authenticating contact...</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ session->appendMessage( msg );
+}
+
+/****************** KeyGenThread *******************/
+
+KeyGenThread::KeyGenThread( QString accountname, QString protocol ){
+ this->accountname = accountname;
+ this->protocol = protocol;
+}
+
+
+void KeyGenThread::run()
+{
+ kdDebug() << "Creating private key... Storing to: " + QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true)) + "privkeys" << endl;
+ otrl_privkey_generate(OtrlChatInterface::self()->getUserstate(), QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkeys", accountname, protocol);
+ OtrlChatInterface::self()->checkFilePermissions( QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkeys" );
+}
+
diff --git a/src/otrlchatinterface.h b/src/otrlchatinterface.h
new file mode 100644
index 0000000..9fcf632
--- /dev/null
+++ b/src/otrlchatinterface.h
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti
+ *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef OTRLCHATINTERFACE_H
+#define OTRLCHATINTERFACE_H
+
+/**
+ * @author Michael Zanetti
+ */
+
+#include <qstring.h>
+#include <qptrlist.h>
+#include <qvaluelist.h>
+#include <qthread.h>
+#include <qmutex.h>
+
+#include <kopetechatsession.h>
+
+extern "C" {
+#include <libotr/privkey.h>
+#include <libotr/proto.h>
+#include <libotr/message.h>
+#include <libotr/userstate.h>
+}
+
+class OtrlChatInterface: public QObject
+{
+
+public:
+ ~OtrlChatInterface();
+ static OtrlChatInterface *self();
+
+ int decryptMessage( QString *msg, QString accountId, QString protocol, QString contactId, Kopete::ChatSession *chatSession );
+ QString encryptMessage( QString msg, QString accountId,
+ QString protocol, QString contactId , Kopete::ChatSession *chatSession );
+ QString getDefaultQuery( QString accountId );
+ void disconnectSession( Kopete::ChatSession *chatSession );
+ void setPolicy( OtrlPolicy policy );
+ bool shouldDiscard( QString message );
+ OtrlUserState getUserstate();
+ int privState( Kopete::ChatSession *session );
+ QString formatContact(QString contactId);
+ bool isVerified( Kopete::ChatSession *session );
+ void updateKeyfile( Kopete::Account *account );
+ void checkFilePermissions( QString file );
+// bool verifyQuestion( Kopete::ChatSession *session, QString fingerprint );
+ QString findActiveFingerprint( Kopete::ChatSession *session );
+ void verifyFingerprint( Kopete::ChatSession *session );
+ void abortSMP( ConnContext *context, Kopete::ChatSession *session );
+ void respondSMP( ConnContext *context, Kopete::ChatSession *session, QString secret, bool initiate );
+ void setTrust( Kopete::ChatSession *session, bool trust );
+
+private:
+ OtrlChatInterface();
+ static OtrlChatInterface *mSelf;
+ Fingerprint *findFingerprint( QString username );
+};
+
+ class KeyGenThread : public QThread {
+
+private:
+ QString accountname;
+ QString protocol;
+
+public:
+ KeyGenThread( QString accountname, QString protocol );
+ virtual void run();
+};
+
+#endif
diff --git a/src/otrlconfinterface.cpp b/src/otrlconfinterface.cpp
new file mode 100644
index 0000000..5d95d06
--- /dev/null
+++ b/src/otrlconfinterface.cpp
@@ -0,0 +1,231 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti
+ *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+
+/**
+ * @author Michael Zanetti
+ */
+
+#include <qapplication.h>
+#include <qeventloop.h>
+
+#include <kopetechatsession.h>
+#include <kopeteaccount.h>
+
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kanimwidget.h>
+
+
+#include "otrlconfinterface.h"
+#include "otrlchatinterface.h"
+#include "otrplugin.h"
+#include "privkeypopup.h"
+
+
+
+/*********************** Konstruktor/Destruktor **********************/
+
+OtrlConfInterface::OtrlConfInterface( QWidget *preferencesDialog ){
+
+ this->preferencesDialog = preferencesDialog;
+
+ OTRL_INIT;
+
+ userstate = OtrlChatInterface::self()->getUserstate();
+
+ kdDebug() << "OtrlConfInterface created" << endl;
+}
+
+OtrlConfInterface::~ OtrlConfInterface(){
+ otrl_userstate_free(userstate);
+}
+
+/*********************** Functions for kcm module ************************/
+
+QString OtrlConfInterface::getPrivFingerprint( QString accountId, QString protocol){
+// if (otrl_privkey_read(userstate, QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkey" ) == 0){
+ char fingerprint[45];
+ if( otrl_privkey_fingerprint( userstate, fingerprint, accountId.latin1(), protocol.latin1()) != 0 ){
+ return fingerprint;
+ }
+// }
+ return i18n("No fingerprint present.");
+}
+
+
+bool OtrlConfInterface::hasPrivFingerprint( QString accountId, QString protocol ){
+ char fingerprint[45];
+ if( otrl_privkey_fingerprint( userstate, fingerprint, accountId.latin1(), protocol.latin1() ) != 0 ){
+ return true;
+ }
+ return false;
+}
+
+
+void OtrlConfInterface::generateNewPrivKey( QString accountId, QString protocol ){
+ PrivKeyPopup *popup = new PrivKeyPopup( preferencesDialog, i18n("Generating private key"), Qt::WStyle_Dialog | Qt::WStyle_StaysOnTop );
+ KAnimWidget *anim = new KAnimWidget( "kde", 72, popup->animFrame, "kopete" );
+ anim->start();
+ anim->show();
+
+ popup->setCloseLock( true );
+ popup->show();
+ KeyGenThread *keyGenThread = new KeyGenThread ( accountId, protocol );
+ keyGenThread->start();
+ while( !keyGenThread->wait(100) ){
+ qApp->eventLoop()->processEvents(QEventLoop::ExcludeUserInput | QEventLoop::ExcludeSocketNotifiers, 100);
+ }
+ popup->setCloseLock( false );
+ popup->close();
+}
+
+QValueList<QString[5]> OtrlConfInterface::readAllFingerprints(){
+ ConnContext *context;
+ Fingerprint *fingerprint;
+ QString entry[5];
+ char hash[45];
+ QValueList<QString[5]> list;
+
+ for( context = userstate->context_root; context != NULL; context = context->next ){
+ fingerprint = context->fingerprint_root.next;
+ while( fingerprint ){
+ entry[0] = context->username;
+
+ if( ( context->msgstate == OTRL_MSGSTATE_ENCRYPTED ) && ( context->active_fingerprint != fingerprint ) ){
+ entry[1] = i18n("Unused");
+ } else {
+ if (context && context->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
+ if (context->active_fingerprint->trust && context->active_fingerprint->trust[0] != NULL) {
+ entry[1] = i18n("Private");
+ } else {
+ entry[1] = i18n("Unverified");
+ }
+ } else if (context && context->msgstate == OTRL_MSGSTATE_FINISHED) {
+ entry[1] = i18n("Finished");
+ } else {
+ entry[1] = i18n("Not Private");
+ }
+ }
+ entry[2] = ( fingerprint->trust && fingerprint->trust[0] ) ? i18n("Yes") : i18n("No") ;
+ otrl_privkey_hash_to_human( hash, fingerprint->fingerprint );
+ entry[3] = hash;
+ entry[4] = context->protocol;
+ list << entry;
+ fingerprint = fingerprint->next;
+ }
+ }
+ return list;
+}
+
+void OtrlConfInterface::verifyFingerprint( QString strFingerprint, bool trust ){
+ Fingerprint *fingerprint;
+
+ fingerprint = findFingerprint( strFingerprint );
+
+ if( fingerprint != 0 ){
+ if( trust ){
+ otrl_context_set_trust( fingerprint, "verified" );
+ } else {
+ otrl_context_set_trust( fingerprint, NULL );
+ }
+ kdDebug() << "Writing fingerprints" << endl;
+ otrl_privkey_write_fingerprints( userstate, QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "fingerprints" );
+ } else {
+ kdDebug() << "could not find fingerprint" << endl;
+ }
+}
+
+bool OtrlConfInterface::isVerified( QString strFingerprint ){
+ Fingerprint *fingerprint;
+
+ fingerprint = findFingerprint( strFingerprint );
+
+ if( fingerprint->trust && fingerprint->trust[0] ){
+ kdDebug() << "found trust" << endl;
+ return true;
+ } else {
+ kdDebug() << "not trusted" << endl;
+ return false;
+ }
+}
+
+
+void OtrlConfInterface::forgetFingerprint( QString strFingerprint ){
+ Fingerprint *fingerprint;
+
+ fingerprint = findFingerprint( strFingerprint );
+ otrl_context_forget_fingerprint( fingerprint, 1 );
+ otrl_privkey_write_fingerprints( userstate, QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "fingerprints" );
+}
+
+Fingerprint *OtrlConfInterface::findFingerprint( QString strFingerprint ){
+// const char *cFingerprint = ;
+// Fingerprint *fingerprintRoot = &userstate->context_root->fingerprint_root;
+ ConnContext *context;
+ Fingerprint *fingerprint;
+ Fingerprint *foundFingerprint = NULL;
+ char hash[45];
+
+ for( context = userstate->context_root; context != NULL; context = context->next ){
+ fingerprint = context->fingerprint_root.next;
+ while( fingerprint ){
+ otrl_privkey_hash_to_human(hash, fingerprint->fingerprint);
+ if( strcmp( hash, strFingerprint.latin1()) == 0 ){
+ foundFingerprint = fingerprint;
+ }
+ fingerprint = fingerprint->next;
+ }
+ }
+ return foundFingerprint;
+}
+
+bool OtrlConfInterface::isEncrypted( QString strFingerprint ){
+ Fingerprint *fingerprint;
+ Fingerprint *tmpFingerprint;
+ Fingerprint *foundFingerprint;
+ ConnContext *context;
+ ConnContext *foundContext = NULL;
+
+ context = userstate->context_root;
+
+ fingerprint = findFingerprint( strFingerprint );
+ for( context = userstate->context_root; context != NULL; context = context->next ){
+ tmpFingerprint = context->fingerprint_root.next;
+ while( tmpFingerprint ){
+ if( tmpFingerprint == fingerprint ){
+ kdDebug() << "Found context" << endl;
+ foundContext = context;
+ foundFingerprint = tmpFingerprint;
+ }
+ tmpFingerprint = tmpFingerprint->next;
+ }
+ }
+
+ if( foundContext && foundContext->msgstate != OTRL_MSGSTATE_ENCRYPTED ){
+ return false;
+ } else if( foundContext && foundFingerprint && foundContext->active_fingerprint == foundFingerprint ){
+ return true;
+ } else {
+ return false;
+ }
+}
diff --git a/src/otrlconfinterface.h b/src/otrlconfinterface.h
new file mode 100644
index 0000000..bb89b3c
--- /dev/null
+++ b/src/otrlconfinterface.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti
+ *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef OTRLCONFINTERFACE_H
+#define OTRLCONFINTERFACE_H
+
+/**
+ * @author Michael Zanetti
+ */
+
+#include <qstring.h>
+#include <qptrlist.h>
+#include <qvaluelist.h>
+#include <qthread.h>
+
+#include <kopetechatsession.h>
+
+extern "C" {
+#include <libotr/privkey.h>
+#include <libotr/proto.h>
+#include <libotr/message.h>
+#include <libotr/userstate.h>
+#include <libotr/context.h>
+}
+
+class OtrlConfInterface
+{
+
+public:
+ ~OtrlConfInterface();
+ OtrlConfInterface( QWidget *preferencesDialog );
+
+ QString getPrivFingerprint( QString accountId, QString protocol );
+ void generateNewPrivKey( QString accountId, QString protocol );
+ QValueList<QString[5]> readAllFingerprints();
+ bool hasPrivFingerprint( QString accountId, QString protocol);
+ void forgetFingerprint( QString strFingerprint );
+ void verifyFingerprint( QString strFingerprint, bool trust );
+ bool isVerified( QString strFingerprint );
+ bool isEncrypted( QString strFingerprint );
+
+private:
+ OtrlUserState userstate;
+ QWidget *preferencesDialog;
+
+ Fingerprint *findFingerprint( QString strFingerprint );
+};
+
+#endif
diff --git a/src/otrplugin.cpp b/src/otrplugin.cpp
new file mode 100644
index 0000000..873c800
--- /dev/null
+++ b/src/otrplugin.cpp
@@ -0,0 +1,344 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti *
+ * *
+ * *
+ * 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 <qstylesheet.h>
+#include <qtimer.h>
+#include <qregexp.h>
+#include <qfile.h>
+#include <qcolor.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kactionclasses.h>
+#include <kpopupmenu.h>
+#include <kconfig.h>
+#include <kgenericfactory.h>
+#include <kdeversion.h>
+#include <kaboutdata.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+
+#include <kopetemetacontact.h>
+#include <kopetecontactlist.h>
+#include <kopetechatsessionmanager.h>
+#include <kopetesimplemessagehandler.h>
+#include <kopeteuiglobal.h>
+#include <kopetecontact.h>
+#include <kopetemessage.h>
+#include <kopeteaccount.h>
+#include <kopeteaccountmanager.h>
+#include <kopetemessageevent.h>
+#include <kopeteprotocol.h>
+
+#include "otrplugin.h"
+#include "otrguiclient.h"
+#include "otrlchatinterface.h"
+#include "kopete_otr.h"
+
+/**
+ * @author Michael Zanetti
+ */
+
+
+
+typedef KGenericFactory<OTRPlugin> OTRPluginFactory;
+static const KAboutData aboutdata("kopete_otr", I18N_NOOP("OTR") , "0.7" );
+K_EXPORT_COMPONENT_FACTORY( kopete_otr, OTRPluginFactory( &aboutdata ) )
+
+OTRPlugin::OTRPlugin( QObject *parent, const char *name, const QStringList & /* args */ )
+: Kopete::Plugin( OTRPluginFactory::instance(), parent, name )
+{
+ if( !pluginStatic_ )
+ pluginStatic_=this;
+
+ m_inboundHandler = new OtrMessageHandlerFactory(this);
+
+ connect( Kopete::ChatSessionManager::self(), SIGNAL( aboutToSend( Kopete::Message & ) ),
+ SLOT( slotOutgoingMessage( Kopete::Message & ) ) );
+// connect( Kopete::ChatSessionManager::self(), SIGNAL( aboutToDisplay( Kopete::Message & ) ),
+// this, SLOT( slotIncomingMessage( Kopete::Message & ) ) );
+
+ connect( Kopete::ChatSessionManager::self(), SIGNAL( chatSessionCreated( Kopete::ChatSession * ) ),
+ this, SLOT( slotNewChatSessionWindow( Kopete::ChatSession * ) ) );
+ QObject::connect( this, SIGNAL( settingsChanged() ), this, SLOT( slotSettingsChanged() ) );
+
+
+
+ //initialize the otrlib and create the interface object
+ otrlChatInterface = OtrlChatInterface::self();
+
+ //update key files when an account is ready to use
+ if( QFile::exists( QString( KGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "privkey" ) &&
+ !QFile::exists( QString( KGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "privkeys" ) ){
+ kdDebug() << "Detected old format keyfile. Doing updates!" << endl;
+ kdDebug() << "Reading old keyfile..." << endl;
+ QFile fpold( QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkey" );
+ QString line;
+ QString file;
+ if( fpold.open( IO_ReadWrite ) ){
+ while( fpold.readLine( line, 100 ) != -1){
+ file.append( line );
+ }
+ }
+ kdDebug() << "Writing new keyfile" << endl;
+ QFile fpnew( QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkeys" );
+ fpnew.open( IO_ReadWrite );
+ fpnew.writeBlock( file.latin1(), file.length() );
+ fpnew.close();
+ kdDebug() << "Writing backup for old keyfile" << endl;
+ QFile fpbup( QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkey.old" );
+ fpbup.open( IO_ReadWrite );
+ fpbup.writeBlock( file.latin1(), file.length() );
+ fpbup.close();
+ kdDebug() << "Deleting old keyfile" << endl;
+ fpold.remove();
+
+ kdDebug() << "Reading old fingerprintsfile..." << endl;
+ QFile fpfingerprintsold( QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "fingerprints" );
+ line = "";
+ file = "";
+ if( fpfingerprintsold.open( IO_ReadWrite ) ){
+ while( fpfingerprintsold.readLine( line, 100 ) != -1){
+ file.append( line );
+ }
+ }
+ kdDebug() << "Writing backup for old fingerprintsfile" << endl;
+ QFile fpfingerprintsbup( QString(KGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "fingerprints.old" );
+ fpfingerprintsbup.open( IO_ReadWrite );
+ fpfingerprintsbup.writeBlock( file.latin1(), file.length() );
+ fpfingerprintsbup.close();
+
+ kdDebug() << "Waiting for accounts to update keyfile format" << endl;
+ connect( Kopete::AccountManager::self(), SIGNAL( accountRegistered( Kopete::Account * ) ),
+ this, SLOT( accountReady( Kopete::Account * ) ) );
+ }
+
+ // Checking file Permissions
+ OtrlChatInterface::self()->checkFilePermissions( QString( KGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "privkeys" );
+ OtrlChatInterface::self()->checkFilePermissions( QString( KGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "fingerprints" );
+ // Check also file permissions for eventuallly old beckup files
+ OtrlChatInterface::self()->checkFilePermissions( QString( KGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "privkey.old" );
+ OtrlChatInterface::self()->checkFilePermissions( QString( KGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "fingerprints.old" );
+
+ //setting the policy
+ slotSettingsChanged();
+
+ //adding menu to contaclists menubar and contacts popup menu
+ QStringList policies;
+ policies << i18n("&Default") << i18n("Al&ways") << i18n("&Opportunistic") << i18n("&Manual") << i18n("Ne&ver");
+ otrPolicyMenu = new KSelectAction( i18n( "&OTR Policy" ), QString::fromLatin1("kopete_otr"), 0, actionCollection(), "otr_policy" );
+ otrPolicyMenu->setItems( policies );
+ otrPolicyMenu->popupMenu()->insertSeparator( 1 );
+ otrPolicyMenu->setEnabled( false );
+ connect( otrPolicyMenu, SIGNAL( activated() ), this, SLOT( slotSetPolicy() ) );
+ connect( Kopete::ContactList::self(), SIGNAL( metaContactSelected( bool ) ), this, SLOT( slotSelectionChanged( bool ) ) );
+
+
+ setXMLFile( "otrui.rc" );
+
+
+
+ //Add GUI action to all already existing kmm
+ // (if the plugin is launched when kopete already runing)
+ QValueList<Kopete::ChatSession*> sessions =
+ Kopete::ChatSessionManager::self()->sessions();
+ QValueListIterator<Kopete::ChatSession*> it;
+ for (it= sessions.begin(); it!=sessions.end() ; ++it){
+ slotNewChatSessionWindow( *it );
+ }
+}
+
+OTRPlugin::~OTRPlugin()
+{
+ delete m_inboundHandler;
+ pluginStatic_ = 0L;
+ kdDebug() << "Exiting plugin" << endl;
+}
+
+
+OTRPlugin* OTRPlugin::plugin()
+{
+ return pluginStatic_ ;
+}
+
+OTRPlugin* OTRPlugin::pluginStatic_ = 0L;
+
+
+void OTRPlugin::slotNewChatSessionWindow( Kopete::ChatSession *KMM )
+{
+ //Check if there is another user in the session.
+ //If not it could be a Jabber-MUC
+ //If there are more then one members it is a MUC
+ // Also don't add the Button on an IRC window!
+ if( KMM->members().count() == 1 && (KMM->protocol()) && ( KMM->protocol()->pluginId() != "IRCProtocol" ) ){
+ new OtrGUIClient( KMM );
+ }
+}
+
+
+void OTRPlugin::slotOutgoingMessage( Kopete::Message& msg )
+{
+ if( msg.direction() == Kopete::Message::Outbound ){
+ QString plainBody = msg.plainBody();
+ QString accountId = msg.manager()->account()->accountId();
+ Kopete::Contact *contact = msg.to().first();
+
+ QString encBody = otrlChatInterface->encryptMessage( plainBody, accountId, msg.manager()->account()->protocol()->displayName(), contact->contactId(), msg.manager() );
+ msg.setBody( encBody, Kopete::Message::Crypted );
+ if( !msg.plainBody().isEmpty() ){
+ messageCache.insert( encBody, plainBody );
+ }
+ }
+}
+
+void OTRPlugin::slotEnableOtr( Kopete::ChatSession *session, bool enable ){
+
+
+ if( enable ){
+ QString policy = session->members().getFirst()->metaContact()->pluginData( OTRPlugin::plugin(), "otr_policy" );
+ bool noerr;
+ KopeteOtrKcfg::self()->readConfig();
+ if( policy.toInt( &noerr, 10 ) == 4 || ( policy.toInt( &noerr, 10 ) == 0 && KopeteOtrKcfg::self()->rbNever() ) ){
+ Kopete::Message msg( session->account()->myself(), session->members(), i18n( "Your policy settings do not allow encrypted sessions to this contact." ), Kopete::Message::Internal, Kopete::Message::RichText );
+ session->appendMessage( msg );
+ } else {
+ QString body = otrlChatInterface->getDefaultQuery( session->account()->accountId() );
+ Kopete::Message msg1( session->account()->myself(), session->members().getFirst(), QString( body ), Kopete::Message::Outbound );
+ if( otrlChatInterface->privState( session ) > 0 ){
+ body = i18n("Attempting to refresh the OTR session with <b>%1</b>...").arg( otrlChatInterface->formatContact( session->members().getFirst()->contactId() ) );
+ } else {
+ body = i18n("Attempting to start a private OTR session with <b>%1</b>...").arg( otrlChatInterface->formatContact( session->members().getFirst()->contactId() ) );
+ }
+ Kopete::Message msg2( session->account()->myself(), session->members().getFirst(), body, Kopete::Message::Internal, Kopete::Message::RichText );
+
+ session->sendMessage( msg1 );
+ session->appendMessage( msg2 );
+ }
+ } else {
+ otrlChatInterface->disconnectSession( session );
+ }
+
+}
+
+void OTRPlugin::slotVerifyFingerprint( Kopete::ChatSession *session ){
+ otrlChatInterface->verifyFingerprint( session );
+}
+
+void OTRPlugin::slotSettingsChanged(){
+ KopeteOtrKcfg::self()->readConfig();
+ if( KopeteOtrKcfg::self()->rbAlways() ){
+ otrlChatInterface->setPolicy( OTRL_POLICY_ALWAYS );
+ } else if( KopeteOtrKcfg::self()->rbOpportunistic() ){
+ otrlChatInterface->setPolicy( OTRL_POLICY_OPPORTUNISTIC );
+ } else if( KopeteOtrKcfg::self()->rbManual() ){
+ otrlChatInterface->setPolicy( OTRL_POLICY_MANUAL );
+ } else if( KopeteOtrKcfg::self()->rbNever() ){
+ otrlChatInterface->setPolicy( OTRL_POLICY_NEVER );
+ } else {
+ otrlChatInterface->setPolicy( OTRL_POLICY_DEFAULT );
+ }
+}
+
+void OTRPlugin::emitGoneSecure( Kopete::ChatSession *session, int status){
+ emit goneSecure( session, status );
+}
+
+QMap<QString, QString> OTRPlugin::getMessageCache(){
+ return messageCache;
+}
+
+void OtrMessageHandler::handleMessage( Kopete::MessageEvent *event ){
+ Kopete::Message msg = event->message();
+ Kopete::ChatSession *session = msg.manager();
+ QMap<QString, QString> messageCache = OTRPlugin::plugin()->getMessageCache();
+
+ if( msg.direction() == Kopete::Message::Inbound ){
+ QString body = msg.parsedBody();
+kdDebug() << "Received Message: " << msg.parsedBody() << endl;
+ QString accountId = msg.manager()->account()->accountId();
+ QString contactId = msg.from()->contactId();
+ int ignoremessage = OtrlChatInterface::self()->decryptMessage( &body, accountId, msg.manager()->account()->protocol()->displayName(), contactId, msg.manager() );
+ msg.setBody( body, Kopete::Message::RichText );
+ if( ignoremessage | OtrlChatInterface::self()->shouldDiscard( msg.plainBody() ) ){
+ event->discard();
+ return;
+ }
+ } else if( msg.direction() == Kopete::Message::Outbound ){
+ if( messageCache.contains( msg.plainBody() ) ){
+ msg.setBody( messageCache[msg.plainBody()] );
+ messageCache.remove( messageCache[msg.plainBody()] );
+ if(messageCache.count() > 5) messageCache.clear();
+ }
+ // Check if Message is an OTR message. Should it be discarded or shown?
+ if( OtrlChatInterface::self()->shouldDiscard( msg.plainBody() ) ){
+ event->discard();
+ kdDebug() << "discarding" << endl;
+ return;
+ }
+ // If the message is sent while a Finished state libotr deletes the messagetext.
+ // This prevents the empty message from beeing shown in out chatwindow
+ if( msg.plainBody().isEmpty() ){
+ event->discard();
+ return;
+ }
+ }
+
+ event->setMessage( msg );
+
+ MessageHandler::handleMessage( event );
+}
+
+
+void OTRPlugin::slotSelectionChanged( bool single){
+ otrPolicyMenu->setEnabled( single );
+
+ if ( !single )
+ return;
+
+ Kopete::MetaContact *metaContact = Kopete::ContactList::self()->selectedMetaContacts().first();
+
+ QString policy = metaContact->pluginData( this, "otr_policy" );
+
+ bool noerr;
+ if ( !policy.isEmpty() && policy != "null" )
+ otrPolicyMenu->setCurrentItem( policy.toInt( &noerr, 10 ));
+ else
+ otrPolicyMenu->setCurrentItem( 0 );
+
+}
+
+void OTRPlugin::slotSetPolicy(){
+ kdDebug() << "Setting contact policy" << endl;
+ Kopete::MetaContact *metaContact = Kopete::ContactList::self()->selectedMetaContacts().first();
+ if( metaContact ){
+ metaContact->setPluginData( this, "otr_policy", QString::number( otrPolicyMenu->currentItem() ) );
+ }
+}
+
+void OTRPlugin::accountReady( Kopete::Account *account ){
+ kdDebug() << "Account " << account->accountId() << " ready. Calling update function."<< endl;
+ otrlChatInterface->updateKeyfile( account );
+}
+
+
+#include "otrplugin.moc"
+
+// vim: set noet ts=4 sts=4 sw=4:
+
diff --git a/src/otrplugin.h b/src/otrplugin.h
new file mode 100644
index 0000000..2ce051d
--- /dev/null
+++ b/src/otrplugin.h
@@ -0,0 +1,118 @@
+/***************************************************************************
+ otrplugin.h - description
+ -------------------
+ begin : 11 03 2007
+ copyright : (C) 2007-2007 by Michael Zanetti
+ email : michael_zanetti@gmx.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef OTRPLUGIN_H
+#define OTRPLUGIN_H
+
+
+#include "kdebug.h"
+
+#include <kopeteplugin.h>
+#include <kopetemessagehandler.h>
+
+#include "otrlchatinterface.h"
+
+
+/**
+ * @author Michael Zanetti
+ */
+
+class OTRPlugin;
+class KSelectAction;
+
+class OtrMessageHandler : public Kopete::MessageHandler
+{
+private:
+ OTRPlugin *plugin;
+public:
+ OtrMessageHandler( OTRPlugin *plugin ) : plugin(plugin) {
+ kdDebug() << "MessageHandler created" << endl;
+ }
+ ~OtrMessageHandler(){
+ kdDebug() << "MessageHandler destroyed" << endl;
+ }
+ void handleMessage( Kopete::MessageEvent *event );
+};
+
+class OtrMessageHandlerFactory : public Kopete::MessageHandlerFactory
+{
+private:
+ OTRPlugin *plugin;
+ OtrMessageHandler *messageHandler;
+public:
+ OtrMessageHandlerFactory( OTRPlugin *plugin ) : plugin(plugin) {}
+ Kopete::MessageHandler *create( Kopete::ChatSession *, Kopete::Message::MessageDirection direction )
+ {
+ return new OtrMessageHandler(plugin);
+ }
+ int filterPosition( Kopete::ChatSession *, Kopete::Message::MessageDirection )
+ {
+ return Kopete::MessageHandlerFactory::InStageToSent+1;
+ }
+};
+
+class OTRPlugin : public Kopete::Plugin
+{
+ Q_OBJECT
+
+public:
+
+ static OTRPlugin *plugin();
+
+ OTRPlugin( QObject *parent, const char *name, const QStringList &args );
+ ~OTRPlugin();
+
+ void emitGoneSecure( Kopete::ChatSession *session, int status );
+ QMap<QString, QString> getMessageCache();
+
+public slots:
+
+ void slotOutgoingMessage( Kopete::Message& msg );
+ void slotEnableOtr( Kopete::ChatSession *session, bool enable );
+ void slotSettingsChanged();
+ void slotVerifyFingerprint( Kopete::ChatSession *session );
+
+private slots:
+ void slotNewChatSessionWindow(Kopete::ChatSession * );
+ void slotSelectionChanged( bool single );
+ void slotSetPolicy();
+ void accountReady( Kopete::Account *account );
+
+private:
+ static OTRPlugin* pluginStatic_;
+ OtrMessageHandlerFactory *m_inboundHandler;
+ OtrlChatInterface *otrlChatInterface;
+ QMap<QString, QString> messageCache;
+ KSelectAction* otrPolicyMenu;
+
+/* KActionMenu *otrPolicyMenuBar;
+ KActionMenu *otrPolicyPopup;
+ KAction *otrPolicyDefault;
+ KAction *otrPolicyAlways;
+ KAction *otrPolicyOpportunistic;
+ KAction *otrPolicyManual;
+ KAction *otrPolicyNever;
+// SessionManager manager
+*/
+
+signals:
+ void goneSecure( Kopete::ChatSession *session, int state );
+
+
+};
+
+#endif
diff --git a/src/otrpreferences.cpp b/src/otrpreferences.cpp
new file mode 100644
index 0000000..b056d58
--- /dev/null
+++ b/src/otrpreferences.cpp
@@ -0,0 +1,199 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti
+ *
+ * *
+ * 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 <qlayout.h>
+#include <qlabel.h>
+#include <qmap.h>
+#include <qptrlist.h>
+#include <qcombobox.h>
+#include <qstringlist.h>
+#include <qtable.h>
+#include <qpaintdevicemetrics.h>
+#include <qvbox.h>
+#include <qradiobutton.h>
+#include <qtabwidget.h>
+
+#include <kgenericfactory.h>
+#include <kurlrequester.h>
+#include <kmessagebox.h>
+#include <kconfig.h>
+#include <kapplication.h>
+#include <kanimwidget.h>
+#include <kpassivepopup.h>
+#include <kiconloader.h>
+#include <kstandarddirs.h>
+#include <kactivelabel.h>
+
+#include <kopeteaccountmanager.h>
+#include <kopeteaccount.h>
+#include <kopeteprotocol.h>
+
+#include "otrprefs.h"
+#include "otrpreferences.h"
+#include "otrplugin.h"
+#include "kopete_otr.h"
+
+/**
+ * @author Michael Zanetti
+ */
+
+typedef KGenericFactory<OTRPreferences> OTRPreferencesFactory;
+K_EXPORT_COMPONENT_FACTORY( kcm_kopete_otr, OTRPreferencesFactory("kcm_kopete_otr"))
+
+OTRPreferences::OTRPreferences(QWidget *parent, const char* /*name*/, const QStringList &args)
+ : KCModule(OTRPreferencesFactory::instance(), parent, args)
+{
+ ( new QVBoxLayout( this ) )->setAutoAdd( true );
+ preferencesDialog = new OTRPrefsUI(this);
+
+
+ this->addConfig( KopeteOtrKcfg::self(), preferencesDialog );
+ KopeteOtrKcfg::self()->readConfig();
+ load();
+
+
+
+ otrlConfInterface = new OtrlConfInterface( preferencesDialog );
+
+ connect( preferencesDialog->btGenFingerprint, SIGNAL(clicked()), SLOT(generateFingerprint()));
+ connect( preferencesDialog->cbKeys, SIGNAL(activated(int)), SLOT(showPrivFingerprint(int)));
+ connect( preferencesDialog->btVerify, SIGNAL(clicked()), SLOT(verifyFingerprint()));
+ connect( preferencesDialog->twSettings, SIGNAL(currentChanged(QWidget *)), SLOT(fillFingerprints()));
+ connect( preferencesDialog->tbFingerprints, SIGNAL(currentChanged(int, int)), SLOT(updateButtons(int, int)));
+ connect( preferencesDialog->btForget, SIGNAL( clicked() ), SLOT( forgetFingerprint() ) );
+
+ int index = 0;
+ int accountnr = 0;
+ QPtrList<Kopete::Account> accounts = Kopete::AccountManager::self()->accounts();
+ if( !accounts.isEmpty() ){
+ for ( QPtrListIterator<Kopete::Account> it( accounts );
+ Kopete::Account *account = it.current();
+ ++it ){
+ if ( account->protocol()->pluginId() != "IRCProtocol" ){
+ preferencesDialog->cbKeys->insertItem(account->accountId() + " (" + account->protocol()->displayName() + ")");
+ privKeys.insert(index++, accountnr);
+ }
+ accountnr++;
+ }
+ }
+ showPrivFingerprint( preferencesDialog->cbKeys->currentItem() );
+
+ preferencesDialog->tbFingerprints->setColumnWidth( 0, 200 );
+ preferencesDialog->tbFingerprints->setColumnWidth( 1, 80 );
+ preferencesDialog->tbFingerprints->setColumnWidth( 2, 60 );
+ preferencesDialog->tbFingerprints->setColumnWidth( 3, 400 );
+ preferencesDialog->tbFingerprints->setColumnWidth( 4, 200 );
+
+}
+
+OTRPreferences::~OTRPreferences(){
+}
+
+void OTRPreferences::generateFingerprint()
+{
+ QPtrList<Kopete::Account> accounts = Kopete::AccountManager::self()->accounts();
+
+ if( (accounts.isEmpty())){
+ return;
+ }
+
+
+ Kopete::Account *account = accounts.at( privKeys[preferencesDialog->cbKeys->currentItem()] );
+
+ if ((otrlConfInterface->hasPrivFingerprint( account->accountId(), account->protocol()->displayName() ) ) && (KMessageBox::questionYesNo(this, i18n("Selected account already has a key. Do you want to create a new one?"), i18n("Overwrite key?")) !=3)) return;
+
+ otrlConfInterface->generateNewPrivKey( account->accountId(), account->protocol()->displayName() );
+ showPrivFingerprint( preferencesDialog->cbKeys->currentItem() );
+}
+
+void OTRPreferences::showPrivFingerprint( int accountnr )
+{
+ QPtrList<Kopete::Account> accounts = Kopete::AccountManager::self()->accounts();
+ if( !accounts.isEmpty() ){
+ Kopete::Account *account = accounts.at(privKeys[accountnr]);
+ preferencesDialog->tlFingerprint->setText( otrlConfInterface->getPrivFingerprint( account->accountId(), account->protocol()->displayName() ) );
+ }
+}
+
+void OTRPreferences::fillFingerprints(){
+ QTable *fingerprintsTable = preferencesDialog->tbFingerprints;
+ preferencesDialog->tbFingerprints->setNumRows(0);
+ QValueList<QString[5]> list = otrlConfInterface->readAllFingerprints();
+ QValueList<QString[5]>::iterator it;
+ int j = 0;
+ for( it = list.begin(); it != list.end(); ++it ){
+ preferencesDialog->tbFingerprints->setNumRows( preferencesDialog->tbFingerprints->numRows() +1 );
+ (*it)[0] = OtrlChatInterface::self()->formatContact((*it)[0]);
+ for( int i = 0; i < 5; i++ ){
+ //preferencesDialog->tbFingerprints->setText(j, i, (*it)[i] );
+ fingerprintsTable->setItem(j,i, new QAlignTableItem(fingerprintsTable, QTableItem::Never,(*it)[i],Qt::AlignLeft));
+ }
+ j++;
+ }
+ updateButtons( preferencesDialog->tbFingerprints->currentRow(), preferencesDialog->tbFingerprints->currentColumn() );
+}
+
+void OTRPreferences::verifyFingerprint(){
+
+ int doVerify = KMessageBox::questionYesNo(
+ this,
+ i18n("Please contact %1 via another secure way and verify that the following Fingerprint is correct:").arg(preferencesDialog->tbFingerprints->text( preferencesDialog->tbFingerprints->currentRow(), 0 )) + "\n\n" + preferencesDialog->tbFingerprints->text( preferencesDialog->tbFingerprints->currentRow(), 3 ) + "\n\n" + i18n("Are you sure you want to trust this fingerprint?"), i18n("Verify fingerprint") );
+
+
+ if( doVerify == KMessageBox::Yes ){
+ otrlConfInterface->verifyFingerprint( preferencesDialog->tbFingerprints->text( preferencesDialog->tbFingerprints->currentRow(), 3 ), true );
+ } else {
+ otrlConfInterface->verifyFingerprint( preferencesDialog->tbFingerprints->text( preferencesDialog->tbFingerprints->currentRow(), 3 ), false );
+ }
+ fillFingerprints();
+}
+
+void OTRPreferences::updateButtons( int row, int col ){
+ if( row != -1 ){
+ if( !otrlConfInterface->isEncrypted( preferencesDialog->tbFingerprints->text( row, 3 ) ) ){
+ preferencesDialog->btForget->setEnabled( true );
+ } else {
+ preferencesDialog->btForget->setEnabled( false );
+ }
+ preferencesDialog->btVerify->setEnabled( true );
+ } else {
+ preferencesDialog->btVerify->setEnabled( false );
+ preferencesDialog->btForget->setEnabled( false );
+ }
+}
+
+void OTRPreferences::forgetFingerprint(){
+ if( !otrlConfInterface->isEncrypted( preferencesDialog->tbFingerprints->text( preferencesDialog->tbFingerprints->currentRow(), 3 ) ) ){
+ otrlConfInterface->forgetFingerprint( preferencesDialog->tbFingerprints->text( preferencesDialog->tbFingerprints->currentRow(), 3 ) );
+ fillFingerprints();
+ } else {
+ updateButtons( preferencesDialog->tbFingerprints->currentRow(), preferencesDialog->tbFingerprints->currentColumn() );
+ }
+}
+
+QAlignTableItem :: QAlignTableItem( QTable *table, EditType editType, const QString& text, int alignment )
+ : QTableItem( table, editType, text ) {
+ align = alignment;
+}
+
+
+#include "otrpreferences.moc"
+
+// vim: set noet ts=4 sts=4 sw=4:
diff --git a/src/otrpreferences.h b/src/otrpreferences.h
new file mode 100644
index 0000000..0de6d5d
--- /dev/null
+++ b/src/otrpreferences.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti
+ *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef OTRPREFERECES_H
+#define OTRPREFERECES_H
+
+#include <kcmodule.h>
+#include "otrlconfinterface.h"
+
+/**
+ * Preference widget for the OTR plugin
+ * @author Michael Zanetti
+ */
+
+class OTRPreferences : public KCModule {
+ Q_OBJECT
+
+public:
+ OTRPreferences(QWidget *parent = 0, const char *name = 0, const QStringList &args = QStringList());
+ ~OTRPreferences();
+
+private:
+ OTRPrefsUI *preferencesDialog;
+ OtrlConfInterface *otrlConfInterface;
+ QMap<int, int> privKeys;
+
+private slots: // Public slots
+ void generateFingerprint();
+ void showPrivFingerprint(int accountnr);
+ void verifyFingerprint();
+ void fillFingerprints();
+ void updateButtons(int row, int col);
+ void forgetFingerprint();
+
+};
+
+
+class QAlignTableItem : public QTableItem {
+
+public :
+ QAlignTableItem(QTable *table, EditType editType, const QString& text, int alignment);
+
+private :
+ int align;
+};
+
+#endif
diff --git a/src/otrprefs.ui b/src/otrprefs.ui
new file mode 100644
index 0000000..da1e238
--- /dev/null
+++ b/src/otrprefs.ui
@@ -0,0 +1,295 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>OTRPrefsUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>OTRPrefsUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>480</width>
+ <height>358</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>twSettings</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>settings</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Settings</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Private Keys</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="0" column="2">
+ <property name="name">
+ <cstring>btGenFingerprint</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Generate</string>
+ </property>
+ <property name="accel">
+ <string>Alt+G</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="0" column="1">
+ <property name="name">
+ <cstring>cbKeys</cstring>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>400</width>
+ <height>32767</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Account:</string>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>tlFingerprint</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>No Fingerprint</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QButtonGroup" row="1" column="0">
+ <property name="name">
+ <cstring>bgPolicy</cstring>
+ </property>
+ <property name="title">
+ <string>Default Policy</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>kcfg_rbOpportunistic</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Opportunistic</string>
+ </property>
+ <property name="accel">
+ <string>Alt+O</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Encrypt messages automatically if the other side supports OTR</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_rbNever</cstring>
+ </property>
+ <property name="text">
+ <string>Ne&amp;ver</string>
+ </property>
+ <property name="accel">
+ <string>Alt+V</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Never encrypt messages</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_rbManual</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Manual</string>
+ </property>
+ <property name="accel">
+ <string>Alt+M</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Encrypt messages if the other side requests an OTR connection</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>kcfg_rbAlways</cstring>
+ </property>
+ <property name="autoMask">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Al&amp;ways</string>
+ </property>
+ <property name="accel">
+ <string>Alt+W</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Always encrypt messages</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>161</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>fingerprints</cstring>
+ </property>
+ <attribute name="title">
+ <string>K&amp;nown Fingerprints</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTable" row="0" column="0" rowspan="1" colspan="2">
+ <column>
+ <property name="text">
+ <string>User</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Status</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Verified</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Fingerprint</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Protocol</string>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>tbFingerprints</cstring>
+ </property>
+ <property name="numRows">
+ <number>1</number>
+ </property>
+ <property name="numCols">
+ <number>5</number>
+ </property>
+ <property name="showGrid">
+ <bool>true</bool>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="sorting">
+ <bool>false</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>SingleRow</enum>
+ </property>
+ <property name="focusStyle">
+ <enum>FollowStyle</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="0">
+ <property name="name">
+ <cstring>btVerify</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Verify Fingerprint</string>
+ </property>
+ <property name="accel">
+ <string>Alt+V</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>btForget</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>F&amp;orget Fingerprint</string>
+ </property>
+ <property name="accel">
+ <string>Alt+O</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<slots>
+ <slot access="private">generateFingerprint()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kactivelabel.h</includehint>
+</includehints>
+</UI>
diff --git a/src/otrui.rc b/src/otrui.rc
new file mode 100644
index 0000000..7b889e3
--- /dev/null
+++ b/src/otrui.rc
@@ -0,0 +1,12 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="kopete_otr" version="1">
+ <MenuBar>
+ <Menu name="edit">
+ <text>&amp;Edit</text>
+ <Action name="otr_policy" />
+ </Menu>
+ </MenuBar>
+ <Menu name="contact_popup">
+ <Action name="otr_policy" />
+ </Menu>
+</kpartgui>
diff --git a/src/pics/Makefile.am b/src/pics/Makefile.am
new file mode 100644
index 0000000..60c5e4f
--- /dev/null
+++ b/src/pics/Makefile.am
@@ -0,0 +1,4 @@
+icondir = $(kde_datadir)/kopete_otr/icons
+icon_ICON = AUTO
+KDE_ICON = kopete_otr
+
diff --git a/src/pics/cr16-action-otr_disabled.png b/src/pics/cr16-action-otr_disabled.png
new file mode 100644
index 0000000..90e5806
--- /dev/null
+++ b/src/pics/cr16-action-otr_disabled.png
Binary files differ
diff --git a/src/pics/cr16-action-otr_finished.png b/src/pics/cr16-action-otr_finished.png
new file mode 100644
index 0000000..ab9a68d
--- /dev/null
+++ b/src/pics/cr16-action-otr_finished.png
Binary files differ
diff --git a/src/pics/cr16-action-otr_private.png b/src/pics/cr16-action-otr_private.png
new file mode 100644
index 0000000..2fc54e2
--- /dev/null
+++ b/src/pics/cr16-action-otr_private.png
Binary files differ
diff --git a/src/pics/cr16-action-otr_unverified.png b/src/pics/cr16-action-otr_unverified.png
new file mode 100644
index 0000000..e1db6c6
--- /dev/null
+++ b/src/pics/cr16-action-otr_unverified.png
Binary files differ
diff --git a/src/pics/cr16-app-kopete_otr.png b/src/pics/cr16-app-kopete_otr.png
new file mode 100644
index 0000000..0f2ce8e
--- /dev/null
+++ b/src/pics/cr16-app-kopete_otr.png
Binary files differ
diff --git a/src/pics/cr16-app-otr.png b/src/pics/cr16-app-otr.png
new file mode 100644
index 0000000..2fc54e2
--- /dev/null
+++ b/src/pics/cr16-app-otr.png
Binary files differ
diff --git a/src/pics/cr22-action-otr_disabled.png b/src/pics/cr22-action-otr_disabled.png
new file mode 100644
index 0000000..fe9332a
--- /dev/null
+++ b/src/pics/cr22-action-otr_disabled.png
Binary files differ
diff --git a/src/pics/cr22-action-otr_finished.png b/src/pics/cr22-action-otr_finished.png
new file mode 100644
index 0000000..f85fa05
--- /dev/null
+++ b/src/pics/cr22-action-otr_finished.png
Binary files differ
diff --git a/src/pics/cr22-action-otr_private.png b/src/pics/cr22-action-otr_private.png
new file mode 100644
index 0000000..767f0a0
--- /dev/null
+++ b/src/pics/cr22-action-otr_private.png
Binary files differ
diff --git a/src/pics/cr22-action-otr_unverified.png b/src/pics/cr22-action-otr_unverified.png
new file mode 100644
index 0000000..b37b39e
--- /dev/null
+++ b/src/pics/cr22-action-otr_unverified.png
Binary files differ
diff --git a/src/pics/cr32-action-otr_disabled.png b/src/pics/cr32-action-otr_disabled.png
new file mode 100644
index 0000000..39e2aba
--- /dev/null
+++ b/src/pics/cr32-action-otr_disabled.png
Binary files differ
diff --git a/src/pics/cr32-action-otr_finished.png b/src/pics/cr32-action-otr_finished.png
new file mode 100644
index 0000000..c0158fc
--- /dev/null
+++ b/src/pics/cr32-action-otr_finished.png
Binary files differ
diff --git a/src/pics/cr32-action-otr_private.png b/src/pics/cr32-action-otr_private.png
new file mode 100644
index 0000000..cbf4b6a
--- /dev/null
+++ b/src/pics/cr32-action-otr_private.png
Binary files differ
diff --git a/src/pics/cr32-action-otr_unverified.png b/src/pics/cr32-action-otr_unverified.png
new file mode 100644
index 0000000..fa3d91e
--- /dev/null
+++ b/src/pics/cr32-action-otr_unverified.png
Binary files differ
diff --git a/src/privkeypopup.cpp b/src/privkeypopup.cpp
new file mode 100644
index 0000000..0fbdc60
--- /dev/null
+++ b/src/privkeypopup.cpp
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+/**
+ * @author Michael Zanetti
+ */
+
+
+#include "privkeypopup.h"
+
+PrivKeyPopup::PrivKeyPopup(QWidget* parent, const char* name, WFlags fl)
+: PrivKeyPopupUI(parent,name,fl)
+{
+}
+
+PrivKeyPopup::~PrivKeyPopup()
+{
+}
+
+void PrivKeyPopup::setCloseLock( bool locked ){
+ closeLock = locked;
+}
+
+void PrivKeyPopup::closeEvent( QCloseEvent *e ){
+ if( closeLock ){
+ e->ignore();
+ } else {
+ e->accept();
+ }
+}
+/*$SPECIALIZATION$*/
+
+
+#include "privkeypopup.moc"
+
diff --git a/src/privkeypopup.h b/src/privkeypopup.h
new file mode 100644
index 0000000..7730356
--- /dev/null
+++ b/src/privkeypopup.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti *
+ * michael_zanetti@gmx.net *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef PRIVKEYPOPUP_H
+#define PRIVKEYPOPUP_H
+
+#include "privkeypopupui.h"
+
+/**
+ * @author Michael Zanetti
+ */
+
+class PrivKeyPopup : public PrivKeyPopupUI
+{
+ Q_OBJECT
+
+public:
+ PrivKeyPopup(QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~PrivKeyPopup();
+ void setCloseLock( bool locked );
+ /*$PUBLIC_FUNCTIONS$*/
+
+public slots:
+ /*$PUBLIC_SLOTS$*/
+
+protected:
+ /*$PROTECTED_FUNCTIONS$*/
+ bool closeLock;
+
+ void closeEvent( QCloseEvent *e );
+
+protected slots:
+ /*$PROTECTED_SLOTS$*/
+
+};
+
+#endif
+
diff --git a/src/privkeypopupui.ui b/src/privkeypopupui.ui
new file mode 100644
index 0000000..e9fdd75
--- /dev/null
+++ b/src/privkeypopupui.ui
@@ -0,0 +1,64 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>PrivKeyPopupUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>PrivKeyPopupUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>507</width>
+ <height>111</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Generating private key</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>tlWait</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ <italic>1</italic>
+ </font>
+ </property>
+ <property name="text">
+ <string>Please wait while generating the private key</string>
+ </property>
+ </widget>
+ <widget class="QFrame" row="0" column="1">
+ <property name="name">
+ <cstring>animFrame</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>72</width>
+ <height>72</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/smppopup.cpp b/src/smppopup.cpp
new file mode 100644
index 0000000..a431e10
--- /dev/null
+++ b/src/smppopup.cpp
@@ -0,0 +1,71 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti *
+ * michael_zanetti@gmx.net *
+ * *
+ * 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 "qlabel.h"
+
+#include "kdebug.h"
+#include "klocale.h"
+#include "klineedit.h"
+#include "kurl.h"
+#include "krun.h"
+
+#include "smppopup.h"
+#include "verifypopup.h"
+
+SMPPopup::SMPPopup(QWidget* parent, const char* name, WFlags fl, ConnContext *context, Kopete::ChatSession *session, bool initiate )
+: SMPPopupUI(parent,name,fl)
+{
+ this->context = context;
+ this->session = session;
+ this->initiate = initiate;
+ tlText->setText( i18n("Please enter the secret passphrase to authenticate %1:").arg(OtrlChatInterface::self()->formatContact(session->members().getFirst()->contactId())));
+}
+
+SMPPopup::~SMPPopup()
+{
+}
+
+/*$SPECIALIZATION$*/
+void SMPPopup::cancelSMP()
+{
+ OtrlChatInterface::self()->abortSMP( context, session );
+ this->close();
+}
+
+void SMPPopup::respondSMP()
+{
+ OtrlChatInterface::self()->respondSMP( context, session, leSecret->text(), initiate );
+ this->close();
+}
+
+void SMPPopup::openHelp()
+{
+ KURL *url = new KURL("http://www.cypherpunks.ca/otr/help/authenticate.php?lang=en");
+ new KRun(*url, 0, false, true);
+}
+
+void SMPPopup::manualAuth(){
+ VerifyPopup *vfPopup = new VerifyPopup(this, i18n("Verify Fingerprint"), session);
+ vfPopup->show();
+ this->close();
+}
+
+#include "smppopup.moc"
+
diff --git a/src/smppopup.h b/src/smppopup.h
new file mode 100644
index 0000000..b486c65
--- /dev/null
+++ b/src/smppopup.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti *
+ * michael_zanetti@gmx.net *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef SMPPOPUP_H
+#define SMPPOPUP_H
+
+#include "kopetechatsession.h"
+
+#include "smppopupui.h"
+#include "otrlchatinterface.h"
+
+extern "C"{
+#include "libotr/proto.h"
+}
+
+class SMPPopup : public SMPPopupUI
+{
+ Q_OBJECT
+
+public:
+ SMPPopup(QWidget* parent = 0, const char* name = 0, WFlags fl = 0, ConnContext *context = 0, Kopete::ChatSession *session = 0, bool initiate = true );
+ ~SMPPopup();
+ /*$PUBLIC_FUNCTIONS$*/
+
+public slots:
+ /*$PUBLIC_SLOTS$*/
+ virtual void cancelSMP();
+ virtual void respondSMP();
+ virtual void openHelp();
+ virtual void manualAuth();
+
+protected:
+ /*$PROTECTED_FUNCTIONS$*/
+
+ ConnContext *context;
+ Kopete::ChatSession *session;
+ bool initiate;
+
+protected slots:
+ /*$PROTECTED_SLOTS$*/
+
+};
+
+#endif
+
diff --git a/src/smppopupui.ui b/src/smppopupui.ui
new file mode 100644
index 0000000..4120e3c
--- /dev/null
+++ b/src/smppopupui.ui
@@ -0,0 +1,191 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>SMPPopupUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>SMPPopupUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>536</width>
+ <height>158</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Enter authentication secret</string>
+ </property>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>pbOK</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>430</x>
+ <y>110</y>
+ <width>90</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="accel">
+ <string>Alt+O</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>pbCancel</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>330</x>
+ <y>110</y>
+ <width>91</width>
+ <height>31</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="accel">
+ <string>Alt+C</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>leSecret</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>120</x>
+ <y>70</y>
+ <width>400</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>tlText</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>124</x>
+ <y>10</y>
+ <width>390</width>
+ <height>50</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Please enter the secret passphrase to authenticate this contact.</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pLIcon</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>30</y>
+ <width>50</width>
+ <height>50</height>
+ </rect>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>pbManual</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>110</x>
+ <y>110</y>
+ <width>160</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&amp;Manual Authentication</string>
+ </property>
+ <property name="accel">
+ <string>Alt+M</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>pbHelp</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>110</y>
+ <width>90</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&amp;Help</string>
+ </property>
+ <property name="accel">
+ <string>Alt+H</string>
+ </property>
+ </widget>
+</widget>
+<images>
+ <image name="image0">
+ <data format="PNG" length="1360">89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000517494441545885c5975d68544714c77f7b5db39b98adf95851a34913158dd1b452db2a488badb5155bfba22f3e54a4da421ffa609fa42fea83a0f8509fc5071529a894422988156cc552d4b40113129ae826249b8fc664f3b17befeede3b7766fa70633edc9bcdfa517ae0b2c3ec9df9ffce393367e6c2ff6c81671d70f6ecb5b052aa1ea80b0428d39acf95523d528a96870fdb2e9e3f7f7a0490ff09c09933df6f0f04025b57adaa0aad5cb98468743152cae3c9a4c5a347fdf4f58d904e9be75a5bef9fb87af5dc502120c142844f9ebc180e040207972faf5cba7bf756caca220402b3d9376d5acbe0e030376ffef9a5d65bde1d1a1af8f8f6ed9fe380c837f782f9c48f1d3b1f564a1f6c6c5cbd74dfbef7282e0e23a5249d4e639a2696656dcf64321886414545191b36d4313c3c1e0d85a2bb1c277bbdbfbf3b05a8e706d8b66df70735354bd7eddfbf13e089287d7d8f696fefa1ab6b60bb942eb69dc6b66d2291080d0d75c462f16830f84a4553d3ad5f0107d0cf0c70e4c877658661ec3d74e8138a8bc32493499249936bd76e73e7ce03f1e0415b4f2cd65bdad939581a8f274a4b4a0c5cd7211a8d5255554e6b6bfc3521c42f7d7db17f00d74f23ef1a504a6fddb8b18ecaca322ccbc2b66d2e5fbe4947c7c3aeebd72f350d0dc54da005d0070e1cfd7a74347978cf9e370887c3545757b3624505f5f56f7e71f7ee8d76c0f68330f2010821963534d4a1b5c6344d9a9b3be9ea8a8f5db870f2f7a1a1f828300e7403dd972e9dfa369148fc78efde437a7b7b0158bffe550c63613d100116fa69e405705df9eaaa55556432198410343777d2d3d3f13790054cc00292400a48f4f5751defee7e4c369b656c6c8cdada65048345af038b9e0bc0715c8a8b4308211042e03882f1f144122f9c4f2f2c75e3c6a576cbca2284606464844864118ee302143147bae74b018ee3e0380eaeeb22844029adf10a8cdfd6924208b4d64829a7c0f116bb6fd19b270202dbb6b16d7b7232172925ccb1a500ed385edd715d77123e6f1dca0fa0b5c6b66d1cc799f45ea1e7929e316626809e67806f5edace36d41b06cb7febed24db761129250b1c87cd65dd6cfe30b1a66aefdaf2c5c50b8461a0811d33c7fe31d049c59843d029412e2c62476d279f1d5d7d3800773e3d15bbcc53e9cbc94bd3e9865d0b17b025525343a4ba26bfbb9e1d9fef8554bc97546f2f89943cbfe344c73778bb47f946209d61cb9a8fdea7eaed46d08ff016fb8bd992b7d631d0b48c891bf70f03a7810120ed0b30616942e551b0aebc1471004c9b506c88096b11403990981320696adc4c3f64ad9723ee2a6819c44d2b92a606af204d2d7e9f0880b415647dcf8e6733a9a0fd31a46ca41364c2c7a7dc08581ad75690cdbf7fe7354742f728980e488deb289256ee96cc8d80a9716d099917888069c3401284f2a2a03c8009b300005782769f330552c1681a5236280d524f0168a9717d6e88fef7019127056ad20bada70bb2ab4048b09c59a2d3bf936d1ff30770d5740a828657aeb49e9e4ca9c94967b4fdfa6601f897e4390024d8024a439eb8d4d31ecd122db0efb922505234dd7e2a9fd30279fa72009e2502a1a0e7b9abc8c9a35f6e0b85f231dfe37860d800a3d203987aa43749bebe9cffa79f8154a8b00848a5e33ffdf05775ac71392b226970b39e074f56fdccf6938539ab9dfb5e7faa88b69152d28e6cc53b8ea7f291731cefac5f1aa9ad2c79a72868546b5dd0b7e35705bcc34446b4dcea787c6530998d0171bc4badaf8001848030de65723e88658500e09dff16308677937601fe058d04715d6cb9690e0000000049454e44ae426082</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>pbCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>SMPPopupUI</receiver>
+ <slot>cancelSMP()</slot>
+ </connection>
+ <connection>
+ <sender>pbOK</sender>
+ <signal>clicked()</signal>
+ <receiver>SMPPopupUI</receiver>
+ <slot>respondSMP()</slot>
+ </connection>
+ <connection>
+ <sender>pbHelp</sender>
+ <signal>clicked()</signal>
+ <receiver>SMPPopupUI</receiver>
+ <slot>openHelp()</slot>
+ </connection>
+ <connection>
+ <sender>pbManual</sender>
+ <signal>clicked()</signal>
+ <receiver>SMPPopupUI</receiver>
+ <slot>manualAuth()</slot>
+ </connection>
+</connections>
+<slots>
+ <slot>manualAuth()</slot>
+ <slot>respondSMP()</slot>
+ <slot>openHelp()</slot>
+ <slot>cancelSMP()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/src/verifypopup.cpp b/src/verifypopup.cpp
new file mode 100644
index 0000000..d647948
--- /dev/null
+++ b/src/verifypopup.cpp
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti *
+ * michael_zanetti@gmx.net *
+ * *
+ * 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 "verifypopup.h"
+#include "otrlchatinterface.h"
+#include "otrplugin.h"
+
+#include "qlabel.h"
+
+#include "klocale.h"
+#include "kactivelabel.h"
+#include "kcombobox.h"
+
+#include "kopetechatsession.h"
+#include "kopetecontact.h"
+
+VerifyPopup::VerifyPopup(QWidget* parent, const char* name, Kopete::ChatSession *session, bool modal, WFlags fl)
+: VerifyPopupUI(parent,name, modal,fl)
+{
+ this->session = session;
+ alContact->setText(i18n("Verify fingerprint for %1.").arg(OtrlChatInterface::self()->formatContact(session->members().getFirst()->contactId())));
+ alFingerprint->setText(i18n("The received fingerprint is:\n\n%1\n\nContact %2 via another secure channel and verify that this fingerprint is correct.").arg(OtrlChatInterface::self()->findActiveFingerprint(session)).arg(OtrlChatInterface::self()->formatContact(session->members().getFirst()->contactId())));
+ alVerified->setText(i18n("verified that this is in fact the correct fingerprint for %1").arg(OtrlChatInterface::self()->formatContact(session->members().getFirst()->contactId())));
+ cbVerify->insertItem(i18n("I have not"));
+ cbVerify->insertItem(i18n("I have"));
+ if( OtrlChatInterface::self()->isVerified(session)){
+ cbVerify->setCurrentItem(1);
+ } else {
+ cbVerify->setCurrentItem(0);
+ }
+}
+
+VerifyPopup::~VerifyPopup()
+{
+}
+
+void VerifyPopup::cbChanged(){
+ kdDebug() << "combobox changed" << endl;
+ if( cbVerify->currentItem() == 0 ){
+ OtrlChatInterface::self()->setTrust(session, false);
+ } else {
+ OtrlChatInterface::self()->setTrust(session, true);
+ }
+ OTRPlugin::plugin()->emitGoneSecure( session, OtrlChatInterface::self()->privState( session ) );
+}
+
+/*$SPECIALIZATION$*/
+
+
+#include "verifypopup.moc"
+
diff --git a/src/verifypopup.h b/src/verifypopup.h
new file mode 100644
index 0000000..212f692
--- /dev/null
+++ b/src/verifypopup.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti *
+ * michael_zanetti@gmx.net *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef VERIFYPOPUP_H
+#define VERIFYPOPUP_H
+
+#include "verifypopupui.h"
+#include "kopetechatsession.h"
+
+class VerifyPopup : public VerifyPopupUI
+{
+ Q_OBJECT
+
+public:
+ VerifyPopup(QWidget* parent = 0, const char* name = 0, Kopete::ChatSession *session = NULL, bool modal = FALSE, WFlags fl = 0 );
+ ~VerifyPopup();
+ /*$PUBLIC_FUNCTIONS$*/
+
+public slots:
+ /*$PUBLIC_SLOTS$*/
+ virtual void cbChanged();
+
+protected:
+ /*$PROTECTED_FUNCTIONS$*/
+ Kopete::ChatSession *session;
+
+protected slots:
+ /*$PROTECTED_SLOTS$*/
+
+};
+
+#endif
+
diff --git a/src/verifypopupui.ui b/src/verifypopupui.ui
new file mode 100644
index 0000000..054858e
--- /dev/null
+++ b/src/verifypopupui.ui
@@ -0,0 +1,113 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>VerifyPopupUI</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>VerifyPopupUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>605</width>
+ <height>250</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Verify Fingerprint</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KPushButton" row="3" column="2">
+ <property name="name">
+ <cstring>pbOK</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="accel">
+ <string>Alt+O</string>
+ </property>
+ </widget>
+ <spacer row="3" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>461</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KActiveLabel" row="2" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>alVerified</cstring>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="2" column="0">
+ <property name="name">
+ <cstring>cbVerify</cstring>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>130</width>
+ <height>32767</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>alContact</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>12</pointsize>
+ </font>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>alFingerprint</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>cbVerify</sender>
+ <signal>activated(int)</signal>
+ <receiver>VerifyPopupUI</receiver>
+ <slot>cbChanged()</slot>
+ </connection>
+ <connection>
+ <sender>pbOK</sender>
+ <signal>clicked()</signal>
+ <receiver>VerifyPopupUI</receiver>
+ <slot>close()</slot>
+ </connection>
+</connections>
+<slots>
+ <slot>cbChanged()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+</includehints>
+</UI>