include/sfx2/docmacromode.hxx | 1 include/sfx2/strings.hrc | 1 include/sfx2/viewfrm.hxx | 1 sfx2/source/doc/docmacromode.cxx | 24 ++++++++++++++++++++-- sfx2/source/view/viewfrm.cxx | 41 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 2 deletions(-)
New commits: commit 2beaa3be3829303e948d401f492dbfd239d60aad Author: Sarper Akdemir <sarper.akde...@allotropia.de> AuthorDate: Tue Jun 11 12:39:36 2024 +0200 Commit: Sarper Akdemir <sarper.akde...@allotropia.de> CommitDate: Wed Jun 12 10:06:04 2024 +0200 remove ability to trust not validated macro signatures in high security Giving the user the option to determine if they should trust an invalid signature in HIGH macro security doesn't make sense. CommonName of the signature is the most prominent feature presented and the CommonName of a certificate can be easily forged for an invalid signature, tricking the user into accepting an invalid signature. in the HIGH macro security setting only show the pop-up to enable/disable signed macro if the certificate signature can be validated. Additionally present a ViewSignatures button in the Macro Disabled infobar, so that the user can inspect what are the invalid signatures and why (wihtout the ability of enabling macros). Change-Id: Ia766fb701660160ee5dc9f6e077f4012a44ce721 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168667 Tested-by: Jenkins Reviewed-by: Sarper Akdemir <sarper.akde...@allotropia.de> diff --git a/include/sfx2/docmacromode.hxx b/include/sfx2/docmacromode.hxx index 0816f310b45b..19ce18250175 100644 --- a/include/sfx2/docmacromode.hxx +++ b/include/sfx2/docmacromode.hxx @@ -265,6 +265,7 @@ namespace sfx2 bool hasMacroLibrary() const; bool hasUnsignedContentError() const; + bool hasInvalidSignaturesError() const; /** determines whether the given document storage has sub storages containing scripts or macros. diff --git a/include/sfx2/strings.hrc b/include/sfx2/strings.hrc index 1c3fafa074c0..35997819573d 100644 --- a/include/sfx2/strings.hrc +++ b/include/sfx2/strings.hrc @@ -289,6 +289,7 @@ #define STR_MACROS_DISABLED_TITLE NC_("STR_MACROS_DISABLED_TITLE", "Macros disabled") #define STR_CONTAINS_MACROS NC_("STR_CONTAINS_MACROS", "Macros in this document are disabled due to the Macro Security settings.") #define STR_MACROS_DISABLED NC_("STR_MACROS_DISABLED", "Macros are disabled due to the Macro Security settings.") +#define STR_MACROS_DISABLED_SIGNATURE_INVALID NC_("STR_MACROS_DISABLED_SIGNATURE_INVALID", "Macros are signed, but at least one signature has problems.") #define STR_MACROS_DISABLED_CONTENT_UNSIGNED NC_("STR_MACROS_DISABLED_CONTENT_UNSIGNED", "Macros are signed, but the document (containing document events) is not signed.") #define STR_MACROS NC_("STR_MACROS", "Show Macros") #define STR_SECURITY_OPTIONS NC_("STR_MACROS", "Show Security Options") diff --git a/include/sfx2/viewfrm.hxx b/include/sfx2/viewfrm.hxx index e0c56342eae5..ff942d4b27b1 100644 --- a/include/sfx2/viewfrm.hxx +++ b/include/sfx2/viewfrm.hxx @@ -67,6 +67,7 @@ class SFX2_DLLPUBLIC SfxViewFrame final : public SfxShell, public SfxListener DECL_DLLPRIVATE_LINK(MacroButtonHandler, weld::Button&, void); DECL_DLLPRIVATE_LINK(SecurityButtonHandler, weld::Button&, void); DECL_DLLPRIVATE_LINK(EventButtonHandler, weld::Button&, void); + DECL_DLLPRIVATE_LINK(ViewSignaturesButtonHandler, weld::Button&, void); DECL_DLLPRIVATE_LINK(SwitchReadOnlyHandler, weld::Button&, void); DECL_DLLPRIVATE_LINK(SignDocumentHandler, weld::Button&, void); DECL_DLLPRIVATE_LINK(HiddenTrackChangesHandler, weld::Button&, void); diff --git a/sfx2/source/doc/docmacromode.cxx b/sfx2/source/doc/docmacromode.cxx index 4e9311593aed..c87224301590 100644 --- a/sfx2/source/doc/docmacromode.cxx +++ b/sfx2/source/doc/docmacromode.cxx @@ -72,10 +72,13 @@ namespace sfx2 { IMacroDocumentAccess& m_rDocumentAccess; bool m_bHasUnsignedContentError; + /// Is true when macros was disabled due to invalid signatures (when macro security is high) + bool m_bHasInvalidSignaturesError; explicit DocumentMacroMode_Data( IMacroDocumentAccess& rDocumentAccess ) :m_rDocumentAccess( rDocumentAccess ) ,m_bHasUnsignedContentError( false ) + ,m_bHasInvalidSignaturesError( false ) { } }; @@ -212,13 +215,26 @@ namespace sfx2 // confirmation when macros are unsigned or untrusted. FROM_LIST_AND_SIGNED_NO_WARN // should not ask any confirmations. FROM_LIST_AND_SIGNED_WARN should only allow // trusted signed macros at this point; so it may only ask for confirmation to add - // certificates to trusted, and shouldn't show UI when trusted list is read-only. + // certificates to trusted, and shouldn't show UI when trusted list is read-only + // or the macro signature can't be validated. const bool bAllowUI = nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN && eAutoConfirm == eNoAutoConfirm && (nMacroExecutionMode == MacroExecMode::ALWAYS_EXECUTE || !SvtSecurityOptions::IsReadOnly( - SvtSecurityOptions::EOption::MacroTrustedAuthors)); + SvtSecurityOptions::EOption::MacroTrustedAuthors)) + && (nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_WARN + || nSignatureState == SignatureState::OK); + + if (nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN + && nSignatureState != SignatureState::NOSIGNATURES + && nSignatureState != SignatureState::OK) + { + // set the flag so that we can show the appropriate error & buttons + // for invalid signatures in the infobar for high macro security. + m_xData->m_bHasInvalidSignaturesError = true; + } + const bool bHasTrustedMacroSignature = m_xData->m_rDocumentAccess.hasTrustedScriptingSignature(bAllowUI ? rxInteraction : nullptr); if (bHasTrustedMacroSignature) @@ -407,6 +423,10 @@ namespace sfx2 return m_xData->m_bHasUnsignedContentError; } + bool DocumentMacroMode::hasInvalidSignaturesError() const + { + return m_xData->m_bHasInvalidSignaturesError; + } bool DocumentMacroMode::storageHasMacros( const Reference< XStorage >& rxStorage ) { diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 59a31cf55d87..414ee53c1deb 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -36,6 +36,7 @@ #include <com/sun/star/frame/XLayoutManager.hpp> #include <com/sun/star/frame/XComponentLoader.hpp> #include <com/sun/star/task/PasswordContainer.hpp> +#include <com/sun/star/security/DocumentDigitalSignatures.hpp> #include <officecfg/Office/Common.hxx> #include <officecfg/Setup.hxx> #include <toolkit/helper/vclunohelper.hxx> @@ -1349,6 +1350,8 @@ void SfxViewFrame::AppendContainsMacrosInfobar() aResId = STR_MACROS_DISABLED; else if (pObjImpl->aMacroMode.hasUnsignedContentError()) aResId = STR_MACROS_DISABLED_CONTENT_UNSIGNED; + else if(pObjImpl->aMacroMode.hasInvalidSignaturesError()) + aResId = STR_MACROS_DISABLED_SIGNATURE_INVALID; // The idea here is to always present an infobar is there was some // macro/script related potential hazard disabled in the source document auto pInfoBar = AppendInfoBar(u"macro"_ustr, SfxResId(STR_MACROS_DISABLED_TITLE), @@ -1419,6 +1422,13 @@ void SfxViewFrame::AppendContainsMacrosInfobar() rEventButton.set_label(SfxResId(STR_EVENTS)); rEventButton.connect_clicked(LINK(this, SfxViewFrame, EventButtonHandler)); } + + if (pObjImpl->aMacroMode.hasInvalidSignaturesError()) + { + weld::Button& rSignaturesButton = pInfoBar->addButton(); + rSignaturesButton.set_label(SfxResId(STR_SIGNATURE_SHOW)); + rSignaturesButton.connect_clicked(LINK(this, SfxViewFrame, ViewSignaturesButtonHandler)); + } } namespace @@ -1920,6 +1930,37 @@ IMPL_LINK_NOARG(SfxViewFrame, EventButtonHandler, weld::Button&, void) {}, { &aDocFrame }); } +IMPL_LINK_NOARG(SfxViewFrame, ViewSignaturesButtonHandler, weld::Button&, void) +{ + SfxObjectShell* pDoc = GetObjectShell(); + if (!pDoc) + return; + + SfxMedium* pMedium = pDoc->GetMedium(); + if (!pMedium) + return; + + OUString maODFVersion{}; + try + { + uno::Reference<beans::XPropertySet> xPropSet(pDoc->GetStorage(), uno::UNO_QUERY_THROW); + xPropSet->getPropertyValue(u"Version"_ustr) >>= maODFVersion; + } + catch (uno::Exception&) + { + } + + uno::Reference<security::XDocumentDigitalSignatures> xDigitalSignatures( + security::DocumentDigitalSignatures::createWithVersion( + comphelper::getProcessComponentContext(), maODFVersion)); + + if (!xDigitalSignatures.is()) + return; + + if (auto xScriptingStorage = pMedium->GetScriptingStorageToSign_Impl()) + xDigitalSignatures->showScriptingContentSignatures(xScriptingStorage, {}); +} + IMPL_LINK_NOARG(SfxViewFrame, RefreshMasterPasswordHdl, weld::Button&, void) { bool bChanged = false;