directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From erodrig...@apache.org
Subject svn commit: r549348 - in /directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos: ./ protocol/
Date Thu, 21 Jun 2007 03:40:31 GMT
Author: erodriguez
Date: Wed Jun 20 20:40:30 2007
New Revision: 549348

URL: http://svn.apache.org/viewvc?view=rev&rev=549348
Log:
More enhancements to Kerberos client component:
o  Moved to IoHandlerAdapter to remove unused handler methods.
o  Enabled TCP and UDP support.
o  Much better error handling.
o  Completed minimum protocol support to successfully retrieve TGT and service tickets.
o  Added demonstration Main class.

Added:
    directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnection.java   (with props)
    directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnectionException.java   (with props)
    directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcControls.java   (with props)
    directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/Main.java   (with props)
Modified:
    directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/GetServiceTicket.java
    directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/GetTicketGrantingTicket.java
    directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientHandler.java
    directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientTcpDecoder.java
    directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientUdpDecoder.java

Modified: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/GetServiceTicket.java
URL: http://svn.apache.org/viewvc/directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/GetServiceTicket.java?view=diff&rev=549348&r1=549347&r2=549348
==============================================================================
--- directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/GetServiceTicket.java (original)
+++ directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/GetServiceTicket.java Wed Jun 20 20:40:30 2007
@@ -20,16 +20,39 @@
 package org.apache.directory.client.kerberos;
 
 
+import java.io.IOException;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.security.SecureRandom;
+import java.util.Date;
 
 import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KerberosTicket;
 
-import org.apache.directory.client.kerberos.protocol.KerberosClientUdpCodecFactory;
 import org.apache.directory.client.kerberos.protocol.KerberosClientHandler;
+import org.apache.directory.server.kerberos.shared.crypto.checksum.ChecksumHandler;
+import org.apache.directory.server.kerberos.shared.crypto.checksum.ChecksumType;
+import org.apache.directory.server.kerberos.shared.crypto.encryption.CipherTextHandler;
 import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
+import org.apache.directory.server.kerberos.shared.crypto.encryption.KeyUsage;
+import org.apache.directory.server.kerberos.shared.exceptions.KerberosException;
+import org.apache.directory.server.kerberos.shared.io.decoder.TicketDecoder;
+import org.apache.directory.server.kerberos.shared.io.encoder.ApplicationRequestEncoder;
+import org.apache.directory.server.kerberos.shared.io.encoder.KdcRequestEncoder;
+import org.apache.directory.server.kerberos.shared.io.encoder.TicketEncoder;
+import org.apache.directory.server.kerberos.shared.messages.ApplicationRequest;
+import org.apache.directory.server.kerberos.shared.messages.ErrorMessage;
+import org.apache.directory.server.kerberos.shared.messages.KdcReply;
 import org.apache.directory.server.kerberos.shared.messages.KdcRequest;
 import org.apache.directory.server.kerberos.shared.messages.MessageType;
+import org.apache.directory.server.kerberos.shared.messages.components.Authenticator;
+import org.apache.directory.server.kerberos.shared.messages.components.AuthenticatorModifier;
+import org.apache.directory.server.kerberos.shared.messages.components.EncKdcRepPart;
+import org.apache.directory.server.kerberos.shared.messages.components.Ticket;
+import org.apache.directory.server.kerberos.shared.messages.value.ApOptions;
+import org.apache.directory.server.kerberos.shared.messages.value.Checksum;
+import org.apache.directory.server.kerberos.shared.messages.value.EncryptedData;
+import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
 import org.apache.directory.server.kerberos.shared.messages.value.KdcOptions;
 import org.apache.directory.server.kerberos.shared.messages.value.KerberosTime;
 import org.apache.directory.server.kerberos.shared.messages.value.PreAuthenticationData;
@@ -41,59 +64,72 @@
 import org.apache.mina.common.ConnectFuture;
 import org.apache.mina.common.IoConnector;
 import org.apache.mina.common.IoSession;
-import org.apache.mina.filter.LoggingFilter;
-import org.apache.mina.filter.codec.ProtocolCodecFilter;
 import org.apache.mina.transport.socket.nio.DatagramConnector;
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
- * A command-line client for requesting Kerberos tickets.
+ * A command object for requesting a Kerberos service ticket.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
 public class GetServiceTicket
 {
+    private static final Logger log = LoggerFactory.getLogger( GetServiceTicket.class );
+
     private static final SecureRandom random = new SecureRandom();
 
+    private static final CipherTextHandler cipherTextHandler = new CipherTextHandler();
+
     /** The remote Kerberos server name. */
-    private String hostname = "localhost";
+    private String hostname;
 
-    /** The remote Kerberos port number. */
-    private static final int REMOTE_PORT = 88;
+    /** The remote Kerberos server port. */
+    private int port;
 
-    /** One day in milliseconds, used for default end time. */
-    private static final int ONE_DAY = 86400000;
+    /** The Kerberos transport. */
+    private String transport;
 
-    /** One week in milliseconds, used for default renewal period. */
-    private static final int ONE_WEEK = 86400000 * 7;
+    /** Session attributes that must be verified. */
+    private EncryptionKey sessionKey;
+    private EncryptionKey subSessionKey;
+    private int sequenceNumber;
+    private KerberosTime now;
 
 
     /**
-     * Get a Ticket-Granting Ticket.
-     * 
-     * @param args
-     * @throws Exception
+     * Creates a new instance of GetServiceTicket.
+     *
+     * @param hostname
+     * @param port 
+     * @param transport
      */
-    public static void main( String[] args ) throws Exception
+    public GetServiceTicket( String hostname, int port, String transport )
     {
-        new GetServiceTicket().go();
+        this.hostname = hostname;
+        this.port = port;
+        this.transport = transport;
     }
 
 
     /**
-     * Make the request for a Ticket-Granting Ticket.
+     * Execute the request for a service ticket.
+     * 
+     * @param tgt 
+     * @param servicePrincipal 
+     * @param controls 
+     * @return The service ticket.
+     * @throws KdcConnectionException 
      */
-    public void go()
+    public KerberosTicket execute( KerberosTicket tgt, KerberosPrincipal servicePrincipal, KdcControls controls )
+        throws KdcConnectionException
     {
-        IoConnector connector = new DatagramConnector();
-
-        connector.getFilterChain()
-            .addLast( "codec", new ProtocolCodecFilter( KerberosClientUdpCodecFactory.getInstance() ) );
-        connector.getFilterChain().addLast( "logger", new LoggingFilter() );
+        IoConnector connector = getConnector( transport );
 
-        ConnectFuture future = connector.connect( new InetSocketAddress( hostname, REMOTE_PORT ),
-            new KerberosClientHandler() );
+        ConnectFuture future = connector.connect( new InetSocketAddress( hostname, port ), new KerberosClientHandler() );
 
         future.join();
 
@@ -101,15 +137,95 @@
 
         try
         {
-            KdcRequest request = getKdcRequest();
+            KdcRequest request = getKdcRequest( tgt, servicePrincipal, controls );
             session.write( request );
         }
         catch ( Exception e )
         {
-            e.printStackTrace();
+            log.debug( "Unexpected exception.", e );
         }
 
         session.getCloseFuture().join();
+
+        Object message = session.getAttribute( "reply" );
+
+        if ( message instanceof KdcReply )
+        {
+            KdcReply reply = ( KdcReply ) message;
+            return processKdcReply( reply );
+        }
+        else
+        {
+            if ( message instanceof ErrorMessage )
+            {
+                ErrorMessage error = ( ErrorMessage ) message;
+                processError( error );
+            }
+        }
+
+        log.error( "KDC returned error; ticket will be null." );
+        return null;
+    }
+
+
+    private void processError( ErrorMessage error ) throws KdcConnectionException
+    {
+        int errorCode = error.getErrorCode();
+        String errorText = error.getExplanatoryText();
+
+        throw new KdcConnectionException( errorText + " (" + errorCode + ")" );
+    }
+
+
+    private KerberosTicket processKdcReply( KdcReply reply ) throws KdcConnectionException
+    {
+        Ticket ticket = reply.getTicket();
+
+        log.debug( "Received ticket for '{}' to access '{}'.", reply.getClientPrincipal().getName(), ticket
+            .getServerPrincipal().getName() );
+
+        byte[] ticketBytes = null;
+        try
+        {
+            ticketBytes = TicketEncoder.encodeTicket( ticket );
+        }
+        catch ( IOException ioe )
+        {
+            throw new KdcConnectionException( "Error converting ticket.", ioe );
+        }
+
+        KerberosPrincipal client = reply.getClientPrincipal();
+        KerberosPrincipal server = ticket.getServerPrincipal();
+
+        EncryptedData encRepPart = reply.getEncPart();
+
+        EncKdcRepPart repPart;
+
+        try
+        {
+            // TODO - could have used sub-session key to seal, if sub-session key set in authenticator.
+            repPart = ( EncKdcRepPart ) cipherTextHandler.unseal( EncKdcRepPart.class, sessionKey, encRepPart,
+                KeyUsage.NUMBER8 );
+        }
+        catch ( KerberosException ke )
+        {
+            log.debug( "Unexpected exception.", ke );
+            return null;
+        }
+
+        byte[] sessionKey = repPart.getKey().getKeyValue();
+        int keyType = repPart.getKey().getKeyType().getOrdinal();
+        Date endTime = repPart.getEndTime().toDate();
+
+        // might be null
+        boolean[] flags = null;
+        Date authTime = null;
+        Date startTime = null;
+        Date renewTill = null;
+        InetAddress[] clientAddresses = null;
+
+        return new KerberosTicket( ticketBytes, client, server, sessionKey, keyType, flags, authTime, startTime,
+            endTime, renewTill, clientAddresses );
     }
 
 
@@ -118,16 +234,27 @@
      * 
      * Based on RFC 1510, A.5.  KRB_TGS_REQ generation
      */
-    private KdcRequest getKdcRequest()
+    private KdcRequest getKdcRequest( KerberosTicket tgt, KerberosPrincipal servicePrincipal, KdcControls controls )
+        throws Exception
     {
-        RequestBodyModifier modifier = new RequestBodyModifier();
+        // Get the session key from the service ticket.
+        byte[] sessionKeyBytes = tgt.getSessionKey().getEncoded();
+        int keyType = tgt.getSessionKeyType();
 
-        KerberosPrincipal principal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
+        sessionKey = new EncryptionKey( EncryptionType.getTypeByOrdinal( keyType ), sessionKeyBytes );
 
-        int pvno = 5;
-        MessageType messageType = MessageType.KRB_TGS_REQ;
+        RequestBodyModifier modifier = new RequestBodyModifier();
 
-        KdcOptions kdcOptions = getKdcOptions();
+        /*
+         Forwardable Ticket false
+         Forwarded Ticket false
+         Proxiable Ticket false
+         Proxy Ticket false
+         Postdated Ticket false
+         Renewable Ticket false
+         Initial Ticket false
+         */
+        KdcOptions kdcOptions = new KdcOptions();
 
         /*
          If the TGT is not for the realm of the end-server
@@ -136,29 +263,33 @@
          will be that of the TGS to which the TGT we are
          sending applies.
          */
-        PrincipalName serverName = new PrincipalName( "ldap/ldap.example.com", principal.getNameType() );
+        PrincipalName serverName = new PrincipalName( servicePrincipal.getName(), servicePrincipal.getNameType() );
         modifier.setServerName( serverName );
-        modifier.setRealm( principal.getRealm() );
+        modifier.setRealm( servicePrincipal.getRealm() );
 
         // Set the requested starting time.
-        if ( kdcOptions.get( KdcOptions.POSTDATED ) )
+        if ( controls.isPostdated() )
         {
-            KerberosTime fromTime = new KerberosTime();
+            KerberosTime fromTime = new KerberosTime( controls.getStartTime() );
             modifier.setFrom( fromTime );
+            kdcOptions.set( KdcOptions.POSTDATED );
         }
 
-        KerberosTime endTime = new KerberosTime( System.currentTimeMillis() + ONE_DAY );
+        long currentTime = System.currentTimeMillis();
+
+        KerberosTime endTime = new KerberosTime( currentTime + KdcControls.DAY );
         modifier.setTill( endTime );
 
-        if ( kdcOptions.get( KdcOptions.RENEWABLE ) )
+        if ( controls.isRenewable() )
         {
-            KerberosTime renewableTime = new KerberosTime( System.currentTimeMillis() + ONE_WEEK );
-            modifier.setRtime( renewableTime );
+            KerberosTime renewTime = new KerberosTime( currentTime + KdcControls.WEEK );
+            modifier.setRtime( renewTime );
+            kdcOptions.set( KdcOptions.RENEWABLE );
         }
 
         modifier.setKdcOptions( kdcOptions );
 
-        modifier.setNonce( getNonce() );
+        modifier.setNonce( random.nextInt() );
 
         EncryptionType[] encryptionTypes = new EncryptionType[1];
         encryptionTypes[0] = EncryptionType.DES_CBC_MD5;
@@ -183,16 +314,42 @@
 
         RequestBody requestBody = modifier.getRequestBody();
 
-        // TODO - check := generate_checksum (req.body,checksumtype);
+        int pvno = 5;
+        MessageType messageType = MessageType.KRB_TGS_REQ;
+
+        // TODO - make body encoder not require KdcRequest
+        KdcRequest req = new KdcRequest( pvno, messageType, null, requestBody );
+        KdcRequestEncoder bodyEncoder = new KdcRequestEncoder();
+        byte[] bodyBytes = bodyEncoder.encodeBody( req );
+
+        ChecksumHandler checksumHandler = new ChecksumHandler();
+        Checksum checksum = checksumHandler.calculateChecksum( ChecksumType.RSA_MD5, bodyBytes, null, KeyUsage.NUMBER8 );
 
         PreAuthenticationData[] paData = new PreAuthenticationData[1];
 
         PreAuthenticationDataModifier preAuth = new PreAuthenticationDataModifier();
         preAuth.setDataType( PreAuthenticationDataType.PA_TGS_REQ );
 
-        // TODO - padata[0].padata-value := create a KRB_AP_REQ using the TGT and checksum
-        preAuth.setDataValue( new byte[]
-            { ( byte ) 0x00 } );
+        // Generate a new sequence number.
+        sequenceNumber = random.nextInt();
+
+        now = new KerberosTime();
+
+        EncryptedData authenticator = getAuthenticator( tgt.getClient(), checksum );
+        Ticket convertedTicket = TicketDecoder.decode( tgt.getEncoded() );
+
+        // Make new ap req, aka the "auth header."
+        ApplicationRequest applicationRequest = new ApplicationRequest();
+        applicationRequest.setMessageType( MessageType.KRB_AP_REQ );
+        applicationRequest.setProtocolVersionNumber( 5 );
+        applicationRequest.setApOptions( new ApOptions() );
+        applicationRequest.setTicket( convertedTicket );
+        applicationRequest.setEncPart( authenticator );
+
+        ApplicationRequestEncoder encoder = new ApplicationRequestEncoder();
+        byte[] encodedApReq = encoder.encode( applicationRequest );
+
+        preAuth.setDataValue( encodedApReq );
 
         paData[0] = preAuth.getPreAuthenticationData();
 
@@ -200,23 +357,50 @@
     }
 
 
-    private int getNonce()
+    /**
+     * Build the authenticator.  The authenticator communicates the sub-session key the
+     * service will use to unlock the private message.  The service will unlock the
+     * authenticator with the session key from the ticket.  The authenticator client
+     * principal must equal the principal in the ticket.  
+     *
+     * @param clientPrincipal
+     * @return The {@link EncryptedData} containing the {@link Authenticator}.
+     * @throws KerberosException
+     */
+    private EncryptedData getAuthenticator( KerberosPrincipal clientPrincipal, Checksum checksum )
+        throws KerberosException
     {
-        return random.nextInt();
+        AuthenticatorModifier authenticatorModifier = new AuthenticatorModifier();
+
+        authenticatorModifier.setVersionNumber( 5 );
+        authenticatorModifier.setClientPrincipal( clientPrincipal );
+        authenticatorModifier.setClientTime( now );
+        authenticatorModifier.setClientMicroSecond( 0 );
+        authenticatorModifier.setSubSessionKey( subSessionKey );
+        authenticatorModifier.setSequenceNumber( sequenceNumber );
+        authenticatorModifier.setChecksum( checksum );
+
+        Authenticator authenticator = authenticatorModifier.getAuthenticator();
+
+        EncryptedData encryptedAuthenticator = cipherTextHandler.seal( sessionKey, authenticator, KeyUsage.NUMBER11 );
+
+        return encryptedAuthenticator;
     }
 
 
-    private KdcOptions getKdcOptions()
+    private IoConnector getConnector( String transport )
     {
-        /*
-         Forwardable Ticket false
-         Forwarded Ticket false
-         Proxiable Ticket false
-         Proxy Ticket false
-         Postdated Ticket false
-         Renewable Ticket false
-         Initial Ticket false
-         */
-        return new KdcOptions();
+        IoConnector connector;
+
+        if ( transport.equals( "UDP" ) )
+        {
+            connector = new DatagramConnector();
+        }
+        else
+        {
+            connector = new SocketConnector();
+        }
+
+        return connector;
     }
 }

Modified: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/GetTicketGrantingTicket.java
URL: http://svn.apache.org/viewvc/directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/GetTicketGrantingTicket.java?view=diff&rev=549348&r1=549347&r2=549348
==============================================================================
--- directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/GetTicketGrantingTicket.java (original)
+++ directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/GetTicketGrantingTicket.java Wed Jun 20 20:40:30 2007
@@ -21,21 +21,28 @@
 
 
 import java.io.IOException;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.security.SecureRandom;
+import java.util.Date;
 
 import javax.security.auth.kerberos.KerberosKey;
 import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KerberosTicket;
 
-import org.apache.directory.client.kerberos.protocol.KerberosClientUdpCodecFactory;
 import org.apache.directory.client.kerberos.protocol.KerberosClientHandler;
 import org.apache.directory.server.kerberos.shared.crypto.encryption.CipherTextHandler;
 import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
 import org.apache.directory.server.kerberos.shared.crypto.encryption.KeyUsage;
 import org.apache.directory.server.kerberos.shared.exceptions.KerberosException;
 import org.apache.directory.server.kerberos.shared.io.encoder.EncryptedDataEncoder;
+import org.apache.directory.server.kerberos.shared.io.encoder.TicketEncoder;
+import org.apache.directory.server.kerberos.shared.messages.ErrorMessage;
+import org.apache.directory.server.kerberos.shared.messages.KdcReply;
 import org.apache.directory.server.kerberos.shared.messages.KdcRequest;
 import org.apache.directory.server.kerberos.shared.messages.MessageType;
+import org.apache.directory.server.kerberos.shared.messages.components.EncKdcRepPart;
+import org.apache.directory.server.kerberos.shared.messages.components.Ticket;
 import org.apache.directory.server.kerberos.shared.messages.value.EncryptedData;
 import org.apache.directory.server.kerberos.shared.messages.value.EncryptedTimeStamp;
 import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
@@ -50,60 +57,69 @@
 import org.apache.mina.common.ConnectFuture;
 import org.apache.mina.common.IoConnector;
 import org.apache.mina.common.IoSession;
-import org.apache.mina.filter.LoggingFilter;
-import org.apache.mina.filter.codec.ProtocolCodecFilter;
 import org.apache.mina.transport.socket.nio.DatagramConnector;
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
- * A command-line client for requesting Kerberos tickets.
+ * A command object for requesting a Kerberos Ticket-Granting Ticket (TGT).
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
 public class GetTicketGrantingTicket
 {
+    private static final Logger log = LoggerFactory.getLogger( GetTicketGrantingTicket.class );
+
     private static final SecureRandom random = new SecureRandom();
-    private static final boolean PA_ENC_TIMESTAMP_REQUIRED = true;
+
+    private static final CipherTextHandler cipherTextHandler = new CipherTextHandler();
 
     /** The remote Kerberos server name. */
-    private String hostname = "localhost";
+    private String hostname;
 
-    /** The remote Kerberos port number. */
-    private static final int REMOTE_PORT = 88;
+    /** The remote Kerberos server port. */
+    private int port;
 
-    /** One day in milliseconds, used for default end time. */
-    private static final int ONE_DAY = 86400000;
+    /** The Kerberos transport. */
+    private String transport;
 
-    /** One week in milliseconds, used for default renewal period. */
-    private static final int ONE_WEEK = 86400000 * 7;
+    /** The client's encryption key. */
+    private EncryptionKey clientKey;
 
 
     /**
-     * Get a Ticket-Granting Ticket.
-     * 
-     * @param args
-     * @throws Exception
+     * Creates a new instance of GetTicketGrantingTicket.
+     *
+     * @param hostname
+     * @param port 
+     * @param transport
      */
-    public static void main( String[] args ) throws Exception
+    public GetTicketGrantingTicket( String hostname, int port, String transport )
     {
-        new GetTicketGrantingTicket().go();
+        this.hostname = hostname;
+        this.port = port;
+        this.transport = transport;
     }
 
 
     /**
-     * Make the request for a Ticket-Granting Ticket.
+     * Execute the request for a Ticket-Granting Ticket (TGT).
+     * 
+     * @param clientPrincipal 
+     * @param password 
+     * @param controls 
+     * @return The TGT.
+     * @throws KdcConnectionException 
      */
-    public void go()
+    public KerberosTicket execute( KerberosPrincipal clientPrincipal, String password, KdcControls controls )
+        throws KdcConnectionException
     {
-        IoConnector connector = new DatagramConnector();
-
-        connector.getFilterChain()
-            .addLast( "codec", new ProtocolCodecFilter( KerberosClientUdpCodecFactory.getInstance() ) );
-        connector.getFilterChain().addLast( "logger", new LoggingFilter() );
+        IoConnector connector = getConnector( transport );
 
-        ConnectFuture future = connector.connect( new InetSocketAddress( hostname, REMOTE_PORT ),
-            new KerberosClientHandler() );
+        ConnectFuture future = connector.connect( new InetSocketAddress( hostname, port ), new KerberosClientHandler() );
 
         future.join();
 
@@ -111,15 +127,94 @@
 
         try
         {
-            KdcRequest request = getKdcRequest();
+            KdcRequest request = getKdcRequest( clientPrincipal, password, controls );
             session.write( request );
         }
         catch ( Exception e )
         {
-            e.printStackTrace();
+            log.debug( "Unexpected exception.", e );
         }
 
         session.getCloseFuture().join();
+
+        Object message = session.getAttribute( "reply" );
+
+        if ( message instanceof KdcReply )
+        {
+            KdcReply reply = ( KdcReply ) message;
+            return processKdcReply( reply );
+        }
+        else
+        {
+            if ( message instanceof ErrorMessage )
+            {
+                ErrorMessage error = ( ErrorMessage ) message;
+                processError( error );
+            }
+        }
+
+        log.error( "KDC returned error; ticket will be null." );
+        return null;
+    }
+
+
+    private void processError( ErrorMessage error ) throws KdcConnectionException
+    {
+        int errorCode = error.getErrorCode();
+        String errorText = error.getExplanatoryText();
+
+        throw new KdcConnectionException( errorText + " (" + errorCode + ")" );
+    }
+
+
+    private KerberosTicket processKdcReply( KdcReply reply ) throws KdcConnectionException
+    {
+        Ticket ticket = reply.getTicket();
+
+        log.debug( "Received ticket for '{}' to access '{}'.", reply.getClientPrincipal().getName(), ticket
+            .getServerPrincipal().getName() );
+
+        byte[] ticketBytes = null;
+        try
+        {
+            ticketBytes = TicketEncoder.encodeTicket( ticket );
+        }
+        catch ( IOException ioe )
+        {
+            throw new KdcConnectionException( "Error converting ticket.", ioe );
+        }
+
+        KerberosPrincipal client = reply.getClientPrincipal();
+        KerberosPrincipal server = ticket.getServerPrincipal();
+
+        EncryptedData encRepPart = reply.getEncPart();
+
+        EncKdcRepPart repPart;
+
+        try
+        {
+            repPart = ( EncKdcRepPart ) cipherTextHandler.unseal( EncKdcRepPart.class, clientKey, encRepPart,
+                KeyUsage.NUMBER3 );
+        }
+        catch ( KerberosException ke )
+        {
+            log.debug( "Unexpected exception.", ke );
+            return null;
+        }
+
+        byte[] sessionKey = repPart.getKey().getKeyValue();
+        int keyType = repPart.getKey().getKeyType().getOrdinal();
+        Date endTime = repPart.getEndTime().toDate();
+
+        // might be null
+        boolean[] flags = null;
+        Date authTime = null;
+        Date startTime = null;
+        Date renewTill = null;
+        InetAddress[] clientAddresses = null;
+
+        return new KerberosTicket( ticketBytes, client, server, sessionKey, keyType, flags, authTime, startTime,
+            endTime, renewTill, clientAddresses );
     }
 
 
@@ -128,24 +223,31 @@
      * 
      * Based on RFC 1510, A.1.  KRB_AS_REQ generation
      */
-    private KdcRequest getKdcRequest() throws IOException
+    private KdcRequest getKdcRequest( KerberosPrincipal clientPrincipal, String password, KdcControls controls )
+        throws IOException
     {
         RequestBodyModifier modifier = new RequestBodyModifier();
 
-        KerberosPrincipal principal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
-        KerberosKey kerberosKey = new KerberosKey( principal, "s3crEt".toCharArray(), "DES" );
+        // TODO - set enc type base on contols
+        KerberosKey kerberosKey = new KerberosKey( clientPrincipal, password.toCharArray(), "DES" );
+        clientKey = new EncryptionKey( EncryptionType.DES_CBC_MD5, kerberosKey.getEncoded() );
 
-        KdcOptions kdcOptions = getKdcOptions();
-
-        int pvno = 5;
-        MessageType messageType = MessageType.KRB_AS_REQ;
+        /*
+         Forwardable Ticket false
+         Forwarded Ticket false
+         Proxiable Ticket false
+         Proxy Ticket false
+         Postdated Ticket false
+         Renewable Ticket false
+         Initial Ticket false
+         */
+        KdcOptions kdcOptions = new KdcOptions();
 
         PreAuthenticationData[] paData = new PreAuthenticationData[1];
 
-        if ( PA_ENC_TIMESTAMP_REQUIRED )
+        if ( controls.isUsePaEncTimestamp() )
         {
             CipherTextHandler lockBox = new CipherTextHandler();
-            EncryptionKey key = new EncryptionKey( EncryptionType.DES_CBC_MD5, kerberosKey.getEncoded() );
 
             KerberosTime timeStamp = new KerberosTime();
             EncryptedTimeStamp encryptedTimeStamp = new EncryptedTimeStamp( timeStamp, 0 );
@@ -154,11 +256,11 @@
 
             try
             {
-                encryptedData = lockBox.seal( key, encryptedTimeStamp, KeyUsage.NUMBER1 );
+                encryptedData = lockBox.seal( clientKey, encryptedTimeStamp, KeyUsage.NUMBER1 );
             }
             catch ( KerberosException ke )
             {
-                ke.printStackTrace();
+                log.error( "Unexpected exception sealing encrypted timestamp.", ke );
             }
 
             byte[] encodedEncryptedData = EncryptedDataEncoder.encode( encryptedData );
@@ -170,11 +272,12 @@
             paData[0] = preAuth.getPreAuthenticationData();
         }
 
-        PrincipalName clientName = new PrincipalName( principal.getName(), principal.getNameType() );
+        PrincipalName clientName = new PrincipalName( clientPrincipal.getName(), clientPrincipal.getNameType() );
         modifier.setClientName( clientName );
-        modifier.setRealm( principal.getRealm() );
+        modifier.setRealm( clientPrincipal.getRealm() );
 
-        PrincipalName serverName = new PrincipalName( "krbtgt/EXAMPLE.COM", principal.getNameType() );
+        PrincipalName serverName = new PrincipalName( "krbtgt/" + clientPrincipal.getRealm(), clientPrincipal
+            .getNameType() );
         modifier.setServerName( serverName );
 
         if ( kdcOptions.get( KdcOptions.POSTDATED ) )
@@ -182,18 +285,20 @@
             // body.from := requested starting time;
         }
 
-        KerberosTime endTime = new KerberosTime( System.currentTimeMillis() + ONE_DAY );
+        long currentTime = System.currentTimeMillis();
+
+        KerberosTime endTime = new KerberosTime( currentTime + KdcControls.DAY );
         modifier.setTill( endTime );
 
         if ( kdcOptions.get( KdcOptions.RENEWABLE ) )
         {
-            KerberosTime rTime = new KerberosTime( System.currentTimeMillis() + ONE_WEEK );
+            KerberosTime rTime = new KerberosTime( currentTime + KdcControls.WEEK );
             modifier.setRtime( rTime );
         }
 
         modifier.setKdcOptions( kdcOptions );
 
-        modifier.setNonce( getNonce() );
+        modifier.setNonce( random.nextInt() );
 
         EncryptionType[] encryptionTypes = new EncryptionType[1];
         encryptionTypes[0] = EncryptionType.DES_CBC_MD5;
@@ -213,27 +318,26 @@
 
         RequestBody requestBody = modifier.getRequestBody();
 
+        int pvno = 5;
+        MessageType messageType = MessageType.KRB_AS_REQ;
+
         return new KdcRequest( pvno, messageType, paData, requestBody );
     }
 
 
-    private int getNonce()
+    private IoConnector getConnector( String transport )
     {
-        return random.nextInt();
-    }
+        IoConnector connector;
 
+        if ( transport.equals( "UDP" ) )
+        {
+            connector = new DatagramConnector();
+        }
+        else
+        {
+            connector = new SocketConnector();
+        }
 
-    private KdcOptions getKdcOptions()
-    {
-        /*
-         Forwardable Ticket false
-         Forwarded Ticket false
-         Proxiable Ticket false
-         Proxy Ticket false
-         Postdated Ticket false
-         Renewable Ticket false
-         Initial Ticket false
-         */
-        return new KdcOptions();
+        return connector;
     }
 }

Added: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnection.java
URL: http://svn.apache.org/viewvc/directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnection.java?view=auto&rev=549348
==============================================================================
--- directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnection.java (added)
+++ directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnection.java Wed Jun 20 20:40:30 2007
@@ -0,0 +1,203 @@
+/*
+ *  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.client.kerberos;
+
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KerberosTicket;
+
+import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
+
+
+/**
+ * Connection to an RFC 4120 Kerberos server (KDC).  Connection users may request Ticket-Granting
+ * Tickets (TGT) or service tickets based on TGTs.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class KdcConnection
+{
+    /** The remote Kerberos port number. */
+    private static final int REMOTE_PORT = 88;
+
+    /** The remote Kerberos server name. */
+    private String hostname = "localhost";
+
+    /** The remote Kerberos server port. */
+    private int port = REMOTE_PORT;
+
+    /** The Kerberos transport. */
+    private String transport = "UDP";
+
+
+    /**
+     * Creates a new instance of KdcConnection.
+     *
+     * @param hostname
+     */
+    public KdcConnection( String hostname )
+    {
+        this( hostname, "UDP" );
+    }
+
+
+    /**
+     * Creates a new instance of KdcConnection.
+     *
+     * @param hostname
+     * @param transport
+     */
+    public KdcConnection( String hostname, String transport )
+    {
+        if ( hostname.contains( ":" ) )
+        {
+            String[] split = hostname.split( ":" );
+            this.hostname = split[0];
+            this.port = Integer.valueOf( split[1] );
+        }
+        else
+        {
+            this.hostname = hostname;
+        }
+
+        if ( !( transport.toLowerCase().equals( "tcp" ) || transport.toLowerCase().equals( "udp" ) ) )
+        {
+            throw new IllegalArgumentException( "Transport must be UDP or TCP." );
+        }
+        else
+        {
+            this.transport = transport;
+        }
+    }
+
+
+    /**
+     * Get a Ticket-Granting Ticket (TGT).
+     *
+     * @param clientPrincipal
+     * @param password
+     * @return The Ticket-Granting Ticket (TGT).
+     * @throws KdcConnectionException
+     */
+    public KerberosTicket getTicketGrantingTicket( KerberosPrincipal clientPrincipal, String password )
+        throws KdcConnectionException
+    {
+        return getTicketGrantingTicket( clientPrincipal, password, getDefaultKdcControls() );
+    }
+
+
+    /**
+     * Get a Ticket-Granting Ticket (TGT).
+     *
+     * @param clientPrincipal
+     * @param password
+     * @param controls
+     * @return The Ticket-Granting Ticket (TGT).
+     * @throws KdcConnectionException
+     */
+    public KerberosTicket getTicketGrantingTicket( KerberosPrincipal clientPrincipal, String password,
+        KdcControls controls ) throws KdcConnectionException
+    {
+        GetTicketGrantingTicket command = new GetTicketGrantingTicket( hostname, port, transport );
+        return command.execute( clientPrincipal, password, controls );
+    }
+
+
+    /**
+     * Get a service ticket.
+     * 
+     * @param tgt 
+     * @param servicePrincipal 
+     * @return The service ticket.
+     * @throws KdcConnectionException
+     */
+    public KerberosTicket getServiceTicket( KerberosTicket tgt, KerberosPrincipal servicePrincipal )
+        throws KdcConnectionException
+    {
+        return getServiceTicket( tgt, servicePrincipal, getDefaultKdcControls() );
+    }
+
+
+    /**
+     * Get a service ticket.
+     * 
+     * @param tgt 
+     * @param servicePrincipal 
+     * @param controls 
+     * @return The service ticket.
+     * @throws KdcConnectionException
+     */
+    public KerberosTicket getServiceTicket( KerberosTicket tgt, KerberosPrincipal servicePrincipal, KdcControls controls )
+        throws KdcConnectionException
+    {
+        GetServiceTicket command = new GetServiceTicket( hostname, port, transport );
+        return command.execute( tgt, servicePrincipal, controls );
+    }
+
+
+    /**
+     * Disconnects the connection.
+     */
+    public void disconnect()
+    {
+        // Wouldn't do anything for UDP.
+    }
+
+
+    private KdcControls getDefaultKdcControls()
+    {
+        List<EncryptionType> encryptionTypes = new ArrayList<EncryptionType>();
+        encryptionTypes.add( EncryptionType.DES_CBC_MD5 );
+
+        KdcControls controls = new KdcControls();
+        controls.setEncryptionTypes( encryptionTypes );
+        controls.setUsePaEncTimestamp( true );
+
+        // default is UDP.  Set to 1 to use TCP.
+        controls.setUdpPreferenceLimit( 1 );
+
+        // useful dates
+        long currentTime = System.currentTimeMillis();
+        Date now = new Date( currentTime );
+        Date oneDay = new Date( currentTime + KdcControls.DAY );
+        Date oneWeek = new Date( currentTime + KdcControls.WEEK );
+
+        // flags & times
+        // if the start time exceeds "now" by more than the clockskew, consider it a POSTDATED request.
+        controls.setStartTime( now );
+        controls.setEndTime( oneDay );
+        controls.setRenewTime( oneWeek );
+
+        // even less important
+        controls.setForwardable( true );
+        controls.setProxiable( true );
+
+        List<InetAddress> clientAddresses = new ArrayList<InetAddress>();
+        controls.setClientAddresses( clientAddresses );
+
+        return controls;
+    }
+}

Propchange: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnectionException.java
URL: http://svn.apache.org/viewvc/directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnectionException.java?view=auto&rev=549348
==============================================================================
--- directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnectionException.java (added)
+++ directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnectionException.java Wed Jun 20 20:40:30 2007
@@ -0,0 +1,64 @@
+/*
+ *  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.client.kerberos;
+
+
+/**
+ * The root of the {@link KdcConnection} exception hierarchy.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class KdcConnectionException extends Exception
+{
+    /** 
+     * The class fingerprint that is set to indicate serialization
+     * compatibility with a previous version of the class.
+     */
+    private static final long serialVersionUID = -3882166764471452526L;
+
+
+    /**
+     * @param message
+     */
+    public KdcConnectionException( String message )
+    {
+        super( message );
+    }
+
+
+    /**
+     * @param cause
+     */
+    public KdcConnectionException( Throwable cause )
+    {
+        super( cause );
+    }
+
+
+    /**
+     * @param message
+     * @param cause
+     */
+    public KdcConnectionException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+}

Propchange: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcConnectionException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcControls.java
URL: http://svn.apache.org/viewvc/directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcControls.java?view=auto&rev=549348
==============================================================================
--- directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcControls.java (added)
+++ directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcControls.java Wed Jun 20 20:40:30 2007
@@ -0,0 +1,413 @@
+/*
+ *  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.client.kerberos;
+
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
+
+
+/**
+ * Parameters for controlling a connection to a Kerberos server (KDC).
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class KdcControls
+{
+    /** The number of milliseconds in a minute. */
+    public static final int MINUTE = 60000;
+
+    /** The number of milliseconds in a day. */
+    public static final int DAY = MINUTE * 1440;
+
+    /** The number of milliseconds in a week. */
+    public static final int WEEK = MINUTE * 10080;
+
+    /** The default allowed clockskew */
+    private static final long DEFAULT_ALLOWED_CLOCKSKEW = 5 * MINUTE;
+
+    /** The default for requiring encrypted timestamps */
+    private static final boolean DEFAULT_USE_PA_ENC_TIMESTAMP = true;
+
+    /** The default for the maximum ticket lifetime */
+    private static final int DEFAULT_TGS_MAXIMUM_TICKET_LIFETIME = DAY;
+
+    /** The default for the maximum renewable lifetime */
+    private static final int DEFAULT_TGS_MAXIMUM_RENEWABLE_LIFETIME = WEEK;
+
+    /** The default for allowing forwardable tickets */
+    private static final boolean DEFAULT_TGS_FORWARDABLE = false;
+
+    /** The default for allowing proxiable tickets */
+    private static final boolean DEFAULT_TGS_PROXIABLE = false;
+
+    /** The default for allowing postdatable tickets */
+    private static final boolean DEFAULT_TGS_POSTDATED = false;
+
+    /** The default for allowing renewable tickets */
+    private static final boolean DEFAULT_TGS_RENEWABLE = true;
+
+    /** The default UDP preference limit */
+    private static final int DEFAULT_UDP_PREFERENCE_LIMIT = 1500;
+
+    /** The allowed clock skew. */
+    private long allowedClockSkew = DEFAULT_ALLOWED_CLOCKSKEW;
+
+    /** Whether pre-authentication by encrypted timestamp is required. */
+    private boolean usePaEncTimestamp = DEFAULT_USE_PA_ENC_TIMESTAMP;
+
+    /** The maximum ticket lifetime. */
+    private long maximumTicketLifetime = DEFAULT_TGS_MAXIMUM_TICKET_LIFETIME;
+
+    /** The maximum renewable lifetime. */
+    private long maximumRenewableLifetime = DEFAULT_TGS_MAXIMUM_RENEWABLE_LIFETIME;
+
+    /** Whether forwardable addresses are allowed. */
+    private boolean isForwardable = DEFAULT_TGS_FORWARDABLE;
+
+    /** Whether proxiable addresses are allowed. */
+    private boolean isProxiable = DEFAULT_TGS_PROXIABLE;
+
+    /** Whether postdating is allowed. */
+    private boolean isPostdated = DEFAULT_TGS_POSTDATED;
+
+    /** Whether renewable tickets are allowed. */
+    private boolean isRenewable = DEFAULT_TGS_RENEWABLE;
+
+    /** The encryption types. */
+    private List<EncryptionType> encryptionTypes = new ArrayList<EncryptionType>();
+
+    /** The client addresses. */
+    private List<InetAddress> clientAddresses = new ArrayList<InetAddress>();
+
+    /** The UDP preference limit. */
+    private int udpPreferenceLimit = DEFAULT_UDP_PREFERENCE_LIMIT;
+
+    private Date startTime;
+    private Date endTime;
+    private Date renewTime;
+
+
+    /**
+     * Creates a new instance of KdcControls.
+     */
+    public KdcControls()
+    {
+        encryptionTypes.add( EncryptionType.DES_CBC_MD5 );
+    }
+
+
+    /**
+     * Returns the allowed clock skew.
+     *
+     * @return The allowed clock skew.
+     */
+    public long getAllowedClockSkew()
+    {
+        return allowedClockSkew;
+    }
+
+
+    /**
+     * @param allowedClockSkew The allowedClockSkew to set.
+     */
+    public void setAllowedClockSkew( long allowedClockSkew )
+    {
+        this.allowedClockSkew = allowedClockSkew;
+    }
+
+
+    /**
+     * Returns whether pre-authentication by encrypted timestamp is used.
+     *
+     * @return Whether pre-authentication by encrypted timestamp is used.
+     */
+    public boolean isUsePaEncTimestamp()
+    {
+        return usePaEncTimestamp;
+    }
+
+
+    /**
+     * @param usePaEncTimestamp Whether to use a encrypted timestamp pre-authentication.
+     */
+    public void setUsePaEncTimestamp( boolean usePaEncTimestamp )
+    {
+        this.usePaEncTimestamp = usePaEncTimestamp;
+    }
+
+
+    /**
+     * @return The udpPreferenceLimit.
+     */
+    public int getUdpPreferenceLimit()
+    {
+        return udpPreferenceLimit;
+    }
+
+
+    /**
+     * Default is UDP.  Set to 1 to use TCP.
+     * 
+     * @param udpPreferenceLimit 
+     */
+    public void setUdpPreferenceLimit( int udpPreferenceLimit )
+    {
+        this.udpPreferenceLimit = udpPreferenceLimit;
+    }
+
+
+    /**
+     * Returns the start time.
+     *
+     * @return The start time.
+     */
+    public Date getStartTime()
+    {
+        return startTime;
+    }
+
+
+    /**
+     * Sets the start time. If the start time exceeds "now" by more than the
+     * clockskew, consider it a POSTDATED request.
+     * 
+     * @param startTime 
+     */
+    public void setStartTime( Date startTime )
+    {
+        this.startTime = startTime;
+    }
+
+
+    /**
+     * Returns the end time.
+     *
+     * @return The end time.
+     */
+    public Date getEndTime()
+    {
+        return endTime;
+    }
+
+
+    /**
+     * Sets the end time.
+     *
+     * @param endTime
+     */
+    public void setEndTime( Date endTime )
+    {
+        this.endTime = endTime;
+    }
+
+
+    /**
+     * Returns the renew time.
+     *
+     * @return The renew time.
+     */
+    public Date getRenewTime()
+    {
+        return renewTime;
+    }
+
+
+    /**
+     * Sets the renew time.
+     *
+     * @param renewTime
+     */
+    public void setRenewTime( Date renewTime )
+    {
+        this.renewTime = renewTime;
+    }
+
+
+    /**
+     * Returns whether to request a forwardable ticket.
+     *
+     * @return true if the request is for a forwardable ticket.
+     */
+    public boolean isForwardable()
+    {
+        return isForwardable;
+    }
+
+
+    /**
+     * Sets whether to request a forwardable ticket.
+     *
+     * @param isForwardable
+     */
+    public void setForwardable( boolean isForwardable )
+    {
+        this.isForwardable = isForwardable;
+    }
+
+
+    /**
+     * Returns whether to request a postdated ticket.
+     * 
+     * @return true if the request is for a postdated ticket.
+     */
+    public boolean isPostdated()
+    {
+        return isPostdated;
+    }
+
+
+    /**
+     * Sets whether to request a postdated ticket.
+     * 
+     * @param isPostdated
+     */
+    public void setPostdated( boolean isPostdated )
+    {
+        this.isPostdated = isPostdated;
+    }
+
+
+    /**
+     * Returns whether to request a proxiable ticket.
+     * 
+     * @return true if the request is for a proxiable ticket.
+     */
+    public boolean isProxiable()
+    {
+        return isProxiable;
+    }
+
+
+    /**
+     * Sets whether to request a proxiable ticket.
+     *
+     * @param isProxiable
+     */
+    public void setProxiable( boolean isProxiable )
+    {
+        this.isProxiable = isProxiable;
+    }
+
+
+    /**
+     * Returns whether to request a renewable ticket.
+     * 
+     * @return true if the request is for a renewable ticket.
+     */
+    public boolean isRenewable()
+    {
+        return isRenewable;
+    }
+
+
+    /**
+     * Sets whether to request a renewable ticket.
+     * 
+     * @param isRenewable
+     */
+    public void setRenewable( boolean isRenewable )
+    {
+        this.isRenewable = isRenewable;
+    }
+
+
+    /**
+     * @return The maximumTicketLifetime.
+     */
+    public long getMaximumTicketLifetime()
+    {
+        return maximumTicketLifetime;
+    }
+
+
+    /**
+     * @param maximumTicketLifetime The maximumTicketLifetime to set.
+     */
+    public void setMaximumTicketLifetime( long maximumTicketLifetime )
+    {
+        this.maximumTicketLifetime = maximumTicketLifetime;
+    }
+
+
+    /**
+     * @return The maximumRenewableLifetime.
+     */
+    public long getMaximumRenewableLifetime()
+    {
+        return maximumRenewableLifetime;
+    }
+
+
+    /**
+     * @param maximumRenewableLifetime The maximumRenewableLifetime to set.
+     */
+    public void setMaximumRenewableLifetime( long maximumRenewableLifetime )
+    {
+        this.maximumRenewableLifetime = maximumRenewableLifetime;
+    }
+
+
+    /**
+     * Returns the encryption types.
+     *
+     * @return The encryption types.
+     */
+    public List<EncryptionType> getEncryptionTypes()
+    {
+        return encryptionTypes;
+    }
+
+
+    /**
+     * @param encryptionTypes The encryption types to set.
+     */
+    public void setEncryptionTypes( List<EncryptionType> encryptionTypes )
+    {
+        this.encryptionTypes = encryptionTypes;
+    }
+
+
+    /**
+     * Returns the client addresses.
+     *
+     * @return The client addresses.
+     */
+    public List<InetAddress> getClientAddresses()
+    {
+        return clientAddresses;
+    }
+
+
+    /**
+     * Sets the client addresses.
+     *
+     * @param clientAddresses
+     */
+    public void setClientAddresses( List<InetAddress> clientAddresses )
+    {
+        this.clientAddresses = clientAddresses;
+    }
+}

Propchange: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/KdcControls.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/Main.java
URL: http://svn.apache.org/viewvc/directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/Main.java?view=auto&rev=549348
==============================================================================
--- directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/Main.java (added)
+++ directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/Main.java Wed Jun 20 20:40:30 2007
@@ -0,0 +1,66 @@
+/*
+ *  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.client.kerberos;
+
+
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KerberosTicket;
+
+
+/**
+ * Main method class for executing a Kerberos service ticket request.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class Main
+{
+    private KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
+    private String password = "cabletr0N";
+
+    private KerberosPrincipal servicePrincipal = new KerberosPrincipal( "ldap/ldap.example.com@EXAMPLE.COM" );
+
+    /** The remote Kerberos server name. */
+    private String hostname = "localhost";
+
+    /** The remote Kerberos server port. */
+    private int port = 88;
+
+
+    /**
+     * Get a service ticket.
+     * 
+     * @param args
+     * @throws Exception
+     */
+    public static void main( String[] args ) throws Exception
+    {
+        new Main().go();
+    }
+
+
+    private void go() throws Exception
+    {
+        KdcConnection con = new KdcConnection( hostname + ":" + port );
+        KerberosTicket tgt = con.getTicketGrantingTicket( clientPrincipal, password );
+        con.getServiceTicket( tgt, servicePrincipal );
+        con.disconnect();
+    }
+}

Propchange: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/Main.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientHandler.java
URL: http://svn.apache.org/viewvc/directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientHandler.java?view=diff&rev=549348&r1=549347&r2=549348
==============================================================================
--- directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientHandler.java (original)
+++ directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientHandler.java Wed Jun 20 20:40:30 2007
@@ -20,12 +20,11 @@
 package org.apache.directory.client.kerberos.protocol;
 
 
-import org.apache.directory.server.kerberos.shared.messages.ErrorMessage;
-import org.apache.directory.server.kerberos.shared.messages.KdcReply;
-import org.apache.mina.common.IdleStatus;
 import org.apache.mina.common.IoHandler;
 import org.apache.mina.common.IoHandlerAdapter;
 import org.apache.mina.common.IoSession;
+import org.apache.mina.common.TransportType;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -45,34 +44,18 @@
     {
         if ( log.isDebugEnabled() )
         {
-            log.debug( session.getRemoteAddress() + " CREATED" );
+            log.debug( session.getRemoteAddress() + " CREATED : " + session.getTransportType() );
         }
-    }
-
 
-    public void sessionOpened( IoSession session )
-    {
-        if ( log.isDebugEnabled() )
+        if ( session.getTransportType() == TransportType.DATAGRAM )
         {
-            log.debug( session.getRemoteAddress() + " OPENED" );
+            session.getFilterChain().addFirst( "codec",
+                new ProtocolCodecFilter( KerberosClientUdpCodecFactory.getInstance() ) );
         }
-    }
-
-
-    public void sessionClosed( IoSession session )
-    {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( session.getRemoteAddress() + " CLOSED" );
-        }
-    }
-
-
-    public void sessionIdle( IoSession session, IdleStatus status )
-    {
-        if ( log.isDebugEnabled() )
+        else
         {
-            log.debug( session.getRemoteAddress() + " IDLE(" + status + ")" );
+            session.getFilterChain().addFirst( "codec",
+                new ProtocolCodecFilter( KerberosClientTcpCodecFactory.getInstance() ) );
         }
     }
 
@@ -84,44 +67,15 @@
             log.debug( session.getRemoteAddress() + " RCVD: " + message );
         }
 
-        System.out.println( session.getRemoteAddress() + " RCVD: " + message );
-
-        if ( message instanceof KdcReply )
-        {
-            KdcReply reply = ( KdcReply ) message;
-            System.out.println( reply.getClientRealm() );
-        }
-        else
-        {
-            if ( message instanceof ErrorMessage )
-            {
-                ErrorMessage error = ( ErrorMessage ) message;
-                System.out.println( error.getExplanatoryText() );
-            }
-        }
+        session.setAttribute( "reply", message );
 
         session.close();
     }
 
 
-    public void messageSent( IoSession session, Object message )
-    {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( session.getRemoteAddress() + " SENT: " + message );
-        }
-
-        System.out.println( session.getRemoteAddress() + " SENT: " + message );
-    }
-
-
     public void exceptionCaught( IoSession session, Throwable cause )
     {
         log.error( session.getRemoteAddress() + " EXCEPTION", cause );
-
-        System.out.println( session.getRemoteAddress() + " EXCEPTION" );
-
-        cause.printStackTrace();
 
         session.close();
     }

Modified: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientTcpDecoder.java
URL: http://svn.apache.org/viewvc/directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientTcpDecoder.java?view=diff&rev=549348&r1=549347&r2=549348
==============================================================================
--- directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientTcpDecoder.java (original)
+++ directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientTcpDecoder.java Wed Jun 20 20:40:30 2007
@@ -20,8 +20,6 @@
 package org.apache.directory.client.kerberos.protocol;
 
 
-import java.util.Arrays;
-
 import org.apache.directory.server.kerberos.shared.io.decoder.ErrorMessageDecoder;
 import org.apache.directory.server.kerberos.shared.io.decoder.KdcReplyDecoder;
 import org.apache.mina.common.BufferDataException;
@@ -40,8 +38,7 @@
  */
 public class KerberosClientTcpDecoder extends CumulativeProtocolDecoder
 {
-    private static final byte[] ERROR = new byte[]
-        { ( byte ) 0x7E, ( byte ) 0x78, ( byte ) 0x30, ( byte ) 0x76 };
+    private static final byte ERROR = ( byte ) 0x7E;
 
     private KdcReplyDecoder replyDecoder = new KdcReplyDecoder();
     private ErrorMessageDecoder errorDecoder = new ErrorMessageDecoder();
@@ -92,18 +89,15 @@
 
         in.getInt();
 
-        byte[] header = new byte[4];
-        in.get( header );
+        byte header = in.get();
         in.rewind();
 
-        if ( Arrays.equals( ERROR, header ) )
+        if ( header == ERROR )
         {
-            System.out.println( "Got error." );
             out.write( errorDecoder.decode( in.buf() ) );
         }
         else
         {
-            System.out.println( "Got reply." );
             out.write( replyDecoder.decode( in.buf() ) );
         }
 

Modified: directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientUdpDecoder.java
URL: http://svn.apache.org/viewvc/directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientUdpDecoder.java?view=diff&rev=549348&r1=549347&r2=549348
==============================================================================
--- directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientUdpDecoder.java (original)
+++ directory/clients/trunk/kerberos/client/src/main/java/org/apache/directory/client/kerberos/protocol/KerberosClientUdpDecoder.java Wed Jun 20 20:40:30 2007
@@ -21,7 +21,6 @@
 
 
 import java.io.IOException;
-import java.util.Arrays;
 
 import org.apache.directory.server.kerberos.shared.io.decoder.ErrorMessageDecoder;
 import org.apache.directory.server.kerberos.shared.io.decoder.KdcReplyDecoder;
@@ -37,8 +36,7 @@
  */
 public class KerberosClientUdpDecoder extends ProtocolDecoderAdapter
 {
-    private static final byte[] ERROR = new byte[]
-        { ( byte ) 0x7E, ( byte ) 0x78, ( byte ) 0x30, ( byte ) 0x76 };
+    private static final byte ERROR = ( byte ) 0x7E;
 
     private KdcReplyDecoder replyDecoder = new KdcReplyDecoder();
     private ErrorMessageDecoder errorDecoder = new ErrorMessageDecoder();
@@ -46,18 +44,15 @@
 
     public void decode( IoSession session, ByteBuffer in, ProtocolDecoderOutput out ) throws IOException
     {
-        byte[] header = new byte[4];
-        in.get( header );
+        byte header = in.get();
         in.rewind();
 
-        if ( Arrays.equals( ERROR, header ) )
+        if ( header == ERROR )
         {
-            System.out.println( "Got error." );
             out.write( errorDecoder.decode( in.buf() ) );
         }
         else
         {
-            System.out.println( "Got reply." );
             out.write( replyDecoder.decode( in.buf() ) );
         }
     }



Mime
View raw message