Fingerprint file check and trust logic #4522
Also refactored the 'get profile dir' code to use the core interface (reduce code duplication)
This commit is contained in:
parent
07b1ea203f
commit
689737ee7a
|
@ -55,7 +55,8 @@ SOURCES += src/main.cpp \
|
|||
src/WebClient.cpp \
|
||||
src/PluginWizardPage.cpp \
|
||||
src/PluginManager.cpp \
|
||||
src/CoreInterface.cpp
|
||||
src/CoreInterface.cpp \
|
||||
src/Fingerprint.cpp
|
||||
HEADERS += src/MainWindow.h \
|
||||
src/AboutDialog.h \
|
||||
src/ServerConfig.h \
|
||||
|
@ -97,7 +98,8 @@ HEADERS += src/MainWindow.h \
|
|||
src/PluginWizardPage.h \
|
||||
src/ProcessorArch.h \
|
||||
src/PluginManager.h \
|
||||
src/CoreInterface.h
|
||||
src/CoreInterface.h \
|
||||
src/Fingerprint.h
|
||||
RESOURCES += res/Synergy.qrc
|
||||
RC_FILE = res/win/Synergy.rc
|
||||
macx {
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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 "Fingerprint.h"
|
||||
|
||||
#include "CoreInterface.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QTextStream>
|
||||
|
||||
static const char kDirName[] = "ssl/fingerprints";
|
||||
static const char kLocalFilename[] = "local.txt";
|
||||
static const char kTrustedServersFilename[] = "trusted-servers.txt";
|
||||
static const char kTrustedClientsFilename[] = "trusted-clients.txt";
|
||||
|
||||
Fingerprint::Fingerprint(const QString& filename)
|
||||
{
|
||||
m_Filename = filename;
|
||||
}
|
||||
|
||||
void Fingerprint::trust(const QString& fingerprintText)
|
||||
{
|
||||
CoreInterface coreInterface;
|
||||
QString profileDir = coreInterface.getProfileDir();
|
||||
|
||||
QString dirName = QString("%1/%2")
|
||||
.arg(profileDir)
|
||||
.arg(kDirName);
|
||||
|
||||
QDir dir(dirName);
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(".");
|
||||
}
|
||||
|
||||
QString path = QString("%1/%2").arg(dirName).arg(m_Filename);
|
||||
QFile file(path);
|
||||
if (file.open(QIODevice::Append))
|
||||
{
|
||||
QTextStream out(&file);
|
||||
out << fingerprintText << "\n";
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
bool Fingerprint::check(const QString& fingerprintText)
|
||||
{
|
||||
CoreInterface coreInterface;
|
||||
QString profileDir = coreInterface.getProfileDir();
|
||||
|
||||
QString dirName = QString("%1/%2")
|
||||
.arg(profileDir)
|
||||
.arg(kDirName);
|
||||
|
||||
if (!QDir(dirName).exists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString path = QString("%1/%2").arg(dirName).arg(m_Filename);
|
||||
QFile file(path);
|
||||
|
||||
if (file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
QTextStream in(&file);
|
||||
while (!in.atEnd())
|
||||
{
|
||||
QString trusted = in.readLine();
|
||||
if (fingerprintText == trusted) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Fingerprint Fingerprint::local()
|
||||
{
|
||||
return Fingerprint(kLocalFilename);
|
||||
}
|
||||
|
||||
Fingerprint Fingerprint::trustedServers()
|
||||
{
|
||||
return Fingerprint(kTrustedServersFilename);
|
||||
}
|
||||
|
||||
Fingerprint Fingerprint::trustedClients()
|
||||
{
|
||||
return Fingerprint(kTrustedClientsFilename);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
class Fingerprint
|
||||
{
|
||||
private:
|
||||
Fingerprint(const QString& filename);
|
||||
|
||||
public:
|
||||
void trust(const QString& fingerprintText);
|
||||
bool check(const QString& fingerprintText);
|
||||
|
||||
public:
|
||||
static Fingerprint local();
|
||||
static Fingerprint trustedServers();
|
||||
static Fingerprint trustedClients();
|
||||
|
||||
private:
|
||||
QString m_Filename;
|
||||
};
|
|
@ -21,6 +21,8 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "MainWindow.h"
|
||||
|
||||
#include "Fingerprint.h"
|
||||
#include "AboutDialog.h"
|
||||
#include "ServerConfigDialog.h"
|
||||
#include "SettingsDialog.h"
|
||||
|
@ -396,32 +398,48 @@ void MainWindow::updateStateFromLogLine(const QString &line)
|
|||
setSynergyState(synergyConnected);
|
||||
}
|
||||
|
||||
checkFingerprint(line);
|
||||
}
|
||||
|
||||
void MainWindow::checkFingerprint(const QString& line)
|
||||
{
|
||||
QRegExp fingerprintRegex(".*server fingerprint: ([A-F0-9:]+)");
|
||||
if (fingerprintRegex.exactMatch(line)) {
|
||||
if (!fingerprintRegex.exactMatch(line)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString fingerprint = fingerprintRegex.cap(1);
|
||||
QMessageBox::StandardButton fingerprintReply =
|
||||
QMessageBox::information(
|
||||
this, tr("Security question"),
|
||||
tr("Do you trust this fingerprint?\n\n"
|
||||
"%1\n\n"
|
||||
"This is a server fingerprint. You should compare this "
|
||||
"fingerprint to the one on your server's screen. If the "
|
||||
"two don't match exactly, then it's probably not the server "
|
||||
"you're expecting (it could be a malicious user).\n\n"
|
||||
"To automatically trust this fingerprint for future "
|
||||
"connections, click Yes. To reject this fingerprint and "
|
||||
"disconnect from the server, click No.")
|
||||
.arg(fingerprint),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
QString fingerprint = fingerprintRegex.cap(1);
|
||||
if (Fingerprint::trustedServers().check(fingerprint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fingerprintReply == QMessageBox::Yes) {
|
||||
// TODO: save to file
|
||||
qDebug() << "fingerprint: " << fingerprint;
|
||||
}
|
||||
else {
|
||||
stopSynergy();
|
||||
}
|
||||
QMessageBox::StandardButton fingerprintReply =
|
||||
QMessageBox::information(
|
||||
this, tr("Security question"),
|
||||
tr("Do you trust this fingerprint?\n\n"
|
||||
"%1\n\n"
|
||||
"This is a server fingerprint. You should compare this "
|
||||
"fingerprint to the one on your server's screen. If the "
|
||||
"two don't match exactly, then it's probably not the server "
|
||||
"you're expecting (it could be a malicious user).\n\n"
|
||||
"To automatically trust this fingerprint for future "
|
||||
"connections, click Yes. To reject this fingerprint and "
|
||||
"disconnect from the server, click No.")
|
||||
.arg(fingerprint),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (fingerprintReply == QMessageBox::Yes) {
|
||||
// restart core process after trusting fingerprint.
|
||||
Fingerprint::trustedServers().trust(fingerprint);
|
||||
startSynergy();
|
||||
}
|
||||
else {
|
||||
// on all platforms, the core process will stop if the
|
||||
// fingerprint is not trusted, so technically the stop
|
||||
// isn't really needed. however on windows, the core
|
||||
// process will keep trying (and failing) unless we
|
||||
// tell it to stop.
|
||||
stopSynergy();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -479,7 +497,11 @@ void MainWindow::startSynergy()
|
|||
}
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
args << "--profile-dir" << getProfileDirectoryForArg();
|
||||
// on windows, the profile directory changes depending on the user that
|
||||
// launched the process (e.g. when launched with elevation). setting the
|
||||
// profile dir on launch ensures it uses the same profile dir is used
|
||||
// no matter how its relaunched.
|
||||
args << "--profile-dir" << getProfileRootForArg();
|
||||
#endif
|
||||
|
||||
if ((synergyType() == synergyClient && !clientArgs(args, app))
|
||||
|
@ -1251,25 +1273,17 @@ void MainWindow::bonjourInstallFinished()
|
|||
m_pCheckBoxAutoConfig->setChecked(true);
|
||||
}
|
||||
|
||||
QString MainWindow::getProfileDirectory()
|
||||
QString MainWindow::getProfileRootForArg()
|
||||
{
|
||||
CoreInterface coreInterface;
|
||||
QString dir = coreInterface.getProfileDir();
|
||||
|
||||
// HACK: strip our app name since we're returning the root dir.
|
||||
#if defined(Q_OS_WIN)
|
||||
|
||||
QString qtDataDir = QDesktopServices::storageLocation(
|
||||
QDesktopServices::DataLocation);
|
||||
|
||||
// HACK: core wants the base app data dir, this seems like a very hacky
|
||||
// way to get it (maybe consider using %LOCALAPPDATA% instead?)
|
||||
return qtDataDir.replace("\\Synergy\\Synergy", "");
|
||||
|
||||
dir.replace("\\Synergy", "");
|
||||
#else
|
||||
|
||||
return "";
|
||||
|
||||
dir.replace("/.synergy", "");
|
||||
#endif
|
||||
}
|
||||
|
||||
QString MainWindow::getProfileDirectoryForArg()
|
||||
{
|
||||
return QString("\"%1\"").arg(getProfileDirectory());
|
||||
return QString("\"%1\"").arg(dir);
|
||||
}
|
||||
|
|
|
@ -165,8 +165,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
|||
void downloadBonjour();
|
||||
void promptAutoConfig();
|
||||
void updateEdition();
|
||||
QString getProfileDirectory();
|
||||
QString getProfileDirectoryForArg();
|
||||
QString getProfileRootForArg();
|
||||
void checkFingerprint(const QString& line);
|
||||
|
||||
private:
|
||||
QSettings& m_Settings;
|
||||
|
|
Loading…
Reference in New Issue