Bug 132637

Summary: Kopete asks for gnupg passwords many times
Product: [Applications] kopete Reporter: Pupeno <pupeno>
Component: Cryptography PluginAssignee: Kopete Developers <kopete-bugs-null>
Status: RESOLVED FIXED    
Severity: normal    
Priority: NOR    
Version: 0.11.1   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In:

Description Pupeno 2006-08-19 14:33:22 UTC
Version:           0.11.1 (using KDE 3.5.2, Kubuntu Package 4:3.5.2-0ubuntu18.1 dapper)
Compiler:          Target: i486-linux-gnu
OS:                Linux (i686) release 2.6.17-5-686

When receiving GnuPG-encrypted messages Kopete asks for the password to decrypt it. If there's more than one incoming encrypted messages (from the same person at least) it ask for the password twice (when asking for it once would have been enough). It ends up asking for the password as many time as an encrypted message arrives until you write the password (very bad if you receive lots of messages while being away).
The problem gets even worse when you consider that the password-asking-dialogs is a stack, so you have to reply the last password first and the first password last. As messages are delivered *after* the password has been written, you end up with all the messages upside-down.
Comment 1 Gehold Bertin 2006-11-29 23:52:50 UTC
Same problem...

Here a screenshot: http://img296.imageshack.us/img296/7826/kopetelaufdringlichuv6.png
Comment 2 Frank Niethardt 2007-06-09 19:23:30 UTC
Bug is still present 0.12.3
Comment 3 Charles Connell 2007-07-17 04:55:12 UTC
SVN commit 688860 by cconnell:

If there are more than one password dialogs, have one propagate input to the others.
This doesn't fix the backwards message display order.
BUG:132637


 M  +28 -13    gpginterface.cpp  


--- trunk/KDE/kdenetwork/kopete/plugins/cryptography/gpginterface.cpp #688859:688860
@@ -31,6 +31,8 @@
 #include <ktemporaryfile.h>
 #include "gpginterface.h"
 
+#include "kopeteuiglobal.h"
+
 QString GpgInterface::encryptText ( QString text, QString userIDs, QString options, bool signAlso, QString privateKey )
 {
 	int counter = 0;
@@ -54,7 +56,7 @@
 		while ( ( counter < 3 ) && ( encResult.isEmpty() ) )
 		{
 			counter++;
-			password = getPassword(password, privateKey, counter);
+			password = getPassword ( password, privateKey, counter );
 			gpgcmd = "gpg --no-secmem-warning --no-tty " + options.toLocal8Bit() + " -e " + dests.toLocal8Bit(); gpgcmd += " --passphrase " + password + " -s ";
 
 			QProcess fp;
@@ -87,7 +89,6 @@
 	QString gpgcmd, encResult;
 	int counter = 0;
 	QString password = CryptographyPlugin::cachedPass();
-	bool passphraseHandling = CryptographyPlugin::passphraseHandling();
 	while ( ( counter<3 ) && ( encResult.isEmpty() ) )
 	{
 		counter++;
@@ -113,7 +114,6 @@
 
 	int counter = 0;
 	QString password = CryptographyPlugin::cachedPass();
-	bool passphraseHandling = CryptographyPlugin::passphraseHandling();
 
 	// give them three tries on passphrase
 	while ( ( counter<3 ) && ( encResult.isEmpty() ) )
@@ -135,20 +135,20 @@
 		fp.closeWriteChannel();
 		fp.waitForFinished();
 		encResult = fp.readAll();
-		
+
 		status = tempfile.readAll();
-		if (status.contains ("GOODSIG") )
+		if ( status.contains ( "GOODSIG" ) )
 			opState = GoodSig;
-		else if (status.contains ("BADSIG") )
+		else if ( status.contains ( "BADSIG" ) )
 			opState = BadSig;
-		else if (status.contains ("ERRSIG") )
+		else if ( status.contains ( "ERRSIG" ) )
 			opState = ErrorSig;
 		else
 			opState = NoSig;
-		
-		if (status.contains ("DECRYPTION_OKAY") )
-			opState = (opState | Decrypted);
-		
+
+		if ( status.contains ( "DECRYPTION_OKAY" ) )
+			opState = ( opState | Decrypted );
+
 		status.clear();
 		password.clear();
 		gpgcmd.clear();
@@ -189,20 +189,35 @@
 		return QString::fromUtf8 ( QString::fromUtf8 ( txt.ascii() ).ascii() );  // perform Utf8 twice, or some keys display badly
 }
 
+class CryptographyPasswordDialog : public KPasswordDialog
+{
+		Q_OBJECT
+	public:
+		CryptographyPasswordDialog ( QWidget *parent=0L, const KPasswordDialogFlags &flags=0, const KDialog::ButtonCodes otherButtons=0 ) : KPasswordDialog ( parent, flags, otherButtons ) {}};
+
 QString GpgInterface::getPassword ( QString password, QString userID, int counter )
 {
-	if (!password.isEmpty() && counter <= 1)
+	if ( !password.isEmpty() && counter <= 1 )
 		return password;
 	bool passphraseHandling = CryptographyPlugin::passphraseHandling();
 	QString passdlg=i18n ( "Enter passphrase for secret key %1:", "0x" + userID.right ( 8 ) );
 	if ( counter>1 )
 		passdlg.prepend ( i18n ( "<b>Bad passphrase</b><br> You have %1 tries left.<br>", 4-counter ) );
-	KPasswordDialog dlg ( 0L, KPasswordDialog::NoFlags );
+	CryptographyPasswordDialog dlg ( Kopete::UI::Global::mainWidget(), KPasswordDialog::NoFlags );
 	dlg.setPrompt ( passdlg );
 	if ( !dlg.exec() )
 		return QString(); //the user canceled
 	if ( passphraseHandling )
 		CryptographyPlugin::setCachedPass ( dlg.password().toLocal8Bit() );
+	
+	// if there is already a password dialog open, get password and send it to that
+	QList<CryptographyPasswordDialog*> otherDialogs = Kopete::UI::Global::mainWidget()->findChildren <CryptographyPasswordDialog *> ();
+	if ( otherDialogs.size() > 1){
+		foreach ( CryptographyPasswordDialog *otherDialog, otherDialogs ){
+			otherDialog->setPassword ( dlg.password());
+			otherDialog->accept();
+		}
+	}
 	return dlg.password();
 }