From d0e4d47caed252840a0f9986a1a18ab7bf451ddb Mon Sep 17 00:00:00 2001 From: gregory guy Date: Mon, 28 Jun 2021 16:13:49 +0200 Subject: [PATCH] Add kopete-otr plugin to kopete. Signed-off-by: gregory guy --- CMakeLists.txt | 35 +- kopete/CMakeLists.txt | 5 + kopete/ConfigureChecks.cmake | 15 + kopete/config-kopete.h.cmake | 2 + kopete/plugins/CMakeLists.txt | 33 +- kopete/plugins/otr/CMakeL10n.txt | 3 + kopete/plugins/otr/CMakeLists.txt | 125 ++ kopete/plugins/otr/kopete_otr.desktop | 20 + kopete/plugins/otr/kopete_otr.kcfg | 23 + kopete/plugins/otr/kopete_otr.kcfgc | 7 + kopete/plugins/otr/kopete_otr_config.desktop | 16 + kopete/plugins/otr/otrchatui.rc | 19 + kopete/plugins/otr/otrguiclient.cpp | 129 ++ kopete/plugins/otr/otrguiclient.h | 78 ++ kopete/plugins/otr/otrlchatinterface.cpp | 1076 +++++++++++++++++ kopete/plugins/otr/otrlchatinterface.h | 96 ++ kopete/plugins/otr/otrlconfinterface.cpp | 236 ++++ kopete/plugins/otr/otrlconfinterface.h | 66 + kopete/plugins/otr/otrplugin-factory.cpp | 58 + kopete/plugins/otr/otrplugin-factory.h | 45 + kopete/plugins/otr/otrplugin.cpp | 339 ++++++ kopete/plugins/otr/otrplugin.h | 117 ++ kopete/plugins/otr/otrpreferences.cpp | 202 ++++ kopete/plugins/otr/otrpreferences.h | 64 + kopete/plugins/otr/otrprefs.ui | 295 +++++ kopete/plugins/otr/otrui.rc | 12 + kopete/plugins/otr/pics/CMakeLists.txt | 5 + .../otr/pics/cr16-action-otr_disabled.png | Bin 0 -> 815 bytes .../otr/pics/cr16-action-otr_finished.png | Bin 0 -> 956 bytes .../otr/pics/cr16-action-otr_private.png | Bin 0 -> 750 bytes .../otr/pics/cr16-action-otr_unverified.png | Bin 0 -> 687 bytes .../plugins/otr/pics/cr16-app-kopete_otr.png | Bin 0 -> 758 bytes kopete/plugins/otr/pics/cr16-app-otr.png | Bin 0 -> 750 bytes .../otr/pics/cr22-action-otr_disabled.png | Bin 0 -> 812 bytes .../otr/pics/cr22-action-otr_finished.png | Bin 0 -> 1124 bytes .../otr/pics/cr22-action-otr_private.png | Bin 0 -> 873 bytes .../otr/pics/cr22-action-otr_unverified.png | Bin 0 -> 853 bytes .../otr/pics/cr32-action-otr_disabled.png | Bin 0 -> 1417 bytes .../otr/pics/cr32-action-otr_finished.png | Bin 0 -> 1889 bytes .../otr/pics/cr32-action-otr_private.png | Bin 0 -> 1391 bytes .../otr/pics/cr32-action-otr_unverified.png | Bin 0 -> 1397 bytes kopete/plugins/otr/privkeypopup.cpp | 57 + kopete/plugins/otr/privkeypopup.h | 54 + kopete/plugins/otr/privkeypopupui.ui | 64 + kopete/plugins/otr/smppopup.cpp | 87 ++ kopete/plugins/otr/smppopup.h | 62 + kopete/plugins/otr/smppopupui.ui | 191 +++ kopete/plugins/otr/verifypopup.cpp | 72 ++ kopete/plugins/otr/verifypopup.h | 49 + kopete/plugins/otr/verifypopupui.ui | 113 ++ 50 files changed, 3837 insertions(+), 33 deletions(-) create mode 100644 kopete/config-kopete.h.cmake create mode 100644 kopete/plugins/otr/CMakeL10n.txt create mode 100644 kopete/plugins/otr/CMakeLists.txt create mode 100644 kopete/plugins/otr/kopete_otr.desktop create mode 100644 kopete/plugins/otr/kopete_otr.kcfg create mode 100644 kopete/plugins/otr/kopete_otr.kcfgc create mode 100644 kopete/plugins/otr/kopete_otr_config.desktop create mode 100644 kopete/plugins/otr/otrchatui.rc create mode 100644 kopete/plugins/otr/otrguiclient.cpp create mode 100644 kopete/plugins/otr/otrguiclient.h create mode 100644 kopete/plugins/otr/otrlchatinterface.cpp create mode 100644 kopete/plugins/otr/otrlchatinterface.h create mode 100644 kopete/plugins/otr/otrlconfinterface.cpp create mode 100644 kopete/plugins/otr/otrlconfinterface.h create mode 100644 kopete/plugins/otr/otrplugin-factory.cpp create mode 100644 kopete/plugins/otr/otrplugin-factory.h create mode 100644 kopete/plugins/otr/otrplugin.cpp create mode 100644 kopete/plugins/otr/otrplugin.h create mode 100644 kopete/plugins/otr/otrpreferences.cpp create mode 100644 kopete/plugins/otr/otrpreferences.h create mode 100644 kopete/plugins/otr/otrprefs.ui create mode 100644 kopete/plugins/otr/otrui.rc create mode 100644 kopete/plugins/otr/pics/CMakeLists.txt create mode 100644 kopete/plugins/otr/pics/cr16-action-otr_disabled.png create mode 100644 kopete/plugins/otr/pics/cr16-action-otr_finished.png create mode 100644 kopete/plugins/otr/pics/cr16-action-otr_private.png create mode 100644 kopete/plugins/otr/pics/cr16-action-otr_unverified.png create mode 100644 kopete/plugins/otr/pics/cr16-app-kopete_otr.png create mode 100644 kopete/plugins/otr/pics/cr16-app-otr.png create mode 100644 kopete/plugins/otr/pics/cr22-action-otr_disabled.png create mode 100644 kopete/plugins/otr/pics/cr22-action-otr_finished.png create mode 100644 kopete/plugins/otr/pics/cr22-action-otr_private.png create mode 100644 kopete/plugins/otr/pics/cr22-action-otr_unverified.png create mode 100644 kopete/plugins/otr/pics/cr32-action-otr_disabled.png create mode 100644 kopete/plugins/otr/pics/cr32-action-otr_finished.png create mode 100644 kopete/plugins/otr/pics/cr32-action-otr_private.png create mode 100644 kopete/plugins/otr/pics/cr32-action-otr_unverified.png create mode 100644 kopete/plugins/otr/privkeypopup.cpp create mode 100644 kopete/plugins/otr/privkeypopup.h create mode 100644 kopete/plugins/otr/privkeypopupui.ui create mode 100644 kopete/plugins/otr/smppopup.cpp create mode 100644 kopete/plugins/otr/smppopup.h create mode 100644 kopete/plugins/otr/smppopupui.ui create mode 100644 kopete/plugins/otr/verifypopup.cpp create mode 100644 kopete/plugins/otr/verifypopup.h create mode 100644 kopete/plugins/otr/verifypopupui.ui 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 @@ + + + + + + + + false + + + + true + + + + false + + + + false + + + \ 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 @@ + + + + &Tools + OTR Encryption + + + + + + + + + OTR Encryption + + + + + 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 +#include +#include +#include +#include +#include +#include +#include +#include + + +#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 +#include + +//#include + +#include +#include +#include + +#include +#include + + +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 * + * * + * * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 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 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 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("Received a new fingerprint from %1. You should authenticate this contact.").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("Private OTR session started."), 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("Unverified OTR session started."), 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("OTR Session ended. The conversation is now insecure!"), 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("OTR connection refreshed successfully.") , 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("Authenticating contact..."), 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("Authentication successful. The conversation is now secure!"), 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("Authentication failed. The conversation is now insecure!"), 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("Authentication failed. The conversation is now insecure!"), 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("Authentication error!"), 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 %1").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("%1 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 %1 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 %1 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 %1."), 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 %1."), 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("The following message received from %1 was not encrypted: [%2]").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("%1 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("%1 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("Authentication successful. The conversation is now secure!"), 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("Authentication failed. The conversation is now insecure!"), 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("Authentication successful. The conversation is now secure!"), 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("Authentication failed. The conversation is now insecure!"), 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("Authentication error!"), 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("
"), 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("<"), 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( "<", "<", 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("Authentication aborded. The conversation is now insecure!"), 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("Authenticating contact..."), 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("Authenticating contact..."), 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 +#include +#include +#include +#include +#include + +#include + +extern "C" { +#include +#include +#include +#include +} + +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 +#include + +#include +#include + +#include +#include +#include +#include +#include + + +#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 OtrlConfInterface::readAllFingerprints(){ + ConnContext *context; + Fingerprint *fingerprint; + TQStringList entry; + char hash[45]; + TQValueList 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 +#include +#include +#include + +#include + +extern "C" { +#include +#include +#include +#include +#include +} + +class KDE_EXPORT OtrlConfInterface +{ + +public: + ~OtrlConfInterface(); + OtrlConfInterface( TQWidget *preferencesDialog ); + + TQString getPrivFingerprint( TQString accountId, TQString protocol ); + void generateNewPrivKey( TQString accountId, TQString protocol ); + TQValueList 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 +#include + +#include "otrplugin-factory.h" +#include "otrplugin.h" + + +// typedef KGenericFactory 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 + + +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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 sessions = + Kopete::ChatSessionManager::self()->sessions(); + TQValueListIterator 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 %1...").arg( otrlChatInterface->formatContact( session->members().getFirst()->contactId() ) ); + } else { + body = i18n("Attempting to start a private OTR session with %1...").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 OTRPlugin::getMessageCache(){ + return messageCache; +} + +void OtrMessageHandler::handleMessage( Kopete::MessageEvent *event ){ + Kopete::Message msg = event->message(); + Kopete::ChatSession *session = msg.manager(); + TQMap 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 + +#include +#include + +#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 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 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "otrprefs.h" +#include "otrpreferences.h" +#include "otrplugin.h" +#include "kopete_otr.h" + +/** + * @author Michael Zanetti + */ + +typedef KGenericFactory 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 accounts = Kopete::AccountManager::self()->accounts(); + if( !accounts.isEmpty() ){ + for ( TQPtrListIterator 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 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 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 list = otrlConfInterface->readAllFingerprints(); + TQValueList::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 +#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 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 @@ + +OTRPrefsUI + + + OTRPrefsUI + + + + 0 + 0 + 480 + 358 + + + + Form1 + + + + unnamed + + + + twSettings + + + + settings + + + &Settings + + + + unnamed + + + + groupBox1 + + + Private Keys + + + + unnamed + + + + btGenFingerprint + + + &Generate + + + Alt+G + + + + + cbKeys + + + + 400 + 32767 + + + + + + textLabel2 + + + Account: + + + + + tlFingerprint + + + + 7 + 5 + 0 + 0 + + + + No Fingerprint + + + + + + + bgPolicy + + + Default Policy + + + + unnamed + + + + kcfg_rbOpportunistic + + + &Opportunistic + + + Alt+O + + + Encrypt messages automatically if the other side supports OTR + + + + + kcfg_rbNever + + + Ne&ver + + + Alt+V + + + Never encrypt messages + + + + + kcfg_rbManual + + + &Manual + + + Alt+M + + + false + + + Encrypt messages if the other side requests an OTR connection + + + + + kcfg_rbAlways + + + false + + + Al&ways + + + Alt+W + + + false + + + Always encrypt messages + + + + + + + spacer2 + + + Vertical + + + Expanding + + + + 20 + 161 + + + + + + + + fingerprints + + + K&nown Fingerprints + + + + unnamed + + + + + User + + + + + Status + + + + + Verified + + + + + Fingerprint + + + + + Protocol + + + + tbFingerprints + + + 1 + + + 5 + + + true + + + true + + + false + + + SingleRow + + + FollowStyle + + + + + btVerify + + + true + + + &Verify Fingerprint + + + Alt+V + + + + + btForget + + + false + + + F&orget Fingerprint + + + Alt+O + + + + + + + + + generateFingerprint() + + + + kactivelabel.h + + 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 @@ + + + + + &Edit + + + + + + + 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 0000000000000000000000000000000000000000..138bf9b64c8d9bfa564d6b52e657de6764080c11 GIT binary patch literal 815 zcmV+~1JL}5P)gE<@iht2oUH9MY%mBz+1bUJYu9d{>~y+c=6OC<6on*796kDh3?NAeA*>x7T=n(7eS7wdkFOU( zUyMPTrlXfGO}&5W)DO>fyWQ7u6CeYKku*&{J#gUVJ?qvz?CjZJ;^gF&fAYK+#>Yp; z_wL=%+`s>&XOA2?`9;6)l_UXD$n#vQ)!x2y=jP`(YfwE0KP2%#V7biZy@B(TXOt<=J zZD5ktU5OL`0Du(TD7my?`ffdi4DQ_TGt*|FL;?UvfD}dG>JoEZcV>q`2J`L6e8F6g zBn2QvK!_}rOy?|D)Png=02#zGGTWnFkkkl~GEkwcC?ZQ0Wuzad1u*~_h=G_8(61;W zWknGvBmGDjC?aJft%wn15R!~q6AQ!y6)_ScRiFx#kt$LJazd4W3})ubpFjRA?#e>5 tA45WnL`1|$M2N&FiIkQ4%u4My_#aJkZm1D1;I9Ax002ovPDHLkV1kgGd~5&! literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..45cdc9171602cac7ecf850665012eff50751ac71 GIT binary patch literal 956 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..18c1481b0eb34023b9da1a04d0925c5c7536c607 GIT binary patch literal 853 zcmV-b1FHOqP)zt=T4oy2r86?#aPr3NyX*i#VFOHbO94-wj9MMjbc5~weNC?;V& zC6ql_(1Y|AK9ngDIcOUG$sD9knX~<|dv|yL?B3h&-qo1f?%e3W;hx{`ob&me-}(K1 z8-*M)Huk!TqHxhr}mz1i1y<9W7xL$=BO{%20Ry}Y%f<0|ZSD_E8#RWhnx=6N2K zm8a0ycov(RJ8dr4m94qCx1M7w?(KbIE-f|R>*={}HW(-bgJI0iFC!3$XsxhVOlWFy zkX<++2yxP`R}r2UYlesKL{d3L>0nV5oz2blW|PT?gM%QZrru$3aeZ!kdw;mAtDRa~ z+rB?N{V}q%^bHnE30$soR+7`1&dC6i)z3FH)PSaGxZP{m*$I3e9qsxsGIEzw{lp$; z7MiUp_# z6pcp7sWX_IeE2il0jqJ6B&n^_?7YBgwSpjMswbit*T5XdWd)x|9eAH!u)bLKo7vqj zkV%iLig(qyGbtfS`^}agMtU8BKY)6h-%8?~j@v7qjO*qZZD==@n(IpJ_FRu~K+h2i z1i-W0jPt?jwIdaWY1Cc1)d_>qOGY800tyi+>cIT?`?ic${5n)%klcj#0|iT5hT-cc z!YIq^aWJ9)(J)zBEDS2iz{)=GnihD^o?n9mc; zk~lw2S|@3(P{A4_9jqvSgSj-Y>QMd#s25mD6rk-c0Ze?AWJtz6))F|P#-ao)CFv+c z&hFEDAQ0pPR95tX$*+>OKrV0z8M1i-v+Y3dw_-0uUY#f>`k0||PTyYGs9Uk;(c@Jo fV8MS#^8fD-#W>v&<3(`m00000NkvXXu0mjf*8PnD literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..fb0a7e35520fb3c410fde58f03e0d3e1fdf2d124 GIT binary patch literal 1417 zcmV;41$O$0P)w zz2`+l7?@)nJ9g}UV(Zp@PXRH&8SC#w1gB8gaf+|8ZQJMNz-q_g1;>djnmO|pM4-1f zjWN0{2-LTK{&{@I?%mrHfSFK$hK4;aMk3LV=FXi}R#!KV+S)nSvu2Fp%$bXvKHW`6 z$K_Oi|KDpH8eabZP=GB4z-YE$!-ie;Tef^Eot-^0Fs!wrloH?fuRk-!NPBySY~H+A z)~wn21#l}69ajd{t$V+I%9PSwD_1_t?Af=WwZ?T_eBVcFjWGse45g)|OrJiTcsx#5 zR}Xvl{zz9>$C?j6+_)3S43~+U0=)IsyXBDxUG??Pm(|u*p_C$>PSe+yrm5)`KP9f7duzAwRMxpWJn|uR99DFEq7E_R?h||4W|<+lK#4? zs@t*F;&~ogYdSi5Xl*_G9ncFT!s1flbiexQy>I&ZGO7Ol49R2?fU>g5R97#$KLm)3 z8o={%kst^##^8A#K@gBmyL5D%=mt`NKcuJx@IBA_J(+ZIT^DODT5EzpMS=Kmda)t^ z$@Ay0uxZmCwANT_Q7RyGI5mRPNe~zjv1GGZlu~G|(b_nnxHD>i0|&PMwtV@^Pqw!= z*9L(q1#x`eO^0a@hPKqdg{u*f5LjW1#h4MzuxJ<9#>UT@fHt5cq?fRtb2sz(0f3v0 zVgM5Eb1-D@Y%zZyE5Hp-czo-E^|6SvDiWcL2^`u;I_aACmaRSYb{Lqw!HOH#FQ_Yt zJI5*?TFRWq9wk~52|I3l!}u|J4xixCuSfZ|CHefu13iZTS43pc79_JWeR3QgUj7J} zpTWB_A<;*Hxpzf4c}U3Q>|9`4SW9LQKyO+iQ%fB1PeO2E;_`nj3$0g3W@nPlNvyyV z1_Pusf(``y9Qb--#9ak#e}T3nGeXW2r_c`u0i;|(1p>-|7mQy#>A|_){CY-6W&}^k z$ZeQ*!H)sHf!sJVa4iE@GGHuN$pd7;Q$>8h^#l_WQ2M`TKpD82fm{Gaz}o!P2suws z!Dx&~8SwO28yzw#KMSJ14q#;rPB^FroP50sAmKuVGq8EV;Y0@k*f9Y3I$r~mV-R&h zv4Tjhixr5D6m{XdW6D5jJnYnh1x8$anCIgHD2e7zZ+ZfvE_^m>fJsvzWhW-;fp=vT zMQBC(0Y2V$m1Pgy3E2yI5gQG!0ydJrmw|h^`4r)o3+16Pnsnh|X6WZQ`r7iEO{MYZ z8~hLBQqtSEuetjj;2dyGM9feC2bcm>JhPx;g*Gzjzx?eUZv1@e>ap+~a1Hot;B)*B XtSi;9B1&Wq00000NkvXXu0mjfjN6u_ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d6dec0ce9ed28218fe1d82e4f591c139a6e0c952 GIT binary patch literal 1889 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 Djq#4I literal 0 HcmV?d00001 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 + +#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 @@ + +PrivKeyPopupUI + + + PrivKeyPopupUI + + + + 0 + 0 + 507 + 111 + + + + Generating private key + + + + unnamed + + + + tlWait + + + + 1 + 1 + + + + Please wait while generating the private key + + + + + animFrame + + + + 0 + 0 + 0 + 0 + + + + + 72 + 72 + + + + StyledPanel + + + Raised + + + + + + 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 + +#include +#include +#include +#include +#include + +#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 @@ + +SMPPopupUI + + + SMPPopupUI + + + + 0 + 0 + 536 + 158 + + + + Enter authentication secret + + + + pbOK + + + + 430 + 110 + 90 + 30 + + + + &OK + + + Alt+O + + + + + pbCancel + + + + 330 + 110 + 91 + 31 + + + + &Cancel + + + Alt+C + + + + + leSecret + + + + 120 + 70 + 400 + 23 + + + + + + tlText + + + + 124 + 10 + 390 + 50 + + + + Please enter the secret passphrase to authenticate this contact. + + + WordBreak|AlignVCenter + + + + + pLIcon + + + + 30 + 30 + 50 + 50 + + + + image0 + + + true + + + + + pbManual + + + + 110 + 110 + 160 + 30 + + + + &Manual Authentication + + + Alt+M + + + + + pbHelp + + + + 10 + 110 + 90 + 30 + + + + &Help + + + Alt+H + + + + + + 89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000517494441545885c5975d68544714c77f7b5db39b98adf95851a34913158dd1b452db2a488badb5155bfba22f3e54a4da421ffa609fa42fea83a0f8509fc5071529a894422988156cc552d4b40113129ae826249b8fc664f3b17befeede3b7766fa70633edc9bcdfa517ae0b2c3ec9df9ffce393367e6c2ff6c81671d70f6ecb5b052aa1ea80b0428d39acf95523d528a96870fdb2e9e3f7f7a0490ff09c09933df6f0f04025b57adaa0aad5cb98468743152cae3c9a4c5a347fdf4f58d904e9be75a5bef9fb87af5dc502120c142844f9ebc180e040207972faf5cba7bf756caca220402b3d9376d5acbe0e030376ffef9a5d65bde1d1a1af8f8f6ed9fe380c837f782f9c48f1d3b1f564a1f6c6c5cbd74dfbef7282e0e23a5249d4e639a2696656dcf64321886414545191b36d4313c3c1e0d85a2bb1c277bbdbfbf3b05a8e706d8b66df70735354bd7eddfbf13e089287d7d8f696fefa1ab6b60bb942eb69dc6b66d2291080d0d75c462f16830f84a4553d3ad5f0107d0cf0c70e4c877658661ec3d74e8138a8bc32493499249936bd76e73e7ce03f1e0415b4f2cd65bdad939581a8f274a4b4a0c5cd7211a8d5255554e6b6bfc3521c42f7d7db17f00d74f23ef1a504a6fddb8b18ecaca322ccbc2b66d2e5fbe4947c7c3aeebd72f350d0dc54da005d0070e1cfd7a74347978cf9e370887c3545757b3624505f5f56f7e71f7ee8d76c0f68330f2010821963534d4a1b5c6344d9a9b3be9ea8a8f5db870f2f7a1a1f828300e7403dd972e9dfa369148fc78efde437a7b7b0158bffe550c63613d100116fa69e405705df9eaaa55556432198410343777d2d3d3f13790054cc00292400a48f4f5751defee7e4c369b656c6c8cdada65048345af038b9e0bc0715c8a8b4308211042e03882f1f144122f9c4f2f2c75e3c6a576cbca2284606464844864118ee302143147bae74b018ee3e0380eaeeb22844029adf10a8cdfd6924208b4d64829a7c0f116bb6fd19b270202dbb6b16d7b7232172925ccb1a500ed385edd715d77123e6f1dca0fa0b5c6b66d1cc799f45ea1e7929e316626809e67806f5edace36d41b06cb7febed24db761129250b1c87cd65dd6cfe30b1a66aefdaf2c5c50b8461a0811d33c7fe31d049c59843d029412e2c62476d279f1d5d7d3800773e3d15bbcc53e9cbc94bd3e9865d0b17b025525343a4ba26bfbb9e1d9fef8554bc97546f2f89943cbfe344c73778bb47f946209d61cb9a8fdea7eaed46d08ff016fb8bd992b7d631d0b48c891bf70f03a7810120ed0b30616942e551b0aebc1471004c9b506c88096b11403990981320696adc4c3f64ad9723ee2a6819c44d2b92a606af204d2d7e9f0880b415647dcf8e6733a9a0fd31a46ca41364c2c7a7dc08581ad75690cdbf7fe7354742f728980e488deb289256ee96cc8d80a9716d099917888069c3401284f2a2a03c8009b300005782769f330552c1681a5236280d524f0168a9717d6e88fef7019127056ad20bada70bb2ab4048b09c59a2d3bf936d1ff30770d5740a828657aeb49e9e4ca9c94967b4fdfa6601f897e4390024d8024a439eb8d4d31ecd122db0efb922505234dd7e2a9fd30279fa72009e2502a1a0e7b9abc8c9a35f6e0b85f231dfe37860d800a3d203987aa43749bebe9cffa79f8154a8b00848a5e33ffdf05775ac71392b226970b39e074f56fdccf6938539ab9dfb5e7faa88b69152d28e6cc53b8ea7f291731cefac5f1aa9ad2c79a72868546b5dd0b7e35705bcc34446b4dcea787c6530998d0171bc4badaf8001848030de65723e88658500e09dff16308677937601fe058d04715d6cb9690e0000000049454e44ae426082 + + + + + pbCancel + clicked() + SMPPopupUI + cancelSMP() + + + pbOK + clicked() + SMPPopupUI + respondSMP() + + + pbHelp + clicked() + SMPPopupUI + openHelp() + + + pbManual + clicked() + SMPPopupUI + manualAuth() + + + + manualAuth() + respondSMP() + openHelp() + cancelSMP() + + + + kpushbutton.h + kpushbutton.h + klineedit.h + kpushbutton.h + kpushbutton.h + + 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 @@ + +VerifyPopupUI + + + VerifyPopupUI + + + + 0 + 0 + 605 + 250 + + + + Verify Fingerprint + + + + unnamed + + + + pbOK + + + &OK + + + Alt+O + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 461 + 20 + + + + + + alVerified + + + + + cbVerify + + + + 130 + 32767 + + + + + + alContact + + + + 12 + + + + + + alFingerprint + + + + + + WordBreak|AlignVCenter + + + + + + + cbVerify + activated(int) + VerifyPopupUI + cbChanged() + + + pbOK + clicked() + VerifyPopupUI + close() + + + + cbChanged() + + + + kpushbutton.h + kactivelabel.h + kcombobox.h + kactivelabel.h + +