diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 8f8e4f309..f1a2884d7 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -463,6 +463,16 @@ void Preferences::setServerDomains(const QString &str) setValue("Preferences/WebUI/ServerDomains", str); } +QString Preferences::getWebUiAddress() const +{ + return value("Preferences/WebUI/Address", "*").toString().trimmed(); +} + +void Preferences::setWebUiAddress(const QString &addr) +{ + setValue("Preferences/WebUI/Address", addr.trimmed()); +} + quint16 Preferences::getWebUiPort() const { return value("Preferences/WebUI/Port", 8080).toInt(); diff --git a/src/base/preferences.h b/src/base/preferences.h index e7f2e53e8..7654b94d9 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -174,6 +174,8 @@ public: void setWebUiLocalAuthEnabled(bool enabled); QString getServerDomains() const; void setServerDomains(const QString &str); + QString getWebUiAddress() const; + void setWebUiAddress(const QString &addr); quint16 getWebUiPort() const; void setWebUiPort(quint16 port); bool useUPnPForWebUIPort() const; diff --git a/src/gui/optionsdlg.cpp b/src/gui/optionsdlg.cpp index c40db1c97..4d2714e26 100644 --- a/src/gui/optionsdlg.cpp +++ b/src/gui/optionsdlg.cpp @@ -340,6 +340,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) // Web UI tab connect(m_ui->textServerDomains, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); connect(m_ui->checkWebUi, &QGroupBox::toggled, this, &ThisType::enableApplyButton); + connect(m_ui->textWebUiAddress, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); connect(m_ui->spinWebUiPort, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); connect(m_ui->checkWebUIUPnP, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); connect(m_ui->checkWebUiHttps, &QGroupBox::toggled, this, &ThisType::enableApplyButton); @@ -648,7 +649,8 @@ void OptionsDialog::saveOptions() pref->setWebUiEnabled(isWebUiEnabled()); if (isWebUiEnabled()) { pref->setServerDomains(m_ui->textServerDomains->text()); - pref->setWebUiPort(webUiPort()); + pref->setWebUiAddress(m_ui->textWebUiAddress->text()); + pref->setWebUiPort(m_ui->spinWebUiPort->value()); pref->setUPnPForWebUIPort(m_ui->checkWebUIUPnP->isChecked()); pref->setWebUiHttpsEnabled(m_ui->checkWebUiHttps->isChecked()); if (m_ui->checkWebUiHttps->isChecked()) { @@ -1038,6 +1040,7 @@ void OptionsDialog::loadOptions() // Web UI preferences m_ui->textServerDomains->setText(pref->getServerDomains()); m_ui->checkWebUi->setChecked(pref->isWebUiEnabled()); + m_ui->textWebUiAddress->setText(pref->getWebUiAddress()); m_ui->spinWebUiPort->setValue(pref->getWebUiPort()); m_ui->checkWebUIUPnP->setChecked(pref->useUPnPForWebUIPort()); m_ui->checkWebUiHttps->setChecked(pref->isWebUiHttpsEnabled()); @@ -1505,11 +1508,6 @@ bool OptionsDialog::isWebUiEnabled() const return m_ui->checkWebUi->isChecked(); } -quint16 OptionsDialog::webUiPort() const -{ - return m_ui->spinWebUiPort->value(); -} - QString OptionsDialog::webUiUsername() const { return m_ui->textWebUiUsername->text(); diff --git a/src/gui/optionsdlg.h b/src/gui/optionsdlg.h index efaaddf95..ab8bb1a10 100644 --- a/src/gui/optionsdlg.h +++ b/src/gui/optionsdlg.h @@ -168,7 +168,6 @@ private: int getMaxActiveUploads() const; int getMaxActiveTorrents() const; bool isWebUiEnabled() const; - quint16 webUiPort() const; QString webUiUsername() const; QString webUiPassword() const; diff --git a/src/gui/optionsdlg.ui b/src/gui/optionsdlg.ui index e617eeb98..a489b067d 100644 --- a/src/gui/optionsdlg.ui +++ b/src/gui/optionsdlg.ui @@ -2758,29 +2758,23 @@ - + - + - Server domains: + IP address: - + - Whitelist for filtering HTTP Host header values. -In order to defend against DNS rebinding attack, -you should put in domain names used by WebUI server. - -Use ';' to split multiple entries. Can use wildcard '*'. + IP address that the Web UI will bind to. +Specify an IPv4 or IPv6 address. You can specify "0.0.0.0" for any IPv4 address, +"::" for any IPv6 address, or "*" for both IPv4 and IPv6. - - - - @@ -2801,18 +2795,27 @@ Use ';' to split multiple entries. Can use wildcard '*'. + + + + - - - Qt::Horizontal + + + Server domains: - - - 21 - 29 - + + + + + + Whitelist for filtering HTTP Host header values. +In order to defend against DNS rebinding attack, +you should put in domain names used by WebUI server. + +Use ';' to split multiple entries. Can use wildcard '*'. - + diff --git a/src/webui/prefjson.cpp b/src/webui/prefjson.cpp index 01390c7ee..f5a0f8195 100644 --- a/src/webui/prefjson.cpp +++ b/src/webui/prefjson.cpp @@ -163,6 +163,7 @@ QByteArray prefjson::getPreferences() data["locale"] = pref->getLocale(); // HTTP Server data["web_ui_domain_list"] = pref->getServerDomains(); + data["web_ui_address"] = pref->getWebUiAddress(); data["web_ui_port"] = pref->getWebUiPort(); data["web_ui_upnp"] = pref->useUPnPForWebUIPort(); data["use_https"] = pref->isWebUiHttpsEnabled(); @@ -399,6 +400,8 @@ void prefjson::setPreferences(const QString& json) // HTTP Server if (m.contains("web_ui_domain_list")) pref->setServerDomains(m["web_ui_domain_list"].toString()); + if (m.contains("web_ui_address")) + pref->setWebUiAddress(m["web_ui_address"].toString()); if (m.contains("web_ui_port")) pref->setWebUiPort(m["web_ui_port"].toUInt()); if (m.contains("web_ui_upnp")) diff --git a/src/webui/webui.cpp b/src/webui/webui.cpp index 96213c397..9861f10a6 100644 --- a/src/webui/webui.cpp +++ b/src/webui/webui.cpp @@ -93,7 +93,11 @@ void WebUI::init() #endif if (!m_httpServer->isListening()) { - bool success = m_httpServer->listen(QHostAddress::Any, m_port); + const QString addressString = pref->getWebUiAddress(); + const auto address = (addressString == "*" || addressString.isEmpty()) + ? QHostAddress::Any : QHostAddress(addressString); + + bool success = m_httpServer->listen(address, m_port); if (success) { logger->addMessage(tr("Web UI: Now listening on port %1").arg(m_port)); } diff --git a/src/webui/www/public/preferences_content.html b/src/webui/www/public/preferences_content.html index f452b1991..08de3291c 100644 --- a/src/webui/www/public/preferences_content.html +++ b/src/webui/www/public/preferences_content.html @@ -410,8 +410,9 @@
QBT_TR(Web User Interface (Remote control))QBT_TR[CONTEXT=OptionsDialog] -
+
+

@@ -1046,6 +1047,7 @@ loadPreferences = function() { // HTTP Server $('webui_domain_textarea').setProperty('value', pref.web_ui_domain_list); + $('webui_address_value').setProperty('value', pref.web_ui_address); $('webui_port_value').setProperty('value', pref.web_ui_port); $('webui_upnp_checkbox').setProperty('checked', pref.web_ui_upnp); $('use_https_checkbox').setProperty('checked', pref.use_https); @@ -1314,11 +1316,13 @@ applyPreferences = function() { // HTTP Server settings.set('web_ui_domain_list', $('webui_domain_textarea').getProperty('value')); + var web_ui_address = $('webui_address_value').getProperty('value').toString(); var web_ui_port = $('webui_port_value').getProperty('value').toInt(); if(isNaN(web_ui_port) || web_ui_port < 1 || web_ui_port > 65535) { alert("QBT_TR(The port used for the Web UI must be between 1 and 65535.)QBT_TR[CONTEXT=HttpServer]"); return; } + settings.set('web_ui_address', web_ui_address); settings.set('web_ui_port', web_ui_port); settings.set('web_ui_upnp', $('webui_upnp_checkbox').getProperty('checked')); settings.set('use_https', $('use_https_checkbox').getProperty('checked'));