/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** 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 The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ #include "sshkeycreationdialog.h" #include "ui_sshkeycreationdialog.h" #include "sshkeygenerator.h" #include #include #include #include #include #include #include namespace QSsh { SshKeyCreationDialog::SshKeyCreationDialog(QWidget *parent) : QDialog(parent), m_keyGenerator(0), m_ui(new Ui::SshKeyCreationDialog) { m_ui->setupUi(this); // Not using Utils::PathChooser::browseButtonLabel to avoid dependency #ifdef Q_OS_MAC m_ui->privateKeyFileButton->setText(tr("Choose...")); #else m_ui->privateKeyFileButton->setText(tr("Browse...")); #endif const QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QLatin1String("/.ssh/qtc_id"); setPrivateKeyFile(defaultPath); connect(m_ui->rsa, &QRadioButton::toggled, this, &SshKeyCreationDialog::keyTypeChanged); connect(m_ui->dsa, &QRadioButton::toggled, this, &SshKeyCreationDialog::keyTypeChanged); connect(m_ui->privateKeyFileButton, &QPushButton::clicked, this, &SshKeyCreationDialog::handleBrowseButtonClicked); connect(m_ui->generateButton, &QPushButton::clicked, this, &SshKeyCreationDialog::generateKeys); keyTypeChanged(); } SshKeyCreationDialog::~SshKeyCreationDialog() { delete m_keyGenerator; delete m_ui; } void SshKeyCreationDialog::keyTypeChanged() { m_ui->comboBox->clear(); QStringList keySizes; if (m_ui->rsa->isChecked()) keySizes << QLatin1String("1024") << QLatin1String("2048") << QLatin1String("4096"); else if (m_ui->ecdsa->isChecked()) keySizes << QLatin1String("256") << QLatin1String("384") << QLatin1String("521"); else if (m_ui->dsa->isChecked()) keySizes << QLatin1String("1024"); m_ui->comboBox->addItems(keySizes); if (!keySizes.isEmpty()) m_ui->comboBox->setCurrentIndex(0); m_ui->comboBox->setEnabled(!keySizes.isEmpty()); } void SshKeyCreationDialog::generateKeys() { if (userForbidsOverwriting()) return; const SshKeyGenerator::KeyType keyType = m_ui->rsa->isChecked() ? SshKeyGenerator::Rsa : m_ui->dsa->isChecked() ? SshKeyGenerator::Dsa : SshKeyGenerator::Ecdsa; if (!m_keyGenerator) m_keyGenerator = new SshKeyGenerator; QApplication::setOverrideCursor(Qt::BusyCursor); const bool success = m_keyGenerator->generateKeys(keyType, SshKeyGenerator::Mixed, m_ui->comboBox->currentText().toUShort()); QApplication::restoreOverrideCursor(); if (success) saveKeys(); else QMessageBox::critical(this, tr("Key Generation Failed"), m_keyGenerator->error()); } void SshKeyCreationDialog::handleBrowseButtonClicked() { const QString filePath = QFileDialog::getSaveFileName(this, tr("Choose Private Key File Name")); if (!filePath.isEmpty()) setPrivateKeyFile(filePath); } void SshKeyCreationDialog::setPrivateKeyFile(const QString &filePath) { m_ui->privateKeyFileValueLabel->setText(filePath); m_ui->generateButton->setEnabled(!privateKeyFilePath().isEmpty()); m_ui->publicKeyFileLabel->setText(filePath + QLatin1String(".pub")); } void SshKeyCreationDialog::saveKeys() { const QString parentDir = QFileInfo(privateKeyFilePath()).dir().path(); if (!QDir::root().mkpath(parentDir)) { QMessageBox::critical(this, tr("Cannot Save Key File"), tr("Failed to create directory: \"%1\".").arg(parentDir)); return; } QFile privateKeyFile(privateKeyFilePath()); if (!privateKeyFile.open(QIODevice::WriteOnly) || !privateKeyFile.write(m_keyGenerator->privateKey())) { QMessageBox::critical(this, tr("Cannot Save Private Key File"), tr("The private key file could not be saved: %1").arg(privateKeyFile.errorString())); return; } QFile::setPermissions(privateKeyFilePath(), QFile::ReadOwner | QFile::WriteOwner); QFile publicKeyFile(publicKeyFilePath()); if (!publicKeyFile.open(QIODevice::WriteOnly) || !publicKeyFile.write(m_keyGenerator->publicKey())) { QMessageBox::critical(this, tr("Cannot Save Public Key File"), tr("The public key file could not be saved: %1").arg(publicKeyFile.errorString())); return; } accept(); } bool SshKeyCreationDialog::userForbidsOverwriting() { if (!QFileInfo::exists(privateKeyFilePath()) && !QFileInfo::exists(publicKeyFilePath())) return false; const QMessageBox::StandardButton reply = QMessageBox::question(this, tr("File Exists"), tr("There already is a file of that name. Do you want to overwrite it?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); return reply != QMessageBox::Yes; } QString SshKeyCreationDialog::privateKeyFilePath() const { return m_ui->privateKeyFileValueLabel->text(); } QString SshKeyCreationDialog::publicKeyFilePath() const { return m_ui->publicKeyFileLabel->text(); } } // namespace QSsh