From directory-cvs-return-2112-apmail-incubator-directory-cvs-archive=incubator.apache.org@incubator.apache.org Sun Nov 07 10:11:16 2004 Return-Path: Delivered-To: apmail-incubator-directory-cvs-archive@www.apache.org Received: (qmail 11830 invoked from network); 7 Nov 2004 10:11:16 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 7 Nov 2004 10:11:16 -0000 Received: (qmail 26833 invoked by uid 500); 7 Nov 2004 10:11:15 -0000 Delivered-To: apmail-incubator-directory-cvs-archive@incubator.apache.org Received: (qmail 26797 invoked by uid 500); 7 Nov 2004 10:11:15 -0000 Mailing-List: contact directory-cvs-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: directory-dev@incubator.apache.org Delivered-To: mailing list directory-cvs@incubator.apache.org Received: (qmail 26784 invoked by uid 99); 7 Nov 2004 10:11:15 -0000 X-ASF-Spam-Status: No, hits=-10.0 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Sun, 07 Nov 2004 02:11:13 -0800 Received: (qmail 11772 invoked by uid 65534); 7 Nov 2004 10:11:12 -0000 Date: 7 Nov 2004 10:11:12 -0000 Message-ID: <20041107101112.11770.qmail@minotaur.apache.org> From: akarasulu@apache.org To: directory-cvs@incubator.apache.org Subject: svn commit: rev 56832 - in incubator/directory/kerberos/trunk/eve-kerberos/src: java/org/apache/kerberos/kdc test/org/apache/kerberos/kdc X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N Author: akarasulu Date: Sun Nov 7 02:11:12 2004 New Revision: 56832 Modified: incubator/directory/kerberos/trunk/eve-kerberos/src/java/org/apache/kerberos/kdc/EmbeddedEveStore.java incubator/directory/kerberos/trunk/eve-kerberos/src/test/org/apache/kerberos/kdc/EmbeddedEveStoreTest.java Log: added code to do the LDIF of entries but it is nto the greatedt stuff - more to follow tomorrow Modified: incubator/directory/kerberos/trunk/eve-kerberos/src/java/org/apache/kerberos/kdc/EmbeddedEveStore.java ============================================================================== --- incubator/directory/kerberos/trunk/eve-kerberos/src/java/org/apache/kerberos/kdc/EmbeddedEveStore.java (original) +++ incubator/directory/kerberos/trunk/eve-kerberos/src/java/org/apache/kerberos/kdc/EmbeddedEveStore.java Sun Nov 7 02:11:12 2004 @@ -18,14 +18,23 @@ import java.util.Hashtable; +import java.io.FileInputStream; +import java.io.File; import javax.security.auth.kerberos.KerberosPrincipal; -import javax.naming.NamingException; -import javax.naming.NamingEnumeration; +import javax.security.auth.kerberos.KerberosKey; +import javax.naming.*; import javax.naming.directory.*; import org.apache.kerberos.kdc.store.PrincipalStore; import org.apache.kerberos.kdc.store.PrincipalStoreEntry; import org.apache.kerberos.kdc.store.PrincipalStoreEntryModifier; +import org.apache.eve.jndi.EveContextFactory; +import org.apache.ldap.common.util.NestableRuntimeException; +import org.apache.ldap.common.name.LdapName; +import org.apache.ldap.common.ldif.LdifIterator; +import org.apache.ldap.common.ldif.LdifParserImpl; +import org.apache.ldap.common.ldif.LdifParser; +import org.apache.ldap.common.message.LockableAttributesImpl; /** @@ -41,13 +50,32 @@ // Krb5 Schema Attributes // ------------------------------------------------------------------------ - private static final String PRINCIPAL_NAME = "krb5PrincipalName"; - private static final String KEY_VERSION_NUMBER = "krb5KeyVersionNumber"; - private static final String ENCRYPTION_TYPE = "krb5EncryptionType"; - private static final String KEY = "krb5Key"; + /** + * The key of the property specifing where kdc users are stored. If this + * property is not set the store defaults to performing a subtree search + * from the DN in the {@link Context#PROVIDER_URL}. If it is present a more + * efficient search is conducted on the + */ + public static final String KDC_ENTRY_BASEDN_KEY = "kdc.entry.basedn"; + public static final String KDC_ENTRY_LDIF_FILE = "kdc.entry.ldif.file"; + + /** the krb5kdc schema key for a krb5KDCEntry */ + private static final String KEY_ATTR = "krb5Key"; + /** the krb5kdc schema key encryption type for a krb5KDCEntry */ + private static final String TYPE_ATTR = "krb5EncryptionType"; + /** the krb5kdc schema principal name for a krb5KDCEntry */ + private static final String PRINCIPAL_ATTR = "krb5PrincipalName"; + /** the krb5kdc schema key version identifier for a krb5KDCEntry */ + private static final String VERSION_ATTR = "krb5KeyVersionNumber"; /** JNDI environment properties and more */ private final Hashtable env; + /** a handle on the top initial context: get new context from this */ + private InitialDirContext ctx; + /** the search scope to use for reading entries */ + private int searchScope = SearchControls.SUBTREE_SCOPE; + /** the search base relative to provider URL to use for reading entries */ + private Name searchBaseDn; /** @@ -59,6 +87,7 @@ public EmbeddedEveStore( Hashtable env ) { this.env = ( Hashtable ) env.clone(); + this.env.put( Context.INITIAL_CONTEXT_FACTORY, EveContextFactory.class.getName() ); } @@ -67,17 +96,188 @@ * constructor. The JNDI default context factor and some other parameters * are automatically set though. This method then checks to see if the * suffix is installed and setup according to the needed DIT structure. + * + * Create some additional indices for the kerberos schema: namely on + * krb5PrincipalName. Also objectClass should be indexed as well. If these + * indices are not specified we should add them here. */ public void init() { + LdapName ctxRoot; + boolean isFirstStart = false; + + try + { + ctx = new InitialDirContext( env ); + } + catch ( NamingException e ) + { + // @todo for now until we can find a better means of error handling + e.printStackTrace(); + String msg = "Failed to create initial context for Eve provider"; + NestableRuntimeException fault; + fault = new NestableRuntimeException( msg, e ); + throw fault; + } + + // get the seach base if it has been set ------------------------------ + if ( env.containsKey( KDC_ENTRY_BASEDN_KEY ) ) + { + try + { + ctxRoot = new LdapName( ctx.getNameInNamespace() ); + searchBaseDn = new LdapName( ( String ) env.get( KDC_ENTRY_BASEDN_KEY ) ); + if ( searchBaseDn.startsWith( ctxRoot ) ) + { + for ( int ii = 0; ii < ctxRoot.size(); ii++ ) + { + searchBaseDn.remove( 0 ); + } + } + else + { + String msg = "Failed to create initial context for Eve provider"; + IllegalArgumentException fault; + fault = new IllegalArgumentException( msg ); + throw fault; + } + } + catch ( NamingException e ) + { + // @todo for now until we can find a better means of error handling + e.printStackTrace(); + String msg = "Failed to find search base for Eve store"; + NestableRuntimeException fault; + fault = new NestableRuntimeException( msg, e ); + throw fault; + } + } + + + // check and see if we have the search base if not we create it + try + { + Attributes attrs = ctx.getAttributes( searchBaseDn ); + if ( attrs == null ) + { + isFirstStart = true; + } + } + catch ( NamingException e ) + { + // @todo for now until we can find a better means of error handling + e.printStackTrace(); + String msg = "looks like the context does not exist"; + isFirstStart = true; + System.out.println( msg ); + } + + // An LDIF must be loaded if this is the first time we're starting + // otherwise we're done and ready to serve lookup requests + if ( ! isFirstStart || ! env.containsKey( KDC_ENTRY_LDIF_FILE ) ) + { + return; + } + + try + { + String ldifFile = ( String ) env.get( KDC_ENTRY_LDIF_FILE ); + FileInputStream in = new FileInputStream( ldifFile ); + LdifIterator iterator = new LdifIterator( in ); + LdifParser ldifParser = new LdifParserImpl(); + + while ( iterator.hasNext() ) + { + String ldif = ( String ) iterator.next(); + Attributes attributes = new LockableAttributesImpl(); + ldifParser.parse( attributes, ldif ); + String dn = ( String ) attributes.remove( "dn" ).get(); + + if ( attributes.get( "krb5KDCEntry" ) != null ) + { + String pw = ( String ) attributes.get( "userpassword" ).get(); + String krbPrincipal = ( String ) attributes.get( PRINCIPAL_ATTR ).get(); + KerberosPrincipal principal = new KerberosPrincipal( krbPrincipal ); + KerberosKey key = new KerberosKey( principal, pw.toCharArray(), "DES" ) ; + byte[] encodedKey = key.getEncoded(); + attributes.put( KEY_ATTR, encodedKey ); + attributes.put( VERSION_ATTR, Integer.toString( key.getVersionNumber() ) ); + attributes.put( TYPE_ATTR, Integer.toString( key.getKeyType() ) ); + } + + ctx.createSubcontext( getRelativeName( ctx, dn ), attributes ); + } + } + catch( Exception e ) + { + // @todo for now until we can find a better means of error handling + e.printStackTrace(); + String msg = "Failed to import initial LDIF into Eve store"; + NestableRuntimeException fault; + fault = new NestableRuntimeException( msg, e ); + throw fault; + } + + + try + { + String ldifFile = ( String ) env.get( KDC_ENTRY_LDIF_FILE ); + FileInputStream in = new FileInputStream( ldifFile ); + LdifIterator iterator = new LdifIterator( in ); + LdifParser ldifParser = new LdifParserImpl(); + + while ( iterator.hasNext() ) + { + String ldif = ( String ) iterator.next(); + Attributes attributes = new LockableAttributesImpl(); + ldifParser.parse( attributes, ldif ); + String dn = ( String ) attributes.remove( "dn" ).get(); + + Context stored = ( Context ) ctx.lookup( getRelativeName( ctx, dn ) ); + + if ( stored == null ) + { + throw new IllegalStateException( "LDIF entries not being pushed to disk" ); + } + } + } + catch( Exception e ) + { + // @todo for now until we can find a better means of error handling + e.printStackTrace(); + String msg = "Failed to import initial LDIF into Eve store"; + NestableRuntimeException fault; + fault = new NestableRuntimeException( msg, e ); + throw fault; + } } - public PrincipalStoreEntry getEntry( KerberosPrincipal principal ) throws KerberosException + public Name getRelativeName( Context base, String dn ) throws NamingException { - InitialDirContext ctx = null; + LdapName rdn = new LdapName( dn ); + LdapName baseDn = new LdapName( base.getNameInNamespace() ); + + if ( rdn.startsWith( baseDn ) ) + { + for ( int ii = 0; ii < baseDn.size(); ii++ ) + { + rdn.remove( 0 ); + } + } + else + { + throw new NamingException( dn + " is not a subordinate of context:" + + baseDn.toString() ); + } + + return rdn; + } + + public PrincipalStoreEntry getEntry( KerberosPrincipal principal ) throws KerberosException + { if ( principal == null ) { return null; @@ -85,32 +285,43 @@ try { - ctx = new InitialDirContext( env ); + NamingEnumeration list = ctx.list( searchBaseDn ); + while ( list.hasMore() ) + { + NameClassPair pair = ( NameClassPair ) list.next(); + System.out.println( pair.getName() ); + } } catch ( NamingException e ) { e.printStackTrace(); - return null; } StringBuffer filter = new StringBuffer(); - filter.append( "(& (" ); - filter.append( PRINCIPAL_NAME ); + filter.append( "(" ); + filter.append( PRINCIPAL_ATTR ); filter.append( '=' ); filter.append( principal.getName() ); - filter.append( ") ( objectClass = krb5KDCEntry ) )" ); + filter.append( ")" ); SearchControls ctrls = new SearchControls(); + ctrls.setSearchScope( searchScope ); try { Attributes attrs = null; - NamingEnumeration list = ctx.search( "ou=users", filter.toString(), ctrls ); + NamingEnumeration list = ctx.search( searchBaseDn, filter.toString(), ctrls ); if ( list.hasMore() ) { SearchResult result = ( SearchResult ) list.next(); attrs = result.getAttributes(); } list.close(); + + if ( attrs == null ) + { + return null; + } + return getEntry( attrs ); } catch ( NamingException e ) @@ -131,10 +342,10 @@ private PrincipalStoreEntry getEntry( Attributes attrs ) throws NamingException { PrincipalStoreEntryModifier modifier = new PrincipalStoreEntryModifier(); - String principal = (String) attrs.get( PRINCIPAL_NAME ).get(); - String encryptionType = (String) attrs.get( ENCRYPTION_TYPE ).get(); - String keyVersionNumber = (String) attrs.get( KEY_VERSION_NUMBER ).get(); - byte[] keyBytes = (byte[]) attrs.get( KEY ).get(); + String principal = (String) attrs.get( PRINCIPAL_ATTR ).get(); + String encryptionType = (String) attrs.get( TYPE_ATTR ).get(); + String keyVersionNumber = (String) attrs.get( VERSION_ATTR ).get(); + byte[] keyBytes = (byte[]) attrs.get( KEY_ATTR ).get(); modifier.setPrincipal( new KerberosPrincipal( principal ) ); modifier.setEncryptionType( Integer.parseInt( encryptionType ) ); Modified: incubator/directory/kerberos/trunk/eve-kerberos/src/test/org/apache/kerberos/kdc/EmbeddedEveStoreTest.java ============================================================================== --- incubator/directory/kerberos/trunk/eve-kerberos/src/test/org/apache/kerberos/kdc/EmbeddedEveStoreTest.java (original) +++ incubator/directory/kerberos/trunk/eve-kerberos/src/test/org/apache/kerberos/kdc/EmbeddedEveStoreTest.java Sun Nov 7 02:11:12 2004 @@ -59,9 +59,16 @@ env.put( EveContextFactory.INDICES_BASE_ENV + "example", "ou objectClass" ); env.put( EveContextFactory.ATTRIBUTES_BASE_ENV + "example", attrs ); + env.put( EmbeddedEveStore.KDC_ENTRY_LDIF_FILE, + "/home/akarasulu/projects/directory/kerberos/trunk/eve-kerberos/src/ldif/example.com" ); + env.put( EmbeddedEveStore.KDC_ENTRY_BASEDN_KEY, "ou=People,dc=example,dc=com" ); + EmbeddedEveStore store = new EmbeddedEveStore( env ); store.init(); assertNull( store.getEntry( null ) ); + + KerberosPrincipal scarter = new KerberosPrincipal( "scarter@EXAMPLE.COM" ); + assertNotNull( store.getEntry( scarter ) ); }