Browse Source

Allow to load/use ECDSA certificate in webUI.

Limit max read size
Improve messages in dialogs
Refactor
adaptive-webui-19844
Chocobo1 8 years ago
parent
commit
759bf4d73d
  1. 59
      src/gui/optionsdlg.cpp
  2. 4
      src/gui/optionsdlg.h
  3. 21
      src/webui/webui.cpp

59
src/gui/optionsdlg.cpp

@ -978,8 +978,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(), false); setSslCertificate(pref->getWebUiHttpsCertificate());
setSslKey(pref->getWebUiHttpsKey(), false); setSslKey(pref->getWebUiHttpsKey());
m_ui->textWebUiUsername->setText(pref->getWebUiUsername()); m_ui->textWebUiUsername->setText(pref->getWebUiUsername());
m_ui->textWebUiPassword->setText(pref->getWebUiPassword()); m_ui->textWebUiPassword->setText(pref->getWebUiPassword());
m_ui->checkBypassLocalAuth->setChecked(!pref->isWebUiLocalAuthEnabled()); m_ui->checkBypassLocalAuth->setChecked(!pref->isWebUiLocalAuthEnabled());
@ -1511,26 +1511,32 @@ void OptionsDialog::showConnectionTab()
void OptionsDialog::on_btnWebUiCrt_clicked() void OptionsDialog::on_btnWebUiCrt_clicked()
{ {
QString filename = QFileDialog::getOpenFileName(this, QString(), QString(), tr("SSL Certificate") + QString(" (*.crt *.pem)")); const QString filename = QFileDialog::getOpenFileName(this, tr("Import SSL certificate"), QString(), tr("SSL Certificate") + QLatin1String(" (*.crt *.pem)"));
if (filename.isNull()) if (filename.isEmpty())
return; return;
QFile file(filename);
if (file.open(QIODevice::ReadOnly)) { QFile cert(filename);
setSslCertificate(file.readAll()); if (!cert.open(QIODevice::ReadOnly))
file.close(); return;
}
bool success = setSslCertificate(cert.read(1024 * 1024));
if (!success)
QMessageBox::warning(this, tr("Invalid certificate"), tr("This is not a valid SSL certificate."));
} }
void OptionsDialog::on_btnWebUiKey_clicked() void OptionsDialog::on_btnWebUiKey_clicked()
{ {
QString filename = QFileDialog::getOpenFileName(this, QString(), QString(), tr("SSL Key") + QString(" (*.key *.pem)")); const QString filename = QFileDialog::getOpenFileName(this, tr("Import SSL key"), QString(), tr("SSL key") + QLatin1String(" (*.key *.pem)"));
if (filename.isNull()) if (filename.isEmpty())
return; return;
QFile file(filename);
if (file.open(QIODevice::ReadOnly)) { QFile key(filename);
setSslKey(file.readAll()); if (!key.open(QIODevice::ReadOnly))
file.close(); return;
}
bool success = setSslKey(key.read(1024 * 1024));
if (!success)
QMessageBox::warning(this, tr("Invalid key"), tr("This is not a valid SSL key."));
} }
void OptionsDialog::on_registerDNSBtn_clicked() void OptionsDialog::on_registerDNSBtn_clicked()
@ -1638,41 +1644,42 @@ QString OptionsDialog::languageToLocalizedString(const QLocale &locale)
} }
} }
void OptionsDialog::setSslKey(const QByteArray &key, bool interactive) bool OptionsDialog::setSslKey(const QByteArray &key)
{ {
#ifndef QT_NO_OPENSSL #ifndef QT_NO_OPENSSL
if (!key.isEmpty() && !QSslKey(key, QSsl::Rsa).isNull()) { // try different formats
const bool isKeyValid = (!QSslKey(key, QSsl::Rsa).isNull() || !QSslKey(key, QSsl::Ec).isNull());
if (isKeyValid) {
m_ui->lblSslKeyStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-high.png").scaledToHeight(20, Qt::SmoothTransformation)); m_ui->lblSslKeyStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-high.png").scaledToHeight(20, Qt::SmoothTransformation));
m_sslKey = key; m_sslKey = key;
} }
else { else {
m_ui->lblSslKeyStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-low.png").scaledToHeight(20, Qt::SmoothTransformation)); m_ui->lblSslKeyStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-low.png").scaledToHeight(20, Qt::SmoothTransformation));
m_sslKey.clear(); m_sslKey.clear();
if (interactive)
QMessageBox::warning(this, tr("Invalid key"), tr("This is not a valid SSL key."));
} }
return isKeyValid;
#else #else
Q_UNUSED(key); Q_UNUSED(key);
Q_UNUSED(interactive); return false;
#endif #endif
} }
void OptionsDialog::setSslCertificate(const QByteArray &cert, bool interactive) bool OptionsDialog::setSslCertificate(const QByteArray &cert)
{ {
#ifndef QT_NO_OPENSSL #ifndef QT_NO_OPENSSL
if (!cert.isEmpty() && !QSslCertificate(cert).isNull()) { const bool isCertValid = !QSslCertificate(cert).isNull();
if (isCertValid) {
m_ui->lblSslCertStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-high.png").scaledToHeight(20, Qt::SmoothTransformation)); m_ui->lblSslCertStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-high.png").scaledToHeight(20, Qt::SmoothTransformation));
m_sslCert = cert; m_sslCert = cert;
} }
else { else {
m_ui->lblSslCertStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-low.png").scaledToHeight(20, Qt::SmoothTransformation)); m_ui->lblSslCertStatus->setPixmap(QPixmap(":/icons/qbt-theme/security-low.png").scaledToHeight(20, Qt::SmoothTransformation));
m_sslCert.clear(); m_sslCert.clear();
if (interactive)
QMessageBox::warning(this, tr("Invalid certificate"), tr("This is not a valid SSL certificate."));
} }
return isCertValid;
#else #else
Q_UNUSED(cert); Q_UNUSED(cert);
Q_UNUSED(interactive); return false;
#endif #endif
} }

4
src/gui/optionsdlg.h

@ -171,8 +171,8 @@ private:
QSize sizeFittingScreen() const; QSize sizeFittingScreen() const;
private: private:
void setSslKey(const QByteArray &key, bool interactive = true); bool setSslKey(const QByteArray &key);
void setSslCertificate(const QByteArray &cert, bool interactive = true); bool setSslCertificate(const QByteArray &cert);
bool schedTimesOk(); bool schedTimesOk();
bool webUIAuthenticationOk(); bool webUIAuthenticationOk();

21
src/webui/webui.cpp

@ -26,13 +26,14 @@
* exception statement from your version. * exception statement from your version.
*/ */
#include "base/preferences.h" #include "webui.h"
#include "base/logger.h"
#include "base/http/server.h" #include "base/http/server.h"
#include "base/logger.h"
#include "base/net/dnsupdater.h" #include "base/net/dnsupdater.h"
#include "base/net/portforwarder.h" #include "base/net/portforwarder.h"
#include "base/preferences.h"
#include "webapplication.h" #include "webapplication.h"
#include "webui.h"
WebUI::WebUI(QObject *parent) WebUI::WebUI(QObject *parent)
: QObject(parent) : QObject(parent)
@ -65,11 +66,15 @@ void WebUI::init()
#ifndef QT_NO_OPENSSL #ifndef QT_NO_OPENSSL
if (pref->isWebUiHttpsEnabled()) { if (pref->isWebUiHttpsEnabled()) {
QList<QSslCertificate> certs = QSslCertificate::fromData(pref->getWebUiHttpsCertificate()); const QByteArray keyRaw = pref->getWebUiHttpsKey();
QSslKey key; QSslKey key(keyRaw, QSsl::Rsa);
key = QSslKey(pref->getWebUiHttpsKey(), QSsl::Rsa); if (key.isNull())
bool certsIsNull = std::any_of(certs.begin(), certs.end(), [](QSslCertificate c) { return c.isNull(); }); key = QSslKey(keyRaw, QSsl::Ec);
if (!certsIsNull && !certs.empty() && !key.isNull())
const QList<QSslCertificate> certs = QSslCertificate::fromData(pref->getWebUiHttpsCertificate());
const bool areCertsValid = !certs.empty() && std::all_of(certs.begin(), certs.end(), [](QSslCertificate c) { return !c.isNull(); });
if (!key.isNull() && areCertsValid)
httpServer_->enableHttps(certs, key); httpServer_->enableHttps(certs, key);
else else
httpServer_->disableHttps(); httpServer_->disableHttps();

Loading…
Cancel
Save