Moved SSL generate code as is into new class #4549

This commit is contained in:
Nick Bolton 2015-04-20 18:51:22 +01:00
parent 2a2d095527
commit f997aea8e7
7 changed files with 246 additions and 161 deletions

View File

@ -56,7 +56,8 @@ SOURCES += src/main.cpp \
src/PluginWizardPage.cpp \ src/PluginWizardPage.cpp \
src/PluginManager.cpp \ src/PluginManager.cpp \
src/CoreInterface.cpp \ src/CoreInterface.cpp \
src/Fingerprint.cpp src/Fingerprint.cpp \
src/SslCertificate.cpp
HEADERS += src/MainWindow.h \ HEADERS += src/MainWindow.h \
src/AboutDialog.h \ src/AboutDialog.h \
src/ServerConfig.h \ src/ServerConfig.h \
@ -99,7 +100,8 @@ HEADERS += src/MainWindow.h \
src/ProcessorArch.h \ src/ProcessorArch.h \
src/PluginManager.h \ src/PluginManager.h \
src/CoreInterface.h \ src/CoreInterface.h \
src/Fingerprint.h src/Fingerprint.h \
src/SslCertificate.h
RESOURCES += res/Synergy.qrc RESOURCES += res/Synergy.qrc
RC_FILE = res/win/Synergy.rc RC_FILE = res/win/Synergy.rc
macx { macx {

View File

@ -37,15 +37,9 @@ static const char kLinuxProcessorArchDeb32[] = "Linux-i686-deb";
static const char kLinuxProcessorArchDeb64[] = "Linux-x86_64-deb"; static const char kLinuxProcessorArchDeb64[] = "Linux-x86_64-deb";
static const char kLinuxProcessorArchRpm32[] = "Linux-i686-rpm"; static const char kLinuxProcessorArchRpm32[] = "Linux-i686-rpm";
static const char kLinuxProcessorArchRpm64[] = "Linux-x86_64-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) #if defined(Q_OS_WIN)
static const char kWinPluginExt[] = ".dll"; static const char kWinPluginExt[] = ".dll";
static const char kWinOpenSslBinary[] = "OpenSSL\\openssl.exe";
#elif defined(Q_OS_MAC) #elif defined(Q_OS_MAC)
static const char kMacPluginPrefix[] = "lib"; 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() bool PluginManager::savePlugin()
{ {
// create the path if not exist // create the path if not exist
@ -308,47 +204,6 @@ QString PluginManager::getPluginUrl(const QString& pluginName)
return result; 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 PluginManager::getPluginOsSpecificName(const QString& pluginName)
{ {
QString result = pluginName; QString result = pluginName;

View File

@ -22,6 +22,7 @@
#include <QStringList> #include <QStringList>
#include <QObject> #include <QObject>
#include "SslCertificate.h"
#include "CoreInterface.h" #include "CoreInterface.h"
#include "DataDownloader.h" #include "DataDownloader.h"
@ -39,7 +40,6 @@ public:
public slots: public slots:
void downloadPlugins(); void downloadPlugins();
void generateCertificate();
private: private:
bool savePlugin(); bool savePlugin();
@ -58,7 +58,6 @@ signals:
void downloadNext(); void downloadNext();
void downloadFinished(); void downloadFinished();
void openSslBinaryReady(); void openSslBinaryReady();
void generateCertificateFinished();
private: private:
QStringList m_PluginList; QStringList m_PluginList;
@ -68,6 +67,7 @@ private:
DataDownloader m_DataDownloader; DataDownloader m_DataDownloader;
CoreInterface m_CoreInterface; CoreInterface m_CoreInterface;
QString m_standardOutput; QString m_standardOutput;
SslCertificate m_SslCertificate;
}; };
#endif // PLUGINMANAGER_H #endif // PLUGINMANAGER_H

View File

@ -18,6 +18,7 @@
#include "PluginWizardPage.h" #include "PluginWizardPage.h"
#include "ui_PluginWizardPageBase.h" #include "ui_PluginWizardPageBase.h"
#include "SslCertificate.h"
#include "WebClient.h" #include "WebClient.h"
#include "PluginManager.h" #include "PluginManager.h"
@ -29,6 +30,7 @@ PluginWizardPage::PluginWizardPage(AppConfig& appConfig, QWidget *parent) :
m_Finished(false), m_Finished(false),
m_pWebClient(NULL), m_pWebClient(NULL),
m_pPluginManager(NULL), m_pPluginManager(NULL),
m_pSslCertificate(NULL),
m_AppConfig(appConfig) m_AppConfig(appConfig)
{ {
setupUi(this); setupUi(this);
@ -36,6 +38,8 @@ PluginWizardPage::PluginWizardPage(AppConfig& appConfig, QWidget *parent) :
QMovie *movie = new QMovie(":/res/image/spinning-wheel.gif"); QMovie *movie = new QMovie(":/res/image/spinning-wheel.gif");
m_pLabelSpinning->setMovie(movie); m_pLabelSpinning->setMovie(movie);
movie->start(); movie->start();
m_pSslCertificate = new SslCertificate(this);
} }
PluginWizardPage::~PluginWizardPage() PluginWizardPage::~PluginWizardPage()
@ -47,6 +51,8 @@ PluginWizardPage::~PluginWizardPage()
if (m_pPluginManager != NULL) { if (m_pPluginManager != NULL) {
delete m_pPluginManager; delete m_pPluginManager;
} }
delete m_pSslCertificate;
} }
void PluginWizardPage::changeEvent(QEvent *e) void PluginWizardPage::changeEvent(QEvent *e)
@ -101,20 +107,20 @@ void PluginWizardPage::finished()
void PluginWizardPage::generateCertificate() void PluginWizardPage::generateCertificate()
{ {
connect(m_pPluginManager, connect(m_pSslCertificate,
SIGNAL(generateCertificateFinished()), SIGNAL(generateCertificateFinished()),
this, this,
SLOT(finished())); SLOT(finished()));
connect(m_pPluginManager, connect(m_pSslCertificate,
SIGNAL(generateCertificateFinished()), SIGNAL(generateCertificateFinished()),
m_pPluginManagerThread, m_pThread,
SLOT(quit())); SLOT(quit()));
updateStatus(tr("Generating SSL certificate...")); updateStatus(tr("Generating SSL certificate..."));
QMetaObject::invokeMethod( QMetaObject::invokeMethod(
m_pPluginManager, m_pSslCertificate,
"generateCertificate", "generateCertificate",
Qt::QueuedConnection); Qt::QueuedConnection);
} }
@ -128,7 +134,7 @@ void PluginWizardPage::downloadPlugins()
{ {
QStringList pluginList = m_pWebClient->getPluginList(); QStringList pluginList = m_pWebClient->getPluginList();
m_pPluginManager = new PluginManager(pluginList); m_pPluginManager = new PluginManager(pluginList);
m_pPluginManagerThread = new QThread; m_pThread = new QThread;
connect(m_pPluginManager, connect(m_pPluginManager,
SIGNAL(error(QString)), SIGNAL(error(QString)),
@ -152,12 +158,12 @@ void PluginWizardPage::downloadPlugins()
connect(m_pPluginManager, connect(m_pPluginManager,
SIGNAL(error(QString)), SIGNAL(error(QString)),
m_pPluginManagerThread, m_pThread,
SLOT(quit())); SLOT(quit()));
connect(m_pPluginManagerThread, connect(m_pThread,
SIGNAL(finished()), SIGNAL(finished()),
m_pPluginManagerThread, m_pThread,
SLOT(deleteLater())); SLOT(deleteLater()));
updateStatus( updateStatus(
@ -165,8 +171,8 @@ void PluginWizardPage::downloadPlugins()
.arg(pluginList.at(0)) .arg(pluginList.at(0))
.arg(pluginList.size())); .arg(pluginList.size()));
m_pPluginManager->moveToThread(m_pPluginManagerThread); m_pPluginManager->moveToThread(m_pThread);
m_pPluginManagerThread->start(); m_pThread->start();
QMetaObject::invokeMethod( QMetaObject::invokeMethod(
m_pPluginManager, m_pPluginManager,

View File

@ -25,6 +25,7 @@
class WebClient; class WebClient;
class PluginManager; class PluginManager;
class SslCertificate;
class PluginWizardPage : public QWizardPage, public Ui::PluginWizardPage { class PluginWizardPage : public QWizardPage, public Ui::PluginWizardPage {
@ -62,7 +63,8 @@ private:
QString m_Password; QString m_Password;
WebClient* m_pWebClient; WebClient* m_pWebClient;
PluginManager* m_pPluginManager; PluginManager* m_pPluginManager;
QThread* m_pPluginManagerThread; SslCertificate* m_pSslCertificate;
QThread* m_pThread;
AppConfig& m_AppConfig; AppConfig& m_AppConfig;
}; };
#endif // PLUGINWIZARDPAGE_H #endif // PLUGINWIZARDPAGE_H

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "SslCertificate.h"
#include "Fingerprint.h"
#include <QProcess>
#include <QDir>
#include <QCoreApplication>
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();
}

View File

@ -0,0 +1,36 @@
#ifndef SSLCERTIFICATE_H
#define SSLCERTIFICATE_H
#include "CoreInterface.h"
#include <QObject>
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