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