Gtk-WARNING gtktreestore.c:1047: Invalid column number 1 added to iter
[LibreOffice.git] / unotools / source / config / securityoptions.cxx
blob19fa71b3beba1815d358550119c5c89185a1da80
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 <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>
38 // namespaces
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 )
53 bool bReadonly;
54 switch(eOption)
56 case SvtSecurityOptions::EOption::SecureUrls :
57 bReadonly = officecfg::Office::Common::Security::Scripting::SecureURL::isReadOnly();
58 break;
59 case SvtSecurityOptions::EOption::DocWarnSaveOrSend:
60 bReadonly = officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::isReadOnly();
61 break;
62 case SvtSecurityOptions::EOption::DocWarnSigning:
63 bReadonly = officecfg::Office::Common::Security::Scripting::WarnSignDoc::isReadOnly();
64 break;
65 case SvtSecurityOptions::EOption::DocWarnPrint:
66 bReadonly = officecfg::Office::Common::Security::Scripting::WarnPrintDoc::isReadOnly();
67 break;
68 case SvtSecurityOptions::EOption::DocWarnCreatePdf:
69 bReadonly = officecfg::Office::Common::Security::Scripting::WarnCreatePDF::isReadOnly();
70 break;
71 case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo:
72 bReadonly = officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::isReadOnly();
73 break;
74 case SvtSecurityOptions::EOption::DocWarnKeepRedlineInfo:
75 bReadonly = officecfg::Office::Common::Security::Scripting::KeepRedlineInfoOnSaving::isReadOnly();
76 break;
77 case SvtSecurityOptions::EOption::DocWarnKeepDocUserInfo:
78 bReadonly = officecfg::Office::Common::Security::Scripting::KeepDocUserInfoOnSaving::isReadOnly();
79 break;
80 case SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo:
81 bReadonly = officecfg::Office::Common::Security::Scripting::KeepNoteAuthorDateInfoOnSaving::isReadOnly();
82 break;
83 case SvtSecurityOptions::EOption::DocWarnKeepDocVersionInfo:
84 bReadonly = officecfg::Office::Common::Security::Scripting::KeepDocVersionInfoOnSaving::isReadOnly();
85 break;
86 case SvtSecurityOptions::EOption::DocKeepPrinterSettings:
87 bReadonly = officecfg::Office::Common::Security::Scripting::KeepDocPrinterSettingsOnSaving::isReadOnly();
88 break;
89 case SvtSecurityOptions::EOption::DocWarnRecommendPassword:
90 bReadonly = officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::isReadOnly();
91 break;
92 case SvtSecurityOptions::EOption::MacroSecLevel:
93 bReadonly = officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::isReadOnly();
94 break;
95 case SvtSecurityOptions::EOption::MacroTrustedAuthors:
96 bReadonly = officecfg::Office::Common::Security::Scripting::TrustedAuthors::isReadOnly();
97 break;
98 case SvtSecurityOptions::EOption::CtrlClickHyperlink:
99 bReadonly = officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::isReadOnly();
100 break;
101 case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks:
102 bReadonly = officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::isReadOnly();
103 break;
104 case SvtSecurityOptions::EOption::DisableActiveContent:
105 bReadonly = officecfg::Office::Common::Security::Scripting::DisableActiveContent::isReadOnly() ||
106 officecfg::Office::Common::Security::Scripting::DisableOLEAutomation::isReadOnly();
107 break;
109 default:
110 assert(false);
111 bReadonly = true;
114 return bReadonly;
117 std::vector< OUString > GetSecureURLs()
119 if (comphelper::IsFuzzing())
120 return {};
121 std::vector<OUString> aRet = comphelper::sequenceToContainer<std::vector<OUString>>(
122 officecfg::Office::Common::Security::Scripting::SecureURL::get());
123 SvtPathOptions aOpt;
124 std::transform(aRet.begin(), aRet.end(), aRet.begin(),
125 [&aOpt](const OUString& rUrl) -> OUString { return aOpt.SubstituteVariable( rUrl ); });
126 return aRet;
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())
133 // return;
134 std::vector< OUString > lURLs( std::move(urlList) );
135 SvtPathOptions aOpt;
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);
140 xChanges->commit();
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:
151 return true;
153 [[fallthrough]];
154 case INetProtocol::Slot:
155 return referer.equalsIgnoreAsciiCase("private:user")
156 || isTrustedLocationUri(referer);
157 default:
158 return true;
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))
175 return true;
178 return false;
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())
196 return;
198 if( _nLevel > 3 || _nLevel < 0 )
199 _nLevel = 3;
201 std::shared_ptr<comphelper::ConfigurationChanges> xChanges = comphelper::ConfigurationChanges::create();
202 officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::set(_nLevel, xChanges);
203 xChanges->commit();
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();
218 if( !c1 )
219 return {};
221 sal_Int32 c2 = c1 * 3; // 3 Properties inside Struct TrustedAuthor
222 Sequence< OUString > lAllAuthors( c2 );
223 auto plAllAuthors = lAllAuthors.getArray();
224 sal_Int32 i2 = 0;
225 OUString aSep( u"/"_ustr );
226 for( const auto& rAuthor : lAuthors )
228 plAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + rAuthor + aSep + PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME;
229 ++i2;
230 plAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + rAuthor + aSep + PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER;
231 ++i2;
232 plAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + rAuthor + aSep + PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA;
233 ++i2;
236 Sequence< Any > lValues = utl::ConfigItem::GetProperties( xHierarchyAccess, lAllAuthors, /*bAllLocales*/false );
237 if( lValues.getLength() != c2 )
238 return {};
240 std::vector< SvtSecurityOptions::Certificate > aTrustedAuthors;
241 SvtSecurityOptions::Certificate aCert;
242 i2 = 0;
243 for( sal_Int32 i1 = 0; i1 < c1; ++i1 )
245 lValues[ i2 ] >>= aCert.SubjectName;
246 ++i2;
247 lValues[ i2 ] >>= aCert.SerialNumber;
248 ++i2;
249 lValues[ i2 ] >>= aCert.RawData;
250 ++i2;
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 )
267 // return;
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 )
285 OUString aPrefix(
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,
294 rAuthors[i].RawData)
297 utl::ConfigItem::SetSetProperties( xHierarchyAccess, PROPERTYNAME_MACRO_TRUSTEDAUTHORS, lPropertyValues );
301 bool IsOptionSet( EOption eOption )
303 if (comphelper::IsFuzzing())
304 return false;
305 bool bSet = false;
306 switch(eOption)
308 case SvtSecurityOptions::EOption::DocWarnSaveOrSend:
309 bSet = officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::get();
310 break;
311 case SvtSecurityOptions::EOption::DocWarnSigning:
312 bSet = officecfg::Office::Common::Security::Scripting::WarnSignDoc::get();
313 break;
314 case SvtSecurityOptions::EOption::DocWarnPrint:
315 bSet = officecfg::Office::Common::Security::Scripting::WarnPrintDoc::get();
316 break;
317 case SvtSecurityOptions::EOption::DocWarnCreatePdf:
318 bSet = officecfg::Office::Common::Security::Scripting::WarnCreatePDF::get();
319 break;
320 case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo:
321 bSet = officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::get();
322 break;
323 case SvtSecurityOptions::EOption::DocWarnKeepRedlineInfo:
324 bSet = officecfg::Office::Common::Security::Scripting::KeepRedlineInfoOnSaving::get();
325 break;
326 case SvtSecurityOptions::EOption::DocWarnKeepDocUserInfo:
327 bSet = officecfg::Office::Common::Security::Scripting::KeepDocUserInfoOnSaving::get();
328 break;
329 case SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo:
330 bSet = officecfg::Office::Common::Security::Scripting::KeepNoteAuthorDateInfoOnSaving::get();
331 break;
332 case SvtSecurityOptions::EOption::DocWarnKeepDocVersionInfo:
333 bSet = officecfg::Office::Common::Security::Scripting::KeepDocVersionInfoOnSaving::get();
334 break;
335 case SvtSecurityOptions::EOption::DocKeepPrinterSettings:
336 bSet = officecfg::Office::Common::Security::Scripting::KeepDocPrinterSettingsOnSaving::get();
337 break;
338 case SvtSecurityOptions::EOption::DocWarnRecommendPassword:
339 bSet = officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::get();
340 break;
341 case SvtSecurityOptions::EOption::CtrlClickHyperlink:
342 bSet = officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::get();
343 break;
344 case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks:
345 bSet = officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::get();
346 break;
347 case SvtSecurityOptions::EOption::DisableActiveContent:
348 bSet = officecfg::Office::Common::Security::Scripting::DisableActiveContent::get() &&
349 officecfg::Office::Common::Security::Scripting::DisableOLEAutomation::get();
350 break;
352 default:
353 assert(false);
356 return bSet;
359 void SetOption( EOption eOption, bool bValue )
361 std::shared_ptr<comphelper::ConfigurationChanges> xChanges = comphelper::ConfigurationChanges::create();
362 switch(eOption)
364 case SvtSecurityOptions::EOption::DocWarnSaveOrSend:
365 officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::set(bValue, xChanges);
366 break;
367 case SvtSecurityOptions::EOption::DocWarnSigning:
368 officecfg::Office::Common::Security::Scripting::WarnSignDoc::set(bValue, xChanges);
369 break;
370 case SvtSecurityOptions::EOption::DocWarnPrint:
371 officecfg::Office::Common::Security::Scripting::WarnPrintDoc::set(bValue, xChanges);
372 break;
373 case SvtSecurityOptions::EOption::DocWarnCreatePdf:
374 officecfg::Office::Common::Security::Scripting::WarnCreatePDF::set(bValue, xChanges);
375 break;
376 case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo:
377 officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::set(bValue, xChanges);
378 break;
379 case SvtSecurityOptions::EOption::DocWarnKeepRedlineInfo:
380 officecfg::Office::Common::Security::Scripting::KeepRedlineInfoOnSaving::set(bValue, xChanges);
381 break;
382 case SvtSecurityOptions::EOption::DocWarnKeepDocUserInfo:
383 officecfg::Office::Common::Security::Scripting::KeepDocUserInfoOnSaving::set(bValue, xChanges);
384 break;
385 case SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo:
386 officecfg::Office::Common::Security::Scripting::KeepNoteAuthorDateInfoOnSaving::set(bValue, xChanges);
387 break;
388 case SvtSecurityOptions::EOption::DocWarnKeepDocVersionInfo:
389 officecfg::Office::Common::Security::Scripting::KeepDocVersionInfoOnSaving::set(bValue, xChanges);
390 break;
391 case SvtSecurityOptions::EOption::DocKeepPrinterSettings:
392 officecfg::Office::Common::Security::Scripting::KeepDocPrinterSettingsOnSaving::set(bValue, xChanges);
393 break;
394 case SvtSecurityOptions::EOption::DocWarnRecommendPassword:
395 officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::set(bValue, xChanges);
396 break;
397 case SvtSecurityOptions::EOption::CtrlClickHyperlink:
398 officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::set(bValue, xChanges);
399 break;
400 case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks:
401 officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::set(bValue, xChanges);
402 break;
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);
406 break;
408 default:
409 assert(false);
411 xChanges->commit();
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;
425 return nNewID;
428 return aIter->second;
431 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */