Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / unotools / source / config / securityoptions.cxx
blobb222b8e70502fda60bb776acc2a5ad0033512992
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <comphelper/propertyvalue.hxx>
29 #include <comphelper/sequence.hxx>
30 #include <tools/urlobj.hxx>
32 #include <unotools/pathoptions.hxx>
33 #include <officecfg/Office/Common.hxx>
35 // namespaces
37 using namespace ::com::sun::star::uno;
39 constexpr OUStringLiteral PROPERTYNAME_MACRO_TRUSTEDAUTHORS = u"TrustedAuthors";
40 constexpr OUStringLiteral PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME = u"SubjectName";
41 constexpr OUStringLiteral PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER = u"SerialNumber";
42 constexpr OUStringLiteral PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA = u"RawData";
45 namespace SvtSecurityOptions
48 bool IsReadOnly( EOption eOption )
50 bool bReadonly;
51 switch(eOption)
53 case SvtSecurityOptions::EOption::SecureUrls :
54 bReadonly = officecfg::Office::Common::Security::Scripting::SecureURL::isReadOnly();
55 break;
56 case SvtSecurityOptions::EOption::DocWarnSaveOrSend:
57 bReadonly = officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::isReadOnly();
58 break;
59 case SvtSecurityOptions::EOption::DocWarnSigning:
60 bReadonly = officecfg::Office::Common::Security::Scripting::WarnSignDoc::isReadOnly();
61 break;
62 case SvtSecurityOptions::EOption::DocWarnPrint:
63 bReadonly = officecfg::Office::Common::Security::Scripting::WarnPrintDoc::isReadOnly();
64 break;
65 case SvtSecurityOptions::EOption::DocWarnCreatePdf:
66 bReadonly = officecfg::Office::Common::Security::Scripting::WarnCreatePDF::isReadOnly();
67 break;
68 case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo:
69 bReadonly = officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::isReadOnly();
70 break;
71 case SvtSecurityOptions::EOption::DocWarnRecommendPassword:
72 bReadonly = officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::isReadOnly();
73 break;
74 case SvtSecurityOptions::EOption::MacroSecLevel:
75 bReadonly = officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::isReadOnly();
76 break;
77 case SvtSecurityOptions::EOption::MacroTrustedAuthors:
78 bReadonly = false; // TODO? officecfg::Office::Common::Security::Scripting::TrustedAuthors::isReadOnly();
79 break;
80 case SvtSecurityOptions::EOption::CtrlClickHyperlink:
81 bReadonly = officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::isReadOnly();
82 break;
83 case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks:
84 bReadonly = officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::isReadOnly();
85 break;
87 default:
88 assert(false);
89 bReadonly = true;
92 return bReadonly;
95 std::vector< OUString > GetSecureURLs()
97 if (utl::ConfigManager::IsFuzzing())
98 return {};
99 std::vector<OUString> aRet = comphelper::sequenceToContainer<std::vector<OUString>>(
100 officecfg::Office::Common::Security::Scripting::SecureURL::get());
101 SvtPathOptions aOpt;
102 std::transform(aRet.begin(), aRet.end(), aRet.begin(),
103 [&aOpt](const OUString& rUrl) -> OUString { return aOpt.SubstituteVariable( rUrl ); });
104 return aRet;
107 void SetSecureURLs( std::vector< OUString >&& urlList )
109 // DBG_ASSERT(!officecfg::SecureURL::isReadOnly(), "SvtSecurityOptions_Impl::SetSecureURLs()\nYou tried to write on a readonly value!\n");
110 // if (officecfg::SecureURL::isReadOnly())
111 // return;
112 std::vector< OUString > lURLs( std::move(urlList) );
113 SvtPathOptions aOpt;
114 std::transform(lURLs.begin(), lURLs.end(), lURLs.begin(),
115 [&aOpt](const OUString& rUrl) -> OUString { return aOpt.UseVariable( rUrl ); });
116 std::shared_ptr<comphelper::ConfigurationChanges> xChanges = comphelper::ConfigurationChanges::create();
117 officecfg::Office::Common::Security::Scripting::SecureURL::set(comphelper::containerToSequence(lURLs), xChanges);
118 xChanges->commit();
121 bool isSecureMacroUri(
122 OUString const & uri, OUString const & referer)
124 switch (INetURLObject(uri).GetProtocol()) {
125 case INetProtocol::Macro:
126 if (uri.startsWithIgnoreAsciiCase("macro:///")) {
127 // Denotes an App-BASIC macro (see SfxMacroLoader::loadMacro), which
128 // is considered safe:
129 return true;
131 [[fallthrough]];
132 case INetProtocol::Slot:
133 return referer.equalsIgnoreAsciiCase("private:user")
134 || isTrustedLocationUri(referer);
135 default:
136 return true;
140 bool isUntrustedReferer(OUString const & referer)
142 return IsOptionSet(EOption::BlockUntrustedRefererLinks)
143 && !(referer.isEmpty() || referer.startsWithIgnoreAsciiCase("private:")
144 || isTrustedLocationUri(referer));
147 bool isTrustedLocationUri(OUString const & uri)
149 for (const auto & url : GetSecureURLs())
151 if (utl::UCBContentHelper::IsSubPath(url, uri))
153 return true;
156 return false;
159 bool isTrustedLocationUriForUpdatingLinks(OUString const & uri)
161 return GetMacroSecurityLevel() == 0 || uri.isEmpty()
162 || uri.startsWithIgnoreAsciiCase("private:")
163 || isTrustedLocationUri(uri);
166 sal_Int32 GetMacroSecurityLevel()
168 return utl::ConfigManager::IsFuzzing() ? 3 : officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::get();
171 void SetMacroSecurityLevel( sal_Int32 _nLevel )
173 if (utl::ConfigManager::IsFuzzing() || officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::isReadOnly())
174 return;
176 if( _nLevel > 3 || _nLevel < 0 )
177 _nLevel = 3;
179 std::shared_ptr<comphelper::ConfigurationChanges> xChanges = comphelper::ConfigurationChanges::create();
180 officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::set(_nLevel, xChanges);
181 xChanges->commit();
184 bool IsMacroDisabled()
186 return utl::ConfigManager::IsFuzzing() || officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get();
189 std::vector< SvtSecurityOptions::Certificate > GetTrustedAuthors()
191 Reference<css::container::XHierarchicalNameAccess> xHierarchyAccess = utl::ConfigManager::acquireTree(u"Office.Common/Security/Scripting");
192 const Sequence< OUString > lAuthors = utl::ConfigItem::GetNodeNames( xHierarchyAccess, PROPERTYNAME_MACRO_TRUSTEDAUTHORS, utl::ConfigNameFormat::LocalPath );
193 sal_Int32 c1 = lAuthors.getLength();
194 if( !c1 )
195 return {};
197 sal_Int32 c2 = c1 * 3; // 3 Properties inside Struct TrustedAuthor
198 Sequence< OUString > lAllAuthors( c2 );
199 auto plAllAuthors = lAllAuthors.getArray();
200 sal_Int32 i2 = 0;
201 OUString aSep( "/" );
202 for( const auto& rAuthor : lAuthors )
204 plAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + rAuthor + aSep + PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME;
205 ++i2;
206 plAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + rAuthor + aSep + PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER;
207 ++i2;
208 plAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + rAuthor + aSep + PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA;
209 ++i2;
212 Sequence< Any > lValues = utl::ConfigItem::GetProperties( xHierarchyAccess, lAllAuthors, /*bAllLocales*/false );
213 if( lValues.getLength() != c2 )
214 return {};
216 std::vector< SvtSecurityOptions::Certificate > aTrustedAuthors;
217 SvtSecurityOptions::Certificate aCert;
218 i2 = 0;
219 for( sal_Int32 i1 = 0; i1 < c1; ++i1 )
221 lValues[ i2 ] >>= aCert.SubjectName;
222 ++i2;
223 lValues[ i2 ] >>= aCert.SerialNumber;
224 ++i2;
225 lValues[ i2 ] >>= aCert.RawData;
226 ++i2;
227 // Filter out TrustedAuthor entries with empty RawData, which
228 // would cause an unexpected std::bad_alloc in
229 // SecurityEnvironment_NssImpl::createCertificateFromAscii and
230 // have been observed in the wild (fdo#55019):
231 if( !aCert.RawData.isEmpty() )
233 aTrustedAuthors.push_back( aCert );
236 return aTrustedAuthors;
239 void SetTrustedAuthors( const std::vector< Certificate >& rAuthors )
241 // DBG_ASSERT(!m_bROTrustedAuthors, "SvtSecurityOptions_Impl::SetTrustedAuthors()\nYou tried to write on a readonly value!\n");
242 // if( m_bROTrustedAuthors )
243 // return;
245 Reference<css::container::XHierarchicalNameAccess> xHierarchyAccess = utl::ConfigManager::acquireTree(u"Office.Common/Security/Scripting");
246 sal_Int32 nCnt = rAuthors.size();
247 for( sal_Int32 i = 0; i < nCnt; ++i )
249 OUString aPrefix(
250 PROPERTYNAME_MACRO_TRUSTEDAUTHORS + "/a"
251 + OUString::number(i) + "/");
252 Sequence< css::beans::PropertyValue > lPropertyValues{
253 comphelper::makePropertyValue(aPrefix + PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME,
254 rAuthors[i].SubjectName),
255 comphelper::makePropertyValue(aPrefix + PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER,
256 rAuthors[i].SerialNumber),
257 comphelper::makePropertyValue(aPrefix + PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA,
258 rAuthors[i].RawData)
261 utl::ConfigItem::SetSetProperties( xHierarchyAccess, PROPERTYNAME_MACRO_TRUSTEDAUTHORS, lPropertyValues );
265 bool IsOptionSet( EOption eOption )
267 if (utl::ConfigManager::IsFuzzing())
268 return false;
269 bool bSet = false;
270 switch(eOption)
272 case SvtSecurityOptions::EOption::DocWarnSaveOrSend:
273 bSet = officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::get();
274 break;
275 case SvtSecurityOptions::EOption::DocWarnSigning:
276 bSet = officecfg::Office::Common::Security::Scripting::WarnSignDoc::get();
277 break;
278 case SvtSecurityOptions::EOption::DocWarnPrint:
279 bSet = officecfg::Office::Common::Security::Scripting::WarnPrintDoc::get();
280 break;
281 case SvtSecurityOptions::EOption::DocWarnCreatePdf:
282 bSet = officecfg::Office::Common::Security::Scripting::WarnCreatePDF::get();
283 break;
284 case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo:
285 bSet = officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::get();
286 break;
287 case SvtSecurityOptions::EOption::DocWarnRecommendPassword:
288 bSet = officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::get();
289 break;
290 case SvtSecurityOptions::EOption::CtrlClickHyperlink:
291 bSet = officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::get();
292 break;
293 case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks:
294 bSet = officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::get();
295 break;
297 default:
298 assert(false);
301 return bSet;
304 void SetOption( EOption eOption, bool bValue )
306 std::shared_ptr<comphelper::ConfigurationChanges> xChanges = comphelper::ConfigurationChanges::create();
307 switch(eOption)
309 case SvtSecurityOptions::EOption::DocWarnSaveOrSend:
310 officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::set(bValue, xChanges);
311 break;
312 case SvtSecurityOptions::EOption::DocWarnSigning:
313 officecfg::Office::Common::Security::Scripting::WarnSignDoc::set(bValue, xChanges);
314 break;
315 case SvtSecurityOptions::EOption::DocWarnPrint:
316 officecfg::Office::Common::Security::Scripting::WarnPrintDoc::set(bValue, xChanges);
317 break;
318 case SvtSecurityOptions::EOption::DocWarnCreatePdf:
319 officecfg::Office::Common::Security::Scripting::WarnCreatePDF::set(bValue, xChanges);
320 break;
321 case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo:
322 officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::set(bValue, xChanges);
323 break;
324 case SvtSecurityOptions::EOption::DocWarnRecommendPassword:
325 officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::set(bValue, xChanges);
326 break;
327 case SvtSecurityOptions::EOption::CtrlClickHyperlink:
328 officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::set(bValue, xChanges);
329 break;
330 case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks:
331 officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::set(bValue, xChanges);
332 break;
334 default:
335 assert(false);
337 xChanges->commit();
340 } // namespace SvtSecurityOptions
343 // map personal info strings to 1, 2, ... to remove personal info
344 size_t SvtSecurityMapPersonalInfo::GetInfoID( const OUString sPersonalInfo )
346 auto aIter = aInfoIDs.find( sPersonalInfo );
347 if ( aIter == aInfoIDs.end() )
349 size_t nNewID = aInfoIDs.size() + 1;
350 aInfoIDs[sPersonalInfo] = nNewID;
351 return nNewID;
354 return aIter->second;
357 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */