/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"

#include "sfx2/docmacromode.hxx"
#include "sfx2/signaturestate.hxx"
#include "sfx2/docfile.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/task/ErrorCodeRequest.hpp>
#include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
#include <com/sun/star/task/InteractionClassification.hpp>
#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
/** === end UNO includes === **/

#include <comphelper/componentcontext.hxx>
#include <comphelper/processfactory.hxx>
#include <framework/interaction.hxx>
#include <osl/file.hxx>
#include <rtl/ref.hxx>
#include <unotools/securityoptions.hxx>
#include <svtools/sfxecode.hxx>
#include <tools/diagnose_ex.h>
#include <tools/urlobj.hxx>

//........................................................................
namespace sfx2
{
//........................................................................

	/** === begin UNO using === **/
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::task::XInteractionHandler;
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::task::XInteractionHandler;
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::task::XInteractionContinuation;
    using ::com::sun::star::task::XInteractionRequest;
    using ::com::sun::star::task::DocumentMacroConfirmationRequest;
    using ::com::sun::star::task::ErrorCodeRequest;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::security::XDocumentDigitalSignatures;
    using ::com::sun::star::security::DocumentSignatureInformation;
    using ::com::sun::star::embed::XStorage;
    using ::com::sun::star::task::InteractionClassification_QUERY;
    using ::com::sun::star::document::XEmbeddedScripts;
    using ::com::sun::star::uno::UNO_SET_THROW;
    using ::com::sun::star::script::XLibraryContainer;
    using ::com::sun::star::container::XNameAccess;
    using ::com::sun::star::uno::UNO_QUERY_THROW;
	/** === end UNO using === **/
    namespace MacroExecMode = ::com::sun::star::document::MacroExecMode;

	//====================================================================
	//= DocumentMacroMode_Data
	//====================================================================
    struct DocumentMacroMode_Data
    {
        IMacroDocumentAccess&       m_rDocumentAccess;
        sal_Bool                    m_bMacroDisabledMessageShown;
        sal_Bool                    m_bDocMacroDisabledMessageShown;

        DocumentMacroMode_Data( IMacroDocumentAccess& rDocumentAccess )
            :m_rDocumentAccess( rDocumentAccess )
            ,m_bMacroDisabledMessageShown( sal_False )
            ,m_bDocMacroDisabledMessageShown( sal_False )
        {
        }
    };

	//====================================================================
	//= helper
	//====================================================================
    namespace
    {
        //................................................................
        void lcl_showGeneralSfxErrorOnce( const Reference< XInteractionHandler >& rxHandler, const sal_Int32 nSfxErrorCode, sal_Bool& rbAlreadyShown )
        {
            if ( rbAlreadyShown )
                return;

            ErrorCodeRequest aErrorCodeRequest;
            aErrorCodeRequest.ErrCode = nSfxErrorCode;

            SfxMedium::CallApproveHandler( rxHandler, makeAny( aErrorCodeRequest ), sal_False );
            rbAlreadyShown = sal_True;
        }

	    //................................................................
        void lcl_showMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown )
        {
            lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_MACROS_SUPPORT_DISABLED, rbAlreadyShown );
        }

        //................................................................
        void lcl_showDocumentMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown )
        {
            lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_DOCUMENT_MACRO_DISABLED, rbAlreadyShown );
        }

        //................................................................
        sal_Bool lcl_showMacroWarning( const Reference< XInteractionHandler >& rxHandler,
            const ::rtl::OUString& rDocumentLocation )
        {
            DocumentMacroConfirmationRequest aRequest;
            aRequest.DocumentURL = rDocumentLocation;
            return SfxMedium::CallApproveHandler( rxHandler, makeAny( aRequest ), sal_True );
        }
    }

	//====================================================================
	//= DocumentMacroMode
	//====================================================================
	//--------------------------------------------------------------------
    DocumentMacroMode::DocumentMacroMode( IMacroDocumentAccess& rDocumentAccess )
        :m_pData( new DocumentMacroMode_Data( rDocumentAccess ) )
    {
    }

	//--------------------------------------------------------------------
    DocumentMacroMode::~DocumentMacroMode()
    {
    }

	//--------------------------------------------------------------------
    sal_Bool DocumentMacroMode::allowMacroExecution()
    {
        m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::ALWAYS_EXECUTE_NO_WARN );
        return sal_True;
    }

	//--------------------------------------------------------------------
    sal_Bool DocumentMacroMode::disallowMacroExecution()
    {
        m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::NEVER_EXECUTE );
        return sal_False;
    }

    /** Change the indicated macro execution mode depending on the current macro security level.
     *
     * @param nMacroExecutionMode current execution mode (must be one of MacroExecMode::USE_XXX).
     *
     * Changes nMacroExecutionMode according to the current security options, if applicable.
     */
    static void adjustMacroExecModeSecurity(sal_uInt16 &nMacroExecutionMode)
    {
        if  (   ( nMacroExecutionMode == MacroExecMode::USE_CONFIG )
            ||  ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION )
            ||  ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION )
            )
        {
            SvtSecurityOptions aOpt;
            switch ( aOpt.GetMacroSecurityLevel() )
            {
                case 3:
                    nMacroExecutionMode = MacroExecMode::FROM_LIST_NO_WARN;
                    break;
                case 2:
                    nMacroExecutionMode = MacroExecMode::FROM_LIST_AND_SIGNED_WARN;
                    break;
                case 1:
                    nMacroExecutionMode = MacroExecMode::ALWAYS_EXECUTE;
                    break;
                case 0:
                    nMacroExecutionMode = MacroExecMode::ALWAYS_EXECUTE_NO_WARN;
                    break;
                default:
                    OSL_ENSURE( sal_False, "DocumentMacroMode::adjustMacroMode: unexpected macro security level!" );
                    nMacroExecutionMode = MacroExecMode::NEVER_EXECUTE;
            }

        }
    }

	//--------------------------------------------------------------------
    sal_Bool DocumentMacroMode::adjustMacroMode( const Reference< XInteractionHandler >& rxInteraction )
    {
        sal_uInt16 nMacroExecutionMode = m_pData->m_rDocumentAccess.getCurrentMacroExecMode();

        if ( SvtSecurityOptions().IsMacroDisabled() )
        {
            // no macro should be executed at all
            lcl_showMacrosDisabledError( rxInteraction, m_pData->m_bMacroDisabledMessageShown );
            return disallowMacroExecution();
        }

        // get setting from configuration if required
        enum AutoConfirmation
        {
            eNoAutoConfirm,
            eAutoConfirmApprove,
            eAutoConfirmReject
        };
        AutoConfirmation eAutoConfirm( eNoAutoConfirm );

        adjustMacroExecModeSecurity(nMacroExecutionMode);
        if ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION )
            eAutoConfirm = eAutoConfirmReject;
        else if ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION )
            eAutoConfirm = eAutoConfirmApprove;

        if ( nMacroExecutionMode == MacroExecMode::NEVER_EXECUTE )
            return sal_False;

        if ( nMacroExecutionMode == MacroExecMode::ALWAYS_EXECUTE_NO_WARN )
            return sal_True;

        try
        {
            ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() );

            // get document location from medium name and check whether it is a trusted one
            // the service is created ohne document version, since it is not of interest here
            ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
            Reference< XDocumentDigitalSignatures > xSignatures;
            if ( aContext.createComponent( "com.sun.star.security.DocumentDigitalSignatures", xSignatures ) )
            {
                INetURLObject aURLReferer( sReferrer );

                ::rtl::OUString aLocation;
                if ( aURLReferer.removeSegment() )
                    aLocation = aURLReferer.GetMainURL( INetURLObject::NO_DECODE );

                if ( aLocation.getLength() && xSignatures->isLocationTrusted( aLocation ) )
                {
                    return allowMacroExecution();
                }
            }

            // at this point it is clear that the document is not in the secure location
            if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN )
            {
                lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown );
                return disallowMacroExecution();
            }

            // check whether the document is signed with trusted certificate
            if ( nMacroExecutionMode != MacroExecMode::FROM_LIST )
            {
                // the trusted macro check will also retrieve the signature state (small optimization)
                sal_Bool bHasTrustedMacroSignature = m_pData->m_rDocumentAccess.hasTrustedScriptingSignature( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN );

                sal_uInt16 nSignatureState = m_pData->m_rDocumentAccess.getScriptingSignatureState();
                if ( nSignatureState == SIGNATURESTATE_SIGNATURES_BROKEN )
                {
                    // the signature is broken, no macro execution
                    if ( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN )
                        m_pData->m_rDocumentAccess.showBrokenSignatureWarning( rxInteraction );

                    return disallowMacroExecution();
                }
                else if ( bHasTrustedMacroSignature )
                {
                    // there is trusted macro signature, allow macro execution
                    return allowMacroExecution();
                }
                else if ( nSignatureState == SIGNATURESTATE_SIGNATURES_OK
                       || nSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED )
                {
                    // there is valid signature, but it is not from the trusted author
                    return disallowMacroExecution();
                }
            }

            // 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 )
                )
            {
                if  ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN )
                    lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown );

                return disallowMacroExecution();
            }
        }
        catch ( Exception& )
        {
            if  (   ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN )
                ||  ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN )
                ||  ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN )
                )
            {
                return disallowMacroExecution();
            }
        }

        // confirmation is required
        sal_Bool bSecure = sal_False;

        if ( eAutoConfirm == eNoAutoConfirm )
        {
            ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() );

            ::rtl::OUString aSystemFileURL;
            if ( osl::FileBase::getSystemPathFromFileURL( sReferrer, aSystemFileURL ) == osl::FileBase::E_None )
                sReferrer = aSystemFileURL;

            bSecure = lcl_showMacroWarning( rxInteraction, sReferrer );
        }
        else
            bSecure = ( eAutoConfirm == eAutoConfirmApprove );

        return ( bSecure ? allowMacroExecution() : disallowMacroExecution() );
    }

	//--------------------------------------------------------------------
    sal_Bool DocumentMacroMode::isMacroExecutionDisallowed() const
    {
        return m_pData->m_rDocumentAccess.getCurrentMacroExecMode() == MacroExecMode::NEVER_EXECUTE;
    }

    //--------------------------------------------------------------------
    sal_Bool DocumentMacroMode::hasMacroLibrary() const
    {
        sal_Bool bHasMacroLib = sal_False;
        try
        {
            Reference< XEmbeddedScripts > xScripts( m_pData->m_rDocumentAccess.getEmbeddedDocumentScripts() );
            Reference< XLibraryContainer > xContainer;
            if ( xScripts.is() )
                xContainer.set( xScripts->getBasicLibraries(), UNO_QUERY_THROW );

            if ( xContainer.is() )
            {
                // a library container exists; check if it's empty

			    // if there are libraries except the "Standard" library
			    // we assume that they are not empty (because they have been created by the user)
			    if ( !xContainer->hasElements() )
                    bHasMacroLib = sal_False;
                else
			    {
				    ::rtl::OUString aStdLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
				    Sequence< ::rtl::OUString > aElements = xContainer->getElementNames();
				    if ( aElements.getLength() )
				    {
					    if ( aElements.getLength() > 1 || !aElements[0].equals( aStdLibName ) )
						    bHasMacroLib = sal_True;
					    else
					    {
						    // usually a "Standard" library is always present (design)
						    // for this reason we must check if it's empty
                            //
                            // Note: Since #i73229#, this is not true anymore. There's no default
                            // "Standard" lib anymore. Wouldn't it be time to get completely
                            // rid of the "Standard" thingie - this shouldn't be necessary
                            // anymore, should it?
                            // 2007-01-25 / frank.schoenheit@sun.com
						    Reference < XNameAccess > xLib;
						    Any aAny = xContainer->getByName( aStdLibName );
						    aAny >>= xLib;
						    if ( xLib.is() )
							    bHasMacroLib = xLib->hasElements();
					    }
				    }
			    }
		    }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }

        return bHasMacroLib;
    }

	//--------------------------------------------------------------------
    sal_Bool DocumentMacroMode::storageHasMacros( const Reference< XStorage >& rxStorage )
    {
	    sal_Bool bHasMacros = sal_False;
	    if ( rxStorage.is() )
	    {
		    try
		    {
                static const ::rtl::OUString s_sBasicStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ) );
                static const ::rtl::OUString s_sScriptsStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Scripts" ) ) );

                bHasMacros =(   (   rxStorage->hasByName( s_sBasicStorageName )
                                &&  rxStorage->isStorageElement( s_sBasicStorageName )
                                )
                            ||  (   rxStorage->hasByName( s_sScriptsStorageName )
                                &&  rxStorage->isStorageElement( s_sScriptsStorageName )
                                )
                            );
		    }
		    catch ( const Exception& )
		    {
			    DBG_UNHANDLED_EXCEPTION();
		    }
	    }
        return bHasMacros;
    }

	//--------------------------------------------------------------------
    sal_Bool DocumentMacroMode::checkMacrosOnLoading( const Reference< XInteractionHandler >& rxInteraction )
    {
        sal_Bool bAllow = sal_False;
        if ( SvtSecurityOptions().IsMacroDisabled() )
        {
            // no macro should be executed at all
            bAllow = disallowMacroExecution();
        }
        else
        {
            if ( m_pData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() )
            {
                bAllow = adjustMacroMode( rxInteraction );
            }
            else if ( !isMacroExecutionDisallowed() )
            {
                // There are no macros (yet) but we want to be careful anyway
                sal_uInt16 nMacroExecutionMode = m_pData->m_rDocumentAccess.getCurrentMacroExecMode();
                adjustMacroExecModeSecurity(nMacroExecutionMode);
                switch (nMacroExecutionMode) {
                case MacroExecMode::NEVER_EXECUTE:
                case MacroExecMode::USE_CONFIG:
                case MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION:
                case MacroExecMode::FROM_LIST_NO_WARN:
                case MacroExecMode::FROM_LIST_AND_SIGNED_WARN:
                case MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN:
                    bAllow = sal_False;
                    break;
                case MacroExecMode::FROM_LIST:
                case MacroExecMode::ALWAYS_EXECUTE:
                case MacroExecMode::ALWAYS_EXECUTE_NO_WARN:
                case MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION:
                    bAllow = sal_True;
                    break;
                }
            }
        }
        return bAllow;
    }

//........................................................................
} // namespace sfx2
//........................................................................
