comphelper/source/misc/docpasswordhelper.cxx |   30 +++++++++++++++++++++++++--
 sfx2/source/dialog/filedlghelper.cxx         |   18 ++++++++++------
 2 files changed, 40 insertions(+), 8 deletions(-)

New commits:
commit aa1e92a889f5e5c25980437f172896d029b15fad
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Fri Nov 29 13:07:57 2019 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon May 18 09:24:59 2020 +0200

    tdf#118639: store ODF encryption data for autorecovery
    
    When saving autorecovery information, ODF is used. If the original
    document is password-protected, its autorecovery is also generated
    password-protected (since ef87ff6680f79362a431db6e7ef2f40cfc576219).
    But when the stored encryption data for non-ODF document does not
    contain "PackageSHA256UTF8EncryptionKey" value, following
    ZipPackage::GetEncryptionKey fails, so the whole save fails.
    
    So just generate and append ODF encryption keys where we still have
    user password.
    
    Reviewed-on: https://gerrit.libreoffice.org/84052
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    (cherry picked from commit 63634738dd03cc74806ce6843c16ff5e51a371a0)
    Reviewed-on: https://gerrit.libreoffice.org/84133
    Reviewed-by: Xisco FaulĂ­ <xiscofa...@libreoffice.org>
    (cherry picked from commit e569dc9824e95617d921bb8f115d243aea0125b9)
    Reviewed-on: https://gerrit.libreoffice.org/84232
    Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com>
    
    Change-Id: I776e28de784489521e4941d1075690f90c056014
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94346
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/comphelper/source/misc/docpasswordhelper.cxx 
b/comphelper/source/misc/docpasswordhelper.cxx
index 6cf07d4795fb..9963e90309d4 100644
--- a/comphelper/source/misc/docpasswordhelper.cxx
+++ b/comphelper/source/misc/docpasswordhelper.cxx
@@ -428,6 +428,7 @@ OUString DocPasswordHelper::GetOoxHashAsBase64(
         bool* pbIsDefaultPassword )
 {
     css::uno::Sequence< css::beans::NamedValue > aEncData;
+    OUString aPassword;
     DocPasswordVerifierResult eResult = 
DocPasswordVerifierResult::WrongPassword;
 
     // first, try provided default passwords
@@ -441,8 +442,12 @@ OUString DocPasswordHelper::GetOoxHashAsBase64(
             if( !aIt->isEmpty() )
             {
                 eResult = rVerifier.verifyPassword( *aIt, aEncData );
-                if( pbIsDefaultPassword )
-                    *pbIsDefaultPassword = eResult == 
DocPasswordVerifierResult::OK;
+                if (eResult == DocPasswordVerifierResult::OK)
+                {
+                    aPassword = *aIt;
+                    if (pbIsDefaultPassword)
+                        *pbIsDefaultPassword = true;
+                }
             }
         }
     }
@@ -462,7 +467,11 @@ OUString DocPasswordHelper::GetOoxHashAsBase64(
     if( eResult == DocPasswordVerifierResult::WrongPassword )
     {
         if( !rMediaPassword.isEmpty() )
+        {
             eResult = rVerifier.verifyPassword( rMediaPassword, aEncData );
+            if (eResult == DocPasswordVerifierResult::OK)
+                aPassword = rMediaPassword;
+        }
     }
 
     // request a password (skip, if result is OK or ABORT)
@@ -478,6 +487,8 @@ OUString DocPasswordHelper::GetOoxHashAsBase64(
             {
                 if( !pRequest->getPassword().isEmpty() )
                     eResult = rVerifier.verifyPassword( 
pRequest->getPassword(), aEncData );
+                if (eResult == DocPasswordVerifierResult::OK)
+                    aPassword = pRequest->getPassword();
             }
             else
             {
@@ -490,6 +501,21 @@ OUString DocPasswordHelper::GetOoxHashAsBase64(
     {
     }
 
+    if (eResult == DocPasswordVerifierResult::OK && !aPassword.isEmpty())
+    {
+        if (std::find_if(std::cbegin(aEncData), std::cend(aEncData),
+                         [](const css::beans::NamedValue& val) {
+                             return val.Name == 
PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
+                         })
+            == std::cend(aEncData))
+        {
+            // tdf#118639: We need ODF encryption data for autorecovery, where 
password
+            // will already be unavailable, so generate and append it here
+            aEncData = comphelper::concatSequences(
+                aEncData, 
OStorageHelper::CreatePackageEncryptionData(aPassword));
+        }
+    }
+
     return (eResult == DocPasswordVerifierResult::OK) ? aEncData : 
uno::Sequence< beans::NamedValue >();
 }
 
diff --git a/sfx2/source/dialog/filedlghelper.cxx 
b/sfx2/source/dialog/filedlghelper.cxx
index 0e5a3610ee3e..8f221b8bfb19 100644
--- a/sfx2/source/dialog/filedlghelper.cxx
+++ b/sfx2/source/dialog/filedlghelper.cxx
@@ -2697,6 +2697,8 @@ ErrCode RequestPassword(const std::shared_ptr<const 
SfxFilter>& pCurrentFilter,
     {
         if ( pPasswordRequest->getPassword().getLength() )
         {
+            css::uno::Sequence< css::beans::NamedValue > aEncryptionData;
+
             // TODO/LATER: The filters should show the password dialog 
themself in future
             if ( bMSType )
             {
@@ -2705,7 +2707,7 @@ ErrCode RequestPassword(const std::shared_ptr<const 
SfxFilter>& pCurrentFilter,
                 {
                     ::comphelper::SequenceAsHashMap aHashData;
                     aHashData[ OUString( "OOXPassword"  ) ] <<= 
pPasswordRequest->getPassword();
-                    pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, 
uno::makeAny( aHashData.getAsConstNamedValueList() ) ) );
+                    aEncryptionData = aHashData.getAsConstNamedValueList();
                 }
                 else
                 {
@@ -2718,7 +2720,7 @@ ErrCode RequestPassword(const std::shared_ptr<const 
SfxFilter>& pCurrentFilter,
                         aHashData[ OUString( "STD97EncryptionKey"  ) ] <<= 
aEncryptionKey;
                         aHashData[ OUString( "STD97UniqueID"  ) ] <<= 
aUniqueID;
 
-                        pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, 
uno::makeAny( aHashData.getAsConstNamedValueList() ) ) );
+                        aEncryptionData = aHashData.getAsConstNamedValueList();
                     }
                     else
                     {
@@ -2726,10 +2728,14 @@ ErrCode RequestPassword(const std::shared_ptr<const 
SfxFilter>& pCurrentFilter,
                     }
                 }
             }
-            else
-            {
-                pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( 
::comphelper::OStorageHelper::CreatePackageEncryptionData( 
pPasswordRequest->getPassword() ) ) ) );
-            }
+
+            // tdf#118639: We need ODF encryption data for autorecovery where 
password will already
+            // be unavailable, even for non-ODF documents, so append it here 
unconditionally
+            pSet->Put(SfxUnoAnyItem(
+                SID_ENCRYPTIONDATA,
+                uno::makeAny(comphelper::concatSequences(
+                    aEncryptionData, 
comphelper::OStorageHelper::CreatePackageEncryptionData(
+                                         pPasswordRequest->getPassword())))));
         }
 
         if ( pPasswordRequest->getRecommendReadOnly() )
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to