diff --git a/generators/poppler/conf/pdfsettings.kcfg b/generators/poppler/conf/pdfsettings.kcfg index c784c2bce..23ac6b0d1 100644 --- a/generators/poppler/conf/pdfsettings.kcfg +++ b/generators/poppler/conf/pdfsettings.kcfg @@ -5,6 +5,7 @@ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > + @@ -17,6 +18,9 @@ + + + true diff --git a/generators/poppler/conf/pdfsettingswidget.ui b/generators/poppler/conf/pdfsettingswidget.ui index 097a897e0..39fde8f83 100644 --- a/generators/poppler/conf/pdfsettingswidget.ui +++ b/generators/poppler/conf/pdfsettingswidget.ui @@ -67,6 +67,47 @@ + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Signature backend: + + + + + + + + + + Qt::Horizontal + + + + 480 + 0 + + + + + + + diff --git a/generators/poppler/generator_pdf.cpp b/generators/poppler/generator_pdf.cpp index 8c74b5248..34a17c931 100644 --- a/generators/poppler/generator_pdf.cpp +++ b/generators/poppler/generator_pdf.cpp @@ -642,6 +642,12 @@ PDFGenerator::PDFGenerator(QObject *parent, const QVariantList &args) if (!PDFSettings::useDefaultCertDB()) { Poppler::setNSSDir(QUrl(PDFSettings::dBCertificatePath()).toLocalFile()); } +#if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 05, 0) + auto activeBackend = PDFSettingsWidget::settingStringToPopplerEnum(PDFSettings::signatureBackend()); + if (activeBackend) { + Poppler::setActiveCryptoSignBackend(activeBackend.value()); + } +#endif } PDFGenerator::~PDFGenerator() @@ -2001,7 +2007,11 @@ Okular::AnnotationProxy *PDFGenerator::annotationProxy() const bool PDFGenerator::canSign() const { +#if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 05, 0) + return !Poppler::availableCryptoSignBackends().empty(); +#else return Poppler::hasNSSSupport(); +#endif } bool PDFGenerator::sign(const Okular::NewSignatureData &oData, const QString &rFilename) diff --git a/generators/poppler/pdfsettingswidget.cpp b/generators/poppler/pdfsettingswidget.cpp index 94d8479d2..30214b79b 100644 --- a/generators/poppler/pdfsettingswidget.cpp +++ b/generators/poppler/pdfsettingswidget.cpp @@ -19,11 +19,92 @@ #include #include +#if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 05, 0) +QString PDFSettingsWidget::popplerEnumToSettingString(Poppler::CryptoSignBackend backend) +{ + switch (backend) { + case Poppler::CryptoSignBackend::NSS: + return QStringLiteral("NSS"); + case Poppler::CryptoSignBackend::GPG: + return QStringLiteral("GPG"); + } + return {}; +} + +static QString popplerEnumToUserString(Poppler::CryptoSignBackend backend) +{ + // I'm unsure if we want these translatable, but if so + // we sholud do something here rather than forward directly to the + // technical popplerEnumToSettingString + return PDFSettingsWidget::popplerEnumToSettingString(backend); +} + +std::optional PDFSettingsWidget::settingStringToPopplerEnum(QStringView backend) +{ + if (backend == QStringLiteral("NSS")) + return Poppler::CryptoSignBackend::NSS; + if (backend == QStringLiteral("GPG")) + return Poppler::CryptoSignBackend::GPG; + return std::nullopt; +} +#endif + PDFSettingsWidget::PDFSettingsWidget(QWidget *parent) : QWidget(parent) { m_pdfsw.setupUi(this); + +#if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 05, 0) + auto backends = Poppler::availableCryptoSignBackends(); + if (!backends.empty()) { + // Let's try get the currently stored backend: + auto currentBackend = settingStringToPopplerEnum(PDFSettings::self()->signatureBackend()); + if (!currentBackend) { + currentBackend = Poppler::activeCryptoSignBackend(); + } + if (currentBackend != Poppler::activeCryptoSignBackend() && currentBackend) { + if (!Poppler::setActiveCryptoSignBackend(currentBackend.value())) { + // erm. This must be a case of having either modified + // the config file manually to something not available + // in the poppler installed here or have reconfigured + // their poppler to not have the previously selected one + // available any longer. + // Probably the safest bet is to take whatever is active + currentBackend = Poppler::activeCryptoSignBackend(); + } + } + int selected = -1; + for (auto backend : backends) { + if (backend == currentBackend) { + selected = m_pdfsw.kcfg_SignatureBackend->count(); + } + m_pdfsw.kcfg_SignatureBackend->addItem(popplerEnumToUserString(backend), QVariant(popplerEnumToSettingString(backend))); + } + m_pdfsw.kcfg_SignatureBackend->setProperty("kcfg_property", QByteArray("currentData")); + + m_pdfsw.kcfg_SignatureBackend->setCurrentIndex(selected); + connect(m_pdfsw.kcfg_SignatureBackend, &QComboBox::currentTextChanged, [this](const QString &text) { + auto backendEnum = settingStringToPopplerEnum(text); + if (!backendEnum) { + return; + } + Poppler::setActiveCryptoSignBackend(backendEnum.value()); + m_pdfsw.certDBGroupBox->setVisible(backendEnum == Poppler::CryptoSignBackend::NSS); + m_certificatesAsked = false; + if (m_tree) { + m_tree->clear(); + } + update(); + }); + + m_pdfsw.certDBGroupBox->setVisible(currentBackend == Poppler::CryptoSignBackend::NSS); +#else if (Poppler::hasNSSSupport()) { + // Better hide the signature backend selection; we have not really any + // need for that. + m_pdfsw.signatureBackendContainer->hide(); +#endif + m_pdfsw.loadSignaturesButton->hide(); KUrlRequester *pDlg = new KUrlRequester(); @@ -92,6 +173,11 @@ bool PDFSettingsWidget::event(QEvent *e) void PDFSettingsWidget::warnRestartNeeded() { if (!m_warnedAboutRestart) { +#if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 05, 0) + if (PDFSettings::self()->signatureBackend() != QStringLiteral("NSS")) { + return; + } +#endif m_warnedAboutRestart = true; QMessageBox::information(this, i18n("Restart needed"), i18n("You need to restart Okular after changing the NSS directory settings")); } diff --git a/generators/poppler/pdfsettingswidget.h b/generators/poppler/pdfsettingswidget.h index e56173d38..79a59f8a4 100644 --- a/generators/poppler/pdfsettingswidget.h +++ b/generators/poppler/pdfsettingswidget.h @@ -11,6 +11,10 @@ #include #include "ui_pdfsettingswidget.h" +#include +#include + +#define POPPLER_VERSION_MACRO ((POPPLER_VERSION_MAJOR << 16) | (POPPLER_VERSION_MINOR << 8) | (POPPLER_VERSION_MICRO)) class QTreeWidget; @@ -21,6 +25,10 @@ class PDFSettingsWidget : public QWidget public: explicit PDFSettingsWidget(QWidget *parent = nullptr); bool event(QEvent *e) override; +#if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 05, 0) + static std::optional settingStringToPopplerEnum(QStringView string); + static QString popplerEnumToSettingString(Poppler::CryptoSignBackend backend); +#endif private: void warnRestartNeeded(); diff --git a/generators/poppler/pdfsignatureutils.cpp b/generators/poppler/pdfsignatureutils.cpp index ddab82cc3..582b433be 100644 --- a/generators/poppler/pdfsignatureutils.cpp +++ b/generators/poppler/pdfsignatureutils.cpp @@ -79,7 +79,19 @@ Okular::CertificateInfo fromPoppler(const Poppler::CertificateInfo &pInfo) oInfo.setPublicKeyStrength(pInfo.publicKeyStrength()); oInfo.setSelfSigned(pInfo.isSelfSigned()); oInfo.setCertificateData(pInfo.certificateData()); - oInfo.setCheckPasswordFunction([pInfo](const QString &password) { return pInfo.checkPassword(password); }); + oInfo.setCheckPasswordFunction([pInfo](const QString &password) { +#if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 05, 0) + auto backend = Poppler::activeCryptoSignBackend(); + if (!backend) { + return false; + } + if (Poppler::hasCryptoSignBackendFeature(backend.value(), Poppler::CryptoSignBackendFeature::BackendAsksPassphrase)) { + // we shouldn't ask anyone about passwords. The backend will do that themselves, so just assume everything is okay. + return true; + } +#endif + return pInfo.checkPassword(password); + }); return oInfo; }