/***************************************************************************
* Copyright ( C ) 2007 by Michael Zanetti
*
* *
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU General Public License for more details . *
* *
* You should have received a copy of the GNU General Public License *
* along with this program ; if not , write to the *
* Free Software Foundation , Inc . , *
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @ author Michael Zanetti
*/
# include <sys/types.h>
# include <sys/stat.h>
# include <kopetechatsession.h>
# include <kopeteaccount.h>
# include <kopeteaccountmanager.h>
# include <kopetemessageevent.h>
# include <kopetecontactlist.h>
# include <kopetemetacontact.h>
# include <kopeteview.h>
# include <kopeteprotocol.h>
# include <kdebug.h>
# include <kmessagebox.h>
# include <kstandarddirs.h>
# include <klocale.h>
# include <kprogress.h>
# include <kpassivepopup.h>
# include <kanimwidget.h>
# include <kpushbutton.h>
# include <tqvbox.h>
# include <tqlabel.h>
# include <tqnamespace.h>
# include <tqeventloop.h>
# include <tqapplication.h>
# include <tqfile.h>
# include <tqfileinfo.h>
# include <tqptrlist.h>
# include "otrlchatinterface.h"
# include "otrguiclient.h"
# include "otrplugin.h"
# include "privkeypopup.h"
# include "smppopup.h"
OtrlChatInterface * OtrlChatInterface : : mSelf = 0 ;
static OtrlUserState userstate ;
static OtrlPolicy confPolicy ;
static void * updateContextList = 0 ;
/***************************** Gui_UI_Ops for libotr **********************************/
static OtrlPolicy policy ( void * opdata , ConnContext * context ) {
Kopete : : ChatSession * session = ( ( Kopete : : ChatSession * ) opdata ) ;
bool noerr ;
// Disable OTR for IRC
if ( session - > protocol ( ) - > pluginId ( ) = = " IRCProtocol " ) {
kdDebug ( ) < < " Disabling OTR for: " < < session - > protocol ( ) - > pluginId ( ) < < endl ;
return OTRL_POLICY_NEVER ;
}
TQString policy = session - > members ( ) . getFirst ( ) - > metaContact ( ) - > pluginData ( OTRPlugin : : plugin ( ) , " otr_policy " ) ;
switch ( policy . toInt ( & noerr , 10 ) ) {
case 1 :
return OTRL_POLICY_ALWAYS ;
case 2 :
return OTRL_POLICY_OPPORTUNISTIC ;
case 3 :
return OTRL_POLICY_MANUAL ;
case 4 :
return OTRL_POLICY_NEVER ;
default :
return confPolicy ;
}
}
static void create_privkey ( void * opdata , const char * accountname , const char * protocol ) {
Kopete : : ChatSession * session = ( ( Kopete : : ChatSession * ) opdata ) ;
PrivKeyPopup * popup = new PrivKeyPopup ( session - > view ( ) - > mainWidget ( ) , i18n ( " Generating private key " ) , TQt : : WStyle_Dialog | TQt : : WStyle_StaysOnTop ) ;
KAnimWidget * anim = new KAnimWidget ( " kde " , 72 , popup - > animFrame , " kopete " ) ;
anim - > start ( ) ;
anim - > show ( ) ;
popup - > setCloseLock ( true ) ;
popup - > show ( ) ;
KeyGenThread * keyGenThread = new KeyGenThread ( accountname , protocol ) ;
keyGenThread - > start ( ) ;
while ( ! keyGenThread - > wait ( 100 ) ) {
tqApp - > eventLoop ( ) - > processEvents ( TQEventLoop : : ExcludeUserInput | TQEventLoop : : ExcludeSocketNotifiers , 100 ) ;
}
popup - > setCloseLock ( false ) ;
popup - > close ( ) ;
}
static int is_logged_in ( void * opdata , const char * accountname , const char * protocol , const char * recipient ) {
Kopete : : ChatSession * session = ( ( Kopete : : ChatSession * ) opdata ) ;
Kopete : : ContactPtrList list = session - > members ( ) ;
for ( TQPtrListIterator < Kopete : : Contact > it ( list ) ; Kopete : : Contact * contact = it . current ( ) ; + + it ) {
if ( contact - > contactId ( ) . compare ( recipient ) = = 0 ) {
Kopete : : OnlineStatus status = session - > contactOnlineStatus ( contact ) ;
if ( status = = Kopete : : OnlineStatus : : Unknown ) {
return - 1 ;
} else if ( status = = Kopete : : OnlineStatus : : Offline ) {
return 0 ;
} else {
return 1 ;
}
}
}
return - 1 ;
}
static void inject_message ( void * opdata , const char * accountname , const char * protocol , const char * recipient , const char * message ) {
//KMessageBox::information( NULL, TQString(accountname) + ":" + TQString(protocol) + ":" + TQString(recipient) + ":" + TQString(message) );
Kopete : : ChatSession * session = ( ( Kopete : : ChatSession * ) opdata ) ;
Kopete : : ContactPtrList list = session - > members ( ) ;
for ( TQPtrListIterator < Kopete : : Contact > it ( list ) ; Kopete : : Contact * contact = it . current ( ) ; + + it ) {
if ( contact - > contactId ( ) . compare ( recipient ) = = 0 ) {
Kopete : : Message msg ( session - > account ( ) - > myself ( ) , contact , TQString ( message ) , Kopete : : Message : : Outbound ) ;
session - > sendMessage ( msg ) ;
return ;
}
}
}
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 ) ) ;
}
static int display_otr_message ( void * opdata , const char * accountname , const char * protocol , const char * username , const char * message ) {
Kopete : : ChatSession * session = ( ( Kopete : : ChatSession * ) opdata ) ;
Kopete : : ContactPtrList list = session - > members ( ) ;
for ( TQPtrListIterator < Kopete : : Contact > it ( list ) ; Kopete : : Contact * contact = it . current ( ) ; + + it ) {
if ( contact - > contactId ( ) . compare ( username ) = = 0 ) {
Kopete : : Message msg ( session - > members ( ) . getFirst ( ) , session - > account ( ) - > myself ( ) , TQString ( message ) , Kopete : : Message : : Internal ) ;
msg . setBody ( TQString ( message ) , Kopete : : Message : : RichText ) ;
session - > appendMessage ( msg ) ;
return 0 ;
}
}
return 1 ;
}
static void update_context_list ( void * opdata ) {
//Not used...
}
static const char * protocol_name ( void * opdata , const char * protocol ) {
//Never seen...
kdDebug ( ) < < " protocol_name called " < < endl ;
}
static void protocol_name_free ( void * opdata , const char * protocol_name ) {
//Never seen...
kdDebug ( ) < < " protocol_name_free called " < < endl ;
}
static void new_fingerprint ( void * opdata , OtrlUserState us , const char * accountname , const char * protocol , const char * username , unsigned char fingerprint [ 20 ] ) {
kdDebug ( ) < < " Received a new Fingerprint " < < endl ;
Kopete : : ChatSession * session = ( ( Kopete : : ChatSession * ) opdata ) ;
Kopete : : Message msg ( session - > members ( ) . getFirst ( ) , session - > account ( ) - > myself ( ) , i18n ( " <b>Received a new fingerprint from <a>%1</a>. You should authenticate this contact.</b> " ) . tqarg ( 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 ( KGlobal : : dirs ( ) - > saveLocation ( " data " , " kopete_otr/ " , true ) ) + " fingerprints " ) ;
}
static void gone_secure ( void * opdata , ConnContext * context ) {
kdDebug ( ) < < " gone secure " < < endl ;
Kopete : : ChatSession * session = ( ( Kopete : : ChatSession * ) opdata ) ;
if ( context - > active_fingerprint - > trust & & context - > active_fingerprint - > trust [ 0 ] ) {
Kopete : : Message msg ( session - > members ( ) . getFirst ( ) , session - > account ( ) - > myself ( ) , i18n ( " <b>Private OTR session started.</b> " ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
session - > appendMessage ( msg ) ;
OTRPlugin : : plugin ( ) - > emitGoneSecure ( ( ( Kopete : : ChatSession * ) opdata ) , 2 ) ;
} else {
Kopete : : Message msg ( session - > members ( ) . getFirst ( ) , session - > account ( ) - > myself ( ) , i18n ( " <b>Unverified OTR session started.</b> " ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
session - > appendMessage ( msg ) ;
OTRPlugin : : plugin ( ) - > emitGoneSecure ( ( ( Kopete : : ChatSession * ) opdata ) , 1 ) ;
}
}
/* Actually I've never seen this event but its implemented in case someone should receive it
kopete , gaim and miranda send a heartbeat message at disconnect . See log_message .
Searching libotr I could not find any call of gone_insecure . */
static void gone_insecure ( void * opdata , ConnContext * context ) {
kdDebug ( ) < < " gone insecure " < < endl ;
OTRPlugin : : plugin ( ) - > emitGoneSecure ( ( ( Kopete : : ChatSession * ) opdata ) , 0 ) ;
Kopete : : ChatSession * session = ( ( Kopete : : ChatSession * ) opdata ) ;
Kopete : : Message msg ( session - > members ( ) . getFirst ( ) , session - > account ( ) - > myself ( ) , i18n ( " <b>OTR Session ended. The conversation is now insecure!</b> " ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
session - > appendMessage ( msg ) ;
}
static void still_secure ( void * opdata , ConnContext * context , int is_reply ) {
kdDebug ( ) < < " still secure " < < endl ;
Kopete : : ChatSession * session = ( ( Kopete : : ChatSession * ) opdata ) ;
Kopete : : Message msg ( session - > members ( ) . getFirst ( ) , session - > account ( ) - > myself ( ) , i18n ( " <b>OTR connection refreshed successfully.</b> " ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
session - > appendMessage ( msg ) ;
if ( context - > active_fingerprint - > trust & & context - > active_fingerprint - > trust [ 0 ] ) {
OTRPlugin : : plugin ( ) - > emitGoneSecure ( session , 2 ) ;
} else {
OTRPlugin : : plugin ( ) - > emitGoneSecure ( session , 1 ) ;
}
}
static void log_message ( void * opdata , const char * message ) {
kdDebug ( ) < < " libotr: " < < message < < endl ;
}
static OtrlMessageAppOps ui_ops = {
policy ,
create_privkey ,
is_logged_in ,
inject_message ,
notify ,
display_otr_message ,
update_context_list ,
protocol_name ,
protocol_name_free ,
new_fingerprint ,
write_fingerprints ,
gone_secure ,
gone_insecure ,
still_secure ,
log_message
} ;
/*********************** Gui_UI_Ops finished *************************/
/*********************** Constructor/Destructor **********************/
OtrlChatInterface : : OtrlChatInterface ( ) {
kdDebug ( ) < < " Creating OtrlChatInterface " < < endl ;
mSelf = this ;
OTRL_INIT ;
userstate = otrl_userstate_create ( ) ;
otrl_privkey_read ( userstate , TQString ( KGlobal : : dirs ( ) - > saveLocation ( " data " , " kopete_otr/ " , true ) ) + " privkeys " ) ;
otrl_privkey_read_fingerprints ( userstate , TQString ( KGlobal : : dirs ( ) - > saveLocation ( " data " , " kopete_otr/ " , true ) ) + " fingerprints " , NULL , NULL ) ;
}
OtrlChatInterface : : ~ OtrlChatInterface ( ) {
otrl_userstate_free ( userstate ) ;
}
OtrlChatInterface * OtrlChatInterface : : self ( ) {
if ( ! mSelf ) {
new OtrlChatInterface ( ) ;
}
return mSelf ;
}
/********************* Chat section ***************************/
OtrlUserState OtrlChatInterface : : getUserstate ( ) {
return userstate ;
}
int OtrlChatInterface : : decryptMessage ( 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 ;
ignoremessage = otrl_message_receiving ( userstate , & ui_ops , chatSession , accountId . latin1 ( ) , protocol . latin1 ( ) , contactId . latin1 ( ) , msg - > latin1 ( ) , & newMessage , & tlvs , NULL , NULL ) ;
tlv = otrl_tlv_find ( tlvs , OTRL_TLV_DISCONNECTED ) ;
if ( tlv ) {
Kopete : : Message msg ( chatSession - > members ( ) . getFirst ( ) , chatSession - > account ( ) - > myself ( ) , i18n ( " <b>%1</b> has ended the OTR session. You should do the same. " ) . tqarg ( chatSession - > members ( ) . getFirst ( ) - > contactId ( ) ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
chatSession - > appendMessage ( msg ) ;
OTRPlugin : : plugin ( ) - > emitGoneSecure ( chatSession , 3 ) ;
}
context = otrl_context_find ( userstate , contactId . latin1 ( ) , accountId . latin1 ( ) , protocol . latin1 ( ) , 0 , NULL , NULL , NULL ) ;
if ( context ) {
nextMsg = context - > smstate - > nextExpected ;
tlv = otrl_tlv_find ( tlvs , OTRL_TLV_SMP1 ) ;
if ( tlv ) {
if ( nextMsg ! = OTRL_SMP_EXPECT1 ) {
abortSMP ( context , chatSession ) ;
} else {
SMPPopup * popup = new SMPPopup ( chatSession - > view ( ) - > mainWidget ( ) , i18n ( " Enter authentication secret " ) , TQt : : WStyle_Dialog | TQt : : WStyle_StaysOnTop , context , chatSession , false ) ;
popup - > show ( ) ;
}
}
tlv = otrl_tlv_find ( tlvs , OTRL_TLV_SMP2 ) ;
if ( tlv ) {
if ( nextMsg ! = OTRL_SMP_EXPECT2 )
abortSMP ( context , chatSession ) ;
else {
kdDebug ( ) < < " Update SMP state: 2 -> 3 " < < endl ;
context - > smstate - > nextExpected = OTRL_SMP_EXPECT4 ;
}
}
tlv = otrl_tlv_find ( tlvs , OTRL_TLV_SMP3 ) ;
if ( tlv ) {
if ( nextMsg ! = OTRL_SMP_EXPECT3 )
abortSMP ( context , chatSession ) ;
else {
if ( context - > active_fingerprint - > trust & & context - > active_fingerprint - > trust [ 0 ] ) {
Kopete : : Message msg ( chatSession - > members ( ) . getFirst ( ) , chatSession - > account ( ) - > myself ( ) , i18n ( " <b>Authentication successful. The conversation is now secure!</b> " ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
chatSession - > appendMessage ( msg ) ;
OTRPlugin : : plugin ( ) - > emitGoneSecure ( chatSession , 2 ) ;
} else {
Kopete : : Message msg ( chatSession - > members ( ) . getFirst ( ) , chatSession - > account ( ) - > myself ( ) , i18n ( " <b>Authentication failed. The conversation is now insecure!</b> " ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
chatSession - > appendMessage ( msg ) ;
OTRPlugin : : plugin ( ) - > emitGoneSecure ( chatSession , 1 ) ;
}
context - > smstate - > nextExpected = OTRL_SMP_EXPECT1 ;
}
}
tlv = otrl_tlv_find ( tlvs , OTRL_TLV_SMP4 ) ;
if ( tlv ) {
if ( nextMsg ! = OTRL_SMP_EXPECT4 )
abortSMP ( context , chatSession ) ;
else {
if ( context - > active_fingerprint - > trust & & context - > active_fingerprint - > trust [ 0 ] ) {
Kopete : : Message msg ( chatSession - > members ( ) . getFirst ( ) , chatSession - > account ( ) - > myself ( ) , i18n ( " <b>Authentication successful. The conversation is now secure!</b> " ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
chatSession - > appendMessage ( msg ) ;
OTRPlugin : : plugin ( ) - > emitGoneSecure ( chatSession , 2 ) ;
} else {
Kopete : : Message msg ( chatSession - > members ( ) . getFirst ( ) , chatSession - > account ( ) - > myself ( ) , i18n ( " <b>Authentication failed. The conversation is now insecure!</b> " ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
chatSession - > appendMessage ( msg ) ;
OTRPlugin : : plugin ( ) - > emitGoneSecure ( chatSession , 1 ) ;
}
context - > smstate - > nextExpected = OTRL_SMP_EXPECT1 ;
}
}
tlv = otrl_tlv_find ( tlvs , OTRL_TLV_SMP_ABORT ) ;
if ( tlv ) {
Kopete : : Message msg ( chatSession - > members ( ) . getFirst ( ) , chatSession - > account ( ) - > myself ( ) , i18n ( " <b>Authentication error!</b> " ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
chatSession - > appendMessage ( msg ) ;
context - > smstate - > nextExpected = OTRL_SMP_EXPECT1 ;
}
otrl_tlv_free ( tlvs ) ;
}
// message is now decrypted or is a Plaintext message and ready to deliver
if ( ! ignoremessage ) {
// message is decrypted
if ( newMessage ! = NULL ) {
* msg = TQString : : fromUtf8 ( newMessage ) ;
otrl_message_free ( newMessage ) ;
msg - > tqreplace ( TQString ( ' \n ' ) , TQString ( " <br> " ) , false ) ;
}
}
return ignoremessage ;
}
TQString OtrlChatInterface : : encryptMessage ( TQString msg , TQString accountId ,
TQString protocol , TQString contactId , Kopete : : ChatSession * chatSession ) {
int err ;
char * newMessage ;
if ( otrl_proto_message_type ( msg ) = = OTRL_MSGTYPE_NOTOTR ) {
msg . tqreplace ( TQString ( ' < ' ) , TQString ( " < " ) , false ) ;
err = otrl_message_sending ( userstate , & ui_ops , chatSession , accountId . latin1 ( ) , protocol . latin1 ( ) , contactId . latin1 ( ) , msg . utf8 ( ) , NULL , & newMessage , NULL , NULL ) ;
if ( err ! = 0 ) {
msg = i18n ( " Encryption error " ) ;
} else {
if ( newMessage ! = NULL ) {
msg = TQString : : fromUtf8 ( newMessage ) ;
otrl_message_free ( newMessage ) ;
}
}
}
OtrlMessageType type = otrl_proto_message_type ( msg ) ;
if ( type = = OTRL_MSGTYPE_NOTOTR | type = = OTRL_MSGTYPE_TAGGEDPLAINTEXT ) {
msg . tqreplace ( " < " , " < " , 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 ) {
otrl_message_disconnect ( userstate , & ui_ops , chatSession , chatSession - > account ( ) - > accountId ( ) . latin1 ( ) , chatSession - > account ( ) - > protocol ( ) - > displayName ( ) . latin1 ( ) , chatSession - > members ( ) . getFirst ( ) - > contactId ( ) ) ;
OTRPlugin : : plugin ( ) - > emitGoneSecure ( chatSession , false ) ;
Kopete : : Message msg ( chatSession - > account ( ) - > myself ( ) , chatSession - > members ( ) . getFirst ( ) , i18n ( " Terminating OTR session. " ) , Kopete : : Message : : Internal ) ;
// msg.setBody( 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 ;
context = otrl_context_find ( userstate , session - > members ( ) . getFirst ( ) - > contactId ( ) , session - > account ( ) - > accountId ( ) , session - > account ( ) - > protocol ( ) - > displayName ( ) , 0 , NULL , NULL , NULL ) ;
if ( context ) {
switch ( context - > msgstate ) {
case OTRL_MSGSTATE_PLAINTEXT :
return 0 ;
case OTRL_MSGSTATE_ENCRYPTED :
if ( context - > active_fingerprint - > trust & & context - > active_fingerprint - > trust [ 0 ] ! = ' \0 ' )
return 2 ;
else
return 1 ;
case OTRL_MSGSTATE_FINISHED :
return 3 ;
}
}
return 0 ;
}
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 ;
context = otrl_context_find ( userstate , session - > members ( ) . getFirst ( ) - > contactId ( ) . latin1 ( ) , session - > account ( ) - > accountId ( ) . latin1 ( ) , session - > protocol ( ) - > displayName ( ) . latin1 ( ) , 0 , NULL , NULL , NULL ) ;
SMPPopup * popup = new SMPPopup ( session - > view ( ) - > mainWidget ( ) , i18n ( " Enter authentication secret " ) , TQt : : WStyle_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 ( KGlobal : : dirs ( ) - > saveLocation ( " data " , " kopete_otr/ " , true ) ) + " fingerprints " ) ;
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 ( strcmp ( context - > username , account ) = = 0 ) {
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 ( strcmp ( context - > username , session - > members ( ) . getFirst ( ) - > contactId ( ) ) = = 0 ) {
// otrl_privkey_hash_to_human( hash, context->fingerprint_root.next->fingerprint );
otrl_privkey_hash_to_human ( hash , context - > active_fingerprint - > fingerprint ) ;
return hash ;
}
}
return NULL ;
}
bool OtrlChatInterface : : isVerified ( Kopete : : ChatSession * session ) {
kdDebug ( ) < < " checking for trust " < < endl ;
Fingerprint * fingerprint = findFingerprint ( session - > members ( ) . getFirst ( ) - > contactId ( ) ) ;
if ( fingerprint - > trust & & fingerprint - > trust [ 0 ] ! = ' \0 ' ) {
kdDebug ( ) < < " verified " < < endl ;
return true ;
} else {
kdDebug ( ) < < " not verified " < < endl ;
return false ;
}
}
void OtrlChatInterface : : updateKeyfile ( Kopete : : Account * account ) {
// Updating private keys from <=0.3
kdDebug ( ) < < " updating keys " < < endl ;
TQFile keyfile ( TQString ( KGlobal : : 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 . tqfind ( " protocol " ) ! = - 1 ) {
if ( line . tqfind ( account - > accountLabel ( ) ) ! = - 1 ) {
line . tqreplace ( 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 ( KGlobal : : dirs ( ) - > saveLocation ( " data " , " kopete_otr/ " , true ) ) + " privkeys " ) ;
file = " " ;
line = " " ;
// Updating fingerprints from <=0.3
kdDebug ( ) < < " updating fingerprints " < < endl ;
TQFile fingerprintfile ( TQString ( KGlobal : : dirs ( ) - > saveLocation ( " data " , " kopete_otr/ " , true ) ) + " fingerprints " ) ;
if ( fingerprintfile . open ( IO_ReadWrite ) ) {
kdDebug ( ) < < " file open " < < endl ;
while ( fingerprintfile . readLine ( line , 200 ) ! = - 1 ) {
int pos = line . tqfindRev ( account - > accountLabel ( ) ) ;
if ( pos ! = - 1 ) {
line . tqreplace ( 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 ( KGlobal : : dirs ( ) - > saveLocation ( " data " , " kopete_otr/ " , true ) ) + " fingerprints " , 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 , 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: " ) . tqarg ( formatContact ( session - > members ( ) . getFirst ( ) - > contactId ( ) ) ) + " \n \n " + fingerprint + " \n \n " + i18n ( " Are you sure you want to trust this fingerprint? " ) ,
i18n ( " Verify fingerprint " ) ) ;
if ( doVerify = = KMessageBox : : Yes ) {
return true ;
} else {
return false ;
verifyFingerprint ( session , false ) ;
}
} else {
KMessageBox : : error ( NULL , i18n ( " No fingerprint yet received from this contact. " ) , i18n ( " No fingerprint found " ) ) ;
}
return false ;
}
*/
/****************** SMP implementations ****************/
void OtrlChatInterface : : abortSMP ( ConnContext * context , Kopete : : ChatSession * session ) {
otrl_message_abort_smp ( userstate , & ui_ops , session , context ) ;
if ( context - > active_fingerprint - > trust & & ! context - > active_fingerprint - > trust [ 0 ] ) {
OTRPlugin : : plugin ( ) - > emitGoneSecure ( session , 1 ) ;
Kopete : : Message msg ( session - > members ( ) . getFirst ( ) , session - > account ( ) - > myself ( ) , i18n ( " <b>Authentication aborded. The conversation is now insecure!</b> " ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
session - > appendMessage ( msg ) ;
}
}
void OtrlChatInterface : : respondSMP ( ConnContext * context , Kopete : : ChatSession * session , TQString secret , bool initiate ) {
if ( initiate ) {
context = otrl_context_find ( userstate , session - > members ( ) . getFirst ( ) - > contactId ( ) . latin1 ( ) , session - > account ( ) - > accountId ( ) . latin1 ( ) , session - > protocol ( ) - > displayName ( ) . latin1 ( ) , 0 , NULL , NULL , NULL ) ;
otrl_message_initiate_smp ( userstate , & ui_ops , session , context , ( unsigned char * ) secret . latin1 ( ) , secret . length ( ) ) ;
} else {
otrl_message_respond_smp ( userstate , & ui_ops , session , context , ( unsigned char * ) secret . latin1 ( ) , secret . length ( ) ) ;
}
Kopete : : Message msg ( session - > members ( ) . getFirst ( ) , session - > account ( ) - > myself ( ) , i18n ( " <b>Authenticating contact...</b> " ) , Kopete : : Message : : Internal , Kopete : : Message : : RichText ) ;
session - > appendMessage ( msg ) ;
}
/****************** KeyGenThread *******************/
KeyGenThread : : KeyGenThread ( TQString accountname , TQString protocol ) {
this - > accountname = accountname ;
this - > protocol = protocol ;
}
void KeyGenThread : : run ( )
{
kdDebug ( ) < < " Creating private key... Storing to: " + TQString ( KGlobal : : dirs ( ) - > saveLocation ( " data " , " kopete_otr/ " , true ) ) + " privkeys " < < endl ;
otrl_privkey_generate ( OtrlChatInterface : : self ( ) - > getUserstate ( ) , TQString ( KGlobal : : dirs ( ) - > saveLocation ( " data " , " kopete_otr/ " , true ) ) + " privkeys " , accountname , protocol ) ;
OtrlChatInterface : : self ( ) - > checkFilePermissions ( TQString ( KGlobal : : dirs ( ) - > saveLocation ( " data " , " kopete_otr/ " , true ) ) + " privkeys " ) ;
}