Author: erodriguez
Date: Sun Nov  7 02:40:48 2004
New Revision: 56838

Added:
   
incubator/directory/kerberos/trunk/kerberos/src/java/org/apache/kerberos/kdc/store/keytab/
   
incubator/directory/kerberos/trunk/kerberos/src/java/org/apache/kerberos/kdc/store/keytab/KeytabEntry.java
   
incubator/directory/kerberos/trunk/kerberos/src/java/org/apache/kerberos/kdc/store/keytab/KeytabException.java
   
incubator/directory/kerberos/trunk/kerberos/src/java/org/apache/kerberos/kdc/store/keytab/KeytabStore.java
Log:
Keytab reader implementation; probably useful for migrations.

Added: 
incubator/directory/kerberos/trunk/kerberos/src/java/org/apache/kerberos/kdc/store/keytab/KeytabEntry.java
==============================================================================
--- (empty file)
+++ 
incubator/directory/kerberos/trunk/kerberos/src/java/org/apache/kerberos/kdc/store/keytab/KeytabEntry.java
  Sun Nov  7 02:40:48 2004
@@ -0,0 +1,121 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.kerberos.kdc.store.keytab;
+
+import org.apache.kerberos.messages.value.KerberosPrincipalModifier;
+import org.apache.kerberos.messages.value.PrincipalNameModifier;
+
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import java.nio.ByteBuffer;
+
+public class KeytabEntry {
+
+    private static boolean isLittleEndian = false;
+
+       private int timestamp;
+    private int kt_vno;
+    private KerberosKey key;
+
+       public KeytabEntry(int kt_vno, byte[] bytes)
+    {
+        this.kt_vno = kt_vno;
+
+        ByteBuffer buf = ByteBuffer.wrap(bytes);
+
+        int keyVersionNumber;
+           int encryptionType;
+           byte[] keyBytes;
+
+        KerberosPrincipalModifier modifier = new KerberosPrincipalModifier();
+        PrincipalNameModifier nameModifier = new PrincipalNameModifier();
+
+        int count = toShort(buf.getShort());
+        if (kt_vno == KeytabStore.VNO_1)
+        {
+            count--;
+        }
+
+        int length = toShort(buf.getShort());
+        modifier.setRealm(getString(buf, length));
+
+        int ii = 0;
+        while (ii < count)
+        {
+            length = toShort(buf.getShort());
+            nameModifier.addName(getString(buf, length));
+            ii++;
+        }
+
+        nameModifier.setType(toInt(buf.getInt()));
+
+        timestamp = toInt(buf.getInt());
+
+        keyVersionNumber = buf.get();
+
+        encryptionType = toShort(buf.getShort());
+
+        length = toShort(buf.getShort());
+
+        keyBytes = new byte[length];
+        buf.get(keyBytes);
+
+        modifier.setPrincipalName(nameModifier.getPrincipalName());
+
+               KerberosPrincipal principal = modifier.getKerberosPrincipal();
+        key = new KerberosKey(principal, keyBytes, encryptionType, 
keyVersionNumber);
+       }
+
+       public int getTimestamp()
+    {
+               return timestamp;
+       }
+
+    public KerberosKey getKerberosKey()
+    {
+        return key;
+    }
+
+    private String getString(ByteBuffer buf, int length)
+    {
+        byte[] bytes = new byte[length];
+        buf.get(bytes);
+        return new String(bytes);
+    }
+
+       private int toShort(short s)
+    {
+               return kt_vno == KeytabStore.VNO_2 ? s : htons(s);
+       }
+
+       private int toInt(int s)
+    {
+               return kt_vno == KeytabStore.VNO_2 ? s : htonl(s);
+       }
+
+       private short htons(short x)
+    {
+           return isLittleEndian ? (short)((0x0000ff00 & x) >>> 8 | x << 8) : 
x;
+       }
+
+    private int htonl(int x)
+    {
+           return isLittleEndian ? x >>> 24 | x << 24 | (0x00ff0000 & x) >>> 8 
|
+               (0x0000ff00 & x) << 8 : x;
+       }
+}
+

Added: 
incubator/directory/kerberos/trunk/kerberos/src/java/org/apache/kerberos/kdc/store/keytab/KeytabException.java
==============================================================================
--- (empty file)
+++ 
incubator/directory/kerberos/trunk/kerberos/src/java/org/apache/kerberos/kdc/store/keytab/KeytabException.java
      Sun Nov  7 02:40:48 2004
@@ -0,0 +1,33 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.kerberos.kdc.store.keytab;
+
+import org.apache.kerberos.kdc.KerberosException;
+
+public class KeytabException extends KerberosException
+{
+       public static final KeytabException FILE_NOT_FOUND = new 
KeytabException(1, "KeytabStore file not found");
+       public static final KeytabException FILE_CORRUPT = new 
KeytabException(2, "KeytabStore file corrupt");
+       public static final KeytabException FILE_VERSION_UNSUPPORTED = new 
KeytabException(3, "KeytabStore file version unsupported");
+       public static final KeytabException FILE_ENTRY_NOT_FOUND = new 
KeytabException(4, "KeytabStore file entry not found");
+
+       protected KeytabException(int ordinal, String s)
+    {
+               super(ordinal, s);
+       }
+}
+

Added: 
incubator/directory/kerberos/trunk/kerberos/src/java/org/apache/kerberos/kdc/store/keytab/KeytabStore.java
==============================================================================
--- (empty file)
+++ 
incubator/directory/kerberos/trunk/kerberos/src/java/org/apache/kerberos/kdc/store/keytab/KeytabStore.java
  Sun Nov  7 02:40:48 2004
@@ -0,0 +1,176 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.kerberos.kdc.store.keytab;
+
+import org.apache.kerberos.kdc.KerberosException;
+
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.HashMap;
+import java.util.Map;
+
+public class KeytabStore
+{
+    private static boolean isLittleEndian = false;
+
+       // KeytabStore version - DCE compatible
+       public static final int VNO_1 = 0x0501;
+       // KeytabStore version - MIT V5 compatible
+       public static final int VNO_2 = 0x0502;
+       
+    private File file;
+    private int keytabVersionNumber;
+
+    private Map entries = new HashMap();
+
+       public KeytabStore(String file)
+    {
+           this(new File(file));
+       }
+
+       public KeytabStore(File file)
+    {
+           this.file = file;
+       }
+
+       public synchronized void init() throws KerberosException
+    {
+           if (!file.exists())
+        {
+               throw KeytabException.FILE_NOT_FOUND;
+        }
+
+           try
+        {
+               RandomAccessFile raf = new RandomAccessFile(file, "r");
+
+               keytabVersionNumber = raf.readShort() & 0x0000ffff;
+
+               if (keytabVersionNumber != VNO_1 && keytabVersionNumber != 
VNO_2)
+            {
+               throw KeytabException.FILE_VERSION_UNSUPPORTED;
+            }
+
+            raf.seek(2);
+
+                       KeytabEntry entry = getNextEntry(raf);
+
+                       while (entry != null)
+            {
+                KerberosKey key = entry.getKerberosKey();
+                String principalName = key.getPrincipal().getName();
+
+                if (entries.containsKey(principalName))
+                {
+                    int currentKeyVersion = key.getVersionNumber();
+                    int previousKeyVersion = (( KerberosKey ) 
entries.get(principalName)).getVersionNumber();
+
+                               if (currentKeyVersion > previousKeyVersion)
+                    {
+                                       entries.put(principalName, key);
+                                   }
+                }
+                else
+                {
+                    entries.put(principalName, key);
+                }
+                               entry = getNextEntry(raf);
+                       }
+
+            raf.close();
+           }
+        catch (IOException e)
+        {
+               throw KeytabException.FILE_CORRUPT;
+           }
+       }
+
+       public KerberosKey getEntry(KerberosPrincipal principal) {
+        return ( KerberosKey ) entries.get( principal.getName() );
+       }
+
+       private synchronized KeytabEntry getNextEntry(RandomAccessFile raf) 
throws KeytabException
+    {
+           while (raf != null)
+        {
+               int length = 0;
+
+               try
+            {
+                   length = raf.readInt();
+               }
+            catch (EOFException e)
+            {
+                   break;
+               }
+            catch (IOException e)
+            {
+                   throw KeytabException.FILE_CORRUPT;
+               }
+
+               length = toInt(length);
+               boolean used = isUsed(length);
+               length = toInt31(length);
+
+               try
+            {
+                   if (used)
+                {
+                       byte[] bytes = new byte[length];
+                   raf.readFully(bytes);
+                       return new KeytabEntry(keytabVersionNumber, bytes);
+               }
+                   raf.seek(raf.getFilePointer() + length);
+               }
+            catch (EOFException e)
+            {
+                   break;
+               }
+            catch (IOException e)
+            {
+                   throw KeytabException.FILE_CORRUPT;
+               }
+           }
+           return null;
+       }
+
+       private int toInt(int s)
+    {
+           return keytabVersionNumber == VNO_2 ? s : htonl(s);
+       }
+
+       private int toInt31(int x)
+    {
+           return 0x07fffffff & x;
+       }
+
+       private boolean isUsed(int x)
+    {
+           return (0x80000000 & x) == 0;
+       }
+
+       private int htonl(int x)
+    {
+           return isLittleEndian ? x >>> 24 | x << 24 | (0x00ff0000 & x) >>> 8 
|
+               (0x0000ff00 & x) << 8 : x;
+       }
+}
+

Reply via email to