/*
 *   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.extended;


import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.directory.server.core.security.CoreKeyStoreSpi;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.server.ldap.ExtendedOperationHandler;
import org.apache.directory.server.ldap.LdapServer;
import org.apache.directory.server.ldap.LdapSession;
import org.apache.directory.shared.ldap.codec.api.ExtendedResponseDecorator;
import org.apache.directory.shared.ldap.codec.api.LdapApiServiceFactory;
import org.apache.directory.shared.ldap.model.message.ExtendedRequest;
import org.apache.directory.shared.ldap.model.message.ExtendedResponse;
import org.apache.directory.shared.ldap.model.message.ExtendedResponseImpl;
import org.apache.directory.shared.ldap.model.message.LdapResult;
import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
import org.apache.directory.shared.util.Strings;
import org.apache.mina.core.filterchain.IoFilterChain;
import org.apache.mina.filter.ssl.SslFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Handler for the StartTLS extended operation.
 *
 * @see <a href="http://www.ietf.org/rfc/rfc2830.txt">RFC 2830</a>
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class StartTlsHandler implements ExtendedOperationHandler<ExtendedRequest<ExtendedResponse>, ExtendedResponse>
{
    public static final String EXTENSION_OID = "1.3.6.1.4.1.1466.20037";

    private static final Set<String> EXTENSION_OIDS;
    private static final Logger LOG = LoggerFactory.getLogger( StartTlsHandler.class );

    private SSLContext sslContext;

    static
    {
        Set<String> set = new HashSet<String>( 3 );
        set.add( EXTENSION_OID );
        EXTENSION_OIDS = Collections.unmodifiableSet( set );
    }


    public void handleExtendedOperation( LdapSession session, ExtendedRequest<ExtendedResponse> req ) throws Exception
    {
        LOG.info( "Handling StartTLS request." );

        IoFilterChain chain = session.getIoSession().getFilterChain();
        SslFilter sslFilter = ( SslFilter ) chain.get( "sslFilter" );
        if ( sslFilter == null )
        {
            sslFilter = new SslFilter( sslContext );
            chain.addFirst( "sslFilter", sslFilter );
        }
        else
        {
            sslFilter.startSsl( session.getIoSession() );
        }

        ExtendedResponseDecorator<ExtendedResponse> res = new ExtendedResponseDecorator<ExtendedResponse>(
            LdapApiServiceFactory.getSingleton(), new ExtendedResponseImpl( req.getMessageId() ) );
        LdapResult result = res.getLdapResult();
        result.setResultCode( ResultCodeEnum.SUCCESS );
        res.setResponseName( EXTENSION_OID );
        res.setResponseValue( Strings.EMPTY_BYTES );

        // Send a response.
        session.getIoSession().setAttribute( SslFilter.DISABLE_ENCRYPTION_ONCE );
        session.getIoSession().write( res );
    }

    static class ServerX509TrustManager implements X509TrustManager
    {
        public void checkClientTrusted( X509Certificate[] chain, String authType ) throws CertificateException
        {
            LOG.debug( "checkClientTrusted() called" );
        }


        public void checkServerTrusted( X509Certificate[] chain, String authType ) throws CertificateException
        {
            LOG.debug( "checkServerTrusted() called" );
        }


        public X509Certificate[] getAcceptedIssuers()
        {
            LOG.debug( "getAcceptedIssuers() called" );
            return new X509Certificate[0];
        }
    }


    public final Set<String> getExtensionOids()
    {
        return EXTENSION_OIDS;
    }


    public final String getOid()
    {
        return EXTENSION_OID;
    }


    public void setLdapServer( LdapServer ldapServer )
    {
        LOG.debug( "Setting LDAP Service" );
        Provider provider = Security.getProvider( "SUN" );
        LOG.debug( "provider = {}", provider );

        KeyStore keyStore = null;

        try
        {
            if ( ldapServer.getKeystoreFile() == null )
            {
                CoreKeyStoreSpi coreKeyStoreSpi = new CoreKeyStoreSpi( ldapServer.getDirectoryService() );
                keyStore = new KeyStore( coreKeyStoreSpi, provider, "JKS" )
                {
                };

                keyStore.load( null, null );
            }
            else
            {
                keyStore = KeyStore.getInstance( "JKS" );
                keyStore.load( new FileInputStream( new File( ldapServer.getKeystoreFile() ) ), null );
            }
        }
        catch ( Exception e1 )
        {
            throw new RuntimeException( I18n.err( I18n.ERR_678 ) );
        }

        KeyManagerFactory keyManagerFactory = null;
        try
        {
            keyManagerFactory = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm() );
        }
        catch ( Exception e )
        {
            throw new RuntimeException( I18n.err( I18n.ERR_679 ), e );
        }

        try
        {
            char[] password = null;

            if ( ldapServer.getKeystoreFile() != null )
            {
                password = ldapServer.getCertificatePassword().toCharArray();
            }

            keyManagerFactory.init( keyStore, password );
        }
        catch ( Exception e )
        {
            throw new RuntimeException( I18n.err( I18n.ERR_680 ), e );
        }

        try
        {
            sslContext = SSLContext.getInstance( "TLS" );
        }
        catch ( Exception e )
        {
            throw new RuntimeException( I18n.err( I18n.ERR_681 ), e );
        }

        try
        {
            sslContext.init( keyManagerFactory.getKeyManagers(), new TrustManager[]
                { new ServerX509TrustManager() }, new SecureRandom() );
        }
        catch ( Exception e )
        {
            throw new RuntimeException( I18n.err( I18n.ERR_682 ), e );
        }
    }
}
