merge the formfield patch from ooo-build
[ooovba.git] / sfx2 / source / doc / docmacromode.cxx
blob131ff7c8d8eb04e31e7a2f99aa858eb5f33879a0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: docmacromode.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #include "sfx2/docmacromode.hxx"
35 #include "sfx2/signaturestate.hxx"
36 #include "sfx2/docfile.hxx"
38 /** === begin UNO includes === **/
39 #include <com/sun/star/document/MacroExecMode.hpp>
40 #include <com/sun/star/task/ErrorCodeRequest.hpp>
41 #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
42 #include <com/sun/star/task/InteractionClassification.hpp>
43 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
44 #include <com/sun/star/script/XLibraryQueryExecutable.hpp>
45 /** === end UNO includes === **/
47 #include <comphelper/componentcontext.hxx>
48 #include <comphelper/processfactory.hxx>
49 #include <framework/interaction.hxx>
50 #include <osl/file.hxx>
51 #include <rtl/ref.hxx>
52 #include <svtools/securityoptions.hxx>
53 #include <svtools/sfxecode.hxx>
54 #include <tools/diagnose_ex.h>
55 #include <tools/urlobj.hxx>
57 //........................................................................
58 namespace sfx2
60 //........................................................................
62 /** === begin UNO using === **/
63 using ::com::sun::star::uno::Reference;
64 using ::com::sun::star::task::XInteractionHandler;
65 using ::com::sun::star::uno::Any;
66 using ::com::sun::star::task::XInteractionHandler;
67 using ::com::sun::star::uno::Sequence;
68 using ::com::sun::star::task::XInteractionContinuation;
69 using ::com::sun::star::task::XInteractionRequest;
70 using ::com::sun::star::task::DocumentMacroConfirmationRequest;
71 using ::com::sun::star::task::ErrorCodeRequest;
72 using ::com::sun::star::uno::Exception;
73 using ::com::sun::star::security::XDocumentDigitalSignatures;
74 using ::com::sun::star::security::DocumentSignatureInformation;
75 using ::com::sun::star::embed::XStorage;
76 using ::com::sun::star::task::InteractionClassification_QUERY;
77 using ::com::sun::star::document::XEmbeddedScripts;
78 using ::com::sun::star::uno::UNO_SET_THROW;
79 using ::com::sun::star::script::XLibraryContainer;
80 using ::com::sun::star::script::XLibraryQueryExecutable;
81 using ::com::sun::star::container::XNameAccess;
82 using ::com::sun::star::uno::UNO_QUERY_THROW;
83 using ::com::sun::star::uno::UNO_QUERY;
84 /** === end UNO using === **/
85 namespace MacroExecMode = ::com::sun::star::document::MacroExecMode;
87 //====================================================================
88 //= DocumentMacroMode_Data
89 //====================================================================
90 struct DocumentMacroMode_Data
92 IMacroDocumentAccess& m_rDocumentAccess;
93 sal_Bool m_bMacroDisabledMessageShown;
94 sal_Bool m_bDocMacroDisabledMessageShown;
96 DocumentMacroMode_Data( IMacroDocumentAccess& rDocumentAccess )
97 :m_rDocumentAccess( rDocumentAccess )
98 ,m_bMacroDisabledMessageShown( sal_False )
99 ,m_bDocMacroDisabledMessageShown( sal_False )
104 //====================================================================
105 //= helper
106 //====================================================================
107 namespace
109 //................................................................
110 void lcl_showGeneralSfxErrorOnce( const Reference< XInteractionHandler >& rxHandler, const sal_Int32 nSfxErrorCode, sal_Bool& rbAlreadyShown )
112 if ( rbAlreadyShown )
113 return;
115 ErrorCodeRequest aErrorCodeRequest;
116 aErrorCodeRequest.ErrCode = nSfxErrorCode;
118 SfxMedium::CallApproveHandler( rxHandler, makeAny( aErrorCodeRequest ), sal_False );
119 rbAlreadyShown = sal_True;
122 //................................................................
123 void lcl_showMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown )
125 lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_MACROS_SUPPORT_DISABLED, rbAlreadyShown );
128 //................................................................
129 void lcl_showDocumentMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown )
131 lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_DOCUMENT_MACRO_DISABLED, rbAlreadyShown );
134 //................................................................
135 sal_Bool lcl_showMacroWarning( const Reference< XInteractionHandler >& rxHandler,
136 const ::rtl::OUString& rDocumentLocation )
138 DocumentMacroConfirmationRequest aRequest;
139 aRequest.DocumentURL = rDocumentLocation;
140 return SfxMedium::CallApproveHandler( rxHandler, makeAny( aRequest ), sal_True );
144 //====================================================================
145 //= DocumentMacroMode
146 //====================================================================
147 //--------------------------------------------------------------------
148 DocumentMacroMode::DocumentMacroMode( IMacroDocumentAccess& rDocumentAccess )
149 :m_pData( new DocumentMacroMode_Data( rDocumentAccess ) )
153 //--------------------------------------------------------------------
154 DocumentMacroMode::~DocumentMacroMode()
158 //--------------------------------------------------------------------
159 sal_Bool DocumentMacroMode::allowMacroExecution()
161 m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::ALWAYS_EXECUTE_NO_WARN );
162 return sal_True;
165 //--------------------------------------------------------------------
166 sal_Bool DocumentMacroMode::disallowMacroExecution()
168 m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::NEVER_EXECUTE );
169 return sal_False;
172 //--------------------------------------------------------------------
173 sal_Bool DocumentMacroMode::adjustMacroMode( const Reference< XInteractionHandler >& rxInteraction )
175 sal_uInt16 nMacroExecutionMode = m_pData->m_rDocumentAccess.getCurrentMacroExecMode();
177 if ( SvtSecurityOptions().IsMacroDisabled() )
179 // no macro should be executed at all
180 lcl_showMacrosDisabledError( rxInteraction, m_pData->m_bMacroDisabledMessageShown );
181 return disallowMacroExecution();
184 // get setting from configuration if required
185 enum AutoConfirmation
187 eNoAutoConfirm,
188 eAutoConfirmApprove,
189 eAutoConfirmReject
191 AutoConfirmation eAutoConfirm( eNoAutoConfirm );
193 if ( ( nMacroExecutionMode == MacroExecMode::USE_CONFIG )
194 || ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION )
195 || ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION )
198 SvtSecurityOptions aOpt;
199 switch ( aOpt.GetMacroSecurityLevel() )
201 case 3:
202 nMacroExecutionMode = MacroExecMode::FROM_LIST_NO_WARN;
203 break;
204 case 2:
205 nMacroExecutionMode = MacroExecMode::FROM_LIST_AND_SIGNED_WARN;
206 break;
207 case 1:
208 nMacroExecutionMode = MacroExecMode::ALWAYS_EXECUTE;
209 break;
210 case 0:
211 nMacroExecutionMode = MacroExecMode::ALWAYS_EXECUTE_NO_WARN;
212 break;
213 default:
214 OSL_ENSURE( sal_False, "DocumentMacroMode::adjustMacroMode: unexpected macro security level!" );
215 nMacroExecutionMode = MacroExecMode::NEVER_EXECUTE;
218 if ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION )
219 eAutoConfirm = eAutoConfirmReject;
220 else if ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION )
221 eAutoConfirm = eAutoConfirmApprove;
224 if ( nMacroExecutionMode == MacroExecMode::NEVER_EXECUTE )
225 return sal_False;
227 if ( nMacroExecutionMode == MacroExecMode::ALWAYS_EXECUTE_NO_WARN )
228 return sal_True;
232 ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() );
234 // get document location from medium name and check whether it is a trusted one
235 // the service is created ohne document version, since it is not of interest here
236 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
237 Reference< XDocumentDigitalSignatures > xSignatures;
238 if ( aContext.createComponent( "com.sun.star.security.DocumentDigitalSignatures", xSignatures ) )
240 INetURLObject aURLReferer( sReferrer );
242 ::rtl::OUString aLocation;
243 if ( aURLReferer.removeSegment() )
244 aLocation = aURLReferer.GetMainURL( INetURLObject::NO_DECODE );
246 if ( aLocation.getLength() && xSignatures->isLocationTrusted( aLocation ) )
248 return allowMacroExecution();
252 // at this point it is clear that the document is not in the secure location
253 if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN )
255 lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown );
256 return disallowMacroExecution();
259 // check whether the document is signed with trusted certificate
260 if ( nMacroExecutionMode != MacroExecMode::FROM_LIST )
262 // the trusted macro check will also retrieve the signature state ( small optimization )
263 sal_Bool bHasTrustedMacroSignature = m_pData->m_rDocumentAccess.hasTrustedScriptingSignature( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN );
265 sal_uInt16 nSignatureState = m_pData->m_rDocumentAccess.getScriptingSignatureState();
266 if ( nSignatureState == SIGNATURESTATE_SIGNATURES_BROKEN )
268 // the signature is broken, no macro execution
269 if ( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN )
270 m_pData->m_rDocumentAccess.showBrokenSignatureWarning( rxInteraction );
272 return disallowMacroExecution();
274 else if ( bHasTrustedMacroSignature )
276 // there is trusted macro signature, allow macro execution
277 return allowMacroExecution();
279 else if ( nSignatureState == SIGNATURESTATE_SIGNATURES_OK
280 || nSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED )
282 // there is valid signature, but it is not from the trusted author
283 return disallowMacroExecution();
287 // at this point it is clear that the document is neither in secure location nor signed with trusted certificate
288 if ( ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN )
289 || ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN )
292 if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN )
293 lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown );
295 return disallowMacroExecution();
298 catch ( Exception& )
300 if ( ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN )
301 || ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN )
302 || ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN )
305 return disallowMacroExecution();
309 // conformation is required
310 sal_Bool bSecure = sal_False;
312 if ( eAutoConfirm == eNoAutoConfirm )
314 ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() );
316 ::rtl::OUString aSystemFileURL;
317 if ( osl::FileBase::getSystemPathFromFileURL( sReferrer, aSystemFileURL ) == osl::FileBase::E_None )
318 sReferrer = aSystemFileURL;
320 bSecure = lcl_showMacroWarning( rxInteraction, sReferrer );
322 else
323 bSecure = ( eAutoConfirm == eAutoConfirmApprove );
325 return ( bSecure ? allowMacroExecution() : disallowMacroExecution() );
328 //--------------------------------------------------------------------
329 sal_Bool DocumentMacroMode::isMacroExecutionDisallowed() const
331 return m_pData->m_rDocumentAccess.getCurrentMacroExecMode() == MacroExecMode::NEVER_EXECUTE;
334 //--------------------------------------------------------------------
335 sal_Bool DocumentMacroMode::hasMacroLibrary() const
337 sal_Bool bHasMacroLib = sal_False;
340 Reference< XEmbeddedScripts > xScripts( m_pData->m_rDocumentAccess.getEmbeddedDocumentScripts() );
341 Reference< XLibraryContainer > xContainer;
342 if ( xScripts.is() )
343 xContainer.set( xScripts->getBasicLibraries(), UNO_QUERY_THROW );
345 if ( xContainer.is() )
347 // a library container exists; check if it's empty
349 // if there are libraries except the "Standard" library
350 // we assume that they are not empty (because they have been created by the user)
351 if ( !xContainer->hasElements() )
352 bHasMacroLib = sal_False;
353 else
355 ::rtl::OUString aStdLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
356 Sequence< ::rtl::OUString > aElements = xContainer->getElementNames();
357 if ( aElements.getLength() )
359 if ( aElements.getLength() > 1 || !aElements[0].equals( aStdLibName ) )
360 bHasMacroLib = sal_True;
361 else
363 // usually a "Standard" library is always present (design)
364 // for this reason we must check if it's empty
366 // Note: Since #i73229#, this is not true anymore. There's no default
367 // "Standard" lib anymore. Wouldn't it be time to get completely
368 // rid of the "Standard" thingie - this shouldn't be necessary
369 // anymore, should it?
370 // 2007-01-25 / frank.schoenheit@sun.com
371 Reference < XLibraryQueryExecutable > xLib( xContainer, UNO_QUERY );
372 if ( xLib.is() )
373 bHasMacroLib = xLib->HasExecutableCode( aStdLibName );
379 catch( const Exception& )
381 DBG_UNHANDLED_EXCEPTION();
384 return bHasMacroLib;
387 //--------------------------------------------------------------------
388 sal_Bool DocumentMacroMode::storageHasMacros( const Reference< XStorage >& rxStorage )
390 sal_Bool bHasMacros = sal_False;
391 if ( rxStorage.is() )
395 static const ::rtl::OUString s_sBasicStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ) );
396 static const ::rtl::OUString s_sScriptsStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Scripts" ) ) );
398 bHasMacros =( ( rxStorage->hasByName( s_sBasicStorageName )
399 && rxStorage->isStorageElement( s_sBasicStorageName )
401 || ( rxStorage->hasByName( s_sScriptsStorageName )
402 && rxStorage->isStorageElement( s_sScriptsStorageName )
406 catch ( const Exception& )
408 DBG_UNHANDLED_EXCEPTION();
411 return bHasMacros;
414 //--------------------------------------------------------------------
415 sal_Bool DocumentMacroMode::checkMacrosOnLoading( const Reference< XInteractionHandler >& rxInteraction )
417 sal_Bool bAllow = sal_False;
418 if ( SvtSecurityOptions().IsMacroDisabled() )
420 // no macro should be executed at all
421 bAllow = disallowMacroExecution();
423 else
425 if ( m_pData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() )
427 bAllow = adjustMacroMode( rxInteraction );
429 else if ( !isMacroExecutionDisallowed() )
431 // if macros will be added by the user later, the security check is obsolete
432 bAllow = allowMacroExecution();
435 return bAllow;
438 //........................................................................
439 } // namespace sfx2
440 //........................................................................