Skip to content

Commit

Permalink
tdf#118639: store ODF encryption data for autorecovery
Browse files Browse the repository at this point in the history
When saving autorecovery information, ODF is used. If the original
document is password-protected, its autorecovery is also generated
password-protected (since ef87ff6).
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.kaganski@collabora.com>
(cherry picked from commit 6363473)
Reviewed-on: https://gerrit.libreoffice.org/84133
Reviewed-by: Xisco Faulí <xiscofauli@libreoffice.org>
(cherry picked from commit e569dc9)
Reviewed-on: https://gerrit.libreoffice.org/84232
Reviewed-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>

Change-Id: I776e28de784489521e4941d1075690f90c056014
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94355
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Andras Timar <andras.timar@collabora.com>
  • Loading branch information
mikekaganski authored and timar committed May 17, 2020
1 parent 21cc8a8 commit ae46145
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 8 deletions.
31 changes: 29 additions & 2 deletions comphelper/source/misc/docpasswordhelper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <comphelper/docpasswordhelper.hxx>
#include <comphelper/storagehelper.hxx>
#include <comphelper/sequence.hxx>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
Expand Down Expand Up @@ -366,6 +367,7 @@ Sequence< sal_Int8 > DocPasswordHelper::GetXLHashAsSequence(
bool* pbIsDefaultPassword )
{
css::uno::Sequence< css::beans::NamedValue > aEncData;
OUString aPassword;
DocPasswordVerifierResult eResult = DocPasswordVerifierResult::WrongPassword;

// first, try provided default passwords
Expand All @@ -379,8 +381,12 @@ Sequence< sal_Int8 > DocPasswordHelper::GetXLHashAsSequence(
if( !aIt->isEmpty() )
{
eResult = rVerifier.verifyPassword( *aIt, aEncData );
if( pbIsDefaultPassword )
*pbIsDefaultPassword = eResult == DocPasswordVerifierResult::OK;
if (eResult == DocPasswordVerifierResult::OK)
{
aPassword = *aIt;
if (pbIsDefaultPassword)
*pbIsDefaultPassword = true;
}
}
}
}
Expand All @@ -400,7 +406,11 @@ Sequence< sal_Int8 > DocPasswordHelper::GetXLHashAsSequence(
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)
Expand All @@ -416,6 +426,8 @@ Sequence< sal_Int8 > DocPasswordHelper::GetXLHashAsSequence(
{
if( !pRequest->getPassword().isEmpty() )
eResult = rVerifier.verifyPassword( pRequest->getPassword(), aEncData );
if (eResult == DocPasswordVerifierResult::OK)
aPassword = pRequest->getPassword();
}
else
{
Expand All @@ -428,6 +440,21 @@ Sequence< sal_Int8 > DocPasswordHelper::GetXLHashAsSequence(
{
}

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 >();
}

Expand Down
18 changes: 12 additions & 6 deletions sfx2/source/dialog/filedlghelper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2673,6 +2673,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 )
{
Expand All @@ -2681,7 +2683,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
{
Expand All @@ -2694,18 +2696,22 @@ 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
{
return ERRCODE_IO_NOTSUPPORTED;
}
}
}
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() )
Expand Down

0 comments on commit ae46145

Please sign in to comment.