From 9728afadb0c0828270f28c835a6be6f8a220ea5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20N=C3=A4tterlund?= Date: Tue, 16 Apr 2013 14:53:24 +0200 Subject: [PATCH] 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 Reviewed-by: Rafael Roquetto Reviewed-by: Mehdi Fekari --- src/plugins/qnx/blackberryconfiguration.cpp | 15 ++-- .../blackberrydeviceconfigurationwizard.cpp | 62 --------------- .../qnx/blackberrydeviceconfigurationwizard.h | 4 - ...ackberrydeviceconfigurationwizardpages.cpp | 77 +++++++++++++------ ...blackberrydeviceconfigurationwizardpages.h | 7 +- ...errydeviceconfigurationwizardsshkeypage.ui | 28 ++++--- 6 files changed, 79 insertions(+), 114 deletions(-) diff --git a/src/plugins/qnx/blackberryconfiguration.cpp b/src/plugins/qnx/blackberryconfiguration.cpp index 537ef617c9a..8fd45f60c8e 100644 --- a/src/plugins/qnx/blackberryconfiguration.cpp +++ b/src/plugins/qnx/blackberryconfiguration.cpp @@ -56,6 +56,7 @@ #include #include #include +#include namespace Qnx { namespace Internal { @@ -442,16 +443,14 @@ QString BlackBerryConfiguration::dataDirPath() const if (Utils::HostOsInfo::isAnyUnixHost()) return homeDir + QLatin1String("/.rim"); -#if defined(Q_OS_WIN) if (Utils::HostOsInfo::isWindowsHost()) { - // needed because QSysInfo::windowsVersion() is not available on other - // platforms. - if (QSysInfo::windowsVersion() == QSysInfo::WV_XP) - return homeDir - + QLatin1String("/Local Settings/Application Data/Research In Motion"); - return homeDir + QLatin1String("/AppData/Local/Research in Motion"); + // Get the proper storage location on Windows using QDesktopServices, + // to not hardcode "AppData/Local", as it might refer to "AppData/Roaming". + QString dataDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + dataDir = dataDir.left(dataDir.indexOf(QCoreApplication::organizationName())); + dataDir.append(QLatin1String("Research in Motion")); + return dataDir; } -#endif return QString(); } diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizard.cpp b/src/plugins/qnx/blackberrydeviceconfigurationwizard.cpp index 936bc9f4467..414ef2c93f0 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwizard.cpp +++ b/src/plugins/qnx/blackberrydeviceconfigurationwizard.cpp @@ -35,15 +35,6 @@ #include "blackberrydeviceconfiguration.h" #include -#include -#include -#include -#include - -#include -#include -#include -#include using namespace Qnx; using namespace Qnx::Internal; @@ -82,56 +73,3 @@ ProjectExplorer::IDevice::Ptr BlackBerryDeviceConfigurationWizard::device() configuration->setDebugToken(m_setupPage->debugToken()); 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; -} diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizard.h b/src/plugins/qnx/blackberrydeviceconfigurationwizard.h index cb7b413a8b7..f5a31d67874 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwizard.h +++ b/src/plugins/qnx/blackberrydeviceconfigurationwizard.h @@ -51,8 +51,6 @@ public: ProjectExplorer::IDevice::Ptr device(); - void accept(); - private: enum PageId { SetupPageId, @@ -60,8 +58,6 @@ private: FinalPageId }; - bool saveKeys(); - BlackBerryDeviceConfigurationWizardSetupPage *m_setupPage; BlackBerryDeviceConfigurationWizardSshKeyPage *m_sshKeyPage; BlackBerryDeviceConfigurationWizardFinalPage *m_finalPage; diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp index 3e84432b510..0bba1dbac7c 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp +++ b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp @@ -30,6 +30,7 @@ ****************************************************************************/ #include "blackberrydeviceconfigurationwizardpages.h" +#include "blackberryconfiguration.h" #include "blackberrydebugtokenrequestdialog.h" #include "blackberrysshkeysgenerator.h" #include "ui_blackberrydeviceconfigurationwizardsetuppage.h" @@ -40,7 +41,9 @@ #include #include +#include #include +#include using namespace ProjectExplorer; using namespace Qnx; @@ -152,13 +155,17 @@ BlackBerryDeviceConfigurationWizardSshKeyPage::BlackBerryDeviceConfigurationWiza : QWizardPage(parent) , m_ui(new Ui::BlackBerryDeviceConfigurationWizardSshKeyPage) , m_sshKeysGenerator(new BlackBerrySshKeysGenerator(this)) - , m_isGenerated(false) { m_ui->setupUi(this); m_ui->privateKey->setExpectedKind(Utils::PathChooser::File); 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")); setSubTitle(tr("Please select an existing 4096-bit key or click Generate to create a new one.")); @@ -187,7 +194,7 @@ bool BlackBerryDeviceConfigurationWizardSshKeyPage::isComplete() const QFileInfo privateKeyFi(m_ui->privateKey->fileName().toString()); QFileInfo publicKeyFi(m_ui->publicKey->text()); - return (privateKeyFi.exists() && publicKeyFi.exists()) || m_isGenerated; + return privateKeyFi.exists() && publicKeyFi.exists(); } QString BlackBerryDeviceConfigurationWizardSshKeyPage::privateKey() const @@ -200,46 +207,69 @@ QString BlackBerryDeviceConfigurationWizardSshKeyPage::publicKey() const 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) { const QString candidate = privateKeyPath + QLatin1String(".pub"); if (QFileInfo(candidate).exists()) m_ui->publicKey->setText(candidate); + else + m_ui->publicKey->clear(); } void BlackBerryDeviceConfigurationWizardSshKeyPage::processSshKeys(bool success) { - m_isGenerated = success; - if (!m_isGenerated) { + setBusy(false); + + if (!success) { QMessageBox::critical(this, tr("Key Generation Failed"), m_sshKeysGenerator->error()); - setBusy(false); return; } - const QString storeLocation = Core::ICore::userResourcePath() + QLatin1String("/qnx/") - + field(QLatin1String(DEVICENAME_FIELD_ID)).toString(); - const QString privKeyPath = storeLocation + QLatin1String("/id_rsa"); - const QString pubKeyPath = storeLocation + QLatin1String("/id_rsa.pub"); + const QString publicKeyPath = m_generatedPrivateKeyPath + QLatin1String(".pub"); - m_ui->privateKey->setFileName(Utils::FileName::fromString(privKeyPath)); - m_ui->publicKey->setText(pubKeyPath); - m_ui->privateKey->setEnabled(false); + if (!saveKeys(m_generatedPrivateKeyPath, publicKeyPath)) // saveKeys(..) will show an error message if necessary + return; - 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() { + 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); m_sshKeysGenerator->start(); } @@ -247,6 +277,7 @@ void BlackBerryDeviceConfigurationWizardSshKeyPage::generateSshKeys() void BlackBerryDeviceConfigurationWizardSshKeyPage::setBusy(bool busy) { m_ui->privateKey->setEnabled(!busy); + m_ui->publicKey->setEnabled(!busy); m_ui->generate->setEnabled(!busy); m_ui->progressBar->setVisible(busy); diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h index 6a2e926a2bd..c9354cd30da 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h +++ b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.h @@ -84,9 +84,6 @@ public: QString privateKey() const; QString publicKey() const; - bool isGenerated() const; - - QSsh::SshKeyGenerator *keyGenerator() const; private slots: void findMatchingPublicKey(const QString &privateKeyPath); @@ -94,13 +91,13 @@ private slots: void generateSshKeys(); private: - void saveKeys(); + bool saveKeys(const QString &privateKeyFile, const QString &publicKeyFile); void setBusy(bool busy); Ui::BlackBerryDeviceConfigurationWizardSshKeyPage *m_ui; BlackBerrySshKeysGenerator *m_sshKeysGenerator; - bool m_isGenerated; + QString m_generatedPrivateKeyPath; }; class BlackBerryDeviceConfigurationWizardFinalPage : public QWizardPage diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizardsshkeypage.ui b/src/plugins/qnx/blackberrydeviceconfigurationwizardsshkeypage.ui index 8754794586a..3eb327e46fa 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwizardsshkeypage.ui +++ b/src/plugins/qnx/blackberrydeviceconfigurationwizardsshkeypage.ui @@ -7,7 +7,7 @@ 0 0 413 - 139 + 92 @@ -22,7 +22,18 @@ - + + + + + + + + Generate... + + + + @@ -31,17 +42,10 @@ - - - - Generate - - - - - - + + + true