Commit 98d78652 authored by Rolf Eike Beer's avatar Rolf Eike Beer Committed by Rolf Eike Beer
Browse files

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
parent b416fabb
......@@ -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
......@@ -190,6 +186,13 @@ KGpgGenerateKey::finish()
}
}
void
KGpgGenerateKey::newPasswordEntered()
{
QApplication::setOverrideCursor(Qt::BusyCursor);
write("%commit");
}
void
KGpgGenerateKey::setName(const QString &name)
{
......
......@@ -72,6 +72,7 @@ protected:
virtual void postStart();
virtual bool nextLine(const QString &line);
virtual void finish();
virtual void newPasswordEntered();
private:
QString m_name;
......
......@@ -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;
}
......@@ -179,6 +188,24 @@ KGpgTransactionPrivate::slotInputTransactionDone(int result)
processDone();
}
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)
{
......@@ -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"
......@@ -224,6 +224,15 @@ protected:
* does nothing which should be enough for most cases.
*/
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:
/**
......@@ -265,6 +276,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
*/
......@@ -383,7 +412,6 @@ protected:
* and the number of tries left.
*/
bool askPassphrase(const QString &message = QString());
};
#endif // KGPGTRANSACTION_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment