From aaa64e986ea86b39ce19c858c81165dbc9a1bacd Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Tue, 28 Jan 2025 23:13:46 +0530 Subject: [PATCH] feat!: Add support for FingerPrintDatabase --- src/lib/net/CMakeLists.txt | 7 +- src/lib/net/FingerprintData.cpp | 48 ++++++++++ src/lib/net/FingerprintData.h | 34 +++++++ src/lib/net/FingerprintDatabase.cpp | 133 ++++++++++++++++++++++++++++ src/lib/net/FingerprintDatabase.h | 45 ++++++++++ 5 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 src/lib/net/FingerprintData.cpp create mode 100644 src/lib/net/FingerprintData.h create mode 100644 src/lib/net/FingerprintDatabase.cpp create mode 100644 src/lib/net/FingerprintDatabase.h diff --git a/src/lib/net/CMakeLists.txt b/src/lib/net/CMakeLists.txt index 1bc51c8c2..ab3a685d5 100644 --- a/src/lib/net/CMakeLists.txt +++ b/src/lib/net/CMakeLists.txt @@ -5,6 +5,10 @@ add_library(net STATIC FingerprintTypes.h + FingerprintData.cpp + FingerprintData.h + FingerprintDatabase.cpp + FingerprintDatabase.h IDataSocket.cpp IDataSocket.h IListenSocket.h @@ -57,5 +61,6 @@ if(WIN32) target_link_libraries( net PUBLIC OpenSSL::applink - PRIVATE Crypt32 ws2_32 OpenSSL::applink) + PRIVATE Crypt32 ws2_32 OpenSSL::applink + ) endif() diff --git a/src/lib/net/FingerprintData.cpp b/src/lib/net/FingerprintData.cpp new file mode 100644 index 000000000..bb9b4831f --- /dev/null +++ b/src/lib/net/FingerprintData.cpp @@ -0,0 +1,48 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers + * SPDX-FileCopyrightText: (C) 2021 Barrier Contributors + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#include "FingerprintDatabase.h" + +#include "io/filesystem.h" + +#include +#include + +namespace deskflow { + +bool FingerprintData::operator==(const FingerprintData &other) const +{ + return algorithm == other.algorithm && data == other.data; +} + +const char *fingerprintTypeToString(FingerprintType type) +{ + switch (type) { + case FingerprintType::Invalid: + return "invalid"; + case FingerprintType::SHA1: + return "sha1"; + case FingerprintType::SHA256: + return "sha256"; + default: + break; + } + return "invalid"; +} + +FingerprintType fingerprintTypeFromString(const std::string &type) +{ + if (type == "sha1") + return FingerprintType::SHA1; + + if (type == "sha256") + return FingerprintType::SHA256; + + return FingerprintType::Invalid; +} + +} // namespace deskflow diff --git a/src/lib/net/FingerprintData.h b/src/lib/net/FingerprintData.h new file mode 100644 index 000000000..e5d53a167 --- /dev/null +++ b/src/lib/net/FingerprintData.h @@ -0,0 +1,34 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers + * SPDX-FileCopyrightText: (C) 2021 Barrier Contributors + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#pragma once + +#include "FingerprintTypes.h" + +#include +#include +#include + +namespace deskflow { + +struct FingerprintData +{ + std::string algorithm; + std::vector data; + + bool valid() const + { + return !algorithm.empty(); + } + + bool operator==(const FingerprintData &other) const; +}; + +const char *fingerprintTypeToString(FingerprintType type); +FingerprintType fingerprintTypeFromString(const std::string &type); + +} // namespace deskflow diff --git a/src/lib/net/FingerprintDatabase.cpp b/src/lib/net/FingerprintDatabase.cpp new file mode 100644 index 000000000..f4f917ac2 --- /dev/null +++ b/src/lib/net/FingerprintDatabase.cpp @@ -0,0 +1,133 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers + * SPDX-FileCopyrightText: (C) 2021 Barrier Contributors + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#include "FingerprintDatabase.h" + +#include "base/String.h" +#include "io/filesystem.h" + +#include +#include + +namespace deskflow { + +void FingerprintDatabase::read(const fs::path &path) +{ + std::ifstream file; + openUtf8Path(file, path, std::ios_base::in); + readStream(file); +} + +void FingerprintDatabase::write(const fs::path &path) +{ + std::ofstream file; + openUtf8Path(file, path, std::ios_base::out); + writeStream(file); +} + +void FingerprintDatabase::readStream(std::istream &stream) +{ + if (!stream.good()) { + return; + } + + std::string line; + while (std::getline(stream, line)) { + if (line.empty()) { + continue; + } + + auto fingerprint = parseDbLine(line); + if (!fingerprint.valid()) { + continue; + } + + m_fingerprints.push_back(fingerprint); + } +} + +void FingerprintDatabase::writeStream(std::ostream &stream) +{ + if (!stream.good()) { + return; + } + + for (const auto &fingerprint : m_fingerprints) { + stream << toDbLine(fingerprint) << "\n"; + } +} + +void FingerprintDatabase::clear() +{ + m_fingerprints.clear(); +} + +void FingerprintDatabase::addTrusted(const FingerprintData &fingerprint) +{ + if (isTrusted(fingerprint)) { + return; + } + m_fingerprints.push_back(fingerprint); +} + +bool FingerprintDatabase::isTrusted(const FingerprintData &fingerprint) +{ + auto found = std::find(m_fingerprints.begin(), m_fingerprints.end(), fingerprint); + return found != m_fingerprints.end(); +} + +FingerprintData FingerprintDatabase::parseDbLine(const std::string &line) +{ + + const auto kSha1ColonCount = 19; + const auto kSha1HexCharCount = 40; + const auto kSha1ExpectedSize = kSha1HexCharCount + kSha1ColonCount; + + FingerprintData result; + + // legacy v1 certificate handling + if (std::count(line.begin(), line.end(), ':') == kSha1ColonCount && line.size() == kSha1ExpectedSize) { + auto data = string::fromHex(line); + if (data.empty()) { + return result; + } + result.algorithm = fingerprintTypeToString(FingerprintType::SHA1); + result.data = data; + return result; + } + + auto versionEndPos = line.find(':'); + if (versionEndPos == std::string::npos) { + return result; + } + if (line.substr(0, versionEndPos) != "v2") { + return result; + } + auto algoStartPos = versionEndPos + 1; + auto algoEndPos = line.find(':', algoStartPos); + if (algoEndPos == std::string::npos) { + return result; + } + auto algorithm = line.substr(algoStartPos, algoEndPos - algoStartPos); + auto data = string::fromHex(line.substr(algoEndPos + 1)); + + if (data.empty()) { + return result; + } + + result.algorithm = algorithm; + result.data = data; + return result; +} + +std::string FingerprintDatabase::toDbLine(const FingerprintData &fingerprint) +{ + std::string fingerprintStr(fingerprint.data.begin(), fingerprint.data.end()); + return "v2:" + fingerprint.algorithm + ":" + string::toHex(fingerprintStr, 2); +} + +} // namespace deskflow diff --git a/src/lib/net/FingerprintDatabase.h b/src/lib/net/FingerprintDatabase.h new file mode 100644 index 000000000..99bcea9a2 --- /dev/null +++ b/src/lib/net/FingerprintDatabase.h @@ -0,0 +1,45 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers + * SPDX-FileCopyrightText: (C) 2021 Barrier Contributors + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#pragma once + +#include "FingerprintData.h" + +#include "io/filesystem.h" + +#include +#include +#include + +namespace deskflow { + +class FingerprintDatabase +{ +public: + void read(const fs::path &path); + void write(const fs::path &path); + + void readStream(std::istream &stream); + void writeStream(std::ostream &stream); + + void clear(); + void addTrusted(const FingerprintData &fingerprint); + bool isTrusted(const FingerprintData &fingerprint); + + const std::vector &fingerprints() const + { + return m_fingerprints; + } + + static FingerprintData parseDbLine(const std::string &line); + static std::string toDbLine(const FingerprintData &fingerprint); + +private: + std::vector m_fingerprints; +}; + +} // namespace deskflow