diff --git a/core/document.cpp b/core/document.cpp index a097f4758..eb8973f6c 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -2704,7 +2704,32 @@ bool Document::canConfigurePrinter() const void Document::sign( const Okular::Annotation* pWhichAnnotation ) { if (d->m_generator->canSign()) - d->m_generator->sign( pWhichAnnotation ); + { + // we technically need to save the document before signing it, + // so let's ask before clobbering + const int res = KMessageBox::warningContinueCancel( + d->m_widget, + i18n( "Signing this document will modify the file \"%1\" on disk by embedding a " + "digital signature inside it. Do you wish to proceed?", + currentDocument().fileName() ), + i18n( "Sign Document" ), + KStandardGuiItem::ok(), + KStandardGuiItem::cancel(), + QStringLiteral("SignatureAutoClobber") ); + + if (res == KMessageBox::Continue) + { + // Sign it! + if (!d->m_generator->sign( pWhichAnnotation, currentDocument().path() )) + { + KMessageBox::error( nullptr, i18n("Could not sign '%1'. Invalid password or cannot write", + currentDocument().fileName() ) ); + } + // no need to - slotAttemptReload() gets called via + //dirty handler anyway: + //swapBackingFile(currentDocument().path(), currentDocument()); + } + } } DocumentInfo Document::documentInfo() const diff --git a/core/generator.h b/core/generator.h index 4ffef90db..5b4d88a02 100644 --- a/core/generator.h +++ b/core/generator.h @@ -309,7 +309,7 @@ public: virtual bool canSign() const { return false; } - virtual void sign( const Okular::Annotation* /*pWhichAnnotation*/) { return; } + virtual bool sign( const Okular::Annotation* /*pWhichAnnotation*/, const QString& /*rFilename*/) { return false; } /** * This method can be called to trigger the generation of diff --git a/generators/poppler/CMakeLists.txt b/generators/poppler/CMakeLists.txt index 7befc57cc..40406548a 100644 --- a/generators/poppler/CMakeLists.txt +++ b/generators/poppler/CMakeLists.txt @@ -19,7 +19,7 @@ check_cxx_source_compiles(" #include int main() { - auto f = &Poppler::Document::sign; + auto f = &Poppler::PDFConverter::sign; } " HAVE_POPPLER_SIGNING) diff --git a/generators/poppler/generator_pdf.cpp b/generators/poppler/generator_pdf.cpp index b954db79a..0769fdf3f 100644 --- a/generators/poppler/generator_pdf.cpp +++ b/generators/poppler/generator_pdf.cpp @@ -1854,16 +1854,35 @@ Okular::AnnotationProxy *PDFGenerator::annotationProxy() const return annotProxy; } -void PDFGenerator::sign( const Okular::Annotation* pWhichAnnotation ) +bool PDFGenerator::sign( const Okular::Annotation* pWhichAnnotation, const QString& rFilename ) { #ifdef HAVE_POPPLER_SIGNING const Okular::WidgetAnnotation* wa = dynamic_cast(pWhichAnnotation); Poppler::Annotation *popplerAnn = qvariant_cast< Poppler::Annotation * >( pWhichAnnotation->nativeId() ); - pdfdoc->sign( popplerAnn, wa->certificateCN(), wa->password() ); + + // save to tmp file - poppler doesn't like overwriting in-place + QTemporaryFile tf(QDir::tempPath() + QLatin1String("/okular_XXXXXX.pdf")); + tf.setAutoRemove(false); + if (!tf.open()) + return false; + std::unique_ptr converter( + pdfdoc->pdfConverter()); + converter->setOutputFileName(tf.fileName()); + converter->setPDFOptions(converter->pdfOptions() | Poppler::PDFConverter::WithChanges); + if (!converter->sign( popplerAnn, wa->certificateCN(), QString(), wa->password(), QString())) + return false; + + // now copy over old file + tf.remove(rFilename); + if (!tf.rename(rFilename)) + return false; #else Q_UNUSED( pWhichAnnotation ); + Q_UNUSED( rFilename ); #endif + + return true; } #include "generator_pdf.moc" diff --git a/generators/poppler/generator_pdf.h b/generators/poppler/generator_pdf.h index b1c6acf66..8b588840b 100644 --- a/generators/poppler/generator_pdf.h +++ b/generators/poppler/generator_pdf.h @@ -101,7 +101,7 @@ public: Okular::AnnotationProxy *annotationProxy() const override; bool canSign() const override {return true;} - void sign( const Okular::Annotation* pWhichAnnotation ) override; + bool sign( const Okular::Annotation* pWhichAnnotation, const QString& rFilename ) override; protected: SwapBackingFileResult swapBackingFile(QString const &newFileName, QVector &newPagesVector) override;