LCOV - code coverage report
Current view: top level - sfx2/source/doc - docmacromode.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 73 158 46.2 %
Date: 2015-06-13 12:38:46 Functions: 10 15 66.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11