diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index 527e7116..920f8472 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -63,7 +63,8 @@ HEADERS += src/MainWindow.h \
src/SetupWizard.h \
src/IpcClient.h \
src/IpcReader.h \
- src/Ipc.h
+ src/Ipc.h \
+ src/CryptoMode.h
RESOURCES += res/Synergy.qrc
RC_FILE = res/win/Synergy.rc
TRANSLATIONS = res/lang/nl_NL.ts
diff --git a/src/gui/res/SettingsDialogBase.ui b/src/gui/res/SettingsDialogBase.ui
index 0fc6f436..b58bfbd0 100644
--- a/src/gui/res/SettingsDialogBase.ui
+++ b/src/gui/res/SettingsDialogBase.ui
@@ -6,22 +6,144 @@
0
0
- 383
- 387
+ 369
+ 459
Settings
-
- -
+
+
-
+
+
+ &Startup
+
+
+
-
+
+
+ &Start Synergy after logging in
+
+
+
+ -
+
+
+ &Automatically start server/client
+
+
+
+ -
+
+
+ &Hide when server/client starts
+
+
+
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+ &Encryption
+
+
+
+ QFormLayout::AllNonFixedFieldsGrow
+
+
-
+
+
+
+ 75
+ 0
+
+
+
+ &Mode:
+
+
+ m_pComboCryptoMode
+
+
+
+ -
+
+
-
+
+ OFB (Output Feedback)
+
+
+ -
+
+ CFB (Cipher Feedback)
+
+
+ -
+
+ CTR (Counter)
+
+
+ -
+
+ GCM (Galois/Counter)
+
+
+ -
+
+ Disable encryption
+
+
+
+
+ -
+
+
+ Pass&word:
+
+
+ m_pLineEditCryptoPass
+
+
+
+ -
+
+
+ true
+
+
+ QLineEdit::Password
+
+
+
+
+
+
+ -
&Advanced
-
+
-
+
+
+ 75
+ 0
+
+
Sc&reen name:
@@ -30,7 +152,7 @@
- -
+
-
true
@@ -47,24 +169,7 @@
- -
-
-
- &Interface:
-
-
- m_pLineEditInterface
-
-
-
- -
-
-
- true
-
-
-
- -
+
-
true
@@ -83,17 +188,34 @@
- -
-
+
-
+
- &Process mode:
+ &Interface:
m_pLineEditInterface
- -
+
-
+
+
+ true
+
+
+
+ -
+
+
+ &Process mode:
+
+
+ m_pComboProcessMode
+
+
+
+ -
-
@@ -110,24 +232,32 @@
- -
-
-
- Qt::Horizontal
-
-
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
-
-
-
- -
+
-
+
+
+ 0
+ 0
+
+
Logging
-
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ false
+
+
-
+
+
+ 75
+ 0
+
+
&Logging level:
@@ -136,31 +266,7 @@
- -
-
-
- Log to file:
-
-
-
- -
-
-
- false
-
-
-
- -
-
-
- false
-
-
- Browse...
-
-
-
- -
+
-
-
@@ -199,40 +305,34 @@
-
-
-
- -
-
-
- &Startup
-
-
-
-
-
+
-
+
- &Start Synergy after logging in
+ Log to file:
- -
-
-
- &Automatically start server/client
+
-
+
+
+ false
- -
-
+
-
+
+
+ false
+
- &Hide when server/client starts
+ Browse...
- -
+
-
Qt::Vertical
@@ -245,6 +345,16 @@
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
@@ -254,7 +364,6 @@
m_pComboLogLevel
m_pCheckBoxLogToFile
m_pLineEditLogFilename
- m_pButtonBrowseLog
buttonBox
diff --git a/src/gui/res/SetupWizardBase.ui b/src/gui/res/SetupWizardBase.ui
index 8b98e791..928fcc39 100644
--- a/src/gui/res/SetupWizardBase.ui
+++ b/src/gui/res/SetupWizardBase.ui
@@ -125,6 +125,310 @@
+
+
+
+ 0
+ 0
+
+
+
+ Encryption
+
+
+ -
+
+
+ Network traffic can be easily monitored. Using encryption can reduce the risk that sensitive information will be revealed to others (for example, passwords).
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
+ Choose a random encryption mode. The mode must be the same on both the client and server.
+
+
+ true
+
+
+
+ -
+
+
+ QFormLayout::ExpandingFieldsGrow
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 100
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 75
+ true
+
+
+
+ &Mode:
+
+
+ 10
+
+
+ m_pComboCryptoMode
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 0
+
+
+
-
+
+
+
+
+ -
+
+ OFB (Output Feedback)
+
+
+ -
+
+ CFB (Cipher Feedback)
+
+
+ -
+
+ CTR (Counter)
+
+
+ -
+
+ GCM (Galois/Counter)
+
+
+ -
+
+ Disable encryption
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 10
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">A longer password will provide stronger encryption. It is a good idea to use 20 characters or more.</span></p></body></html>
+
+
+ true
+
+
+
+ -
+
+
-
+
+
+
+ 100
+ 0
+
+
+
+
+ 75
+ true
+
+
+
+ &Password:
+
+
+ 10
+
+
+ m_pLineEditCryptoPass
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+ QLineEdit::Password
+
+
+
+ -
+
+
+
+ 100
+ 0
+
+
+
+
+ 75
+ true
+
+
+
+ &Confirm:
+
+
+ 10
+
+
+ m_pLineEditCryptoPassConfirm
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 0
+
+
+
+ QLineEdit::Password
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 100
+
+
+
+
+
+
diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp
index 076c789f..ba3c1de9 100644
--- a/src/gui/src/AppConfig.cpp
+++ b/src/gui/src/AppConfig.cpp
@@ -54,7 +54,9 @@ AppConfig::AppConfig(QSettings* settings) :
m_AutoStart(false),
m_AutoHide(false),
m_AutoStartPrompt(false),
- m_WizardHasRun(false),
+ m_WizardLastRun(0),
+ m_CryptoPass(),
+ m_CryptoMode(),
m_ProcessMode(DEFAULT_PROCESS_MODE)
{
Q_ASSERT(m_pSettings);
@@ -154,8 +156,10 @@ void AppConfig::loadSettings()
m_AutoStart = settings().value("autoStart", false).toBool();
m_AutoHide = settings().value("autoHide", true).toBool();
m_AutoStartPrompt = settings().value("autoStartPrompt", true).toBool();
- m_WizardHasRun = settings().value("wizardHasRun", false).toBool();
+ m_WizardLastRun = settings().value("wizardLastRun", 0).toInt();
m_ProcessMode = (ProcessMode)settings().value("processMode2", DEFAULT_PROCESS_MODE).toInt();
+ m_CryptoPass = settings().value("cryptoPass", "").toString();
+ m_CryptoMode = (CryptoMode)settings().value("cryptoMode", Disabled).toInt();
}
void AppConfig::saveSettings()
@@ -170,6 +174,53 @@ void AppConfig::saveSettings()
settings().setValue("autoStart", m_AutoStart);
settings().setValue("autoHide", m_AutoHide);
settings().setValue("autoStartPrompt", m_AutoStartPrompt);
- settings().setValue("wizardHasRun", m_WizardHasRun);
+ settings().setValue("wizardLastRun", kWizardVersion);
settings().setValue("processMode2", m_ProcessMode);
+ settings().setValue("cryptoPass", m_CryptoPass);
+ settings().setValue("cryptoMode", m_CryptoMode);
+}
+
+QString AppConfig::hash(const QString& string)
+{
+ QByteArray data = string.toUtf8();
+ QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5);
+ return hash.toHex();
+}
+
+void AppConfig::setCryptoPass(const QString &s)
+{
+ // clear field to user doesn't get confused.
+ if (s.isEmpty())
+ {
+ m_CryptoPass.clear();
+ return;
+ }
+
+ // only hash if password changes -- don't re-hash the hash.
+ if (m_CryptoPass != s)
+ {
+ m_CryptoPass = hash(s);
+ }
+}
+
+QString AppConfig::cryptoModeString() const
+{
+ switch (cryptoMode())
+ {
+ case OFB:
+ return "ofb";
+
+ case CFB:
+ return "cfb";
+
+ case CTR:
+ return "ctr";
+
+ case GCM:
+ return "gcm";
+
+ default:
+ qCritical() << "invalid crypto mode";
+ return "";
+ }
}
diff --git a/src/gui/src/AppConfig.h b/src/gui/src/AppConfig.h
index ddce9706..65ab1d9b 100644
--- a/src/gui/src/AppConfig.h
+++ b/src/gui/src/AppConfig.h
@@ -21,6 +21,13 @@
#define APPCONFIG_H
#include
+#include "CryptoMode.h"
+
+// this should be incremented each time a new page is added. this is
+// saved to settings when the user finishes running the wizard. if
+// the saved wizard version is lower than this number, the wizard
+// will be displayed.
+const int kWizardVersion = 1;
class QSettings;
class SettingsDialog;
@@ -52,8 +59,11 @@ class AppConfig
bool autoStart() const { return m_AutoStart; }
bool autoHide() const { return m_AutoHide; }
bool autoStartPrompt() const { return m_AutoStartPrompt; }
- bool wizardHasRun() const { return m_WizardHasRun; }
+ const QString& cryptoPass() const { return m_CryptoPass; }
+ CryptoMode cryptoMode() const { return m_CryptoMode; }
+ QString cryptoModeString() const;
ProcessMode processMode() const { return m_ProcessMode; }
+ bool wizardShouldRun() const { return m_WizardLastRun < kWizardVersion; }
QString synergysName() const { return m_SynergysName; }
QString synergycName() const { return m_SynergycName; }
@@ -75,12 +85,16 @@ class AppConfig
void setAutoStart(bool b);
void setAutoHide(bool b) { m_AutoHide = b; }
void setAutoStartPrompt(bool b) { m_AutoStartPrompt = b; }
- void setWizardHasRun(bool b) { m_WizardHasRun = b; }
+ void setCryptoMode(CryptoMode c) { m_CryptoMode = c; }
void setProcessMode(ProcessMode p) { m_ProcessMode = p; }
+ void setWizardHasRun() { m_WizardLastRun = kWizardVersion; }
void loadSettings();
void saveSettings();
+ void setCryptoPass(const QString& s);
+ static QString hash(const QString& string);
+
private:
QSettings* m_pSettings;
bool m_AutoConnect;
@@ -93,7 +107,9 @@ class AppConfig
bool m_AutoStart;
bool m_AutoHide;
bool m_AutoStartPrompt;
- bool m_WizardHasRun;
+ int m_WizardLastRun;
+ QString m_CryptoPass;
+ CryptoMode m_CryptoMode;
ProcessMode m_ProcessMode;
static const char m_SynergysName[];
diff --git a/src/gui/src/CryptoMode.h b/src/gui/src/CryptoMode.h
new file mode 100644
index 00000000..5db9964c
--- /dev/null
+++ b/src/gui/src/CryptoMode.h
@@ -0,0 +1,26 @@
+/*
+ * synergy -- mouse and keyboard sharing utility
+ * Copyright (C) 2013 Bolton Software 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 .
+ */
+
+#pragma once
+
+enum CryptoMode {
+ Disabled,
+ OFB,
+ CFB,
+ CTR,
+ GCM
+};
diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp
index 64b333c4..b9343006 100644
--- a/src/gui/src/MainWindow.cpp
+++ b/src/gui/src/MainWindow.cpp
@@ -380,6 +380,12 @@ void MainWindow::startSynergy()
if (!appConfig().screenName().isEmpty())
args << "--name" << appConfig().screenName();
+ if (appConfig().cryptoMode() != Disabled)
+ {
+ args << "--crypto-mode" << appConfig().cryptoModeString();
+ args << "--crypto-pass" << appConfig().cryptoPass();
+ }
+
if (desktopMode)
{
setSynergyProcess(new QProcess(this));
diff --git a/src/gui/src/SettingsDialog.cpp b/src/gui/src/SettingsDialog.cpp
index fc425c95..5ec01122 100644
--- a/src/gui/src/SettingsDialog.cpp
+++ b/src/gui/src/SettingsDialog.cpp
@@ -20,6 +20,7 @@
#include
#include
+#include
#include "AppConfig.h"
@@ -40,10 +41,24 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
m_pLineEditLogFilename->setText(appConfig().logFilename());
m_pCheckBoxAutoStart->setChecked(appConfig().autoStart());
m_pCheckBoxAutoHide->setChecked(appConfig().autoHide());
+ m_pComboCryptoMode->setCurrentIndex(getCryptoModeIndex(appConfig().cryptoMode()));
+ m_pLineEditCryptoPass->setText(appConfig().cryptoPass());
}
void SettingsDialog::accept()
{
+ const QString& cryptoPass = m_pLineEditCryptoPass->text();
+ CryptoMode cryptoMode = parseCryptoMode(m_pComboCryptoMode->currentText());
+ if ((cryptoMode != Disabled) && cryptoPass.isEmpty())
+ {
+ QMessageBox message;
+ message.setWindowTitle("Settings");
+ message.setIcon(QMessageBox::Information);
+ message.setText(tr("Encryption password must not be empty."));
+ message.exec();
+ return;
+ }
+
appConfig().setAutoConnect(m_pCheckBoxAutoConnect->isChecked());
appConfig().setScreenName(m_pLineEditScreenName->text());
appConfig().setPort(m_pSpinBoxPort->value());
@@ -54,7 +69,9 @@ void SettingsDialog::accept()
appConfig().setLogFilename(m_pLineEditLogFilename->text());
appConfig().setAutoStart(m_pCheckBoxAutoStart->isChecked());
appConfig().setAutoHide(m_pCheckBoxAutoHide->isChecked());
-
+ appConfig().setCryptoMode(cryptoMode);
+ appConfig().setCryptoPass(cryptoPass);
+ appConfig().saveSettings();
QDialog::accept();
}
@@ -78,3 +95,56 @@ void SettingsDialog::on_m_pButtonBrowseLog_clicked()
m_pLineEditLogFilename->setText(fileName);
}
}
+
+void SettingsDialog::on_m_pComboCryptoMode_currentIndexChanged(int index)
+{
+ bool enabled = parseCryptoMode(m_pComboCryptoMode->currentText()) != Disabled;
+ m_pLineEditCryptoPass->setEnabled(enabled);
+ if (!enabled)
+ {
+ m_pLineEditCryptoPass->clear();
+ }
+}
+
+int SettingsDialog::getCryptoModeIndex(const CryptoMode& mode) const
+{
+ switch (mode)
+ {
+ case OFB:
+ return m_pComboCryptoMode->findText("OFB", Qt::MatchStartsWith);
+
+ case CFB:
+ return m_pComboCryptoMode->findText("CFB", Qt::MatchStartsWith);
+
+ case CTR:
+ return m_pComboCryptoMode->findText("CTR", Qt::MatchStartsWith);
+
+ case GCM:
+ return m_pComboCryptoMode->findText("GCM", Qt::MatchStartsWith);
+
+ default:
+ return m_pComboCryptoMode->findText("Disable", Qt::MatchStartsWith);
+ }
+}
+
+CryptoMode SettingsDialog::parseCryptoMode(const QString& s)
+{
+ if (s.startsWith("OFB"))
+ {
+ return OFB;
+ }
+ else if (s.startsWith("CFB"))
+ {
+ return CFB;
+ }
+ else if (s.startsWith("CTR"))
+ {
+ return CTR;
+ }
+ else if (s.startsWith("GCM"))
+ {
+ return GCM;
+ }
+
+ return Disabled;
+}
diff --git a/src/gui/src/SettingsDialog.h b/src/gui/src/SettingsDialog.h
index 603328b2..ab67ca98 100644
--- a/src/gui/src/SettingsDialog.h
+++ b/src/gui/src/SettingsDialog.h
@@ -22,6 +22,7 @@
#include
#include "ui_SettingsDialogBase.h"
+#include "CryptoMode.h"
class AppConfig;
@@ -39,9 +40,12 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
AppConfig& appConfig() { return m_AppConfig; }
private:
+ int getCryptoModeIndex(const CryptoMode& mode) const;
+ CryptoMode parseCryptoMode(const QString& s);
AppConfig& m_AppConfig;
private slots:
+ void on_m_pComboCryptoMode_currentIndexChanged(int index);
void on_m_pCheckBoxLogToFile_stateChanged(int );
void on_m_pButtonBrowseLog_clicked();
};
diff --git a/src/gui/src/SetupWizard.cpp b/src/gui/src/SetupWizard.cpp
index e82b6b54..98e91c1f 100644
--- a/src/gui/src/SetupWizard.cpp
+++ b/src/gui/src/SetupWizard.cpp
@@ -45,7 +45,7 @@ SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) :
#endif
- connect(this, SIGNAL(finished(int)), this, SLOT(handlefinished()));
+ connect(this, SIGNAL(finished(int)), this, SLOT(handleFinished()));
connect(m_pServerRadioButton, SIGNAL(toggled(bool)), m_MainWindow.m_pGroupServer, SLOT(setChecked(bool)));
connect(m_pClientRadioButton, SIGNAL(toggled(bool)), m_MainWindow.m_pGroupClient, SLOT(setChecked(bool)));
}
@@ -60,28 +60,59 @@ bool SetupWizard::validateCurrentPage()
message.setWindowTitle(tr("Setup Synergy"));
message.setIcon(QMessageBox::Information);
- bool result = false;
if (currentPage() == m_pNodePage)
{
- result = m_pClientRadioButton->isChecked() ||
+ bool result = m_pClientRadioButton->isChecked() ||
m_pServerRadioButton->isChecked();
if (!result)
{
message.setText(tr("Please select an option."));
message.exec();
+ return false;
}
}
- return result;
+ else if (currentPage() == m_pCryptoPage)
+ {
+ QString modeText = m_pComboCryptoMode->currentText();
+ if (modeText.isEmpty())
+ {
+ message.setText(tr("Encryption mode required."));
+ message.exec();
+ return false;
+ }
+
+ if (parseCryptoMode(modeText) != Disabled)
+ {
+ if (m_pLineEditCryptoPass->text().isEmpty())
+ {
+ message.setText(tr("Encryption password required."));
+ message.exec();
+ return false;
+ }
+
+ if (m_pLineEditCryptoPass->text() != m_pLineEditCryptoPassConfirm->text())
+ {
+ message.setText(tr("Encryption password and confirmation do not match."));
+ message.exec();
+ return false;
+ }
+ }
+ }
+
+ return true;
}
-void SetupWizard::handlefinished()
+void SetupWizard::handleFinished()
{
close();
AppConfig& appConfig = m_MainWindow.appConfig();
- appConfig.setWizardHasRun(true);
+ appConfig.setCryptoMode(parseCryptoMode(m_pComboCryptoMode->currentText()));
+ appConfig.setCryptoPass(m_pLineEditCryptoPass->text());
+
+ appConfig.setWizardHasRun();
appConfig.saveSettings();
QSettings& settings = m_MainWindow.settings();
@@ -95,6 +126,7 @@ void SetupWizard::handlefinished()
settings.setValue("groupClientChecked", true);
settings.setValue("groupServerChecked", false);
}
+
settings.sync();
if (m_StartMain)
@@ -102,3 +134,32 @@ void SetupWizard::handlefinished()
m_MainWindow.start(true);
}
}
+
+void SetupWizard::on_m_pComboCryptoMode_currentIndexChanged(int index)
+{
+ bool enabled = parseCryptoMode(m_pComboCryptoMode->currentText()) != Disabled;
+ m_pLineEditCryptoPass->setEnabled(enabled);
+ m_pLineEditCryptoPassConfirm->setEnabled(enabled);
+}
+
+CryptoMode SetupWizard::parseCryptoMode(const QString& s)
+{
+ if (s.startsWith("OFB"))
+ {
+ return OFB;
+ }
+ else if (s.startsWith("CFB"))
+ {
+ return CFB;
+ }
+ else if (s.startsWith("CTR"))
+ {
+ return CTR;
+ }
+ else if (s.startsWith("GCM"))
+ {
+ return GCM;
+ }
+
+ return Disabled;
+}
diff --git a/src/gui/src/SetupWizard.h b/src/gui/src/SetupWizard.h
index d2d8953d..6c0c79c8 100644
--- a/src/gui/src/SetupWizard.h
+++ b/src/gui/src/SetupWizard.h
@@ -18,8 +18,8 @@
#pragma once
#include
-
#include "ui_SetupWizardBase.h"
+#include "CryptoMode.h"
class MainWindow;
@@ -31,8 +31,11 @@ public:
virtual ~SetupWizard();
bool validateCurrentPage();
protected slots:
- void handlefinished();
+ void handleFinished();
private:
MainWindow& m_MainWindow;
bool m_StartMain;
+ CryptoMode parseCryptoMode(const QString& s);
+private slots:
+ void on_m_pComboCryptoMode_currentIndexChanged(int index);
};
diff --git a/src/gui/src/main.cpp b/src/gui/src/main.cpp
index 66bba88d..ee9bcb67 100644
--- a/src/gui/src/main.cpp
+++ b/src/gui/src/main.cpp
@@ -66,13 +66,13 @@ int main(int argc, char* argv[])
MainWindow mainWindow(settings, appConfig);
SetupWizard setupWizard(mainWindow, true);
- if (appConfig.wizardHasRun())
+ if (appConfig.wizardShouldRun())
{
- mainWindow.start(false);
+ setupWizard.show();
}
else
{
- setupWizard.show();
+ mainWindow.start(false);
}
return app.exec();