From dd9ad67e6b611dc98a18d7c729a7f11843bace35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Wed, 20 Jan 2021 00:44:34 +0100 Subject: [PATCH 01/10] Config: authentication enabled by default --- src/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Config.cpp b/src/Config.cpp index 1a17065f9..3c955d8c6 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -45,7 +45,7 @@ Config::Config() : LockToIPv4(false), DebugEnabled(false), AlertsEnabled(true), - AuthRequired(false), + AuthRequired(true), Secret(""), Salt(""), SettingsLoaded(false) From c02382b6e5475890822a6f62d8bb5770b0cb842d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Fri, 29 Jan 2021 19:16:53 +0100 Subject: [PATCH 02/10] config: initial password setup prompt wip --- src/Config.cpp | 160 ++++++++++++++++++++++++++++++++----------------- src/Config.h | 1 + 2 files changed, 106 insertions(+), 55 deletions(-) diff --git a/src/Config.cpp b/src/Config.cpp index 3c955d8c6..1148b8922 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -18,9 +18,13 @@ with this program. If not, see #include +#include #include #include #include +#include +#include +#include #define SECTION_NAME "WebsocketAPI" #define PARAM_ENABLE "ServerEnabled" @@ -32,6 +36,8 @@ with this program. If not, see #define PARAM_SECRET "AuthSecret" #define PARAM_SALT "AuthSalt" +#define GLOBAL_AUTH_SETUP_PROMPTED "AuthSetupPrompted" + #include "Utils.h" #include "WSServer.h" @@ -130,6 +136,70 @@ config_t* Config::GetConfigStore() return obs_frontend_get_profile_config(); } +void Config::MigrateFromGlobalSettings() +{ + config_t* source = obs_frontend_get_global_config(); + config_t* destination = obs_frontend_get_profile_config(); + + if(config_has_user_value(source, SECTION_NAME, PARAM_ENABLE)) { + bool value = config_get_bool(source, SECTION_NAME, PARAM_ENABLE); + config_set_bool(destination, SECTION_NAME, PARAM_ENABLE, value); + + config_remove_value(source, SECTION_NAME, PARAM_ENABLE); + } + + if(config_has_user_value(source, SECTION_NAME, PARAM_PORT)) { + uint64_t value = config_get_uint(source, SECTION_NAME, PARAM_PORT); + config_set_uint(destination, SECTION_NAME, PARAM_PORT, value); + + config_remove_value(source, SECTION_NAME, PARAM_PORT); + } + + if(config_has_user_value(source, SECTION_NAME, PARAM_LOCKTOIPV4)) { + bool value = config_get_bool(source, SECTION_NAME, PARAM_LOCKTOIPV4); + config_set_bool(destination, SECTION_NAME, PARAM_LOCKTOIPV4, value); + + config_remove_value(source, SECTION_NAME, PARAM_LOCKTOIPV4); + } + + if(config_has_user_value(source, SECTION_NAME, PARAM_DEBUG)) { + bool value = config_get_bool(source, SECTION_NAME, PARAM_DEBUG); + config_set_bool(destination, SECTION_NAME, PARAM_DEBUG, value); + + config_remove_value(source, SECTION_NAME, PARAM_DEBUG); + } + + if(config_has_user_value(source, SECTION_NAME, PARAM_ALERT)) { + bool value = config_get_bool(source, SECTION_NAME, PARAM_ALERT); + config_set_bool(destination, SECTION_NAME, PARAM_ALERT, value); + + config_remove_value(source, SECTION_NAME, PARAM_ALERT); + } + + if(config_has_user_value(source, SECTION_NAME, PARAM_AUTHREQUIRED)) { + bool value = config_get_bool(source, SECTION_NAME, PARAM_AUTHREQUIRED); + config_set_bool(destination, SECTION_NAME, PARAM_AUTHREQUIRED, value); + + config_remove_value(source, SECTION_NAME, PARAM_AUTHREQUIRED); + } + + if(config_has_user_value(source, SECTION_NAME, PARAM_SECRET)) { + const char* value = config_get_string(source, SECTION_NAME, PARAM_SECRET); + config_set_string(destination, SECTION_NAME, PARAM_SECRET, value); + + config_remove_value(source, SECTION_NAME, PARAM_SECRET); + } + + if(config_has_user_value(source, SECTION_NAME, PARAM_SALT)) { + const char* value = config_get_string(source, SECTION_NAME, PARAM_SALT); + config_set_string(destination, SECTION_NAME, PARAM_SALT, value); + + config_remove_value(source, SECTION_NAME, PARAM_SALT); + } + + config_save(destination); +} + QString Config::GenerateSalt() { // Generate 32 random chars @@ -233,68 +303,48 @@ void Config::OnFrontendEvent(enum obs_frontend_event event, void* param) } } } + else if (event == OBS_FRONTEND_EVENT_FINISHED_LOADING) { + FirstRunPasswordSetup(); + } } -void Config::MigrateFromGlobalSettings() +void Config::FirstRunPasswordSetup() { - config_t* source = obs_frontend_get_global_config(); - config_t* destination = obs_frontend_get_profile_config(); - - if(config_has_user_value(source, SECTION_NAME, PARAM_ENABLE)) { - bool value = config_get_bool(source, SECTION_NAME, PARAM_ENABLE); - config_set_bool(destination, SECTION_NAME, PARAM_ENABLE, value); - - config_remove_value(source, SECTION_NAME, PARAM_ENABLE); + // check if we already showed the auth setup prompt to the user, independently of the current settings (tied to the current profile) + config_t* globalConfig = obs_frontend_get_global_config(); + bool alreadyPrompted = config_get_bool(globalConfig, SECTION_NAME, GLOBAL_AUTH_SETUP_PROMPTED); + if (alreadyPrompted) { + return; } - if(config_has_user_value(source, SECTION_NAME, PARAM_PORT)) { - uint64_t value = config_get_uint(source, SECTION_NAME, PARAM_PORT); - config_set_uint(destination, SECTION_NAME, PARAM_PORT, value); + // lift the flag up and save it + config_set_bool(globalConfig, SECTION_NAME, GLOBAL_AUTH_SETUP_PROMPTED, true); + config_save(globalConfig); - config_remove_value(source, SECTION_NAME, PARAM_PORT); - } - - if(config_has_user_value(source, SECTION_NAME, PARAM_LOCKTOIPV4)) { - bool value = config_get_bool(source, SECTION_NAME, PARAM_LOCKTOIPV4); - config_set_bool(destination, SECTION_NAME, PARAM_LOCKTOIPV4, value); + obs_frontend_push_ui_translation(obs_module_get_string); + QString initialPasswordSetupTitle = QObject::tr("OBSWebsocket.InitialPasswordSetup.Title"); + QString initialPasswordSetupText = QObject::tr("OBSWebsocket.InitialPasswordSetup.Text"); + QString setupDismissedTitle = QObject::tr("OBSWebsocket.InitialPasswordSetupDismissed.Title"); + QString setupDismissedText = QObject::tr("OBSWebsocket.InitialPasswordSetupDismissed.Text"); + obs_frontend_pop_ui_translation(); - config_remove_value(source, SECTION_NAME, PARAM_LOCKTOIPV4); - } - - if(config_has_user_value(source, SECTION_NAME, PARAM_DEBUG)) { - bool value = config_get_bool(source, SECTION_NAME, PARAM_DEBUG); - config_set_bool(destination, SECTION_NAME, PARAM_DEBUG, value); - - config_remove_value(source, SECTION_NAME, PARAM_DEBUG); - } - - if(config_has_user_value(source, SECTION_NAME, PARAM_ALERT)) { - bool value = config_get_bool(source, SECTION_NAME, PARAM_ALERT); - config_set_bool(destination, SECTION_NAME, PARAM_ALERT, value); - - config_remove_value(source, SECTION_NAME, PARAM_ALERT); - } - - if(config_has_user_value(source, SECTION_NAME, PARAM_AUTHREQUIRED)) { - bool value = config_get_bool(source, SECTION_NAME, PARAM_AUTHREQUIRED); - config_set_bool(destination, SECTION_NAME, PARAM_AUTHREQUIRED, value); - - config_remove_value(source, SECTION_NAME, PARAM_AUTHREQUIRED); - } - - if(config_has_user_value(source, SECTION_NAME, PARAM_SECRET)) { - const char* value = config_get_string(source, SECTION_NAME, PARAM_SECRET); - config_set_string(destination, SECTION_NAME, PARAM_SECRET, value); + // prompt for a password + auto mainWindow = reinterpret_cast( + obs_frontend_get_main_window() + ); + bool promptAccepted = false; + QString newPassword = QInputDialog::getText( + mainWindow, + initialPasswordSetupTitle, initialPasswordSetupText, + QLineEdit::PasswordEchoOnEdit, QString::Null(), &promptAccepted + ); - config_remove_value(source, SECTION_NAME, PARAM_SECRET); - } + if (promptAccepted) { + // set new password + GetConfig()->SetPassword(newPassword); + } else { + // tell the user they still can set the password later in our settings dialog + QMessageBox::information(mainWindow, setupDismissedTitle, setupDismissedText, QMessageBox::Ok); - if(config_has_user_value(source, SECTION_NAME, PARAM_SALT)) { - const char* value = config_get_string(source, SECTION_NAME, PARAM_SALT); - config_set_string(destination, SECTION_NAME, PARAM_SALT, value); - - config_remove_value(source, SECTION_NAME, PARAM_SALT); } - - config_save(destination); -} +} \ No newline at end of file diff --git a/src/Config.h b/src/Config.h index f21e396ad..1aa29ebf1 100644 --- a/src/Config.h +++ b/src/Config.h @@ -55,4 +55,5 @@ class Config { private: static void OnFrontendEvent(enum obs_frontend_event event, void* param); + static void FirstRunPasswordSetup(); }; From c8ca79f00b4f9aca8972e5b2b1d4f7ae6acfc72e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Sun, 31 Jan 2021 00:58:56 +0100 Subject: [PATCH 03/10] config: add locale texts for initial password setup --- data/locale/en-US.ini | 4 ++++ src/Config.cpp | 51 ++++++++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 69fbed16a..b32da6b00 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -15,3 +15,7 @@ OBSWebsocket.Server.StartFailed.Message="The WebSockets server failed to start, OBSWebsocket.ProfileChanged.Started="WebSockets server enabled in this profile. Server started." OBSWebsocket.ProfileChanged.Stopped="WebSockets server disabled in this profile. Server stopped." OBSWebsocket.ProfileChanged.Restarted="WebSockets server port changed in this profile. Server restarted." +OBSWebsocket.InitialPasswordSetup.Title="obs-websocket - Server Password Configuration" +OBSWebsocket.InitialPasswordSetup.Text="It looks like you are running obs-websocket for the first time. Do you want set a password for the WebSockets server now?" +OBSWebsocket.InitialPasswordSetup.SuccessText="Server Password set successfully." +OBSWebsocket.InitialPasswordSetup.DismissedText="You can configure a server password anytime in obs-websocket settings (under the Tools menu of OBS Studio)" diff --git a/src/Config.cpp b/src/Config.cpp index 1148b8922..6f148739f 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -310,6 +310,12 @@ void Config::OnFrontendEvent(enum obs_frontend_event event, void* param) void Config::FirstRunPasswordSetup() { + // check if the password is already set + auto config = GetConfig(); + if (!(config->Secret.isEmpty()) && !(config->Salt.isEmpty())) { + return; + } + // check if we already showed the auth setup prompt to the user, independently of the current settings (tied to the current profile) config_t* globalConfig = obs_frontend_get_global_config(); bool alreadyPrompted = config_get_bool(globalConfig, SECTION_NAME, GLOBAL_AUTH_SETUP_PROMPTED); @@ -322,29 +328,34 @@ void Config::FirstRunPasswordSetup() config_save(globalConfig); obs_frontend_push_ui_translation(obs_module_get_string); - QString initialPasswordSetupTitle = QObject::tr("OBSWebsocket.InitialPasswordSetup.Title"); - QString initialPasswordSetupText = QObject::tr("OBSWebsocket.InitialPasswordSetup.Text"); - QString setupDismissedTitle = QObject::tr("OBSWebsocket.InitialPasswordSetupDismissed.Title"); - QString setupDismissedText = QObject::tr("OBSWebsocket.InitialPasswordSetupDismissed.Text"); + QString dialogTitle = QObject::tr("OBSWebsocket.InitialPasswordSetup.Title"); + QString dialogText = QObject::tr("OBSWebsocket.InitialPasswordSetup.Text"); + QString successText = QObject::tr("OBSWebsocket.InitialPasswordSetup.SuccessText"); + QString dismissedText = QObject::tr("OBSWebsocket.InitialPasswordSetup.DismissedText"); + QString passwordLabel = QObject::tr("OBSWebsocket.Settings.Password"); obs_frontend_pop_ui_translation(); - // prompt for a password auto mainWindow = reinterpret_cast( obs_frontend_get_main_window() ); - bool promptAccepted = false; - QString newPassword = QInputDialog::getText( - mainWindow, - initialPasswordSetupTitle, initialPasswordSetupText, - QLineEdit::PasswordEchoOnEdit, QString::Null(), &promptAccepted - ); - - if (promptAccepted) { - // set new password - GetConfig()->SetPassword(newPassword); - } else { - // tell the user they still can set the password later in our settings dialog - QMessageBox::information(mainWindow, setupDismissedTitle, setupDismissedText, QMessageBox::Ok); - + + int proceed = QMessageBox::question(mainWindow, dialogTitle, dialogText, QMessageBox::No, QMessageBox::Yes); + if (proceed) { + bool promptAccepted = false; + QString newPassword = QInputDialog::getText( + mainWindow, + dialogTitle, passwordLabel, + QLineEdit::PasswordEchoOnEdit, QString::Null(), &promptAccepted + ); + + if (promptAccepted) { + // set new password + GetConfig()->SetPassword(newPassword); + QMessageBox::information(mainWindow, dialogTitle, successText); + return; + } } -} \ No newline at end of file + + // tell the user they still can set the password later in our settings dialog + QMessageBox::information(mainWindow, dialogTitle, dismissedText); +} From 38cf0270b155056db99296f853641d55ca44a99c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Sun, 31 Jan 2021 01:26:38 +0100 Subject: [PATCH 04/10] settings: add auth disabled warning --- data/locale/en-US.ini | 1 + src/Config.cpp | 4 ++-- src/forms/settings-dialog.cpp | 30 +++++++++++++++++++++++------- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index b32da6b00..b5b9fdc45 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -6,6 +6,7 @@ OBSWebsocket.Settings.Password="Password" OBSWebsocket.Settings.LockToIPv4="Lock server to only using IPv4" OBSWebsocket.Settings.DebugEnable="Enable debug logging" OBSWebsocket.Settings.AlertsEnable="Enable System Tray Alerts" +OBSWebsocket.Settings.AuthDisabledWarning="Running obs-websocket with authentication disabled is not recommended. Are you sure you want to proceed with that change?" OBSWebsocket.NotifyConnect.Title="New WebSocket connection" OBSWebsocket.NotifyConnect.Message="Client %1 connected" OBSWebsocket.NotifyDisconnect.Title="WebSocket client disconnected" diff --git a/src/Config.cpp b/src/Config.cpp index 6f148739f..af62aeeb4 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -339,8 +339,8 @@ void Config::FirstRunPasswordSetup() obs_frontend_get_main_window() ); - int proceed = QMessageBox::question(mainWindow, dialogTitle, dialogText, QMessageBox::No, QMessageBox::Yes); - if (proceed) { + QMessageBox::StandardButton response = QMessageBox::question(mainWindow, dialogTitle, dialogText); + if (response == QMessageBox::Yes) { bool promptAccepted = false; QString newPassword = QInputDialog::getText( mainWindow, diff --git a/src/forms/settings-dialog.cpp b/src/forms/settings-dialog.cpp index ca686dfef..338ffb1e6 100644 --- a/src/forms/settings-dialog.cpp +++ b/src/forms/settings-dialog.cpp @@ -16,12 +16,16 @@ You should have received a copy of the GNU General Public License along with this program. If not, see */ +#include "settings-dialog.h" + #include +#include +#include #include "../obs-websocket.h" #include "../Config.h" #include "../WSServer.h" -#include "settings-dialog.h" + #define CHANGE_ME "changeme" @@ -35,9 +39,6 @@ SettingsDialog::SettingsDialog(QWidget* parent) : this, &SettingsDialog::AuthCheckboxChanged); connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &SettingsDialog::FormAccepted); - - - AuthCheckboxChanged(); } void SettingsDialog::showEvent(QShowEvent* event) { @@ -50,8 +51,12 @@ void SettingsDialog::showEvent(QShowEvent* event) { ui->debugEnabled->setChecked(conf->DebugEnabled); ui->alertsEnabled->setChecked(conf->AlertsEnabled); + ui->authRequired->blockSignals(true); ui->authRequired->setChecked(conf->AuthRequired); + ui->authRequired->blockSignals(false); + ui->password->setText(CHANGE_ME); + ui->password->setEnabled(ui->authRequired->isChecked()); } void SettingsDialog::ToggleShowHide() { @@ -62,10 +67,21 @@ void SettingsDialog::ToggleShowHide() { } void SettingsDialog::AuthCheckboxChanged() { - if (ui->authRequired->isChecked()) + if (ui->authRequired->isChecked()) { ui->password->setEnabled(true); - else - ui->password->setEnabled(false); + } + else { + obs_frontend_push_ui_translation(obs_module_get_string); + QString authDisabledWarning = QObject::tr("OBSWebsocket.Settings.AuthDisabledWarning"); + obs_frontend_pop_ui_translation(); + + QMessageBox::StandardButton response = QMessageBox::question(this, "obs-websocket", authDisabledWarning); + if (response == QMessageBox::Yes) { + ui->password->setEnabled(false); + } else { + ui->authRequired->setChecked(true); + } + } } void SettingsDialog::FormAccepted() { From a8aa34529e03ec7eb9913aa9c8271abf20e29998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Sun, 31 Jan 2021 01:51:19 +0100 Subject: [PATCH 05/10] config: simplify initial password setup --- data/locale/en-US.ini | 5 ++--- src/Config.cpp | 35 +++++++++++------------------------ src/obs-websocket.cpp | 11 +++++++++-- src/obs-websocket.h | 1 + 4 files changed, 23 insertions(+), 29 deletions(-) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index b5b9fdc45..9647ac724 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -17,6 +17,5 @@ OBSWebsocket.ProfileChanged.Started="WebSockets server enabled in this profile. OBSWebsocket.ProfileChanged.Stopped="WebSockets server disabled in this profile. Server stopped." OBSWebsocket.ProfileChanged.Restarted="WebSockets server port changed in this profile. Server restarted." OBSWebsocket.InitialPasswordSetup.Title="obs-websocket - Server Password Configuration" -OBSWebsocket.InitialPasswordSetup.Text="It looks like you are running obs-websocket for the first time. Do you want set a password for the WebSockets server now?" -OBSWebsocket.InitialPasswordSetup.SuccessText="Server Password set successfully." -OBSWebsocket.InitialPasswordSetup.DismissedText="You can configure a server password anytime in obs-websocket settings (under the Tools menu of OBS Studio)" +OBSWebsocket.InitialPasswordSetup.Text="It looks like you are running obs-websocket for the first time. Do you want to configure a password now for the WebSockets server?" +OBSWebsocket.InitialPasswordSetup.DismissedText="You can configure a server password later in obs-websocket settings (under the Tools menu of OBS Studio)" diff --git a/src/Config.cpp b/src/Config.cpp index af62aeeb4..60bdddca1 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -310,12 +310,6 @@ void Config::OnFrontendEvent(enum obs_frontend_event event, void* param) void Config::FirstRunPasswordSetup() { - // check if the password is already set - auto config = GetConfig(); - if (!(config->Secret.isEmpty()) && !(config->Salt.isEmpty())) { - return; - } - // check if we already showed the auth setup prompt to the user, independently of the current settings (tied to the current profile) config_t* globalConfig = obs_frontend_get_global_config(); bool alreadyPrompted = config_get_bool(globalConfig, SECTION_NAME, GLOBAL_AUTH_SETUP_PROMPTED); @@ -327,12 +321,16 @@ void Config::FirstRunPasswordSetup() config_set_bool(globalConfig, SECTION_NAME, GLOBAL_AUTH_SETUP_PROMPTED, true); config_save(globalConfig); + // check if the password is already set + auto config = GetConfig(); + if (!(config->Secret.isEmpty()) && !(config->Salt.isEmpty())) { + return; + } + obs_frontend_push_ui_translation(obs_module_get_string); QString dialogTitle = QObject::tr("OBSWebsocket.InitialPasswordSetup.Title"); QString dialogText = QObject::tr("OBSWebsocket.InitialPasswordSetup.Text"); - QString successText = QObject::tr("OBSWebsocket.InitialPasswordSetup.SuccessText"); QString dismissedText = QObject::tr("OBSWebsocket.InitialPasswordSetup.DismissedText"); - QString passwordLabel = QObject::tr("OBSWebsocket.Settings.Password"); obs_frontend_pop_ui_translation(); auto mainWindow = reinterpret_cast( @@ -341,21 +339,10 @@ void Config::FirstRunPasswordSetup() QMessageBox::StandardButton response = QMessageBox::question(mainWindow, dialogTitle, dialogText); if (response == QMessageBox::Yes) { - bool promptAccepted = false; - QString newPassword = QInputDialog::getText( - mainWindow, - dialogTitle, passwordLabel, - QLineEdit::PasswordEchoOnEdit, QString::Null(), &promptAccepted - ); - - if (promptAccepted) { - // set new password - GetConfig()->SetPassword(newPassword); - QMessageBox::information(mainWindow, dialogTitle, successText); - return; - } + ShowSettingsDialog(); + } + else { + // tell the user they still can set the password later in our settings dialog + QMessageBox::information(mainWindow, dialogTitle, dismissedText); } - - // tell the user they still can set the password later in our settings dialog - QMessageBox::information(mainWindow, dialogTitle, dismissedText); } diff --git a/src/obs-websocket.cpp b/src/obs-websocket.cpp index b198ebb72..123249068 100644 --- a/src/obs-websocket.cpp +++ b/src/obs-websocket.cpp @@ -47,6 +47,7 @@ OBS_MODULE_USE_DEFAULT_LOCALE("obs-websocket", "en-US") ConfigPtr _config; WSServerPtr _server; WSEventsPtr _eventsSystem; +SettingsDialog* settingsDialog = nullptr; bool obs_module_load(void) { blog(LOG_INFO, "you can haz websockets (version %s)", OBS_WEBSOCKET_VERSION); @@ -64,14 +65,14 @@ bool obs_module_load(void) { // UI setup obs_frontend_push_ui_translation(obs_module_get_string); QMainWindow* mainWindow = (QMainWindow*)obs_frontend_get_main_window(); - SettingsDialog* settingsDialog = new SettingsDialog(mainWindow); + settingsDialog = new SettingsDialog(mainWindow); obs_frontend_pop_ui_translation(); const char* menuActionText = obs_module_text("OBSWebsocket.Settings.DialogTitle"); QAction* menuAction = (QAction*)obs_frontend_add_tools_menu_qaction(menuActionText); - QObject::connect(menuAction, &QAction::triggered, [settingsDialog] { + QObject::connect(menuAction, &QAction::triggered, [] { // The settings dialog belongs to the main window. Should be ok // to pass the pointer to this QAction belonging to the main window settingsDialog->ToggleShowHide(); @@ -115,3 +116,9 @@ WSServerPtr GetServer() { WSEventsPtr GetEventsSystem() { return _eventsSystem; } + +void ShowSettingsDialog() { + if (settingsDialog) { + settingsDialog->setVisible(true); + } +} diff --git a/src/obs-websocket.h b/src/obs-websocket.h index 5f118d286..671b22baa 100644 --- a/src/obs-websocket.h +++ b/src/obs-websocket.h @@ -55,6 +55,7 @@ typedef std::shared_ptr WSEventsPtr; ConfigPtr GetConfig(); WSServerPtr GetServer(); WSEventsPtr GetEventsSystem(); +void ShowSettingsDialog(); #define OBS_WEBSOCKET_VERSION "4.8.0" From 2015d401863f70ff8f3fbcab9dd6c4e61dd283ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Sun, 31 Jan 2021 01:58:22 +0100 Subject: [PATCH 06/10] docs(introduction): update authentication section --- docs/partials/introduction.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/partials/introduction.md b/docs/partials/introduction.md index 496363e73..c63111bf6 100644 --- a/docs/partials/introduction.md +++ b/docs/partials/introduction.md @@ -5,6 +5,8 @@ Messages are exchanged between the client and the server as JSON objects. This protocol is based on the original OBS Remote protocol created by Bill Hamilton, with new commands specific to OBS Studio. As of v5.0.0, backwards compatability with the protocol will not be kept. # Authentication +**Starting with obs-websocket 4.9, authentication is enabled by default and users are encouraged to configure a password on first run.** + `obs-websocket` uses SHA256 to transmit credentials. A request for [`GetAuthRequired`](#getauthrequired) returns two elements: From 98712c7b7169a944c7304ed4ce63ad86418e1f65 Mon Sep 17 00:00:00 2001 From: tt2468 Date: Mon, 1 Feb 2021 05:16:47 -0800 Subject: [PATCH 07/10] Password Prompt: Enable authRequired toggle and highlight password --- src/Config.cpp | 2 +- src/forms/settings-dialog.cpp | 10 ++++++++++ src/forms/settings-dialog.h | 1 + src/obs-websocket.cpp | 7 +++++++ src/obs-websocket.h | 1 + 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Config.cpp b/src/Config.cpp index 60bdddca1..3cb9730ec 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -339,7 +339,7 @@ void Config::FirstRunPasswordSetup() QMessageBox::StandardButton response = QMessageBox::question(mainWindow, dialogTitle, dialogText); if (response == QMessageBox::Yes) { - ShowSettingsDialog(); + ShowPasswordSetting(); } else { // tell the user they still can set the password later in our settings dialog diff --git a/src/forms/settings-dialog.cpp b/src/forms/settings-dialog.cpp index 338ffb1e6..ebe210732 100644 --- a/src/forms/settings-dialog.cpp +++ b/src/forms/settings-dialog.cpp @@ -66,6 +66,16 @@ void SettingsDialog::ToggleShowHide() { setVisible(false); } +void SettingsDialog::PreparePasswordEntry() { + auto conf = GetConfig(); + conf->AuthRequired = true; + ui->authRequired->blockSignals(true); + ui->authRequired->setChecked(true); + ui->authRequired->blockSignals(false); + ui->password->setEnabled(true); + ui->password->setFocus(); +} + void SettingsDialog::AuthCheckboxChanged() { if (ui->authRequired->isChecked()) { ui->password->setEnabled(true); diff --git a/src/forms/settings-dialog.h b/src/forms/settings-dialog.h index 138ae3951..f67f1f98e 100644 --- a/src/forms/settings-dialog.h +++ b/src/forms/settings-dialog.h @@ -31,6 +31,7 @@ class SettingsDialog : public QDialog ~SettingsDialog(); void showEvent(QShowEvent* event); void ToggleShowHide(); + void PreparePasswordEntry(); private Q_SLOTS: void AuthCheckboxChanged(); diff --git a/src/obs-websocket.cpp b/src/obs-websocket.cpp index 123249068..ef5ea7e26 100644 --- a/src/obs-websocket.cpp +++ b/src/obs-websocket.cpp @@ -122,3 +122,10 @@ void ShowSettingsDialog() { settingsDialog->setVisible(true); } } + +void ShowPasswordSetting() { + if (settingsDialog) { + settingsDialog->PreparePasswordEntry(); + settingsDialog->setVisible(true); + } +} \ No newline at end of file diff --git a/src/obs-websocket.h b/src/obs-websocket.h index 671b22baa..b900d476a 100644 --- a/src/obs-websocket.h +++ b/src/obs-websocket.h @@ -56,6 +56,7 @@ ConfigPtr GetConfig(); WSServerPtr GetServer(); WSEventsPtr GetEventsSystem(); void ShowSettingsDialog(); +void ShowPasswordSetting(); #define OBS_WEBSOCKET_VERSION "4.8.0" From e6c2c906779d697f925a670eb682e973da20218a Mon Sep 17 00:00:00 2001 From: tt2468 Date: Mon, 1 Feb 2021 05:33:01 -0800 Subject: [PATCH 08/10] Password Prompt: Improve english strings --- data/locale/en-US.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 9647ac724..0382082fb 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -6,7 +6,7 @@ OBSWebsocket.Settings.Password="Password" OBSWebsocket.Settings.LockToIPv4="Lock server to only using IPv4" OBSWebsocket.Settings.DebugEnable="Enable debug logging" OBSWebsocket.Settings.AlertsEnable="Enable System Tray Alerts" -OBSWebsocket.Settings.AuthDisabledWarning="Running obs-websocket with authentication disabled is not recommended. Are you sure you want to proceed with that change?" +OBSWebsocket.Settings.AuthDisabledWarning="Running obs-websocket with authentication disabled is not recommended, as it allows attackers to easily collect sensetive data. Are you sure you want to proceed?" OBSWebsocket.NotifyConnect.Title="New WebSocket connection" OBSWebsocket.NotifyConnect.Message="Client %1 connected" OBSWebsocket.NotifyDisconnect.Title="WebSocket client disconnected" @@ -17,5 +17,5 @@ OBSWebsocket.ProfileChanged.Started="WebSockets server enabled in this profile. OBSWebsocket.ProfileChanged.Stopped="WebSockets server disabled in this profile. Server stopped." OBSWebsocket.ProfileChanged.Restarted="WebSockets server port changed in this profile. Server restarted." OBSWebsocket.InitialPasswordSetup.Title="obs-websocket - Server Password Configuration" -OBSWebsocket.InitialPasswordSetup.Text="It looks like you are running obs-websocket for the first time. Do you want to configure a password now for the WebSockets server?" -OBSWebsocket.InitialPasswordSetup.DismissedText="You can configure a server password later in obs-websocket settings (under the Tools menu of OBS Studio)" +OBSWebsocket.InitialPasswordSetup.Text="It looks like you are running obs-websocket for the first time. Do you want to configure a password now for the WebSockets server? Setting a password is highly recommended." +OBSWebsocket.InitialPasswordSetup.DismissedText="You can configure a server password later in the WebSockets Server Settings. (Under the Tools menu of OBS Studio)" From 20fa14563cc58a62a06a77bdbf9740192e65fcc2 Mon Sep 17 00:00:00 2001 From: tt2468 Date: Mon, 1 Feb 2021 05:35:58 -0800 Subject: [PATCH 09/10] Settings Dialog: Don't need ShowSettingsDialog() --- src/obs-websocket.cpp | 8 +------- src/obs-websocket.h | 1 - 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/obs-websocket.cpp b/src/obs-websocket.cpp index ef5ea7e26..4fb3e7296 100644 --- a/src/obs-websocket.cpp +++ b/src/obs-websocket.cpp @@ -117,15 +117,9 @@ WSEventsPtr GetEventsSystem() { return _eventsSystem; } -void ShowSettingsDialog() { - if (settingsDialog) { - settingsDialog->setVisible(true); - } -} - void ShowPasswordSetting() { if (settingsDialog) { settingsDialog->PreparePasswordEntry(); settingsDialog->setVisible(true); } -} \ No newline at end of file +} diff --git a/src/obs-websocket.h b/src/obs-websocket.h index b900d476a..38da66a46 100644 --- a/src/obs-websocket.h +++ b/src/obs-websocket.h @@ -55,7 +55,6 @@ typedef std::shared_ptr WSEventsPtr; ConfigPtr GetConfig(); WSServerPtr GetServer(); WSEventsPtr GetEventsSystem(); -void ShowSettingsDialog(); void ShowPasswordSetting(); #define OBS_WEBSOCKET_VERSION "4.8.0" From e39585befc703615cc0548605378f7b00f5dda3e Mon Sep 17 00:00:00 2001 From: tt2468 Date: Tue, 2 Feb 2021 03:04:03 -0800 Subject: [PATCH 10/10] Password Dialog: Only change form options and not underlying config --- src/forms/settings-dialog.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/forms/settings-dialog.cpp b/src/forms/settings-dialog.cpp index ebe210732..f852186c7 100644 --- a/src/forms/settings-dialog.cpp +++ b/src/forms/settings-dialog.cpp @@ -67,8 +67,6 @@ void SettingsDialog::ToggleShowHide() { } void SettingsDialog::PreparePasswordEntry() { - auto conf = GetConfig(); - conf->AuthRequired = true; ui->authRequired->blockSignals(true); ui->authRequired->setChecked(true); ui->authRequired->blockSignals(false);