sc/inc/tabprotection.hxx | 10 ++ sc/source/core/data/tabprotection.cxx | 98 ++++++++++++++++++++++++++--- sc/source/filter/excel/excrecds.cxx | 10 ++ sc/source/filter/oox/worksheetsettings.cxx | 6 + 4 files changed, 114 insertions(+), 10 deletions(-)
New commits: commit 95bee23dffe87e36eaa7a58ba8aca8434bf01007 Author: Eike Rathke <[email protected]> Date: Sat Feb 24 20:59:08 2018 +0100 Resolves: tdf#104250 import sheetProtection hash attributes Change-Id: Ibae0934a84173b0933a03a6050abaaf3384404cb diff --git a/sc/source/filter/oox/worksheetsettings.cxx b/sc/source/filter/oox/worksheetsettings.cxx index bdeb6cc04884..ea69be9f2bc8 100644 --- a/sc/source/filter/oox/worksheetsettings.cxx +++ b/sc/source/filter/oox/worksheetsettings.cxx @@ -241,6 +241,12 @@ void WorksheetSettings::finalizeImport() { ScTableProtection aProtect; aProtect.setProtected(true); + aProtect.setPasswordHash( maSheetProt.maAlgorithmName, maSheetProt.maHashValue, + maSheetProt.maSaltValue, maSheetProt.mnSpinCount); + // Set the simple hash after the proper hash because setting the proper + // hash resets the simple hash, yet if the simple hash is present we + // may as well use it and more important want to keep it for saving the + // document again. if (maSheetProt.mnPasswordHash) { Sequence<sal_Int8> aPass(2); commit 1bf8006f6344d67dbfe0055da7d7dd5bdfa529d2 Author: Eike Rathke <[email protected]> Date: Sat Feb 24 20:56:28 2018 +0100 Write ScOoxPasswordHash to OOXML if set, tdf#104250 prep Change-Id: I51996c673e6c44bbfc27972800d78d9807fe67db diff --git a/sc/inc/tabprotection.hxx b/sc/inc/tabprotection.hxx index 4c9edcb2f4cc..c174957f1e18 100644 --- a/sc/inc/tabprotection.hxx +++ b/sc/inc/tabprotection.hxx @@ -85,6 +85,7 @@ public: virtual void setPassword(const OUString& aPassText) = 0; virtual css::uno::Sequence<sal_Int8> getPasswordHash( ScPasswordHash eHash, ScPasswordHash eHas2 = PASSHASH_UNSPECIFIED) const = 0; + virtual const ScOoxPasswordHash& getPasswordHash() const = 0; virtual void setPasswordHash( const css::uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2 = PASSHASH_UNSPECIFIED) = 0; @@ -116,6 +117,7 @@ public: virtual void setPassword(const OUString& aPassText) override; virtual css::uno::Sequence<sal_Int8> getPasswordHash( ScPasswordHash eHash, ScPasswordHash eHash2 = PASSHASH_UNSPECIFIED) const override; + virtual const ScOoxPasswordHash& getPasswordHash() const override; virtual void setPasswordHash( const css::uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2 = PASSHASH_UNSPECIFIED) override; @@ -199,6 +201,7 @@ public: virtual void setPassword(const OUString& aPassText) override; virtual css::uno::Sequence<sal_Int8> getPasswordHash( ScPasswordHash eHash, ScPasswordHash eHash2 = PASSHASH_UNSPECIFIED) const override; + virtual const ScOoxPasswordHash& getPasswordHash() const override; virtual void setPasswordHash( const css::uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2 = PASSHASH_UNSPECIFIED) override; diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx index 0eab574d7b42..68e7914dc984 100644 --- a/sc/source/core/data/tabprotection.cxx +++ b/sc/source/core/data/tabprotection.cxx @@ -124,6 +124,7 @@ public: void setPassword(const OUString& aPassText); css::uno::Sequence<sal_Int8> getPasswordHash( ScPasswordHash eHash, ScPasswordHash eHash2) const; + const ScOoxPasswordHash& getPasswordHash() const; void setPasswordHash( const css::uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2); @@ -311,6 +312,11 @@ Sequence<sal_Int8> ScTableProtectionImpl::getPasswordHash( return Sequence<sal_Int8>(); } +const ScOoxPasswordHash& ScTableProtectionImpl::getPasswordHash() const +{ + return maPasswordHash; +} + void ScTableProtectionImpl::setPasswordHash( const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2) { @@ -586,6 +592,11 @@ uno::Sequence<sal_Int8> ScDocProtection::getPasswordHash(ScPasswordHash eHash, S return mpImpl->getPasswordHash(eHash, eHash2); } +const ScOoxPasswordHash& ScDocProtection::getPasswordHash() const +{ + return mpImpl->getPasswordHash(); +} + void ScDocProtection::setPasswordHash( const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2) { @@ -666,6 +677,11 @@ Sequence<sal_Int8> ScTableProtection::getPasswordHash(ScPasswordHash eHash, ScPa return mpImpl->getPasswordHash(eHash, eHash2); } +const ScOoxPasswordHash& ScTableProtection::getPasswordHash() const +{ + return mpImpl->getPasswordHash(); +} + void ScTableProtection::setPasswordHash( const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2) { diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx index e3af479967a0..4dab73a20805 100644 --- a/sc/source/filter/excel/excrecds.cxx +++ b/sc/source/filter/excel/excrecds.cxx @@ -469,6 +469,12 @@ void XclExpSheetProtection::SaveXml( XclExpXmlStream& rStrm ) const ScTableProtection* pTabProtect = rDoc.GetTabProtection(mnTab); if ( pTabProtect ) { + const ScOoxPasswordHash& rPH = pTabProtect->getPasswordHash(); + // Do not write any hash attributes if there is no password. + ScOoxPasswordHash aPH; + if (rPH.hasPassword()) + aPH = rPH; + Sequence<sal_Int8> aHash = pTabProtect->getPasswordHash(PASSHASH_XL); OString sHash; if (aHash.getLength() >= 2) @@ -480,6 +486,10 @@ void XclExpSheetProtection::SaveXml( XclExpXmlStream& rStrm ) } sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream(); rWorksheet->singleElement( XML_sheetProtection, + XML_algorithmName, aPH.maAlgorithmName.isEmpty() ? nullptr : XclXmlUtils::ToOString( aPH.maAlgorithmName).getStr(), + XML_hashValue, aPH.maHashValue.isEmpty() ? nullptr : XclXmlUtils::ToOString( aPH.maHashValue).getStr(), + XML_saltValue, aPH.maSaltValue.isEmpty() ? nullptr : XclXmlUtils::ToOString( aPH.maSaltValue).getStr(), + XML_spinCount, aPH.mnSpinCount ? OString::number( aPH.mnSpinCount).getStr() : nullptr, XML_sheet, ToPsz( true ), XML_password, sHash.isEmpty()? nullptr : sHash.getStr(), XML_objects, pTabProtect->isOptionEnabled( ScTableProtection::OBJECTS ) ? nullptr : ToPsz( true ), commit e3dd12fa8a71c7d0d35fb2146436934d1f4ee004 Author: Eike Rathke <[email protected]> Date: Sat Feb 24 20:52:08 2018 +0100 Handle mbEmptyPass and empty hash with OOXML hash value, tdf#104250 prep Change-Id: Ib24102c442c4675cc5b256fcf8e9d81370aba11f diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx index 5379e2beba45..0eab574d7b42 100644 --- a/sc/source/core/data/tabprotection.cxx +++ b/sc/source/core/data/tabprotection.cxx @@ -330,6 +330,20 @@ void ScTableProtectionImpl::setPasswordHash( void ScTableProtectionImpl::setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue, const OUString& rSaltValue, sal_uInt32 nSpinCount ) { + if (!rHashValue.isEmpty()) + { + // Invalidate the other hashes. + setPasswordHash( uno::Sequence<sal_Int8>(), PASSHASH_UNSPECIFIED, PASSHASH_UNSPECIFIED); + + // We don't know whether this is an empty password (or would + // unnecessarily have to try to verify an empty password), assume it is + // not. A later verifyPassword() with an empty password will determine. + // If this was not set to false then a verifyPassword() with an empty + // password would unlock even if this hash here wasn't for an empty + // password. Ugly stuff. + mbEmptyPass = false; + } + maPasswordHash.maAlgorithmName = rAlgorithmName; maPasswordHash.maHashValue = rHashValue; maPasswordHash.maSaltValue = rSaltValue; @@ -350,19 +364,24 @@ bool ScTableProtectionImpl::verifyPassword(const OUString& aPassText) const // Clear text password exists, and this one takes precedence. return aPassText == maPassText; - Sequence<sal_Int8> aHash = hashPassword(aPassText, meHash1); - aHash = hashPassword(aHash, meHash2); + // For PASSHASH_UNSPECIFIED also maPassHash is empty and any aPassText + // would yield an empty hash as well and thus compare true. Don't. + if (meHash1 != PASSHASH_UNSPECIFIED) + { + Sequence<sal_Int8> aHash = hashPassword(aPassText, meHash1); + aHash = hashPassword(aHash, meHash2); #if DEBUG_TAB_PROTECTION - fprintf(stdout, "ScTableProtectionImpl::verifyPassword: hash = "); - for (sal_Int32 i = 0; i < aHash.getLength(); ++i) - printf("%2.2X ", static_cast<sal_uInt8>(aHash[i])); - printf("\n"); + fprintf(stdout, "ScTableProtectionImpl::verifyPassword: hash = "); + for (sal_Int32 i = 0; i < aHash.getLength(); ++i) + printf("%2.2X ", static_cast<sal_uInt8>(aHash[i])); + printf("\n"); #endif - if (aHash == maPassHash) - { - return true; + if (aHash == maPassHash) + { + return true; + } } // tdf#115483 compat hack for ODF 1.2; for now UTF8-SHA1 passwords are only commit 0423db153603368a69297e5309d3065d57c4d068 Author: Eike Rathke <[email protected]> Date: Sat Feb 24 15:06:28 2018 +0100 Add ScTableProtectionImpl::setPasswordHash() for OOXML, tdf#104250 prep Change-Id: I9589f750cf2f69f4b725cd351aa9ef3749190431 diff --git a/sc/inc/tabprotection.hxx b/sc/inc/tabprotection.hxx index f33981699b9b..4c9edcb2f4cc 100644 --- a/sc/inc/tabprotection.hxx +++ b/sc/inc/tabprotection.hxx @@ -88,6 +88,8 @@ public: virtual void setPasswordHash( const css::uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2 = PASSHASH_UNSPECIFIED) = 0; + virtual void setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue, + const OUString& rSaltValue, sal_uInt32 nSpinCount ) = 0; virtual bool verifyPassword(const OUString& aPassText) const = 0; }; @@ -117,6 +119,8 @@ public: virtual void setPasswordHash( const css::uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2 = PASSHASH_UNSPECIFIED) override; + virtual void setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue, + const OUString& rSaltValue, sal_uInt32 nSpinCount ) override; virtual bool verifyPassword(const OUString& aPassText) const override; bool isOptionEnabled(Option eOption) const; @@ -198,6 +202,8 @@ public: virtual void setPasswordHash( const css::uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2 = PASSHASH_UNSPECIFIED) override; + virtual void setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue, + const OUString& rSaltValue, sal_uInt32 nSpinCount ) override; virtual bool verifyPassword(const OUString& aPassText) const override; bool isOptionEnabled(Option eOption) const; diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx index b0732aa23dc0..5379e2beba45 100644 --- a/sc/source/core/data/tabprotection.cxx +++ b/sc/source/core/data/tabprotection.cxx @@ -127,6 +127,8 @@ public: void setPasswordHash( const css::uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2); + void setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue, + const OUString& rSaltValue, sal_uInt32 nSpinCount ); bool verifyPassword(const OUString& aPassText) const; bool isOptionEnabled(SCSIZE nOptId) const; @@ -325,6 +327,15 @@ void ScTableProtectionImpl::setPasswordHash( #endif } +void ScTableProtectionImpl::setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue, + const OUString& rSaltValue, sal_uInt32 nSpinCount ) +{ + maPasswordHash.maAlgorithmName = rAlgorithmName; + maPasswordHash.maHashValue = rHashValue; + maPasswordHash.maSaltValue = rSaltValue; + maPasswordHash.mnSpinCount = nSpinCount; +} + bool ScTableProtectionImpl::verifyPassword(const OUString& aPassText) const { #if DEBUG_TAB_PROTECTION @@ -562,6 +573,12 @@ void ScDocProtection::setPasswordHash( mpImpl->setPasswordHash(aPassword, eHash, eHash2); } +void ScDocProtection::setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue, + const OUString& rSaltValue, sal_uInt32 nSpinCount ) +{ + mpImpl->setPasswordHash( rAlgorithmName, rHashValue, rSaltValue, nSpinCount); +} + bool ScDocProtection::verifyPassword(const OUString& aPassText) const { return mpImpl->verifyPassword(aPassText); @@ -636,6 +653,12 @@ void ScTableProtection::setPasswordHash( mpImpl->setPasswordHash(aPassword, eHash, eHash2); } +void ScTableProtection::setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue, + const OUString& rSaltValue, sal_uInt32 nSpinCount ) +{ + mpImpl->setPasswordHash( rAlgorithmName, rHashValue, rSaltValue, nSpinCount); +} + bool ScTableProtection::verifyPassword(const OUString& aPassText) const { return mpImpl->verifyPassword(aPassText); commit c6eb3bf58c9c236dc7fe47fb9c4df7dd2a98c2d0 Author: Eike Rathke <[email protected]> Date: Sat Feb 24 14:34:56 2018 +0100 Check also ScOoxPasswordHash::verifyPassword(), tdf#104250 prep Change-Id: Idf1ec7a4b7cde674891df05aae369c403c028fee diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx index 2dec79100484..b0732aa23dc0 100644 --- a/sc/source/core/data/tabprotection.cxx +++ b/sc/source/core/data/tabprotection.cxx @@ -362,6 +362,11 @@ bool ScTableProtectionImpl::verifyPassword(const OUString& aPassText) const return aHash2 == maPassHash; } + // Not yet generated or tracked with meHash1 or meHash2, but can be read + // from OOXML. + if (maPasswordHash.verifyPassword( aPassText)) + return true; + return false; } commit d841f348b94f30cb8e94a0d34e9b20aa34d33aca Author: Eike Rathke <[email protected]> Date: Sat Feb 24 14:18:04 2018 +0100 Add ScOoxPasswordHash::verifyPassword(), tdf#104250 prep Change-Id: Ife588fa0626b01336813e956a25e51541d1096e6 diff --git a/sc/inc/tabprotection.hxx b/sc/inc/tabprotection.hxx index 6a776807a191..f33981699b9b 100644 --- a/sc/inc/tabprotection.hxx +++ b/sc/inc/tabprotection.hxx @@ -55,6 +55,7 @@ struct ScOoxPasswordHash maHashValue.clear(); maSaltValue.clear(); } + bool verifyPassword( const OUString& aPassText ) const; }; namespace ScPassHashHelper diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx index 6aecc83a3c11..2dec79100484 100644 --- a/sc/source/core/data/tabprotection.cxx +++ b/sc/source/core/data/tabprotection.cxx @@ -20,6 +20,7 @@ #include <tabprotection.hxx> #include <svl/PasswordHelper.hxx> #include <comphelper/docpasswordhelper.hxx> +#include <comphelper/hash.hxx> #include <osl/diagnose.h> #include <document.hxx> @@ -88,6 +89,19 @@ ScPasswordHash ScPassHashHelper::getHashTypeFromURI(const OUString& rURI) return PASSHASH_UNSPECIFIED; } +bool ScOoxPasswordHash::verifyPassword( const OUString& aPassText ) const +{ + if (!hasPassword()) + return false; + + const OUString aHash( comphelper::Hash::calculateHashBase64( aPassText, maSaltValue, mnSpinCount, maAlgorithmName)); + if (aHash.isEmpty()) + // unsupported algorithm + return false; + + return aHash == maHashValue; +} + ScPassHashProtectable::~ScPassHashProtectable() { } commit 5f4df7af832e886bd279db566dc6693db9bb6a89 Author: Eike Rathke <[email protected]> Date: Sat Feb 24 13:46:10 2018 +0100 Consider ScOoxPasswordHash in isProtectedWithPass(), tdf#104250 prep And clear in setPassword() Change-Id: Ib68bb5be8d6908909afc1e1d5bd6bbeccb6d0083 diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx index 9eefbfce4c97..6aecc83a3c11 100644 --- a/sc/source/core/data/tabprotection.cxx +++ b/sc/source/core/data/tabprotection.cxx @@ -209,7 +209,7 @@ bool ScTableProtectionImpl::isProtectedWithPass() const if (!mbProtected) return false; - return !maPassText.isEmpty() || maPassHash.getLength(); + return !maPassText.isEmpty() || maPassHash.getLength() || maPasswordHash.hasPassword(); } void ScTableProtectionImpl::setProtected(bool bProtected) @@ -232,6 +232,7 @@ void ScTableProtectionImpl::setPassword(const OUString& aPassText) { maPassHash = Sequence<sal_Int8>(); } + maPasswordHash.clear(); } bool ScTableProtectionImpl::hasPasswordHash(ScPasswordHash eHash, ScPasswordHash eHash2) const _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
