From b7eb5c467bc38dc53bb8309669e70af1d3d1ae4e Mon Sep 17 00:00:00 2001 From: sithlord48 Date: Sat, 22 Feb 2025 01:01:58 -0500 Subject: [PATCH] feat: Remove Inverse Connections Option --- src/apps/deskflow-gui/MainWindow.cpp | 10 +- src/apps/deskflow-gui/MainWindow.ui | 52 +- src/apps/deskflow-gui/ServerConfig.cpp | 28 -- .../deskflow-gui/dialogs/SettingsDialog.cpp | 3 - .../deskflow-gui/dialogs/SettingsDialog.ui | 7 - src/lib/deskflow/ClientApp.cpp | 11 +- src/lib/deskflow/ServerApp.cpp | 11 +- src/lib/gui/config/AppConfig.cpp | 25 +- src/lib/gui/config/AppConfig.h | 6 +- src/lib/gui/config/IAppConfig.h | 2 - src/lib/gui/core/CoreProcess.cpp | 29 +- src/lib/net/CMakeLists.txt | 16 +- src/lib/net/InverseSockets/AutoArchSocket.cpp | 182 ------- src/lib/net/InverseSockets/AutoArchSocket.h | 43 -- .../InverseSockets/InverseClientSocket.cpp | 409 ---------------- .../net/InverseSockets/InverseClientSocket.h | 115 ----- .../InverseSockets/InverseServerSocket.cpp | 106 ----- .../net/InverseSockets/InverseServerSocket.h | 52 -- .../InverseSockets/InverseSocketFactory.cpp | 46 -- .../net/InverseSockets/InverseSocketFactory.h | 30 -- .../net/InverseSockets/SecureClientSocket.cpp | 445 ------------------ .../net/InverseSockets/SecureClientSocket.h | 61 --- .../net/InverseSockets/SecureServerSocket.cpp | 72 --- .../net/InverseSockets/SecureServerSocket.h | 20 - src/lib/net/InverseSockets/SslApi.cpp | 261 ---------- src/lib/net/InverseSockets/SslApi.h | 46 -- src/test/shared/gui/mocks/AppConfigMock.h | 2 - 27 files changed, 18 insertions(+), 2072 deletions(-) delete mode 100644 src/lib/net/InverseSockets/AutoArchSocket.cpp delete mode 100644 src/lib/net/InverseSockets/AutoArchSocket.h delete mode 100644 src/lib/net/InverseSockets/InverseClientSocket.cpp delete mode 100644 src/lib/net/InverseSockets/InverseClientSocket.h delete mode 100644 src/lib/net/InverseSockets/InverseServerSocket.cpp delete mode 100644 src/lib/net/InverseSockets/InverseServerSocket.h delete mode 100644 src/lib/net/InverseSockets/InverseSocketFactory.cpp delete mode 100644 src/lib/net/InverseSockets/InverseSocketFactory.h delete mode 100644 src/lib/net/InverseSockets/SecureClientSocket.cpp delete mode 100644 src/lib/net/InverseSockets/SecureClientSocket.h delete mode 100644 src/lib/net/InverseSockets/SecureServerSocket.cpp delete mode 100644 src/lib/net/InverseSockets/SecureServerSocket.h delete mode 100644 src/lib/net/InverseSockets/SslApi.cpp delete mode 100644 src/lib/net/InverseSockets/SslApi.h diff --git a/src/apps/deskflow-gui/MainWindow.cpp b/src/apps/deskflow-gui/MainWindow.cpp index 156b30ec3..f7cd02c62 100644 --- a/src/apps/deskflow-gui/MainWindow.cpp +++ b/src/apps/deskflow-gui/MainWindow.cpp @@ -280,7 +280,6 @@ void MainWindow::connectSlots() connect(&m_appConfig, &AppConfig::tlsChanged, this, &MainWindow::appConfigTlsChanged); connect(&m_appConfig, &AppConfig::screenNameChanged, this, &MainWindow::updateScreenName); - connect(&m_appConfig, &AppConfig::invertConnectionChanged, this, &MainWindow::applyConfig); connect(&m_coreProcess, &CoreProcess::starting, this, &MainWindow::coreProcessStarting, Qt::DirectConnection); connect(&m_coreProcess, &CoreProcess::error, this, &MainWindow::coreProcessError); @@ -319,14 +318,10 @@ void MainWindow::connectSlots() connect(ui->btnToggleCore, &QPushButton::clicked, m_actionStartCore, &QAction::trigger, Qt::UniqueConnection); connect(ui->btnApplySettings, &QPushButton::clicked, this, &MainWindow::resetCore); connect(ui->btnConnect, &QPushButton::clicked, this, &MainWindow::resetCore); - connect(ui->btnConnectToClient, &QPushButton::clicked, this, &MainWindow::resetCore); connect(ui->lineHostname, &QLineEdit::returnPressed, ui->btnConnect, &QPushButton::click); connect(ui->lineHostname, &QLineEdit::textChanged, &m_coreProcess, &deskflow::gui::CoreProcess::setAddress); - connect(ui->lineClientIp, &QLineEdit::returnPressed, ui->btnConnectToClient, &QPushButton::click); - connect(ui->lineClientIp, &QLineEdit::textChanged, &m_coreProcess, &deskflow::gui::CoreProcess::setAddress); - connect(ui->btnConfigureServer, &QPushButton::clicked, this, [this] { showConfigureServer(""); }); connect(ui->lblComputerName, &QLabel::linkActivated, this, &MainWindow::openSettings); connect(m_btnFingerprint, &QToolButton::clicked, this, &MainWindow::showMyFingerprint); @@ -670,7 +665,6 @@ void MainWindow::applyConfig() enableClient(m_appConfig.clientGroupChecked()); ui->lineHostname->setText(m_appConfig.serverHostname()); - ui->lineClientIp->setText(m_serverConfig.getClientAddress()); updateLocalFingerprint(); setIcon(); } @@ -680,7 +674,6 @@ void MainWindow::saveSettings() m_appConfig.setServerGroupChecked(ui->rbModeServer->isChecked()); m_appConfig.setClientGroupChecked(ui->rbModeClient->isChecked()); m_appConfig.setServerHostname(ui->lineHostname->text()); - m_serverConfig.setClientAddress(ui->lineClientIp->text()); m_configScopes.save(); } @@ -1033,7 +1026,6 @@ void MainWindow::enableServer(bool enable) m_appConfig.setServerGroupChecked(enable); ui->rbModeServer->setChecked(enable); ui->widgetServer->setEnabled(enable); - ui->widgetServerInput->setVisible(m_appConfig.invertConnection()); if (enable) { ui->btnToggleCore->setEnabled(true); @@ -1062,7 +1054,7 @@ void MainWindow::enableClient(bool enable) m_appConfig.setClientGroupChecked(enable); ui->rbModeClient->setChecked(enable); ui->widgetClientInput->setEnabled(enable); - ui->widgetClientInput->setVisible(!m_appConfig.invertConnection()); + ui->widgetClientInput->setVisible(true); if (enable) { ui->btnToggleCore->setEnabled(true); diff --git a/src/apps/deskflow-gui/MainWindow.ui b/src/apps/deskflow-gui/MainWindow.ui index 174c1a6b2..0013638bb 100644 --- a/src/apps/deskflow-gui/MainWindow.ui +++ b/src/apps/deskflow-gui/MainWindow.ui @@ -7,7 +7,7 @@ 0 0 883 - 583 + 521 @@ -171,54 +171,6 @@ 0 - - - - - 15 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Client IP address or hostname: - - - 20 - - - - - - - 20 - - - - - - - - Connect - - - - - - - - @@ -494,8 +446,6 @@ rbModeServer - lineClientIp - btnConnectToClient btnConfigureServer rbModeClient lineHostname diff --git a/src/apps/deskflow-gui/ServerConfig.cpp b/src/apps/deskflow-gui/ServerConfig.cpp index fdcfcc92d..17ecad3ad 100644 --- a/src/apps/deskflow-gui/ServerConfig.cpp +++ b/src/apps/deskflow-gui/ServerConfig.cpp @@ -130,10 +130,6 @@ void ServerConfig::commit() settings().setValue("clipboardSharing", clipboardSharing()); settings().setValue("clipboardSharingSize", QVariant::fromValue(clipboardSharingSize())); - if (!getClientAddress().isEmpty()) { - settings().setValue("clientAddress", getClientAddress()); - } - writeSettings(settings(), switchCorners(), "switchCorner"); settings().beginWriteArray("screens"); @@ -186,7 +182,6 @@ void ServerConfig::recall() settings().value("clipboardSharingSize", (int)ServerConfig::defaultClipboardSharingSize()).toULongLong() ); setClipboardSharing(settings().value("clipboardSharing", true).toBool()); - setClientAddress(settings().value("clientAddress", "").toString()); readSettings(settings(), switchCorners(), "switchCorner", 0, static_cast(NumSwitchCorners)); @@ -293,11 +288,6 @@ QTextStream &operator<<(QTextStream &outStream, const ServerConfig &config) outStream << "\t" << "clipboardSharingSize = " << config.clipboardSharingSize() << Qt::endl; - if (!config.getClientAddress().isEmpty()) { - outStream << "\t" - << "clientAddress = " << config.getClientAddress() << Qt::endl; - } - if (config.hasSwitchDelay()) outStream << "\t" << "switchDelay = " << config.switchDelay() << Qt::endl; @@ -545,24 +535,6 @@ size_t ServerConfig::setClipboardSharingSize(size_t size) return size; } -void ServerConfig::setClientAddress(const QString &address) -{ - if (m_pAppConfig->invertConnection()) { - m_ClientAddress = address; - } -} - -QString ServerConfig::getClientAddress() const -{ - QString clientAddress; - - if (m_pAppConfig->invertConnection()) { - clientAddress = m_ClientAddress.trimmed(); - } - - return clientAddress; -} - QSettingsProxy &ServerConfig::settings() { return m_pAppConfig->scopes().activeSettings(); diff --git a/src/apps/deskflow-gui/dialogs/SettingsDialog.cpp b/src/apps/deskflow-gui/dialogs/SettingsDialog.cpp index 117d7c587..0480ac6c3 100644 --- a/src/apps/deskflow-gui/dialogs/SettingsDialog.cpp +++ b/src/apps/deskflow-gui/dialogs/SettingsDialog.cpp @@ -190,7 +190,6 @@ void SettingsDialog::accept() m_appConfig.setInvertScrollDirection(ui->m_pCheckBoxScrollDirection->isChecked()); m_appConfig.setEnableService(ui->m_pCheckBoxServiceEnabled->isChecked()); m_appConfig.setCloseToTray(ui->m_pCheckBoxCloseToTray->isChecked()); - m_appConfig.setInvertConnection(ui->m_pInvertConnection->isChecked()); m_appConfig.setColorfulTrayIcon(ui->rb_icon_colorful->isChecked()); m_appConfig.setRequireClientCerts(ui->chkRequireClientCert->isChecked()); @@ -236,8 +235,6 @@ void SettingsDialog::loadFromConfig() ui->m_pRadioUserScope->setChecked(true); } - ui->m_pInvertConnection->setChecked(m_appConfig.invertConnection()); - if (m_appConfig.colorfulTrayIcon()) ui->rb_icon_colorful->setChecked(true); else diff --git a/src/apps/deskflow-gui/dialogs/SettingsDialog.ui b/src/apps/deskflow-gui/dialogs/SettingsDialog.ui index dd3728997..2d4ae9a0f 100644 --- a/src/apps/deskflow-gui/dialogs/SettingsDialog.ui +++ b/src/apps/deskflow-gui/dialogs/SettingsDialog.ui @@ -457,13 +457,6 @@ - - - - Invert server/client TCP connection - - - diff --git a/src/lib/deskflow/ClientApp.cpp b/src/lib/deskflow/ClientApp.cpp index fa3b0b7ad..d1e456cb9 100644 --- a/src/lib/deskflow/ClientApp.cpp +++ b/src/lib/deskflow/ClientApp.cpp @@ -19,7 +19,6 @@ #include "deskflow/Screen.h" #include "deskflow/XScreen.h" #include "deskflow/protocol_types.h" -#include "net/InverseSockets/InverseSocketFactory.h" #include "net/NetworkAddress.h" #include "net/SocketMultiplexer.h" #include "net/TCPSocketFactory.h" @@ -547,13 +546,5 @@ void ClientApp::startNode() ISocketFactory *ClientApp::getSocketFactory() const { - ISocketFactory *socketFactory = nullptr; - - if (args().m_hostMode) { - socketFactory = new InverseSocketFactory(m_events, getSocketMultiplexer()); - } else { - socketFactory = new TCPSocketFactory(m_events, getSocketMultiplexer()); - } - - return socketFactory; + return new TCPSocketFactory(m_events, getSocketMultiplexer()); } diff --git a/src/lib/deskflow/ServerApp.cpp b/src/lib/deskflow/ServerApp.cpp index c701ee2dc..884b341af 100644 --- a/src/lib/deskflow/ServerApp.cpp +++ b/src/lib/deskflow/ServerApp.cpp @@ -19,7 +19,6 @@ #include "deskflow/Screen.h" #include "deskflow/ServerArgs.h" #include "deskflow/XScreen.h" -#include "net/InverseSockets/InverseSocketFactory.h" #include "net/SocketMultiplexer.h" #include "net/TCPSocketFactory.h" #include "net/XSocket.h" @@ -660,15 +659,7 @@ void ServerApp::handleScreenSwitched(const Event &e, void *) ISocketFactory *ServerApp::getSocketFactory() const { - ISocketFactory *socketFactory = nullptr; - - if (args().m_config->isClientMode()) { - socketFactory = new InverseSocketFactory(m_events, getSocketMultiplexer()); - } else { - socketFactory = new TCPSocketFactory(m_events, getSocketMultiplexer()); - } - - return socketFactory; + return new TCPSocketFactory(m_events, getSocketMultiplexer()); } NetworkAddress ServerApp::getAddress(const NetworkAddress &address) const diff --git a/src/lib/gui/config/AppConfig.cpp b/src/lib/gui/config/AppConfig.cpp index d329ffb6d..41eb2c7f2 100644 --- a/src/lib/gui/config/AppConfig.cpp +++ b/src/lib/gui/config/AppConfig.cpp @@ -63,12 +63,12 @@ const char *const AppConfig::m_SettingsName[] = { "preventSleep", "languageSync", "invertScrollDirection", - "", // 31 = guid, obsolete - "", // 32 = licenseRegistryUrl, obsolete - "", // 33 = licenseNextCheck, obsolete - "initiateConnectionFromServer", // kInvertConnection - "", // 35 = clientHostMode, obsolete - "", // 36 = serverClientMode, obsolete + "", // 31 = guid, obsolete + "", // 32 = licenseRegistryUrl, obsolete + "", // 33 = licenseNextCheck, obsolete + "", // 34 = kInvertConnection, obsolete + "", // 35 = clientHostMode, obsolete + "", // 36 = serverClientMode, obsolete "enableService", "closeToTray", "mainWindowSize", @@ -133,7 +133,6 @@ void AppConfig::recallFromCurrentScope() m_PreventSleep = getFromCurrentScope(kPreventSleep, m_PreventSleep).toBool(); m_LanguageSync = getFromCurrentScope(kLanguageSync, m_LanguageSync).toBool(); m_InvertScrollDirection = getFromCurrentScope(kInvertScrollDirection, m_InvertScrollDirection).toBool(); - m_InvertConnection = getFromCurrentScope(kInvertConnection, m_InvertConnection).toBool(); m_EnableService = getFromCurrentScope(kEnableService, m_EnableService).toBool(); m_CloseToTray = getFromCurrentScope(kCloseToTray, m_CloseToTray).toBool(); m_TlsEnabled = getFromCurrentScope(kTlsEnabled, m_TlsEnabled).toBool(); @@ -197,7 +196,6 @@ void AppConfig::commit() setInCurrentScope(kPreventSleep, m_PreventSleep); setInCurrentScope(kLanguageSync, m_LanguageSync); setInCurrentScope(kInvertScrollDirection, m_InvertScrollDirection); - setInCurrentScope(kInvertConnection, m_InvertConnection); setInCurrentScope(kEnableService, m_EnableService); setInCurrentScope(kCloseToTray, m_CloseToTray); setInCurrentScope(kMainWindowSize, m_MainWindowSize); @@ -508,11 +506,6 @@ bool AppConfig::preventSleep() const return m_PreventSleep; } -bool AppConfig::invertConnection() const -{ - return m_InvertConnection; -} - QString AppConfig::tlsCertPath() const { return m_TlsCertPath; @@ -745,12 +738,6 @@ void AppConfig::setCloseToTray(bool minimize) m_CloseToTray = minimize; } -void AppConfig::setInvertConnection(bool value) -{ - m_InvertConnection = value; - Q_EMIT invertConnectionChanged(); -} - void AppConfig::setRequireClientCerts(bool requireClientCerts) { if (requireClientCerts == m_RequireClientCert) diff --git a/src/lib/gui/config/AppConfig.h b/src/lib/gui/config/AppConfig.h index 0756ac88b..a86d85753 100644 --- a/src/lib/gui/config/AppConfig.h +++ b/src/lib/gui/config/AppConfig.h @@ -89,7 +89,7 @@ private: // 31 = guid, obsolete // 32 = license registry url, obsolete // 33 = license next check, obsolete - kInvertConnection = 34, + // 34 = InvertConnection, obsolete // 35 = client-host-mode, obsolete // 36 = server-client-mode, obsolete kEnableService = 37, @@ -145,7 +145,6 @@ public: const QString &logFilename() const override; QString coreServerName() const override; QString coreClientName() const override; - bool invertConnection() const override; void persistLogDir() const override; bool languageSync() const override; bool invertScrollDirection() const override; @@ -200,7 +199,6 @@ public: void setCloseToTray(bool minimize) override; void setTlsCertPath(const QString &path) override; void setTlsKeyLength(int length) override; - void setInvertConnection(bool value) override; void setRequireClientCerts(bool requireClientCerts) override; // @@ -312,7 +310,6 @@ private: bool m_InvertScrollDirection = false; bool m_LanguageSync = true; bool m_PreventSleep = false; - bool m_InvertConnection = false; bool m_ServerGroupChecked = false; bool m_UseExternalConfig = false; QString m_ConfigFile = QStringLiteral("%1/%2.%3").arg(QDir::homePath(), kAppId, s_ConfigFileExt); @@ -345,5 +342,4 @@ private: signals: void tlsChanged(); void screenNameChanged(); - void invertConnectionChanged(); }; diff --git a/src/lib/gui/config/IAppConfig.h b/src/lib/gui/config/IAppConfig.h index a4b5b060c..f4d34255f 100644 --- a/src/lib/gui/config/IAppConfig.h +++ b/src/lib/gui/config/IAppConfig.h @@ -44,7 +44,6 @@ public: virtual const QString &logFilename() const = 0; virtual QString coreServerName() const = 0; virtual QString coreClientName() const = 0; - virtual bool invertConnection() const = 0; virtual void persistLogDir() const = 0; virtual bool languageSync() const = 0; virtual bool invertScrollDirection() const = 0; @@ -83,7 +82,6 @@ public: virtual void setInvertScrollDirection(bool invertScrollDirection) = 0; virtual void setEnableService(bool enableService) = 0; virtual void setCloseToTray(bool closeToTray) = 0; - virtual void setInvertConnection(bool invertConnection) = 0; virtual void setRequireClientCerts(bool requireClientCerts) = 0; }; diff --git a/src/lib/gui/core/CoreProcess.cpp b/src/lib/gui/core/CoreProcess.cpp index c8babb669..af5630b48 100644 --- a/src/lib/gui/core/CoreProcess.cpp +++ b/src/lib/gui/core/CoreProcess.cpp @@ -564,16 +564,6 @@ bool CoreProcess::addServerArgs(QStringList &args, QString &app) return false; } - if (m_appConfig.invertConnection()) { - qDebug("inverting server connection"); - - if (correctedAddress().isEmpty()) { - Q_EMIT error(Error::AddressMissing); - qDebug("address is missing for server args"); - return false; - } - } - // the address arg is dual purpose; when in listening mode, it's the address // that the server listens on. when tcp sockets are inverted, it connects to // that address. this is a bit confusing, and there should be probably be @@ -619,21 +609,14 @@ bool CoreProcess::addClientArgs(QStringList &args, QString &app) args << "--invert-scroll"; } - if (m_appConfig.invertConnection()) { - qDebug("inverting client connection"); - args << "--host"; - args << ":" + QString::number(m_appConfig.port()); - } else { - - if (correctedAddress().isEmpty()) { - Q_EMIT error(Error::AddressMissing); - qDebug("address is missing for client args"); - return false; - } - - args << correctedAddress() + ":" + QString::number(m_appConfig.port()); + if (correctedAddress().isEmpty()) { + Q_EMIT error(Error::AddressMissing); + qDebug("address is missing for client args"); + return false; } + args << correctedAddress() + ":" + QString::number(m_appConfig.port()); + return true; } diff --git a/src/lib/net/CMakeLists.txt b/src/lib/net/CMakeLists.txt index 2a2457018..16e911dd9 100644 --- a/src/lib/net/CMakeLists.txt +++ b/src/lib/net/CMakeLists.txt @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2024 Chris Rizzitello +# SPDX-FileCopyrightText: 2024 - 2025 Chris Rizzitello # SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd # SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton # SPDX-License-Identifier: MIT @@ -36,20 +36,6 @@ add_library(net STATIC TSocketMultiplexerMethodJob.h XSocket.cpp XSocket.h - InverseSockets/AutoArchSocket.cpp - InverseSockets/AutoArchSocket.h - InverseSockets/InverseClientSocket.cpp - InverseSockets/InverseClientSocket.h - InverseSockets/InverseServerSocket.cpp - InverseSockets/InverseServerSocket.h - InverseSockets/InverseSocketFactory.cpp - InverseSockets/InverseSocketFactory.h - InverseSockets/SecureClientSocket.cpp - InverseSockets/SecureClientSocket.h - InverseSockets/SecureServerSocket.cpp - InverseSockets/SecureServerSocket.h - InverseSockets/SslApi.cpp - InverseSockets/SslApi.h ) target_link_libraries( diff --git a/src/lib/net/InverseSockets/AutoArchSocket.cpp b/src/lib/net/InverseSockets/AutoArchSocket.cpp deleted file mode 100644 index a0198b367..000000000 --- a/src/lib/net/InverseSockets/AutoArchSocket.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2022 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "AutoArchSocket.h" - -#include "arch/Arch.h" -#include "arch/XArch.h" -#include "base/Log.h" -#include "net/XSocket.h" - -AutoArchSocket::AutoArchSocket(IArchNetwork::EAddressFamily family) -{ - try { - m_socket = ARCH->newSocket(family, IArchNetwork::kSTREAM); - LOG((CLOG_DEBUG "opening new socket: %08X", m_socket)); - } catch (const XArchNetwork &e) { - throw XSocketCreate(e.what()); - } -} - -AutoArchSocket::~AutoArchSocket() -{ - closeSocket(); -} - -void AutoArchSocket::setNoDelayOnSocket(bool value) -{ - if (isValid()) { - ARCH->setNoDelayOnSocket(m_socket, value); - } -} - -void AutoArchSocket::setReuseAddrOnSocket(bool value) -{ - if (isValid()) { - ARCH->setReuseAddrOnSocket(m_socket, value); - } -} - -void AutoArchSocket::closeSocket() -{ - if (isValid()) { - try { - LOG((CLOG_DEBUG "closing socket: %08X", m_socket)); - ARCH->closeSocket(m_socket); - m_socket = nullptr; - } catch (const XArchNetwork &e) { - // ignore, there's not much we can do - LOG((CLOG_WARN "error closing socket: %s", e.what())); - } - } else { - LOG((CLOG_WARN "error closing socket because the socket already closed")); - } -} - -void AutoArchSocket::bindSocket(const NetworkAddress &addr) -{ - if (isValid()) { - try { - ARCH->bindSocket(m_socket, addr.getAddress()); - } catch (const XArchNetworkAddressInUse &e) { - throw XSocketAddressInUse(e.what()); - } catch (const XArchNetwork &e) { - throw XSocketBind(e.what()); - } - } -} - -void AutoArchSocket::bindAndListen(const NetworkAddress &addr) -{ - try { - setReuseAddrOnSocket(); - bindSocket(addr); - listenOnSocket(); - } catch (const XArchNetworkAddressInUse &e) { - throw XSocketAddressInUse(e.what()); - } catch (const XArchNetwork &e) { - throw XSocketBind(e.what()); - } -} - -void AutoArchSocket::listenOnSocket() -{ - if (isValid()) { - ARCH->listenOnSocket(m_socket); - } -} - -ArchSocket AutoArchSocket::acceptSocket() -{ - return ARCH->acceptSocket(m_socket, nullptr); -} - -void AutoArchSocket::closeSocketForRead() -{ - if (isValid()) { - try { - ARCH->closeSocketForRead(m_socket); - } catch (const XArchNetwork &e) { - // ignore, there's not much we can do - LOG((CLOG_WARN "error closing socket: %s", e.what())); - } - } -} - -void AutoArchSocket::closeSocketForWrite() -{ - if (isValid()) { - try { - ARCH->closeSocketForWrite(m_socket); - } catch (const XArchNetwork &e) { - // ignore, there's not much we can do - LOG((CLOG_WARN "error closing socket: %s", e.what())); - } - } -} - -bool AutoArchSocket::connectSocket(const NetworkAddress &addr) -{ - bool result = false; - - if (isValid()) { - // turn off Nagle algorithm. we send lots of very short messages - // that should be sent without (much) delay. for example, the - // mouse motion messages are much less useful if they're delayed. - setNoDelayOnSocket(); - result = ARCH->connectSocket(m_socket, addr.getAddress()); - } - - return result; -} - -size_t AutoArchSocket::readSocket(uint8_t *buffer, size_t size) -{ - size_t result = 0; - - if (isValid()) { - result = ARCH->readSocket(m_socket, buffer, size); - } - - return result; -} - -size_t AutoArchSocket::writeSocket(const uint8_t *buffer, size_t size) -{ - size_t result = 0; - - if (isValid()) { - result = ARCH->writeSocket(m_socket, buffer, size); - } - - return result; -} - -void AutoArchSocket::throwErrorOnSocket() -{ - if (isValid()) { - ARCH->throwErrorOnSocket(m_socket); - } -} - -ArchSocket AutoArchSocket::getRawSocket() const -{ - return m_socket; -} - -bool AutoArchSocket::isValid() const -{ - return (m_socket != nullptr); -} - -void AutoArchSocket::operator=(ArchSocket socket) -{ - if (isValid()) { - closeSocket(); - } - m_socket = socket; -} diff --git a/src/lib/net/InverseSockets/AutoArchSocket.h b/src/lib/net/InverseSockets/AutoArchSocket.h deleted file mode 100644 index 99226970d..000000000 --- a/src/lib/net/InverseSockets/AutoArchSocket.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2022 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once -#include "net/NetworkAddress.h" - -class AutoArchSocket -{ -public: - explicit AutoArchSocket(IArchNetwork::EAddressFamily family); - ~AutoArchSocket(); - - AutoArchSocket(const AutoArchSocket &) = delete; - AutoArchSocket &operator=(const AutoArchSocket &) = delete; - - void setNoDelayOnSocket(bool value = true); - void setReuseAddrOnSocket(bool value = true); - - void listenOnSocket(); - ArchSocket acceptSocket(); - void bindSocket(const NetworkAddress &addr); - bool connectSocket(const NetworkAddress &addr); - void bindAndListen(const NetworkAddress &addr); - - void closeSocket(); - void closeSocketForRead(); - void closeSocketForWrite(); - - size_t readSocket(uint8_t *buffer, size_t size); - size_t writeSocket(const uint8_t *buffer, size_t size); - void throwErrorOnSocket(); - - bool isValid() const; - ArchSocket getRawSocket() const; - void operator=(ArchSocket socket); - -private: - ArchSocket m_socket = nullptr; -}; diff --git a/src/lib/net/InverseSockets/InverseClientSocket.cpp b/src/lib/net/InverseSockets/InverseClientSocket.cpp deleted file mode 100644 index d06aca13b..000000000 --- a/src/lib/net/InverseSockets/InverseClientSocket.cpp +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2022 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "InverseClientSocket.h" - -#include "arch/Arch.h" -#include "arch/XArch.h" -#include "base/IEventJob.h" -#include "base/IEventQueue.h" -#include "base/Log.h" -#include "mt/Lock.h" -#include "net/NetworkAddress.h" -#include "net/SocketMultiplexer.h" -#include "net/TSocketMultiplexerMethodJob.h" -#include "net/XSocket.h" - -#include -#include -#include - -// -// InverseClientSocket -// - -InverseClientSocket::InverseClientSocket( - IEventQueue *events, SocketMultiplexer *socketMultiplexer, IArchNetwork::EAddressFamily family -) - : IDataSocket(events), - m_events(events), - m_socket(family), - m_listener(family), - m_flushed(&m_mutex, true), - m_socketMultiplexer(socketMultiplexer) -{ -} - -InverseClientSocket::~InverseClientSocket() -{ - try { - // warning virtual function in destructor is very danger practice - InverseClientSocket::close(); - } catch (...) { - LOG((CLOG_DEBUG "error while TCP socket destruction")); - } -} - -void InverseClientSocket::bind(const NetworkAddress &addr) -{ - m_socket.bindSocket(addr); -} - -void InverseClientSocket::close() -{ - setJob(nullptr); - - Lock lock(&m_mutex); - onDisconnected(); -} - -void *InverseClientSocket::getEventTarget() const -{ - return const_cast(static_cast(this)); -} - -uint32_t InverseClientSocket::read(void *buffer, uint32_t n) -{ - // copy data directly from our input buffer - Lock lock(&m_mutex); - uint32_t size = m_inputBuffer.getSize(); - if (n > size) { - n = size; - } - if (buffer != nullptr && n != 0) { - memcpy(buffer, m_inputBuffer.peek(n), n); - } - m_inputBuffer.pop(n); - - // if no more data and we cannot read or write then send disconnected - if (n > 0 && m_inputBuffer.getSize() == 0 && !m_readable && !m_writable) { - sendEvent(m_events->forISocket().disconnected()); - m_connected = false; - } - - return n; -} - -void InverseClientSocket::write(const void *buffer, uint32_t n) -{ - bool wasEmpty; - { - Lock lock(&m_mutex); - - // must not have shutdown output - if (!m_writable) { - sendEvent(m_events->forIStream().outputError()); - return; - } - - // ignore empty writes - if (n == 0) { - return; - } - - // copy data to the output buffer - wasEmpty = (m_outputBuffer.getSize() == 0); - m_outputBuffer.write(buffer, n); - - // there's data to write - m_flushed = false; - } - - // make sure we're waiting to write - if (wasEmpty) { - setJob(newJob(m_socket.getRawSocket())); - } -} - -void InverseClientSocket::flush() -{ - Lock lock(&m_mutex); - while (m_flushed == false) { - m_flushed.wait(); - } -} - -void InverseClientSocket::shutdownInput() -{ - bool useNewJob = false; - { - Lock lock(&m_mutex); - - // shutdown socket for reading - m_socket.closeSocketForRead(); - - // shutdown buffer for reading - if (m_readable) { - sendEvent(m_events->forIStream().inputShutdown()); - onInputShutdown(); - useNewJob = true; - } - } - if (useNewJob) { - setJob(newJob(m_socket.getRawSocket())); - } -} - -void InverseClientSocket::shutdownOutput() -{ - bool useNewJob = false; - { - Lock lock(&m_mutex); - - // shutdown socket for writing - m_socket.closeSocketForWrite(); - - // shutdown buffer for writing - if (m_writable) { - sendEvent(m_events->forIStream().outputShutdown()); - onOutputShutdown(); - useNewJob = true; - } - } - if (useNewJob) { - setJob(newJob(m_socket.getRawSocket())); - } -} - -bool InverseClientSocket::isReady() const -{ - Lock lock(&m_mutex); - return (m_inputBuffer.getSize() > 0); -} - -bool InverseClientSocket::isFatal() const -{ - // TCP sockets aren't ever left in a fatal state. - LOG((CLOG_ERR "isFatal() not valid for non-secure connections")); - return false; -} - -uint32_t InverseClientSocket::getSize() const -{ - Lock lock(&m_mutex); - return m_inputBuffer.getSize(); -} - -void InverseClientSocket::connect(const NetworkAddress &addr) -{ - { - Lock lock(&m_mutex); - m_listener.bindAndListen(addr); - m_writable = true; - m_readable = true; - } - setJob(newJob(m_listener.getRawSocket())); -} - -InverseClientSocket::EJobResult InverseClientSocket::doRead() -{ - uint8_t buffer[4096] = {0}; - size_t bytesRead = m_socket.readSocket(buffer, sizeof(buffer)); - - if (bytesRead > 0) { - bool wasEmpty = (m_inputBuffer.getSize() == 0); - - // slurp up as much as possible - do { - m_inputBuffer.write(buffer, static_cast(bytesRead)); - - bytesRead = m_socket.readSocket(buffer, sizeof(buffer)); - } while (bytesRead > 0); - - // send input ready if input buffer was empty - if (wasEmpty) { - sendEvent(m_events->forIStream().inputReady()); - } - } else { - // remote write end of stream hungup. our input side - // has therefore shutdown but don't flush our buffer - // since there's still data to be read. - sendEvent(m_events->forIStream().inputShutdown()); - if (!m_writable && m_inputBuffer.getSize() == 0) { - sendEvent(m_events->forISocket().disconnected()); - m_connected = false; - } - m_readable = false; - return InverseClientSocket::EJobResult::kNew; - } - - return InverseClientSocket::EJobResult::kRetry; -} - -InverseClientSocket::EJobResult InverseClientSocket::doWrite() -{ - uint32_t bufferSize = m_outputBuffer.getSize(); - auto buffer = static_cast(m_outputBuffer.peek(bufferSize)); - const auto bytesWrote = static_cast(m_socket.writeSocket(buffer, bufferSize)); - - if (bytesWrote > 0) { - discardWrittenData(bytesWrote); - return InverseClientSocket::EJobResult::kNew; - } - - return InverseClientSocket::EJobResult::kRetry; -} - -void InverseClientSocket::setJob(ISocketMultiplexerJob *job) -{ - // multiplexer will delete the old job - if (job == nullptr) { - m_socketMultiplexer->removeSocket(this); - } else { - m_socketMultiplexer->addSocket(this, job); - } -} - -ISocketMultiplexerJob *InverseClientSocket::newJob(ArchSocket socket) -{ - // note -- must have m_mutex locked on entry - - ISocketMultiplexerJob *result = nullptr; - - if (socket) { - auto isWritable = m_writable; - auto handler = &InverseClientSocket::serviceConnecting; - - if (m_connected) { - handler = &InverseClientSocket::serviceConnected; - isWritable = (isWritable && (m_outputBuffer.getSize() > 0)); - } - - if (m_readable || isWritable) { - result = new TSocketMultiplexerMethodJob(this, handler, socket, m_readable, isWritable); - } - } - - return result; -} - -void InverseClientSocket::sendConnectionFailedEvent(const char *msg) -{ - auto info = new ConnectionFailedInfo(msg); - m_events->addEvent(Event(m_events->forIDataSocket().connectionFailed(), getEventTarget(), info, Event::kDontFreeData) - ); -} - -void InverseClientSocket::sendEvent(Event::Type type) -{ - m_events->addEvent(Event(type, getEventTarget())); -} - -void InverseClientSocket::discardWrittenData(int bytesWrote) -{ - m_outputBuffer.pop(bytesWrote); - if (m_outputBuffer.getSize() == 0) { - sendEvent(m_events->forIStream().outputFlushed()); - m_flushed = true; - m_flushed.broadcast(); - } -} - -void InverseClientSocket::onConnected() -{ - sendEvent(m_events->forIDataSocket().connected()); - m_connected = true; - m_readable = true; - m_writable = true; -} - -void InverseClientSocket::onInputShutdown() -{ - m_inputBuffer.pop(m_inputBuffer.getSize()); - m_readable = false; -} - -void InverseClientSocket::onOutputShutdown() -{ - m_outputBuffer.pop(m_outputBuffer.getSize()); - m_writable = false; - - // we're now flushed - m_flushed = true; - m_flushed.broadcast(); -} - -void InverseClientSocket::onDisconnected() -{ - if (m_connected) { - sendEvent(m_events->forISocket().disconnected()); - } - // disconnected - onInputShutdown(); - onOutputShutdown(); - m_connected = false; -} - -ISocketMultiplexerJob *InverseClientSocket::serviceConnecting(ISocketMultiplexerJob *job, bool read, bool, bool) -{ - Lock lock(&m_mutex); - - if (read) { - m_socket = m_listener.acceptSocket(); - onConnected(); - return newJob(m_socket.getRawSocket()); - } - - return job; -} - -ISocketMultiplexerJob * -InverseClientSocket::serviceConnected(ISocketMultiplexerJob *job, bool read, bool write, bool error) -{ - Lock lock(&m_mutex); - - if (error) { - onDisconnected(); - return newJob(m_listener.getRawSocket()); - } - - EJobResult result = InverseClientSocket::EJobResult::kRetry; - if (write) { - try { - result = doWrite(); - } catch (const XArchNetworkShutdown &) { - // remote read end of stream hungup. our output side - // has therefore shutdown. - onOutputShutdown(); - sendEvent(m_events->forIStream().outputShutdown()); - if (!m_readable && m_inputBuffer.getSize() == 0) { - sendEvent(m_events->forISocket().disconnected()); - m_connected = false; - } - result = InverseClientSocket::EJobResult::kNew; - } catch (const XArchNetworkDisconnected &) { - // stream hungup - onDisconnected(); - result = InverseClientSocket::EJobResult::kNew; - } catch (const XArchNetwork &e) { - // other write error - LOG((CLOG_WARN "error writing socket: %s", e.what())); - onDisconnected(); - sendEvent(m_events->forIStream().outputError()); - result = InverseClientSocket::EJobResult::kNew; - } - } - - if (read && m_readable) { - try { - result = doRead(); - } catch (const XArchNetworkDisconnected &) { - // stream hungup - onDisconnected(); - result = InverseClientSocket::EJobResult::kNew; - } catch (const XArchNetwork &e) { - // ignore other read error - LOG((CLOG_WARN "error reading socket: %s", e.what())); - } - } - - if (result == InverseClientSocket::EJobResult::kBreak) { - return nullptr; - } - - return result == InverseClientSocket::EJobResult::kNew ? newJob(m_socket.getRawSocket()) : job; -} diff --git a/src/lib/net/InverseSockets/InverseClientSocket.h b/src/lib/net/InverseSockets/InverseClientSocket.h deleted file mode 100644 index 96ec1a998..000000000 --- a/src/lib/net/InverseSockets/InverseClientSocket.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2022 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include "AutoArchSocket.h" -#include "arch/IArchNetwork.h" -#include "io/StreamBuffer.h" -#include "mt/CondVar.h" -#include "mt/Mutex.h" -#include "net/IDataSocket.h" - -class ISocketMultiplexerJob; -class IEventQueue; -class SocketMultiplexer; - -class InverseClientSocket : public IDataSocket -{ -public: - InverseClientSocket( - IEventQueue *events, SocketMultiplexer *socketMultiplexer, - IArchNetwork::EAddressFamily family = IArchNetwork::kINET - ); - InverseClientSocket(InverseClientSocket const &) = delete; - InverseClientSocket(InverseClientSocket &&) = delete; - ~InverseClientSocket() override; - - InverseClientSocket &operator=(InverseClientSocket const &) = delete; - InverseClientSocket &operator=(InverseClientSocket &&) = delete; - - // ISocket overrides - void bind(const NetworkAddress &) override; - void close() override; - void *getEventTarget() const override; - - // IStream overrides - uint32_t read(void *buffer, uint32_t n) override; - void write(const void *buffer, uint32_t n) override; - void flush() override; - void shutdownInput() override; - void shutdownOutput() override; - bool isReady() const override; - bool isFatal() const override; - uint32_t getSize() const override; - - // IDataSocket overrides - void connect(const NetworkAddress &) override; - - virtual ISocketMultiplexerJob *newJob(ArchSocket socket); - -protected: - enum class EJobResult - { - kBreak = -1, //!< Break the Job chain - kRetry, //!< Retry the same job - kNew //!< Require a new job - }; - - ArchSocket getSocket() - { - return m_socket.getRawSocket(); - } - IEventQueue *getEvents() - { - return m_events; - } - virtual EJobResult doRead(); - virtual EJobResult doWrite(); - - void setJob(ISocketMultiplexerJob *); - - bool isReadable() const - { - return m_readable; - } - bool isWritable() const - { - return m_writable; - } - - Mutex &getMutex() - { - return m_mutex; - } - - void sendEvent(Event::Type); - void discardWrittenData(int bytesWrote); - -private: - void sendConnectionFailedEvent(const char *); - void onConnected(); - void onInputShutdown(); - void onOutputShutdown(); - void onDisconnected(); - - ISocketMultiplexerJob *serviceConnecting(ISocketMultiplexerJob *, bool, bool, bool); - ISocketMultiplexerJob *serviceConnected(ISocketMultiplexerJob *, bool, bool, bool); - -protected: - bool m_readable = false; - bool m_writable = false; - bool m_connected = false; - IEventQueue *m_events; - StreamBuffer m_inputBuffer; - StreamBuffer m_outputBuffer; - Mutex m_mutex; - AutoArchSocket m_socket; - AutoArchSocket m_listener; - CondVar m_flushed; - SocketMultiplexer *m_socketMultiplexer; -}; diff --git a/src/lib/net/InverseSockets/InverseServerSocket.cpp b/src/lib/net/InverseSockets/InverseServerSocket.cpp deleted file mode 100644 index d8f4bbe3c..000000000 --- a/src/lib/net/InverseSockets/InverseServerSocket.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2022 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "InverseServerSocket.h" - -#include "arch/Arch.h" -#include "arch/XArch.h" -#include "base/IEventQueue.h" -#include "base/Log.h" -#include "io/XIO.h" -#include "mt/Lock.h" -#include "mt/Mutex.h" -#include "net/NetworkAddress.h" -#include "net/SocketMultiplexer.h" -#include "net/TCPSocket.h" -#include "net/TSocketMultiplexerMethodJob.h" -#include "net/XSocket.h" - -// -// InverseServerSocket -// - -InverseServerSocket::InverseServerSocket( - IEventQueue *events, SocketMultiplexer *socketMultiplexer, IArchNetwork::EAddressFamily family -) - : m_socket(family), - m_events(events), - m_socketMultiplexer(socketMultiplexer) -{ -} - -InverseServerSocket::~InverseServerSocket() -{ - m_socketMultiplexer->removeSocket(this); -} - -void InverseServerSocket::bind(const NetworkAddress &addr) -{ - Lock lock(&m_mutex); - m_address = addr; - m_socket.connectSocket(m_address); - setListeningJob(true); -} - -void InverseServerSocket::close() -{ - Lock lock(&m_mutex); - m_socketMultiplexer->removeSocket(this); - m_socket.closeSocket(); -} - -void *InverseServerSocket::getEventTarget() const -{ - return const_cast(static_cast(this)); -} - -IDataSocket *InverseServerSocket::accept() -{ - IDataSocket *socket = nullptr; - try { - socket = new TCPSocket(m_events, m_socketMultiplexer, m_socket.getRawSocket()); - if (socket != nullptr) { - setListeningJob(); - } - return socket; - } catch (const XArchNetwork &) { - if (socket != nullptr) { - delete socket; - setListeningJob(); - } - return nullptr; - } catch (const std::exception &) { - if (socket != nullptr) { - delete socket; - setListeningJob(); - } - throw; - } -} - -void InverseServerSocket::setListeningJob(bool read) -{ - m_socketMultiplexer->addSocket( - this, new TSocketMultiplexerMethodJob( - this, &InverseServerSocket::serviceListening, m_socket.getRawSocket(), true, read - ) - ); -} - -ISocketMultiplexerJob *InverseServerSocket::serviceListening(ISocketMultiplexerJob *job, bool, bool write, bool error) -{ - if (error) { - m_socket.connectSocket(m_address); - return job; - } - if (write) { - m_events->addEvent(Event(m_events->forIListenSocket().connecting(), this)); - // stop polling on this socket until the client accepts - return nullptr; - } - return job; -} diff --git a/src/lib/net/InverseSockets/InverseServerSocket.h b/src/lib/net/InverseSockets/InverseServerSocket.h deleted file mode 100644 index 9d544b0c1..000000000 --- a/src/lib/net/InverseSockets/InverseServerSocket.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2022 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include "AutoArchSocket.h" -#include "arch/IArchNetwork.h" -#include "mt/Mutex.h" -#include "net/IListenSocket.h" - -class ISocketMultiplexerJob; -class IEventQueue; -class SocketMultiplexer; - -class InverseServerSocket : public IListenSocket -{ -public: - InverseServerSocket(IEventQueue *events, SocketMultiplexer *socketMultiplexer, IArchNetwork::EAddressFamily family); - InverseServerSocket(InverseServerSocket const &) = delete; - InverseServerSocket(InverseServerSocket &&) = delete; - ~InverseServerSocket() override; - - InverseServerSocket &operator=(InverseServerSocket const &) = delete; - InverseServerSocket &operator=(InverseServerSocket &&) = delete; - - // ISocket overrides - void bind(const NetworkAddress &) override; - void close() override; - void *getEventTarget() const override; - - // IListenSocket overrides - IDataSocket *accept() override; - -protected: - void setListeningJob(bool read = false); - -public: - ISocketMultiplexerJob *serviceListening(ISocketMultiplexerJob *, bool, bool, bool); - -protected: - AutoArchSocket m_socket; - Mutex m_mutex; - IEventQueue *m_events; - SocketMultiplexer *m_socketMultiplexer; - -private: - NetworkAddress m_address; -}; diff --git a/src/lib/net/InverseSockets/InverseSocketFactory.cpp b/src/lib/net/InverseSockets/InverseSocketFactory.cpp deleted file mode 100644 index 00cc5edbd..000000000 --- a/src/lib/net/InverseSockets/InverseSocketFactory.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers - * SPDX-FileCopyrightText: (C) 2012 - 2022 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "InverseSocketFactory.h" -#include "net/InverseSockets/InverseClientSocket.h" -#include "net/InverseSockets/InverseServerSocket.h" -#include "net/InverseSockets/SecureClientSocket.h" -#include "net/InverseSockets/SecureServerSocket.h" - -// -// InverseSocketFactory -// - -InverseSocketFactory::InverseSocketFactory(IEventQueue *events, SocketMultiplexer *socketMultiplexer) - : m_events(events), - m_socketMultiplexer(socketMultiplexer) -{ -} - -IDataSocket *InverseSocketFactory::create(IArchNetwork::EAddressFamily family, SecurityLevel securityLevel) const -{ - if (securityLevel != SecurityLevel::PlainText) { - auto secureSocket = new SecureClientSocket(m_events, m_socketMultiplexer, family); - return secureSocket; - } else { - return new InverseClientSocket(m_events, m_socketMultiplexer, family); - } -} - -IListenSocket * -InverseSocketFactory::createListen(IArchNetwork::EAddressFamily family, SecurityLevel securityLevel) const -{ - IListenSocket *socket = nullptr; - - if (securityLevel != SecurityLevel::PlainText) { - socket = new SecureServerSocket(m_events, m_socketMultiplexer, family); - } else { - socket = new InverseServerSocket(m_events, m_socketMultiplexer, family); - } - - return socket; -} diff --git a/src/lib/net/InverseSockets/InverseSocketFactory.h b/src/lib/net/InverseSockets/InverseSocketFactory.h deleted file mode 100644 index 10de223b0..000000000 --- a/src/lib/net/InverseSockets/InverseSocketFactory.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers - * SPDX-FileCopyrightText: (C) 2012 - 2022 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once -#include "net/ISocketFactory.h" - -class IEventQueue; -class SocketMultiplexer; - -class InverseSocketFactory : public ISocketFactory -{ -public: - InverseSocketFactory(IEventQueue *events, SocketMultiplexer *socketMultiplexer); - - // ISocketFactory overrides - IDataSocket *create( - IArchNetwork::EAddressFamily family = IArchNetwork::kINET, SecurityLevel securityLevel = SecurityLevel::PlainText - ) const override; - IListenSocket *createListen( - IArchNetwork::EAddressFamily family = IArchNetwork::kINET, SecurityLevel securityLevel = SecurityLevel::PlainText - ) const override; - -private: - IEventQueue *m_events = nullptr; - SocketMultiplexer *m_socketMultiplexer = nullptr; -}; diff --git a/src/lib/net/InverseSockets/SecureClientSocket.cpp b/src/lib/net/InverseSockets/SecureClientSocket.cpp deleted file mode 100644 index c534cc92a..000000000 --- a/src/lib/net/InverseSockets/SecureClientSocket.cpp +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2015 - 2022 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "SecureClientSocket.h" -#include "../SslLogger.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include - -// -// SecureClientSocket -// -constexpr float s_retryDelay = 0.01f; - -SecureClientSocket::SecureClientSocket( - IEventQueue *events, SocketMultiplexer *socketMultiplexer, IArchNetwork::EAddressFamily family -) - : InverseClientSocket(events, socketMultiplexer, family) -{ -} - -void SecureClientSocket::connect(const NetworkAddress &addr) -{ - m_events->adoptHandler( - m_events->forIDataSocket().connected(), getEventTarget(), - new TMethodEventJob(this, &SecureClientSocket::handleTCPConnected) - ); - - InverseClientSocket::connect(addr); -} - -ISocketMultiplexerJob *SecureClientSocket::newJob() -{ - // after TCP connection is established, SecureClientSocket will pick up - // connected event and do secureConnect - if (m_connected && !m_secureReady) { - return nullptr; - } - - return InverseClientSocket::newJob(getSocket()); -} - -void SecureClientSocket::secureConnect() -{ - setJob(new TSocketMultiplexerMethodJob( - this, &SecureClientSocket::serviceConnect, getSocket(), isReadable(), isWritable() - )); -} - -void SecureClientSocket::secureAccept() -{ - setJob(new TSocketMultiplexerMethodJob( - this, &SecureClientSocket::serviceAccept, getSocket(), isReadable(), isWritable() - )); -} - -InverseClientSocket::EJobResult SecureClientSocket::doRead() -{ - uint8_t buffer[4096] = {0}; - int bytesRead = 0; - int status = 0; - - if (isSecureReady()) { - status = secureRead(buffer, sizeof(buffer), bytesRead); - - if (status < 0) { - return InverseClientSocket::EJobResult::kBreak; - } else if (status == 0) { - return InverseClientSocket::EJobResult::kNew; - } - } else { - return InverseClientSocket::EJobResult::kRetry; - } - - if (bytesRead > 0) { - bool wasEmpty = (m_inputBuffer.getSize() == 0); - - // slurp up as much as possible - do { - m_inputBuffer.write(buffer, bytesRead); - - status = secureRead(buffer, sizeof(buffer), bytesRead); - if (status < 0) { - return InverseClientSocket::EJobResult::kBreak; - } - } while (bytesRead > 0 || status > 0); - - // send input ready if input buffer was empty - if (wasEmpty) { - sendEvent(m_events->forIStream().inputReady()); - } - } else { - // remote write end of stream hungup. our input side - // has therefore shutdown but don't flush our buffer - // since there's still data to be read. - sendEvent(m_events->forIStream().inputShutdown()); - if (!m_writable && m_inputBuffer.getSize() == 0) { - sendEvent(m_events->forISocket().disconnected()); - m_connected = false; - } - m_readable = false; - return InverseClientSocket::EJobResult::kNew; - } - - return InverseClientSocket::EJobResult::kRetry; -} - -InverseClientSocket::EJobResult SecureClientSocket::doWrite() -{ - static bool s_retry = false; - static int s_retrySize = 0; - static int s_staticBufferSize = 0; - static void *s_staticBuffer = nullptr; - - // write data - int bufferSize = 0; - int bytesWrote = 0; - int status = 0; - - if (s_retry) { - bufferSize = s_retrySize; - } else { - bufferSize = m_outputBuffer.getSize(); - if (bufferSize != 0) { - if (bufferSize > s_staticBufferSize) { - s_staticBuffer = realloc(s_staticBuffer, bufferSize); - s_staticBufferSize = bufferSize; - } - memcpy(s_staticBuffer, m_outputBuffer.peek(bufferSize), bufferSize); - } - } - - if (bufferSize == 0) { - return InverseClientSocket::EJobResult::kRetry; - } - - if (isSecureReady()) { - status = secureWrite(s_staticBuffer, bufferSize, bytesWrote); - if (status > 0) { - s_retry = false; - } else if (status < 0) { - return InverseClientSocket::EJobResult::kBreak; - } else if (status == 0) { - s_retry = true; - s_retrySize = bufferSize; - return InverseClientSocket::EJobResult::kNew; - } - } else { - return InverseClientSocket::EJobResult::kRetry; - } - - if (bytesWrote > 0) { - discardWrittenData(bytesWrote); - return InverseClientSocket::EJobResult::kNew; - } - - return InverseClientSocket::EJobResult::kRetry; -} - -int SecureClientSocket::secureRead(void *buffer, int size, int &read) -{ - LOG((CLOG_DEBUG2 "reading secure socket")); - read = m_ssl.read(static_cast(buffer), size); - - static int retry = 0; - - // Check result will cleanup the connection in the case of a fatal - checkResult(read, retry); - - if (retry) { - return 0; - } - - if (isFatal()) { - return -1; - } - // According to SSL spec, the number of bytes read must not be negative and - // not have an error code from SSL_get_error(). If this happens, it is - // itself an error. Let the parent handle the case - return read; -} - -int SecureClientSocket::secureWrite(const void *buffer, int size, int &wrote) -{ - LOG((CLOG_DEBUG2 "writing secure socket: %p", this)); - wrote = m_ssl.write(static_cast(buffer), size); - - static int retry = 0; - - // Check result will cleanup the connection in the case of a fatal - checkResult(wrote, retry); - - if (retry) { - return 0; - } - - if (isFatal()) { - return -1; - } - - // According to SSL spec, r must not be negative and not have an error code - // from SSL_get_error(). If this happens, it is itself an error. Let the - // parent handle the case - return wrote; -} - -bool SecureClientSocket::isSecureReady() const -{ - return m_secureReady; -} - -bool SecureClientSocket::loadCertificates(const std::string &filename) -{ - return m_ssl.loadCertificate(filename); -} - -int SecureClientSocket::secureAccept(int socket) -{ - LOG((CLOG_DEBUG2 "accepting secure socket")); - static int retry = 0; - checkResult(m_ssl.accept(socket), retry); - - if (isFatal()) { - // tell user and sleep so the socket isn't hammered. - LOG((CLOG_ERR "failed to accept secure socket")); - LOG((CLOG_WARN "client connection may not be secure")); - m_secureReady = false; - ARCH->sleep(1); - retry = 0; - return -1; // Failed, error out - } - - // If not fatal and no retry, state is good - if (retry == 0) { - m_secureReady = true; - LOG((CLOG_INFO "accepted secure socket")); - m_ssl.logSecureInfo(); - return 1; - } - - // If not fatal and retry is set, not ready, and return retry - if (retry > 0) { - LOG((CLOG_DEBUG2 "retry accepting secure socket")); - m_secureReady = false; - ARCH->sleep(s_retryDelay); - return 0; - } - - // no good state exists here - LOG((CLOG_ERR "unexpected state attempting to accept connection")); - return -1; -} - -int SecureClientSocket::secureConnect(int socket) -{ - LOG((CLOG_DEBUG2 "connecting secure socket")); - static int retry = 0; - checkResult(m_ssl.connect(socket), retry); - - if (isFatal()) { - LOG((CLOG_ERR "failed to connect secure socket")); - retry = 0; - return -1; - } - - // If we should retry, not ready and return 0 - if (retry > 0) { - LOG((CLOG_DEBUG2 "retry connect secure socket")); - m_secureReady = false; - ARCH->sleep(s_retryDelay); - return 0; - } - - retry = 0; - // No error, set ready, process and return ok - m_secureReady = true; - sendEvent(m_events->forIDataSocket().secureConnected()); - - auto fingerprint = m_ssl.getFingerprint(); - LOG((CLOG_NOTE "server fingerprint: %s", fingerprint.c_str())); - - if (m_ssl.isTrustedFingerprint(fingerprint)) { - LOG((CLOG_INFO "connected to secure socket")); - m_ssl.logSecureInfo(); - return 1; - } else { - LOG((CLOG_ERR "failed to verify server certificate fingerprint")); - disconnect(); - return -1; // Fingerprint failed, error - } -} - -void SecureClientSocket::setFatal(int code) -{ - const std::set nonFatal{ - SSL_ERROR_NONE, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT - }; - m_fatal = nonFatal.find(code) == nonFatal.end(); -} - -int SecureClientSocket::getRetry(int errorCode, int retry) const -{ - const std::set retryCodes{ - SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT - }; - - if (errorCode == SSL_ERROR_NONE || isFatal()) { - retry = 0; - } else if (retryCodes.find(errorCode) != retryCodes.end()) { - ++retry; - } - - return retry; -} - -void SecureClientSocket::checkResult(int status, int &retry) -{ - // ssl errors are a little quirky. the "want" errors are normal and - // should result in a retry. - int errorCode = m_ssl.getErrorCode(status); - setFatal(errorCode); - retry = getRetry(errorCode, retry); - - switch (errorCode) { - case SSL_ERROR_WANT_WRITE: - // Need to make sure the socket is known to be writable so the impending - // select action actually triggers on a write. This isn't necessary for - // m_readable because the socket logic is always readable - m_writable = true; - break; - - case SSL_ERROR_SYSCALL: - if (ERR_peek_error() == 0) { - if (status == 0) { - LOG((CLOG_ERR "eof violates tls protocol")); - } else if (status == -1) { - // underlying socket I/O reproted an error - try { - ARCH->throwErrorOnSocket(getSocket()); - } catch (const XArchNetwork &e) { - LOG((CLOG_ERR "%s", e.what())); - } - } - } - break; - default: - break; - } - - SslLogger::logErrorByCode(errorCode, retry); - - if (isFatal()) { - SslLogger::logError(); - disconnect(); - } -} - -void SecureClientSocket::disconnect() -{ - sendEvent(getEvents()->forISocket().stopRetry()); - sendEvent(getEvents()->forISocket().disconnected()); - sendEvent(getEvents()->forIStream().inputShutdown()); -} - -ISocketMultiplexerJob *SecureClientSocket::serviceConnect(ISocketMultiplexerJob *, bool, bool, bool) -{ - Lock lock(&getMutex()); - - int status = 0; - -#ifdef SYSAPI_WIN32 - status = secureConnect(static_cast(getSocket()->m_socket)); -#elif SYSAPI_UNIX - status = secureConnect(getSocket()->m_fd); -#endif - - // If status < 0, error happened - if (status < 0) { - return nullptr; - } - - // If status > 0, success - if (status > 0) { - sendEvent(m_events->forIDataSocket().secureConnected()); - return newJob(); - } - - // Retry case - return new TSocketMultiplexerMethodJob( - this, &SecureClientSocket::serviceConnect, getSocket(), isReadable(), isWritable() - ); -} - -ISocketMultiplexerJob *SecureClientSocket::serviceAccept(ISocketMultiplexerJob *, bool, bool, bool) -{ - Lock lock(&getMutex()); - - int status = 0; -#ifdef SYSAPI_WIN32 - status = secureAccept(static_cast(getSocket()->m_socket)); -#elif SYSAPI_UNIX - status = secureAccept(getSocket()->m_fd); -#endif - // If status < 0, error happened - if (status < 0) { - return nullptr; - } - - // If status > 0, success - if (status > 0) { - sendEvent(m_events->forClientListener().accepted()); - return newJob(); - } - - // Retry case - return new TSocketMultiplexerMethodJob( - this, &SecureClientSocket::serviceAccept, getSocket(), isReadable(), isWritable() - ); -} - -void SecureClientSocket::handleTCPConnected(const Event &, void *) -{ - if (getSocket()) { - secureConnect(); - } else { - LOG((CLOG_DEBUG "disregarding stale connect event")); - } -} diff --git a/src/lib/net/InverseSockets/SecureClientSocket.h b/src/lib/net/InverseSockets/SecureClientSocket.h deleted file mode 100644 index b33af61cc..000000000 --- a/src/lib/net/InverseSockets/SecureClientSocket.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2015 - 2022 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once -#include "InverseClientSocket.h" -#include "SslApi.h" - -//! Secure socket -/*! -A secure socket using SSL. -*/ -class SecureClientSocket : public InverseClientSocket -{ -public: - SecureClientSocket(IEventQueue *events, SocketMultiplexer *socketMultiplexer, IArchNetwork::EAddressFamily family); - SecureClientSocket(SecureClientSocket const &) = delete; - SecureClientSocket(SecureClientSocket &&) = delete; - - SecureClientSocket &operator=(SecureClientSocket const &) = delete; - SecureClientSocket &operator=(SecureClientSocket &&) = delete; - - // IDataSocket overrides - void connect(const NetworkAddress &) override; - - ISocketMultiplexerJob *newJob(); - bool isFatal() const override - { - return m_fatal; - } - void setFatal(int code); - int getRetry(int errorCode, int retry) const; - bool isSecureReady() const; - void secureConnect(); - void secureAccept(); - int secureRead(void *buffer, int size, int &read); - int secureWrite(const void *buffer, int size, int &wrote); - EJobResult doRead() override; - EJobResult doWrite() override; - bool loadCertificates(const std::string &CertFile); - -private: - // SSL - void initContext(bool server); - int secureAccept(int s); - int secureConnect(int s); - void checkResult(int n, int &retry); - void disconnect(); - - ISocketMultiplexerJob *serviceConnect(ISocketMultiplexerJob *, bool, bool, bool); - - ISocketMultiplexerJob *serviceAccept(ISocketMultiplexerJob *, bool, bool, bool); - - void handleTCPConnected(const Event &, void *); - - deskflow::ssl::SslApi m_ssl{false}; - bool m_secureReady = false; - bool m_fatal = false; -}; diff --git a/src/lib/net/InverseSockets/SecureServerSocket.cpp b/src/lib/net/InverseSockets/SecureServerSocket.cpp deleted file mode 100644 index d09113bbc..000000000 --- a/src/lib/net/InverseSockets/SecureServerSocket.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2015 - 2022 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "SecureServerSocket.h" - -#include -#include -#include -#include -#include -#include -#include - -// -// SecureServerSocket -// -SecureServerSocket::SecureServerSocket( - IEventQueue *events, SocketMultiplexer *socketMultiplexer, IArchNetwork::EAddressFamily family -) - : InverseServerSocket(events, socketMultiplexer, family) -{ -} - -IDataSocket *SecureServerSocket::accept() -{ - SecureSocket *socket = nullptr; - - try { - socket = new SecureSocket(m_events, m_socketMultiplexer, m_socket.getRawSocket()); - socket->initSsl(true); - setListeningJob(); - - auto certificateFilename = getCertificateFileName(); - if (socket->loadCertificates(certificateFilename)) { - socket->secureAccept(); - } else { - delete socket; - socket = nullptr; - } - } catch (const XArchNetwork &) { - if (socket) { - delete socket; - socket = nullptr; - setListeningJob(); - } - } catch (const std::exception &) { - if (socket) { - delete socket; - setListeningJob(); - } - throw; - } - - return dynamic_cast(socket); -} - -std::string SecureServerSocket::getCertificateFileName() const -{ - // if the tls cert option is set use that for the certificate file - auto certificateFilename = ArgParser::argsBase().m_tlsCertFile; - - if (certificateFilename.empty()) { - // TODO: Reduce duplication of these strings between here and - // SecureSocket.cpp - certificateFilename = deskflow::string::sprintf("%s/tls/%s.pem", ARCH->getProfileDirectory().c_str(), kAppId); - } - - return certificateFilename; -} diff --git a/src/lib/net/InverseSockets/SecureServerSocket.h b/src/lib/net/InverseSockets/SecureServerSocket.h deleted file mode 100644 index d4090386a..000000000 --- a/src/lib/net/InverseSockets/SecureServerSocket.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2015 - 2022 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once -#include "InverseServerSocket.h" - -class SecureServerSocket : public InverseServerSocket -{ -public: - SecureServerSocket(IEventQueue *events, SocketMultiplexer *socketMultiplexer, IArchNetwork::EAddressFamily family); - - // IListenSocket overrides - IDataSocket *accept() override; - -private: - std::string getCertificateFileName() const; -}; diff --git a/src/lib/net/InverseSockets/SslApi.cpp b/src/lib/net/InverseSockets/SslApi.cpp deleted file mode 100644 index a311074fe..000000000 --- a/src/lib/net/InverseSockets/SslApi.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2015 - 2022 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "SslApi.h" -#include "../SslLogger.h" - -#include -#include - -#include -#include -#include -#include - -namespace deskflow { -namespace ssl { - -using AutoX509 = std::unique_ptr; - -SslApi::SslApi(bool isServer) -{ - SSL_library_init(); - // load & register all cryptos, etc. - OpenSSL_add_all_algorithms(); - // load all error messages - SSL_load_error_strings(); - createContext(isServer); - SslLogger::logSecureLibInfo(); -} - -SslApi::~SslApi() -{ - if (m_ssl) { - SSL_shutdown(m_ssl); - SSL_free(m_ssl); - m_ssl = nullptr; - } - - if (m_context) { - SSL_CTX_free(m_context); - m_context = nullptr; - } -} - -int SslApi::read(char *buffer, int size) -{ - auto read = 0; - - if (m_ssl) { - read = SSL_read(m_ssl, buffer, size); - } - - return read; -} - -int SslApi::write(const char *buffer, int size) -{ - auto wrote = 0; - - if (m_ssl) { - wrote = SSL_write(m_ssl, buffer, size); - } - - return wrote; -} - -int SslApi::accept(int socket) -{ - int result = 0; - - if (m_ssl) { - // set connection socket to SSL state - SSL_set_fd(m_ssl, socket); - result = SSL_accept(m_ssl); - } - - return result; -} - -int SslApi::connect(int socket) -{ - auto result = 0; - - if (m_ssl) { - // attach the socket descriptor - SSL_set_fd(m_ssl, socket); - result = SSL_connect(m_ssl); - } - - return result; -} - -void SslApi::createSSL() -{ - if (m_ssl == nullptr && m_context != nullptr) { - m_ssl = SSL_new(m_context); - } -} - -bool SslApi::loadCertificate(const std::string &filename) -{ - bool result = false; - - if (isCertificateExists(filename)) { - auto r = SSL_CTX_use_certificate_file(m_context, filename.c_str(), SSL_FILETYPE_PEM); - if (r <= 0) { - SslLogger::logError("could not use tls certificate"); - return false; - } - - r = SSL_CTX_use_PrivateKey_file(m_context, filename.c_str(), SSL_FILETYPE_PEM); - if (r <= 0) { - SslLogger::logError("could not use tls private key"); - return false; - } - - r = SSL_CTX_check_private_key(m_context); - if (!r) { - SslLogger::logError("could not verify tls private key"); - return false; - } - } - - return result; -} - -bool SslApi::showCertificate() const -{ - bool result = false; - - if (m_ssl) { - // get the server's certificate - AutoX509 cert(SSL_get_peer_certificate(m_ssl), &X509_free); - if (cert) { - auto line = X509_NAME_oneline(X509_get_subject_name(cert.get()), nullptr, 0); - LOG((CLOG_INFO "server tls certificate info: %s", line)); - OPENSSL_free(line); - result = true; - } else { - SslLogger::logError("server has no tls certificate"); - } - } - - return result; -} - -std::string SslApi::getFingerprint() const -{ - // calculate received certificate fingerprint - AutoX509 cert(SSL_get_peer_certificate(m_ssl), &X509_free); - unsigned int tempFingerprintLen = 0; - unsigned char tempFingerprint[EVP_MAX_MD_SIZE] = {0}; - int digestResult = X509_digest(cert.get(), EVP_sha256(), tempFingerprint, &tempFingerprintLen); - - if (digestResult <= 0) { - LOG((CLOG_ERR "failed to calculate fingerprint, digest result: %d", digestResult)); - return ""; - } - - // format fingerprint into hexdecimal format with colon separator - std::string fingerprint(static_cast(static_cast(tempFingerprint)), tempFingerprintLen); - formatFingerprint(fingerprint); - - return fingerprint; -} - -bool SslApi::isTrustedFingerprint(const std::string &fingerprint) const -{ - // TODO: Reduce duplication of these strings between here and SecureSocket.cpp - auto trustedServersFilename = - deskflow::string::sprintf("%s/tls/trusted-servers", ARCH->getProfileDirectory().c_str()); - - // check if this fingerprint exist - std::ifstream file; - file.open(deskflow::filesystem::path(trustedServersFilename)); - - bool isValid = false; - if (file.is_open()) { - while (!file.eof()) { - std::string fileLine; - getline(file, fileLine); - if (!fileLine.empty() && !fileLine.compare(fingerprint)) { - isValid = true; - break; - } - } - } else { - LOG((CLOG_ERR "failed to open trusted fingerprints file: %s", trustedServersFilename.c_str())); - } - - return (isValid && showCertificate()); -} - -void SslApi::createContext(bool isServer) -{ - // create new context from method - if (isServer) { - m_context = SSL_CTX_new(SSLv23_server_method()); - } else { - m_context = SSL_CTX_new(SSLv23_client_method()); - } - // Prevent the usage of of all version prior to TLSv1.2 as they are known to - // be vulnerable - SSL_CTX_set_options(m_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1); - - if (m_context) { - m_ssl = SSL_new(m_context); - } else { - SslLogger::logError(); - } -} - -void SslApi::logSecureInfo() const -{ - SslLogger::logSecureCipherInfo(m_ssl); - SslLogger::logSecureConnectInfo(m_ssl); -} - -int SslApi::getErrorCode(int status) const -{ - return SSL_get_error(m_ssl, status); -} - -void SslApi::formatFingerprint(std::string &fingerprint) const -{ - // to hexidecimal - fingerprint = deskflow::string::toHex(fingerprint, 2); - // all uppercase - deskflow::string::uppercase(fingerprint); - // add colon to separate each 2 charactors - size_t separators = fingerprint.size() / 2; - for (size_t i = 1; i < separators; i++) { - fingerprint.insert(i * 3 - 1, ":"); - } -} - -bool SslApi::isCertificateExists(const std::string &filename) const -{ - bool result = (!filename.empty()); - - if (result) { - std::ifstream file(deskflow::filesystem::path(filename)); - result = file.good(); - - if (!result) { - std::string errorMsg("tls certificate doesn't exist: "); - errorMsg.append(filename); - SslLogger::logError(errorMsg.c_str()); - } - } else { - SslLogger::logError("tls certificate is not specified"); - } - - return result; -} - -} // namespace ssl -} // namespace deskflow diff --git a/src/lib/net/InverseSockets/SslApi.h b/src/lib/net/InverseSockets/SslApi.h deleted file mode 100644 index 3cc24b070..000000000 --- a/src/lib/net/InverseSockets/SslApi.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2015 - 2022 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once -#include -#include - -namespace deskflow { -namespace ssl { - -class SslApi -{ -public: - explicit SslApi(bool isServer = false); - SslApi(SslApi const &) = delete; - SslApi &operator=(SslApi const &) = delete; - ~SslApi(); - - int read(char *buffer, int size); - int write(const char *buffer, int size); - int accept(int socket); - int connect(int socket); - - bool loadCertificate(const std::string &filename); - bool showCertificate() const; - std::string getFingerprint() const; - bool isTrustedFingerprint(const std::string &fingerprint) const; - - void logSecureInfo() const; - int getErrorCode(int status) const; - -private: - void createSSL(); - void formatFingerprint(std::string &fingerprint) const; - bool isCertificateExists(const std::string &filename) const; - void createContext(bool isServer = false); - - SSL *m_ssl = nullptr; - SSL_CTX *m_context = nullptr; -}; - -} // namespace ssl -} // namespace deskflow diff --git a/src/test/shared/gui/mocks/AppConfigMock.h b/src/test/shared/gui/mocks/AppConfigMock.h index 636c42347..1da8e282b 100644 --- a/src/test/shared/gui/mocks/AppConfigMock.h +++ b/src/test/shared/gui/mocks/AppConfigMock.h @@ -45,7 +45,6 @@ public: MOCK_METHOD(const QString &, logFilename, (), (const, override)); MOCK_METHOD(QString, coreServerName, (), (const, override)); MOCK_METHOD(QString, coreClientName, (), (const, override)); - MOCK_METHOD(bool, invertConnection, (), (const, override)); MOCK_METHOD(void, persistLogDir, (), (const, override)); MOCK_METHOD(bool, languageSync, (), (const, override)); MOCK_METHOD(bool, invertScrollDirection, (), (const, override)); @@ -84,7 +83,6 @@ public: MOCK_METHOD(void, setInvertScrollDirection, (bool invertScrollDirection), (override)); MOCK_METHOD(void, setEnableService, (bool enableService), (override)); MOCK_METHOD(void, setCloseToTray, (bool closeToTray), (override)); - MOCK_METHOD(void, setInvertConnection, (bool invertConnection), (override)); MOCK_METHOD(void, setRequireClientCerts, (bool requireClientCerts), (override)); private: