/*
 *  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.
 *
 */
package org.apache.directory.server.ldap.handlers.bind;


import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;

import org.apache.directory.shared.ldap.constants.SaslQoP;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoFilterAdapter;
import org.apache.mina.common.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * An {@link IoFilterAdapter} that handles integrity and confidentiality protection
 * for a SASL bound session.  The SaslFilter must be constructed with a SASL
 * context that has completed SASL negotiation.  Some SASL mechanisms, such as
 * CRAM-MD5, only support authentication and thus do not need this filter.  DIGEST-MD5
 * and GSSAPI do support message integrity and confidentiality and, therefore,
 * do need this filter.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$, $Date$
 */
public class SaslFilter extends IoFilterAdapter
{
    private static final Logger log = LoggerFactory.getLogger( SaslFilter.class );

    /**
     * A session attribute key that makes next one write request bypass
     * this filter (not adding a security layer).  This is a marker attribute,
     * which means that you can put whatever as its value. ({@link Boolean#TRUE}
     * is preferred.)  The attribute is automatically removed from the session
     * attribute map as soon as {@link IoSession#write(Object)} is invoked,
     * and therefore should be put again if you want to make more messages
     * bypass this filter.
     */
    public static final String DISABLE_SECURITY_LAYER_ONCE = SaslFilter.class.getName() + ".DisableSecurityLayerOnce";

    private SaslServer context;


    /**
     * Creates a new instance of SaslFilter.  The SaslFilter must be constructed
     * with a SASL context that has completed SASL negotiation.  The SASL context
     * will be used to provide message integrity and, optionally, message
     * confidentiality.
     *
     * @param context The initialized SASL context.
     */
    public SaslFilter( SaslServer context )
    {
        if ( context == null )
        {
            throw new IllegalStateException();
        }

        this.context = context;
    }


    public void messageReceived( NextFilter nextFilter, IoSession session, Object message ) throws SaslException
    {
        log.debug( "Message received:  {}", message );

        /*
         * Unwrap the data for mechanisms that support QoP (DIGEST-MD5, GSSAPI).
         */
        String qop = ( String ) context.getNegotiatedProperty( Sasl.QOP );
        boolean hasSecurityLayer = ( qop != null && ( qop.equals( SaslQoP.QOP_AUTH_INT ) || qop.equals( SaslQoP.QOP_AUTH_CONF ) ) );

        if ( hasSecurityLayer )
        {
            /*
             * Get the buffer as bytes.  First 4 bytes are length as int.
             */
            ByteBuffer buf = ( ByteBuffer ) message;
            int bufferLength = buf.getInt();
            byte[] bufferBytes = new byte[bufferLength];
            buf.get( bufferBytes );

            log.debug( "Will use SASL to unwrap received message of length:  {}", bufferLength );
            byte[] token = context.unwrap( bufferBytes, 0, bufferBytes.length );
            nextFilter.messageReceived( session, ByteBuffer.wrap( token ) );
        }
        else
        {
            log.debug( "Will not use SASL on received message." );
            nextFilter.messageReceived( session, message );
        }
    }


    public void filterWrite( NextFilter nextFilter, IoSession session, WriteRequest writeRequest ) throws SaslException
    {
        log.debug( "Filtering write request:  {}", writeRequest );

        /*
         * Check if security layer processing should be disabled once.
         */
        if ( session.containsAttribute( DISABLE_SECURITY_LAYER_ONCE ) )
        {
            // Remove the marker attribute because it is temporary.
            log.debug( "Disabling SaslFilter once; will not use SASL on write request." );
            session.removeAttribute( DISABLE_SECURITY_LAYER_ONCE );
            nextFilter.filterWrite( session, writeRequest );
            return;
        }

        /*
         * Wrap the data for mechanisms that support QoP (DIGEST-MD5, GSSAPI).
         */
        String qop = ( String ) context.getNegotiatedProperty( Sasl.QOP );
        boolean hasSecurityLayer = ( qop != null && ( qop.equals( SaslQoP.QOP_AUTH_INT ) || qop.equals( SaslQoP.QOP_AUTH_CONF ) ) );

        ByteBuffer saslLayerBuffer = null;

        if ( hasSecurityLayer )
        {
            /*
             * Get the buffer as bytes.
             */
            ByteBuffer buf = ( ByteBuffer ) writeRequest.getMessage();
            int bufferLength = buf.remaining();
            byte[] bufferBytes = new byte[bufferLength];
            buf.get( bufferBytes );

            log.debug( "Will use SASL to wrap message of length:  {}", bufferLength );

            byte[] saslLayer = context.wrap( bufferBytes, 0, bufferBytes.length );

            /*
             * Prepend 4 byte length.
             */
            saslLayerBuffer = ByteBuffer.allocate( 4 + saslLayer.length );
            saslLayerBuffer.putInt( saslLayer.length );
            saslLayerBuffer.put( saslLayer );
            saslLayerBuffer.position( 0 );
            saslLayerBuffer.limit( 4 + saslLayer.length );

            log.debug( "Sending encrypted token of length {}.", saslLayerBuffer.limit() );
            nextFilter.filterWrite( session, new WriteRequest( saslLayerBuffer, writeRequest.getFuture() ) );
        }
        else
        {
            log.debug( "Will not use SASL on write request." );
            nextFilter.filterWrite( session, writeRequest );
        }
    }
}
