forked from qt-creator/qt-creator
QNX: Improved generation of SSH keys for BlackBerry devices
The user is now asked where to store the generated SSH key, before it is generated, and if that would fail, is still enabled to select a different key. Task-number: QTCREATORBUG-9101 Task-number: QTCREATORBUG-9102 Change-Id: I8e2f732dbcbe7bd3bd3fa9b512a7a195fa868c17 Reviewed-by: Nicolas Arnaud-Cormos <nicolas@kdab.com> Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com> Reviewed-by: Mehdi Fekari <mfekari@blackberry.com>
This commit is contained in:
committed by
Tobias Nätterlund
parent
22fcb71a8e
commit
9728afadb0
@@ -56,6 +56,7 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
|
||||||
namespace Qnx {
|
namespace Qnx {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -442,16 +443,14 @@ QString BlackBerryConfiguration::dataDirPath() const
|
|||||||
if (Utils::HostOsInfo::isAnyUnixHost())
|
if (Utils::HostOsInfo::isAnyUnixHost())
|
||||||
return homeDir + QLatin1String("/.rim");
|
return homeDir + QLatin1String("/.rim");
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
if (Utils::HostOsInfo::isWindowsHost()) {
|
if (Utils::HostOsInfo::isWindowsHost()) {
|
||||||
// needed because QSysInfo::windowsVersion() is not available on other
|
// Get the proper storage location on Windows using QDesktopServices,
|
||||||
// platforms.
|
// to not hardcode "AppData/Local", as it might refer to "AppData/Roaming".
|
||||||
if (QSysInfo::windowsVersion() == QSysInfo::WV_XP)
|
QString dataDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
|
||||||
return homeDir
|
dataDir = dataDir.left(dataDir.indexOf(QCoreApplication::organizationName()));
|
||||||
+ QLatin1String("/Local Settings/Application Data/Research In Motion");
|
dataDir.append(QLatin1String("Research in Motion"));
|
||||||
return homeDir + QLatin1String("/AppData/Local/Research in Motion");
|
return dataDir;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,15 +35,6 @@
|
|||||||
#include "blackberrydeviceconfiguration.h"
|
#include "blackberrydeviceconfiguration.h"
|
||||||
|
|
||||||
#include <ssh/sshconnection.h>
|
#include <ssh/sshconnection.h>
|
||||||
#include <ssh/sshkeygenerator.h>
|
|
||||||
#include <utils/portlist.h>
|
|
||||||
#include <utils/fileutils.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QHostInfo>
|
|
||||||
|
|
||||||
using namespace Qnx;
|
using namespace Qnx;
|
||||||
using namespace Qnx::Internal;
|
using namespace Qnx::Internal;
|
||||||
@@ -82,56 +73,3 @@ ProjectExplorer::IDevice::Ptr BlackBerryDeviceConfigurationWizard::device()
|
|||||||
configuration->setDebugToken(m_setupPage->debugToken());
|
configuration->setDebugToken(m_setupPage->debugToken());
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlackBerryDeviceConfigurationWizard::accept()
|
|
||||||
{
|
|
||||||
if (m_sshKeyPage->isGenerated()) {
|
|
||||||
if (saveKeys())
|
|
||||||
QWizard::accept();
|
|
||||||
} else {
|
|
||||||
QWizard::accept();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BlackBerryDeviceConfigurationWizard::saveKeys()
|
|
||||||
{
|
|
||||||
const QString privKeyPath = m_sshKeyPage->privateKey();
|
|
||||||
const QString pubKeyPath = m_sshKeyPage->publicKey();
|
|
||||||
|
|
||||||
const QString storeLocation = QFileInfo(privKeyPath).absolutePath();
|
|
||||||
if (!QDir::root().mkpath(storeLocation)) {
|
|
||||||
QMessageBox::critical(this, tr("Failure to Save Key File"),
|
|
||||||
tr("Failed to create directory: '%1'.").arg(storeLocation));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (QFileInfo(privKeyPath).exists()) {
|
|
||||||
QMessageBox::critical(this, tr("Failure to Save Key File"),
|
|
||||||
tr("Private key file already exists: '%1'").arg(privKeyPath));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (QFileInfo(pubKeyPath).exists()) {
|
|
||||||
QMessageBox::critical(this, tr("Failure to Save Key File"),
|
|
||||||
tr("Public key file already exists: '%1'").arg(pubKeyPath));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils::FileSaver privSaver(privKeyPath);
|
|
||||||
privSaver.write(m_sshKeyPage->keyGenerator()->privateKey());
|
|
||||||
if (!privSaver.finalize(this))
|
|
||||||
return false; // finalize shows an error message if necessary
|
|
||||||
QFile::setPermissions(privKeyPath, QFile::ReadOwner | QFile::WriteOwner);
|
|
||||||
|
|
||||||
Utils::FileSaver pubSaver(pubKeyPath);
|
|
||||||
|
|
||||||
// blackberry-connect requires an @ character to be included in the RSA comment
|
|
||||||
const QString atHost = QLatin1String("@") + QHostInfo::localHostName();
|
|
||||||
QByteArray pubKeyContent = m_sshKeyPage->keyGenerator()->publicKey();
|
|
||||||
pubKeyContent.append(atHost.toLocal8Bit());
|
|
||||||
|
|
||||||
pubSaver.write(pubKeyContent);
|
|
||||||
if (!pubSaver.finalize(this))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -51,8 +51,6 @@ public:
|
|||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr device();
|
ProjectExplorer::IDevice::Ptr device();
|
||||||
|
|
||||||
void accept();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum PageId {
|
enum PageId {
|
||||||
SetupPageId,
|
SetupPageId,
|
||||||
@@ -60,8 +58,6 @@ private:
|
|||||||
FinalPageId
|
FinalPageId
|
||||||
};
|
};
|
||||||
|
|
||||||
bool saveKeys();
|
|
||||||
|
|
||||||
BlackBerryDeviceConfigurationWizardSetupPage *m_setupPage;
|
BlackBerryDeviceConfigurationWizardSetupPage *m_setupPage;
|
||||||
BlackBerryDeviceConfigurationWizardSshKeyPage *m_sshKeyPage;
|
BlackBerryDeviceConfigurationWizardSshKeyPage *m_sshKeyPage;
|
||||||
BlackBerryDeviceConfigurationWizardFinalPage *m_finalPage;
|
BlackBerryDeviceConfigurationWizardFinalPage *m_finalPage;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "blackberrydeviceconfigurationwizardpages.h"
|
#include "blackberrydeviceconfigurationwizardpages.h"
|
||||||
|
#include "blackberryconfiguration.h"
|
||||||
#include "blackberrydebugtokenrequestdialog.h"
|
#include "blackberrydebugtokenrequestdialog.h"
|
||||||
#include "blackberrysshkeysgenerator.h"
|
#include "blackberrysshkeysgenerator.h"
|
||||||
#include "ui_blackberrydeviceconfigurationwizardsetuppage.h"
|
#include "ui_blackberrydeviceconfigurationwizardsetuppage.h"
|
||||||
@@ -40,7 +41,9 @@
|
|||||||
|
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QFileDialog>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QHostInfo>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace Qnx;
|
using namespace Qnx;
|
||||||
@@ -152,13 +155,17 @@ BlackBerryDeviceConfigurationWizardSshKeyPage::BlackBerryDeviceConfigurationWiza
|
|||||||
: QWizardPage(parent)
|
: QWizardPage(parent)
|
||||||
, m_ui(new Ui::BlackBerryDeviceConfigurationWizardSshKeyPage)
|
, m_ui(new Ui::BlackBerryDeviceConfigurationWizardSshKeyPage)
|
||||||
, m_sshKeysGenerator(new BlackBerrySshKeysGenerator(this))
|
, m_sshKeysGenerator(new BlackBerrySshKeysGenerator(this))
|
||||||
, 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();
|
m_ui->progressBar->hide();
|
||||||
|
|
||||||
|
QString initialBrowsePath = BlackBerryConfiguration::instance().dataDirPath();
|
||||||
|
if (!QFileInfo(initialBrowsePath).exists())
|
||||||
|
initialBrowsePath = QDir::homePath();
|
||||||
|
m_ui->privateKey->setInitialBrowsePathBackup(initialBrowsePath);
|
||||||
|
|
||||||
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."));
|
||||||
|
|
||||||
@@ -187,7 +194,7 @@ bool BlackBerryDeviceConfigurationWizardSshKeyPage::isComplete() const
|
|||||||
QFileInfo privateKeyFi(m_ui->privateKey->fileName().toString());
|
QFileInfo privateKeyFi(m_ui->privateKey->fileName().toString());
|
||||||
QFileInfo publicKeyFi(m_ui->publicKey->text());
|
QFileInfo publicKeyFi(m_ui->publicKey->text());
|
||||||
|
|
||||||
return (privateKeyFi.exists() && publicKeyFi.exists()) || m_isGenerated;
|
return privateKeyFi.exists() && publicKeyFi.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BlackBerryDeviceConfigurationWizardSshKeyPage::privateKey() const
|
QString BlackBerryDeviceConfigurationWizardSshKeyPage::privateKey() const
|
||||||
@@ -200,46 +207,69 @@ QString BlackBerryDeviceConfigurationWizardSshKeyPage::publicKey() const
|
|||||||
return m_ui->publicKey->text();
|
return m_ui->publicKey->text();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlackBerryDeviceConfigurationWizardSshKeyPage::isGenerated() const
|
|
||||||
{
|
|
||||||
return m_isGenerated;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSsh::SshKeyGenerator *BlackBerryDeviceConfigurationWizardSshKeyPage::keyGenerator() const
|
|
||||||
{
|
|
||||||
return m_sshKeysGenerator->keyGenerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlackBerryDeviceConfigurationWizardSshKeyPage::findMatchingPublicKey(const QString &privateKeyPath)
|
void BlackBerryDeviceConfigurationWizardSshKeyPage::findMatchingPublicKey(const QString &privateKeyPath)
|
||||||
{
|
{
|
||||||
const QString candidate = privateKeyPath + QLatin1String(".pub");
|
const QString candidate = privateKeyPath + QLatin1String(".pub");
|
||||||
if (QFileInfo(candidate).exists())
|
if (QFileInfo(candidate).exists())
|
||||||
m_ui->publicKey->setText(candidate);
|
m_ui->publicKey->setText(candidate);
|
||||||
|
else
|
||||||
|
m_ui->publicKey->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlackBerryDeviceConfigurationWizardSshKeyPage::processSshKeys(bool success)
|
void BlackBerryDeviceConfigurationWizardSshKeyPage::processSshKeys(bool success)
|
||||||
{
|
{
|
||||||
m_isGenerated = success;
|
|
||||||
if (!m_isGenerated) {
|
|
||||||
QMessageBox::critical(this, tr("Key Generation Failed"), m_sshKeysGenerator->error());
|
|
||||||
setBusy(false);
|
setBusy(false);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
QMessageBox::critical(this, tr("Key Generation Failed"), m_sshKeysGenerator->error());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString storeLocation = Core::ICore::userResourcePath() + QLatin1String("/qnx/")
|
const QString publicKeyPath = m_generatedPrivateKeyPath + QLatin1String(".pub");
|
||||||
+ field(QLatin1String(DEVICENAME_FIELD_ID)).toString();
|
|
||||||
const QString privKeyPath = storeLocation + QLatin1String("/id_rsa");
|
|
||||||
const QString pubKeyPath = storeLocation + QLatin1String("/id_rsa.pub");
|
|
||||||
|
|
||||||
m_ui->privateKey->setFileName(Utils::FileName::fromString(privKeyPath));
|
if (!saveKeys(m_generatedPrivateKeyPath, publicKeyPath)) // saveKeys(..) will show an error message if necessary
|
||||||
m_ui->publicKey->setText(pubKeyPath);
|
return;
|
||||||
m_ui->privateKey->setEnabled(false);
|
|
||||||
|
|
||||||
setBusy(false);
|
m_ui->privateKey->setFileName(Utils::FileName::fromString(m_generatedPrivateKeyPath));
|
||||||
|
m_ui->publicKey->setText(publicKeyPath);
|
||||||
|
|
||||||
|
emit completeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BlackBerryDeviceConfigurationWizardSshKeyPage::saveKeys(const QString &privateKeyFile, const QString &publicKeyFile)
|
||||||
|
{
|
||||||
|
Utils::FileSaver privSaver(privateKeyFile);
|
||||||
|
privSaver.write(m_sshKeysGenerator->keyGenerator()->privateKey());
|
||||||
|
if (!privSaver.finalize(this))
|
||||||
|
return false; // finalize shows an error message if necessary
|
||||||
|
QFile::setPermissions(privateKeyFile, QFile::ReadOwner | QFile::WriteOwner);
|
||||||
|
|
||||||
|
Utils::FileSaver pubSaver(publicKeyFile);
|
||||||
|
|
||||||
|
// blackberry-connect requires an @ character to be included in the RSA comment
|
||||||
|
const QString atHost = QLatin1String("@") + QHostInfo::localHostName();
|
||||||
|
QByteArray pubKeyContent = m_sshKeysGenerator->keyGenerator()->publicKey();
|
||||||
|
pubKeyContent.append(atHost.toLocal8Bit());
|
||||||
|
|
||||||
|
pubSaver.write(pubKeyContent);
|
||||||
|
if (!pubSaver.finalize(this))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlackBerryDeviceConfigurationWizardSshKeyPage::generateSshKeys()
|
void BlackBerryDeviceConfigurationWizardSshKeyPage::generateSshKeys()
|
||||||
{
|
{
|
||||||
|
QString lookInDir = BlackBerryConfiguration::instance().dataDirPath();
|
||||||
|
if (!QFileInfo(lookInDir).exists())
|
||||||
|
lookInDir = QDir::homePath();
|
||||||
|
|
||||||
|
QString privateKeyPath = QFileDialog::getSaveFileName(this, tr("Choose Private Key File Name"), lookInDir);
|
||||||
|
if (privateKeyPath.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_generatedPrivateKeyPath = privateKeyPath;
|
||||||
|
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
m_sshKeysGenerator->start();
|
m_sshKeysGenerator->start();
|
||||||
}
|
}
|
||||||
@@ -247,6 +277,7 @@ void BlackBerryDeviceConfigurationWizardSshKeyPage::generateSshKeys()
|
|||||||
void BlackBerryDeviceConfigurationWizardSshKeyPage::setBusy(bool busy)
|
void BlackBerryDeviceConfigurationWizardSshKeyPage::setBusy(bool busy)
|
||||||
{
|
{
|
||||||
m_ui->privateKey->setEnabled(!busy);
|
m_ui->privateKey->setEnabled(!busy);
|
||||||
|
m_ui->publicKey->setEnabled(!busy);
|
||||||
m_ui->generate->setEnabled(!busy);
|
m_ui->generate->setEnabled(!busy);
|
||||||
m_ui->progressBar->setVisible(busy);
|
m_ui->progressBar->setVisible(busy);
|
||||||
|
|
||||||
|
|||||||
@@ -84,9 +84,6 @@ public:
|
|||||||
|
|
||||||
QString privateKey() const;
|
QString privateKey() const;
|
||||||
QString publicKey() const;
|
QString publicKey() const;
|
||||||
bool isGenerated() const;
|
|
||||||
|
|
||||||
QSsh::SshKeyGenerator *keyGenerator() const;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void findMatchingPublicKey(const QString &privateKeyPath);
|
void findMatchingPublicKey(const QString &privateKeyPath);
|
||||||
@@ -94,13 +91,13 @@ private slots:
|
|||||||
void generateSshKeys();
|
void generateSshKeys();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveKeys();
|
bool saveKeys(const QString &privateKeyFile, const QString &publicKeyFile);
|
||||||
void setBusy(bool busy);
|
void setBusy(bool busy);
|
||||||
|
|
||||||
Ui::BlackBerryDeviceConfigurationWizardSshKeyPage *m_ui;
|
Ui::BlackBerryDeviceConfigurationWizardSshKeyPage *m_ui;
|
||||||
|
|
||||||
BlackBerrySshKeysGenerator *m_sshKeysGenerator;
|
BlackBerrySshKeysGenerator *m_sshKeysGenerator;
|
||||||
bool m_isGenerated;
|
QString m_generatedPrivateKeyPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlackBerryDeviceConfigurationWizardFinalPage : public QWizardPage
|
class BlackBerryDeviceConfigurationWizardFinalPage : public QWizardPage
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>413</width>
|
<width>413</width>
|
||||||
<height>139</height>
|
<height>92</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -22,8 +22,19 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
<widget class="Utils::PathChooser" name="privateKey" native="true"/>
|
<widget class="Utils::PathChooser" name="privateKey" native="true"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="generate">
|
||||||
|
<property name="text">
|
||||||
|
<string>Generate...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -31,17 +42,10 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QPushButton" name="generate">
|
|
||||||
<property name="text">
|
|
||||||
<string>Generate</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QLabel" name="publicKey">
|
<widget class="QLineEdit" name="publicKey">
|
||||||
<property name="text">
|
<property name="readOnly">
|
||||||
<string/>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user