summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasily Melenchuk <vasily.melenchuk@cib.de>2019-11-08 21:17:10 +0300
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2019-12-04 17:13:37 +0100
commita52f2a82ca33d31ef7491f57bfa0a306a8235ed1 (patch)
tree7aeaf9a7ccb51e2f983e2bd25f25dc9a9880b5ce
parent0a9c0a330d7bebee358ee26207c798f437a0caa3 (diff)
sd: support for DRM encryption during saving to ppt
Change-Id: Id82f8b3fa7ea045b00d7d81e2c9ce5e130c8060c
-rw-r--r--sd/source/filter/sdpptwrp.cxx109
1 files changed, 104 insertions, 5 deletions
diff --git a/sd/source/filter/sdpptwrp.cxx b/sd/source/filter/sdpptwrp.cxx
index bb42b9d4bc11..f2ec9038c7b1 100644
--- a/sd/source/filter/sdpptwrp.cxx
+++ b/sd/source/filter/sdpptwrp.cxx
@@ -19,17 +19,21 @@
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
+#include <sfx2/frame.hxx>
#include <filter/msfilter/msoleexp.hxx>
#include <svx/svxerr.hxx>
#include <unotools/fltrcfg.hxx>
+#include <unotools/streamwrap.hxx>
#include <sot/storage.hxx>
#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/processfactory.hxx>
#include <com/sun/star/packages/XPackageEncryption.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <sdpptwrp.hxx>
#include <DrawDocShell.hxx>
+#include <sfx2/sfxsids.hrc>
using namespace ::com::sun::star::uno;
@@ -219,8 +223,6 @@ bool SdPPTFilter::Export()
if( mxModel.is() )
{
- tools::SvRef<SotStorage> xStorRef = new SotStorage( mrMedium.GetOutStream(), false );
-
#ifdef DISABLE_DYNLOADING
ExportPPTPointer PPTExport = ExportPPT;
#else
@@ -228,7 +230,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();
@@ -252,8 +254,105 @@ 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;
+ 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.reset(new 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 : 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 != (size_t)aStreamContent.getLength())
+ {
+ bRet = false;
+ break;
+ }
+ }
+ xEncryptedRootStrg->Commit();
+
+ // Restore encryption data
+ mrMedium.GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, makeAny(aEncryptionData)));
+ }
+ }
}
}