summaryrefslogtreecommitdiffstats
path: root/unotools/source/config/securityoptions.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--unotools/source/config/securityoptions.cxx357
1 files changed, 357 insertions, 0 deletions
diff --git a/unotools/source/config/securityoptions.cxx b/unotools/source/config/securityoptions.cxx
new file mode 100644
index 000000000..4749065fb
--- /dev/null
+++ b/unotools/source/config/securityoptions.cxx
@@ -0,0 +1,357 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unotools/securityoptions.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/configitem.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/sequence.hxx>
+#include <tools/urlobj.hxx>
+
+#include <unotools/pathoptions.hxx>
+#include <officecfg/Office/Common.hxx>
+
+// namespaces
+
+using namespace ::com::sun::star::uno;
+
+constexpr OUStringLiteral PROPERTYNAME_MACRO_TRUSTEDAUTHORS = u"TrustedAuthors";
+constexpr OUStringLiteral PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME = u"SubjectName";
+constexpr OUStringLiteral PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER = u"SerialNumber";
+constexpr OUStringLiteral PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA = u"RawData";
+
+
+namespace SvtSecurityOptions
+{
+
+bool IsReadOnly( EOption eOption )
+{
+ bool bReadonly;
+ switch(eOption)
+ {
+ case SvtSecurityOptions::EOption::SecureUrls :
+ bReadonly = officecfg::Office::Common::Security::Scripting::SecureURL::isReadOnly();
+ break;
+ case SvtSecurityOptions::EOption::DocWarnSaveOrSend:
+ bReadonly = officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::isReadOnly();
+ break;
+ case SvtSecurityOptions::EOption::DocWarnSigning:
+ bReadonly = officecfg::Office::Common::Security::Scripting::WarnSignDoc::isReadOnly();
+ break;
+ case SvtSecurityOptions::EOption::DocWarnPrint:
+ bReadonly = officecfg::Office::Common::Security::Scripting::WarnPrintDoc::isReadOnly();
+ break;
+ case SvtSecurityOptions::EOption::DocWarnCreatePdf:
+ bReadonly = officecfg::Office::Common::Security::Scripting::WarnCreatePDF::isReadOnly();
+ break;
+ case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo:
+ bReadonly = officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::isReadOnly();
+ break;
+ case SvtSecurityOptions::EOption::DocWarnRecommendPassword:
+ bReadonly = officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::isReadOnly();
+ break;
+ case SvtSecurityOptions::EOption::MacroSecLevel:
+ bReadonly = officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::isReadOnly();
+ break;
+ case SvtSecurityOptions::EOption::MacroTrustedAuthors:
+ bReadonly = false; // TODO? officecfg::Office::Common::Security::Scripting::TrustedAuthors::isReadOnly();
+ break;
+ case SvtSecurityOptions::EOption::CtrlClickHyperlink:
+ bReadonly = officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::isReadOnly();
+ break;
+ case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks:
+ bReadonly = officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::isReadOnly();
+ break;
+
+ default:
+ assert(false);
+ bReadonly = true;
+ }
+
+ return bReadonly;
+}
+
+std::vector< OUString > GetSecureURLs()
+{
+ if (utl::ConfigManager::IsFuzzing())
+ return {};
+ std::vector<OUString> aRet = comphelper::sequenceToContainer<std::vector<OUString>>(
+ officecfg::Office::Common::Security::Scripting::SecureURL::get());
+ SvtPathOptions aOpt;
+ std::transform(aRet.begin(), aRet.end(), aRet.begin(),
+ [&aOpt](const OUString& rUrl) -> OUString { return aOpt.SubstituteVariable( rUrl ); });
+ return aRet;
+}
+
+void SetSecureURLs( std::vector< OUString >&& urlList )
+{
+// DBG_ASSERT(!officecfg::SecureURL::isReadOnly(), "SvtSecurityOptions_Impl::SetSecureURLs()\nYou tried to write on a readonly value!\n");
+// if (officecfg::SecureURL::isReadOnly())
+// return;
+ std::vector< OUString > lURLs( std::move(urlList) );
+ SvtPathOptions aOpt;
+ std::transform(lURLs.begin(), lURLs.end(), lURLs.begin(),
+ [&aOpt](const OUString& rUrl) -> OUString { return aOpt.UseVariable( rUrl ); });
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges = comphelper::ConfigurationChanges::create();
+ officecfg::Office::Common::Security::Scripting::SecureURL::set(comphelper::containerToSequence(lURLs), xChanges);
+ xChanges->commit();
+}
+
+bool isSecureMacroUri(
+ OUString const & uri, OUString const & referer)
+{
+ switch (INetURLObject(uri).GetProtocol()) {
+ case INetProtocol::Macro:
+ if (uri.startsWithIgnoreAsciiCase("macro:///")) {
+ // Denotes an App-BASIC macro (see SfxMacroLoader::loadMacro), which
+ // is considered safe:
+ return true;
+ }
+ [[fallthrough]];
+ case INetProtocol::Slot:
+ return referer.equalsIgnoreAsciiCase("private:user")
+ || isTrustedLocationUri(referer);
+ default:
+ return true;
+ }
+}
+
+bool isUntrustedReferer(OUString const & referer)
+{
+ return IsOptionSet(EOption::BlockUntrustedRefererLinks)
+ && !(referer.isEmpty() || referer.startsWithIgnoreAsciiCase("private:")
+ || isTrustedLocationUri(referer));
+}
+
+bool isTrustedLocationUri(OUString const & uri)
+{
+ for (const auto & url : GetSecureURLs())
+ {
+ if (utl::UCBContentHelper::IsSubPath(url, uri))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool isTrustedLocationUriForUpdatingLinks(OUString const & uri)
+{
+ return GetMacroSecurityLevel() == 0 || uri.isEmpty()
+ || uri.startsWithIgnoreAsciiCase("private:")
+ || isTrustedLocationUri(uri);
+}
+
+sal_Int32 GetMacroSecurityLevel()
+{
+ return officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::get();
+}
+
+void SetMacroSecurityLevel( sal_Int32 _nLevel )
+{
+ if( officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::isReadOnly() )
+ return;
+
+ if( _nLevel > 3 || _nLevel < 0 )
+ _nLevel = 3;
+
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges = comphelper::ConfigurationChanges::create();
+ officecfg::Office::Common::Security::Scripting::MacroSecurityLevel::set(_nLevel, xChanges);
+ xChanges->commit();
+}
+
+bool IsMacroDisabled()
+{
+ return officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get();
+}
+
+std::vector< SvtSecurityOptions::Certificate > GetTrustedAuthors()
+{
+ Reference<css::container::XHierarchicalNameAccess> xHierarchyAccess = utl::ConfigManager::acquireTree(u"Office.Common/Security/Scripting");
+ const Sequence< OUString > lAuthors = utl::ConfigItem::GetNodeNames( xHierarchyAccess, PROPERTYNAME_MACRO_TRUSTEDAUTHORS, utl::ConfigNameFormat::LocalPath );
+ sal_Int32 c1 = lAuthors.getLength();
+ if( !c1 )
+ return {};
+
+ sal_Int32 c2 = c1 * 3; // 3 Properties inside Struct TrustedAuthor
+ Sequence< OUString > lAllAuthors( c2 );
+ auto plAllAuthors = lAllAuthors.getArray();
+ sal_Int32 i2 = 0;
+ OUString aSep( "/" );
+ for( const auto& rAuthor : lAuthors )
+ {
+ plAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + rAuthor + aSep + PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME;
+ ++i2;
+ plAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + rAuthor + aSep + PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER;
+ ++i2;
+ plAllAuthors[ i2 ] = PROPERTYNAME_MACRO_TRUSTEDAUTHORS + aSep + rAuthor + aSep + PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA;
+ ++i2;
+ }
+
+ Sequence< Any > lValues = utl::ConfigItem::GetProperties( xHierarchyAccess, lAllAuthors, /*bAllLocales*/false );
+ if( lValues.getLength() != c2 )
+ return {};
+
+ std::vector< SvtSecurityOptions::Certificate > aTrustedAuthors;
+ SvtSecurityOptions::Certificate aCert;
+ i2 = 0;
+ for( sal_Int32 i1 = 0; i1 < c1; ++i1 )
+ {
+ lValues[ i2 ] >>= aCert.SubjectName;
+ ++i2;
+ lValues[ i2 ] >>= aCert.SerialNumber;
+ ++i2;
+ lValues[ i2 ] >>= aCert.RawData;
+ ++i2;
+ // Filter out TrustedAuthor entries with empty RawData, which
+ // would cause an unexpected std::bad_alloc in
+ // SecurityEnvironment_NssImpl::createCertificateFromAscii and
+ // have been observed in the wild (fdo#55019):
+ if( !aCert.RawData.isEmpty() )
+ {
+ aTrustedAuthors.push_back( aCert );
+ }
+ }
+ return aTrustedAuthors;
+}
+
+void SetTrustedAuthors( const std::vector< Certificate >& rAuthors )
+{
+// DBG_ASSERT(!m_bROTrustedAuthors, "SvtSecurityOptions_Impl::SetTrustedAuthors()\nYou tried to write on a readonly value!\n");
+// if( m_bROTrustedAuthors )
+// return;
+
+ Reference<css::container::XHierarchicalNameAccess> xHierarchyAccess = utl::ConfigManager::acquireTree(u"Office.Common/Security/Scripting");
+ sal_Int32 nCnt = rAuthors.size();
+ for( sal_Int32 i = 0; i < nCnt; ++i )
+ {
+ OUString aPrefix(
+ PROPERTYNAME_MACRO_TRUSTEDAUTHORS + "/a"
+ + OUString::number(i) + "/");
+ Sequence< css::beans::PropertyValue > lPropertyValues{
+ comphelper::makePropertyValue(aPrefix + PROPERTYNAME_TRUSTEDAUTHOR_SUBJECTNAME,
+ rAuthors[i].SubjectName),
+ comphelper::makePropertyValue(aPrefix + PROPERTYNAME_TRUSTEDAUTHOR_SERIALNUMBER,
+ rAuthors[i].SerialNumber),
+ comphelper::makePropertyValue(aPrefix + PROPERTYNAME_TRUSTEDAUTHOR_RAWDATA,
+ rAuthors[i].RawData)
+ };
+
+ utl::ConfigItem::SetSetProperties( xHierarchyAccess, PROPERTYNAME_MACRO_TRUSTEDAUTHORS, lPropertyValues );
+ }
+}
+
+bool IsOptionSet( EOption eOption )
+{
+ if (utl::ConfigManager::IsFuzzing())
+ return false;
+ bool bSet = false;
+ switch(eOption)
+ {
+ case SvtSecurityOptions::EOption::DocWarnSaveOrSend:
+ bSet = officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::get();
+ break;
+ case SvtSecurityOptions::EOption::DocWarnSigning:
+ bSet = officecfg::Office::Common::Security::Scripting::WarnSignDoc::get();
+ break;
+ case SvtSecurityOptions::EOption::DocWarnPrint:
+ bSet = officecfg::Office::Common::Security::Scripting::WarnPrintDoc::get();
+ break;
+ case SvtSecurityOptions::EOption::DocWarnCreatePdf:
+ bSet = officecfg::Office::Common::Security::Scripting::WarnCreatePDF::get();
+ break;
+ case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo:
+ bSet = officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::get();
+ break;
+ case SvtSecurityOptions::EOption::DocWarnRecommendPassword:
+ bSet = officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::get();
+ break;
+ case SvtSecurityOptions::EOption::CtrlClickHyperlink:
+ bSet = officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::get();
+ break;
+ case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks:
+ bSet = officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::get();
+ break;
+
+ default:
+ assert(false);
+ }
+
+ return bSet;
+}
+
+void SetOption( EOption eOption, bool bValue )
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges = comphelper::ConfigurationChanges::create();
+ switch(eOption)
+ {
+ case SvtSecurityOptions::EOption::DocWarnSaveOrSend:
+ officecfg::Office::Common::Security::Scripting::WarnSaveOrSendDoc::set(bValue, xChanges);
+ break;
+ case SvtSecurityOptions::EOption::DocWarnSigning:
+ officecfg::Office::Common::Security::Scripting::WarnSignDoc::set(bValue, xChanges);
+ break;
+ case SvtSecurityOptions::EOption::DocWarnPrint:
+ officecfg::Office::Common::Security::Scripting::WarnPrintDoc::set(bValue, xChanges);
+ break;
+ case SvtSecurityOptions::EOption::DocWarnCreatePdf:
+ officecfg::Office::Common::Security::Scripting::WarnCreatePDF::set(bValue, xChanges);
+ break;
+ case SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo:
+ officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::set(bValue, xChanges);
+ break;
+ case SvtSecurityOptions::EOption::DocWarnRecommendPassword:
+ officecfg::Office::Common::Security::Scripting::RecommendPasswordProtection::set(bValue, xChanges);
+ break;
+ case SvtSecurityOptions::EOption::CtrlClickHyperlink:
+ officecfg::Office::Common::Security::Scripting::HyperlinksWithCtrlClick::set(bValue, xChanges);
+ break;
+ case SvtSecurityOptions::EOption::BlockUntrustedRefererLinks:
+ officecfg::Office::Common::Security::Scripting::BlockUntrustedRefererLinks::set(bValue, xChanges);
+ break;
+
+ default:
+ assert(false);
+ }
+ xChanges->commit();
+}
+
+} // namespace SvtSecurityOptions
+
+
+// map personal info strings to 1, 2, ... to remove personal info
+size_t SvtSecurityMapPersonalInfo::GetInfoID( const OUString sPersonalInfo )
+{
+ auto aIter = aInfoIDs.find( sPersonalInfo );
+ if ( aIter == aInfoIDs.end() )
+ {
+ size_t nNewID = aInfoIDs.size() + 1;
+ aInfoIDs[sPersonalInfo] = nNewID;
+ return nNewID;
+ }
+
+ return aIter->second;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */