You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by er...@apache.org on 2004/11/07 11:40:49 UTC

svn commit: rev 56838 - incubator/directory/kerberos/trunk/kerberos/src/java/org/apache/kerberos/kdc/store/keytab

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;
+	}
+}
+