From be8ba0d13248fd6d51382f524b1992c380d21887 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:45 +0200 Subject: [PATCH] gui: Use new FingerprintDatabase to handle fingerprints --- src/gui/CMakeLists.txt | 2 - src/gui/src/Fingerprint.cpp | 147 ---------------------- src/gui/src/Fingerprint.h | 42 ------- src/gui/src/MainWindow.cpp | 50 ++++++-- src/gui/src/SslCertificate.cpp | 28 +++-- src/gui/src/SslCertificate.h | 4 +- src/lib/common/DataDirectories.h | 4 + src/lib/common/DataDirectories_static.cpp | 25 ++++ 8 files changed, 87 insertions(+), 215 deletions(-) delete mode 100644 src/gui/src/Fingerprint.cpp delete mode 100644 src/gui/src/Fingerprint.h diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 49557352..fb7678f2 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -29,7 +29,6 @@ set(GUI_SOURCE_FILES src/CommandProcess.cpp src/DataDownloader.cpp src/DisplayIsValid.cpp - src/Fingerprint.cpp src/HotkeyDialog.cpp src/IpcClient.cpp src/Ipc.cpp @@ -70,7 +69,6 @@ set(GUI_HEADER_FILES src/DataDownloader.h src/DisplayIsValid.h src/ElevateMode.h - src/Fingerprint.h src/HotkeyDialog.h src/IpcClient.h src/Ipc.h diff --git a/src/gui/src/Fingerprint.cpp b/src/gui/src/Fingerprint.cpp deleted file mode 100644 index cc1ce3bf..00000000 --- a/src/gui/src/Fingerprint.cpp +++ /dev/null @@ -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 . - */ - -#include "Fingerprint.h" - -#include "common/DataDirectories.h" - -#include -#include - -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); -} diff --git a/src/gui/src/Fingerprint.h b/src/gui/src/Fingerprint.h deleted file mode 100644 index 5a38d201..00000000 --- a/src/gui/src/Fingerprint.h +++ /dev/null @@ -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 . - */ - -#pragma once - -#include - -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; -}; diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 9072b864..02499a12 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -20,7 +20,6 @@ #include "MainWindow.h" -#include "Fingerprint.h" #include "AboutDialog.h" #include "ServerConfigDialog.h" #include "SettingsDialog.h" @@ -31,7 +30,10 @@ #include "ProcessorArch.h" #include "SslCertificate.h" #include "ShutdownCh.h" +#include "base/String.h" #include "common/DataDirectories.h" +#include "net/FingerprintDatabase.h" +#include "net/SecureUtils.h" #include #include @@ -417,11 +419,21 @@ void MainWindow::checkFingerprint(const QString& line) return; } - QString fingerprint = fingerprintRegex.cap(1); - if (Fingerprint::trustedServers().isTrusted(fingerprint)) { + barrier::FingerprintData 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; } + auto formatted_fingerprint = barrier::format_ssl_fingerprint(fingerprint.data); + static bool messageBoxAlreadyShown = false; if (!messageBoxAlreadyShown) { @@ -440,12 +452,13 @@ void MainWindow::checkFingerprint(const QString& line) "To automatically trust this fingerprint for future " "connections, click Yes. To reject this fingerprint and " "disconnect from the server, click No.") - .arg(fingerprint), + .arg(QString::fromStdString(formatted_fingerprint)), QMessageBox::Yes | QMessageBox::No); if (fingerprintReply == QMessageBox::Yes) { // restart core process after trusting fingerprint. - Fingerprint::trustedServers().trust(fingerprint); + db.add_trusted(fingerprint); + db.write(db_path); startBarrier(); } @@ -965,12 +978,29 @@ void MainWindow::updateSSLFingerprint() }); 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) diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index ac70d01a..4242df56 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -16,8 +16,8 @@ */ #include "SslCertificate.h" -#include "Fingerprint.h" #include "common/DataDirectories.h" +#include "net/FingerprintDatabase.h" #include "net/SecureUtils.h" #include @@ -44,17 +44,17 @@ SslCertificate::SslCertificate(QObject *parent) : void SslCertificate::generateCertificate() { - auto filename = QString::fromStdString(getCertificatePath()); + auto cert_path = getCertificatePath(); - QFile file(filename); - if (!file.exists() || !isCertificateValid(filename)) { + QFile file(QString::fromStdString(cert_path)); + if (!file.exists() || !isCertificateValid(cert_path)) { QDir sslDir(QString::fromStdString(getCertificateDirectory())); if (!sslDir.exists()) { sslDir.mkpath("."); } try { - barrier::generate_pem_self_signed_cert(filename.toStdString()); + barrier::generate_pem_self_signed_cert(cert_path); } catch (const std::exception& e) { emit error(QString("SSL tool failed: %1").arg(e.what())); return; @@ -63,18 +63,22 @@ void SslCertificate::generateCertificate() emit info(tr("SSL certificate generated.")); } - generateFingerprint(filename); + generateFingerprint(cert_path); emit generateFinished(); } -void SslCertificate::generateFingerprint(const QString& certificateFilename) +void SslCertificate::generateFingerprint(const std::string& cert_path) { try { - auto fingerprint = barrier::get_pem_file_cert_fingerprint(certificateFilename.toStdString(), + auto fingerprint = barrier::get_pem_file_cert_fingerprint(cert_path, 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.")); } catch (const std::exception& e) { 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; } -bool SslCertificate::isCertificateValid(const QString& path) +bool SslCertificate::isCertificateValid(const std::string& path) { OpenSSL_add_all_algorithms(); ERR_load_BIO_strings(); @@ -99,7 +103,7 @@ bool SslCertificate::isCertificateValid(const QString& path) 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) { emit info(tr("Could not read from default certificate file.")); BIO_free_all(bio); diff --git a/src/gui/src/SslCertificate.h b/src/gui/src/SslCertificate.h index 2fe807a2..7f77771a 100644 --- a/src/gui/src/SslCertificate.h +++ b/src/gui/src/SslCertificate.h @@ -37,12 +37,12 @@ signals: private: std::pair runTool(const QStringList& args); - void generateFingerprint(const QString& certificateFilename); + void generateFingerprint(const std::string& cert_path); std::string getCertificatePath(); std::string getCertificateDirectory(); - bool isCertificateValid(const QString& path); + bool isCertificateValid(const std::string& path); private: std::string m_ProfileDir; }; diff --git a/src/lib/common/DataDirectories.h b/src/lib/common/DataDirectories.h index 783ff138..4489ac24 100644 --- a/src/lib/common/DataDirectories.h +++ b/src/lib/common/DataDirectories.h @@ -31,6 +31,10 @@ public: static const std::string& systemconfig(); 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: static std::string _profile; static std::string _global; diff --git a/src/lib/common/DataDirectories_static.cpp b/src/lib/common/DataDirectories_static.cpp index 48dccb68..5e28e055 100644 --- a/src/lib/common/DataDirectories_static.cpp +++ b/src/lib/common/DataDirectories_static.cpp @@ -21,3 +21,28 @@ std::string DataDirectories::_profile; std::string DataDirectories::_global; 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; +}