LCOV - code coverage report
Current view: top level - libreoffice/sfx2/source/doc - docmacromode.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 63 142 44.4 %
Date: 2012-12-17 Functions: 9 14 64.3 %
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             : 
      21             : #include "sfx2/docmacromode.hxx"
      22             : #include "sfx2/signaturestate.hxx"
      23             : #include "sfx2/docfile.hxx"
      24             : 
      25             : #include <com/sun/star/document/MacroExecMode.hpp>
      26             : #include <com/sun/star/task/ErrorCodeRequest.hpp>
      27             : #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
      28             : #include <com/sun/star/task/InteractionClassification.hpp>
      29             : #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
      30             : #include <com/sun/star/script/XLibraryQueryExecutable.hpp>
      31             : 
      32             : #include <comphelper/componentcontext.hxx>
      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             :     /** === begin UNO using === **/
      48             :     using ::com::sun::star::uno::Reference;
      49             :     using ::com::sun::star::task::XInteractionHandler;
      50             :     using ::com::sun::star::uno::Any;
      51             :     using ::com::sun::star::task::XInteractionHandler;
      52             :     using ::com::sun::star::uno::Sequence;
      53             :     using ::com::sun::star::task::XInteractionContinuation;
      54             :     using ::com::sun::star::task::XInteractionRequest;
      55             :     using ::com::sun::star::task::DocumentMacroConfirmationRequest;
      56             :     using ::com::sun::star::task::ErrorCodeRequest;
      57             :     using ::com::sun::star::uno::Exception;
      58             :     using ::com::sun::star::security::DocumentDigitalSignatures;
      59             :     using ::com::sun::star::security::XDocumentDigitalSignatures;
      60             :     using ::com::sun::star::security::DocumentSignatureInformation;
      61             :     using ::com::sun::star::embed::XStorage;
      62             :     using ::com::sun::star::task::InteractionClassification_QUERY;
      63             :     using ::com::sun::star::document::XEmbeddedScripts;
      64             :     using ::com::sun::star::uno::UNO_SET_THROW;
      65             :     using ::com::sun::star::script::XLibraryContainer;
      66             :     using ::com::sun::star::script::XLibraryQueryExecutable;
      67             :     using ::com::sun::star::container::XNameAccess;
      68             :     using ::com::sun::star::uno::UNO_QUERY_THROW;
      69             :     using ::com::sun::star::uno::UNO_QUERY;
      70             :     /** === end UNO using === **/
      71             :     namespace MacroExecMode = ::com::sun::star::document::MacroExecMode;
      72             : 
      73             :     //====================================================================
      74             :     //= DocumentMacroMode_Data
      75             :     //====================================================================
      76             :     struct DocumentMacroMode_Data
      77             :     {
      78             :         IMacroDocumentAccess&       m_rDocumentAccess;
      79             :         sal_Bool                    m_bMacroDisabledMessageShown;
      80             :         sal_Bool                    m_bDocMacroDisabledMessageShown;
      81             : 
      82        1510 :         DocumentMacroMode_Data( IMacroDocumentAccess& rDocumentAccess )
      83             :             :m_rDocumentAccess( rDocumentAccess )
      84             :             ,m_bMacroDisabledMessageShown( sal_False )
      85        1510 :             ,m_bDocMacroDisabledMessageShown( sal_False )
      86             :         {
      87        1510 :         }
      88             :     };
      89             : 
      90             :     //====================================================================
      91             :     //= helper
      92             :     //====================================================================
      93             :     namespace
      94             :     {
      95             :         //................................................................
      96           0 :         void lcl_showGeneralSfxErrorOnce( const Reference< XInteractionHandler >& rxHandler, const sal_Int32 nSfxErrorCode, sal_Bool& rbAlreadyShown )
      97             :         {
      98           0 :             if ( rbAlreadyShown )
      99           0 :                 return;
     100             : 
     101           0 :             ErrorCodeRequest aErrorCodeRequest;
     102           0 :             aErrorCodeRequest.ErrCode = nSfxErrorCode;
     103             : 
     104           0 :             SfxMedium::CallApproveHandler( rxHandler, makeAny( aErrorCodeRequest ), sal_False );
     105           0 :             rbAlreadyShown = sal_True;
     106             :         }
     107             : 
     108             :         //................................................................
     109           0 :         void lcl_showMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown )
     110             :         {
     111           0 :             lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_MACROS_SUPPORT_DISABLED, rbAlreadyShown );
     112           0 :         }
     113             : 
     114             :         //................................................................
     115           0 :         void lcl_showDocumentMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown )
     116             :         {
     117             : #ifdef MACOSX
     118             :             lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_DOCUMENT_MACRO_DISABLED_MAC, rbAlreadyShown );
     119             : #else
     120           0 :             lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_DOCUMENT_MACRO_DISABLED, rbAlreadyShown );
     121             : #endif
     122           0 :         }
     123             : 
     124             :         //................................................................
     125           0 :         sal_Bool lcl_showMacroWarning( const Reference< XInteractionHandler >& rxHandler,
     126             :             const ::rtl::OUString& rDocumentLocation )
     127             :         {
     128           0 :             DocumentMacroConfirmationRequest aRequest;
     129           0 :             aRequest.DocumentURL = rDocumentLocation;
     130           0 :             return SfxMedium::CallApproveHandler( rxHandler, makeAny( aRequest ), sal_True );
     131             :         }
     132             :     }
     133             : 
     134             :     //====================================================================
     135             :     //= DocumentMacroMode
     136             :     //====================================================================
     137             :     //--------------------------------------------------------------------
     138        1510 :     DocumentMacroMode::DocumentMacroMode( IMacroDocumentAccess& rDocumentAccess )
     139        1510 :         :m_pData( new DocumentMacroMode_Data( rDocumentAccess ) )
     140             :     {
     141        1510 :     }
     142             : 
     143             :     //--------------------------------------------------------------------
     144         794 :     DocumentMacroMode::~DocumentMacroMode()
     145             :     {
     146         794 :     }
     147             : 
     148             :     //--------------------------------------------------------------------
     149        1325 :     sal_Bool DocumentMacroMode::allowMacroExecution()
     150             :     {
     151        1325 :         m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::ALWAYS_EXECUTE_NO_WARN );
     152        1325 :         return sal_True;
     153             :     }
     154             : 
     155             :     //--------------------------------------------------------------------
     156           0 :     sal_Bool DocumentMacroMode::disallowMacroExecution()
     157             :     {
     158           0 :         m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::NEVER_EXECUTE );
     159           0 :         return sal_False;
     160             :     }
     161             : 
     162             :     //--------------------------------------------------------------------
     163          32 :     sal_Bool DocumentMacroMode::adjustMacroMode( const Reference< XInteractionHandler >& rxInteraction )
     164             :     {
     165          32 :         sal_uInt16 nMacroExecutionMode = m_pData->m_rDocumentAccess.getCurrentMacroExecMode();
     166             : 
     167          32 :         if ( SvtSecurityOptions().IsMacroDisabled() )
     168             :         {
     169             :             // no macro should be executed at all
     170           0 :             lcl_showMacrosDisabledError( rxInteraction, m_pData->m_bMacroDisabledMessageShown );
     171           0 :             return disallowMacroExecution();
     172             :         }
     173             : 
     174             :         // get setting from configuration if required
     175             :         enum AutoConfirmation
     176             :         {
     177             :             eNoAutoConfirm,
     178             :             eAutoConfirmApprove,
     179             :             eAutoConfirmReject
     180             :         };
     181          32 :         AutoConfirmation eAutoConfirm( eNoAutoConfirm );
     182             : 
     183          32 :         if  (   ( nMacroExecutionMode == MacroExecMode::USE_CONFIG )
     184             :             ||  ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION )
     185             :             ||  ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION )
     186             :             )
     187             :         {
     188           0 :             SvtSecurityOptions aOpt;
     189           0 :             switch ( aOpt.GetMacroSecurityLevel() )
     190             :             {
     191             :                 case 3:
     192           0 :                     nMacroExecutionMode = MacroExecMode::FROM_LIST_NO_WARN;
     193           0 :                     break;
     194             :                 case 2:
     195           0 :                     nMacroExecutionMode = MacroExecMode::FROM_LIST_AND_SIGNED_WARN;
     196           0 :                     break;
     197             :                 case 1:
     198           0 :                     nMacroExecutionMode = MacroExecMode::ALWAYS_EXECUTE;
     199           0 :                     break;
     200             :                 case 0:
     201           0 :                     nMacroExecutionMode = MacroExecMode::ALWAYS_EXECUTE_NO_WARN;
     202           0 :                     break;
     203             :                 default:
     204             :                     OSL_FAIL( "DocumentMacroMode::adjustMacroMode: unexpected macro security level!" );
     205           0 :                     nMacroExecutionMode = MacroExecMode::NEVER_EXECUTE;
     206             :             }
     207             : 
     208           0 :             if ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION )
     209           0 :                 eAutoConfirm = eAutoConfirmReject;
     210           0 :             else if ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION )
     211           0 :                 eAutoConfirm = eAutoConfirmApprove;
     212             :         }
     213             : 
     214          32 :         if ( nMacroExecutionMode == MacroExecMode::NEVER_EXECUTE )
     215           8 :             return sal_False;
     216             : 
     217          24 :         if ( nMacroExecutionMode == MacroExecMode::ALWAYS_EXECUTE_NO_WARN )
     218          24 :             return sal_True;
     219             : 
     220             :         try
     221             :         {
     222           0 :             ::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           0 :             Reference< XDocumentDigitalSignatures > xSignatures(DocumentDigitalSignatures::createDefault(::comphelper::getProcessComponentContext()));
     227           0 :             INetURLObject aURLReferer( sReferrer );
     228             : 
     229           0 :             ::rtl::OUString aLocation;
     230           0 :             if ( aURLReferer.removeSegment() )
     231           0 :                 aLocation = aURLReferer.GetMainURL( INetURLObject::NO_DECODE );
     232             : 
     233           0 :             if ( !aLocation.isEmpty() && xSignatures->isLocationTrusted( aLocation ) )
     234             :             {
     235           0 :                 return allowMacroExecution();
     236             :             }
     237             : 
     238             :             // at this point it is clear that the document is not in the secure location
     239           0 :             if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN )
     240             :             {
     241           0 :                 lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown );
     242           0 :                 return disallowMacroExecution();
     243             :             }
     244             : 
     245             :             // check whether the document is signed with trusted certificate
     246           0 :             if ( nMacroExecutionMode != MacroExecMode::FROM_LIST )
     247             :             {
     248             :                 // the trusted macro check will also retrieve the signature state ( small optimization )
     249           0 :                 sal_Bool bHasTrustedMacroSignature = m_pData->m_rDocumentAccess.hasTrustedScriptingSignature( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN );
     250             : 
     251           0 :                 sal_uInt16 nSignatureState = m_pData->m_rDocumentAccess.getScriptingSignatureState();
     252           0 :                 if ( nSignatureState == SIGNATURESTATE_SIGNATURES_BROKEN )
     253             :                 {
     254             :                     // the signature is broken, no macro execution
     255           0 :                     if ( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN )
     256           0 :                         m_pData->m_rDocumentAccess.showBrokenSignatureWarning( rxInteraction );
     257             : 
     258           0 :                     return disallowMacroExecution();
     259             :                 }
     260           0 :                 else if ( bHasTrustedMacroSignature )
     261             :                 {
     262             :                     // there is trusted macro signature, allow macro execution
     263           0 :                     return allowMacroExecution();
     264             :                 }
     265           0 :                 else if ( nSignatureState == SIGNATURESTATE_SIGNATURES_OK
     266             :                        || nSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED )
     267             :                 {
     268             :                     // there is valid signature, but it is not from the trusted author
     269           0 :                     return disallowMacroExecution();
     270             :                 }
     271             :             }
     272             : 
     273             :             // at this point it is clear that the document is neither in secure location nor signed with trusted certificate
     274           0 :             if  (   ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN )
     275             :                 ||  ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN )
     276             :                 )
     277             :             {
     278           0 :                 if  ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN )
     279           0 :                     lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown );
     280             : 
     281           0 :                 return disallowMacroExecution();
     282           0 :             }
     283             :         }
     284           0 :         catch ( const Exception& )
     285             :         {
     286           0 :             if  (   ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN )
     287             :                 ||  ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN )
     288             :                 ||  ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN )
     289             :                 )
     290             :             {
     291           0 :                 return disallowMacroExecution();
     292             :             }
     293             :         }
     294             : 
     295             :         // conformation is required
     296           0 :         sal_Bool bSecure = sal_False;
     297             : 
     298           0 :         if ( eAutoConfirm == eNoAutoConfirm )
     299             :         {
     300           0 :             ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() );
     301             : 
     302           0 :             ::rtl::OUString aSystemFileURL;
     303           0 :             if ( osl::FileBase::getSystemPathFromFileURL( sReferrer, aSystemFileURL ) == osl::FileBase::E_None )
     304           0 :                 sReferrer = aSystemFileURL;
     305             : 
     306           0 :             bSecure = lcl_showMacroWarning( rxInteraction, sReferrer );
     307             :         }
     308             :         else
     309           0 :             bSecure = ( eAutoConfirm == eAutoConfirmApprove );
     310             : 
     311           0 :         return ( bSecure ? allowMacroExecution() : disallowMacroExecution() );
     312             :     }
     313             : 
     314             :     //--------------------------------------------------------------------
     315        1203 :     sal_Bool DocumentMacroMode::isMacroExecutionDisallowed() const
     316             :     {
     317        1203 :         return m_pData->m_rDocumentAccess.getCurrentMacroExecMode() == MacroExecMode::NEVER_EXECUTE;
     318             :     }
     319             : 
     320             :     //--------------------------------------------------------------------
     321        1217 :     sal_Bool DocumentMacroMode::hasMacroLibrary() const
     322             :     {
     323        1217 :         sal_Bool bHasMacroLib = sal_False;
     324             : #ifndef DISABLE_SCRIPTING
     325             :         try
     326             :         {
     327        1217 :             Reference< XEmbeddedScripts > xScripts( m_pData->m_rDocumentAccess.getEmbeddedDocumentScripts() );
     328        1217 :             Reference< XLibraryContainer > xContainer;
     329        1217 :             if ( xScripts.is() )
     330        1209 :                 xContainer.set( xScripts->getBasicLibraries(), UNO_QUERY_THROW );
     331             : 
     332         807 :             if ( xContainer.is() )
     333             :             {
     334             :                 // a library container exists; check if it's empty
     335             : 
     336             :                 // if there are libraries except the "Standard" library
     337             :                 // we assume that they are not empty (because they have been created by the user)
     338         799 :                 if ( !xContainer->hasElements() )
     339         385 :                     bHasMacroLib = sal_False;
     340             :                 else
     341             :                 {
     342         414 :                     ::rtl::OUString aStdLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
     343         414 :                     Sequence< ::rtl::OUString > aElements = xContainer->getElementNames();
     344         414 :                     if ( aElements.getLength() )
     345             :                     {
     346         414 :                         if ( aElements.getLength() > 1 || !aElements[0].equals( aStdLibName ) )
     347          14 :                             bHasMacroLib = sal_True;
     348             :                         else
     349             :                         {
     350             :                             // usually a "Standard" library is always present (design)
     351             :                             // for this reason we must check if it's empty
     352             :                             //
     353             :                             // Note: Since #i73229#, this is not true anymore. There's no default
     354             :                             // "Standard" lib anymore. Wouldn't it be time to get completely
     355             :                             // rid of the "Standard" thingie - this shouldn't be necessary
     356             :                             // anymore, should it?
     357         400 :                             Reference < XNameAccess > xLib;
     358         400 :                             Any aAny = xContainer->getByName( aStdLibName );
     359         400 :                             aAny >>= xLib;
     360         400 :                             if ( xLib.is() )
     361         400 :                                 bHasMacroLib = xLib->hasElements();
     362             :                         }
     363         414 :                     }
     364             :                 }
     365        1217 :             }
     366             :         }
     367         410 :         catch( const Exception& )
     368             :         {
     369             :             DBG_UNHANDLED_EXCEPTION();
     370             :         }
     371             : #endif
     372        1217 :         return bHasMacroLib;
     373             :     }
     374             : 
     375             :     //--------------------------------------------------------------------
     376        1227 :     sal_Bool DocumentMacroMode::storageHasMacros( const Reference< XStorage >& rxStorage )
     377             :     {
     378        1227 :         sal_Bool bHasMacros = sal_False;
     379        1227 :         if ( rxStorage.is() )
     380             :         {
     381             :             try
     382             :             {
     383         895 :                 const ::rtl::OUString s_sBasicStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ) );
     384         895 :                 const ::rtl::OUString s_sScriptsStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Scripts" ) ) );
     385             : 
     386         895 :                 bHasMacros =(   (   rxStorage->hasByName( s_sBasicStorageName )
     387          10 :                                 &&  rxStorage->isStorageElement( s_sBasicStorageName )
     388             :                                 )
     389         885 :                             ||  (   rxStorage->hasByName( s_sScriptsStorageName )
     390           0 :                                 &&  rxStorage->isStorageElement( s_sScriptsStorageName )
     391             :                                 )
     392        1790 :                             );
     393             :             }
     394           0 :             catch ( const Exception& )
     395             :             {
     396             :                 DBG_UNHANDLED_EXCEPTION();
     397             :             }
     398             :         }
     399        1227 :         return bHasMacros;
     400             :     }
     401             : 
     402             :     //--------------------------------------------------------------------
     403        1227 :     sal_Bool DocumentMacroMode::checkMacrosOnLoading( const Reference< XInteractionHandler >& rxInteraction )
     404             :     {
     405        1227 :         sal_Bool bAllow = sal_False;
     406        1227 :         if ( SvtSecurityOptions().IsMacroDisabled() )
     407             :         {
     408             :             // no macro should be executed at all
     409           0 :             bAllow = disallowMacroExecution();
     410             :         }
     411             :         else
     412             :         {
     413        1227 :             if ( m_pData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() )
     414             :             {
     415          24 :                 bAllow = adjustMacroMode( rxInteraction );
     416             :             }
     417        1203 :             else if ( !isMacroExecutionDisallowed() )
     418             :             {
     419             :                 // if macros will be added by the user later, the security check is obsolete
     420        1000 :                 bAllow = allowMacroExecution();
     421             :             }
     422             :         }
     423        1227 :         return bAllow;
     424             :     }
     425             : 
     426             : //........................................................................
     427             : } // namespace sfx2
     428             : //........................................................................
     429             : 
     430             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10