From bcb704366cb5e333a626c18c308c7e0448a8e69f Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kopete/plugins/cryptography/cryptographyplugin.cpp | 326 +++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 kopete/plugins/cryptography/cryptographyplugin.cpp (limited to 'kopete/plugins/cryptography/cryptographyplugin.cpp') diff --git a/kopete/plugins/cryptography/cryptographyplugin.cpp b/kopete/plugins/cryptography/cryptographyplugin.cpp new file mode 100644 index 00000000..701ad8bd --- /dev/null +++ b/kopete/plugins/cryptography/cryptographyplugin.cpp @@ -0,0 +1,326 @@ +/*************************************************************************** + cryptographyplugin.cpp - description + ------------------- + begin : jeu nov 14 2002 + copyright : (C) 2002-2004 by Olivier Goffart + email : ogoffart @ kde.org + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "kopetemetacontact.h" +#include "kopetecontactlist.h" +#include "kopetechatsessionmanager.h" +#include "kopetesimplemessagehandler.h" +#include "kopeteuiglobal.h" +#include "kopetecontact.h" + +#include "cryptographyplugin.h" +#include "cryptographyselectuserkey.h" +#include "cryptographyguiclient.h" + +#include "kgpginterface.h" + +//This regexp try to match an HTML text, but only some authorized tags. +// used in slotIncomingMessage +//There are not rules to know if the test should be sent in html or not. +//In Jabber, the JEP says it's not. so we don't use richtext in our message, but some client did. +//We limit the html to some basis tag to limit security problem (bad links) +// - Olivier +const QRegExp CryptographyPlugin::isHTML( QString::fromLatin1( "^[^<>]*(|[\\s/][^><]*>)[^><]*)+$" ) , false ); + +typedef KGenericFactory CryptographyPluginFactory; +static const KAboutData aboutdata("kopete_cryptography", I18N_NOOP("Cryptography") , "1.0" ); +K_EXPORT_COMPONENT_FACTORY( kopete_cryptography, CryptographyPluginFactory( &aboutdata ) ) + +CryptographyPlugin::CryptographyPlugin( QObject *parent, const char *name, const QStringList & /* args */ ) +: Kopete::Plugin( CryptographyPluginFactory::instance(), parent, name ), + m_cachedPass() +{ + if( !pluginStatic_ ) + pluginStatic_=this; + + m_inboundHandler = new Kopete::SimpleMessageHandlerFactory( Kopete::Message::Inbound, + Kopete::MessageHandlerFactory::InStageToSent, this, SLOT( slotIncomingMessage( Kopete::Message& ) ) ); + connect( Kopete::ChatSessionManager::self(), + SIGNAL( aboutToSend( Kopete::Message & ) ), + SLOT( slotOutgoingMessage( Kopete::Message & ) ) ); + + m_cachedPass_timer = new QTimer(this, "m_cachedPass_timer" ); + QObject::connect(m_cachedPass_timer, SIGNAL(timeout()), this, SLOT(slotForgetCachedPass() )); + + + KAction *action=new KAction( i18n("&Select Cryptography Public Key..."), "encrypted", 0, this, SLOT (slotSelectContactKey()), actionCollection() , "contactSelectKey"); + connect ( Kopete::ContactList::self() , SIGNAL( metaContactSelected(bool)) , action , SLOT(setEnabled(bool))); + action->setEnabled(Kopete::ContactList::self()->selectedMetaContacts().count()==1 ); + + setXMLFile("cryptographyui.rc"); + loadSettings(); + connect(this, SIGNAL(settingsChanged()), this, SLOT( loadSettings() ) ); + + connect( Kopete::ChatSessionManager::self(), SIGNAL( chatSessionCreated( Kopete::ChatSession * )) , SLOT( slotNewKMM( Kopete::ChatSession * ) ) ); + //Add GUI action to all already existing kmm (if the plugin is launched when kopete already rining) + QValueList sessions = Kopete::ChatSessionManager::self()->sessions(); + for (QValueListIterator it= sessions.begin(); it!=sessions.end() ; ++it) + { + slotNewKMM(*it); + } + +} + +CryptographyPlugin::~CryptographyPlugin() +{ + delete m_inboundHandler; + pluginStatic_ = 0L; +} + +void CryptographyPlugin::loadSettings() +{ + KConfig *config = KGlobal::config(); + config->setGroup("Cryptography Plugin"); + + mPrivateKeyID = config->readEntry("PGP_private_key"); + mAlsoMyKey = config->readBoolEntry("Also_my_key", false); + + if(config->readBoolEntry("Cache_Till_App_Close", false)) + mCachePassPhrase = Keep; + if(config->readBoolEntry("Cache_Till_Time", false)) + mCachePassPhrase = Time; + if(config->readBoolEntry("Cache_Never", false)) + mCachePassPhrase = Never; + mCacheTime = config->readNumEntry("Cache_Time", 15); + mAskPassPhrase = config->readBoolEntry("No_Passphrase_Handling", false); +} + +CryptographyPlugin* CryptographyPlugin::plugin() +{ + return pluginStatic_ ; +} + +CryptographyPlugin* CryptographyPlugin::pluginStatic_ = 0L; + +QCString CryptographyPlugin::cachedPass() +{ + return pluginStatic_->m_cachedPass; +} + +void CryptographyPlugin::setCachedPass(const QCString& p) +{ + if(pluginStatic_->mCacheMode==Never) + return; + if(pluginStatic_->mCacheMode==Time) + pluginStatic_->m_cachedPass_timer->start(pluginStatic_->mCacheTime * 60000, false); + + pluginStatic_->m_cachedPass=p; +} + +bool CryptographyPlugin::passphraseHandling() +{ + return !pluginStatic_->mAskPassPhrase; +} + + +/*KActionCollection *CryptographyPlugin::customChatActions(Kopete::ChatSession *KMM) +{ + delete m_actionCollection; + + m_actionCollection = new KActionCollection(this); + KAction *actionTranslate = new KAction( i18n ("Translate"), 0, + this, SLOT( slotTranslateChat() ), m_actionCollection, "actionTranslate" ); + m_actionCollection->insert( actionTranslate ); + + m_currentChatSession=KMM; + return m_actionCollection; +}*/ + +void CryptographyPlugin::slotIncomingMessage( Kopete::Message& msg ) +{ + QString body = msg.plainBody(); + if( !body.startsWith( QString::fromLatin1("-----BEGIN PGP MESSAGE----") ) + || !body.contains( QString::fromLatin1("-----END PGP MESSAGE----") ) ) + return; + + if( msg.direction() != Kopete::Message::Inbound ) + { + QString plainBody; + if ( m_cachedMessages.contains( body ) ) + { + plainBody = m_cachedMessages[ body ]; + m_cachedMessages.remove( body ); + } + else + { + plainBody = KgpgInterface::KgpgDecryptText( body, mPrivateKeyID ); + } + + if( !plainBody.isEmpty() ) + { + //Check if this is a RTF message before escaping it + if( !isHTML.exactMatch( plainBody ) ) + { + plainBody = QStyleSheet::escape( plainBody ); + + //this is the same algoritm as in Kopete::Message::escapedBody(); + plainBody.replace( QString::fromLatin1( "\n" ), QString::fromLatin1( "
" ) ) + .replace( QString::fromLatin1( "\t" ), QString::fromLatin1( "    " ) ) + .replace( QRegExp( QString::fromLatin1( "\\s\\s" ) ), QString::fromLatin1( "  " ) ); + } + + msg.setBody( QString::fromLatin1("
") + + i18n("Outgoing Encrypted Message: ") + + QString::fromLatin1("
") + + plainBody + + QString::fromLatin1("
") + , Kopete::Message::RichText ); + } + + //if there are too messages in cache, clear the cache + if(m_cachedMessages.count() > 5) + m_cachedMessages.clear(); + + return; + } + + + //the Message::unescape is there because client like fire replace linebreak by
to work even if the protocol doesn't allow newlines (IRC) + // cf http://fire.sourceforge.net/forums/viewtopic.php?t=174 and Bug #96052 + if(body.contains("<")) + body= Kopete::Message::unescape(body); + + body = KgpgInterface::KgpgDecryptText( body, mPrivateKeyID ); + + if( !body.isEmpty() ) + { + //Check if this is a RTF message before escaping it + if( !isHTML.exactMatch( body ) ) + { + body = Kopete::Message::escape( body ); + } + + msg.setBody( QString::fromLatin1("
") + + i18n("Incoming Encrypted Message: ") + + QString::fromLatin1("
") + + body + + QString::fromLatin1("
") + , Kopete::Message::RichText ); + } + +} + +void CryptographyPlugin::slotOutgoingMessage( Kopete::Message& msg ) +{ + if(msg.direction() != Kopete::Message::Outbound) + return; + + QStringList keys; + QPtrList contactlist = msg.to(); + for( Kopete::Contact *c = contactlist.first(); c; c = contactlist.next() ) + { + QString tmpKey; + if( c->metaContact() ) + { + if(c->metaContact()->pluginData( this, "encrypt_messages" ) == "off" ) + return; + tmpKey = c->metaContact()->pluginData( this, "gpgKey" ); + } + if( tmpKey.isEmpty() ) + { + // kdDebug( 14303 ) << "CryptographyPlugin::slotOutgoingMessage: no key selected for one contact" <selectedMetaContacts().first(); + if(!m) + return; + QString key = m->pluginData( this, "gpgKey" ); + CryptographySelectUserKey *opts = new CryptographySelectUserKey( key, m ); + opts->exec(); + if( opts->result() ) + { + key = opts->publicKey(); + m->setPluginData( this, "gpgKey", key ); + } + delete opts; +} + +void CryptographyPlugin::slotForgetCachedPass() +{ + m_cachedPass=QCString(); + m_cachedPass_timer->stop(); +} + +void CryptographyPlugin::slotNewKMM(Kopete::ChatSession *KMM) +{ + connect(this , SIGNAL( destroyed(QObject*)) , + new CryptographyGUIClient(KMM) , SLOT(deleteLater())); +} + + + +#include "cryptographyplugin.moc" + +// vim: set noet ts=4 sts=4 sw=4: + -- cgit v1.2.3