gui: Use new FingerprintDatabase to handle fingerprints
This commit is contained in:
parent
9cac96b4af
commit
be8ba0d132
|
@ -29,7 +29,6 @@ set(GUI_SOURCE_FILES
|
||||||
src/CommandProcess.cpp
|
src/CommandProcess.cpp
|
||||||
src/DataDownloader.cpp
|
src/DataDownloader.cpp
|
||||||
src/DisplayIsValid.cpp
|
src/DisplayIsValid.cpp
|
||||||
src/Fingerprint.cpp
|
|
||||||
src/HotkeyDialog.cpp
|
src/HotkeyDialog.cpp
|
||||||
src/IpcClient.cpp
|
src/IpcClient.cpp
|
||||||
src/Ipc.cpp
|
src/Ipc.cpp
|
||||||
|
@ -70,7 +69,6 @@ set(GUI_HEADER_FILES
|
||||||
src/DataDownloader.h
|
src/DataDownloader.h
|
||||||
src/DisplayIsValid.h
|
src/DisplayIsValid.h
|
||||||
src/ElevateMode.h
|
src/ElevateMode.h
|
||||||
src/Fingerprint.h
|
|
||||||
src/HotkeyDialog.h
|
src/HotkeyDialog.h
|
||||||
src/IpcClient.h
|
src/IpcClient.h
|
||||||
src/Ipc.h
|
src/Ipc.h
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015-2016 Symless 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 LICENSE 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 "common/DataDirectories.h"
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QTextStream>
|
|
||||||
|
|
||||||
static const char kDirName[] = "SSL/Fingerprints";
|
|
||||||
static const char kLocalFilename[] = "Local.txt";
|
|
||||||
static const char kTrustedServersFilename[] = "TrustedServers.txt";
|
|
||||||
static const char kTrustedClientsFilename[] = "TrustedClients.txt";
|
|
||||||
|
|
||||||
Fingerprint::Fingerprint(const QString& filename)
|
|
||||||
{
|
|
||||||
m_Filename = filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Fingerprint::trust(const QString& fingerprintText, bool append)
|
|
||||||
{
|
|
||||||
Fingerprint::persistDirectory();
|
|
||||||
|
|
||||||
QIODevice::OpenMode openMode;
|
|
||||||
if (append) {
|
|
||||||
openMode = QIODevice::Append;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
openMode = QIODevice::WriteOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile file(filePath());
|
|
||||||
if (file.open(openMode))
|
|
||||||
{
|
|
||||||
QTextStream out(&file);
|
|
||||||
out << fingerprintText << "\n";
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Fingerprint::fileExists() const
|
|
||||||
{
|
|
||||||
QString dirName = Fingerprint::directoryPath();
|
|
||||||
if (!QDir(dirName).exists()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile file(filePath());
|
|
||||||
return file.exists();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Fingerprint::isTrusted(const QString& fingerprintText)
|
|
||||||
{
|
|
||||||
QStringList list = readList();
|
|
||||||
for (QString trusted : list) {
|
|
||||||
if (trusted == fingerprintText) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList Fingerprint::readList(const int readTo)
|
|
||||||
{
|
|
||||||
QStringList list;
|
|
||||||
|
|
||||||
QString dirName = Fingerprint::directoryPath();
|
|
||||||
if (!QDir(dirName).exists()) {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile file(filePath());
|
|
||||||
|
|
||||||
if (file.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
QTextStream in(&file);
|
|
||||||
while (!in.atEnd())
|
|
||||||
{
|
|
||||||
list.append(in.readLine());
|
|
||||||
if (list.size() == readTo) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Fingerprint::readFirst()
|
|
||||||
{
|
|
||||||
QStringList list = readList(1);
|
|
||||||
return list.at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Fingerprint::filePath() const
|
|
||||||
{
|
|
||||||
QString dir = Fingerprint::directoryPath();
|
|
||||||
return QString("%1/%2").arg(dir).arg(m_Filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Fingerprint::persistDirectory()
|
|
||||||
{
|
|
||||||
QDir dir(Fingerprint::directoryPath());
|
|
||||||
if (!dir.exists()) {
|
|
||||||
dir.mkpath(".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Fingerprint::directoryPath()
|
|
||||||
{
|
|
||||||
auto profileDir = QString::fromStdString(DataDirectories::profile());
|
|
||||||
|
|
||||||
return QString("%1/%2")
|
|
||||||
.arg(profileDir)
|
|
||||||
.arg(kDirName);
|
|
||||||
}
|
|
||||||
|
|
||||||
Fingerprint Fingerprint::local()
|
|
||||||
{
|
|
||||||
return Fingerprint(kLocalFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
Fingerprint Fingerprint::trustedServers()
|
|
||||||
{
|
|
||||||
return Fingerprint(kTrustedServersFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
Fingerprint Fingerprint::trustedClients()
|
|
||||||
{
|
|
||||||
return Fingerprint(kTrustedClientsFilename);
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015-2016 Symless 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 LICENSE 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
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void trust(const QString& fingerprintText, bool append = true);
|
|
||||||
bool isTrusted(const QString& fingerprintText);
|
|
||||||
QStringList readList(const int readTo = -1);
|
|
||||||
QString readFirst();
|
|
||||||
QString filePath() const;
|
|
||||||
bool fileExists() const;
|
|
||||||
|
|
||||||
static Fingerprint local();
|
|
||||||
static Fingerprint trustedServers();
|
|
||||||
static Fingerprint trustedClients();
|
|
||||||
static QString directoryPath();
|
|
||||||
static void persistDirectory();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Fingerprint(const QString& filename);
|
|
||||||
|
|
||||||
QString m_Filename;
|
|
||||||
};
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
|
|
||||||
#include "Fingerprint.h"
|
|
||||||
#include "AboutDialog.h"
|
#include "AboutDialog.h"
|
||||||
#include "ServerConfigDialog.h"
|
#include "ServerConfigDialog.h"
|
||||||
#include "SettingsDialog.h"
|
#include "SettingsDialog.h"
|
||||||
|
@ -31,7 +30,10 @@
|
||||||
#include "ProcessorArch.h"
|
#include "ProcessorArch.h"
|
||||||
#include "SslCertificate.h"
|
#include "SslCertificate.h"
|
||||||
#include "ShutdownCh.h"
|
#include "ShutdownCh.h"
|
||||||
|
#include "base/String.h"
|
||||||
#include "common/DataDirectories.h"
|
#include "common/DataDirectories.h"
|
||||||
|
#include "net/FingerprintDatabase.h"
|
||||||
|
#include "net/SecureUtils.h"
|
||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
@ -417,11 +419,21 @@ void MainWindow::checkFingerprint(const QString& line)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString fingerprint = fingerprintRegex.cap(1);
|
barrier::FingerprintData fingerprint = {
|
||||||
if (Fingerprint::trustedServers().isTrusted(fingerprint)) {
|
barrier::fingerprint_type_to_string(barrier::FingerprintType::SHA1),
|
||||||
|
barrier::string::from_hex(fingerprintRegex.cap(1).toStdString())
|
||||||
|
};
|
||||||
|
|
||||||
|
auto db_path = DataDirectories::trusted_servers_ssl_fingerprints_path();
|
||||||
|
|
||||||
|
barrier::FingerprintDatabase db;
|
||||||
|
db.read(db_path);
|
||||||
|
if (db.is_trusted(fingerprint)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto formatted_fingerprint = barrier::format_ssl_fingerprint(fingerprint.data);
|
||||||
|
|
||||||
static bool messageBoxAlreadyShown = false;
|
static bool messageBoxAlreadyShown = false;
|
||||||
|
|
||||||
if (!messageBoxAlreadyShown) {
|
if (!messageBoxAlreadyShown) {
|
||||||
|
@ -440,12 +452,13 @@ void MainWindow::checkFingerprint(const QString& line)
|
||||||
"To automatically trust this fingerprint for future "
|
"To automatically trust this fingerprint for future "
|
||||||
"connections, click Yes. To reject this fingerprint and "
|
"connections, click Yes. To reject this fingerprint and "
|
||||||
"disconnect from the server, click No.")
|
"disconnect from the server, click No.")
|
||||||
.arg(fingerprint),
|
.arg(QString::fromStdString(formatted_fingerprint)),
|
||||||
QMessageBox::Yes | QMessageBox::No);
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
|
|
||||||
if (fingerprintReply == QMessageBox::Yes) {
|
if (fingerprintReply == QMessageBox::Yes) {
|
||||||
// restart core process after trusting fingerprint.
|
// restart core process after trusting fingerprint.
|
||||||
Fingerprint::trustedServers().trust(fingerprint);
|
db.add_trusted(fingerprint);
|
||||||
|
db.write(db_path);
|
||||||
startBarrier();
|
startBarrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -965,12 +978,29 @@ void MainWindow::updateSSLFingerprint()
|
||||||
});
|
});
|
||||||
m_pSslCertificate->generateCertificate();
|
m_pSslCertificate->generateCertificate();
|
||||||
}
|
}
|
||||||
if (m_AppConfig->getCryptoEnabled() && Fingerprint::local().fileExists()) {
|
|
||||||
m_pLabelLocalFingerprint->setText(Fingerprint::local().readFirst());
|
|
||||||
m_pLabelLocalFingerprint->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
|
||||||
} else {
|
|
||||||
m_pLabelLocalFingerprint->setText("Disabled");
|
m_pLabelLocalFingerprint->setText("Disabled");
|
||||||
|
|
||||||
|
if (!m_AppConfig->getCryptoEnabled()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto local_path = DataDirectories::local_ssl_fingerprints_path();
|
||||||
|
if (!QFile::exists(QString::fromStdString(local_path))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
barrier::FingerprintDatabase db;
|
||||||
|
db.read(local_path);
|
||||||
|
if (db.fingerprints().empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& fingerprint = db.fingerprints().front();
|
||||||
|
auto formatted_fingerprint = barrier::format_ssl_fingerprint(fingerprint.data);
|
||||||
|
|
||||||
|
m_pLabelLocalFingerprint->setText(QString::fromStdString(formatted_fingerprint));
|
||||||
|
m_pLabelLocalFingerprint->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_m_pGroupClient_toggled(bool on)
|
void MainWindow::on_m_pGroupClient_toggled(bool on)
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SslCertificate.h"
|
#include "SslCertificate.h"
|
||||||
#include "Fingerprint.h"
|
|
||||||
#include "common/DataDirectories.h"
|
#include "common/DataDirectories.h"
|
||||||
|
#include "net/FingerprintDatabase.h"
|
||||||
#include "net/SecureUtils.h"
|
#include "net/SecureUtils.h"
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
@ -44,17 +44,17 @@ SslCertificate::SslCertificate(QObject *parent) :
|
||||||
|
|
||||||
void SslCertificate::generateCertificate()
|
void SslCertificate::generateCertificate()
|
||||||
{
|
{
|
||||||
auto filename = QString::fromStdString(getCertificatePath());
|
auto cert_path = getCertificatePath();
|
||||||
|
|
||||||
QFile file(filename);
|
QFile file(QString::fromStdString(cert_path));
|
||||||
if (!file.exists() || !isCertificateValid(filename)) {
|
if (!file.exists() || !isCertificateValid(cert_path)) {
|
||||||
QDir sslDir(QString::fromStdString(getCertificateDirectory()));
|
QDir sslDir(QString::fromStdString(getCertificateDirectory()));
|
||||||
if (!sslDir.exists()) {
|
if (!sslDir.exists()) {
|
||||||
sslDir.mkpath(".");
|
sslDir.mkpath(".");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
barrier::generate_pem_self_signed_cert(filename.toStdString());
|
barrier::generate_pem_self_signed_cert(cert_path);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
emit error(QString("SSL tool failed: %1").arg(e.what()));
|
emit error(QString("SSL tool failed: %1").arg(e.what()));
|
||||||
return;
|
return;
|
||||||
|
@ -63,18 +63,22 @@ void SslCertificate::generateCertificate()
|
||||||
emit info(tr("SSL certificate generated."));
|
emit info(tr("SSL certificate generated."));
|
||||||
}
|
}
|
||||||
|
|
||||||
generateFingerprint(filename);
|
generateFingerprint(cert_path);
|
||||||
|
|
||||||
emit generateFinished();
|
emit generateFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SslCertificate::generateFingerprint(const QString& certificateFilename)
|
void SslCertificate::generateFingerprint(const std::string& cert_path)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
auto fingerprint = barrier::get_pem_file_cert_fingerprint(certificateFilename.toStdString(),
|
auto fingerprint = barrier::get_pem_file_cert_fingerprint(cert_path,
|
||||||
barrier::FingerprintType::SHA1);
|
barrier::FingerprintType::SHA1);
|
||||||
Fingerprint::local().trust(QString::fromStdString(
|
|
||||||
barrier::format_ssl_fingerprint(fingerprint)), false);
|
auto local_path = DataDirectories::local_ssl_fingerprints_path();
|
||||||
|
barrier::FingerprintDatabase db;
|
||||||
|
db.add_trusted(barrier::FingerprintData{"sha1", fingerprint});
|
||||||
|
db.write(local_path);
|
||||||
|
|
||||||
emit info(tr("SSL fingerprint generated."));
|
emit info(tr("SSL fingerprint generated."));
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
emit error(tr("Failed to find SSL fingerprint.") + e.what());
|
emit error(tr("Failed to find SSL fingerprint.") + e.what());
|
||||||
|
@ -91,7 +95,7 @@ std::string SslCertificate::getCertificateDirectory()
|
||||||
return m_ProfileDir + QDir::separator().toLatin1() + kSslDir;
|
return m_ProfileDir + QDir::separator().toLatin1() + kSslDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SslCertificate::isCertificateValid(const QString& path)
|
bool SslCertificate::isCertificateValid(const std::string& path)
|
||||||
{
|
{
|
||||||
OpenSSL_add_all_algorithms();
|
OpenSSL_add_all_algorithms();
|
||||||
ERR_load_BIO_strings();
|
ERR_load_BIO_strings();
|
||||||
|
@ -99,7 +103,7 @@ bool SslCertificate::isCertificateValid(const QString& path)
|
||||||
|
|
||||||
BIO* bio = BIO_new(BIO_s_file());
|
BIO* bio = BIO_new(BIO_s_file());
|
||||||
|
|
||||||
auto ret = BIO_read_filename(bio, path.toStdString().c_str());
|
auto ret = BIO_read_filename(bio, path.c_str());
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
emit info(tr("Could not read from default certificate file."));
|
emit info(tr("Could not read from default certificate file."));
|
||||||
BIO_free_all(bio);
|
BIO_free_all(bio);
|
||||||
|
|
|
@ -37,12 +37,12 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<bool, std::string> runTool(const QStringList& args);
|
std::pair<bool, std::string> runTool(const QStringList& args);
|
||||||
void generateFingerprint(const QString& certificateFilename);
|
void generateFingerprint(const std::string& cert_path);
|
||||||
|
|
||||||
std::string getCertificatePath();
|
std::string getCertificatePath();
|
||||||
std::string getCertificateDirectory();
|
std::string getCertificateDirectory();
|
||||||
|
|
||||||
bool isCertificateValid(const QString& path);
|
bool isCertificateValid(const std::string& path);
|
||||||
private:
|
private:
|
||||||
std::string m_ProfileDir;
|
std::string m_ProfileDir;
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,6 +31,10 @@ public:
|
||||||
static const std::string& systemconfig();
|
static const std::string& systemconfig();
|
||||||
static const std::string& systemconfig(const std::string& path);
|
static const std::string& systemconfig(const std::string& path);
|
||||||
|
|
||||||
|
static std::string ssl_fingerprints_path();
|
||||||
|
static std::string local_ssl_fingerprints_path();
|
||||||
|
static std::string trusted_servers_ssl_fingerprints_path();
|
||||||
|
static std::string trusted_clients_ssl_fingerprints_path();
|
||||||
private:
|
private:
|
||||||
static std::string _profile;
|
static std::string _profile;
|
||||||
static std::string _global;
|
static std::string _global;
|
||||||
|
|
|
@ -21,3 +21,28 @@
|
||||||
std::string DataDirectories::_profile;
|
std::string DataDirectories::_profile;
|
||||||
std::string DataDirectories::_global;
|
std::string DataDirectories::_global;
|
||||||
std::string DataDirectories::_systemconfig;
|
std::string DataDirectories::_systemconfig;
|
||||||
|
|
||||||
|
static const char kFingerprintsDirName[] = "SSL/Fingerprints";
|
||||||
|
static const char kFingerprintsLocalFilename[] = "Local.txt";
|
||||||
|
static const char kFingerprintsTrustedServersFilename[] = "TrustedServers.txt";
|
||||||
|
static const char kFingerprintsTrustedClientsFilename[] = "TrustedClients.txt";
|
||||||
|
|
||||||
|
std::string DataDirectories::ssl_fingerprints_path()
|
||||||
|
{
|
||||||
|
return profile() + "/" + kFingerprintsDirName;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DataDirectories::local_ssl_fingerprints_path()
|
||||||
|
{
|
||||||
|
return ssl_fingerprints_path() + "/" + kFingerprintsLocalFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DataDirectories::trusted_servers_ssl_fingerprints_path()
|
||||||
|
{
|
||||||
|
return ssl_fingerprints_path() + "/" + kFingerprintsTrustedServersFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DataDirectories::trusted_clients_ssl_fingerprints_path()
|
||||||
|
{
|
||||||
|
return ssl_fingerprints_path() + "/" + kFingerprintsTrustedClientsFilename;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue