|
|
@ -42,13 +42,9 @@ |
|
|
|
#include <QSystemTrayIcon> |
|
|
|
#include <QSystemTrayIcon> |
|
|
|
#include <QTranslator> |
|
|
|
#include <QTranslator> |
|
|
|
|
|
|
|
|
|
|
|
#ifndef QT_NO_OPENSSL |
|
|
|
|
|
|
|
#include <QSslCertificate> |
|
|
|
|
|
|
|
#include <QSslKey> |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "base/bittorrent/session.h" |
|
|
|
#include "base/bittorrent/session.h" |
|
|
|
#include "base/global.h" |
|
|
|
#include "base/global.h" |
|
|
|
|
|
|
|
#include "base/http/server.h" |
|
|
|
#include "base/net/dnsupdater.h" |
|
|
|
#include "base/net/dnsupdater.h" |
|
|
|
#include "base/net/portforwarder.h" |
|
|
|
#include "base/net/portforwarder.h" |
|
|
|
#include "base/net/proxyconfigurationmanager.h" |
|
|
|
#include "base/net/proxyconfigurationmanager.h" |
|
|
@ -59,6 +55,7 @@ |
|
|
|
#include "base/torrentfileguard.h" |
|
|
|
#include "base/torrentfileguard.h" |
|
|
|
#include "base/unicodestrings.h" |
|
|
|
#include "base/unicodestrings.h" |
|
|
|
#include "base/utils/fs.h" |
|
|
|
#include "base/utils/fs.h" |
|
|
|
|
|
|
|
#include "base/utils/net.h" |
|
|
|
#include "base/utils/password.h" |
|
|
|
#include "base/utils/password.h" |
|
|
|
#include "base/utils/random.h" |
|
|
|
#include "base/utils/random.h" |
|
|
|
#include "addnewtorrentdialog.h" |
|
|
|
#include "addnewtorrentdialog.h" |
|
|
@ -196,11 +193,6 @@ OptionsDialog::OptionsDialog(QWidget *parent) |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if defined(QT_NO_OPENSSL) |
|
|
|
|
|
|
|
m_ui->checkWebUiHttps->setVisible(false); |
|
|
|
|
|
|
|
m_ui->checkSmtpSSL->setVisible(false); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef Q_OS_WIN |
|
|
|
#ifndef Q_OS_WIN |
|
|
|
m_ui->checkStartup->setVisible(false); |
|
|
|
m_ui->checkStartup->setVisible(false); |
|
|
|
#endif |
|
|
|
#endif |
|
|
@ -390,14 +382,23 @@ OptionsDialog::OptionsDialog(QWidget *parent) |
|
|
|
|
|
|
|
|
|
|
|
#ifndef DISABLE_WEBUI |
|
|
|
#ifndef DISABLE_WEBUI |
|
|
|
// Web UI tab
|
|
|
|
// Web UI tab
|
|
|
|
|
|
|
|
m_ui->textWebUIHttpsCert->setMode(FileSystemPathEdit::Mode::FileOpen); |
|
|
|
|
|
|
|
m_ui->textWebUIHttpsCert->setFileNameFilter(tr("Certificate") + QLatin1String(" (*.cer *.crt *.pem)")); |
|
|
|
|
|
|
|
m_ui->textWebUIHttpsCert->setDialogCaption(tr("Select certificate")); |
|
|
|
|
|
|
|
m_ui->textWebUIHttpsKey->setMode(FileSystemPathEdit::Mode::FileOpen); |
|
|
|
|
|
|
|
m_ui->textWebUIHttpsKey->setFileNameFilter(tr("Private key") + QLatin1String(" (*.key *.pem)")); |
|
|
|
|
|
|
|
m_ui->textWebUIHttpsKey->setDialogCaption(tr("Select private key")); |
|
|
|
|
|
|
|
|
|
|
|
connect(m_ui->textServerDomains, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->textServerDomains, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->checkWebUi, &QGroupBox::toggled, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->checkWebUi, &QGroupBox::toggled, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->textWebUiAddress, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->textWebUiAddress, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->spinWebUiPort, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->spinWebUiPort, qSpinBoxValueChanged, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->checkWebUIUPnP, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->checkWebUIUPnP, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->checkWebUiHttps, &QGroupBox::toggled, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->checkWebUiHttps, &QGroupBox::toggled, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->btnWebUiKey, &QAbstractButton::clicked, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->textWebUIHttpsCert, &FileSystemPathLineEdit::selectedPathChanged, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->btnWebUiCrt, &QAbstractButton::clicked, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->textWebUIHttpsCert, &FileSystemPathLineEdit::selectedPathChanged, this, [this](const QString &s) { webUIHttpsCertChanged(s, ShowError::Show); }); |
|
|
|
|
|
|
|
connect(m_ui->textWebUIHttpsKey, &FileSystemPathLineEdit::selectedPathChanged, this, &ThisType::enableApplyButton); |
|
|
|
|
|
|
|
connect(m_ui->textWebUIHttpsKey, &FileSystemPathLineEdit::selectedPathChanged, this, [this](const QString &s) { webUIHttpsKeyChanged(s, ShowError::Show); }); |
|
|
|
connect(m_ui->textWebUiUsername, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->textWebUiUsername, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->textWebUiPassword, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->textWebUiPassword, &QLineEdit::textChanged, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->checkBypassLocalAuth, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); |
|
|
|
connect(m_ui->checkBypassLocalAuth, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); |
|
|
@ -722,11 +723,8 @@ void OptionsDialog::saveOptions() |
|
|
|
pref->setWebUiPort(m_ui->spinWebUiPort->value()); |
|
|
|
pref->setWebUiPort(m_ui->spinWebUiPort->value()); |
|
|
|
pref->setUPnPForWebUIPort(m_ui->checkWebUIUPnP->isChecked()); |
|
|
|
pref->setUPnPForWebUIPort(m_ui->checkWebUIUPnP->isChecked()); |
|
|
|
pref->setWebUiHttpsEnabled(m_ui->checkWebUiHttps->isChecked()); |
|
|
|
pref->setWebUiHttpsEnabled(m_ui->checkWebUiHttps->isChecked()); |
|
|
|
// HTTPS
|
|
|
|
pref->setWebUIHttpsCertificatePath(m_ui->textWebUIHttpsCert->selectedPath()); |
|
|
|
if (m_ui->checkWebUiHttps->isChecked()) { |
|
|
|
pref->setWebUIHttpsKeyPath(m_ui->textWebUIHttpsKey->selectedPath()); |
|
|
|
pref->setWebUiHttpsCertificate(m_sslCert); |
|
|
|
|
|
|
|
pref->setWebUiHttpsKey(m_sslKey); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Authentication
|
|
|
|
// Authentication
|
|
|
|
pref->setWebUiUsername(webUiUsername()); |
|
|
|
pref->setWebUiUsername(webUiUsername()); |
|
|
|
if (!webUiPassword().isEmpty()) |
|
|
|
if (!webUiPassword().isEmpty()) |
|
|
@ -1089,8 +1087,8 @@ void OptionsDialog::loadOptions() |
|
|
|
m_ui->spinWebUiPort->setValue(pref->getWebUiPort()); |
|
|
|
m_ui->spinWebUiPort->setValue(pref->getWebUiPort()); |
|
|
|
m_ui->checkWebUIUPnP->setChecked(pref->useUPnPForWebUIPort()); |
|
|
|
m_ui->checkWebUIUPnP->setChecked(pref->useUPnPForWebUIPort()); |
|
|
|
m_ui->checkWebUiHttps->setChecked(pref->isWebUiHttpsEnabled()); |
|
|
|
m_ui->checkWebUiHttps->setChecked(pref->isWebUiHttpsEnabled()); |
|
|
|
setSslCertificate(pref->getWebUiHttpsCertificate()); |
|
|
|
webUIHttpsCertChanged(pref->getWebUIHttpsCertificatePath(), ShowError::NotShow); |
|
|
|
setSslKey(pref->getWebUiHttpsKey()); |
|
|
|
webUIHttpsKeyChanged(pref->getWebUIHttpsKeyPath(), ShowError::NotShow); |
|
|
|
m_ui->textWebUiUsername->setText(pref->getWebUiUsername()); |
|
|
|
m_ui->textWebUiUsername->setText(pref->getWebUiUsername()); |
|
|
|
m_ui->checkBypassLocalAuth->setChecked(!pref->isWebUiLocalAuthEnabled()); |
|
|
|
m_ui->checkBypassLocalAuth->setChecked(!pref->isWebUiLocalAuthEnabled()); |
|
|
|
m_ui->checkBypassAuthSubnetWhitelist->setChecked(pref->isWebUiAuthSubnetWhitelistEnabled()); |
|
|
|
m_ui->checkBypassAuthSubnetWhitelist->setChecked(pref->isWebUiAuthSubnetWhitelistEnabled()); |
|
|
@ -1559,39 +1557,57 @@ QString OptionsDialog::webUiPassword() const |
|
|
|
return m_ui->textWebUiPassword->text(); |
|
|
|
return m_ui->textWebUiPassword->text(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void OptionsDialog::showConnectionTab() |
|
|
|
void OptionsDialog::webUIHttpsCertChanged(const QString &path, const ShowError showError) |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_ui->tabSelection->setCurrentRow(TAB_CONNECTION); |
|
|
|
m_ui->textWebUIHttpsCert->setSelectedPath(path); |
|
|
|
} |
|
|
|
m_ui->lblSslCertStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-low.svg", this, 24)); |
|
|
|
|
|
|
|
|
|
|
|
void OptionsDialog::on_btnWebUiCrt_clicked() |
|
|
|
if (path.isEmpty()) |
|
|
|
{ |
|
|
|
|
|
|
|
const QString filename = QFileDialog::getOpenFileName(this, tr("Import SSL certificate"), QString(), tr("SSL Certificate") + QLatin1String(" (*.crt *.pem)")); |
|
|
|
|
|
|
|
if (filename.isEmpty()) |
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
QFile cert(filename); |
|
|
|
QFile file(path); |
|
|
|
if (!cert.open(QIODevice::ReadOnly)) |
|
|
|
if (!file.open(QIODevice::ReadOnly)) { |
|
|
|
|
|
|
|
if (showError == ShowError::Show) |
|
|
|
|
|
|
|
QMessageBox::warning(this, tr("Invalid path"), file.errorString()); |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool success = setSslCertificate(cert.read(1024 * 1024)); |
|
|
|
if (!Utils::Net::isSSLCertificatesValid(file.read(Utils::Net::MAX_SSL_FILE_SIZE))) { |
|
|
|
if (!success) |
|
|
|
if (showError == ShowError::Show) |
|
|
|
QMessageBox::warning(this, tr("Invalid certificate"), tr("This is not a valid SSL certificate.")); |
|
|
|
QMessageBox::warning(this, tr("Invalid certificate"), tr("This is not a valid SSL certificate.")); |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void OptionsDialog::on_btnWebUiKey_clicked() |
|
|
|
m_ui->lblSslCertStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-high.svg", this, 24)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void OptionsDialog::webUIHttpsKeyChanged(const QString &path, const ShowError showError) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const QString filename = QFileDialog::getOpenFileName(this, tr("Import SSL key"), QString(), tr("SSL key") + QLatin1String(" (*.key *.pem)")); |
|
|
|
m_ui->textWebUIHttpsKey->setSelectedPath(path); |
|
|
|
if (filename.isEmpty()) |
|
|
|
m_ui->lblSslKeyStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-low.svg", this, 24)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (path.isEmpty()) |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
QFile key(filename); |
|
|
|
QFile file(path); |
|
|
|
if (!key.open(QIODevice::ReadOnly)) |
|
|
|
if (!file.open(QIODevice::ReadOnly)) { |
|
|
|
|
|
|
|
if (showError == ShowError::Show) |
|
|
|
|
|
|
|
QMessageBox::warning(this, tr("Invalid path"), file.errorString()); |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool success = setSslKey(key.read(1024 * 1024)); |
|
|
|
if (!Utils::Net::isSSLKeyValid(file.read(Utils::Net::MAX_SSL_FILE_SIZE))) { |
|
|
|
if (!success) |
|
|
|
if (showError == ShowError::Show) |
|
|
|
QMessageBox::warning(this, tr("Invalid key"), tr("This is not a valid SSL key.")); |
|
|
|
QMessageBox::warning(this, tr("Invalid key"), tr("This is not a valid SSL key.")); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_ui->lblSslKeyStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-high.svg", this, 24)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void OptionsDialog::showConnectionTab() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_ui->tabSelection->setCurrentRow(TAB_CONNECTION); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void OptionsDialog::on_registerDNSBtn_clicked() |
|
|
|
void OptionsDialog::on_registerDNSBtn_clicked() |
|
|
@ -1698,45 +1714,6 @@ QString OptionsDialog::languageToLocalizedString(const QLocale &locale) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool OptionsDialog::setSslKey(const QByteArray &key) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
#ifndef QT_NO_OPENSSL |
|
|
|
|
|
|
|
// try different formats
|
|
|
|
|
|
|
|
const bool isKeyValid = (!QSslKey(key, QSsl::Rsa).isNull() || !QSslKey(key, QSsl::Ec).isNull()); |
|
|
|
|
|
|
|
if (isKeyValid) { |
|
|
|
|
|
|
|
m_ui->lblSslKeyStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-high.svg", this, 24)); |
|
|
|
|
|
|
|
m_sslKey = key; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
m_ui->lblSslKeyStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-low.svg", this, 24)); |
|
|
|
|
|
|
|
m_sslKey.clear(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return isKeyValid; |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
Q_UNUSED(key); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool OptionsDialog::setSslCertificate(const QByteArray &cert) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
#ifndef QT_NO_OPENSSL |
|
|
|
|
|
|
|
const bool isCertValid = !QSslCertificate(cert).isNull(); |
|
|
|
|
|
|
|
if (isCertValid) { |
|
|
|
|
|
|
|
m_ui->lblSslCertStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-high.svg", this, 24)); |
|
|
|
|
|
|
|
m_sslCert = cert; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
m_ui->lblSslCertStatus->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/qbt-theme/security-low.svg", this, 24)); |
|
|
|
|
|
|
|
m_sslCert.clear(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return isCertValid; |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
Q_UNUSED(cert); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool OptionsDialog::schedTimesOk() |
|
|
|
bool OptionsDialog::schedTimesOk() |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (m_ui->timeEditScheduleFrom->time() == m_ui->timeEditScheduleTo->time()) { |
|
|
|
if (m_ui->timeEditScheduleFrom->time() == m_ui->timeEditScheduleTo->time()) { |
|
|
|