Qnx: Generate SSH keys in a separate thread

This avoids locking up the UI while the keys are being generated

Task-number: QTCREATORBUG-9078
Change-Id: I2229811298f07a6c402d39dd83773fb453d2b2ae
Reviewed-by: Tobias Nätterlund <tobias.naetterlund@kdab.com>
Reviewed-by: Nicolas Arnaud-Cormos <nicolas@kdab.com>
Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
This commit is contained in:
Mehdi Fekari
2013-04-23 10:39:05 +02:00
parent ba315fa750
commit b91462aad1
7 changed files with 187 additions and 23 deletions

View File

@@ -31,6 +31,7 @@
#include "blackberrydeviceconfigurationwizardpages.h" #include "blackberrydeviceconfigurationwizardpages.h"
#include "blackberrydebugtokenrequestdialog.h" #include "blackberrydebugtokenrequestdialog.h"
#include "blackberrysshkeysgenerator.h"
#include "ui_blackberrydeviceconfigurationwizardsetuppage.h" #include "ui_blackberrydeviceconfigurationwizardsetuppage.h"
#include "ui_blackberrydeviceconfigurationwizardsshkeypage.h" #include "ui_blackberrydeviceconfigurationwizardsshkeypage.h"
@@ -150,28 +151,31 @@ void BlackBerryDeviceConfigurationWizardSetupPage::requestDebugToken()
BlackBerryDeviceConfigurationWizardSshKeyPage::BlackBerryDeviceConfigurationWizardSshKeyPage(QWidget *parent) BlackBerryDeviceConfigurationWizardSshKeyPage::BlackBerryDeviceConfigurationWizardSshKeyPage(QWidget *parent)
: QWizardPage(parent) : QWizardPage(parent)
, m_ui(new Ui::BlackBerryDeviceConfigurationWizardSshKeyPage) , m_ui(new Ui::BlackBerryDeviceConfigurationWizardSshKeyPage)
, m_keyGen(0) , m_sshKeysGenerator(new BlackBerrySshKeysGenerator(this))
, m_isGenerated(false) , m_isGenerated(false)
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->privateKey->setExpectedKind(Utils::PathChooser::File); m_ui->privateKey->setExpectedKind(Utils::PathChooser::File);
m_ui->progressBar->hide();
setTitle(tr("SSH Key Setup")); setTitle(tr("SSH Key Setup"));
setSubTitle(tr("Please select an existing <b>4096</b>-bit key or click <b>Generate</b> to create a new one.")); setSubTitle(tr("Please select an existing <b>4096</b>-bit key or click <b>Generate</b> to create a new one."));
connect(m_ui->privateKey, SIGNAL(changed(QString)), this, SLOT(findMatchingPublicKey(QString))); connect(m_ui->privateKey, SIGNAL(changed(QString)), this, SLOT(findMatchingPublicKey(QString)));
connect(m_ui->privateKey, SIGNAL(changed(QString)), this, SIGNAL(completeChanged())); connect(m_ui->privateKey, SIGNAL(changed(QString)), this, SIGNAL(completeChanged()));
connect(m_ui->generate, SIGNAL(clicked()), this, SLOT(generateSshKey())); connect(m_ui->generate, SIGNAL(clicked()), this, SLOT(generateSshKeys()));
connect(m_sshKeysGenerator, SIGNAL(sshKeysGenerationFinished(bool)), this, SLOT(processSshKeys(bool)));
} }
BlackBerryDeviceConfigurationWizardSshKeyPage::~BlackBerryDeviceConfigurationWizardSshKeyPage() BlackBerryDeviceConfigurationWizardSshKeyPage::~BlackBerryDeviceConfigurationWizardSshKeyPage()
{ {
// Make sure the m_sshKeysGenerator thread is terminated before it's destroyed
m_sshKeysGenerator->terminate();
m_sshKeysGenerator->wait();
delete m_ui; delete m_ui;
m_ui = 0; m_ui = 0;
delete m_keyGen;
m_keyGen = 0;
} }
void BlackBerryDeviceConfigurationWizardSshKeyPage::initializePage() void BlackBerryDeviceConfigurationWizardSshKeyPage::initializePage()
@@ -203,7 +207,7 @@ bool BlackBerryDeviceConfigurationWizardSshKeyPage::isGenerated() const
QSsh::SshKeyGenerator *BlackBerryDeviceConfigurationWizardSshKeyPage::keyGenerator() const QSsh::SshKeyGenerator *BlackBerryDeviceConfigurationWizardSshKeyPage::keyGenerator() const
{ {
return m_keyGen; return m_sshKeysGenerator->keyGenerator();
} }
void BlackBerryDeviceConfigurationWizardSshKeyPage::findMatchingPublicKey(const QString &privateKeyPath) void BlackBerryDeviceConfigurationWizardSshKeyPage::findMatchingPublicKey(const QString &privateKeyPath)
@@ -213,21 +217,14 @@ void BlackBerryDeviceConfigurationWizardSshKeyPage::findMatchingPublicKey(const
m_ui->publicKey->setText(candidate); m_ui->publicKey->setText(candidate);
} }
void BlackBerryDeviceConfigurationWizardSshKeyPage::generateSshKey() void BlackBerryDeviceConfigurationWizardSshKeyPage::processSshKeys(bool success)
{ {
if (!m_keyGen) m_isGenerated = success;
m_keyGen = new QSsh::SshKeyGenerator; if (!m_isGenerated) {
QMessageBox::critical(this, tr("Key Generation Failed"), m_sshKeysGenerator->error());
const bool success = m_keyGen->generateKeys(QSsh::SshKeyGenerator::Rsa, setBusy(false);
QSsh::SshKeyGenerator::Mixed, 4096,
QSsh::SshKeyGenerator::DoNotOfferEncryption);
if (!success) {
QMessageBox::critical(this, tr("Key Generation Failed"), m_keyGen->error());
m_isGenerated = false;
return; return;
} }
m_isGenerated = true;
const QString storeLocation = Core::ICore::userResourcePath() + QLatin1String("/qnx/") const QString storeLocation = Core::ICore::userResourcePath() + QLatin1String("/qnx/")
+ field(QLatin1String(DEVICENAME_FIELD_ID)).toString(); + field(QLatin1String(DEVICENAME_FIELD_ID)).toString();
@@ -237,8 +234,27 @@ void BlackBerryDeviceConfigurationWizardSshKeyPage::generateSshKey()
m_ui->privateKey->setFileName(Utils::FileName::fromString(privKeyPath)); m_ui->privateKey->setFileName(Utils::FileName::fromString(privKeyPath));
m_ui->publicKey->setText(pubKeyPath); m_ui->publicKey->setText(pubKeyPath);
m_ui->privateKey->setEnabled(false); m_ui->privateKey->setEnabled(false);
setBusy(false);
} }
void BlackBerryDeviceConfigurationWizardSshKeyPage::generateSshKeys()
{
setBusy(true);
m_sshKeysGenerator->start();
}
void BlackBerryDeviceConfigurationWizardSshKeyPage::setBusy(bool busy)
{
m_ui->privateKey->setEnabled(!busy);
m_ui->generate->setEnabled(!busy);
m_ui->progressBar->setVisible(busy);
wizard()->button(QWizard::BackButton)->setEnabled(!busy);
wizard()->button(QWizard::NextButton)->setEnabled(!busy);
wizard()->button(QWizard::FinishButton)->setEnabled(!busy);
wizard()->button(QWizard::CancelButton)->setEnabled(!busy);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -251,3 +267,6 @@ BlackBerryDeviceConfigurationWizardFinalPage::BlackBerryDeviceConfigurationWizar
QLabel *label = new QLabel(tr("The new device configuration will now be created."), this); QLabel *label = new QLabel(tr("The new device configuration will now be created."), this);
layout->addWidget(label); layout->addWidget(label);
} }

View File

@@ -46,6 +46,7 @@ namespace Ui {
class BlackBerryDeviceConfigurationWizardSetupPage; class BlackBerryDeviceConfigurationWizardSetupPage;
class BlackBerryDeviceConfigurationWizardSshKeyPage; class BlackBerryDeviceConfigurationWizardSshKeyPage;
} }
class BlackBerrySshKeysGenerator;
class BlackBerryDeviceConfigurationWizardSetupPage : public QWizardPage class BlackBerryDeviceConfigurationWizardSetupPage : public QWizardPage
{ {
@@ -89,14 +90,16 @@ public:
private slots: private slots:
void findMatchingPublicKey(const QString &privateKeyPath); void findMatchingPublicKey(const QString &privateKeyPath);
void generateSshKey(); void processSshKeys(bool success);
void generateSshKeys();
private: private:
void saveKeys(); void saveKeys();
void setBusy(bool busy);
Ui::BlackBerryDeviceConfigurationWizardSshKeyPage *m_ui; Ui::BlackBerryDeviceConfigurationWizardSshKeyPage *m_ui;
QSsh::SshKeyGenerator *m_keyGen; BlackBerrySshKeysGenerator *m_sshKeysGenerator;
bool m_isGenerated; bool m_isGenerated;
}; };

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>413</width> <width>413</width>
<height>88</height> <height>139</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -45,6 +45,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1">
<widget class="QProgressBar" name="progressBar">
<property name="maximum">
<number>0</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>

View File

@@ -0,0 +1,65 @@
/**************************************************************************
**
** Copyright (C) 2011 - 2013 Research In Motion
**
** Contact: Research In Motion (blackberry-qt@qnx.com)
** Contact: KDAB (info@kdab.com)
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "blackberrysshkeysgenerator.h"
#include <ssh/sshkeygenerator.h>
using namespace Qnx::Internal;
BlackBerrySshKeysGenerator::BlackBerrySshKeysGenerator(QObject *parent)
: QThread(parent)
, m_keyGen(new QSsh::SshKeyGenerator)
{
}
BlackBerrySshKeysGenerator::~BlackBerrySshKeysGenerator()
{
delete m_keyGen;
m_keyGen = 0;
}
void BlackBerrySshKeysGenerator::run()
{
const bool success = m_keyGen->generateKeys(QSsh::SshKeyGenerator::Rsa,
QSsh::SshKeyGenerator::Mixed, 4096,
QSsh::SshKeyGenerator::DoNotOfferEncryption);
emit sshKeysGenerationFinished(success);
}
QSsh::SshKeyGenerator *BlackBerrySshKeysGenerator::keyGenerator() const
{
return m_keyGen;
}
QString BlackBerrySshKeysGenerator::error() const
{
return m_keyGen->error();
}

View File

@@ -0,0 +1,63 @@
/**************************************************************************
**
** Copyright (C) 2011 - 2013 Research In Motion
**
** Contact: Research In Motion (blackberry-qt@qnx.com)
** Contact: KDAB (info@kdab.com)
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef BLACKBERRYSSHKEYSGENERATOR_H
#define BLACKBERRYSSHKEYSGENERATOR_H
#include <QThread>
namespace QSsh {
class SshKeyGenerator;
}
namespace Qnx {
namespace Internal {
class BlackBerrySshKeysGenerator : public QThread
{
Q_OBJECT
public:
BlackBerrySshKeysGenerator(QObject *parent = 0);
~BlackBerrySshKeysGenerator();
QSsh::SshKeyGenerator *keyGenerator() const;
QString error() const;
signals:
void sshKeysGenerationFinished(bool success);
private:
QSsh::SshKeyGenerator *m_keyGen;
void run();
};
} // namespace Internal
} // namespace Qnx
#endif // BLACKBERRYSSHKEYSGENERATOR_H

View File

@@ -76,7 +76,8 @@ SOURCES += qnxplugin.cpp \
blackberrycheckdevmodestepconfigwidget.cpp \ blackberrycheckdevmodestepconfigwidget.cpp \
blackberrydeviceconnection.cpp \ blackberrydeviceconnection.cpp \
blackberrydeviceconnectionmanager.cpp \ blackberrydeviceconnectionmanager.cpp \
blackberrydeviceinformation.cpp blackberrydeviceinformation.cpp \
blackberrysshkeysgenerator.cpp
HEADERS += qnxplugin.h\ HEADERS += qnxplugin.h\
qnxconstants.h \ qnxconstants.h \
@@ -152,7 +153,8 @@ HEADERS += qnxplugin.h\
blackberrycheckdevmodestepconfigwidget.h \ blackberrycheckdevmodestepconfigwidget.h \
blackberrydeviceconnection.h \ blackberrydeviceconnection.h \
blackberrydeviceconnectionmanager.h \ blackberrydeviceconnectionmanager.h \
blackberrydeviceinformation.h blackberrydeviceinformation.h \
blackberrysshkeysgenerator.h
FORMS += \ FORMS += \
blackberrydeviceconfigurationwizardsetuppage.ui \ blackberrydeviceconfigurationwizardsetuppage.ui \

View File

@@ -140,6 +140,8 @@ QtcPlugin {
"blackberrydebugtokenuploader.h", "blackberrydebugtokenuploader.h",
"blackberryndkprocess.cpp", "blackberryndkprocess.cpp",
"blackberryndkprocess.h", "blackberryndkprocess.h",
"blackberrysshkeysgenerator.cpp",
"blackberrysshkeysgenerator.h",
"pathchooserdelegate.cpp", "pathchooserdelegate.cpp",
"pathchooserdelegate.h", "pathchooserdelegate.h",
"qnx.qrc", "qnx.qrc",