Author: erodriguez Date: Thu Oct 21 05:54:26 2004 New Revision: 55219 Added: incubator/directory/kerberos/trunk/source/main/org/apache/kerberos/kdc/store/LdapStore.java Removed: incubator/directory/kerberos/trunk/source/main/org/apache/kerberos/kdc/store/KdcSchema.java Log: PrincipalStore implementation for LDAP, tested against OpenLDAP.
Added: incubator/directory/kerberos/trunk/source/main/org/apache/kerberos/kdc/store/LdapStore.java ============================================================================== --- (empty file) +++ incubator/directory/kerberos/trunk/source/main/org/apache/kerberos/kdc/store/LdapStore.java Thu Oct 21 05:54:26 2004 @@ -0,0 +1,151 @@ +/* + * 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; + +import org.apache.kerberos.kdc.*; +import org.apache.kerberos.kdc.jaas.*; +import org.apache.kerberos.messages.value.*; + +import java.security.*; +import java.util.*; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.security.auth.*; + +public class LdapStore implements PrincipalStore { + + public static final String PRINCIPAL_NAME = "krb5PrincipalName"; + public static final String KEY_VERSION_NUMBER = "krb5KeyVersionNumber"; + public static final String MAX_LIFE = "krb5MaxLife"; + public static final String MAX_RENEW = "krb5MaxRenew"; + public static final String KDC_FLAGS = "krb5KDCFlags"; + public static final String ENCRYPTION_TYPE = "krb5EncryptionType"; + public static final String VALID_START = "krb5ValidStart"; + public static final String VALID_END = "krb5ValidEnd"; + public static final String PASSWORD_END = "krb5PasswordEnd"; + public static final String KEY = "krb5Key"; + public static final String PRINCIPAL_REALM = "krb5PrincipalRealm"; + public static final String REALM_NAME = "krb5RealmName"; + + private Subject _subject; + + public void init() { + if (_subject == null) { + KdcSubject subjectLogin = new KdcSubjectLogin(LocalConfig.KDC_PRINCIPAL, + LocalConfig.KDC_PASSPHRASE); + _subject = subjectLogin.getSubject(); + System.out.println("Subject >>>" + _subject); + } + } + + public PrincipalStoreEntry getEntry(PrincipalName name) { + return (PrincipalStoreEntry)Subject.doAs(_subject, new JaasLdapLookupAction(name)); + } +} + +class JaasLdapLookupAction implements PrivilegedAction { + + private PrincipalName _principal; + private PrincipalStoreEntry _entry; + + public JaasLdapLookupAction(PrincipalName principal) { + _principal = principal; + } + + public Object run() { + performJndiOperation(); + return _entry; + } + + private void performJndiOperation() { + + // Set up environment for initial context + Hashtable env = new Hashtable(); + env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + env.put(Context.PROVIDER_URL, LocalConfig.JNDI_PROVIDER_URL); + // Request that the key be returned as binary, not String + env.put("java.naming.ldap.attributes.binary", "krb5Key"); + // Request the use of SASL-GSSAPI, using already established Kerberos credentials + env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI"); + // Request mutual authentication + env.put("javax.security.sasl.server.authentication", "true"); + // Request authentication with integrity and privacy protection + env.put("javax.security.sasl.qop", "auth-conf"); + // Request high-strength cryptographic protection + env.put("javax.security.sasl.strength", "high"); + + try { + DirContext ctx = new InitialDirContext(env); + + search(ctx); + + ctx.close(); + } catch (NamingException e) { + e.printStackTrace(); + } + } + + private void search(DirContext ctx) { + + try { + String[] attrIDs = {LdapStore.PRINCIPAL_NAME, LdapStore.KEY_VERSION_NUMBER, + LdapStore.ENCRYPTION_TYPE, LdapStore.KEY}; + + Attributes matchAttrs = new BasicAttributes(false); // case-sensitive + matchAttrs.put(new BasicAttribute(LdapStore.PRINCIPAL_NAME, _principal)); + matchAttrs.put(new BasicAttribute(LdapStore.KEY)); + matchAttrs.put(new BasicAttribute(LdapStore.ENCRYPTION_TYPE)); + matchAttrs.put(new BasicAttribute(LdapStore.KEY_VERSION_NUMBER)); + + // Search for objects that have those matching attributes + NamingEnumeration answer = ctx.search("", matchAttrs, attrIDs); + + getFirstEntry(answer); + + } catch (NamingException e) { + System.err.println("Problem getting attribute: " + e); + } + } + + private void getFirstEntry(NamingEnumeration enum) { + + PrincipalStoreEntryModifier modifier = new PrincipalStoreEntryModifier(); + + try { + SearchResult sr = (SearchResult) enum.next(); + if (sr != null) { + System.out.println(">>>" + sr.getName()); + Attributes attrs = sr.getAttributes(); + + String principal = (String) attrs.get(LdapStore.PRINCIPAL_NAME).get(); + String encryptionType = (String) attrs.get(LdapStore.ENCRYPTION_TYPE).get(); + String keyVersionNumber = (String) attrs.get(LdapStore.KEY_VERSION_NUMBER).get(); + byte[] keyBytes = (byte[]) attrs.get(LdapStore.KEY).get(); + + modifier.setPrincipalName(principal); + modifier.setEncryptionType(Integer.parseInt(encryptionType)); + modifier.setEncryptionType(Integer.parseInt(keyVersionNumber)); + modifier.setKey(keyBytes); + } + } catch (NamingException e) { + e.printStackTrace(); + } + _entry = modifier.getEntry(); + } +} +
