[Libreoffice-commits] core.git: sd/source
Vasily Melenchuk (via logerrit)
logerrit at kemper.freedesktop.org
Mon May 25 08:08:07 UTC 2020
sd/source/filter/sdpptwrp.cxx | 107 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 106 insertions(+), 1 deletion(-)
New commits:
commit 1e18f22c6f497f269fe3226bc00afc3c8874049d
Author: Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Fri Nov 8 21:00:12 2019 +0300
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon May 25 10:07:26 2020 +0200
sd: add XPackageEncryption support for binary ppt
This adds read support for API-based MS-CRYPTO algos.
DRM encryption is implemented as a service and description
will be called if we found corresponding streams inside
binary OLE package.
Change-Id: Ib91538d53ee1f53a3cd14a44d47fd6f6136c0472
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/84441
Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/sd/source/filter/sdpptwrp.cxx b/sd/source/filter/sdpptwrp.cxx
index edc21c482d45..08d897f6acfd 100644
--- a/sd/source/filter/sdpptwrp.cxx
+++ b/sd/source/filter/sdpptwrp.cxx
@@ -19,14 +19,21 @@
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
+#include <sfx2/sfxsids.hrc>
#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/frame.hxx>
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
@@ -67,9 +74,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);
+ if (rStream.is())
+ {
+ sal_Int32 nStreamSize = rStream->GetSize();
+ Sequence< sal_Int8 > oData;
+ oData.realloc(nStreamSize);
+ sal_Int32 nReadBytes = rStream->ReadBytes(oData.getArray(), nStreamSize);
+ if (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;
+ }
+
+ comphelper::SequenceAsHashMap aStreamsData;
+ lcl_getListOfStreams(rStorage.get(), aStreamsData, "");
+
+ 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 = std::make_shared<SvMemoryStream>();
+
+ Reference<css::io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(rContentStream.get(), false));
+ Reference<css::io::XOutputStream > xDecryptedStream(new utl::OSeekableOutputStreamWrapper(*rNewStorageStrm));
+
+ 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 +181,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 )
{
More information about the Libreoffice-commits
mailing list