using ::com::sun::star::uno::Reference; using ::com::sun::star::task::XInteractionHandler; using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Sequence; using ::com::sun::star::task::DocumentMacroConfirmationRequest; using ::com::sun::star::uno::Exception; using ::com::sun::star::security::DocumentDigitalSignatures; using ::com::sun::star::security::XDocumentDigitalSignatures; using ::com::sun::star::embed::XStorage; using ::com::sun::star::document::XEmbeddedScripts; using ::com::sun::star::script::XLibraryContainer; using ::com::sun::star::container::XNameAccess; using ::com::sun::star::uno::UNO_QUERY_THROW;
struct DocumentMacroMode_Data
{
IMacroDocumentAccess& m_rDocumentAccess; bool m_bHasUnsignedContentError; /// Is true when macros was disabled due to invalid signatures (when macro security is high) bool m_bHasInvalidSignaturesError;
bool DocumentMacroMode::adjustMacroMode( const Reference< XInteractionHandler >& rxInteraction, bool bHasValidContentSignature )
{ if ( SvtSecurityOptions::IsMacroDisabled() )
{ // no macro should be executed at all return disallowMacroExecution();
}
// get setting from configuration if required enum AutoConfirmation
{
eNoAutoConfirm,
eAutoConfirmApprove,
eAutoConfirmReject
};
AutoConfirmation eAutoConfirm( eNoAutoConfirm );
sal_Int16 nMacroExecutionMode = m_xData->m_rDocumentAccess.getCurrentMacroExecMode(); if ( ( nMacroExecutionMode == MacroExecMode::USE_CONFIG )
|| ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION )
|| ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION )
)
{ // check confirm first, as nMacroExecutionMode is always overwritten by the GetMacroSecurityLevel() switch if (nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION)
eAutoConfirm = eAutoConfirmReject; elseif (nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION)
eAutoConfirm = eAutoConfirmApprove;
if ( nMacroExecutionMode == MacroExecMode::NEVER_EXECUTE ) return disallowMacroExecution();
if ( nMacroExecutionMode == MacroExecMode::ALWAYS_EXECUTE_NO_WARN ) return allowMacroExecution();
SignatureState nSignatureState = SignatureState::UNKNOWN; const OUString sURL(m_xData->m_rDocumentAccess.getDocumentLocation()); try
{ // get document location from medium name and check whether it is a trusted one // the service is created without document version, since it is not of interest here
Reference< XDocumentDigitalSignatures > xSignatures(DocumentDigitalSignatures::createDefault(::comphelper::getProcessComponentContext()));
INetURLObject aURLReferer(sURL);
// at this point it is clear that the document is not in the secure location if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN )
{ return disallowMacroExecution();
}
// check whether the document is signed with trusted certificate if ( nMacroExecutionMode != MacroExecMode::FROM_LIST )
{
nSignatureState = m_xData->m_rDocumentAccess.getScriptingSignatureState();
if (!bHasValidContentSignature
&& (nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN
|| nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN)
&& m_xData->m_rDocumentAccess.macroCallsSeenWhileLoading())
{ // When macros are required to be signed, and the document has events which call // macros, the document content needs to be signed, too. Do it here, and avoid // possible UI asking to always trust certificates, after which the user's choice // to allow macros would be ignored anyway.
m_xData->m_bHasUnsignedContentError
= nSignatureState == SignatureState::OK
|| nSignatureState == SignatureState::NOTVALIDATED; return disallowMacroExecution();
}
// At this point, the possible values of nMacroExecutionMode are: ALWAYS_EXECUTE, // FROM_LIST_AND_SIGNED_WARN (the default), FROM_LIST_AND_SIGNED_NO_WARN. // ALWAYS_EXECUTE corresponds to the Medium security level; it should ask for // 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 // or the macro signature can't be validated. constbool bAllowUI
= nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN
&& eAutoConfirm == eNoAutoConfirm
&& (nMacroExecutionMode == MacroExecMode::ALWAYS_EXECUTE
|| !SvtSecurityOptions::IsReadOnly(
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;
}
if (bHasTrustedMacroSignature)
{ // there is trusted macro signature, allow macro execution return allowMacroExecution();
} elseif ( nSignatureState == SignatureState::OK
|| nSignatureState == SignatureState::NOTVALIDATED )
{ // there is valid signature, but it is not from the trusted author if (eAutoConfirm == eAutoConfirmApprove
&& nMacroExecutionMode == MacroExecMode::ALWAYS_EXECUTE)
{ // For ALWAYS_EXECUTE + eAutoConfirmApprove (USE_CONFIG_APPROVE_CONFIRMATION // in Medium security mode), do not approve it right here; let Security Zone // check below do its job first.
} else
{ // All other cases of valid but untrusted signatures should result in denied // macros here. This includes explicit reject from user in the UI in cases // of FROM_LIST_AND_SIGNED_WARN and ALWAYS_EXECUTE return disallowMacroExecution();
}
} // Other values of nSignatureState would result in either rejected macros // (FROM_LIST_AND_SIGNED_*), or a confirmation.
}
} catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("sfx.doc");
}
// at this point it is clear that the document is neither in secure location nor signed with trusted certificate if ((nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN)
|| (nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN))
{ return disallowMacroExecution();
}
#ifdefined(_WIN32) // Windows specific: try to decide macros loading depending on Windows Security Zones // (is the file local, or it was downloaded from internet, etc?)
OUString sFilePath;
osl::FileBase::getSystemPathFromFileURL(sURL, sFilePath);
sal::systools::COMReference<IZoneIdentifier> pZoneId;
pZoneId.CoCreateInstance(CLSID_PersistentZoneIdentifier);
sal::systools::COMReference<IPersistFile> pPersist(pZoneId, sal::systools::COM_QUERY);
DWORD dwZone; if (!pPersist || !SUCCEEDED(pPersist->Load(o3tl::toW(sFilePath.getStr()), STGM_READ)) ||
!SUCCEEDED(pZoneId->GetId(&dwZone)))
{ // no Security Zone info found -> assume a local file, not // from the internet
dwZone = URLZONE_LOCAL_MACHINE;
}
// determine action from zone and settings
sal_Int32 nAction; switch (dwZone) { case URLZONE_LOCAL_MACHINE:
nAction = officecfg::Office::Common::Security::Scripting::WindowsSecurityZone::ZoneLocal::get(); break; case URLZONE_INTRANET:
nAction = officecfg::Office::Common::Security::Scripting::WindowsSecurityZone::ZoneIntranet::get(); break; case URLZONE_TRUSTED:
nAction = officecfg::Office::Common::Security::Scripting::WindowsSecurityZone::ZoneTrusted::get(); break; case URLZONE_INTERNET:
nAction = officecfg::Office::Common::Security::Scripting::WindowsSecurityZone::ZoneInternet::get(); break; case URLZONE_UNTRUSTED:
nAction = officecfg::Office::Common::Security::Scripting::WindowsSecurityZone::ZoneUntrusted::get(); break; default: // unknown zone, let's ask the user
nAction = 0; break;
}
// act on result switch (nAction)
{ case0: // Ask break; case1: // Allow if (nSignatureState != SignatureState::BROKEN
&& nSignatureState != SignatureState::INVALID) return allowMacroExecution(); break; case2: // Deny return disallowMacroExecution();
} #endif // confirmation is required bool bSecure = false;
bool DocumentMacroMode::checkMacrosOnLoading( const Reference< XInteractionHandler >& rxInteraction, bool bHasValidContentSignature, bool bHasMacros )
{ bool bAllow = false; if ( SvtSecurityOptions::IsMacroDisabled() )
{ // no macro should be executed at all
bAllow = disallowMacroExecution();
} else
{ if (bHasMacros)
{
bAllow = adjustMacroMode( rxInteraction, bHasValidContentSignature );
} elseif ( !isMacroExecutionDisallowed() )
{ // if macros will be added by the user later, the security check is obsolete
bAllow = allowMacroExecution();
}
} return bAllow;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.