LibreOffice Module sc (master) 1
tabprotection.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <tabprotection.hxx>
23#include <comphelper/hash.hxx>
25#include <osl/diagnose.h>
26#include <document.hxx>
27
28#include <vector>
29
30#define DEBUG_TAB_PROTECTION 0
31
32constexpr OUStringLiteral URI_SHA1 = u"http://www.w3.org/2000/09/xmldsig#sha1";
33constexpr OUStringLiteral URI_SHA256_ODF12 = u"http://www.w3.org/2000/09/xmldsig#sha256";
34constexpr OUStringLiteral URI_SHA256_W3C = u"http://www.w3.org/2001/04/xmlenc#sha256";
35constexpr OUStringLiteral URI_XLS_LEGACY = u"http://docs.oasis-open.org/office/ns/table/legacy-hash-excel";
36
37using namespace ::com::sun::star;
38using ::com::sun::star::uno::Sequence;
39using ::std::vector;
40
42{
43 if (rDoc.IsDocProtected())
44 {
45 const ScDocProtection* p = rDoc.GetDocProtection();
46 if (!p->isPasswordEmpty() && !p->hasPasswordHash(eHash1, eHash2))
47 return true;
48 }
49
50 SCTAB nTabCount = rDoc.GetTableCount();
51 for (SCTAB i = 0; i < nTabCount; ++i)
52 {
54 if (!p || !p->isProtected())
55 // Sheet not protected. Skip it.
56 continue;
57
58 if (!p->isPasswordEmpty() && !p->hasPasswordHash(eHash1, eHash2))
59 return true;
60 }
61
62 return false;
63}
64
66{
67 switch (eHash)
68 {
69 case PASSHASH_SHA256:
70 return URI_SHA256_ODF12;
71 case PASSHASH_SHA1:
72 return URI_SHA1;
73 case PASSHASH_XL:
74 return URI_XLS_LEGACY;
76 default:
77 ;
78 }
79 return OUString();
80}
81
83{
84 if (rURI == URI_SHA256_ODF12 || rURI == URI_SHA256_W3C)
85 return PASSHASH_SHA256;
86 if ( rURI == URI_SHA1 )
87 return PASSHASH_SHA1;
88 else if ( rURI == URI_XLS_LEGACY )
89 return PASSHASH_XL;
91}
92
93bool ScOoxPasswordHash::verifyPassword( const OUString& aPassText ) const
94{
95 if (!hasPassword())
96 return false;
97
100 if (aHash.isEmpty())
101 // unsupported algorithm
102 return false;
103
104 return aHash == maHashValue;
105}
106
108{
109}
110
112{
113public:
114 static Sequence<sal_Int8> hashPassword(std::u16string_view aPassText, ScPasswordHash eHash);
115 static Sequence<sal_Int8> hashPassword(const Sequence<sal_Int8>& rPassHash, ScPasswordHash eHash);
116
117 explicit ScTableProtectionImpl(SCSIZE nOptSize);
119
120 bool isProtected() const { return mbProtected;}
121 bool isProtectedWithPass() const;
122 void setProtected(bool bProtected);
123
124 bool isPasswordEmpty() const { return mbEmptyPass;}
125 bool hasPasswordHash(ScPasswordHash eHash, ScPasswordHash eHash2) const;
126 void setPassword(const OUString& aPassText);
127 css::uno::Sequence<sal_Int8> getPasswordHash(
128 ScPasswordHash eHash, ScPasswordHash eHash2) const;
129 const ScOoxPasswordHash& getPasswordHash() const;
131 const css::uno::Sequence<sal_Int8>& aPassword,
132 ScPasswordHash eHash, ScPasswordHash eHash2);
133 void setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue,
134 const OUString& rSaltValue, sal_uInt32 nSpinCount );
135 bool verifyPassword(const OUString& aPassText) const;
136
137 bool isOptionEnabled(SCSIZE nOptId) const;
138 void setOption(SCSIZE nOptId, bool bEnabled);
139
140 void setEnhancedProtection( ::std::vector< ScEnhancedProtection > && rProt );
141 const ::std::vector< ScEnhancedProtection > & getEnhancedProtection() const { return maEnhancedProtection;}
142 bool updateReference( UpdateRefMode, const ScDocument&, const ScRange& rWhere, SCCOL nDx, SCROW nDy, SCTAB nDz );
143 bool isBlockEditable( const ScRange& rRange ) const;
144 bool isSelectionEditable( const ScRangeList& rRangeList ) const;
145
146private:
147 OUString maPassText;
148 css::uno::Sequence<sal_Int8> maPassHash;
149 ::std::vector<bool> maOptions;
155 ::std::vector< ScEnhancedProtection > maEnhancedProtection;
156};
157
158Sequence<sal_Int8> ScTableProtectionImpl::hashPassword(std::u16string_view aPassText, ScPasswordHash eHash)
159{
160 Sequence<sal_Int8> aHash;
161 switch (eHash)
162 {
163 case PASSHASH_XL:
165 break;
166 case PASSHASH_SHA1:
167 SvPasswordHelper::GetHashPassword(aHash, aPassText);
168 break;
171 break;
172 case PASSHASH_SHA256:
174 break;
175 default:
176 ;
177 }
178 return aHash;
179}
180
182 const Sequence<sal_Int8>& rPassHash, ScPasswordHash eHash)
183{
184 if (!rPassHash.hasElements() || eHash == PASSHASH_UNSPECIFIED)
185 return rPassHash;
186
187 // TODO: Right now, we only support double-hash by SHA1.
188 if (eHash == PASSHASH_SHA1)
189 {
190 auto aChars = comphelper::sequenceToContainer<vector<char>>(rPassHash);
191
192 Sequence<sal_Int8> aNewHash;
193 SvPasswordHelper::GetHashPassword(aNewHash, aChars.data(), aChars.size());
194 return aNewHash;
195 }
196
197 return rPassHash;
198}
199
201 maOptions(nOptSize),
202 mbEmptyPass(true),
203 mbProtected(false),
204 meHash1(PASSHASH_SHA1),
205 meHash2(PASSHASH_UNSPECIFIED)
206{
207}
208
210 maPassText(r.maPassText),
211 maPassHash(r.maPassHash),
212 maOptions(r.maOptions),
213 mbEmptyPass(r.mbEmptyPass),
214 mbProtected(r.mbProtected),
215 meHash1(r.meHash1),
216 meHash2(r.meHash2),
217 maPasswordHash(r.maPasswordHash),
218 maEnhancedProtection(r.maEnhancedProtection)
219{
220}
221
223{
224 if (!mbProtected)
225 return false;
226
227 return !maPassText.isEmpty() || maPassHash.hasElements() || maPasswordHash.hasPassword();
228}
229
231{
232 mbProtected = bProtected;
233 // We need to keep the old password even when the protection is off. So,
234 // don't erase the password data here.
235}
236
237void ScTableProtectionImpl::setPassword(const OUString& aPassText)
238{
239 // We can't hash it here because we don't know whether this document will
240 // get saved to Excel or ODF, depending on which we will need to use a
241 // different hashing algorithm. One alternative is to hash it using all
242 // hash algorithms that we support, and store them all.
243
244 maPassText = aPassText;
245 mbEmptyPass = aPassText.isEmpty();
246 if (mbEmptyPass)
247 {
248 maPassHash = Sequence<sal_Int8>();
249 }
251}
252
254{
255 if (mbEmptyPass)
256 return true;
257
258 if (!maPassText.isEmpty())
259 return true;
260
261 if (meHash1 == eHash)
262 {
264 // single hash.
265 return true;
266
267 return meHash2 == eHash2;
268 }
269
270 return false;
271}
272
274 ScPasswordHash eHash, ScPasswordHash eHash2) const
275{
276 Sequence<sal_Int8> aPassHash;
277
278 if (mbEmptyPass)
279 // Flagged as empty.
280 return aPassHash;
281
282 if (!maPassText.isEmpty())
283 {
284 // Cleartext password exists. Hash it.
285 aPassHash = hashPassword(maPassText, eHash);
286 if (eHash2 != PASSHASH_UNSPECIFIED)
287 // Double-hash it.
288 aPassHash = hashPassword(aPassHash, eHash2);
289
290 return aPassHash;
291 }
292 else
293 {
294 // No clear text password. Check if we have a hash value of the right hash type.
295 if (meHash1 == eHash)
296 {
297 aPassHash = maPassHash;
298
299 if (meHash2 == eHash2)
300 // Matching double-hash requested.
301 return aPassHash;
302 else if (meHash2 == PASSHASH_UNSPECIFIED)
303 // primary hashing type match. Double hash it by the requested
304 // double-hash type.
305 return hashPassword(aPassHash, eHash2);
306 }
307 }
308
309 // failed.
310 return Sequence<sal_Int8>();
311}
312
314{
315 return maPasswordHash;
316}
317
319 const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2)
320{
321 sal_Int32 nLen = aPassword.getLength();
322 mbEmptyPass = nLen <= 0;
323 meHash1 = eHash;
324 meHash2 = eHash2;
325 maPassHash = aPassword;
326
327#if DEBUG_TAB_PROTECTION
328 for (sal_Int8 n : aPassword)
329 printf("%2.2X ", static_cast<sal_uInt8>(n));
330 printf("\n");
331#endif
332}
333
334void ScTableProtectionImpl::setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue,
335 const OUString& rSaltValue, sal_uInt32 nSpinCount )
336{
337 if (!rHashValue.isEmpty())
338 {
339 // Invalidate the other hashes.
340 setPasswordHash( uno::Sequence<sal_Int8>(), PASSHASH_UNSPECIFIED, PASSHASH_UNSPECIFIED);
341
342 // We don't know whether this is an empty password (or would
343 // unnecessarily have to try to verify an empty password), assume it is
344 // not. A later verifyPassword() with an empty password will determine.
345 // If this was not set to false then a verifyPassword() with an empty
346 // password would unlock even if this hash here wasn't for an empty
347 // password. Ugly stuff.
348 mbEmptyPass = false;
349 }
350
351 maPasswordHash.maAlgorithmName = rAlgorithmName;
352 maPasswordHash.maHashValue = rHashValue;
353 maPasswordHash.maSaltValue = rSaltValue;
354 maPasswordHash.mnSpinCount = nSpinCount;
355}
356
357bool ScTableProtectionImpl::verifyPassword(const OUString& aPassText) const
358{
359#if DEBUG_TAB_PROTECTION
360 fprintf(stdout, "ScTableProtectionImpl::verifyPassword: input = '%s'\n",
361 OUStringToOString(aPassText, RTL_TEXTENCODING_UTF8).getStr());
362#endif
363
364 if (mbEmptyPass)
365 return aPassText.isEmpty();
366
367 if (!maPassText.isEmpty())
368 // Clear text password exists, and this one takes precedence.
369 return aPassText == maPassText;
370
371 // For PASSHASH_UNSPECIFIED also maPassHash is empty and any aPassText
372 // would yield an empty hash as well and thus compare true. Don't.
374 {
375 Sequence<sal_Int8> aHash = hashPassword(aPassText, meHash1);
376 aHash = hashPassword(aHash, meHash2);
377
378#if DEBUG_TAB_PROTECTION
379 fprintf(stdout, "ScTableProtectionImpl::verifyPassword: hash = ");
380 for (sal_Int32 i = 0; i < aHash.getLength(); ++i)
381 printf("%2.2X ", static_cast<sal_uInt8>(aHash[i]));
382 printf("\n");
383#endif
384
385 if (aHash == maPassHash)
386 {
387 return true;
388 }
389 }
390
391 // tdf#115483 compat hack for ODF 1.2; for now UTF8-SHA1 passwords are only
392 // verified, not generated
394 {
395 Sequence<sal_Int8> const aHash2 = hashPassword(aPassText, PASSHASH_SHA1_UTF8);
396 return aHash2 == maPassHash;
397 }
398
399 // Not yet generated or tracked with meHash1 or meHash2, but can be read
400 // from OOXML.
401 return maPasswordHash.verifyPassword( aPassText);
402}
403
405{
406 if ( maOptions.size() <= static_cast<size_t>(nOptId) )
407 {
408 OSL_FAIL("ScTableProtectionImpl::isOptionEnabled: wrong size");
409 return false;
410 }
411
412 return maOptions[nOptId];
413}
414
415void ScTableProtectionImpl::setOption(SCSIZE nOptId, bool bEnabled)
416{
417 if ( maOptions.size() <= static_cast<size_t>(nOptId) )
418 {
419 OSL_FAIL("ScTableProtectionImpl::setOption: wrong size");
420 return;
421 }
422
423 maOptions[nOptId] = bEnabled;
424}
425
426void ScTableProtectionImpl::setEnhancedProtection( ::std::vector< ScEnhancedProtection > && rProt )
427{
428 maEnhancedProtection = std::move(rProt);
429}
430
432 const ScRange& rWhere, SCCOL nDx, SCROW nDy, SCTAB nDz )
433{
434 bool bChanged = false;
435 for (auto& rEnhancedProtection : maEnhancedProtection)
436 {
437 if (rEnhancedProtection.maRangeList.is())
438 bChanged |= rEnhancedProtection.maRangeList->UpdateReference( eMode, &rDoc, rWhere, nDx, nDy, nDz);
439 }
440 return bChanged;
441}
442
444{
445 /* TODO: ask for password (and remember) if a password was set for
446 * a matching range and no matching range without password was encountered.
447 * Would need another return type than boolean to reflect
448 * "password required for a specific protection". */
449
450 // No protection exception or overriding permission to edit if empty.
451 if (maEnhancedProtection.empty())
452 return false;
453
454 // No security descriptor in an enhanced protection means the ranges of
455 // that protection are editable. If there is any security descriptor
456 // present we assume the permission to edit is not granted. Until we
457 // actually can evaluate the descriptors...
458
459 auto lIsEditable = [rRange](const ScEnhancedProtection& rEnhancedProtection) {
460 return !rEnhancedProtection.hasSecurityDescriptor()
461 && rEnhancedProtection.maRangeList.is() && rEnhancedProtection.maRangeList->Contains( rRange)
462 && !rEnhancedProtection.hasPassword(); // Range is editable if no password is assigned.
463 };
464 if (std::any_of(maEnhancedProtection.begin(), maEnhancedProtection.end(), lIsEditable))
465 return true;
466
467 // For a single address, a simple check with single ranges was sufficient.
468 if (rRange.aStart == rRange.aEnd)
469 return false;
470
471 // Test also for cases where rRange is encompassed by a union of two or
472 // more ranges of the list. The original ranges are not necessarily joined.
473 for (const auto& rEnhancedProtection : maEnhancedProtection)
474 {
475 if (!rEnhancedProtection.hasSecurityDescriptor() && rEnhancedProtection.maRangeList.is())
476 {
477 ScRangeList aList( rEnhancedProtection.maRangeList->GetIntersectedRange( rRange));
478 if (aList.size() == 1 && aList[0] == rRange)
479 {
480 // Range is editable if no password is assigned.
481 if (!rEnhancedProtection.hasPassword())
482 return true;
483 }
484 }
485 }
486
487 // Ranges may even be distributed over different protection records, for
488 // example if they are assigned different names, and can have different
489 // passwords. Combine the ones that can be edited.
490 /* TODO: once we handle passwords, remember a successful unlock at
491 * ScEnhancedProtection so we can use that here. */
492 ScRangeList aRangeList;
493 for (const auto& rEnhancedProtection : maEnhancedProtection)
494 {
495 if (!rEnhancedProtection.hasSecurityDescriptor() && rEnhancedProtection.maRangeList.is())
496 {
497 // Ranges are editable if no password is assigned.
498 if (!rEnhancedProtection.hasPassword())
499 {
500 const ScRangeList& rRanges = *rEnhancedProtection.maRangeList;
501 size_t nRanges = rRanges.size();
502 for (size_t i=0; i < nRanges; ++i)
503 {
504 aRangeList.push_back( rRanges[i]);
505 }
506 }
507 }
508 }
509 ScRangeList aResultList( aRangeList.GetIntersectedRange( rRange));
510 return aResultList.size() == 1 && aResultList[0] == rRange;
511}
512
514{
515 if (rRangeList.empty())
516 return false;
517
518 for (size_t i=0, nRanges = rRangeList.size(); i < nRanges; ++i)
519 {
520 if (!isBlockEditable( rRangeList[i]))
521 return false;
522 }
523 return true;
524}
525
527 mpImpl(new ScTableProtectionImpl(static_cast<SCSIZE>(ScDocProtection::NONE)))
528{
529}
530
533 mpImpl(new ScTableProtectionImpl(*r.mpImpl))
534{
535}
536
538{
539}
540
542{
543 return mpImpl->isProtected();
544}
545
547{
548 return mpImpl->isProtectedWithPass();
549}
550
551void ScDocProtection::setProtected(bool bProtected)
552{
553 mpImpl->setProtected(bProtected);
554
555 // Currently Calc doesn't support document protection options. So, let's
556 // assume that when the document is protected, its structure is protected.
557 // We need to do this for Excel export.
558 mpImpl->setOption(ScDocProtection::STRUCTURE, bProtected);
559}
560
562{
563 return mpImpl->isPasswordEmpty();
564}
565
567{
568 return mpImpl->hasPasswordHash(eHash, eHash2);
569}
570
571void ScDocProtection::setPassword(const OUString& aPassText)
572{
573 mpImpl->setPassword(aPassText);
574}
575
576uno::Sequence<sal_Int8> ScDocProtection::getPasswordHash(ScPasswordHash eHash, ScPasswordHash eHash2) const
577{
578 return mpImpl->getPasswordHash(eHash, eHash2);
579}
580
582{
583 return mpImpl->getPasswordHash();
584}
585
587 const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2)
588{
589 mpImpl->setPasswordHash(aPassword, eHash, eHash2);
590}
591
592void ScDocProtection::setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue,
593 const OUString& rSaltValue, sal_uInt32 nSpinCount )
594{
595 mpImpl->setPasswordHash( rAlgorithmName, rHashValue, rSaltValue, nSpinCount);
596}
597
598bool ScDocProtection::verifyPassword(const OUString& aPassText) const
599{
600 return mpImpl->verifyPassword(aPassText);
601}
602
604{
605 return mpImpl->isOptionEnabled(eOption);
606}
607
608void ScDocProtection::setOption(Option eOption, bool bEnabled)
609{
610 mpImpl->setOption(eOption, bEnabled);
611}
612
614 mpImpl(new ScTableProtectionImpl(static_cast<SCSIZE>(ScTableProtection::NONE)))
615{
616 // Set default values for the options.
617 mpImpl->setOption(SELECT_LOCKED_CELLS, true);
618 mpImpl->setOption(SELECT_UNLOCKED_CELLS, true);
619}
620
623 mpImpl(new ScTableProtectionImpl(*r.mpImpl))
624{
625}
626
628{
629}
630
632{
633 return mpImpl->isProtected();
634}
635
637{
638 return mpImpl->isProtectedWithPass();
639}
640
642{
643 mpImpl->setProtected(bProtected);
644}
645
647{
648 return mpImpl->isPasswordEmpty();
649}
650
652{
653 return mpImpl->hasPasswordHash(eHash, eHash2);
654}
655
656void ScTableProtection::setPassword(const OUString& aPassText)
657{
658 mpImpl->setPassword(aPassText);
659}
660
662{
663 return mpImpl->getPasswordHash(eHash, eHash2);
664}
665
667{
668 return mpImpl->getPasswordHash();
669}
670
672 const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash, ScPasswordHash eHash2)
673{
674 mpImpl->setPasswordHash(aPassword, eHash, eHash2);
675}
676
677void ScTableProtection::setPasswordHash( const OUString& rAlgorithmName, const OUString& rHashValue,
678 const OUString& rSaltValue, sal_uInt32 nSpinCount )
679{
680 mpImpl->setPasswordHash( rAlgorithmName, rHashValue, rSaltValue, nSpinCount);
681}
682
683bool ScTableProtection::verifyPassword(const OUString& aPassText) const
684{
685 return mpImpl->verifyPassword(aPassText);
686}
687
689{
690 return mpImpl->isOptionEnabled(eOption);
691}
692
693void ScTableProtection::setOption(Option eOption, bool bEnabled)
694{
695 mpImpl->setOption(eOption, bEnabled);
696}
697
698void ScTableProtection::setEnhancedProtection( ::std::vector< ScEnhancedProtection > && rProt )
699{
700 mpImpl->setEnhancedProtection(std::move(rProt));
701}
702
703const ::std::vector< ScEnhancedProtection > & ScTableProtection::getEnhancedProtection() const
704{
705 return mpImpl->getEnhancedProtection();
706}
707
709 SCCOL nDx, SCROW nDy, SCTAB nDz )
710{
711 return mpImpl->updateReference( eMode, rDoc, rWhere, nDx, nDy, nDz);
712}
713
715{
716 return mpImpl->isBlockEditable( rRange);
717}
718
720{
721 return mpImpl->isSelectionEditable( rRangeList);
722}
723
724/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
virtual void setPasswordHash(const css::uno::Sequence< sal_Int8 > &aPassword, ScPasswordHash eHash, ScPasswordHash eHash2=PASSHASH_UNSPECIFIED) override
virtual bool verifyPassword(const OUString &aPassText) const override
virtual const ScOoxPasswordHash & getPasswordHash() const override
virtual bool isPasswordEmpty() const override
virtual ~ScDocProtection() override
virtual void setPassword(const OUString &aPassText) override
virtual bool hasPasswordHash(ScPasswordHash eHash, ScPasswordHash eHash2=PASSHASH_UNSPECIFIED) const override
void setOption(Option eOption, bool bEnabled)
virtual bool isProtected() const override
virtual bool isProtectedWithPass() const override
virtual void setProtected(bool bProtected) override
std::unique_ptr< ScTableProtectionImpl > mpImpl
bool isOptionEnabled(Option eOption) const
SC_DLLPUBLIC const ScTableProtection * GetTabProtection(SCTAB nTab) const
Definition: documen3.cxx:1928
SC_DLLPUBLIC bool IsDocProtected() const
Definition: documen3.cxx:1908
SC_DLLPUBLIC ScDocProtection * GetDocProtection() const
Definition: documen3.cxx:1895
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:316
virtual ~ScPassHashProtectable()=0
ScRangeList GetIntersectedRange(const ScRange &rRange) const
Definition: rangelst.cxx:1165
bool empty() const
Definition: rangelst.hxx:88
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1137
size_t size() const
Definition: rangelst.hxx:89
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
void setPassword(const OUString &aPassText)
bool isOptionEnabled(SCSIZE nOptId) const
bool verifyPassword(const OUString &aPassText) const
ScPasswordHash meHash2
bool updateReference(UpdateRefMode, const ScDocument &, const ScRange &rWhere, SCCOL nDx, SCROW nDy, SCTAB nDz)
ScTableProtectionImpl(SCSIZE nOptSize)
::std::vector< ScEnhancedProtection > maEnhancedProtection
bool isProtectedWithPass() const
bool hasPasswordHash(ScPasswordHash eHash, ScPasswordHash eHash2) const
ScPasswordHash meHash1
bool isPasswordEmpty() const
const ::std::vector< ScEnhancedProtection > & getEnhancedProtection() const
bool isBlockEditable(const ScRange &rRange) const
const ScOoxPasswordHash & getPasswordHash() const
static Sequence< sal_Int8 > hashPassword(std::u16string_view aPassText, ScPasswordHash eHash)
bool isSelectionEditable(const ScRangeList &rRangeList) const
::std::vector< bool > maOptions
ScOoxPasswordHash maPasswordHash
void setProtected(bool bProtected)
void setOption(SCSIZE nOptId, bool bEnabled)
void setEnhancedProtection(::std::vector< ScEnhancedProtection > &&rProt)
void setPasswordHash(const css::uno::Sequence< sal_Int8 > &aPassword, ScPasswordHash eHash, ScPasswordHash eHash2)
css::uno::Sequence< sal_Int8 > maPassHash
sheet protection state container
virtual bool isProtectedWithPass() const override
virtual bool verifyPassword(const OUString &aPassText) const override
std::unique_ptr< ScTableProtectionImpl > mpImpl
bool isOptionEnabled(Option eOption) const
virtual bool hasPasswordHash(ScPasswordHash eHash, ScPasswordHash eHash2=PASSHASH_UNSPECIFIED) const override
void setOption(Option eOption, bool bEnabled)
virtual void setPassword(const OUString &aPassText) override
virtual ~ScTableProtection() override
virtual bool isPasswordEmpty() const override
void setEnhancedProtection(::std::vector< ScEnhancedProtection > &&rProt)
virtual const ScOoxPasswordHash & getPasswordHash() const override
virtual bool isProtected() const override
virtual void setPasswordHash(const css::uno::Sequence< sal_Int8 > &aPassword, ScPasswordHash eHash, ScPasswordHash eHash2=PASSHASH_UNSPECIFIED) override
const ::std::vector< ScEnhancedProtection > & getEnhancedProtection() const
bool isBlockEditable(const ScRange &rRange) const
bool isSelectionEditable(const ScRangeList &rRangeList) const
virtual void setProtected(bool bProtected) override
bool updateReference(UpdateRefMode, const ScDocument &, const ScRange &rWhere, SCCOL nDx, SCROW nDy, SCTAB nDz)
static SVL_DLLPUBLIC void GetHashPassword(css::uno::Sequence< sal_Int8 > &rPassHash, const char *pPass, sal_uInt32 nLen)
static SVL_DLLPUBLIC void GetHashPasswordSHA1UTF8(css::uno::Sequence< sal_Int8 > &rPassHash, std::u16string_view sPass)
static SVL_DLLPUBLIC void GetHashPasswordSHA256(css::uno::Sequence< sal_Int8 > &rPassHash, std::u16string_view sPass)
static css::uno::Sequence< sal_Int8 > GetXLHashAsSequence(std::u16string_view aString)
static OUString GetOoxHashAsBase64(const OUString &rPassword, std::u16string_view rSaltValue, sal_uInt32 nSpinCount, comphelper::Hash::IterCount eIterCount, std::u16string_view rAlgorithmName)
float u
UpdateRefMode
Definition: global.hxx:300
Mode eMode
void * p
ScPasswordHash getHashTypeFromURI(std::u16string_view rURI)
bool needsPassHashRegen(const ScDocument &rDoc, ScPasswordHash eHash1, ScPasswordHash eHash2=PASSHASH_UNSPECIFIED)
Check for the compatibility of all password hashes.
OUString getHashURI(ScPasswordHash eHash)
int i
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
Container for the Excel EnhancedProtection feature.
OOXML password definitions: algorithmName, hashValue, saltValue, spinCount.
OUString maSaltValue
base64 encoded hash value
bool verifyPassword(const OUString &aPassText) const
OUString maHashValue
"SHA-512", ...
sal_uInt32 mnSpinCount
base64 encoded salt value
OUString maAlgorithmName
bool hasPassword() const
constexpr OUStringLiteral URI_SHA256_ODF12
constexpr OUStringLiteral URI_XLS_LEGACY
constexpr OUStringLiteral URI_SHA256_W3C
constexpr OUStringLiteral URI_SHA1
ScPasswordHash
@ PASSHASH_XL
@ PASSHASH_UNSPECIFIED
@ PASSHASH_SHA1
@ PASSHASH_SHA256
@ PASSHASH_SHA1_UTF8
unsigned char sal_uInt8
signed char sal_Int8
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17