[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