From f997aea8e74a9225ac320be61eacdb5153efed9e Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Mon, 20 Apr 2015 18:51:22 +0100 Subject: [PATCH] Moved SSL generate code as is into new class #4549 --- src/gui/gui.pro | 8 +- src/gui/src/PluginManager.cpp | 145 ------------------------ src/gui/src/PluginManager.h | 4 +- src/gui/src/PluginWizardPage.cpp | 26 +++-- src/gui/src/PluginWizardPage.h | 4 +- src/gui/src/SslCertificate.cpp | 184 +++++++++++++++++++++++++++++++ src/gui/src/SslCertificate.h | 36 ++++++ 7 files changed, 246 insertions(+), 161 deletions(-) create mode 100644 src/gui/src/SslCertificate.cpp create mode 100644 src/gui/src/SslCertificate.h diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 7f2670be..f519885e 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -56,7 +56,8 @@ SOURCES += src/main.cpp \ src/PluginWizardPage.cpp \ src/PluginManager.cpp \ src/CoreInterface.cpp \ - src/Fingerprint.cpp + src/Fingerprint.cpp \ + src/SslCertificate.cpp HEADERS += src/MainWindow.h \ src/AboutDialog.h \ src/ServerConfig.h \ @@ -99,10 +100,11 @@ HEADERS += src/MainWindow.h \ src/ProcessorArch.h \ src/PluginManager.h \ src/CoreInterface.h \ - src/Fingerprint.h + src/Fingerprint.h \ + src/SslCertificate.h RESOURCES += res/Synergy.qrc RC_FILE = res/win/Synergy.rc -macx { +macx { QMAKE_INFO_PLIST = res/mac/Info.plist TARGET = Synergy QSYNERGY_ICON.files = res/mac/Synergy.icns diff --git a/src/gui/src/PluginManager.cpp b/src/gui/src/PluginManager.cpp index b32f982c..27224e7e 100644 --- a/src/gui/src/PluginManager.cpp +++ b/src/gui/src/PluginManager.cpp @@ -37,15 +37,9 @@ static const char kLinuxProcessorArchDeb32[] = "Linux-i686-deb"; static const char kLinuxProcessorArchDeb64[] = "Linux-x86_64-deb"; static const char kLinuxProcessorArchRpm32[] = "Linux-i686-rpm"; static const char kLinuxProcessorArchRpm64[] = "Linux-x86_64-rpm"; -static QString kCertificateLifetime = "365"; -static QString kCertificateSubjectInfo = "/CN=Synergy"; -static QString kCertificateFilename = "Synergy.pem"; -static QString kSslDir = "SSL"; -static QString kUnixOpenSslCommand = "openssl"; #if defined(Q_OS_WIN) static const char kWinPluginExt[] = ".dll"; -static const char kWinOpenSslBinary[] = "OpenSSL\\openssl.exe"; #elif defined(Q_OS_MAC) static const char kMacPluginPrefix[] = "lib"; @@ -123,104 +117,6 @@ void PluginManager::downloadPlugins() } } -void PluginManager::generateCertificate() -{ - QString openSslProgramFile; - -#if defined(Q_OS_WIN) - openSslProgramFile = QCoreApplication::applicationDirPath(); - openSslProgramFile.append("\\").append(kWinOpenSslBinary); -#else - openSslProgramFile = kUnixOpenSslCommand; -#endif - - QStringList arguments; - - // self signed certificate - arguments.append("req"); - arguments.append("-x509"); - arguments.append("-nodes"); - - // valide duration - arguments.append("-days"); - arguments.append(kCertificateLifetime); - - // subject information - arguments.append("-subj"); - - QString subInfo(kCertificateSubjectInfo); - arguments.append(subInfo); - - // private key - arguments.append("-newkey"); - arguments.append("rsa:1024"); - - QString sslDirPath = QString("%1%2%3") - .arg(m_ProfileDir) - .arg(QDir::separator()) - .arg(kSslDir); - - QDir sslDir(sslDirPath); - if (!sslDir.exists()) { - sslDir.mkdir("."); - } - - QString filename = QString("%1%2%3") - .arg(sslDirPath) - .arg(QDir::separator()) - .arg(kCertificateFilename); - - // key output filename - arguments.append("-keyout"); - arguments.append(filename); - - // certificate output filename - arguments.append("-out"); - arguments.append(filename); - - QStringList environment; - -#if defined(Q_OS_WIN) - environment << QString("OPENSSL_CONF=%1\\OpenSSL\\synergy.conf") - .arg(QCoreApplication::applicationDirPath()); -#endif - - if (!runProgram(openSslProgramFile, arguments, environment)) { - return; - } - - emit info(tr("SSL certificate generated")); - - // generate fingerprint - arguments.clear(); - arguments.append("x509"); - arguments.append("-fingerprint"); - arguments.append("-sha1"); - arguments.append("-noout"); - arguments.append("-in"); - arguments.append(filename); - - if (!runProgram(openSslProgramFile, arguments, environment)) { - return; - } - - // write the standard output into file - filename.clear(); - filename.append(Fingerprint::local().filePath()); - - // only write the fingerprint part - int i = m_standardOutput.indexOf("="); - if (i != -1) { - i++; - QString fingerprint = m_standardOutput.mid(i, m_standardOutput.size() - i); - - Fingerprint::local().trust(fingerprint, false); - emit info(tr("SSL fingerprint generated")); - } - - emit generateCertificateFinished(); -} - bool PluginManager::savePlugin() { // create the path if not exist @@ -308,47 +204,6 @@ QString PluginManager::getPluginUrl(const QString& pluginName) return result; } -bool PluginManager::checkOpenSslBinary() -{ - // assume OpenSsl is unavailable on Windows, - // but always available on both Mac and Linux -#if defined(Q_OS_WIN) - return false; -#else - return true; -#endif -} - -bool PluginManager::runProgram( - const QString& program, const QStringList& args, const QStringList& env) -{ - QProcess process; - process.setEnvironment(env); - process.start(program, args); - - bool success = process.waitForStarted(); - - QString standardError; - if (success && process.waitForFinished()) - { - m_standardOutput = process.readAllStandardOutput().trimmed(); - standardError = process.readAllStandardError().trimmed(); - } - - int code = process.exitCode(); - if (!success || code != 0) - { - emit error( - QString("Program failed: %1\n\nCode: %2\nError: %3") - .arg(program) - .arg(process.exitCode()) - .arg(standardError.isEmpty() ? "Unknown" : standardError)); - return false; - } - - return true; -} - QString PluginManager::getPluginOsSpecificName(const QString& pluginName) { QString result = pluginName; diff --git a/src/gui/src/PluginManager.h b/src/gui/src/PluginManager.h index bd7fea00..e5a6a33e 100644 --- a/src/gui/src/PluginManager.h +++ b/src/gui/src/PluginManager.h @@ -22,6 +22,7 @@ #include #include +#include "SslCertificate.h" #include "CoreInterface.h" #include "DataDownloader.h" @@ -39,7 +40,6 @@ public: public slots: void downloadPlugins(); - void generateCertificate(); private: bool savePlugin(); @@ -58,7 +58,6 @@ signals: void downloadNext(); void downloadFinished(); void openSslBinaryReady(); - void generateCertificateFinished(); private: QStringList m_PluginList; @@ -68,6 +67,7 @@ private: DataDownloader m_DataDownloader; CoreInterface m_CoreInterface; QString m_standardOutput; + SslCertificate m_SslCertificate; }; #endif // PLUGINMANAGER_H diff --git a/src/gui/src/PluginWizardPage.cpp b/src/gui/src/PluginWizardPage.cpp index 8c0a4d05..9c7e3103 100644 --- a/src/gui/src/PluginWizardPage.cpp +++ b/src/gui/src/PluginWizardPage.cpp @@ -18,6 +18,7 @@ #include "PluginWizardPage.h" #include "ui_PluginWizardPageBase.h" +#include "SslCertificate.h" #include "WebClient.h" #include "PluginManager.h" @@ -29,6 +30,7 @@ PluginWizardPage::PluginWizardPage(AppConfig& appConfig, QWidget *parent) : m_Finished(false), m_pWebClient(NULL), m_pPluginManager(NULL), + m_pSslCertificate(NULL), m_AppConfig(appConfig) { setupUi(this); @@ -36,6 +38,8 @@ PluginWizardPage::PluginWizardPage(AppConfig& appConfig, QWidget *parent) : QMovie *movie = new QMovie(":/res/image/spinning-wheel.gif"); m_pLabelSpinning->setMovie(movie); movie->start(); + + m_pSslCertificate = new SslCertificate(this); } PluginWizardPage::~PluginWizardPage() @@ -47,6 +51,8 @@ PluginWizardPage::~PluginWizardPage() if (m_pPluginManager != NULL) { delete m_pPluginManager; } + + delete m_pSslCertificate; } void PluginWizardPage::changeEvent(QEvent *e) @@ -101,20 +107,20 @@ void PluginWizardPage::finished() void PluginWizardPage::generateCertificate() { - connect(m_pPluginManager, + connect(m_pSslCertificate, SIGNAL(generateCertificateFinished()), this, SLOT(finished())); - connect(m_pPluginManager, + connect(m_pSslCertificate, SIGNAL(generateCertificateFinished()), - m_pPluginManagerThread, + m_pThread, SLOT(quit())); updateStatus(tr("Generating SSL certificate...")); QMetaObject::invokeMethod( - m_pPluginManager, + m_pSslCertificate, "generateCertificate", Qt::QueuedConnection); } @@ -128,7 +134,7 @@ void PluginWizardPage::downloadPlugins() { QStringList pluginList = m_pWebClient->getPluginList(); m_pPluginManager = new PluginManager(pluginList); - m_pPluginManagerThread = new QThread; + m_pThread = new QThread; connect(m_pPluginManager, SIGNAL(error(QString)), @@ -152,12 +158,12 @@ void PluginWizardPage::downloadPlugins() connect(m_pPluginManager, SIGNAL(error(QString)), - m_pPluginManagerThread, + m_pThread, SLOT(quit())); - connect(m_pPluginManagerThread, + connect(m_pThread, SIGNAL(finished()), - m_pPluginManagerThread, + m_pThread, SLOT(deleteLater())); updateStatus( @@ -165,8 +171,8 @@ void PluginWizardPage::downloadPlugins() .arg(pluginList.at(0)) .arg(pluginList.size())); - m_pPluginManager->moveToThread(m_pPluginManagerThread); - m_pPluginManagerThread->start(); + m_pPluginManager->moveToThread(m_pThread); + m_pThread->start(); QMetaObject::invokeMethod( m_pPluginManager, diff --git a/src/gui/src/PluginWizardPage.h b/src/gui/src/PluginWizardPage.h index 0300ebac..b2de1e3b 100644 --- a/src/gui/src/PluginWizardPage.h +++ b/src/gui/src/PluginWizardPage.h @@ -25,6 +25,7 @@ class WebClient; class PluginManager; +class SslCertificate; class PluginWizardPage : public QWizardPage, public Ui::PluginWizardPage { @@ -62,7 +63,8 @@ private: QString m_Password; WebClient* m_pWebClient; PluginManager* m_pPluginManager; - QThread* m_pPluginManagerThread; + SslCertificate* m_pSslCertificate; + QThread* m_pThread; AppConfig& m_AppConfig; }; #endif // PLUGINWIZARDPAGE_H diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp new file mode 100644 index 00000000..08ebd4da --- /dev/null +++ b/src/gui/src/SslCertificate.cpp @@ -0,0 +1,184 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2015 Synergy Si Ltd. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file COPYING that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "SslCertificate.h" + +#include "Fingerprint.h" + +#include +#include +#include + +static const char kCertificateLifetime[] = "365"; +static const char kCertificateSubjectInfo[] = "/CN=Synergy"; +static const char kCertificateFilename[] = "Synergy.pem"; +static const char kSslDir[] = "SSL"; +static const char kUnixOpenSslCommand[] = "openssl"; + +#if defined(Q_OS_WIN) +static const char kWinOpenSslBinary[] = "OpenSSL\\openssl.exe"; +#endif + +SslCertificate::SslCertificate(QObject *parent) : + QObject(parent) +{ + m_ProfileDir = m_CoreInterface.getProfileDir(); + if (m_ProfileDir.isEmpty()) { + emit error(tr("Failed to get profile directory.")); + } +} + +bool SslCertificate::checkOpenSslBinary() +{ + // assume OpenSsl is unavailable on Windows, + // but always available on both Mac and Linux +#if defined(Q_OS_WIN) + return false; +#else + return true; +#endif +} + +bool SslCertificate::runProgram( + const QString& program, + const QStringList& args, + const QStringList& env) +{ + QProcess process; + process.setEnvironment(env); + process.start(program, args); + + bool success = process.waitForStarted(); + + QString standardError; + if (success && process.waitForFinished()) + { + m_standardOutput = process.readAllStandardOutput().trimmed(); + standardError = process.readAllStandardError().trimmed(); + } + + int code = process.exitCode(); + if (!success || code != 0) + { + emit error( + QString("Program failed: %1\n\nCode: %2\nError: %3") + .arg(program) + .arg(process.exitCode()) + .arg(standardError.isEmpty() ? "Unknown" : standardError)); + return false; + } + + return true; +} + +void SslCertificate::generateCertificate() +{ + QString openSslProgramFile; + +#if defined(Q_OS_WIN) + openSslProgramFile = QCoreApplication::applicationDirPath(); + openSslProgramFile.append("\\").append(kWinOpenSslBinary); +#else + openSslProgramFile = kUnixOpenSslCommand; +#endif + + QStringList arguments; + + // self signed certificate + arguments.append("req"); + arguments.append("-x509"); + arguments.append("-nodes"); + + // valide duration + arguments.append("-days"); + arguments.append(kCertificateLifetime); + + // subject information + arguments.append("-subj"); + + QString subInfo(kCertificateSubjectInfo); + arguments.append(subInfo); + + // private key + arguments.append("-newkey"); + arguments.append("rsa:1024"); + + QString sslDirPath = QString("%1%2%3") + .arg(m_ProfileDir) + .arg(QDir::separator()) + .arg(kSslDir); + + QDir sslDir(sslDirPath); + if (!sslDir.exists()) { + sslDir.mkdir("."); + } + + QString filename = QString("%1%2%3") + .arg(sslDirPath) + .arg(QDir::separator()) + .arg(kCertificateFilename); + + // key output filename + arguments.append("-keyout"); + arguments.append(filename); + + // certificate output filename + arguments.append("-out"); + arguments.append(filename); + + QStringList environment; + +#if defined(Q_OS_WIN) + environment << QString("OPENSSL_CONF=%1\\OpenSSL\\synergy.conf") + .arg(QCoreApplication::applicationDirPath()); +#endif + + if (!runProgram(openSslProgramFile, arguments, environment)) { + return; + } + + emit info(tr("SSL certificate generated")); + + // generate fingerprint + arguments.clear(); + arguments.append("x509"); + arguments.append("-fingerprint"); + arguments.append("-sha1"); + arguments.append("-noout"); + arguments.append("-in"); + arguments.append(filename); + + if (!runProgram(openSslProgramFile, arguments, environment)) { + return; + } + + // write the standard output into file + filename.clear(); + filename.append(Fingerprint::local().filePath()); + + // only write the fingerprint part + int i = m_standardOutput.indexOf("="); + if (i != -1) { + i++; + QString fingerprint = m_standardOutput.mid(i, m_standardOutput.size() - i); + + Fingerprint::local().trust(fingerprint, false); + emit info(tr("SSL fingerprint generated")); + } + + emit generateCertificateFinished(); +} diff --git a/src/gui/src/SslCertificate.h b/src/gui/src/SslCertificate.h new file mode 100644 index 00000000..1e6f8214 --- /dev/null +++ b/src/gui/src/SslCertificate.h @@ -0,0 +1,36 @@ +#ifndef SSLCERTIFICATE_H +#define SSLCERTIFICATE_H + +#include "CoreInterface.h" + +#include + +class SslCertificate : public QObject +{ +Q_OBJECT + +public: + explicit SslCertificate(QObject *parent = 0); + +public slots: + void generateCertificate(); + +signals: + void error(QString e); + void info(QString i); + void generateCertificateFinished(); + +private: + bool checkOpenSslBinary(); + bool runProgram( + const QString& program, + const QStringList& args, + const QStringList& env); + +private: + QString m_ProfileDir; + QString m_standardOutput; + CoreInterface m_CoreInterface; +}; + +#endif // SSLCERTIFICATE_H