diff --git a/src/apps/deskflow-gui/dialogs/SettingsDialog.cpp b/src/apps/deskflow-gui/dialogs/SettingsDialog.cpp
index 8c3bd53c4..117d7c587 100644
--- a/src/apps/deskflow-gui/dialogs/SettingsDialog.cpp
+++ b/src/apps/deskflow-gui/dialogs/SettingsDialog.cpp
@@ -192,6 +192,7 @@ void SettingsDialog::accept()
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());
QDialog::accept();
}
@@ -261,6 +262,8 @@ void SettingsDialog::updateTlsControls()
ui->m_pCheckBoxEnableTls->setEnabled(writable);
ui->m_pCheckBoxEnableTls->setChecked(writable && tlsEnabled);
ui->m_pLineEditTlsCertPath->setText(m_appConfig.tlsCertPath());
+ ui->chkRequireClientCert->setEnabled(writable);
+ ui->chkRequireClientCert->setChecked(m_appConfig.requireClientCerts());
}
void SettingsDialog::updateTlsControlsEnabled()
@@ -276,6 +279,7 @@ void SettingsDialog::updateTlsControlsEnabled()
ui->m_pLineEditTlsCertPath->setEnabled(enabled);
ui->m_pPushButtonTlsCertPath->setEnabled(enabled);
ui->m_pPushButtonTlsRegenCert->setEnabled(enabled);
+ ui->chkRequireClientCert->setEnabled(enabled);
}
bool SettingsDialog::isClientMode() const
diff --git a/src/apps/deskflow-gui/dialogs/SettingsDialog.ui b/src/apps/deskflow-gui/dialogs/SettingsDialog.ui
index c71a09c1b..dd3728997 100644
--- a/src/apps/deskflow-gui/dialogs/SettingsDialog.ui
+++ b/src/apps/deskflow-gui/dialogs/SettingsDialog.ui
@@ -360,6 +360,13 @@
+ -
+
+
+ Require client certificates
+
+
+
diff --git a/src/lib/gui/config/AppConfig.cpp b/src/lib/gui/config/AppConfig.cpp
index a66beb693..d329ffb6d 100644
--- a/src/lib/gui/config/AppConfig.cpp
+++ b/src/lib/gui/config/AppConfig.cpp
@@ -1,5 +1,6 @@
/*
* Deskflow -- mouse and keyboard sharing utility
+ * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
* SPDX-FileCopyrightText: (C) 2012 Symless Ltd.
* SPDX-FileCopyrightText: (C) 2008 Volker Lanz
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
@@ -77,6 +78,7 @@ const char *const AppConfig::m_SettingsName[] = {
"enableUpdateCheck",
"logExpanded",
"colorfulIcon",
+ "requireClientCerts",
};
AppConfig::AppConfig(deskflow::gui::IConfigScopes &scopes, std::shared_ptr deps)
@@ -137,6 +139,7 @@ void AppConfig::recallFromCurrentScope()
m_TlsEnabled = getFromCurrentScope(kTlsEnabled, m_TlsEnabled).toBool();
m_TlsCertPath = getFromCurrentScope(kTlsCertPath, m_TlsCertPath).toString();
m_TlsKeyLength = getFromCurrentScope(kTlsKeyLength, m_TlsKeyLength).toInt();
+ m_RequireClientCert = getFromCurrentScope(kRequireClientCert, m_RequireClientCert).toBool();
m_MainWindowPosition =
getFromCurrentScope(kMainWindowPosition, [](const QVariant &v) { return v.toPoint(); });
m_MainWindowSize = getFromCurrentScope(kMainWindowSize, [](const QVariant &v) { return v.toSize(); });
@@ -203,6 +206,7 @@ void AppConfig::commit()
setInCurrentScope(kEnableUpdateCheck, m_EnableUpdateCheck);
setInCurrentScope(kLogExpanded, m_logExpanded);
setInCurrentScope(kColorfulIcon, m_colorfulTrayIcon);
+ setInCurrentScope(kRequireClientCert, m_RequireClientCert);
}
if (m_TlsChanged) {
@@ -554,6 +558,11 @@ bool AppConfig::clientGroupChecked() const
return m_ClientGroupChecked;
}
+bool AppConfig::requireClientCerts() const
+{
+ return m_RequireClientCert;
+}
+
const QString &AppConfig::serverHostname() const
{
return m_ServerHostname;
@@ -742,6 +751,13 @@ void AppConfig::setInvertConnection(bool value)
Q_EMIT invertConnectionChanged();
}
+void AppConfig::setRequireClientCerts(bool requireClientCerts)
+{
+ if (requireClientCerts == m_RequireClientCert)
+ return;
+ m_RequireClientCert = requireClientCerts;
+}
+
void AppConfig::setMainWindowSize(const QSize &size)
{
m_MainWindowSize = size;
diff --git a/src/lib/gui/config/AppConfig.h b/src/lib/gui/config/AppConfig.h
index a600cc1c8..0756ac88b 100644
--- a/src/lib/gui/config/AppConfig.h
+++ b/src/lib/gui/config/AppConfig.h
@@ -1,5 +1,6 @@
/*
* Deskflow -- mouse and keyboard sharing utility
+ * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
* SPDX-FileCopyrightText: (C) 2012 Symless Ltd.
* SPDX-FileCopyrightText: (C) 2008 Volker Lanz
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
@@ -99,7 +100,8 @@ private:
kShowCloseReminder = 42,
kEnableUpdateCheck = 43,
kLogExpanded = 44,
- kColorfulIcon = 45
+ kColorfulIcon = 45,
+ kRequireClientCert = 46
};
public:
@@ -159,6 +161,7 @@ public:
bool enableService() const override;
bool closeToTray() const override;
bool clientGroupChecked() const override;
+ bool requireClientCerts() const override;
//
// Getters (new methods)
@@ -198,6 +201,7 @@ public:
void setTlsCertPath(const QString &path) override;
void setTlsKeyLength(int length) override;
void setInvertConnection(bool value) override;
+ void setRequireClientCerts(bool requireClientCerts) override;
//
// Setters (new methods)
@@ -325,6 +329,7 @@ private:
std::optional m_EnableUpdateCheck;
bool m_logExpanded = true;
bool m_colorfulTrayIcon = false;
+ bool m_RequireClientCert = true;
/**
* @brief Flag is set when any TLS is setting is changed, and is reset
diff --git a/src/lib/gui/config/IAppConfig.h b/src/lib/gui/config/IAppConfig.h
index 081c7e7ec..a4b5b060c 100644
--- a/src/lib/gui/config/IAppConfig.h
+++ b/src/lib/gui/config/IAppConfig.h
@@ -60,6 +60,7 @@ public:
virtual bool isActiveScopeSystem() const = 0;
virtual bool isActiveScopeWritable() const = 0;
virtual bool clientGroupChecked() const = 0;
+ virtual bool requireClientCerts() const = 0;
//
// Setters
@@ -83,6 +84,7 @@ public:
virtual void setEnableService(bool enableService) = 0;
virtual void setCloseToTray(bool closeToTray) = 0;
virtual void setInvertConnection(bool invertConnection) = 0;
+ virtual void setRequireClientCerts(bool requireClientCerts) = 0;
};
} // namespace deskflow::gui
diff --git a/src/test/shared/gui/mocks/AppConfigMock.h b/src/test/shared/gui/mocks/AppConfigMock.h
index 42d760525..636c42347 100644
--- a/src/test/shared/gui/mocks/AppConfigMock.h
+++ b/src/test/shared/gui/mocks/AppConfigMock.h
@@ -61,6 +61,7 @@ public:
MOCK_METHOD(bool, isActiveScopeSystem, (), (const, override));
MOCK_METHOD(bool, isActiveScopeWritable, (), (const, override));
MOCK_METHOD(bool, clientGroupChecked, (), (const, override));
+ MOCK_METHOD(bool, requireClientCerts, (), (const, override));
//
// Setters
@@ -84,6 +85,7 @@ public:
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:
const QString m_stub = "stub";