summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRolf Eike Beer <kde@opensource.sf-tec.de>2011-10-27 16:37:20 (GMT)
committerRolf Eike Beer <eike-kernel@sf-tec.de>2011-10-27 20:31:45 (GMT)
commit98d7865250cc8ce3016101d54facdbe01c12983d (patch)
treee779451bdc885c95addfb3e139915a6861eceba5
parentb416fabb00fb53e5f4c0774247b640dd3f6a014d (diff)
fix crash when generating a key fails before user entered password
If the GnuPG process started to generate a new key failed before the user entered the password (e.g. because of a broken configuration file) we will use an already deleted object. The reason for this was opening a dialog and waiting for its result in a slot, so the underlying object could have been deleted by the return to the event loop. Now this is completely handled by signals and slots. BUG:283357 FIXED-IN:4.7.3
-rw-r--r--transactions/kgpggeneratekey.cpp15
-rw-r--r--transactions/kgpggeneratekey.h1
-rw-r--r--transactions/kgpgtransaction.cpp48
-rw-r--r--transactions/kgpgtransaction.h30
4 files changed, 86 insertions, 8 deletions
diff --git a/transactions/kgpggeneratekey.cpp b/transactions/kgpggeneratekey.cpp
index 1738077..0b3a299 100644
--- a/transactions/kgpggeneratekey.cpp
+++ b/transactions/kgpggeneratekey.cpp
@@ -100,7 +100,6 @@ KGpgGenerateKey::postStart()
keymessage.append("\nPassphrase: ");
write(keymessage, false);
- QApplication::restoreOverrideCursor();
QString passdlgmessage;
if (!m_email.isEmpty()) {
passdlgmessage = i18n("<p><b>Enter passphrase for %1 &lt;%2&gt;</b>:<br />Passphrase should include non alphanumeric characters and random sequences.</p>", m_name, m_email);
@@ -108,11 +107,8 @@ KGpgGenerateKey::postStart()
passdlgmessage = i18n("<p><b>Enter passphrase for %1</b>:<br />Passphrase should include non alphanumeric characters and random sequences.</p>", m_name);
}
- if (sendPassphrase(passdlgmessage, true)) {
- setSuccess(TS_USER_ABORTED);
- }
- QApplication::setOverrideCursor(Qt::BusyCursor);
- write("%commit");
+ QApplication::restoreOverrideCursor();
+ askNewPassphrase(passdlgmessage);
}
bool
@@ -191,6 +187,13 @@ KGpgGenerateKey::finish()
}
void
+KGpgGenerateKey::newPasswordEntered()
+{
+ QApplication::setOverrideCursor(Qt::BusyCursor);
+ write("%commit");
+}
+
+void
KGpgGenerateKey::setName(const QString &name)
{
m_name = name;
diff --git a/transactions/kgpggeneratekey.h b/transactions/kgpggeneratekey.h
index 95ec880..8cb7e1a 100644
--- a/transactions/kgpggeneratekey.h
+++ b/transactions/kgpggeneratekey.h
@@ -72,6 +72,7 @@ protected:
virtual void postStart();
virtual bool nextLine(const QString &line);
virtual void finish();
+ virtual void newPasswordEntered();
private:
QString m_name;
diff --git a/transactions/kgpgtransaction.cpp b/transactions/kgpgtransaction.cpp
index ebe23b9..0ce9add 100644
--- a/transactions/kgpgtransaction.cpp
+++ b/transactions/kgpgtransaction.cpp
@@ -18,6 +18,7 @@
#include <QWidget>
#include <KDebug>
+#include <knewpassworddialog.h>
#include <KLocale>
#include "gpgproc.h"
@@ -34,6 +35,7 @@ public:
KGpgTransaction *m_parent;
GPGProc *m_process;
KGpgTransaction *m_inputTransaction;
+ KNewPasswordDialog *m_passwordDialog;
int m_success;
int m_tries;
QString m_description;
@@ -45,6 +47,8 @@ public:
void slotProcessExited();
void slotProcessStarted();
void slotInputTransactionDone(int result);
+ void slotPasswordEntered(const QString &password);
+ void slotPasswordAborted();
QList<int *> m_argRefs;
bool m_inputProcessDone;
@@ -70,6 +74,7 @@ KGpgTransactionPrivate::KGpgTransactionPrivate(KGpgTransaction *parent, bool all
m_parent(parent),
m_process(new GPGProc()),
m_inputTransaction(NULL),
+ m_passwordDialog(NULL),
m_success(KGpgTransaction::TS_OK),
m_tries(3),
m_chainingAllowed(allowChaining),
@@ -82,6 +87,10 @@ KGpgTransactionPrivate::KGpgTransactionPrivate(KGpgTransaction *parent, bool all
KGpgTransactionPrivate::~KGpgTransactionPrivate()
{
+ if (m_passwordDialog) {
+ m_passwordDialog->close();
+ m_passwordDialog->deleteLater();
+ }
delete m_inputTransaction;
delete m_process;
}
@@ -180,6 +189,24 @@ KGpgTransactionPrivate::slotInputTransactionDone(int result)
}
void
+KGpgTransactionPrivate::slotPasswordEntered(const QString &password)
+{
+ sender()->deleteLater();
+ m_passwordDialog = NULL;
+ m_process->write(password.toUtf8() + '\n');
+ m_parent->newPasswordEntered();
+}
+
+void
+KGpgTransactionPrivate::slotPasswordAborted()
+{
+ sender()->deleteLater();
+ m_passwordDialog = NULL;
+ m_process->kill();
+ m_success = KGpgTransaction::TS_USER_ABORTED;
+}
+
+void
KGpgTransactionPrivate::write(const QByteArray &a)
{
m_process->write(a);
@@ -241,6 +268,19 @@ KGpgTransaction::sendPassphrase(const QString &text, const bool isnew)
return KgpgInterface::sendPassphrase(text, d->m_process, isnew, qobject_cast<QWidget *>(parent()));
}
+void
+KGpgTransaction::askNewPassphrase(const QString& text)
+{
+ emit statusMessage(i18n("Requesting Passphrase"));
+
+ d->m_passwordDialog = new KNewPasswordDialog(qobject_cast<QWidget *>(parent()));
+ d->m_passwordDialog->setPrompt(text);
+ d->m_passwordDialog->setAllowEmptyPasswords(false);
+ connect(d->m_passwordDialog, SIGNAL(newPassword(QString)), SLOT(slotPasswordEntered(QString)));
+ connect(d->m_passwordDialog, SIGNAL(rejected()), SLOT(slotPasswordAborted()));
+ d->m_passwordDialog->show();
+}
+
int
KGpgTransaction::getSuccess() const
{
@@ -472,9 +512,15 @@ KGpgTransaction::hasInputTransaction() const
return (d->m_inputTransaction != NULL);
}
-void KGpgTransaction::kill()
+void
+KGpgTransaction::kill()
{
d->m_process->kill();
}
+void
+KGpgTransaction::newPasswordEntered()
+{
+}
+
#include "kgpgtransaction.moc"
diff --git a/transactions/kgpgtransaction.h b/transactions/kgpgtransaction.h
index 1af3d5d..bf47fcc 100644
--- a/transactions/kgpgtransaction.h
+++ b/transactions/kgpgtransaction.h
@@ -225,6 +225,15 @@ protected:
*/
virtual void finish();
/**
+ * @brief called when the user entered a new password
+ *
+ * This is called after askNewPassphrase() was called, the user has
+ * entered a new password and it was sent to the GnuPG process.
+ *
+ * The default implementation does nothing.
+ */
+ virtual void newPasswordEntered();
+ /**
* @brief set the description returned in getDescription()
* @param description the new description of this transaction
*/
@@ -249,6 +258,8 @@ private:
Q_PRIVATE_SLOT(d, void slotProcessExited())
Q_PRIVATE_SLOT(d, void slotProcessStarted())
Q_PRIVATE_SLOT(d, void slotInputTransactionDone(int))
+ Q_PRIVATE_SLOT(d, void slotPasswordEntered(const QString &))
+ Q_PRIVATE_SLOT(d, void slotPasswordAborted())
protected:
/**
@@ -266,6 +277,24 @@ protected:
int sendPassphrase(const QString &text, const bool isnew = false);
/**
+ * @brief Ask user for passphrase and send it to gpg process.
+ *
+ * If the gpg process asks for a new passphrase this function will do
+ * all necessary steps for you: ask the user for the password and write
+ * it to the gpg process. If the password is wrong the user is prompted
+ * again for the correct password. If the user aborts the password
+ * entry the gpg process will be killed and the transaction result will
+ * be set to TS_USER_ABORTED.
+ *
+ * In contrast to sendPassphrase() this function will not block, but
+ * handle everything using signals and slots.
+ *
+ * @see KgpgInterface::sendPassphrase
+ * @see sendPassphrase
+ */
+ void askNewPassphrase(const QString &text);
+
+ /**
* @brief get the success value that will be returned with the done signal
*/
int getSuccess() const;
@@ -383,7 +412,6 @@ protected:
* and the number of tries left.
*/
bool askPassphrase(const QString &message = QString());
-
};
#endif // KGPGTRANSACTION_H