1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <unotools/securityoptions.hxx>
21 #include <unotools/configmgr.hxx>
22 #include <unotools/configitem.hxx>
23 #include <unotools/ucbhelper.hxx>
24 #include <com/sun/star/uno/Any.hxx>
25 #include <com/sun/star/uno/Sequence.hxx>
27 #include <com/sun/star/beans/PropertyValue.hpp>
28 #include <com/sun/star/container/XNameContainer.hpp>
29 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
30 #include <com/sun/star/util/XChangesBatch.hpp>
31 #include <comphelper/propertyvalue.hxx>
32 #include <comphelper/sequence.hxx>
33 #include <tools/urlobj.hxx>
35 #include <unotools/pathoptions.hxx>
36 #include <officecfg/Office/Common.hxx>
40 using namespace ::com::sun::star::uno
;
42 constexpr OUString PROPERTYNAME_MACRO_TRUSTEDAUTHORS
= u
"TrustedAuthors"_ustr
;
43 constexpr OUString PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME
= u
"SubjectName"_ustr
;
44 constexpr OUString PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER
= u
"SerialNumber"_ustr
;
45 constexpr OUString PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA
= u
"RawData"_ustr
;
48 namespace SvtSecurityOptions
51 bool IsReadOnly( EOption eOption
)
56 case SvtSecurityOptions::EOption::SecureUrls
:
57 bReadonly
= officecfg::Office::Common::Security::Scripting::SecureURL::isReadOnly();
59 case SvtSecurityOptions::EOption::DocWarnSaveOrSend
:
60 bReadonly
= officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::isReadOnly();
62 case SvtSecurityOptions::EOption::DocWarnSigning
:
63 bReadonly
= officecfg::Office::Common::Security::Scripting::WarnSignDoc::isReadOnly();
65 case SvtSecurityOptions::EOption::DocWarnPrint
:
66 bReadonly
= officecfg::Office::Common::Security::Scripting::WarnPrintDoc::isReadOnly();
68 case SvtSecurityOptions::EOption::DocWarnCreatePdf
:
69 bReadonly
= officecfg::Office::Common::Security::Scripting::WarnCreatePDF::isReadOnly();
71 case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo
:
72 bReadonly
= officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::isReadOnly();
74 case SvtSecurityOptions::EOption::DocWarnKeepRedlineInfo
:
75 bReadonly
= officecfg::Office::Common::Security::Scripting::KeepRedlineInfoOnSaving::isReadOnly();
77 case SvtSecurityOptions::EOption::DocWarnKeepDocUserInfo
:
78 bReadonly
= officecfg::Office::Common::Security::Scripting::KeepDocUserInfoOnSaving::isReadOnly();
80 case SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo
:
81 bReadonly
= officecfg::Office::Common::Security::Scripting::KeepNoteAuthorDateInfoOnSaving::isReadOnly();
83 case SvtSecurityOptions::EOption::DocWarnKeepDocVersionInfo
:
84 bReadonly
= officecfg::Office::Common::Security::Scripting::KeepDocVersionInfoOnSaving::isReadOnly();
86 case SvtSecurityOptions::EOption::DocKeepPrinterSettings
:
87 bReadonly
= officecfg::Office::Common::Security::Scripting::KeepDocPrinterSettingsOnSaving::isReadOnly();
89 case SvtSecurityOptions::EOption::DocWarnRecommendPassword
:
90 bReadonly
= officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::isReadOnly();
92 case SvtSecurityOptions::EOption::MacroSecLevel
:
93 bReadonly
= officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::isReadOnly();
95 case SvtSecurityOptions::EOption::MacroTrustedAuthors
:
96 bReadonly
= officecfg::Office::Common::Security::Scripting::TrustedAuthors::isReadOnly();
98 case SvtSecurityOptions::EOption::CtrlClickHyperlink
:
99 bReadonly
= officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::isReadOnly();
101 case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks
:
102 bReadonly
= officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::isReadOnly();
104 case SvtSecurityOptions::EOption::DisableActiveContent
:
105 bReadonly
= officecfg::Office::Common::Security::Scripting::DisableActiveContent::isReadOnly() ||
106 officecfg::Office::Common::Security::Scripting::DisableOLEAutomation::isReadOnly();
117 std::vector
< OUString
> GetSecureURLs()
119 if (comphelper::IsFuzzing())
121 std::vector
<OUString
> aRet
= comphelper::sequenceToContainer
<std::vector
<OUString
>>(
122 officecfg::Office::Common::Security::Scripting::SecureURL::get());
124 std::transform(aRet
.begin(), aRet
.end(), aRet
.begin(),
125 [&aOpt
](const OUString
& rUrl
) -> OUString
{ return aOpt
.SubstituteVariable( rUrl
); });
129 void SetSecureURLs( std::vector
< OUString
>&& urlList
)
131 // DBG_ASSERT(!officecfg::SecureURL::isReadOnly(), "SvtSecurityOptions_Impl::SetSecureURLs()\nYou tried to write on a readonly value!\n");
132 // if (officecfg::SecureURL::isReadOnly())
134 std::vector
< OUString
> lURLs( std::move(urlList
) );
136 std::transform(lURLs
.begin(), lURLs
.end(), lURLs
.begin(),
137 [&aOpt
](const OUString
& rUrl
) -> OUString
{ return aOpt
.UseVariable( rUrl
); });
138 std::shared_ptr
<comphelper::ConfigurationChanges
> xChanges
= comphelper::ConfigurationChanges::create();
139 officecfg::Office::Common::Security::Scripting::SecureURL::set(comphelper::containerToSequence(lURLs
), xChanges
);
143 bool isSecureMacroUri(
144 OUString
const & uri
, OUString
const & referer
)
146 switch (INetURLObject(uri
).GetProtocol()) {
147 case INetProtocol::Macro
:
148 if (uri
.startsWithIgnoreAsciiCase("macro:///")) {
149 // Denotes an App-BASIC macro (see SfxMacroLoader::loadMacro), which
150 // is considered safe:
154 case INetProtocol::Slot
:
155 return referer
.equalsIgnoreAsciiCase("private:user")
156 || isTrustedLocationUri(referer
);
162 bool isUntrustedReferer(OUString
const & referer
)
164 return IsOptionSet(EOption::BlockUntrustedRefererLinks
)
165 && !(referer
.isEmpty() || referer
.startsWithIgnoreAsciiCase("private:")
166 || isTrustedLocationUri(referer
));
169 bool isTrustedLocationUri(OUString
const & uri
)
171 for (const auto & url
: GetSecureURLs())
173 if (utl::UCBContentHelper::IsSubPath(url
, uri
))
181 bool isTrustedLocationUriForUpdatingLinks(OUString
const & uri
)
183 return GetMacroSecurityLevel() == 0 || uri
.isEmpty()
184 || uri
.startsWithIgnoreAsciiCase("private:")
185 || isTrustedLocationUri(uri
);
188 sal_Int32
GetMacroSecurityLevel()
190 return comphelper::IsFuzzing() ? 3 : officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::get();
193 void SetMacroSecurityLevel( sal_Int32 _nLevel
)
195 if (comphelper::IsFuzzing() || officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::isReadOnly())
198 if( _nLevel
> 3 || _nLevel
< 0 )
201 std::shared_ptr
<comphelper::ConfigurationChanges
> xChanges
= comphelper::ConfigurationChanges::create();
202 officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::set(_nLevel
, xChanges
);
206 bool IsMacroDisabled()
208 return comphelper::IsFuzzing()
209 || officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get()
210 || officecfg::Office::Common::Misc::ViewerAppMode::get();
213 std::vector
< SvtSecurityOptions::Certificate
> GetTrustedAuthors()
215 Reference
<css::container::XHierarchicalNameAccess
> xHierarchyAccess
= utl::ConfigManager::acquireTree(u
"Office.Common/Security/Scripting");
216 const Sequence
< OUString
> lAuthors
= utl::ConfigItem::GetNodeNames( xHierarchyAccess
, PROPERTYNAME_MACRO_TRUSTEDAUTHORS
, utl::ConfigNameFormat::LocalPath
);
217 sal_Int32 c1
= lAuthors
.getLength();
221 sal_Int32 c2
= c1
* 3; // 3 Properties inside Struct TrustedAuthor
222 Sequence
< OUString
> lAllAuthors( c2
);
223 auto plAllAuthors
= lAllAuthors
.getArray();
225 OUString
aSep( u
"/"_ustr
);
226 for( const auto& rAuthor
: lAuthors
)
228 plAllAuthors
[ i2
] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS
+ aSep
+ rAuthor
+ aSep
+ PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME
;
230 plAllAuthors
[ i2
] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS
+ aSep
+ rAuthor
+ aSep
+ PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER
;
232 plAllAuthors
[ i2
] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS
+ aSep
+ rAuthor
+ aSep
+ PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA
;
236 Sequence
< Any
> lValues
= utl::ConfigItem::GetProperties( xHierarchyAccess
, lAllAuthors
, /*bAllLocales*/false );
237 if( lValues
.getLength() != c2
)
240 std::vector
< SvtSecurityOptions::Certificate
> aTrustedAuthors
;
241 SvtSecurityOptions::Certificate aCert
;
243 for( sal_Int32 i1
= 0; i1
< c1
; ++i1
)
245 lValues
[ i2
] >>= aCert
.SubjectName
;
247 lValues
[ i2
] >>= aCert
.SerialNumber
;
249 lValues
[ i2
] >>= aCert
.RawData
;
251 // Filter out TrustedAuthor entries with empty RawData, which
252 // would cause an unexpected std::bad_alloc in
253 // SecurityEnvironment_NssImpl::createCertificateFromAscii and
254 // have been observed in the wild (fdo#55019):
255 if( !aCert
.RawData
.isEmpty() )
257 aTrustedAuthors
.push_back( aCert
);
260 return aTrustedAuthors
;
263 void SetTrustedAuthors( const std::vector
< Certificate
>& rAuthors
)
265 // DBG_ASSERT(!m_bROTrustedAuthors, "SvtSecurityOptions_Impl::SetTrustedAuthors()\nYou tried to write on a readonly value!\n");
266 // if( m_bROTrustedAuthors )
269 Reference
<css::container::XHierarchicalNameAccess
> xHierarchyAccess
= utl::ConfigManager::acquireTree(u
"Office.Common/Security/Scripting");
271 // first, clear existing entries
273 Reference
<css::container::XNameContainer
> xCont
;
274 xHierarchyAccess
->getByHierarchicalName(PROPERTYNAME_MACRO_TRUSTEDAUTHORS
) >>= xCont
;
275 const Sequence
< OUString
> aNames
= xCont
->getElementNames();
276 Reference
<css::util::XChangesBatch
> xBatch(xHierarchyAccess
, UNO_QUERY
);
277 for (const OUString
& rName
: aNames
)
278 xCont
->removeByName(rName
);
279 xBatch
->commitChanges();
282 sal_Int32 nCnt
= rAuthors
.size();
283 for( sal_Int32 i
= 0; i
< nCnt
; ++i
)
286 PROPERTYNAME_MACRO_TRUSTEDAUTHORS
+ "/a"
287 + OUString::number(i
) + "/");
288 Sequence
< css::beans::PropertyValue
> lPropertyValues
{
289 comphelper::makePropertyValue(aPrefix
+ PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME
,
290 rAuthors
[i
].SubjectName
),
291 comphelper::makePropertyValue(aPrefix
+ PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER
,
292 rAuthors
[i
].SerialNumber
),
293 comphelper::makePropertyValue(aPrefix
+ PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA
,
297 utl::ConfigItem::SetSetProperties( xHierarchyAccess
, PROPERTYNAME_MACRO_TRUSTEDAUTHORS
, lPropertyValues
);
301 bool IsOptionSet( EOption eOption
)
303 if (comphelper::IsFuzzing())
308 case SvtSecurityOptions::EOption::DocWarnSaveOrSend
:
309 bSet
= officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::get();
311 case SvtSecurityOptions::EOption::DocWarnSigning
:
312 bSet
= officecfg::Office::Common::Security::Scripting::WarnSignDoc::get();
314 case SvtSecurityOptions::EOption::DocWarnPrint
:
315 bSet
= officecfg::Office::Common::Security::Scripting::WarnPrintDoc::get();
317 case SvtSecurityOptions::EOption::DocWarnCreatePdf
:
318 bSet
= officecfg::Office::Common::Security::Scripting::WarnCreatePDF::get();
320 case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo
:
321 bSet
= officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::get();
323 case SvtSecurityOptions::EOption::DocWarnKeepRedlineInfo
:
324 bSet
= officecfg::Office::Common::Security::Scripting::KeepRedlineInfoOnSaving::get();
326 case SvtSecurityOptions::EOption::DocWarnKeepDocUserInfo
:
327 bSet
= officecfg::Office::Common::Security::Scripting::KeepDocUserInfoOnSaving::get();
329 case SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo
:
330 bSet
= officecfg::Office::Common::Security::Scripting::KeepNoteAuthorDateInfoOnSaving::get();
332 case SvtSecurityOptions::EOption::DocWarnKeepDocVersionInfo
:
333 bSet
= officecfg::Office::Common::Security::Scripting::KeepDocVersionInfoOnSaving::get();
335 case SvtSecurityOptions::EOption::DocKeepPrinterSettings
:
336 bSet
= officecfg::Office::Common::Security::Scripting::KeepDocPrinterSettingsOnSaving::get();
338 case SvtSecurityOptions::EOption::DocWarnRecommendPassword
:
339 bSet
= officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::get();
341 case SvtSecurityOptions::EOption::CtrlClickHyperlink
:
342 bSet
= officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::get();
344 case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks
:
345 bSet
= officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::get();
347 case SvtSecurityOptions::EOption::DisableActiveContent
:
348 bSet
= officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() &&
349 officecfg::Office::Common::Security::Scripting::DisableOLEAutomation::get();
359 void SetOption( EOption eOption
, bool bValue
)
361 std::shared_ptr
<comphelper::ConfigurationChanges
> xChanges
= comphelper::ConfigurationChanges::create();
364 case SvtSecurityOptions::EOption::DocWarnSaveOrSend
:
365 officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::set(bValue
, xChanges
);
367 case SvtSecurityOptions::EOption::DocWarnSigning
:
368 officecfg::Office::Common::Security::Scripting::WarnSignDoc::set(bValue
, xChanges
);
370 case SvtSecurityOptions::EOption::DocWarnPrint
:
371 officecfg::Office::Common::Security::Scripting::WarnPrintDoc::set(bValue
, xChanges
);
373 case SvtSecurityOptions::EOption::DocWarnCreatePdf
:
374 officecfg::Office::Common::Security::Scripting::WarnCreatePDF::set(bValue
, xChanges
);
376 case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo
:
377 officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::set(bValue
, xChanges
);
379 case SvtSecurityOptions::EOption::DocWarnKeepRedlineInfo
:
380 officecfg::Office::Common::Security::Scripting::KeepRedlineInfoOnSaving::set(bValue
, xChanges
);
382 case SvtSecurityOptions::EOption::DocWarnKeepDocUserInfo
:
383 officecfg::Office::Common::Security::Scripting::KeepDocUserInfoOnSaving::set(bValue
, xChanges
);
385 case SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo
:
386 officecfg::Office::Common::Security::Scripting::KeepNoteAuthorDateInfoOnSaving::set(bValue
, xChanges
);
388 case SvtSecurityOptions::EOption::DocWarnKeepDocVersionInfo
:
389 officecfg::Office::Common::Security::Scripting::KeepDocVersionInfoOnSaving::set(bValue
, xChanges
);
391 case SvtSecurityOptions::EOption::DocKeepPrinterSettings
:
392 officecfg::Office::Common::Security::Scripting::KeepDocPrinterSettingsOnSaving::set(bValue
, xChanges
);
394 case SvtSecurityOptions::EOption::DocWarnRecommendPassword
:
395 officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::set(bValue
, xChanges
);
397 case SvtSecurityOptions::EOption::CtrlClickHyperlink
:
398 officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::set(bValue
, xChanges
);
400 case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks
:
401 officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::set(bValue
, xChanges
);
403 case SvtSecurityOptions::EOption::DisableActiveContent
:
404 officecfg::Office::Common::Security::Scripting::DisableActiveContent::set(bValue
, xChanges
);
405 officecfg::Office::Common::Security::Scripting::DisableOLEAutomation::set(bValue
, xChanges
);
414 } // namespace SvtSecurityOptions
417 // map personal info strings to 1, 2, ... to remove personal info
418 size_t SvtSecurityMapPersonalInfo::GetInfoID( const OUString
& sPersonalInfo
)
420 auto aIter
= aInfoIDs
.find( sPersonalInfo
);
421 if ( aIter
== aInfoIDs
.end() )
423 size_t nNewID
= aInfoIDs
.size() + 1;
424 aInfoIDs
[sPersonalInfo
] = nNewID
;
428 return aIter
->second
;
431 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */