sw/source/filter/ww8/wrtww8.cxx | 105 ++++++++++++++++++++++++++++++++++++++++ sw/source/filter/ww8/wrtww8.hxx | 1 2 files changed, 106 insertions(+)
New commits: commit c6665a0fc8cdad31160daad65c10894cd3174584 Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Mon May 25 02:15:42 2020 +0200 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Mon May 25 10:05:33 2020 +0200 sw: add XPackageEncryption save support for binary doc This adds save support for API-based MS-CRYPTO algos. If we have custom encryption data in media descriptor and corresponding service is available it will be used during saving. Change-Id: I814e4a7f73979ff7a65831b99f77f1a9e85916de Reviewed-on: https://gerrit.libreoffice.org/c/core/+/84438 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de> diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx index 91d049a42e11..c3fe9c0a36f9 100644 --- a/sw/source/filter/ww8/wrtww8.cxx +++ b/sw/source/filter/ww8/wrtww8.cxx @@ -23,7 +23,10 @@ #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/embed/XStorage.hpp> #include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/packages/XPackageEncryption.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> #include <unotools/ucbstreamhelper.hxx> +#include <unotools/streamwrap.hxx> #include <algorithm> #include <map> #include <hintids.hxx> @@ -87,6 +90,8 @@ #include "sprmids.hxx" #include <comphelper/sequenceashashmap.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/string.hxx> #include "writerhelper.hxx" #include "writerwordglue.hxx" #include "ww8attributeoutput.hxx" @@ -3666,6 +3671,106 @@ void WW8Export::PrepareStorage() } ErrCode SwWW8Writer::WriteStorage() +{ + tools::SvRef<SotStorage> pOrigStg; + uno::Reference< packages::XPackageEncryption > xPackageEncryption; + std::shared_ptr<SvStream> pSotStorageStream; + uno::Sequence< beans::NamedValue > aEncryptionData; + if (mpMedium) + { + // Check for specific encryption requests + const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(mpMedium->GetItemSet(), SID_ENCRYPTIONDATA, false); + if (pEncryptionDataItem && (pEncryptionDataItem->GetValue() >>= aEncryptionData)) + { + ::comphelper::SequenceAsHashMap aHashData(aEncryptionData); + OUString sCryptoType = aHashData.getUnpackedValueOrDefault("CryptoType", OUString()); + + if (sCryptoType.getLength()) + { + uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext()); + uno::Sequence<uno::Any> aArguments{ + uno::makeAny(beans::NamedValue("Binary", uno::makeAny(true))) }; + xPackageEncryption.set( + xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, xComponentContext), uno::UNO_QUERY); + + if (xPackageEncryption.is()) + { + // We have an encryptor + // Create new temporary storage for content + pOrigStg = m_pStg; + pSotStorageStream = std::make_shared<SvMemoryStream>(); + m_pStg = new SotStorage(*pSotStorageStream); + } + } + } + } + + ErrCode nErrorCode = WriteStorageImpl(); + + if (xPackageEncryption.is()) + { + m_pStg->Commit(); + pSotStorageStream->Seek(0); + + // Encrypt data written into temporary storage + xPackageEncryption->setupEncryption(aEncryptionData); + + uno::Reference<io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(pSotStorageStream.get(), false)); + uno::Sequence<beans::NamedValue> aStreams = xPackageEncryption->encrypt(xInputStream); + + m_pStg = pOrigStg; + for (const beans::NamedValue & aStreamData : std::as_const(aStreams)) + { + // To avoid long paths split and open substorages recursively + // Splitting paths manually, since comphelper::string::split is trimming special characters like \0x01, \0x09 + SotStorage * pStorage = m_pStg.get(); + OUString sFileName; + sal_Int32 idx = 0; + do + { + OUString sPathElem = aStreamData.Name.getToken(0, L'/', idx); + if (!sPathElem.isEmpty()) + { + if (idx < 0) + { + sFileName = sPathElem; + } + else + { + pStorage = pStorage->OpenSotStorage(sPathElem); + if (!pStorage) + break; + } + } + } while (pStorage && idx >= 0); + + if (!pStorage) + { + nErrorCode = ERRCODE_IO_GENERAL; + break; + } + + SotStorageStream* pStream = pStorage->OpenSotStream(sFileName); + if (!pStream) + { + nErrorCode = ERRCODE_IO_GENERAL; + break; + } + uno::Sequence<sal_Int8> aStreamContent; + aStreamData.Value >>= aStreamContent; + size_t nBytesWritten = pStream->WriteBytes(aStreamContent.getArray(), aStreamContent.getLength()); + if (nBytesWritten != static_cast<size_t>(aStreamContent.getLength())) + { + nErrorCode = ERRCODE_IO_CANTWRITE; + break; + } + } + } + + return nErrorCode; +} +ErrCode SwWW8Writer::WriteStorageImpl() { // #i34818# - update layout (if present), for SwWriteTable SwViewShell* pViewShell = m_pDoc->getIDocumentLayoutAccess().GetCurrentViewShell(); diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 99063ef12a20..8c66df7a630a 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -983,6 +983,7 @@ public: private: SwWW8Writer(const SwWW8Writer&) = delete; SwWW8Writer& operator=(const SwWW8Writer&) = delete; + ErrCode WriteStorageImpl(); }; /// Exporter of the binary Word file formats. _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits