Package org.apache.directory.server.kerberos.kdc

Source Code of org.apache.directory.server.kerberos.kdc.KerberosTestUtils

/*
*  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.apache.directory.shared.util.Strings;
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( Strings.EMPTY_BYTES, 0, 0 );

                // byte[] outToken = context.initSecContext( Strings.EMPTY_BYTES, 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" );
        }
    }
}
TOP

Related Classes of org.apache.directory.server.kerberos.kdc.KerberosTestUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.