[Libreoffice-commits] core.git: sd/source
Vasily Melenchuk (via logerrit)
logerrit at kemper.freedesktop.org
Mon May 25 08:08:29 UTC 2020
sd/source/filter/sdpptwrp.cxx | 106 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 101 insertions(+), 5 deletions(-)
New commits:
commit 956529cc28a5710ff6ea4e46dbe635fae64c4eb5
Author: Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Fri Nov 8 21:17:10 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon May 25 10:07:49 2020 +0200
sd: add XPackageEncryption write support for binary ppt
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: Id82f8b3fa7ea045b00d7d81e2c9ce5e130c8060c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/84442
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Tested-by: Jenkins
diff --git a/sd/source/filter/sdpptwrp.cxx b/sd/source/filter/sdpptwrp.cxx
index 08d897f6acfd..2374c69f280d 100644
--- a/sd/source/filter/sdpptwrp.cxx
+++ b/sd/source/filter/sdpptwrp.cxx
@@ -222,8 +222,6 @@ bool SdPPTFilter::Export()
if( mxModel.is() )
{
- tools::SvRef<SotStorage> xStorRef = new SotStorage( mrMedium.GetOutStream(), false );
-
#ifdef DISABLE_DYNLOADING
ExportPPTPointer PPTExport = ExportPPT;
#else
@@ -231,7 +229,7 @@ bool SdPPTFilter::Export()
SdFilter::GetLibrarySymbol(mrMedium.GetFilter()->GetUserData(), "ExportPPT"));
#endif
- if( PPTExport && xStorRef.is() )
+ if( PPTExport)
{
sal_uInt32 nCnvrtFlags = 0;
const SvtFilterOptions& rFilterOptions = SvtFilterOptions::Get();
@@ -255,8 +253,106 @@ bool SdPPTFilter::Export()
aProperty.Value <<= mrMedium.GetBaseURL( true );
aProperties.push_back( aProperty );
- bRet = PPTExport( aProperties, xStorRef, mxModel, mxStatusIndicator, pBas, nCnvrtFlags );
- xStorRef->Commit();
+ SvStream * pOutputStrm = mrMedium.GetOutStream();
+
+ Sequence< NamedValue > aEncryptionData;
+ Reference< css::packages::XPackageEncryption > xPackageEncryption;
+ const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(mrMedium.GetItemSet(), SID_ENCRYPTIONDATA, false);
+ std::shared_ptr<SvStream> pMediaStrm;
+ if (pEncryptionDataItem && (pEncryptionDataItem->GetValue() >>= aEncryptionData))
+ {
+ ::comphelper::SequenceAsHashMap aHashData(aEncryptionData);
+ OUString sCryptoType = aHashData.getUnpackedValueOrDefault("CryptoType", OUString());
+
+ if (sCryptoType.getLength())
+ {
+ Reference<XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
+ Sequence<Any> aArguments{
+ makeAny(NamedValue("Binary", makeAny(true))) };
+ xPackageEncryption.set(
+ xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, xComponentContext), UNO_QUERY);
+
+ if (xPackageEncryption.is())
+ {
+ // We have an encryptor. Export document into memory stream and encrypt it later
+ pMediaStrm = std::make_shared<SvMemoryStream>();
+ pOutputStrm = pMediaStrm.get();
+
+ // Temp removal of EncryptionData to avoid password protection triggering
+ mrMedium.GetItemSet()->ClearItem(SID_ENCRYPTIONDATA);
+ }
+ }
+ }
+
+ tools::SvRef<SotStorage> xStorRef = new SotStorage(pOutputStrm, false);
+
+ if (xStorRef.is())
+ {
+ bRet = PPTExport(aProperties, xStorRef, mxModel, mxStatusIndicator, pBas, nCnvrtFlags);
+ xStorRef->Commit();
+
+ if (xPackageEncryption.is())
+ {
+ // Perform DRM encryption
+ pOutputStrm->Seek(0);
+
+ xPackageEncryption->setupEncryption(aEncryptionData);
+
+ Reference<css::io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(pOutputStrm, false));
+ Sequence<NamedValue> aStreams = xPackageEncryption->encrypt(xInputStream);
+
+ tools::SvRef<SotStorage> xEncryptedRootStrg = new SotStorage(mrMedium.GetOutStream(), false);
+ for (const 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 = xEncryptedRootStrg.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);
+ }
+ }
+ } while (pStorage && idx >= 0);
+
+ if (!pStorage)
+ {
+ bRet = false;
+ break;
+ }
+
+ SotStorageStream* pStream = pStorage->OpenSotStream(sFileName);
+ if (!pStream)
+ {
+ bRet = false;
+ break;
+ }
+ Sequence<sal_Int8> aStreamContent;
+ aStreamData.Value >>= aStreamContent;
+ size_t nBytesWritten = pStream->WriteBytes(aStreamContent.getArray(), aStreamContent.getLength());
+ if (nBytesWritten != static_cast<size_t>(aStreamContent.getLength()))
+ {
+ bRet = false;
+ break;
+ }
+ }
+ xEncryptedRootStrg->Commit();
+
+ // Restore encryption data
+ mrMedium.GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, makeAny(aEncryptionData)));
+ }
+ }
}
}
More information about the Libreoffice-commits
mailing list