You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2013/04/17 09:26:18 UTC

svn commit: r1468781 - in /directory/apacheds/trunk/kerberos-client2/src: main/java/org/apache/directory/kerberos/client/ test/java/org/apache/directory/kerberos/client/

Author: kayyagari
Date: Wed Apr 17 07:26:17 2013
New Revision: 1468781

URL: http://svn.apache.org/r1468781
Log:
o turned off preauth flag by default
o modified getTgt() to try two times while getting a TGT
o getTgt() now gets the etypes from the KrbError received from the server
o made the use of useUdp flag consistent
o added utility methods to parse EtypeInfo and EtypeInfo2 structures

Modified:
    directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KdcClientUtil.java
    directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KdcConnection.java
    directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KerberosChannel.java
    directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/TgtRequest.java
    directory/apacheds/trunk/kerberos-client2/src/test/java/org/apache/directory/kerberos/client/KdcAsRepTest.java
    directory/apacheds/trunk/kerberos-client2/src/test/java/org/apache/directory/kerberos/client/KdcConnectionTest.java

Modified: directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KdcClientUtil.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KdcClientUtil.java?rev=1468781&r1=1468780&r2=1468781&view=diff
==============================================================================
--- directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KdcClientUtil.java (original)
+++ directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KdcClientUtil.java Wed Apr 17 07:26:17 2013
@@ -20,6 +20,34 @@
 package org.apache.directory.kerberos.client;
 
 
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.directory.api.asn1.DecoderException;
+import org.apache.directory.api.asn1.ber.Asn1Decoder;
+import org.apache.directory.shared.kerberos.codec.etypeInfo.ETypeInfoContainer;
+import org.apache.directory.shared.kerberos.codec.etypeInfo2.ETypeInfo2Container;
+import org.apache.directory.shared.kerberos.codec.methodData.MethodDataContainer;
+import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
+import org.apache.directory.shared.kerberos.codec.types.PaDataType;
+import org.apache.directory.shared.kerberos.components.ETypeInfo;
+import org.apache.directory.shared.kerberos.components.ETypeInfo2;
+import org.apache.directory.shared.kerberos.components.ETypeInfo2Entry;
+import org.apache.directory.shared.kerberos.components.ETypeInfoEntry;
+import org.apache.directory.shared.kerberos.components.MethodData;
+import org.apache.directory.shared.kerberos.components.PaData;
+import org.apache.directory.shared.kerberos.messages.KrbError;
+
+
+/**
+ * A class with utility methods.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
 public class KdcClientUtil
 {
     public static String extractRealm( String principal )
@@ -33,4 +61,97 @@ public class KdcClientUtil
 
         throw new IllegalArgumentException( "Not a valid principal, missing realm name" );
     }
+
+
+    public static String extractName( String principal )
+    {
+        int pos = principal.indexOf( '@' );
+
+        if ( pos < 0 )
+        {
+            return principal;
+        }
+
+        return principal.substring( 0, pos );
+    }
+
+
+    public static Set<EncryptionType> getEtypesFromError( KrbError error )
+    {
+        try
+        {
+            ByteBuffer stream = ByteBuffer.wrap( error.getEData() );
+
+            Asn1Decoder decoder = new Asn1Decoder();
+            MethodDataContainer container = new MethodDataContainer();
+            container.setStream( stream );
+            decoder.decode( stream, container );
+            
+            MethodData methodData = container.getMethodData();
+            
+            for( PaData pd : methodData.getPaDatas() )
+            {
+                if( pd.getPaDataType() == PaDataType.PA_ENCTYPE_INFO2 )
+                {
+                    return parseEtpeInfo2( pd.getPaDataValue() );
+                }
+                else if( pd.getPaDataType() == PaDataType.PA_ENCTYPE_INFO )
+                {
+                    return parseEtpeInfo( pd.getPaDataValue() );
+                }
+            }
+        }
+        catch ( Exception e )
+        {
+            // shouldn't happen, but iff happens blast off
+            throw new RuntimeException( e );
+        }
+        
+        return Collections.EMPTY_SET;
+    }
+    
+    
+    private static Set<EncryptionType> parseEtpeInfo2( byte[] data ) throws DecoderException
+    {
+        ByteBuffer stream = ByteBuffer.wrap( data );
+        
+        Asn1Decoder decoder = new Asn1Decoder();
+        ETypeInfo2Container container = new ETypeInfo2Container();
+        container.setStream( stream );
+        decoder.decode( stream, container );
+        
+        ETypeInfo2 info2 = container.getETypeInfo2();
+
+        Set<EncryptionType> lstEtypes = new LinkedHashSet<EncryptionType>();
+        
+        for( ETypeInfo2Entry e2e : info2.getETypeInfo2Entries() )
+        {
+            lstEtypes.add( e2e.getEType() );
+        }
+        
+        return lstEtypes;
+    }
+    
+    
+    private static Set<EncryptionType> parseEtpeInfo( byte[] data ) throws DecoderException
+    {
+        ByteBuffer stream = ByteBuffer.wrap( data );
+        
+        Asn1Decoder decoder = new Asn1Decoder();
+        ETypeInfoContainer container = new ETypeInfoContainer();
+        container.setStream( stream );
+        decoder.decode( stream, container );
+        
+        ETypeInfo einfo = container.getETypeInfo();
+
+        Set<EncryptionType> lstEtypes = new LinkedHashSet<EncryptionType>();
+        
+        for( ETypeInfoEntry eie : einfo.getETypeInfoEntries() )
+        {
+            lstEtypes.add( eie.getEType() );
+        }
+        
+        return lstEtypes;
+    }
+    
 }

Modified: directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KdcConnection.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KdcConnection.java?rev=1468781&r1=1468780&r2=1468781&view=diff
==============================================================================
--- directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KdcConnection.java (original)
+++ directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KdcConnection.java Wed Apr 17 07:26:17 2013
@@ -87,7 +87,7 @@ import org.slf4j.LoggerFactory;
  * 
  * A client to connect to kerberos servers using TCP or UDP transports.
  * 
- * @author Kiran Ayyagari
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class KdcConnection
 {
@@ -193,7 +193,7 @@ public class KdcConnection
     
     private void connect() throws IOException
     {
-        channel.openConnection( host, port, timeout, !useUdp );
+        channel.openConnection( host, port, timeout, useUdp );
     }
     
     
@@ -236,9 +236,48 @@ public class KdcConnection
         return getServiceTicket( new ServiceTicketRequest( tgt, serverPrincipal ) );
     }
 
-    
     public TgTicket getTgt( TgtRequest clientTgtReq ) throws KerberosException
     {
+        TgTicket tgt = null;
+        
+        KerberosException ke = null;
+        
+        for( int i=0; i < 2; i++ )
+        {
+            ke = null;
+            
+            try
+            {
+                tgt = _getTgt( clientTgtReq );
+            }
+            catch( KerberosException e )
+            {
+                // using exception for control flow, b.a.d, but here it is better than
+                // defining a new Result class to hold ticket and exception and validating
+                // the Result instance from _getTgt()
+                ke = e;
+            }
+            
+            if( ke != null )
+            {
+                if ( ke.getErrorCode() == ErrorType.KDC_ERR_PREAUTH_REQUIRED.getValue() )
+                {
+                    encryptionTypes = KdcClientUtil.getEtypesFromError( ke.getError() );
+                    clientTgtReq.setPreAuthEnabled( true );
+                }
+            }
+        }
+        
+        if( ke != null )
+        {
+            throw ke;
+        }
+        
+        return tgt;
+    }
+    
+    /* default protected */ TgTicket _getTgt( TgtRequest clientTgtReq ) throws KerberosException
+    {
         String realm = clientTgtReq.getRealm();
         
         if ( clientTgtReq.getServerPrincipal() == null )
@@ -348,7 +387,7 @@ public class KdcConnection
             
             EncKdcRepPart encKdcRepPart = encAsRepPart.getEncKdcRepPart();
             
-            if ( !encKdcRepPart.getSName().getNameString().equals( clientTgtReq.getServerPrincipal() ) )
+            if ( !encKdcRepPart.getSName().getNameString().equals( clientTgtReq.getSName() ) )
             {
                 throw new KerberosException( ErrorType.KDC_ERR_SERVER_NOMATCH );
             }

Modified: directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KerberosChannel.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KerberosChannel.java?rev=1468781&r1=1468780&r2=1468781&view=diff
==============================================================================
--- directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KerberosChannel.java (original)
+++ directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/KerberosChannel.java Wed Apr 17 07:26:17 2013
@@ -29,51 +29,77 @@ import java.net.Socket;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 
+/**
+ * A class for sending and receiving kerberos request and response data
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
 public class KerberosChannel
 {
+    /** the TCP socket */
     private Socket tcpSocket;
+    
+    /** the UDP socket */
     private DatagramSocket udpSocket;
     
+    /** data input stream to read from */
     private DataInputStream in;
+    
+    /** data output stream to write to */
     private OutputStream out;
     
-    private boolean useTcp;
+    /** flag to detect if this is a UDP channel */
+    private boolean useUdp;
     
     private int timeOut = 60000;
 
+    /** the UDP socket address of the server */
     private SocketAddress udpServerAddr = null;
     
-    public void openConnection( String hostName, int  portNo, int timeOut, boolean isTcp ) throws IOException
+    protected void openConnection( String hostName, int  portNo, int timeOut, boolean isUdp ) throws IOException
     {
-        this.useTcp = isTcp;
+        this.useUdp = isUdp;
         this.timeOut = timeOut;
         
-        if ( isTcp )
+        if ( isUdp )
+        {
+            udpServerAddr = new InetSocketAddress( hostName, portNo );
+            udpSocket = new DatagramSocket();
+        }
+        else
         {
             tcpSocket = new Socket( hostName, portNo );
             tcpSocket.setSoTimeout( ( int ) timeOut );
             in = new DataInputStream( tcpSocket.getInputStream() );
             out = tcpSocket.getOutputStream();
         }
-        else
-        {
-            udpServerAddr = new InetSocketAddress( hostName, portNo );
-            udpSocket = new DatagramSocket();
-        }
     }
 
 
-    public ByteBuffer sendAndReceive( ByteBuffer encodedBuf ) throws IOException
+    protected ByteBuffer sendAndReceive( ByteBuffer encodedBuf ) throws IOException
     {
         byte[] reqData  = encodedBuf.array();
         
         ByteBuffer repData;
         
-        if ( useTcp )
+        if ( useUdp )
+        {
+            DatagramPacket reqPacket = new DatagramPacket( reqData, reqData.length, udpServerAddr );
+            udpSocket.send( reqPacket );
+            
+            byte[] buffer = new byte[2048];
+            DatagramPacket repPacket = new DatagramPacket( buffer, buffer.length );
+            udpSocket.receive( repPacket );
+            
+            byte[] receivedData = repPacket.getData();
+            repData = ByteBuffer.allocate( receivedData.length );
+            repData.put( receivedData );
+        }
+        else
         {
             out.write( reqData );
             out.flush();
-
+            
             int len = in.readInt();
             
             repData = ByteBuffer.allocate( len + 4 );
@@ -86,19 +112,6 @@ public class KerberosChannel
                 repData.put( tmp, 0, read );
             }
         }
-        else
-        {
-            DatagramPacket reqPacket = new DatagramPacket( reqData, reqData.length, udpServerAddr );
-            udpSocket.send( reqPacket );
-            
-            byte[] buffer = new byte[2048];
-            DatagramPacket repPacket = new DatagramPacket( buffer, buffer.length );
-            udpSocket.receive( repPacket );
-            
-            byte[] receivedData = repPacket.getData();
-            repData = ByteBuffer.allocate( receivedData.length );
-            repData.put( receivedData );
-        }
         
         repData.flip();
         
@@ -106,21 +119,21 @@ public class KerberosChannel
     }
     
     
-    public boolean isUseTcp()
+    protected boolean isUseTcp()
     {
-        return useTcp;
+        return !useUdp;
     }
 
 
-    public void close() throws IOException
+    protected void close() throws IOException
     {
-        if( useTcp )
+        if( useUdp )
         {
-            tcpSocket.close();
+            udpSocket.close();
         }
         else
         {
-            udpSocket.close();
+            tcpSocket.close();
         }
     }
 }

Modified: directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/TgtRequest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/TgtRequest.java?rev=1468781&r1=1468780&r2=1468781&view=diff
==============================================================================
--- directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/TgtRequest.java (original)
+++ directory/apacheds/trunk/kerberos-client2/src/main/java/org/apache/directory/kerberos/client/TgtRequest.java Wed Apr 17 07:26:17 2013
@@ -46,7 +46,7 @@ public class TgtRequest
 
     private KdcOptions options = new KdcOptions();
 
-    private boolean preAuthEnabled = true;
+    private boolean preAuthEnabled = false;
 
     public TgtRequest()
     {
@@ -200,6 +200,15 @@ public class TgtRequest
         this.preAuthEnabled = preAuthEnabled;
     }
 
+    public String getSName()
+    {
+        return KdcClientUtil.extractName( serverPrincipal );
+    }
+
+    public String getCName()
+    {
+        return KdcClientUtil.extractName( clientPrincipal );
+    }
 
     private void setOrClear( int pos, boolean set )
     {

Modified: directory/apacheds/trunk/kerberos-client2/src/test/java/org/apache/directory/kerberos/client/KdcAsRepTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/kerberos-client2/src/test/java/org/apache/directory/kerberos/client/KdcAsRepTest.java?rev=1468781&r1=1468780&r2=1468781&view=diff
==============================================================================
--- directory/apacheds/trunk/kerberos-client2/src/test/java/org/apache/directory/kerberos/client/KdcAsRepTest.java (original)
+++ directory/apacheds/trunk/kerberos-client2/src/test/java/org/apache/directory/kerberos/client/KdcAsRepTest.java Wed Apr 17 07:26:17 2013
@@ -161,11 +161,10 @@ public class KdcAsRepTest extends Abstra
         TgtRequest tgtReq = new TgtRequest();
         tgtReq.setClientPrincipal( principalName );
         tgtReq.setPassword( userPassword );
-        tgtReq.setPreAuthEnabled( false );
 
         try
         {
-            conn.getTgt( tgtReq );
+            conn._getTgt( tgtReq );
         }
         catch( KerberosException e )
         {

Modified: directory/apacheds/trunk/kerberos-client2/src/test/java/org/apache/directory/kerberos/client/KdcConnectionTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/kerberos-client2/src/test/java/org/apache/directory/kerberos/client/KdcConnectionTest.java?rev=1468781&r1=1468780&r2=1468781&view=diff
==============================================================================
--- directory/apacheds/trunk/kerberos-client2/src/test/java/org/apache/directory/kerberos/client/KdcConnectionTest.java (original)
+++ directory/apacheds/trunk/kerberos-client2/src/test/java/org/apache/directory/kerberos/client/KdcConnectionTest.java Wed Apr 17 07:26:17 2013
@@ -127,6 +127,11 @@ import org.junit.runner.RunWith;
     "krb5PrincipalName: ldap/localhost@EXAMPLE.COM",
     "krb5KeyVersionNumber: 0"
 })
+/**
+ * KDC connection tests
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
 public class KdcConnectionTest extends AbstractLdapTestUnit
 {
     public static final String USERS_DN = "dc=example,dc=com";