summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasily Melenchuk <vasily.melenchuk@cib.de>2019-11-08 21:00:12 +0300
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2019-12-04 17:13:37 +0100
commit0a9c0a330d7bebee358ee26207c798f437a0caa3 (patch)
tree3e28a880e43d8c55c827c9e844bdd59079d20e72
parent94d4c5b2bee411a9307889ad1cf1c9f58fcb51f2 (diff)
sd: support of DRM encrypted ppt files reading
Change-Id: Ib91538d53ee1f53a3cd14a44d47fd6f6136c0472
-rw-r--r--sd/source/filter/sdpptwrp.cxx102
1 files changed, 102 insertions, 0 deletions
diff --git a/sd/source/filter/sdpptwrp.cxx b/sd/source/filter/sdpptwrp.cxx
index edc21c482d45..bb42b9d4bc11 100644
--- a/sd/source/filter/sdpptwrp.cxx
+++ b/sd/source/filter/sdpptwrp.cxx
@@ -23,6 +23,10 @@
#include <svx/svxerr.hxx>
#include <unotools/fltrcfg.hxx>
#include <sot/storage.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+
+#include <com/sun/star/packages/XPackageEncryption.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
#include <sdpptwrp.hxx>
#include <DrawDocShell.hxx>
@@ -67,9 +71,101 @@ SdPPTFilter::~SdPPTFilter()
delete pBas; // deleting the compressed basic storage
}
+static void lcl_getListOfStreams(SotStorage * pStorage, comphelper::SequenceAsHashMap& aStreamsData, const OUString& sPrefix)
+{
+ SvStorageInfoList aElements;
+ pStorage->FillInfoList(&aElements);
+ for (const auto & aElement : aElements)
+ {
+ OUString sStreamFullName = sPrefix.getLength() ? sPrefix + "/" + aElement.GetName() : aElement.GetName();
+ if (aElement.IsStorage())
+ {
+ SotStorage * pSubStorage = pStorage->OpenSotStorage(aElement.GetName(), StreamMode::STD_READ | StreamMode::SHARE_DENYALL);
+ lcl_getListOfStreams(pSubStorage, aStreamsData, sStreamFullName);
+ }
+ else
+ {
+ // Read stream
+ tools::SvRef<SotStorageStream> rStream = pStorage->OpenSotStream(aElement.GetName(), StreamMode::READ | StreamMode::SHARE_DENYALL);
+ assert(rStream.is());
+
+ sal_Int32 nStreamSize = rStream->GetSize();
+ Sequence< sal_Int8 > oData;
+ oData.realloc(nStreamSize);
+ sal_Int32 nReadBytes = rStream->ReadBytes(oData.getArray(), nStreamSize);
+ assert(nStreamSize == nReadBytes);
+ aStreamsData[sStreamFullName] <<= oData;
+ }
+ }
+}
+
+static tools::SvRef<SotStorage> lcl_DRMDecrypt(SfxMedium& rMedium, tools::SvRef<SotStorage>& rStorage, std::shared_ptr<SvStream>& rNewStorageStrm)
+{
+ tools::SvRef<SotStorage> aNewStorage;
+
+ // We have DRM encrypted storage. We should try to decrypt it first, if we can
+ Sequence< Any > aArguments;
+ Reference<XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
+ Reference< css::packages::XPackageEncryption > xPackageEncryption(
+ xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.oox.crypto.DRMDataSpace", aArguments, xComponentContext), UNO_QUERY);
+
+ if (!xPackageEncryption.is())
+ {
+ // We do not know how to decrypt this
+ return aNewStorage;
+ }
+
+ std::vector<OUString> aStreamsList;
+ comphelper::SequenceAsHashMap aStreamsData;
+ lcl_getListOfStreams(rStorage.get(), aStreamsData, OUString(""));
+
+ try {
+ Sequence<NamedValue> aStreams = aStreamsData.getAsConstNamedValueList();
+ if (!xPackageEncryption->readEncryptionInfo(aStreams))
+ {
+ // We failed with decryption
+ return aNewStorage;
+ }
+
+ tools::SvRef<SotStorageStream> rContentStream = rStorage->OpenSotStream("\011DRMContent", StreamMode::READ | StreamMode::SHARE_DENYALL);
+ if (!rContentStream.is())
+ {
+ return aNewStorage;
+ }
+
+ rNewStorageStrm.reset(new SvMemoryStream());
+
+ Reference<css::io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(rContentStream.get(), false));
+ Reference<css::io::XOutputStream > xDecryptedStream(new utl::OSeekableOutputStreamWrapper(*rNewStorageStrm.get()));
+
+ if (!xPackageEncryption->decrypt(xInputStream, xDecryptedStream))
+ {
+ // We failed with decryption
+ return aNewStorage;
+ }
+
+ rNewStorageStrm->Seek(0);
+
+ // Further reading is done from new document
+ aNewStorage = new SotStorage(*rNewStorageStrm);
+
+ // Set the media descriptor data
+ Sequence<NamedValue> aEncryptionData = xPackageEncryption->createEncryptionData("");
+ rMedium.GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, makeAny(aEncryptionData)));
+ }
+ catch (const std::exception&)
+ {
+ return aNewStorage;
+ }
+
+ return aNewStorage;
+}
+
bool SdPPTFilter::Import()
{
bool bRet = false;
+ std::shared_ptr<SvStream> aDecryptedStorageStrm;
tools::SvRef<SotStorage> pStorage = new SotStorage( mrMedium.GetInStream(), false );
if( !pStorage->GetError() )
{
@@ -82,6 +178,12 @@ bool SdPPTFilter::Import()
xDualStorage = pStorage->OpenSotStorage( sDualStorage, StreamMode::STD_READ );
pStorage = xDualStorage;
}
+ OUString sDRMContent("\011DRMContent");
+ if (pStorage->IsContained(sDRMContent))
+ {
+ // Document is DRM encrypted
+ pStorage = lcl_DRMDecrypt(mrMedium, pStorage, aDecryptedStorageStrm);
+ }
std::unique_ptr<SvStream> pDocStream(pStorage->OpenSotStream( "PowerPoint Document" , StreamMode::STD_READ ));
if( pDocStream )
{