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


import java.io.BufferedInputStream;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.PrivilegedAction;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

import org.apache.directory.ldap.client.api.Krb5LoginConfiguration;
import org.apache.directory.server.i18n.I18n;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;


/**
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class KerberosTestUtils
{
    public static char[] getControlDocument( String resource ) throws IOException
    {
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream( resource );

        Reader reader = new InputStreamReader( new BufferedInputStream( is ) );

        CharArrayWriter writer = new CharArrayWriter();

        try
        {
            char[] buf = new char[2048];
            int len = 0;
            while ( len >= 0 )
            {
                len = reader.read( buf );
                if ( len > 0 )
                {
                    writer.write( buf, 0, len );
                }
            }
        }
        finally
        {
            try
            {
                reader.close();
            }
            catch ( IOException ioe )
            {
            }
        }

        char[] isca = writer.toCharArray();
        return isca;
    }


    public static byte[] getBytesFromResource( String resource ) throws IOException
    {
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream( resource );

        BufferedInputStream stream = new BufferedInputStream( is );
        int len = stream.available();
        byte[] bytes = new byte[len];
        stream.read( bytes, 0, len );

        return bytes;
    }


    public static void hexdump( byte[] data )
    {
        hexdump( data, true );
    }


    public static void hexdump( byte[] data, boolean delimit )
    {
        String delimiter = new String( "-------------------------------------------------" );

        if ( delimit )
        {
            System.out.println( delimiter );
        }

        int lineLength = 0;
        for ( int ii = 0; ii < data.length; ii++ )
        {
            System.out.print( byte2hexString( data[ii] ) + " " );
            lineLength++;

            if ( lineLength == 8 )
            {
                System.out.print( "  " );
            }

            if ( lineLength == 16 )
            {
                System.out.println();
                lineLength = 0;
            }
        }

        if ( delimit )
        {
            System.out.println();
            System.out.println( delimiter );
        }
    }

    public static final String[] hex_digit =
        { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };


    public static String byte2hexString( byte x )
    {
        String s = "";
        for ( int ii = 0; ii < 2; ii++ )
        {
            s = hex_digit[( ( ( x ) & 0xff ) & ( 15 << ( ii * 4 ) ) ) >>> ( ii * 4 )] + s;
        }

        return s;
    }


    public static String int2hexString( int x )
    {
        String s = "";
        for ( int ii = 0; ii < 8; ii++ )
        {
            s = hex_digit[( x & ( 15 << ( ii * 4 ) ) ) >>> ( ii * 4 )] + s;
        }

        return s;
    }


    public static String int2binString( int x )
    {
        String s = "";
        for ( int ii = 0; ii < 32; ii++ )
        {
            if ( ( ii > 0 ) && ( ii % 4 == 0 ) )
            {
                s = " " + s;
            }

            s = hex_digit[( x & ( 1 << ii ) ) >>> ii] + s;
        }

        return s;
    }


    public static String long2hexString( long x )
    {
        String s = "";
        for ( int ii = 0; ii < 16; ii++ )
        {
            s = hex_digit[( int ) ( ( x & ( 15L << ( ii * 4 ) ) ) >>> ( ii * 4 ) )] + s;
        }

        return s;
    }


    public static String long2binString( long x )
    {
        String s = "";
        for ( int ii = 0; ii < 64; ii++ )
        {
            if ( ( ii > 0 ) && ( ii % 4 == 0 ) )
            {
                s = " " + s;
            }

            s = hex_digit[( int ) ( ( x & ( 1L << ii ) ) >>> ii )] + s;
        }

        return s;
    }


    public static String byte2hexString( byte[] input )
    {
        return byte2hexString( input, 0, input.length );
    }


    public static String byte2hexString( byte[] input, int offset )
    {
        return byte2hexString( input, offset, input.length );
    }


    public static String byte2hexString( byte[] input, int offset, int length )
    {
        String result = "";
        for ( int ii = 0; ii < length; ii++ )
        {
            if ( ii + offset < input.length )
            {
                result += byte2hexString( input[ii + offset] );
            }
        }

        return result;
    }


    /**
     * Gets the host name for 'localhost' used for Kerberos tests.
     * On Windows 7 and Server 2008 the loopback address 127.0.0.1
     * isn't resolved to localhost by default. In that case we need
     * to use the IP address for the service principal.
     *
     * @return the hostname
     */
    public static String getHostName()
    {
        String hostName;
        try
        {
            InetAddress loopback = InetAddress.getByName( "127.0.0.1" );
            hostName = loopback.getHostName();
        }
        catch ( UnknownHostException e )
        {
            System.err.println( "Can't find loopback address '127.0.0.1', using hostname 'localhost'" );
            hostName = "localhost";
        }
        return hostName;
    }


    /**
     * Obtains a new TGT from KDC.
     * 
     * Possible errors:
     * Bad username:  Client not found in Kerberos database
     * Bad password:  Integrity check on decrypted field failed
     * 
     * @param subject the empty subject
     * @param userName the user name 
     * @param password the password
     * @throws LoginException
     * 
     */
    public static void obtainTGT( Subject subject, String userName, String password ) throws LoginException
    {
        // Use our custom configuration to avoid reliance on external config
        Configuration.setConfiguration( new Krb5LoginConfiguration() );

        // Obtain TGT
        LoginContext lc = new LoginContext( KerberosUdpITest.class.getName(), subject, new
            CallbackHandlerBean( userName, password ) );
        lc.login();
    }

    private static class CallbackHandlerBean implements CallbackHandler
    {
        private String name;
        private String password;


        /**
         * Creates a new instance of CallbackHandlerBean.
         *
         * @param name
         * @param password
         */
        public CallbackHandlerBean( String name, String password )
        {
            this.name = name;
            this.password = password;
        }


        public void handle( Callback[] callbacks ) throws UnsupportedCallbackException, IOException
        {
            for ( Callback callback : callbacks )
            {
                if ( callback instanceof NameCallback )
                {
                    NameCallback nameCallback = ( NameCallback ) callback;
                    nameCallback.setName( name );
                }
                else if ( callback instanceof PasswordCallback )
                {
                    PasswordCallback passwordCallback = ( PasswordCallback ) callback;
                    passwordCallback.setPassword( password.toCharArray() );
                }
                else
                {
                    throw new UnsupportedCallbackException( callback, I18n.err( I18n.ERR_617 ) );
                }
            }
        }
    }


    /**
     * Obtains a Service Ticket from KDC.
     *
     * @param subject the subject, must contain a valid TGT
     * @param userName the user name
     * @param serviceName the service name
     * @param hostName the host name of the service
     * @throws GSSException
     */
    public static void obtainServiceTickets( Subject subject, String userName, String serviceName, String hostName )
        throws GSSException
    {
        ObtainServiceTicketAction action = new ObtainServiceTicketAction( userName, serviceName, hostName );
        GSSException exception = Subject.doAs( subject, action );
        if ( exception != null )
        {
            throw exception;
        }
    }

    private static class ObtainServiceTicketAction implements PrivilegedAction<GSSException>
    {
        private String userName;
        private String serviceName;
        private String hostName;


        public ObtainServiceTicketAction( String userName, String serviceName, String hostName )
        {
            this.userName = userName;
            this.serviceName = serviceName;
            this.hostName = hostName;
        }


        public GSSException run()
        {
            try
            {
                GSSManager manager = GSSManager.getInstance();
                GSSName clientName = manager.createName( userName, GSSName.NT_USER_NAME );
                GSSCredential clientCred = manager.createCredential( clientName,
                    8 * 3600,
                    createKerberosOid(),
                    GSSCredential.INITIATE_ONLY );

                GSSName serverName = manager.createName( serviceName + "@" + hostName, GSSName.NT_HOSTBASED_SERVICE );
                GSSContext context = manager.createContext( serverName,
                    createKerberosOid(),
                    clientCred,
                    GSSContext.DEFAULT_LIFETIME );
                context.requestMutualAuth( true );
                context.requestConf( true );
                context.requestInteg( true );

                context.initSecContext( new byte[0], 0, 0 );

                // byte[] outToken = context.initSecContext( new byte[0], 0, 0 );
                // System.out.println(new BASE64Encoder().encode(outToken));
                context.dispose();

                return null;
            }
            catch ( GSSException gsse )
            {
                return gsse;
            }
        }


        private Oid createKerberosOid() throws GSSException
        {
            return new Oid( "1.2.840.113554.1.2.2" );
        }
    }
}
