1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sfx2.hxx" 26 27 #include "sfx2/docmacromode.hxx" 28 #include "sfx2/signaturestate.hxx" 29 #include "sfx2/docfile.hxx" 30 31 /** === begin UNO includes === **/ 32 #include <com/sun/star/document/MacroExecMode.hpp> 33 #include <com/sun/star/task/ErrorCodeRequest.hpp> 34 #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp> 35 #include <com/sun/star/task/InteractionClassification.hpp> 36 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp> 37 /** === end UNO includes === **/ 38 39 #include <comphelper/componentcontext.hxx> 40 #include <comphelper/processfactory.hxx> 41 #include <framework/interaction.hxx> 42 #include <osl/file.hxx> 43 #include <rtl/ref.hxx> 44 #include <unotools/securityoptions.hxx> 45 #include <svtools/sfxecode.hxx> 46 #include <tools/diagnose_ex.h> 47 #include <tools/urlobj.hxx> 48 49 //........................................................................ 50 namespace sfx2 51 { 52 //........................................................................ 53 54 /** === begin UNO using === **/ 55 using ::com::sun::star::uno::Reference; 56 using ::com::sun::star::task::XInteractionHandler; 57 using ::com::sun::star::uno::Any; 58 using ::com::sun::star::task::XInteractionHandler; 59 using ::com::sun::star::uno::Sequence; 60 using ::com::sun::star::task::XInteractionContinuation; 61 using ::com::sun::star::task::XInteractionRequest; 62 using ::com::sun::star::task::DocumentMacroConfirmationRequest; 63 using ::com::sun::star::task::ErrorCodeRequest; 64 using ::com::sun::star::uno::Exception; 65 using ::com::sun::star::security::XDocumentDigitalSignatures; 66 using ::com::sun::star::security::DocumentSignatureInformation; 67 using ::com::sun::star::embed::XStorage; 68 using ::com::sun::star::task::InteractionClassification_QUERY; 69 using ::com::sun::star::document::XEmbeddedScripts; 70 using ::com::sun::star::uno::UNO_SET_THROW; 71 using ::com::sun::star::script::XLibraryContainer; 72 using ::com::sun::star::container::XNameAccess; 73 using ::com::sun::star::uno::UNO_QUERY_THROW; 74 /** === end UNO using === **/ 75 namespace MacroExecMode = ::com::sun::star::document::MacroExecMode; 76 77 //==================================================================== 78 //= DocumentMacroMode_Data 79 //==================================================================== 80 struct DocumentMacroMode_Data 81 { 82 IMacroDocumentAccess& m_rDocumentAccess; 83 sal_Bool m_bMacroDisabledMessageShown; 84 sal_Bool m_bDocMacroDisabledMessageShown; 85 DocumentMacroMode_Datasfx2::DocumentMacroMode_Data86 DocumentMacroMode_Data( IMacroDocumentAccess& rDocumentAccess ) 87 :m_rDocumentAccess( rDocumentAccess ) 88 ,m_bMacroDisabledMessageShown( sal_False ) 89 ,m_bDocMacroDisabledMessageShown( sal_False ) 90 { 91 } 92 }; 93 94 //==================================================================== 95 //= helper 96 //==================================================================== 97 namespace 98 { 99 //................................................................ lcl_showGeneralSfxErrorOnce(const Reference<XInteractionHandler> & rxHandler,const sal_Int32 nSfxErrorCode,sal_Bool & rbAlreadyShown)100 void lcl_showGeneralSfxErrorOnce( const Reference< XInteractionHandler >& rxHandler, const sal_Int32 nSfxErrorCode, sal_Bool& rbAlreadyShown ) 101 { 102 if ( rbAlreadyShown ) 103 return; 104 105 ErrorCodeRequest aErrorCodeRequest; 106 aErrorCodeRequest.ErrCode = nSfxErrorCode; 107 108 SfxMedium::CallApproveHandler( rxHandler, makeAny( aErrorCodeRequest ), sal_False ); 109 rbAlreadyShown = sal_True; 110 } 111 112 //................................................................ lcl_showMacrosDisabledError(const Reference<XInteractionHandler> & rxHandler,sal_Bool & rbAlreadyShown)113 void lcl_showMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown ) 114 { 115 lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_MACROS_SUPPORT_DISABLED, rbAlreadyShown ); 116 } 117 118 //................................................................ lcl_showDocumentMacrosDisabledError(const Reference<XInteractionHandler> & rxHandler,sal_Bool & rbAlreadyShown)119 void lcl_showDocumentMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown ) 120 { 121 lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_DOCUMENT_MACRO_DISABLED, rbAlreadyShown ); 122 } 123 124 //................................................................ lcl_showMacroWarning(const Reference<XInteractionHandler> & rxHandler,const::rtl::OUString & rDocumentLocation)125 sal_Bool lcl_showMacroWarning( const Reference< XInteractionHandler >& rxHandler, 126 const ::rtl::OUString& rDocumentLocation ) 127 { 128 DocumentMacroConfirmationRequest aRequest; 129 aRequest.DocumentURL = rDocumentLocation; 130 return SfxMedium::CallApproveHandler( rxHandler, makeAny( aRequest ), sal_True ); 131 } 132 } 133 134 //==================================================================== 135 //= DocumentMacroMode 136 //==================================================================== 137 //-------------------------------------------------------------------- DocumentMacroMode(IMacroDocumentAccess & rDocumentAccess)138 DocumentMacroMode::DocumentMacroMode( IMacroDocumentAccess& rDocumentAccess ) 139 :m_pData( new DocumentMacroMode_Data( rDocumentAccess ) ) 140 { 141 } 142 143 //-------------------------------------------------------------------- ~DocumentMacroMode()144 DocumentMacroMode::~DocumentMacroMode() 145 { 146 } 147 148 //-------------------------------------------------------------------- allowMacroExecution()149 sal_Bool DocumentMacroMode::allowMacroExecution() 150 { 151 m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::ALWAYS_EXECUTE_NO_WARN ); 152 return sal_True; 153 } 154 155 //-------------------------------------------------------------------- disallowMacroExecution()156 sal_Bool DocumentMacroMode::disallowMacroExecution() 157 { 158 m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::NEVER_EXECUTE ); 159 return sal_False; 160 } 161 162 //-------------------------------------------------------------------- adjustMacroMode(const Reference<XInteractionHandler> & rxInteraction)163 sal_Bool DocumentMacroMode::adjustMacroMode( const Reference< XInteractionHandler >& rxInteraction ) 164 { 165 sal_uInt16 nMacroExecutionMode = m_pData->m_rDocumentAccess.getCurrentMacroExecMode(); 166 167 if ( SvtSecurityOptions().IsMacroDisabled() ) 168 { 169 // no macro should be executed at all 170 lcl_showMacrosDisabledError( rxInteraction, m_pData->m_bMacroDisabledMessageShown ); 171 return disallowMacroExecution(); 172 } 173 174 // get setting from configuration if required 175 enum AutoConfirmation 176 { 177 eNoAutoConfirm, 178 eAutoConfirmApprove, 179 eAutoConfirmReject 180 }; 181 AutoConfirmation eAutoConfirm( eNoAutoConfirm ); 182 183 if ( ( nMacroExecutionMode == MacroExecMode::USE_CONFIG ) 184 || ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION ) 185 || ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION ) 186 ) 187 { 188 SvtSecurityOptions aOpt; 189 switch ( aOpt.GetMacroSecurityLevel() ) 190 { 191 case 3: 192 nMacroExecutionMode = MacroExecMode::FROM_LIST_NO_WARN; 193 break; 194 case 2: 195 nMacroExecutionMode = MacroExecMode::FROM_LIST_AND_SIGNED_WARN; 196 break; 197 case 1: 198 nMacroExecutionMode = MacroExecMode::ALWAYS_EXECUTE; 199 break; 200 case 0: 201 nMacroExecutionMode = MacroExecMode::ALWAYS_EXECUTE_NO_WARN; 202 break; 203 default: 204 OSL_ENSURE( sal_False, "DocumentMacroMode::adjustMacroMode: unexpected macro security level!" ); 205 nMacroExecutionMode = MacroExecMode::NEVER_EXECUTE; 206 } 207 208 if ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION ) 209 eAutoConfirm = eAutoConfirmReject; 210 else if ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION ) 211 eAutoConfirm = eAutoConfirmApprove; 212 } 213 214 if ( nMacroExecutionMode == MacroExecMode::NEVER_EXECUTE ) 215 return sal_False; 216 217 if ( nMacroExecutionMode == MacroExecMode::ALWAYS_EXECUTE_NO_WARN ) 218 return sal_True; 219 220 try 221 { 222 ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() ); 223 224 // get document location from medium name and check whether it is a trusted one 225 // the service is created ohne document version, since it is not of interest here 226 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); 227 Reference< XDocumentDigitalSignatures > xSignatures; 228 if ( aContext.createComponent( "com.sun.star.security.DocumentDigitalSignatures", xSignatures ) ) 229 { 230 INetURLObject aURLReferer( sReferrer ); 231 232 ::rtl::OUString aLocation; 233 if ( aURLReferer.removeSegment() ) 234 aLocation = aURLReferer.GetMainURL( INetURLObject::NO_DECODE ); 235 236 if ( aLocation.getLength() && xSignatures->isLocationTrusted( aLocation ) ) 237 { 238 return allowMacroExecution(); 239 } 240 } 241 242 // at this point it is clear that the document is not in the secure location 243 if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN ) 244 { 245 lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown ); 246 return disallowMacroExecution(); 247 } 248 249 // check whether the document is signed with trusted certificate 250 if ( nMacroExecutionMode != MacroExecMode::FROM_LIST ) 251 { 252 // the trusted macro check will also retrieve the signature state ( small optimization ) 253 sal_Bool bHasTrustedMacroSignature = m_pData->m_rDocumentAccess.hasTrustedScriptingSignature( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN ); 254 255 sal_uInt16 nSignatureState = m_pData->m_rDocumentAccess.getScriptingSignatureState(); 256 if ( nSignatureState == SIGNATURESTATE_SIGNATURES_BROKEN ) 257 { 258 // the signature is broken, no macro execution 259 if ( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN ) 260 m_pData->m_rDocumentAccess.showBrokenSignatureWarning( rxInteraction ); 261 262 return disallowMacroExecution(); 263 } 264 else if ( bHasTrustedMacroSignature ) 265 { 266 // there is trusted macro signature, allow macro execution 267 return allowMacroExecution(); 268 } 269 else if ( nSignatureState == SIGNATURESTATE_SIGNATURES_OK 270 || nSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) 271 { 272 // there is valid signature, but it is not from the trusted author 273 return disallowMacroExecution(); 274 } 275 } 276 277 // at this point it is clear that the document is neither in secure location nor signed with trusted certificate 278 if ( ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN ) 279 || ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN ) 280 ) 281 { 282 if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN ) 283 lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown ); 284 285 return disallowMacroExecution(); 286 } 287 } 288 catch ( Exception& ) 289 { 290 if ( ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN ) 291 || ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN ) 292 || ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN ) 293 ) 294 { 295 return disallowMacroExecution(); 296 } 297 } 298 299 // conformation is required 300 sal_Bool bSecure = sal_False; 301 302 if ( eAutoConfirm == eNoAutoConfirm ) 303 { 304 ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() ); 305 306 ::rtl::OUString aSystemFileURL; 307 if ( osl::FileBase::getSystemPathFromFileURL( sReferrer, aSystemFileURL ) == osl::FileBase::E_None ) 308 sReferrer = aSystemFileURL; 309 310 bSecure = lcl_showMacroWarning( rxInteraction, sReferrer ); 311 } 312 else 313 bSecure = ( eAutoConfirm == eAutoConfirmApprove ); 314 315 return ( bSecure ? allowMacroExecution() : disallowMacroExecution() ); 316 } 317 318 //-------------------------------------------------------------------- isMacroExecutionDisallowed() const319 sal_Bool DocumentMacroMode::isMacroExecutionDisallowed() const 320 { 321 return m_pData->m_rDocumentAccess.getCurrentMacroExecMode() == MacroExecMode::NEVER_EXECUTE; 322 } 323 324 //-------------------------------------------------------------------- hasMacroLibrary() const325 sal_Bool DocumentMacroMode::hasMacroLibrary() const 326 { 327 sal_Bool bHasMacroLib = sal_False; 328 try 329 { 330 Reference< XEmbeddedScripts > xScripts( m_pData->m_rDocumentAccess.getEmbeddedDocumentScripts() ); 331 Reference< XLibraryContainer > xContainer; 332 if ( xScripts.is() ) 333 xContainer.set( xScripts->getBasicLibraries(), UNO_QUERY_THROW ); 334 335 if ( xContainer.is() ) 336 { 337 // a library container exists; check if it's empty 338 339 // if there are libraries except the "Standard" library 340 // we assume that they are not empty (because they have been created by the user) 341 if ( !xContainer->hasElements() ) 342 bHasMacroLib = sal_False; 343 else 344 { 345 ::rtl::OUString aStdLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); 346 Sequence< ::rtl::OUString > aElements = xContainer->getElementNames(); 347 if ( aElements.getLength() ) 348 { 349 if ( aElements.getLength() > 1 || !aElements[0].equals( aStdLibName ) ) 350 bHasMacroLib = sal_True; 351 else 352 { 353 // usually a "Standard" library is always present (design) 354 // for this reason we must check if it's empty 355 // 356 // Note: Since #i73229#, this is not true anymore. There's no default 357 // "Standard" lib anymore. Wouldn't it be time to get completely 358 // rid of the "Standard" thingie - this shouldn't be necessary 359 // anymore, should it? 360 // 2007-01-25 / frank.schoenheit@sun.com 361 Reference < XNameAccess > xLib; 362 Any aAny = xContainer->getByName( aStdLibName ); 363 aAny >>= xLib; 364 if ( xLib.is() ) 365 bHasMacroLib = xLib->hasElements(); 366 } 367 } 368 } 369 } 370 } 371 catch( const Exception& ) 372 { 373 DBG_UNHANDLED_EXCEPTION(); 374 } 375 376 return bHasMacroLib; 377 } 378 379 //-------------------------------------------------------------------- storageHasMacros(const Reference<XStorage> & rxStorage)380 sal_Bool DocumentMacroMode::storageHasMacros( const Reference< XStorage >& rxStorage ) 381 { 382 sal_Bool bHasMacros = sal_False; 383 if ( rxStorage.is() ) 384 { 385 try 386 { 387 static const ::rtl::OUString s_sBasicStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ) ); 388 static const ::rtl::OUString s_sScriptsStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Scripts" ) ) ); 389 390 bHasMacros =( ( rxStorage->hasByName( s_sBasicStorageName ) 391 && rxStorage->isStorageElement( s_sBasicStorageName ) 392 ) 393 || ( rxStorage->hasByName( s_sScriptsStorageName ) 394 && rxStorage->isStorageElement( s_sScriptsStorageName ) 395 ) 396 ); 397 } 398 catch ( const Exception& ) 399 { 400 DBG_UNHANDLED_EXCEPTION(); 401 } 402 } 403 return bHasMacros; 404 } 405 406 //-------------------------------------------------------------------- checkMacrosOnLoading(const Reference<XInteractionHandler> & rxInteraction)407 sal_Bool DocumentMacroMode::checkMacrosOnLoading( const Reference< XInteractionHandler >& rxInteraction ) 408 { 409 sal_Bool bAllow = sal_False; 410 if ( SvtSecurityOptions().IsMacroDisabled() ) 411 { 412 // no macro should be executed at all 413 bAllow = disallowMacroExecution(); 414 } 415 else 416 { 417 if ( m_pData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() ) 418 { 419 bAllow = adjustMacroMode( rxInteraction ); 420 } 421 else if ( !isMacroExecutionDisallowed() ) 422 { 423 // if macros will be added by the user later, the security check is obsolete 424 bAllow = allowMacroExecution(); 425 } 426 } 427 return bAllow; 428 } 429 430 //........................................................................ 431 } // namespace sfx2 432 //........................................................................ 433