diff options
author | Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de> | 2020-04-01 09:58:09 +0200 |
---|---|---|
committer | Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de> | 2020-04-01 12:31:16 +0200 |
commit | 8d27d495a733cfc29753e2e78000b199632695f7 (patch) | |
tree | 99cdb876805e77dd4f34bc7cf313ea9cf202be14 /dbaccess | |
parent | e73688139b1d861a19bddbf5c2fd82de97d0c741 (diff) |
Related tdf#97694 Preserve macro signatures in Base
Change-Id: I139ac003d1c95144e6cb1beec774f3cf142625b7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91466
Tested-by: Jenkins
Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
Diffstat (limited to 'dbaccess')
-rw-r--r-- | dbaccess/source/core/dataaccess/databasedocument.cxx | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/dbaccess/source/core/dataaccess/databasedocument.cxx b/dbaccess/source/core/dataaccess/databasedocument.cxx index ff4e68ef3c15..fd93febbe8f1 100644 --- a/dbaccess/source/core/dataaccess/databasedocument.cxx +++ b/dbaccess/source/core/dataaccess/databasedocument.cxx @@ -40,6 +40,8 @@ #include <com/sun/star/lang/NoSupportException.hpp> #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp> +#include <com/sun/star/security/DocumentDigitalSignatures.hpp> +#include <com/sun/star/security/XDocumentDigitalSignatures.hpp> #include <com/sun/star/sdb/DatabaseContext.hpp> #include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp> #include <com/sun/star/task/XStatusIndicator.hpp> @@ -60,6 +62,7 @@ #include <comphelper/namedvaluecollection.hxx> #include <comphelper/numberedcollection.hxx> #include <comphelper/storagehelper.hxx> +#include <comphelper/processfactory.hxx> #include <comphelper/propertysetinfo.hxx> #include <comphelper/types.hxx> @@ -69,7 +72,9 @@ #include <cppuhelper/supportsservice.hxx> #include <framework/titlehelper.hxx> #include <unotools/saveopt.hxx> +#include <unotools/tempfile.hxx> #include <tools/diagnose_ex.h> +#include <osl/file.hxx> #include <osl/diagnose.h> #include <vcl/GraphicObject.hxx> @@ -1021,6 +1026,22 @@ void ODatabaseDocument::impl_storeAs_throw( const OUString& _rURL, const ::comph _rGuard.reset(); } + bool bTryToPreserveScriptSignature = false; + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + OUString aTmpFileURL = aTempFile.GetURL(); + if (m_pImpl->getScriptingSignatureState() == SignatureState::OK + || m_pImpl->getScriptingSignatureState() == SignatureState::NOTVALIDATED + || m_pImpl->getScriptingSignatureState() == SignatureState::INVALID) + { + bTryToPreserveScriptSignature = true; + // We need to first save the file (which removes the macro signature), then add the macro signature again. + // For that, we need a temporary copy of the original file. + osl::File::RC rc = osl::File::copy(m_pImpl->getDocFileLocation(), aTmpFileURL); + if (rc != osl::FileBase::E_None) + throw uno::RuntimeException("Could not create temp file"); + } + Reference< XStorage > xNewRootStorage; // will be non-NULL if our storage changed @@ -1066,6 +1087,75 @@ void ODatabaseDocument::impl_storeAs_throw( const OUString& _rURL, const ::comph Sequence< PropertyValue > aMediaDescriptor( lcl_appendFileNameToDescriptor( _rArguments, _rURL ) ); impl_storeToStorage_throw( xCurrentStorage, aMediaDescriptor, _rGuard ); + // Preserve script signature if the script has not changed + if (bTryToPreserveScriptSignature) + { + uno::Reference<security::XDocumentDigitalSignatures> xDDSigns; + try + { + OUString aODFVersion( + comphelper::OStorageHelper::GetODFVersionFromStorage(xCurrentStorage)); + xDDSigns = security::DocumentDigitalSignatures::createWithVersion( + comphelper::getProcessComponentContext(), aODFVersion); + + const OUString aScriptSignName + = xDDSigns->getScriptingContentSignatureDefaultStreamName(); + + if (!aScriptSignName.isEmpty()) + { + Reference<XStorage> xReadOrig + = comphelper::OStorageHelper::GetStorageOfFormatFromURL( + ZIP_STORAGE_FORMAT_STRING, aTmpFileURL, ElementModes::READ); + if (!xReadOrig.is()) + throw uno::RuntimeException("Could not read " + aTmpFileURL); + uno::Reference<embed::XStorage> xMetaInf + = xReadOrig->openStorageElement("META-INF", embed::ElementModes::READ); + + Reference<XStorage> xTarget + = comphelper::OStorageHelper::GetStorageOfFormatFromURL( + ZIP_STORAGE_FORMAT_STRING, _rURL, ElementModes::READWRITE); + if (!xTarget.is()) + throw uno::RuntimeException("Could not read " + _rURL); + uno::Reference<embed::XStorage> xTargetMetaInf + = xTarget->openStorageElement("META-INF", embed::ElementModes::READWRITE); + + if (xMetaInf.is() && xTargetMetaInf.is()) + { + xMetaInf->copyElementTo(aScriptSignName, xTargetMetaInf, aScriptSignName); + + uno::Reference<embed::XTransactedObject> xTransact(xTargetMetaInf, + uno::UNO_QUERY); + if (xTransact.is()) + xTransact->commit(); + + xTargetMetaInf->dispose(); + + // now check the copied signature + uno::Sequence<security::DocumentSignatureInformation> aInfos + = xDDSigns->verifyScriptingContentSignatures( + xTarget, uno::Reference<io::XInputStream>()); + SignatureState nState = DocumentSignatures::getSignatureState(aInfos); + if (nState == SignatureState::OK || nState == SignatureState::NOTVALIDATED + || nState == SignatureState::PARTIAL_OK) + { + // commit the ZipStorage from target medium + xTransact.set(xTarget, uno::UNO_QUERY); + if (xTransact.is()) + xTransact->commit(); + } + else + { + SAL_WARN("dbaccess", "An invalid signature was copied!"); + } + } + } + } + catch (uno::Exception&) + { + SAL_WARN("dbaccess", "Preserving macro signature failed!"); + } + } + // success - tell our impl m_pImpl->setDocFileLocation( _rURL ); m_pImpl->setResource( _rURL, aMediaDescriptor ); |