Skip to content

Commit

Permalink
Add option to lock parameters system scope
Browse files Browse the repository at this point in the history
IB-7376

Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma committed May 25, 2023
1 parent 8b07a7f commit 56d638a
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 127 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,18 @@ jobs:
container: ${{ matrix.container }}
strategy:
matrix:
container: ['ubuntu:20.04', 'ubuntu:22.04', 'ubuntu:22.10']
container: ['ubuntu:20.04', 'ubuntu:22.04', 'ubuntu:23.04']
env:
DEBIAN_FRONTEND: noninteractive
DEBFULLNAME: github-actions
DEBEMAIL: [email protected]
steps:
- name: Install dependencies
if: matrix.container == 'ubuntu:20.04'
run: apt update -qq && apt install --no-install-recommends -y git lsb-release fakeroot build-essential devscripts cdbs pkg-config cmake libldap2-dev gettext libpcsclite-dev libssl-dev libqt5svg5-dev qttools5-dev-tools qttools5-dev lintian
run: apt update -qq && apt install --no-install-recommends -y git lsb-release fakeroot build-essential devscripts debhelper cdbs pkg-config cmake libldap2-dev gettext libpcsclite-dev libssl-dev libqt5svg5-dev qttools5-dev-tools qttools5-dev lintian
- name: Install dependencies
if: matrix.container != 'ubuntu:20.04'
run: apt update -qq && apt install --no-install-recommends -y git lsb-release fakeroot build-essential devscripts cdbs pkg-config cmake libldap2-dev gettext libpcsclite-dev libssl-dev libgl-dev libqt6svg6-dev qt6-tools-dev qt6-tools-dev-tools qt6-l10n-tools libqt6core5compat6-dev lintian
run: apt update -qq && apt install --no-install-recommends -y git lsb-release fakeroot build-essential devscripts debhelper cdbs pkg-config cmake libldap2-dev gettext libpcsclite-dev libssl-dev libgl-dev libqt6svg6-dev qt6-tools-dev qt6-tools-dev-tools qt6-l10n-tools libqt6core5compat6-dev lintian
- name: Checkout
uses: actions/checkout@v3
with:
Expand Down Expand Up @@ -105,7 +105,7 @@ jobs:
container: ${{ matrix.container }}
strategy:
matrix:
container: ['fedora:36', 'fedora:37']
container: ['fedora:37', 'fedora:38']
env:
MAKEFLAGS: -j3
steps:
Expand Down
6 changes: 0 additions & 6 deletions client/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,6 @@ class DigidocConf final: public digidoc::XmlConfCurrent
if(Settings::TSA_URL == Application::confValue(Settings::TSA_URL.KEY).toString())
Settings::TSA_URL.clear(); // Cleanup user conf if it is default url
Settings::SETTINGS_MIGRATED.clear();
QList<QSslCertificate> list;
for(const auto &cert: Application::confValue(QLatin1String("CERT-BUNDLE")).toArray())
list.append(QSslCertificate(fromBase64(cert), QSsl::Der));
QSslConfiguration ssl = QSslConfiguration::defaultConfiguration();
ssl.setCaCertificates(list);
QSslConfiguration::setDefaultConfiguration(ssl);
}
#endif

Expand Down
55 changes: 50 additions & 5 deletions client/CheckConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,22 @@

#include "CheckConnection.h"

#include "Application.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QEventLoop>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonValue>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>

CheckConnection::CheckConnection() = default;

bool CheckConnection::check(const QString &url)
{
QNetworkAccessManager nam;
QEventLoop e;
QNetworkReply *reply = nam.head(QNetworkRequest(url));
QObject::connect(reply, &QNetworkReply::sslErrors, reply, [&](const QList<QSslError> &errors){
reply->ignoreSslErrors(errors);
});
QObject::connect(reply, &QNetworkReply::sslErrors, reply,
QOverload<const QList<QSslError> &>::of(&QNetworkReply::ignoreSslErrors));
QObject::connect(reply, &QNetworkReply::finished, &e, &QEventLoop::quit);
e.exec();
m_error = reply->error();
Expand All @@ -60,3 +61,47 @@ QString CheckConnection::errorString() const
return QCoreApplication::translate("CheckConnection", "Cannot connect to certificate status service!");
}
}

QNetworkAccessManager* CheckConnection::setupNAM(QNetworkRequest &req, const QByteArray &add)
{
req.setSslConfiguration(sslConfiguration(add));
req.setRawHeader("User-Agent", QStringLiteral("%1/%2 (%3)")
.arg(Application::applicationName(), Application::applicationVersion(), Common::applicationOs()).toUtf8());
auto *nam = new QNetworkAccessManager();
QObject::connect(nam, &QNetworkAccessManager::sslErrors, nam, [](QNetworkReply *reply, const QList<QSslError> &errors) {
QList<QSslError> ignore;
for(const QSslError &error: errors)
{
switch(error.error())
{
case QSslError::UnableToVerifyFirstCertificate:
case QSslError::UnableToGetLocalIssuerCertificate:
case QSslError::CertificateUntrusted:
case QSslError::SelfSignedCertificateInChain:
if(reply->sslConfiguration().caCertificates().contains(reply->sslConfiguration().peerCertificate())) {
ignore.append(error);
break;
}
Q_FALLTHROUGH();
default:
qDebug() << "SSL Error:" << error.error() << error.certificate().subjectInfo(QSslCertificate::CommonName);
}
}
reply->ignoreSslErrors(ignore);
});
return nam;
}

QSslConfiguration CheckConnection::sslConfiguration(const QByteArray &add)
{
QSslConfiguration ssl = QSslConfiguration::defaultConfiguration();
#ifdef CONFIG_URL
QList<QSslCertificate> trusted;
for(const auto &cert: Application::confValue(QLatin1String("CERT-BUNDLE")).toArray())
trusted.append(QSslCertificate(QByteArray::fromBase64(cert.toString().toLatin1()), QSsl::Der));
if(!add.isEmpty())
trusted.append(QSslCertificate(QByteArray::fromBase64(add), QSsl::Der));
ssl.setCaCertificates(trusted);
#endif
return ssl;
}
5 changes: 3 additions & 2 deletions client/CheckConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@
class CheckConnection
{
public:
CheckConnection();

bool check(const QString &url);
QNetworkReply::NetworkError error() const;
QString errorString() const;
QString errorDetails() const;

static QNetworkAccessManager* setupNAM(QNetworkRequest &req, const QByteArray &add = {});
static QSslConfiguration sslConfiguration(const QByteArray &add = {});

private:
QNetworkReply::NetworkError m_error = QNetworkReply::NoError;
QString qtmessage;
Expand Down
12 changes: 8 additions & 4 deletions client/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ using Option = Settings::Option<T, D>;
const Option<QString> Settings::MID_UUID { QStringLiteral("MIDUUID") };
const Option<QString> Settings::MID_NAME { QStringLiteral("MIDNAME"), QStringLiteral("RIA DigiDoc") };
const Option<QString, QString (*)()> Settings::MID_PROXY_URL { QStringLiteral("MID-PROXY-URL"), [] {
return qApp->confValue(QLatin1String("MID-PROXY-URL")).toString(QStringLiteral(MOBILEID_URL));
return Application::confValue(QLatin1String("MID-PROXY-URL")).toString(QStringLiteral(MOBILEID_URL));
}};
const Option<QString, QString (*)()> Settings::MID_SK_URL { QStringLiteral("MID-SK-URL"), [] {
return qApp->confValue(QLatin1String("MID-SK-URL")).toString(QStringLiteral(MOBILEID_URL));
return Application::confValue(QLatin1String("MID-SK-URL")).toString(QStringLiteral(MOBILEID_URL));
}};
const Option<bool, bool (*)()> Settings::MID_UUID_CUSTOM
{ QStringLiteral("MIDUUID-CUSTOM"), [] { return Settings::MID_UUID.isSet(); } };
Expand All @@ -44,10 +44,14 @@ const Option<bool> Settings::MOBILEID_ORDER { QStringLiteral("MIDOrder"), true }
const Option<QString> Settings::SID_UUID { QStringLiteral("SIDUUID") };
const Option<QString> Settings::SID_NAME { QStringLiteral("SIDNAME"), QStringLiteral("RIA DigiDoc") };
const Option<QString, QString (*)()> Settings::SID_PROXY_URL { QStringLiteral("SID-PROXY-URL"), []{
return qApp->confValue(QLatin1String("SIDV2-PROXY-URL")).toString(qApp->confValue(QLatin1String("SID-PROXY-URL")).toString(QStringLiteral(SMARTID_URL)));
return Application::confValue(QLatin1String("SIDV2-PROXY-URL"))
.toString(Application::confValue(QLatin1String("SID-PROXY-URL"))
.toString(QStringLiteral(SMARTID_URL)));
}};
const Option<QString, QString (*)()> Settings::SID_SK_URL { QStringLiteral("SID-SK-URL"), []{
return qApp->confValue(QLatin1String("SIDV2-SK-URL")).toString(qApp->confValue(QLatin1String("SID-SK-URL")).toString(QStringLiteral(SMARTID_URL)));
return Application::confValue(QLatin1String("SIDV2-SK-URL"))
.toString(Application::confValue(QLatin1String("SID-SK-URL"))
.toString(QStringLiteral(SMARTID_URL)));
}};
const Option<bool, bool (*)()> Settings::SID_UUID_CUSTOM
{ QStringLiteral("SIDUUID-CUSTOM"), [] { return Settings::SID_UUID.isSet(); } };
Expand Down
18 changes: 16 additions & 2 deletions client/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#pragma once

#include <QtCore/QCoreApplication>
#include <QtCore/QSettings>

template<typename T>
Expand All @@ -30,7 +31,7 @@ struct Settings
struct Option
{
operator QVariant() const {
return QSettings().value(KEY, defaultValue());
return settings().value(KEY, defaultValue());
}
operator T() const {
return operator QVariant().template value<T>();
Expand All @@ -52,11 +53,14 @@ struct Settings
void clear() const {
QSettings().remove(KEY);
}
bool isLocked() const {
return settings(QSettings::SystemScope).value(KEY + QLatin1String("_LOCK"), false).toBool();
}
bool isSet() const {
return QSettings().contains(KEY);
}
T value(const QVariant &def) const {
return QSettings().value(KEY, def).template value<T>();
return settings().value(KEY, def).template value<T>();
}
void setValue(const QVariant &value, const QVariant &def = {}) const {
if(bool valueIsNullOrEmpty = value.type() == QVariant::String ? value.toString().isEmpty() : value.isNull();
Expand All @@ -71,6 +75,16 @@ struct Settings
else
return DEFAULT;
}
QSettings settings() const {
return settings(isLocked() ? QSettings::SystemScope : QSettings::UserScope);
}
static QSettings settings(QSettings::Scope scope) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
return QSettings(scope);
#else
return QSettings(scope, QCoreApplication::organizationName(), QCoreApplication::applicationName());
#endif
}
const QString KEY;
const D DEFAULT {};
};
Expand Down
24 changes: 14 additions & 10 deletions client/dialogs/AddRecipients.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "ui_AddRecipients.h"

#include "Application.h"
#include "CheckConnection.h"
#include "common_enums.h"
#include "FileDialog.h"
#include "IKValidator.h"
Expand All @@ -32,18 +33,18 @@
#include "dialogs/WarningDialog.h"
#include "effects/Overlay.h"

#include <common/Configuration.h>

#include <QDebug>
#include <QDateTime>
#include <QSslKey>
#include <QStandardPaths>
#include <QtCore/QDateTime>
#include <QtCore/QDebug>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonObject>
#include <QtCore/QSettings>
#include <QtCore/QStandardPaths>
#include <QtCore/QXmlStreamReader>
#include <QtCore/QXmlStreamWriter>
#include <QtCore/QSettings>
#include <QMessageBox>
#include <QtNetwork/QSslConfiguration>
#include <QtNetwork/QSslError>
#include <QtNetwork/QSslKey>
#include <QtWidgets/QMessageBox>

AddRecipients::AddRecipients(ItemList* itemList, QWidget *parent)
: QDialog(parent)
Expand Down Expand Up @@ -230,9 +231,12 @@ bool AddRecipients::addRecipientToRightPane(const CKey &key, bool update)
dlg->setCancelText(tr("NO"));
dlg->addButton(tr("YES"), QMessageBox::Yes);
if(dlg->exec() != QMessageBox::Yes)
return false;
return false;
}
QSslConfiguration backup = QSslConfiguration::defaultConfiguration();
QSslConfiguration::setDefaultConfiguration(CheckConnection::sslConfiguration());
QList<QSslError> errors = QSslCertificate::verify({ key.cert });
QSslConfiguration::setDefaultConfiguration(backup);
errors.removeAll(QSslError(QSslError::CertificateExpired, key.cert));
if(!errors.isEmpty())
{
Expand Down Expand Up @@ -305,7 +309,7 @@ QList<CKey> AddRecipients::keys()
QString AddRecipients::path()
{
#ifdef Q_OS_WIN
QSettings s( QSettings::IniFormat, QSettings::UserScope, qApp->organizationName(), "qdigidoccrypto" );
QSettings s(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), "qdigidoccrypto");
QFileInfo f( s.fileName() );
return f.absolutePath() + "/" + f.baseName() + "/certhistory.xml";
#else
Expand Down
38 changes: 4 additions & 34 deletions client/dialogs/MobileProgress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@
#include "ui_MobileProgress.h"

#include "Application.h"
#include "CheckConnection.h"
#include "Settings.h"
#include "Styles.h"
#include "Utils.h"
#include "dialogs/WarningDialog.h"

#include <common/Common.h>

#include <digidocpp/crypto/X509Cert.h>

#include <QtCore/QDir>
Expand All @@ -52,7 +51,7 @@ class MobileProgress::Private final: public QDialog, public Ui::MobileProgress
using QDialog::QDialog;
void reject() final { l.exit(QDialog::Rejected); }
QTimeLine *statusTimer{};
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QNetworkAccessManager *manager {};
QNetworkRequest req;
QString ssid, cell, sessionID;
std::vector<unsigned char> signature;
Expand Down Expand Up @@ -102,38 +101,9 @@ background-color: #007aff;
QObject::connect(d->statusTimer, &QTimeLine::frameChanged, d->signProgressBar, &QProgressBar::setValue);
QObject::connect(d->statusTimer, &QTimeLine::finished, d, &QDialog::reject);

#ifdef CONFIG_URL
QList<QSslCertificate> trusted;
for(const auto &cert: Application::confValue(QLatin1String("CERT-BUNDLE")).toArray())
trusted.append(QSslCertificate(QByteArray::fromBase64(cert.toString().toLatin1()), QSsl::Der));
QSslConfiguration ssl = QSslConfiguration::defaultConfiguration();
ssl.setCaCertificates(trusted);
d->req.setSslConfiguration(ssl);
#endif
d->req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
d->req.setRawHeader("User-Agent", QStringLiteral("%1/%2 (%3)")
.arg(QApplication::applicationName(), QApplication::applicationVersion(), Common::applicationOs()).toUtf8());
QObject::connect(d->manager, &QNetworkAccessManager::sslErrors, d->manager, [](QNetworkReply *reply, const QList<QSslError> &err) {
QList<QSslError> ignore;
for(const QSslError &e: err)
{
switch(e.error())
{
case QSslError::UnableToGetLocalIssuerCertificate:
case QSslError::CertificateUntrusted:
case QSslError::SelfSignedCertificateInChain:
if(reply->sslConfiguration().caCertificates().contains(reply->sslConfiguration().peerCertificate())) {
ignore << e;
break;
}
Q_FALLTHROUGH();
default:
qCWarning(MIDLog) << "SSL Error:" << e.error() << e.certificate().subjectInfo(QSslCertificate::CommonName);
break;
}
}
reply->ignoreSslErrors(ignore);
});
d->manager = CheckConnection::setupNAM(d->req);
d->manager->setParent(d);
QObject::connect(d->manager, &QNetworkAccessManager::finished, d, [=](QNetworkReply *reply) {
QScopedPointer<QNetworkReply,QScopedPointerDeleteLater> scope(reply);
auto returnError = [=](const QString &err, const QString &details = {}) {
Expand Down
Loading

0 comments on commit 56d638a

Please sign in to comment.