From b096c8a2fa639fb23d4cadb53bb9053a9c238873 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 12 May 2026 15:16:02 +0300 Subject: [PATCH] Use LDAP trust store from Central Configuration IB-8929 Reported by Mark Zelinski (mazeli@taltech.ee) Signed-off-by: Raul Metsma --- client/LdapSearch.cpp | 50 ++++++++++++++++---------------- client/LdapSearch.h | 2 +- client/dialogs/AddRecipients.cpp | 20 +++++++++---- client/dialogs/AddRecipients.h | 2 ++ 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/client/LdapSearch.cpp b/client/LdapSearch.cpp index 7c725e9dc..98779c374 100644 --- a/client/LdapSearch.cpp +++ b/client/LdapSearch.cpp @@ -19,6 +19,7 @@ #include "LdapSearch.h" +#include #include #include #include @@ -61,14 +62,16 @@ class LdapSearch::Private public: LDAP *ldap {}; QUrl url; + QByteArray caCertPath; QTimer *timer {}; }; -LdapSearch::LdapSearch(const QString &url, QObject *parent) +LdapSearch::LdapSearch(const QString &url, const QString &caCertPath, QObject *parent) : QObject( parent ) , d(new Private) { d->url = QUrl(url); + d->caCertPath = QFile::encodeName(caCertPath); d->timer = new QTimer(this); d->timer->setSingleShot(true); connect(d->timer, &QTimer::timeout, this, [this]{ @@ -104,9 +107,24 @@ bool LdapSearch::init() } ULONG err = 0; #else + if(!d->caCertPath.isEmpty()) + { + if(auto err = ldap_set_option(nullptr, LDAP_OPT_X_TLS_CACERTFILE, d->caCertPath.constData()); err) + { + setLastError(tr("Failed to set ldap CA cert"), err); + return false; + } + } + + int cert_flag = LDAP_OPT_X_TLS_DEMAND; + if(auto err = ldap_set_option(nullptr, LDAP_OPT_X_TLS_REQUIRE_CERT, &cert_flag); err) + { + setLastError(tr("Failed to start ssl"), err); + return false; + } + QByteArray host = d->url.toString(QUrl::RemovePath|QUrl::RemoveQuery|QUrl::RemoveFragment).toUtf8(); - int err = ldap_initialize(&d->ldap, host.constData()); - if(err) + if(auto err = ldap_initialize(&d->ldap, host.constData())) { setLastError(tr("Failed to init ldap"), err); return false; @@ -114,38 +132,20 @@ bool LdapSearch::init() #endif int version = LDAP_VERSION3; - err = ldap_set_option(d->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); - if(err) + if(auto err = ldap_set_option(d->ldap, LDAP_OPT_PROTOCOL_VERSION, &version)) { setLastError(tr("Failed to set ldap version"), err); return false; } -#ifndef Q_OS_WIN -#if 1 - int cert_flag = LDAP_OPT_X_TLS_NEVER; - err = ldap_set_option(nullptr, LDAP_OPT_X_TLS_REQUIRE_CERT, &cert_flag); - if(err) + if(auto err = ldap_simple_bind_s(d->ldap, nullptr, nullptr)) { - setLastError(tr("Failed to start ssl"), err); - return false; - } -#else - err = ldap_set_option(nullptr, LDAP_OPT_X_TLS_CACERTFILE, ""); - if(err) - { - setLastError(tr("Failed to start ssl"), err); + setLastError(tr("Failed to init ldap"), err); return false; } -#endif -#endif - - err = ldap_simple_bind_s(d->ldap, nullptr, nullptr); - if(err) - setLastError(tr("Failed to init ldap"), err); d->timer->start(4min); - return !err; + return true; } void LdapSearch::search(const QString &search, const QVariantMap &userData) diff --git a/client/LdapSearch.h b/client/LdapSearch.h index e8a0d336d..fca009945 100644 --- a/client/LdapSearch.h +++ b/client/LdapSearch.h @@ -27,7 +27,7 @@ class LdapSearch final: public QObject Q_OBJECT public: - LdapSearch(const QString &url, QObject *parent = nullptr); + LdapSearch(const QString &url, const QString &caCertPath = {}, QObject *parent = nullptr); ~LdapSearch() final; void search(const QString &search, const QVariantMap &userData); diff --git a/client/dialogs/AddRecipients.cpp b/client/dialogs/AddRecipients.cpp index 1fb42a270..a81ecbfd5 100644 --- a/client/dialogs/AddRecipients.cpp +++ b/client/dialogs/AddRecipients.cpp @@ -43,18 +43,26 @@ AddRecipients::AddRecipients(ItemList* itemList, QWidget *parent) : QDialog(parent) , ui(new Ui::AddRecipients) - , ldap_corp(new LdapSearch(Application::confValue(QLatin1String("LDAP-CORP-URL")).toString(QStringLiteral("ldaps://k3.ldap.sk.ee")), this)) { - for(const auto list = Application::confValue(QLatin1String("LDAP-PERSON-URLS")).toArray(); auto url: list) { - ldap_person.append(new LdapSearch(url.toString(), this)); +#ifndef Q_OS_WIN + if(const auto list = Application::confValue(QLatin1String("LDAP-CERTS")).toArray(); + !list.isEmpty() && ldapCACerts.open()) + { + for(const auto &entry : list) + ldapCACerts.write(QSslCertificate(QByteArray::fromBase64(entry.toString().toLatin1()), QSsl::Der).toPem()); + ldapCACerts.close(); } +#endif + ldap_corp = new LdapSearch(Application::confValue(QLatin1String("LDAP-CORP-URL")).toString(QStringLiteral("ldaps://k3.ldap.sk.ee")), ldapCACerts.fileName(), this); + for(const auto list = Application::confValue(QLatin1String("LDAP-PERSON-URLS")).toArray(); auto url: list) + ldap_person.append(new LdapSearch(url.toString(), ldapCACerts.fileName(), this)); if(ldap_person.isEmpty()) { - ldap_person.append(new LdapSearch(QStringLiteral("ldaps://esteid.ldap.sk.ee"), this)); - ldap_person.append(new LdapSearch(QStringLiteral("ldaps://ldap.eidpki.ee/dc=eidpki,dc=ee"), this)); + ldap_person.append(new LdapSearch(QStringLiteral("ldaps://esteid.ldap.sk.ee"), ldapCACerts.fileName(), this)); + ldap_person.append(new LdapSearch(QStringLiteral("ldaps://ldap.eidpki.ee/dc=eidpki,dc=ee"), ldapCACerts.fileName(), this)); } ui->setupUi(this); -#if defined (Q_OS_WIN) +#ifdef Q_OS_WIN ui->actionLayout->setDirection(QBoxLayout::RightToLeft); #endif setWindowFlags( Qt::Dialog | Qt::CustomizeWindowHint ); diff --git a/client/dialogs/AddRecipients.h b/client/dialogs/AddRecipients.h index e18de0fee..3c0b6b339 100644 --- a/client/dialogs/AddRecipients.h +++ b/client/dialogs/AddRecipients.h @@ -22,6 +22,7 @@ #include "CertificateHistory.h" #include +#include namespace Ui { class AddRecipients; @@ -61,5 +62,6 @@ class AddRecipients final : public QDialog LdapSearch *ldap_corp; int multiSearch = 0; + QTemporaryFile ldapCACerts; HistoryList historyCertData; };