summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgregory guy <gregory-tde@laposte.net>2021-06-28 16:13:49 +0200
committergregory guy <gregory-tde@laposte.net>2021-07-02 17:30:02 +0200
commitd0e4d47caed252840a0f9986a1a18ab7bf451ddb (patch)
tree939dabe4b69e2bf0c14fc93ee3d5f093f6d77565
parent7a3a7896b3c96bee076ed0da65d10eec7fc06b85 (diff)
downloadtdenetwork-feat/add_kopete-otr_plugin.tar.gz
tdenetwork-feat/add_kopete-otr_plugin.zip
Add kopete-otr plugin to kopete.feat/add_kopete-otr_plugin
Signed-off-by: gregory guy <gregory-tde@laposte.net>
-rw-r--r--CMakeLists.txt35
-rw-r--r--kopete/CMakeLists.txt5
-rw-r--r--kopete/ConfigureChecks.cmake15
-rw-r--r--kopete/config-kopete.h.cmake2
-rw-r--r--kopete/plugins/CMakeLists.txt33
-rw-r--r--kopete/plugins/otr/CMakeL10n.txt3
-rw-r--r--kopete/plugins/otr/CMakeLists.txt125
-rw-r--r--kopete/plugins/otr/kopete_otr.desktop20
-rw-r--r--kopete/plugins/otr/kopete_otr.kcfg23
-rw-r--r--kopete/plugins/otr/kopete_otr.kcfgc7
-rw-r--r--kopete/plugins/otr/kopete_otr_config.desktop16
-rw-r--r--kopete/plugins/otr/otrchatui.rc19
-rw-r--r--kopete/plugins/otr/otrguiclient.cpp129
-rw-r--r--kopete/plugins/otr/otrguiclient.h78
-rw-r--r--kopete/plugins/otr/otrlchatinterface.cpp1076
-rw-r--r--kopete/plugins/otr/otrlchatinterface.h96
-rw-r--r--kopete/plugins/otr/otrlconfinterface.cpp236
-rw-r--r--kopete/plugins/otr/otrlconfinterface.h66
-rw-r--r--kopete/plugins/otr/otrplugin-factory.cpp58
-rw-r--r--kopete/plugins/otr/otrplugin-factory.h45
-rw-r--r--kopete/plugins/otr/otrplugin.cpp339
-rw-r--r--kopete/plugins/otr/otrplugin.h117
-rw-r--r--kopete/plugins/otr/otrpreferences.cpp202
-rw-r--r--kopete/plugins/otr/otrpreferences.h64
-rw-r--r--kopete/plugins/otr/otrprefs.ui295
-rw-r--r--kopete/plugins/otr/otrui.rc12
-rw-r--r--kopete/plugins/otr/pics/CMakeLists.txt5
-rw-r--r--kopete/plugins/otr/pics/cr16-action-otr_disabled.pngbin0 -> 815 bytes
-rw-r--r--kopete/plugins/otr/pics/cr16-action-otr_finished.pngbin0 -> 956 bytes
-rw-r--r--kopete/plugins/otr/pics/cr16-action-otr_private.pngbin0 -> 750 bytes
-rw-r--r--kopete/plugins/otr/pics/cr16-action-otr_unverified.pngbin0 -> 687 bytes
-rw-r--r--kopete/plugins/otr/pics/cr16-app-kopete_otr.pngbin0 -> 758 bytes
-rw-r--r--kopete/plugins/otr/pics/cr16-app-otr.pngbin0 -> 750 bytes
-rw-r--r--kopete/plugins/otr/pics/cr22-action-otr_disabled.pngbin0 -> 812 bytes
-rw-r--r--kopete/plugins/otr/pics/cr22-action-otr_finished.pngbin0 -> 1124 bytes
-rw-r--r--kopete/plugins/otr/pics/cr22-action-otr_private.pngbin0 -> 873 bytes
-rw-r--r--kopete/plugins/otr/pics/cr22-action-otr_unverified.pngbin0 -> 853 bytes
-rw-r--r--kopete/plugins/otr/pics/cr32-action-otr_disabled.pngbin0 -> 1417 bytes
-rw-r--r--kopete/plugins/otr/pics/cr32-action-otr_finished.pngbin0 -> 1889 bytes
-rw-r--r--kopete/plugins/otr/pics/cr32-action-otr_private.pngbin0 -> 1391 bytes
-rw-r--r--kopete/plugins/otr/pics/cr32-action-otr_unverified.pngbin0 -> 1397 bytes
-rw-r--r--kopete/plugins/otr/privkeypopup.cpp57
-rw-r--r--kopete/plugins/otr/privkeypopup.h54
-rw-r--r--kopete/plugins/otr/privkeypopupui.ui64
-rw-r--r--kopete/plugins/otr/smppopup.cpp87
-rw-r--r--kopete/plugins/otr/smppopup.h62
-rw-r--r--kopete/plugins/otr/smppopupui.ui191
-rw-r--r--kopete/plugins/otr/verifypopup.cpp72
-rw-r--r--kopete/plugins/otr/verifypopup.h49
-rw-r--r--kopete/plugins/otr/verifypopupui.ui113
50 files changed, 3837 insertions, 33 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6caab770..9f338a3e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -90,24 +90,25 @@ option( BUILD_KOPETE_PROTOCOL_MEANWHILE "Build kopete protocol meanwhile" ${BUIL
##### kopete plugins ############################
-option( BUILD_KOPETE_PLUGIN_ALL "Build all kopete plugins" OFF )
-option( BUILD_KOPETE_PLUGIN_LATEX "Build latex kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_AUTOREPLACE "Build autoreplace kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_HISTORY "Build history kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_CONTACTNOTES "Build contactnotes kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_CRYPTOGRAPHY "Build cryptography kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_ALL "Build all kopete plugins" OFF )
+option( BUILD_KOPETE_PLUGIN_LATEX "Build latex kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_AUTOREPLACE "Build autoreplace kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_HISTORY "Build history kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_CONTACTNOTES "Build contactnotes kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_CRYPTOGRAPHY "Build cryptography kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
option( BUILD_KOPETE_PLUGIN_CONNECTIONSTATUS "Build connectionstatus kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_TRANSLATOR "Build translator kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_NOWLISTENING "Build nowlistening kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_WEBPRESENCE "Build webpresence kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_TEXTEFFECT "Build texteffect kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_HIGHLIGHT "Build highlight kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_ALIAS "Build alias kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_MOTIONAUTOAWAY "Build motionautoaway kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_NETMEETING "Build netmeeting kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_ADDBOOKMARKS "Build addbookmarks kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_STATISTICS "Build statistics kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
-option( BUILD_KOPETE_PLUGIN_SMPPPDCS "Build smpppdcs kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_TRANSLATOR "Build translator kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_NOWLISTENING "Build nowlistening kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_WEBPRESENCE "Build webpresence kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_TEXTEFFECT "Build texteffect kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_HIGHLIGHT "Build highlight kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_ALIAS "Build alias kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_MOTIONAUTOAWAY "Build motionautoaway kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_NETMEETING "Build netmeeting kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_ADDBOOKMARKS "Build addbookmarks kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_STATISTICS "Build statistics kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_SMPPPDCS "Build smpppdcs kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
+option( BUILD_KOPETE_PLUGIN_OTR "Build otr kopete plugin" ${BUILD_KOPETE_PLUGIN_ALL} )
##### user requested modules ####################
diff --git a/kopete/CMakeLists.txt b/kopete/CMakeLists.txt
index f04465a7..aae2eda3 100644
--- a/kopete/CMakeLists.txt
+++ b/kopete/CMakeLists.txt
@@ -22,3 +22,8 @@ add_subdirectory( plugins )
add_subdirectory( icons )
add_subdirectory( sounds )
add_subdirectory( styles )
+
+
+##### write configure files #####################
+
+configure_file( config-kopete.h.cmake config-kopete.h @ONLY )
diff --git a/kopete/ConfigureChecks.cmake b/kopete/ConfigureChecks.cmake
index c8e03e06..6581c08a 100644
--- a/kopete/ConfigureChecks.cmake
+++ b/kopete/ConfigureChecks.cmake
@@ -64,3 +64,18 @@ endif( )
### Check for tm_gmtoff in tm struct
check_struct_has_member( "struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF )
+
+#### check for libotr
+
+if( BUILD_KOPETE_PLUGIN_OTR )
+ pkg_search_module( LIBOTR libotr )
+
+ if( LIBOTR_FOUND )
+ if( NOT LIBOTR_VERSION VERSION_LESS 4.0.0 )
+ set( HAVE_LIBOTR_0400 1 )
+ endif()
+ else()
+ tde_message_fatal( "Libotr is required but was not found on your system" )
+ endif()
+endif( BUILD_KOPETE_PLUGIN_OTR )
+
diff --git a/kopete/config-kopete.h.cmake b/kopete/config-kopete.h.cmake
new file mode 100644
index 00000000..d354b6c4
--- /dev/null
+++ b/kopete/config-kopete.h.cmake
@@ -0,0 +1,2 @@
+/* Defined if libotr >= 4.0.0 */
+#cmakedefine HAVE_LIBOTR_0400 1
diff --git a/kopete/plugins/CMakeLists.txt b/kopete/plugins/CMakeLists.txt
index a5c6b08c..49414aae 100644
--- a/kopete/plugins/CMakeLists.txt
+++ b/kopete/plugins/CMakeLists.txt
@@ -9,20 +9,21 @@
#
#################################################
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_LATEX latex )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_AUTOREPLACE autoreplace )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_HISTORY history )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_CONTACTNOTES contactnotes )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_CRYPTOGRAPHY cryptography )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_LATEX latex )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_AUTOREPLACE autoreplace )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_HISTORY history )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_CONTACTNOTES contactnotes )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_CRYPTOGRAPHY cryptography )
tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_CONNECTIONSTATUS connectionstatus )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_TRANSLATOR translator )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_NOWLISTENING nowlistening )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_WEBPRESENCE webpresence )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_TEXTEFFECT texteffect )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_HIGHLIGHT highlight )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_ALIAS alias )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_MOTIONAUTOAWAY motionautoaway )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_NETMEETING netmeeting )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_ADDBOOKMARKS addbookmarks )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_STATISTICS statistics )
-tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_SMPPPDCS smpppdcs )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_TRANSLATOR translator )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_NOWLISTENING nowlistening )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_WEBPRESENCE webpresence )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_TEXTEFFECT texteffect )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_HIGHLIGHT highlight )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_ALIAS alias )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_MOTIONAUTOAWAY motionautoaway )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_NETMEETING netmeeting )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_ADDBOOKMARKS addbookmarks )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_STATISTICS statistics )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_SMPPPDCS smpppdcs )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PLUGIN_OTR otr )
diff --git a/kopete/plugins/otr/CMakeL10n.txt b/kopete/plugins/otr/CMakeL10n.txt
new file mode 100644
index 00000000..591bd6b1
--- /dev/null
+++ b/kopete/plugins/otr/CMakeL10n.txt
@@ -0,0 +1,3 @@
+##### create translation templates ##############
+
+tde_l10n_create_template( "messages/kopete_otr" )
diff --git a/kopete/plugins/otr/CMakeLists.txt b/kopete/plugins/otr/CMakeLists.txt
new file mode 100644
index 00000000..8c45e5c3
--- /dev/null
+++ b/kopete/plugins/otr/CMakeLists.txt
@@ -0,0 +1,125 @@
+add_subdirectory( pics )
+
+include_directories(
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}/src
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+ ${LIBOTR_INCLUDE_DIRS}
+ ${CMAKE_BINARY_DIR}/kopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+ ${TDE_LIB_DIR}
+)
+
+
+##### kotr_kcfgc (static)
+
+tde_add_library( kotr_kcfgc STATIC_PIC AUTOMOC
+
+ SOURCES
+ kopete_otr.kcfgc
+)
+
+
+##### kotr (shared)
+
+tde_add_library( kotr SHARED AUTOMOC
+
+ SOURCES
+ otrplugin.cpp
+ otrguiclient.cpp
+ otrlchatinterface.cpp
+ otrlconfinterface.cpp
+ privkeypopup.cpp
+ privkeypopupui.ui
+ smppopup.cpp
+ smppopupui.ui
+ verifypopup.cpp
+ verifypopupui.ui
+
+ LINK
+ kotr_kcfgc-static
+ tdecore-shared
+ tdeui-shared
+ tdeio-shared
+ kopete-shared
+ ${LIBOTR_LIBRARIES}
+
+ VERSION 0.0.0
+
+ DESTINATION ${LIB_INSTALL_DIR}
+)
+
+
+##### kcm_kopete_otr (kpart)
+
+tde_add_kpart( kcm_kopete_otr AUTOMOC
+
+ SOURCES
+ otrpreferences.cpp
+ otrprefs.ui
+ LINK
+ kotr_kcfgc-static
+ kotr-shared
+ tdecore-shared
+ tdeui-shared
+ tdehtml-shared
+ kopete-shared
+ ${LIBOTR_LIBRARIES}
+
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
+
+
+##### kopete_otr (kpart)
+
+tde_add_kpart( kopete_otr AUTOMOC
+
+ SOURCES
+ otrplugin-factory.cpp
+
+ LINK
+ kotr-shared
+ tdecore-shared
+ tdeui-shared
+ tdehtml-shared
+ kopete-shared
+ ${LIBOTR_LIBRARIES}
+
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
+
+
+##### other data
+
+install(
+ FILES otrchatui.rc otrui.rc
+ DESTINATION ${DATA_INSTALL_DIR}/kopete_otr
+)
+
+install(
+ FILES kopete_otr.kcfg
+ DESTINATION ${KCFG_INSTALL_DIR}
+)
+
+
+#### desktop files
+
+tde_create_translated_desktop(
+ SOURCE kopete_otr.desktop
+ DESTINATION ${SERVICES_INSTALL_DIR}
+ PO_DIR kopete_otr-desktops
+)
+
+tde_create_translated_desktop(
+ SOURCE kopete_otr_config.desktop
+ DESTINATION ${SERVICES_INSTALL_DIR}/tdeconfiguredialog
+ PO_DIR kopete_otr-desktops
+)
diff --git a/kopete/plugins/otr/kopete_otr.desktop b/kopete/plugins/otr/kopete_otr.desktop
new file mode 100644
index 00000000..7f924746
--- /dev/null
+++ b/kopete/plugins/otr/kopete_otr.desktop
@@ -0,0 +1,20 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Service
+X-Kopete-Version=1000900
+Icon=kopete_otr
+X-TDE-ServiceTypes=Kopete/Plugin
+X-TDE-Library=kopete_otr
+X-TDE-PluginInfo-Author=Michael Zanetti
+X-TDE-PluginInfo-Email=michael_zanetti@gmx.net
+X-TDE-PluginInfo-Name=kopete_otr
+X-TDE-PluginInfo-Version=0.7
+X-TDE-PluginInfo-Website=http://kopete-otr.follefuder.org
+X-TDE-PluginInfo-Category=Plugins
+X-TDE-PluginInfo-Depends=
+X-TDE-PluginInfo-License=GPL
+X-TDE-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
diff --git a/kopete/plugins/otr/kopete_otr.kcfg b/kopete/plugins/otr/kopete_otr.kcfg
new file mode 100644
index 00000000..1db6935b
--- /dev/null
+++ b/kopete/plugins/otr/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/kopete/plugins/otr/kopete_otr.kcfgc b/kopete/plugins/otr/kopete_otr.kcfgc
new file mode 100644
index 00000000..71216cfa
--- /dev/null
+++ b/kopete/plugins/otr/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/kopete/plugins/otr/kopete_otr_config.desktop b/kopete/plugins/otr/kopete_otr_config.desktop
new file mode 100644
index 00000000..7f8ebb3e
--- /dev/null
+++ b/kopete/plugins/otr/kopete_otr_config.desktop
@@ -0,0 +1,16 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Service
+Icon=kopete_otr
+X-TDE-ServiceTypes=TDECModule
+
+X-TDE-ModuleType=Library
+X-TDE-Library=kopete_otr
+X-TDE-FactoryName=OTRPreferencesFactory
+X-TDE-ParentApp=kopete_otr
+X-TDE-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
diff --git a/kopete/plugins/otr/otrchatui.rc b/kopete/plugins/otr/otrchatui.rc
new file mode 100644
index 00000000..2c3d710b
--- /dev/null
+++ b/kopete/plugins/otr/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/kopete/plugins/otr/otrguiclient.cpp b/kopete/plugins/otr/otrguiclient.cpp
new file mode 100644
index 00000000..48dc193a
--- /dev/null
+++ b/kopete/plugins/otr/otrguiclient.cpp
@@ -0,0 +1,129 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <tdeaction.h>
+#include <tdelocale.h>
+#include <tdeactionclasses.h>
+#include <kopetechatsession.h>
+#include <kopeteview.h>
+#include <kopetemessage.h>
+#include <kdebug.h>
+#include <kstandarddirs.h>
+#include <tdemessagebox.h>
+
+
+#include "otrguiclient.h"
+#include "otrplugin.h"
+
+/**
+ * @author Frank Scheffold
+ * @author Michael Zanetti
+ */
+
+
+OtrGUIClient::OtrGUIClient( Kopete::ChatSession *parent, const char *name )
+: TQObject( parent, name ), KXMLGUIClient( parent )
+{
+ setInstance( OTRPlugin::plugin()->instance() );
+
+ connect( OTRPlugin::plugin(),
+ TQT_SIGNAL( destroyed( TQObject * ) ), this,
+ TQT_SLOT( deleteLater() )
+
+ );
+
+ connect(this, TQT_SIGNAL( signalOtrChatsession(Kopete::ChatSession*, bool) ), OTRPlugin::plugin(), TQT_SLOT(slotEnableOtr(Kopete::ChatSession*, bool)));
+
+ connect( OTRPlugin::plugin(), TQT_SIGNAL( goneSecure( Kopete::ChatSession *, int ) ),
+ this, TQT_SLOT( encryptionEnabled( Kopete::ChatSession *, int ) ) );
+
+ connect( this, TQT_SIGNAL( signalVerifyFingerprint( Kopete::ChatSession * ) ), OTRPlugin::plugin(), TQT_SLOT(slotVerifyFingerprint( Kopete::ChatSession * )) );
+
+ m_manager = parent;
+ otrActionMenu = new TDEActionMenu(i18n("OTR Settings"),"otr_disabled", actionCollection(), "otr_settings");
+ otrActionMenu->setDelayed( false );
+ actionEnableOtr = new TDEAction(i18n( "Start OTR session" ), "otr_private", 0,this,TQT_SLOT(slotEnableOtr()),actionCollection(), "enable_otr");
+ actionDisableOtr = new TDEAction(i18n("End OTR session"), "otr_disabled",0, this,TQT_SLOT(slotDisableOtr()), actionCollection(), "disable_otr");
+ actionVerifyFingerprint = new TDEAction(i18n("Authenticate Contact"), "signature",0, this,TQT_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"
diff --git a/kopete/plugins/otr/otrguiclient.h b/kopete/plugins/otr/otrguiclient.h
new file mode 100644
index 00000000..9eaef0e9
--- /dev/null
+++ b/kopete/plugins/otr/otrguiclient.h
@@ -0,0 +1,78 @@
+/***************************************************************************
+ * 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 <tqobject.h>
+#include <kxmlguiclient.h>
+
+//#include <tdeio/job.h>
+
+#include <tdeglobal.h>
+#include <kstandarddirs.h>
+#include <kiconloader.h>
+
+#include <kopetemessage.h>
+#include <kopeteplugin.h>
+
+
+class TDEActionMenu;
+class TDEAction;
+
+namespace Kopete { class ChatSession; }
+
+/**
+ * @author Frank Scheffold
+ */
+
+
+class OtrGUIClient : public TQObject, public KXMLGUIClient
+{
+ Q_OBJECT
+
+public:
+
+ OtrGUIClient( Kopete::ChatSession *parent, const char *name=0L );
+ ~OtrGUIClient();
+
+
+private:
+ Kopete::ChatSession *m_manager;
+ TDEActionMenu *otrActionMenu;
+ TDEAction *actionEnableOtr;
+ TDEAction *actionDisableOtr;
+ TDEAction *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/kopete/plugins/otr/otrlchatinterface.cpp b/kopete/plugins/otr/otrlchatinterface.cpp
new file mode 100644
index 00000000..0d216cce
--- /dev/null
+++ b/kopete/plugins/otr/otrlchatinterface.cpp
@@ -0,0 +1,1076 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Michael Zanetti *
+ * Copyright (C) 2014 by Timothy Pearson <kb9vqf@pearsoncomputing.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. *
+ ***************************************************************************/
+
+
+/**
+ * @author Michael Zanetti
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config-kopete.h"
+#endif
+
+#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 <tdemessagebox.h>
+#include <kstandarddirs.h>
+#include <tdelocale.h>
+#include <kprogress.h>
+#include <kpassivepopup.h>
+#include <kanimwidget.h>
+#include <kpushbutton.h>
+
+#include <tqvbox.h>
+#include <tqlabel.h>
+#include <tqnamespace.h>
+#include <tqeventloop.h>
+#include <tqapplication.h>
+#include <tqfile.h>
+#include <tqfileinfo.h>
+#include <tqptrlist.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;
+ }
+ TQString 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").utf8(), TQt::WType_Dialog | TQt::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) ){
+ tqApp->eventLoop()->processEvents(TQEventLoop::ExcludeUserInput | TQEventLoop::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 ( TQPtrListIterator<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, TQString(accountname) + ":" + TQString(protocol) + ":" + TQString(recipient) + ":" + TQString(message) );
+ Kopete::ChatSession *session= ((Kopete::ChatSession*)opdata);
+ Kopete::ContactPtrList list = session->members();
+ for ( TQPtrListIterator<Kopete::Contact> it( list ); Kopete::Contact *contact = it.current(); ++it ){
+ if( contact->contactId().compare( recipient ) == 0 ){
+ Kopete::Message msg( session->account()->myself(), contact, TQString( message ), Kopete::Message::Outbound );
+ session->sendMessage( msg );
+ return;
+ }
+ }
+}
+
+#ifndef HAVE_LIBOTR_0400
+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, TQString( primary ) + TQString( secondary ), TQString( title ) );
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifndef HAVE_LIBOTR_0400
+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 ( TQPtrListIterator<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(), TQString( message ), Kopete::Message::Internal );
+ msg.setBody( TQString( message ), Kopete::Message::RichText );
+ session->appendMessage( msg );
+ return 0;
+ }
+ }
+ return 1;
+}
+#endif // HAVE_LIBOTR_0400
+
+static void update_context_list(void *opdata){
+//Not used...
+}
+
+#ifndef HAVE_LIBOTR_0400
+static const char *protocol_name(void *opdata, const char *protocol){
+//Never seen...
+ kdDebug() << "protocol_name called" << endl;
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifndef HAVE_LIBOTR_0400
+static void protocol_name_free(void *opdata, const char *protocol_name){
+//Never seen...
+ kdDebug() << "protocol_name_free called" << endl;
+}
+#endif // HAVE_LIBOTR_0400
+
+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, TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("fingerprints").local8Bit() );
+}
+
+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 );
+ }
+
+#ifdef HAVE_LIBOTR_0400
+ session->setProperty("otr-instag", QString::number(context->their_instance));
+#endif // HAVE_LIBOTR_0400
+}
+
+/* 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);
+ }
+}
+
+#ifndef HAVE_LIBOTR_0400
+static void log_message(void *opdata, const char *message){
+ kdDebug() << "libotr: "<< message << endl;
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+static void received_symkey(void *opdata, ConnContext *context, unsigned int use, const unsigned char *usedata, size_t usedatalen, const unsigned char *symkey){
+ // Not used
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+static const char *otr_error_message(void *opdata, ConnContext *context, OtrlErrorCode err_code){
+ Q_UNUSED(opdata)
+
+ char *err_msg = 0;
+ switch (err_code)
+ {
+ case OTRL_ERRCODE_NONE :
+ break;
+ case OTRL_ERRCODE_ENCRYPTION_ERROR : {
+ TQString message = i18n("Error occurred encrypting message.");
+ err_msg = (char*)malloc(message.length() + 1);
+ memset(err_msg, 0, message.length() + 1);
+ memcpy(err_msg, message.utf8().data(), message.length());
+ break;
+ }
+ case OTRL_ERRCODE_MSG_NOT_IN_PRIVATE :
+ if (context) {
+ TQString message = i18n("You sent encrypted data to %s, who wasn't expecting it.").arg(context->accountname);
+ err_msg = (char*)malloc(message.length() + 1);
+ memset(err_msg, 0, message.length() + 1);
+ memcpy(err_msg, message.utf8().data(), message.length());
+ }
+ break;
+ case OTRL_ERRCODE_MSG_UNREADABLE : {
+ TQString message = i18n("You transmitted an unreadable encrypted message.");
+ err_msg = (char*)malloc(message.length() + 1);
+ memset(err_msg, 0, message.length() + 1);
+ memcpy(err_msg, message.utf8().data(), message.length());
+ break;
+ }
+ case OTRL_ERRCODE_MSG_MALFORMED : {
+ TQString message = i18n("You transmitted a malformed data message.");
+ err_msg = (char*)malloc(message.length() + 1);
+ memset(err_msg, 0, message.length() + 1);
+ memcpy(err_msg, message.utf8().data(), message.length());
+ break;
+ }
+ }
+ return err_msg;
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+void otr_error_message_free(void *opdata, const char *err_msg){
+ Q_UNUSED(opdata)
+
+ if (err_msg) {
+ free((char*)err_msg);
+ }
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+const char *resent_msg_prefix(void *opdata, ConnContext *context){
+ Q_UNUSED(opdata)
+ Q_UNUSED(context)
+
+ TQString message = i18n("[resent]");
+ char *msg_prefix = (char*)malloc(message.length() + 1);
+ memset(msg_prefix, 0, message.length() + 1);
+ memcpy(msg_prefix, message.utf8().data(), message.length());
+ return msg_prefix;
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+void resent_msg_prefix_free(void *opdata, const char *prefix){
+ Q_UNUSED(opdata)
+
+ if (prefix) {
+ free((char*)prefix);
+ }
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+void handle_smp_event(void *opdata, OtrlSMPEvent smp_event, ConnContext *context, unsigned short progress_percent, char *question){
+ Q_UNUSED(progress_percent)
+
+ Kopete::ChatSession *chatSession = (Kopete::ChatSession*)opdata;
+
+ if (!context) {
+ return;
+ }
+
+ switch (smp_event) {
+ case OTRL_SMPEVENT_NONE:
+ break;
+ case OTRL_SMPEVENT_ASK_FOR_SECRET: {
+ SMPPopup *popup = new SMPPopup( chatSession->view()->mainWidget(), i18n("Enter authentication secret").utf8(), TQString::null, TQt::WType_Dialog | TQt::WStyle_StaysOnTop, context, chatSession, false );
+ popup->show();
+ break;
+ }
+ case OTRL_SMPEVENT_ASK_FOR_ANSWER: {
+ SMPPopup *popup = new SMPPopup( chatSession->view()->mainWidget(), question, question, TQt::WType_Dialog | TQt::WStyle_StaysOnTop, context, chatSession, false );
+ popup->show();
+ break;
+ }
+ case OTRL_SMPEVENT_IN_PROGRESS: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("<b>Authenticating contact...</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ break;
+ }
+ case OTRL_SMPEVENT_SUCCESS: {
+ 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 );
+ }
+ break;
+ }
+ case OTRL_SMPEVENT_FAILURE: {
+ 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 );
+ break;
+ }
+ case OTRL_SMPEVENT_ABORT:
+ case OTRL_SMPEVENT_CHEATED:
+ case OTRL_SMPEVENT_ERROR: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("<b>Authentication error!</b>"), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ OtrlChatInterface::self()->abortSMP( context, chatSession );
+ break;
+ }
+ }
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+void handle_msg_event(void *opdata, OtrlMessageEvent msg_event, ConnContext *context, const char *message, gcry_error_t err){
+ Kopete::ChatSession *chatSession= ((Kopete::ChatSession*)opdata);
+ Kopete::ContactPtrList list = chatSession->members();
+
+ switch (msg_event)
+ {
+ case OTRL_MSGEVENT_NONE:
+ break;
+ case OTRL_MSGEVENT_ENCRYPTION_REQUIRED: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("You attempted to send an unencrypted message to <b>%1</b>").arg(context->username) , Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ break;
+ }
+ case OTRL_MSGEVENT_ENCRYPTION_ERROR: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("An error occurred when encrypting your message. The message was not sent."), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ break;
+ }
+ case OTRL_MSGEVENT_CONNECTION_ENDED: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("<b>%1</b> has ended the OTR session. You should do the same.").arg(context->username) , Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ break;
+ }
+ case OTRL_MSGEVENT_SETUP_ERROR: {
+ if (!err) {
+ err = GPG_ERR_INV_VALUE;
+ }
+ switch(gcry_err_code(err)) {
+ case GPG_ERR_INV_VALUE:
+ kdDebug() << "Error setting up private conversation: Malformed message received";
+ default:
+ kdDebug() << "Error setting up private conversation:" << err;
+ }
+
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("OTR error"), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ break;
+ }
+ case OTRL_MSGEVENT_MSG_REFLECTED: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("We are receiving our own OTR messages. You are either trying to talk to yourself, or someone is reflecting your messages back at you."), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ break;
+ }
+ case OTRL_MSGEVENT_MSG_RESENT: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("The last message to <b>%1</b> was resent.").arg(context->username) , Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ break;
+ }
+ case OTRL_MSGEVENT_RCVDMSG_NOT_IN_PRIVATE: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("The encrypted message received from <b>%1</b> is unreadable, as you are not currently communicating privately.").arg(context->username) , Kopete::Message::Inbound, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ //OtrlChatInterface::self()->m_blacklistIds.append(msg.id());
+ break;
+ }
+ case OTRL_MSGEVENT_RCVDMSG_UNREADABLE: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("We received an unreadable encrypted message from <b>%1</b>."), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ break;
+ }
+ case OTRL_MSGEVENT_RCVDMSG_MALFORMED: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("We received a malformed data message from <b>%1</b>."), Kopete::Message::Internal, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ break;
+ }
+ case OTRL_MSGEVENT_LOG_HEARTBEAT_RCVD: {
+ kdDebug() << "Heartbeat received from" << context->username;
+ return;
+ }
+ case OTRL_MSGEVENT_LOG_HEARTBEAT_SENT: {
+ kdDebug() << "Heartbeat sent to" << context->username;
+ break;
+ }
+ case OTRL_MSGEVENT_RCVDMSG_GENERAL_ERR: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), message, Kopete::Message::Inbound, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ break;
+ }
+ case OTRL_MSGEVENT_RCVDMSG_UNENCRYPTED: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("<b>The following message received from <b>%1</b> was <i>not</i> encrypted: [</b>%2<b>]</b>").arg(context->username).arg(message), Kopete::Message::Inbound, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ //OtrlChatInterface::self()->m_blacklistIds.append(msg.id());
+ break;
+ }
+ case OTRL_MSGEVENT_RCVDMSG_UNRECOGNIZED: {
+ kdDebug() << "Unrecognized OTR message received from" << context->username;
+ break;
+ }
+ case OTRL_MSGEVENT_RCVDMSG_FOR_OTHER_INSTANCE: {
+ Kopete::Message msg( chatSession->members().getFirst(), chatSession->account()->myself(), i18n("<b>%1</b> has sent an encrypted message intended for a different session. If you are logged in multiple times, another session may have received the message.").arg(context->username), Kopete::Message::Inbound, Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+ //OtrlChatInterface::self()->m_blacklistIds.append(msg.id());
+ break;
+ }
+ }
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+void create_instag(void *opdata, const char *accountname, const char *protocol){
+ Q_UNUSED(opdata)
+
+ otrl_instag_generate(OtrlChatInterface::self()->getUserstate(), TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("instags").local8Bit(), accountname, protocol);
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+void convert_msg(void *opdata, ConnContext *context, OtrlConvertType convert_type, char ** dest, const char *src){
+ // Not used
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+void convert_free(void *opdata, ConnContext *context, char *dest){
+ // Not used
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+void timer_control(void *opdata, unsigned int interval){
+ kdDebug() << "timer_control called" << endl;
+
+ Q_UNUSED(opdata)
+ if (interval > 0) {
+ OtrlChatInterface::self()->forwardSecrecyTimerStart(interval);
+ }
+ else {
+ OtrlChatInterface::self()->forwardSecrecyTimerStop();
+ }
+}
+#endif // HAVE_LIBOTR_0400
+
+#ifdef HAVE_LIBOTR_0400
+static OtrlMessageAppOps ui_ops = {
+ policy,
+ create_privkey,
+ is_logged_in,
+ inject_message,
+ update_context_list,
+ new_fingerprint,
+ write_fingerprints,
+ gone_secure,
+ gone_insecure,
+ still_secure,
+ NULL, // max_message_size,
+ NULL, // account_name,
+ NULL, // account_name_free,
+ received_symkey,
+ otr_error_message,
+ otr_error_message_free,
+ resent_msg_prefix,
+ resent_msg_prefix_free,
+ handle_smp_event,
+ handle_msg_event,
+ create_instag,
+ NULL, // convert_msg,
+ NULL, // convert_free,
+ timer_control
+};
+#else // HAVE_LIBOTR_0400
+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
+};
+#endif // HAVE_LIBOTR_0400
+
+/*********************** Gui_UI_Ops finished *************************/
+
+
+/*********************** Constructor/Destructor **********************/
+
+OtrlChatInterface::OtrlChatInterface(){
+ kdDebug() << "Creating OtrlChatInterface" << endl;
+ mSelf = this;
+ OTRL_INIT;
+
+ userstate = otrl_userstate_create();
+
+ otrl_privkey_read( userstate, TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("privkeys").local8Bit() );
+
+ otrl_privkey_read_fingerprints(userstate, TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("fingerprints").local8Bit(), NULL, NULL);
+
+#ifdef HAVE_LIBOTR_0400
+ otrl_instag_read(userstate, TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("instags").local8Bit());
+
+ unsigned int interval = otrl_message_poll_get_default_interval(userstate);
+ forwardSecrecyTimerStart(interval);
+ connect(&m_forwardSecrecyTimer, SIGNAL(timeout()), this, SLOT(otrlMessagePoll()));
+#endif // HAVE_LIBOTR_0400
+
+}
+
+OtrlChatInterface::~ OtrlChatInterface(){
+ otrl_userstate_free(userstate);
+}
+
+
+OtrlChatInterface *OtrlChatInterface::self(){
+ if( !mSelf ){
+ new OtrlChatInterface();
+ }
+ return mSelf;
+}
+
+void OtrlChatInterface::forwardSecrecyTimerStart(int interval){
+ m_forwardSecrecyTimer.start(interval * 1000);
+}
+
+void OtrlChatInterface::forwardSecrecyTimerStop(){
+ m_forwardSecrecyTimer.stop();
+}
+
+void OtrlChatInterface::otrlMessagePoll(){
+#ifdef HAVE_LIBOTR_0400
+ otrl_message_poll(userstate, 0, 0);
+#endif // HAVE_LIBOTR_0400
+}
+
+/********************* Chat section ***************************/
+
+OtrlUserState OtrlChatInterface::getUserstate(){
+ return userstate;
+}
+
+
+int OtrlChatInterface::decryptMessage( TQString *msg, TQString accountId,
+ TQString protocol, TQString contactId , Kopete::ChatSession *chatSession){
+
+ int ignoremessage;
+ char *newMessage = NULL;
+ OtrlTLV *tlvs = NULL;
+ OtrlTLV *tlv = NULL;
+ ConnContext *context;
+ NextExpectedSMP nextMsg;
+
+#ifdef HAVE_LIBOTR_0400
+ ignoremessage = otrl_message_receiving( userstate, &ui_ops, chatSession, accountId.latin1(), protocol.latin1(), contactId.latin1(), msg->latin1(), &newMessage, &tlvs, NULL, NULL, NULL );
+#else // HAVE_LIBOTR_0400
+ ignoremessage = otrl_message_receiving( userstate, &ui_ops, chatSession, accountId.latin1(), protocol.latin1(), contactId.latin1(), msg->latin1(), &newMessage, &tlvs, NULL, NULL );
+#endif // HAVE_LIBOTR_0400
+
+
+ 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 );
+ }
+
+#ifdef HAVE_LIBOTR_0400
+ context = otrl_context_find( userstate, contactId.latin1(), accountId.latin1(), protocol.latin1(), 0, 0, NULL, NULL, NULL);
+#else // HAVE_LIBOTR_0400
+ context = otrl_context_find( userstate, contactId.latin1(), accountId.latin1(), protocol.latin1(), 0, NULL, NULL, NULL);
+#endif // HAVE_LIBOTR_0400
+ 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").utf8(), TQString::null, TQt::WType_Dialog | TQt::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 = TQString::fromUtf8(newMessage);
+ otrl_message_free( newMessage );
+ msg->replace( TQString("\n"), TQString("<br>"), false );
+ }
+ }
+ return ignoremessage;
+}
+
+TQString OtrlChatInterface::encryptMessage( TQString msg, TQString accountId,
+ TQString protocol, TQString contactId , Kopete::ChatSession *chatSession ){
+ int err;
+ char * newMessage;
+ if( otrl_proto_message_type( msg.latin1() ) == OTRL_MSGTYPE_NOTOTR ){
+ msg.replace( TQString("<"), TQString("&lt;"), false );
+#ifdef HAVE_LIBOTR_0400
+ otrl_instag_t instance = chatSession->property("otr-instag").toUInt();
+ err = otrl_message_sending( userstate, &ui_ops, chatSession, accountId.latin1(), protocol.latin1(), contactId.latin1(), instance, msg.utf8(), NULL, &newMessage, OTRL_FRAGMENT_SEND_ALL_BUT_LAST, NULL, NULL, NULL );
+#else // HAVE_LIBOTR_0400
+ err = otrl_message_sending( userstate, &ui_ops, chatSession, accountId.latin1(), protocol.latin1(), contactId.latin1(), msg.utf8(), NULL, &newMessage, NULL, NULL );
+#endif // HAVE_LIBOTR_0400
+
+ if( err != 0 ){
+ msg = i18n("Encryption error");
+ } else {
+ if( newMessage != NULL ){
+ msg = TQString::fromUtf8( newMessage );
+ otrl_message_free( newMessage );
+ }
+ }
+ }
+ OtrlMessageType type = otrl_proto_message_type( msg.latin1() );
+ if( type == OTRL_MSGTYPE_NOTOTR | type == OTRL_MSGTYPE_TAGGEDPLAINTEXT ){
+ msg.replace( "&lt;", "<", false );
+ }
+ return msg;
+}
+
+TQString OtrlChatInterface::getDefaultQuery( TQString accountId ){
+ char *message;
+ message = otrl_proto_default_query_msg( accountId.latin1(), OTRL_POLICY_ALLOW_V2 );
+ TQString msg( message );
+ otrl_message_free( message );
+ return msg;
+}
+
+void OtrlChatInterface::disconnectSession( Kopete::ChatSession *chatSession ){
+#ifdef HAVE_LIBOTR_0400
+ otrl_instag_t instance = chatSession->property("otr-instag").toUInt();
+ otrl_message_disconnect( userstate, &ui_ops, chatSession, chatSession->account()->accountId().latin1(), chatSession->account()->protocol()->displayName().latin1(), chatSession->members().getFirst()->contactId().latin1(), instance );
+#else // HAVE_LIBOTR_0400
+ otrl_message_disconnect( userstate, &ui_ops, chatSession, chatSession->account()->accountId().latin1(), chatSession->account()->protocol()->displayName().latin1(), chatSession->members().getFirst()->contactId().latin1() );
+#endif // HAVE_LIBOTR_0400
+ OTRPlugin::plugin()->emitGoneSecure( chatSession, false );
+
+ Kopete::Message msg( chatSession->account()->myself(), chatSession->members().getFirst(), i18n("Terminating OTR session."), Kopete::Message::Internal );
+// msg.setBody( TQString( message ), Kopete::Message::RichText );
+ chatSession->appendMessage( msg );
+
+}
+
+bool OtrlChatInterface::shouldDiscard( TQString 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;
+
+#ifdef HAVE_LIBOTR_0400
+ otrl_instag_t instance = session->property("otr-instag").toUInt();
+ context = otrl_context_find(userstate, session->members().getFirst()->contactId().latin1(), session->account()->accountId().latin1(), session->account()->protocol()->displayName().latin1(), instance, 0, NULL, NULL, NULL);
+#else // HAVE_LIBOTR_0400
+ context = otrl_context_find(userstate, session->members().getFirst()->contactId().latin1(), session->account()->accountId().latin1(), session->account()->protocol()->displayName().latin1(), 0, NULL, NULL, NULL);
+#endif // HAVE_LIBOTR_0400
+
+ 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;
+}
+
+TQString OtrlChatInterface::formatContact(TQString contactId){
+
+ Kopete::MetaContact *metaContact = Kopete::ContactList::self()->findMetaContactByContactId(contactId);
+ if( metaContact ){
+ TQString displayName = metaContact->displayName();
+ if((displayName != contactId) && !displayName.isNull()){
+ return displayName + " (" + contactId+")";
+ }
+ }
+ return contactId;
+}
+
+void OtrlChatInterface::verifyFingerprint( Kopete::ChatSession *session ){
+ ConnContext *context;
+
+#ifdef HAVE_LIBOTR_0400
+ otrl_instag_t instance = session->property("otr-instag").toUInt();
+ context = otrl_context_find( userstate, session->members().getFirst()->contactId().latin1(), session->account()->accountId().latin1(), session->protocol()->displayName().latin1(), instance, 0, NULL, NULL, NULL);
+#else // HAVE_LIBOTR_0400
+ context = otrl_context_find( userstate, session->members().getFirst()->contactId().latin1(), session->account()->accountId().latin1(), session->protocol()->displayName().latin1(), 0, NULL, NULL, NULL);
+#endif // HAVE_LIBOTR_0400
+
+ SMPPopup *popup = new SMPPopup( session->view()->mainWidget(), i18n("Enter authentication secret").utf8(), TQString::null, TQt::WType_Dialog | TQt::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, TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("fingerprints").local8Bit() );
+ OTRPlugin::plugin()->emitGoneSecure( session, privState( session ) );
+ } else {
+ kdDebug() << "could not find fingerprint" << endl;
+ }
+}
+
+Fingerprint *OtrlChatInterface::findFingerprint( TQString account ){
+ ConnContext *context;
+
+ for( context = userstate->context_root; context != NULL; context = context->next ){
+ kdDebug() << context->username << endl;
+ if (context->username == account)
+ {
+ kdDebug() << "found Context" << endl;
+ return context->active_fingerprint ? context->active_fingerprint : NULL;
+ }
+ }
+ return NULL;
+}
+
+TQString 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 (context->username == session->members().getFirst()->contactId())
+ {
+// 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;
+ TQFile keyfile( TQString(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkeys" );
+ TQString line;
+ TQString 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, TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("privkeys").local8Bit() );
+
+ file = "";
+ line = "";
+// Updating fingerprints from <=0.3
+ kdDebug() << "updating fingerprints" << endl;
+ TQFile fingerprintfile( TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("fingerprints").local8Bit() );
+
+ 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, TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("fingerprints").local8Bit(), NULL, NULL);
+
+}
+
+void OtrlChatInterface::checkFilePermissions( TQString file ){
+ if( TQFile::exists( file ) ){
+ TQFile privkeys( file );
+ TQFileInfo privkeysInfo( privkeys );
+ if( !privkeysInfo.permission( TQFileInfo::ReadOwner | TQFileInfo::WriteOwner ) |
+ privkeysInfo.permission( TQFileInfo::ReadGroup ) |
+ privkeysInfo.permission( TQFileInfo::WriteGroup ) |
+ privkeysInfo.permission( TQFileInfo::ExeGroup ) |
+ privkeysInfo.permission( TQFileInfo::ReadOther ) |
+ privkeysInfo.permission( TQFileInfo::WriteOther ) |
+ privkeysInfo.permission( TQFileInfo::ExeOther ) ){
+ kdDebug() << "Permissions of OTR storage file are wrong! Correcting..." << endl;
+ chmod( file.local8Bit(), 0600);
+ }
+ }
+
+}
+
+/*bool OtrlChatInterface::verifyQuestion( Kopete::ChatSession *session, TQString 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, TQString secret, bool initiate ){
+ if( initiate ){
+#ifdef HAVE_LIBOTR_0400
+ otrl_instag_t instance = session->property("otr-instag").toUInt();
+ context = otrl_context_find( userstate, session->members().getFirst()->contactId().latin1(), session->account()->accountId().latin1(), session->protocol()->displayName().latin1(), instance, 0, NULL, NULL, NULL);
+#else // HAVE_LIBOTR_0400
+ context = otrl_context_find( userstate, session->members().getFirst()->contactId().latin1(), session->account()->accountId().latin1(), session->protocol()->displayName().latin1(), 0, NULL, NULL, NULL);
+#endif // HAVE_LIBOTR_0400
+ 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 );
+}
+
+void OtrlChatInterface::respondSMPQ( ConnContext *context, Kopete::ChatSession *session, TQString question, TQString secret, bool initiate ){
+ if( initiate ){
+#ifdef HAVE_LIBOTR_0400
+ otrl_instag_t instance = session->property("otr-instag").toUInt();
+ context = otrl_context_find( userstate, session->members().getFirst()->contactId().latin1(), session->account()->accountId().latin1(), session->protocol()->displayName().latin1(), instance, 0, NULL, NULL, NULL);
+#else // HAVE_LIBOTR_0400
+ context = otrl_context_find( userstate, session->members().getFirst()->contactId().latin1(), session->account()->accountId().latin1(), session->protocol()->displayName().latin1(), 0, NULL, NULL, NULL);
+#endif // HAVE_LIBOTR_0400
+ otrl_message_initiate_smp_q( userstate, &ui_ops, session, context, (const char*)question.latin1(), (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( TQString accountname, TQString protocol ){
+ this->accountname = accountname;
+ this->protocol = protocol;
+}
+
+
+void KeyGenThread::run()
+{
+ kdDebug() << "Creating private key... Storing to: " + TQString(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true)) + "privkeys" << endl;
+ otrl_privkey_generate(OtrlChatInterface::self()->getUserstate(), TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("privkeys").local8Bit(), accountname.latin1(), protocol.latin1());
+ OtrlChatInterface::self()->checkFilePermissions( TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("privkeys").local8Bit() );
+}
+
+#include "otrlchatinterface.moc"
diff --git a/kopete/plugins/otr/otrlchatinterface.h b/kopete/plugins/otr/otrlchatinterface.h
new file mode 100644
index 00000000..c4a94280
--- /dev/null
+++ b/kopete/plugins/otr/otrlchatinterface.h
@@ -0,0 +1,96 @@
+/***************************************************************************
+ * 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 <tqstring.h>
+#include <tqptrlist.h>
+#include <tqvaluelist.h>
+#include <tqthread.h>
+#include <tqmutex.h>
+#include <tqtimer.h>
+
+#include <kopetechatsession.h>
+
+extern "C" {
+#include <libotr/privkey.h>
+#include <libotr/proto.h>
+#include <libotr/message.h>
+#include <libotr/userstate.h>
+}
+
+class KDE_EXPORT OtrlChatInterface: public TQObject
+{
+ Q_OBJECT
+
+public:
+ ~OtrlChatInterface();
+ static OtrlChatInterface *self();
+
+ int decryptMessage( TQString *msg, TQString accountId, TQString protocol, TQString contactId, Kopete::ChatSession *chatSession );
+ TQString encryptMessage( TQString msg, TQString accountId,
+ TQString protocol, TQString contactId , Kopete::ChatSession *chatSession );
+ TQString getDefaultQuery( TQString accountId );
+ void disconnectSession( Kopete::ChatSession *chatSession );
+ void setPolicy( OtrlPolicy policy );
+ bool shouldDiscard( TQString message );
+ OtrlUserState getUserstate();
+ int privState( Kopete::ChatSession *session );
+ TQString formatContact(TQString contactId);
+ bool isVerified( Kopete::ChatSession *session );
+ void updateKeyfile( Kopete::Account *account );
+ void checkFilePermissions( TQString file );
+// bool verifyQuestion( Kopete::ChatSession *session, TQString fingerprint );
+ TQString findActiveFingerprint( Kopete::ChatSession *session );
+ void verifyFingerprint( Kopete::ChatSession *session );
+ void abortSMP( ConnContext *context, Kopete::ChatSession *session );
+ void respondSMP( ConnContext *context, Kopete::ChatSession *session, TQString secret, bool initiate );
+ void respondSMPQ( ConnContext *context, Kopete::ChatSession *session, TQString question, TQString secret, bool initiate );
+ void setTrust( Kopete::ChatSession *session, bool trust );
+ void forwardSecrecyTimerStart(int interval);
+ void forwardSecrecyTimerStop();
+
+private slots:
+ void otrlMessagePoll();
+
+private:
+ OtrlChatInterface();
+ static OtrlChatInterface *mSelf;
+ Fingerprint *findFingerprint( TQString username );
+ TQTimer m_forwardSecrecyTimer;
+};
+
+class KeyGenThread : public TQThread {
+
+private:
+ TQString accountname;
+ TQString protocol;
+
+public:
+ KeyGenThread( TQString accountname, TQString protocol );
+ virtual void run();
+};
+
+#endif
diff --git a/kopete/plugins/otr/otrlconfinterface.cpp b/kopete/plugins/otr/otrlconfinterface.cpp
new file mode 100644
index 00000000..7a025bd1
--- /dev/null
+++ b/kopete/plugins/otr/otrlconfinterface.cpp
@@ -0,0 +1,236 @@
+/***************************************************************************
+ * 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
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <tqapplication.h>
+#include <tqeventloop.h>
+
+#include <kopetechatsession.h>
+#include <kopeteaccount.h>
+
+#include <kdebug.h>
+#include <tdemessagebox.h>
+#include <kstandarddirs.h>
+#include <tdelocale.h>
+#include <kanimwidget.h>
+
+
+#include "otrlconfinterface.h"
+#include "otrlchatinterface.h"
+#include "otrplugin.h"
+#include "privkeypopup.h"
+
+
+
+/*********************** Konstruktor/Destruktor **********************/
+
+OtrlConfInterface::OtrlConfInterface( TQWidget *preferencesDialog ){
+
+ this->preferencesDialog = preferencesDialog;
+
+ OTRL_INIT;
+
+ userstate = OtrlChatInterface::self()->getUserstate();
+
+ kdDebug() << "OtrlConfInterface created" << endl;
+}
+
+OtrlConfInterface::~ OtrlConfInterface(){
+ otrl_userstate_free(userstate);
+}
+
+/*********************** Functions for kcm module ************************/
+
+TQString OtrlConfInterface::getPrivFingerprint( TQString accountId, TQString protocol){
+// if (otrl_privkey_read(userstate, TQString(TDEGlobal::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( TQString accountId, TQString protocol ){
+ char fingerprint[45];
+ if( otrl_privkey_fingerprint( userstate, fingerprint, accountId.latin1(), protocol.latin1() ) != 0 ){
+ return true;
+ }
+ return false;
+}
+
+
+void OtrlConfInterface::generateNewPrivKey( TQString accountId, TQString protocol ){
+ PrivKeyPopup *popup = new PrivKeyPopup( preferencesDialog, i18n("Generating private key").utf8(), TQt::WType_Dialog | TQt::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) ){
+ tqApp->eventLoop()->processEvents(TQEventLoop::ExcludeUserInput | TQEventLoop::ExcludeSocketNotifiers, 100);
+ }
+ popup->setCloseLock( false );
+ popup->close();
+}
+
+TQValueList<TQStringList> OtrlConfInterface::readAllFingerprints(){
+ ConnContext *context;
+ Fingerprint *fingerprint;
+ TQStringList entry;
+ char hash[45];
+ TQValueList<TQStringList> list;
+
+ for( context = userstate->context_root; context != NULL; context = context->next ){
+ fingerprint = context->fingerprint_root.next;
+ while( fingerprint ){
+ entry.clear();
+ entry << context->username;
+
+ if( ( context->msgstate == OTRL_MSGSTATE_ENCRYPTED ) && ( context->active_fingerprint != fingerprint ) ){
+ entry << i18n("Unused");
+ } else {
+ if (context && context->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
+ if (context->active_fingerprint->trust && context->active_fingerprint->trust[0] != 0) {
+ entry << i18n("Private");
+ } else {
+ entry << i18n("Unverified");
+ }
+ } else if (context && context->msgstate == OTRL_MSGSTATE_FINISHED) {
+ entry << i18n("Finished");
+ } else {
+ entry << i18n("Not Private");
+ }
+ }
+ entry << ((fingerprint->trust && fingerprint->trust[0]) ? i18n("Yes") : i18n("No"));
+ otrl_privkey_hash_to_human( hash, fingerprint->fingerprint );
+ entry << hash;
+ entry << context->protocol;
+ list << entry;
+ fingerprint = fingerprint->next;
+ }
+ }
+ return list;
+}
+
+void OtrlConfInterface::verifyFingerprint( TQString 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, TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("fingerprints").local8Bit() );
+ } else {
+ kdDebug() << "could not find fingerprint" << endl;
+ }
+}
+
+bool OtrlConfInterface::isVerified( TQString strFingerprint ){
+ Fingerprint *fingerprint;
+
+ fingerprint = findFingerprint( strFingerprint.latin1() );
+
+ if( fingerprint->trust && fingerprint->trust[0] ){
+ kdDebug() << "found trust" << endl;
+ return true;
+ } else {
+ kdDebug() << "not trusted" << endl;
+ return false;
+ }
+}
+
+
+void OtrlConfInterface::forgetFingerprint( TQString strFingerprint ){
+ Fingerprint *fingerprint;
+
+ fingerprint = findFingerprint( strFingerprint );
+ otrl_context_forget_fingerprint( fingerprint, 1 );
+ otrl_privkey_write_fingerprints( userstate, TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("fingerprints").local8Bit() );
+}
+
+Fingerprint *OtrlConfInterface::findFingerprint( TQString 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( TQString 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/kopete/plugins/otr/otrlconfinterface.h b/kopete/plugins/otr/otrlconfinterface.h
new file mode 100644
index 00000000..0e743e2f
--- /dev/null
+++ b/kopete/plugins/otr/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 <tqstring.h>
+#include <tqptrlist.h>
+#include <tqvaluelist.h>
+#include <tqthread.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 KDE_EXPORT OtrlConfInterface
+{
+
+public:
+ ~OtrlConfInterface();
+ OtrlConfInterface( TQWidget *preferencesDialog );
+
+ TQString getPrivFingerprint( TQString accountId, TQString protocol );
+ void generateNewPrivKey( TQString accountId, TQString protocol );
+ TQValueList<TQStringList> readAllFingerprints();
+ bool hasPrivFingerprint( TQString accountId, TQString protocol);
+ void forgetFingerprint( TQString strFingerprint );
+ void verifyFingerprint( TQString strFingerprint, bool trust );
+ bool isVerified( TQString strFingerprint );
+ bool isEncrypted( TQString strFingerprint );
+
+private:
+ OtrlUserState userstate;
+ TQWidget *preferencesDialog;
+
+ Fingerprint *findFingerprint( TQString strFingerprint );
+};
+
+#endif
diff --git a/kopete/plugins/otr/otrplugin-factory.cpp b/kopete/plugins/otr/otrplugin-factory.cpp
new file mode 100644
index 00000000..1d6fafcd
--- /dev/null
+++ b/kopete/plugins/otr/otrplugin-factory.cpp
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * Copyright (C) 2021 by Slávek Banko *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <kgenericfactory.h>
+#include <tdeaboutdata.h>
+
+#include "otrplugin-factory.h"
+#include "otrplugin.h"
+
+
+// typedef KGenericFactory<OTRPlugin> OTRPluginFactory;
+static const TDEAboutData aboutdata("kopete_otr", I18N_NOOP("OTR") , "0.7" );
+K_EXPORT_COMPONENT_FACTORY( kopete_otr, OTRPluginFactory( &aboutdata ) )
+
+TDEInstance *OTRPluginFactory::s_instance = 0;
+
+OTRPluginFactory::OTRPluginFactory( const TDEAboutData *aboutdata )
+{
+ s_instance = new TDEInstance( aboutdata );
+}
+
+OTRPluginFactory::~OTRPluginFactory()
+{
+ delete s_instance;
+}
+
+KParts::Part *OTRPluginFactory::createPartObject( TQWidget * /*parentWidget*/,
+ const char * /*widgetName*/,
+ TQObject *parent,
+ const char *name,
+ const char * /*className*/,
+ const TQStringList & args )
+{
+ return (KParts::Part*) new OTRPlugin( instance(), parent, name, args);
+}
+
+#include "otrplugin-factory.moc"
diff --git a/kopete/plugins/otr/otrplugin-factory.h b/kopete/plugins/otr/otrplugin-factory.h
new file mode 100644
index 00000000..a38ea5fe
--- /dev/null
+++ b/kopete/plugins/otr/otrplugin-factory.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2021 by Slávek Banko *
+ * *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#if !defined(OTRPLUGIN_FACTORY_H)
+#define OTRPLUGIN_FACTORY_H
+
+#include <tdeparts/factory.h>
+
+
+class OTRPluginFactory : public KParts::Factory
+{
+ Q_OBJECT
+
+public:
+ OTRPluginFactory( const TDEAboutData* );
+ virtual ~OTRPluginFactory();
+
+ virtual KParts::Part *createPartObject( TQWidget *parentWidget, const char *widgetName,
+ TQObject *parent, const char *name,
+ const char *className, const TQStringList &args );
+
+ static TDEInstance *instance() { return s_instance; }
+
+private:
+ static TDEInstance *s_instance;
+};
+
+#endif /* OTRPLUGIN_FACTORY_H */
diff --git a/kopete/plugins/otr/otrplugin.cpp b/kopete/plugins/otr/otrplugin.cpp
new file mode 100644
index 00000000..a78cfd52
--- /dev/null
+++ b/kopete/plugins/otr/otrplugin.cpp
@@ -0,0 +1,339 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <tqstylesheet.h>
+#include <tqtimer.h>
+#include <tqregexp.h>
+#include <tqfile.h>
+#include <tqcolor.h>
+
+#include <kdebug.h>
+#include <tdeaction.h>
+#include <tdeactionclasses.h>
+#include <tdepopupmenu.h>
+#include <tdeconfig.h>
+#include <kgenericfactory.h>
+#include <tdeversion.h>
+#include <kstandarddirs.h>
+#include <tdemessagebox.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
+ */
+
+
+OTRPlugin::OTRPlugin( TDEInstance *instance, TQObject *parent, const char *name, const TQStringList & /* args */ )
+: Kopete::Plugin( instance, parent, name )
+{
+ if( !pluginStatic_ )
+ pluginStatic_=this;
+
+ m_inboundHandler = new OtrMessageHandlerFactory(this);
+
+ connect( Kopete::ChatSessionManager::self(), TQT_SIGNAL( aboutToSend( Kopete::Message & ) ),
+ TQT_SLOT( slotOutgoingMessage( Kopete::Message & ) ) );
+// connect( Kopete::ChatSessionManager::self(), TQT_SIGNAL( aboutToDisplay( Kopete::Message & ) ),
+// this, TQT_SLOT( slotIncomingMessage( Kopete::Message & ) ) );
+
+ connect( Kopete::ChatSessionManager::self(), TQT_SIGNAL( chatSessionCreated( Kopete::ChatSession * ) ),
+ this, TQT_SLOT( slotNewChatSessionWindow( Kopete::ChatSession * ) ) );
+ TQObject::connect( this, TQT_SIGNAL( settingsChanged() ), this, TQT_SLOT( slotSettingsChanged() ) );
+
+
+
+ //initialize the otrlib and create the interface object
+ otrlChatInterface = OtrlChatInterface::self();
+
+ //update key files when an account is ready to use
+ if( TQFile::exists( TQString( TDEGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "privkey" ) &&
+ !TQFile::exists( TQString( TDEGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "privkeys" ) ){
+ kdDebug() << "Detected old format keyfile. Doing updates!" << endl;
+ kdDebug() << "Reading old keyfile..." << endl;
+ TQFile fpold( TQString(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkey" );
+ TQString line;
+ TQString file;
+ if( fpold.open( IO_ReadWrite ) ){
+ while( fpold.readLine( line, 100 ) != -1){
+ file.append( line );
+ }
+ }
+ kdDebug() << "Writing new keyfile" << endl;
+ TQFile fpnew( TQString(TDEGlobal::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;
+ TQFile fpbup( TQString(TDEGlobal::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;
+ TQFile fpfingerprintsold( TQString(TDEGlobal::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;
+ TQFile fpfingerprintsbup( TQString(TDEGlobal::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(), TQT_SIGNAL( accountRegistered( Kopete::Account * ) ),
+ this, TQT_SLOT( accountReady( Kopete::Account * ) ) );
+ }
+
+ // Checking file Permissions
+ OtrlChatInterface::self()->checkFilePermissions( TQString( TDEGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "privkeys" );
+ OtrlChatInterface::self()->checkFilePermissions( TQString( TDEGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "fingerprints" );
+ // Check also file permissions for eventuallly old beckup files
+ OtrlChatInterface::self()->checkFilePermissions( TQString( TDEGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "privkey.old" );
+ OtrlChatInterface::self()->checkFilePermissions( TQString( TDEGlobal::dirs()->saveLocation( "data", "kopete_otr/", true ) ) + "fingerprints.old" );
+
+ //setting the policy
+ slotSettingsChanged();
+
+ //adding menu to contaclists menubar and contacts popup menu
+ TQStringList policies;
+ policies << i18n("&Default") << i18n("Al&ways") << i18n("&Opportunistic") << i18n("&Manual") << i18n("Ne&ver");
+ otrPolicyMenu = new TDESelectAction( i18n( "&OTR Policy" ), TQString::fromLatin1("kopete_otr"), 0, actionCollection(), "otr_policy" );
+ otrPolicyMenu->setItems( policies );
+ otrPolicyMenu->popupMenu()->insertSeparator( 1 );
+ otrPolicyMenu->setEnabled( false );
+ connect( otrPolicyMenu, TQT_SIGNAL( activated() ), this, TQT_SLOT( slotSetPolicy() ) );
+ connect( Kopete::ContactList::self(), TQT_SIGNAL( metaContactSelected( bool ) ), this, TQT_SLOT( slotSelectionChanged( bool ) ) );
+
+
+ setXMLFile( "otrui.rc" );
+
+
+
+ //Add GUI action to all already existing kmm
+ // (if the plugin is launched when kopete already runing)
+ TQValueList<Kopete::ChatSession*> sessions =
+ Kopete::ChatSessionManager::self()->sessions();
+ TQValueListIterator<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 ){
+ TQString plainBody = msg.plainBody();
+ TQString accountId = msg.manager()->account()->accountId();
+ Kopete::Contact *contact = msg.to().first();
+
+ TQString 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 ){
+ TQString 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 {
+ TQString body = otrlChatInterface->getDefaultQuery( session->account()->accountId() );
+ Kopete::Message msg1( session->account()->myself(), session->members().getFirst(), TQString( 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 );
+}
+
+TQMap<TQString, TQString> OTRPlugin::getMessageCache(){
+ return messageCache;
+}
+
+void OtrMessageHandler::handleMessage( Kopete::MessageEvent *event ){
+ Kopete::Message msg = event->message();
+ Kopete::ChatSession *session = msg.manager();
+ TQMap<TQString, TQString> messageCache = OTRPlugin::plugin()->getMessageCache();
+
+ if( msg.direction() == Kopete::Message::Inbound ){
+ TQString body = msg.parsedBody();
+kdDebug() << "Received Message: " << msg.parsedBody() << endl;
+ TQString accountId = msg.manager()->account()->accountId();
+ TQString 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();
+
+ TQString 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", TQString::number( otrPolicyMenu->currentItem() ) );
+ }
+}
+
+void OTRPlugin::accountReady( Kopete::Account *account ){
+ kdDebug() << "Account " << account->accountId() << " ready. Calling update function."<< endl;
+ otrlChatInterface->updateKeyfile( account );
+}
+
+
+#include "otrplugin.moc"
diff --git a/kopete/plugins/otr/otrplugin.h b/kopete/plugins/otr/otrplugin.h
new file mode 100644
index 00000000..23943aa0
--- /dev/null
+++ b/kopete/plugins/otr/otrplugin.h
@@ -0,0 +1,117 @@
+/***************************************************************************
+ 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 TDESelectAction;
+
+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 KDE_EXPORT OTRPlugin : public Kopete::Plugin
+{
+ Q_OBJECT
+
+public:
+
+ static OTRPlugin *plugin();
+
+ OTRPlugin( TDEInstance *instance, TQObject *parent, const char *name, const TQStringList &args );
+ ~OTRPlugin();
+
+ void emitGoneSecure( Kopete::ChatSession *session, int status );
+ TQMap<TQString, TQString> 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;
+ TQMap<TQString, TQString> messageCache;
+ TDESelectAction* otrPolicyMenu;
+
+/* TDEActionMenu *otrPolicyMenuBar;
+ TDEActionMenu *otrPolicyPopup;
+ TDEAction *otrPolicyDefault;
+ TDEAction *otrPolicyAlways;
+ TDEAction *otrPolicyOpportunistic;
+ TDEAction *otrPolicyManual;
+ TDEAction *otrPolicyNever;
+// SessionManager manager
+*/
+
+signals:
+ void goneSecure( Kopete::ChatSession *session, int state );
+
+};
+
+#endif
diff --git a/kopete/plugins/otr/otrpreferences.cpp b/kopete/plugins/otr/otrpreferences.cpp
new file mode 100644
index 00000000..b88c602e
--- /dev/null
+++ b/kopete/plugins/otr/otrpreferences.cpp
@@ -0,0 +1,202 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tqmap.h>
+#include <tqptrlist.h>
+#include <tqcombobox.h>
+#include <tqstringlist.h>
+#include <tqtable.h>
+#include <tqpaintdevicemetrics.h>
+#include <tqvbox.h>
+#include <tqradiobutton.h>
+#include <tqtabwidget.h>
+
+#include <kgenericfactory.h>
+#include <kurlrequester.h>
+#include <tdemessagebox.h>
+#include <tdeconfig.h>
+#include <tdeapplication.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(TQWidget *parent, const char* /*name*/, const TQStringList &args)
+ : TDECModule(OTRPreferencesFactory::instance(), parent, args)
+{
+ ( new TQVBoxLayout( this ) )->setAutoAdd( true );
+ preferencesDialog = new OTRPrefsUI(this);
+
+
+ this->addConfig( KopeteOtrKcfg::self(), preferencesDialog );
+ KopeteOtrKcfg::self()->readConfig();
+ load();
+
+
+
+ otrlConfInterface = new OtrlConfInterface( preferencesDialog );
+
+ connect( preferencesDialog->btGenFingerprint, TQT_SIGNAL(clicked()), TQT_SLOT(generateFingerprint()));
+ connect( preferencesDialog->cbKeys, TQT_SIGNAL(activated(int)), TQT_SLOT(showPrivFingerprint(int)));
+ connect( preferencesDialog->btVerify, TQT_SIGNAL(clicked()), TQT_SLOT(verifyFingerprint()));
+ connect( preferencesDialog->twSettings, TQT_SIGNAL(currentChanged(TQWidget *)), TQT_SLOT(fillFingerprints()));
+ connect( preferencesDialog->tbFingerprints, TQT_SIGNAL(currentChanged(int, int)), TQT_SLOT(updateButtons(int, int)));
+ connect( preferencesDialog->btForget, TQT_SIGNAL( clicked() ), TQT_SLOT( forgetFingerprint() ) );
+
+ int index = 0;
+ int accountnr = 0;
+ TQPtrList<Kopete::Account> accounts = Kopete::AccountManager::self()->accounts();
+ if( !accounts.isEmpty() ){
+ for ( TQPtrListIterator<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()
+{
+ TQPtrList<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 )
+{
+ TQPtrList<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(){
+ TQTable *fingerprintsTable = preferencesDialog->tbFingerprints;
+ preferencesDialog->tbFingerprints->setNumRows(0);
+ TQValueList<TQStringList> list = otrlConfInterface->readAllFingerprints();
+ TQValueList<TQStringList>::iterator it;
+ int j = 0;
+ for( it = list.begin(); it != list.end(); ++it ){
+ preferencesDialog->tbFingerprints->setNumRows( preferencesDialog->tbFingerprints->numRows() +1 );
+ fingerprintsTable->setItem(j, 0, new TQAlignTableItem(fingerprintsTable, TQTableItem::Never,
+ OtrlChatInterface::self()->formatContact((*it)[0]), TQt::AlignLeft));
+ for( int i = 1; i < 5; i++ ){
+ //preferencesDialog->tbFingerprints->setText(j, i, (*it)[i] );
+ fingerprintsTable->setItem(j,i, new TQAlignTableItem(fingerprintsTable, TQTableItem::Never,(*it)[i],TQt::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() );
+ }
+}
+
+TQAlignTableItem :: TQAlignTableItem( TQTable *table, EditType editType, const TQString& text, int alignment )
+ : TQTableItem( table, editType, text ) {
+ align = alignment;
+}
+
+
+#include "otrpreferences.moc"
diff --git a/kopete/plugins/otr/otrpreferences.h b/kopete/plugins/otr/otrpreferences.h
new file mode 100644
index 00000000..f4b4f162
--- /dev/null
+++ b/kopete/plugins/otr/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 <tdecmodule.h>
+#include "otrlconfinterface.h"
+
+/**
+ * Preference widget for the OTR plugin
+ * @author Michael Zanetti
+ */
+
+class OTRPreferences : public TDECModule {
+ Q_OBJECT
+
+public:
+ OTRPreferences(TQWidget *parent = 0, const char *name = 0, const TQStringList &args = TQStringList());
+ ~OTRPreferences();
+
+private:
+ OTRPrefsUI *preferencesDialog;
+ OtrlConfInterface *otrlConfInterface;
+ TQMap<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 TQAlignTableItem : public TQTableItem {
+
+public :
+ TQAlignTableItem(TQTable *table, EditType editType, const TQString& text, int alignment);
+
+private :
+ int align;
+};
+
+#endif
diff --git a/kopete/plugins/otr/otrprefs.ui b/kopete/plugins/otr/otrprefs.ui
new file mode 100644
index 00000000..cb93975f
--- /dev/null
+++ b/kopete/plugins/otr/otrprefs.ui
@@ -0,0 +1,295 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>OTRPrefsUI</class>
+<widget class="TQWidget">
+ <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="TQTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>twSettings</cstring>
+ </property>
+ <widget class="TQWidget">
+ <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="TQGroupBox" 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="TQPushButton" 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="TQComboBox" 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="TQLabel" 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="TQButtonGroup" 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="TQRadioButton" 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="TQRadioButton" 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="TQRadioButton" 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="TQRadioButton" 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="TQWidget">
+ <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="TQTable" 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="TQPushButton" 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="TQPushButton" 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>
+<Q_SLOTS>
+ <slot access="private">generateFingerprint()</slot>
+</Q_SLOTS>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kactivelabel.h</includehint>
+</includehints>
+</UI>
diff --git a/kopete/plugins/otr/otrui.rc b/kopete/plugins/otr/otrui.rc
new file mode 100644
index 00000000..7b889e37
--- /dev/null
+++ b/kopete/plugins/otr/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/kopete/plugins/otr/pics/CMakeLists.txt b/kopete/plugins/otr/pics/CMakeLists.txt
new file mode 100644
index 00000000..18554eb0
--- /dev/null
+++ b/kopete/plugins/otr/pics/CMakeLists.txt
@@ -0,0 +1,5 @@
+##### icons
+
+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete_otr/icons )
+
+tde_install_icons( kopete_otr )
diff --git a/kopete/plugins/otr/pics/cr16-action-otr_disabled.png b/kopete/plugins/otr/pics/cr16-action-otr_disabled.png
new file mode 100644
index 00000000..138bf9b6
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr16-action-otr_disabled.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr16-action-otr_finished.png b/kopete/plugins/otr/pics/cr16-action-otr_finished.png
new file mode 100644
index 00000000..45cdc917
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr16-action-otr_finished.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr16-action-otr_private.png b/kopete/plugins/otr/pics/cr16-action-otr_private.png
new file mode 100644
index 00000000..ccddf679
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr16-action-otr_private.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr16-action-otr_unverified.png b/kopete/plugins/otr/pics/cr16-action-otr_unverified.png
new file mode 100644
index 00000000..b1930dd1
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr16-action-otr_unverified.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr16-app-kopete_otr.png b/kopete/plugins/otr/pics/cr16-app-kopete_otr.png
new file mode 100644
index 00000000..6941f9f7
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr16-app-kopete_otr.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr16-app-otr.png b/kopete/plugins/otr/pics/cr16-app-otr.png
new file mode 100644
index 00000000..ccddf679
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr16-app-otr.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr22-action-otr_disabled.png b/kopete/plugins/otr/pics/cr22-action-otr_disabled.png
new file mode 100644
index 00000000..fdd0674e
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr22-action-otr_disabled.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr22-action-otr_finished.png b/kopete/plugins/otr/pics/cr22-action-otr_finished.png
new file mode 100644
index 00000000..de313280
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr22-action-otr_finished.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr22-action-otr_private.png b/kopete/plugins/otr/pics/cr22-action-otr_private.png
new file mode 100644
index 00000000..d325a8d4
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr22-action-otr_private.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr22-action-otr_unverified.png b/kopete/plugins/otr/pics/cr22-action-otr_unverified.png
new file mode 100644
index 00000000..18c1481b
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr22-action-otr_unverified.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr32-action-otr_disabled.png b/kopete/plugins/otr/pics/cr32-action-otr_disabled.png
new file mode 100644
index 00000000..fb0a7e35
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr32-action-otr_disabled.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr32-action-otr_finished.png b/kopete/plugins/otr/pics/cr32-action-otr_finished.png
new file mode 100644
index 00000000..d6dec0ce
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr32-action-otr_finished.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr32-action-otr_private.png b/kopete/plugins/otr/pics/cr32-action-otr_private.png
new file mode 100644
index 00000000..b45526c9
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr32-action-otr_private.png
Binary files differ
diff --git a/kopete/plugins/otr/pics/cr32-action-otr_unverified.png b/kopete/plugins/otr/pics/cr32-action-otr_unverified.png
new file mode 100644
index 00000000..04021c29
--- /dev/null
+++ b/kopete/plugins/otr/pics/cr32-action-otr_unverified.png
Binary files differ
diff --git a/kopete/plugins/otr/privkeypopup.cpp b/kopete/plugins/otr/privkeypopup.cpp
new file mode 100644
index 00000000..58c92b52
--- /dev/null
+++ b/kopete/plugins/otr/privkeypopup.cpp
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * 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
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <kdemacros.h>
+
+#include "privkeypopup.h"
+
+PrivKeyPopup::PrivKeyPopup(TQWidget* parent, const char* name, WFlags fl)
+: PrivKeyPopupUI(parent,name,fl)
+{
+}
+
+PrivKeyPopup::~PrivKeyPopup()
+{
+}
+
+void PrivKeyPopup::setCloseLock( bool locked ){
+ closeLock = locked;
+}
+
+void PrivKeyPopup::closeEvent( TQCloseEvent *e ){
+ if( closeLock ){
+ e->ignore();
+ } else {
+ e->accept();
+ }
+}
+/*$SPECIALIZATION$*/
+
+
+#include "privkeypopup.moc"
+
diff --git a/kopete/plugins/otr/privkeypopup.h b/kopete/plugins/otr/privkeypopup.h
new file mode 100644
index 00000000..fab64ab4
--- /dev/null
+++ b/kopete/plugins/otr/privkeypopup.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * 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(TQWidget* 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( TQCloseEvent *e );
+
+protected slots:
+ /*$PROTECTED_SLOTS$*/
+
+};
+
+#endif
diff --git a/kopete/plugins/otr/privkeypopupui.ui b/kopete/plugins/otr/privkeypopupui.ui
new file mode 100644
index 00000000..34f90d40
--- /dev/null
+++ b/kopete/plugins/otr/privkeypopupui.ui
@@ -0,0 +1,64 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>PrivKeyPopupUI</class>
+<widget class="TQWidget">
+ <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="TQLabel" 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="TQFrame" 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/kopete/plugins/otr/smppopup.cpp b/kopete/plugins/otr/smppopup.cpp
new file mode 100644
index 00000000..fef988e4
--- /dev/null
+++ b/kopete/plugins/otr/smppopup.cpp
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <tqlabel.h>
+
+#include <kdebug.h>
+#include <tdelocale.h>
+#include <klineedit.h>
+#include <kurl.h>
+#include <krun.h>
+
+#include "smppopup.h"
+#include "verifypopup.h"
+
+SMPPopup::SMPPopup(TQWidget* parent, const char* name, TQString title, WFlags fl, ConnContext *context, Kopete::ChatSession *session, bool initiate )
+: SMPPopupUI(parent,name,fl)
+{
+ this->context = context;
+ this->session = session;
+ this->initiate = initiate;
+ if (title.isNull()) {
+ question = false;
+ tlText->setText( i18n("Please enter the secret passphrase to authenticate %1:").arg(OtrlChatInterface::self()->formatContact(session->members().getFirst()->contactId())));
+ }
+ else {
+ question = true;
+ tlText->setText( title );
+ }
+}
+
+SMPPopup::~SMPPopup()
+{
+}
+
+/*$SPECIALIZATION$*/
+void SMPPopup::cancelSMP()
+{
+ OtrlChatInterface::self()->abortSMP( context, session );
+ this->close();
+}
+
+void SMPPopup::respondSMP()
+{
+ if (question) {
+ OtrlChatInterface::self()->respondSMPQ( context, session, tlText->text(), leSecret->text(), initiate );
+ }
+ else {
+ 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").utf8(), session);
+ vfPopup->show();
+ this->close();
+}
+
+#include "smppopup.moc"
+
diff --git a/kopete/plugins/otr/smppopup.h b/kopete/plugins/otr/smppopup.h
new file mode 100644
index 00000000..10801dd8
--- /dev/null
+++ b/kopete/plugins/otr/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(TQWidget* parent = 0, const char* name = 0, TQString title = TQString::null, 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;
+ bool question;
+
+protected slots:
+ /*$PROTECTED_SLOTS$*/
+
+};
+
+#endif
diff --git a/kopete/plugins/otr/smppopupui.ui b/kopete/plugins/otr/smppopupui.ui
new file mode 100644
index 00000000..b2dc7f81
--- /dev/null
+++ b/kopete/plugins/otr/smppopupui.ui
@@ -0,0 +1,191 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>SMPPopupUI</class>
+<widget class="TQWidget">
+ <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="TQLabel">
+ <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="TQLabel">
+ <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>
+<Q_SLOTS>
+ <slot>manualAuth()</slot>
+ <slot>respondSMP()</slot>
+ <slot>openHelp()</slot>
+ <slot>cancelSMP()</slot>
+</Q_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/kopete/plugins/otr/verifypopup.cpp b/kopete/plugins/otr/verifypopup.cpp
new file mode 100644
index 00000000..92b52eb0
--- /dev/null
+++ b/kopete/plugins/otr/verifypopup.cpp
@@ -0,0 +1,72 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include "verifypopup.h"
+#include "otrlchatinterface.h"
+#include "otrplugin.h"
+
+#include "tqlabel.h"
+
+#include "tdelocale.h"
+#include "kactivelabel.h"
+#include "kcombobox.h"
+
+#include "kopetechatsession.h"
+#include "kopetecontact.h"
+
+VerifyPopup::VerifyPopup(TQWidget* 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/kopete/plugins/otr/verifypopup.h b/kopete/plugins/otr/verifypopup.h
new file mode 100644
index 00000000..934de5db
--- /dev/null
+++ b/kopete/plugins/otr/verifypopup.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * 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(TQWidget* 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/kopete/plugins/otr/verifypopupui.ui b/kopete/plugins/otr/verifypopupui.ui
new file mode 100644
index 00000000..b1e066c8
--- /dev/null
+++ b/kopete/plugins/otr/verifypopupui.ui
@@ -0,0 +1,113 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>VerifyPopupUI</class>
+<widget class="TQDialog">
+ <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="TQLabel" 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>
+<Q_SLOTS>
+ <slot>cbChanged()</slot>
+</Q_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>