You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2013/02/06 15:13:00 UTC
svn commit: r1442971 -
/directory/apacheds/trunk/interceptor-kerberos/src/main/java/org/apache/directory/server/core/kerberos/KeyDerivationInterceptor.java
Author: elecharny
Date: Wed Feb 6 14:12:59 2013
New Revision: 1442971
URL: http://svn.apache.org/viewvc?rev=1442971&view=rev
Log:
o Added a dedicated KERBEROS logger
o Added an init() method
o Used pre-initialized AT all over the class
o Added the missing Javadoc
o Simplified the code by using the LDAP API more closely
o Used StringBuilder instead of StringBuffer
o Made some methods private
Modified:
directory/apacheds/trunk/interceptor-kerberos/src/main/java/org/apache/directory/server/core/kerberos/KeyDerivationInterceptor.java
Modified: directory/apacheds/trunk/interceptor-kerberos/src/main/java/org/apache/directory/server/core/kerberos/KeyDerivationInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptor-kerberos/src/main/java/org/apache/directory/server/core/kerberos/KeyDerivationInterceptor.java?rev=1442971&r1=1442970&r2=1442971&view=diff
==============================================================================
--- directory/apacheds/trunk/interceptor-kerberos/src/main/java/org/apache/directory/server/core/kerberos/KeyDerivationInterceptor.java (original)
+++ directory/apacheds/trunk/interceptor-kerberos/src/main/java/org/apache/directory/server/core/kerberos/KeyDerivationInterceptor.java Wed Feb 6 14:12:59 2013
@@ -35,12 +35,12 @@ import org.apache.directory.api.ldap.mod
import org.apache.directory.api.ldap.model.entry.Modification;
import org.apache.directory.api.ldap.model.entry.ModificationOperation;
import org.apache.directory.api.ldap.model.entry.StringValue;
-import org.apache.directory.api.ldap.model.entry.Value;
import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.name.Dn;
-import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.util.Strings;
+import org.apache.directory.server.core.api.DirectoryService;
import org.apache.directory.server.core.api.entry.ClonedServerEntry;
import org.apache.directory.server.core.api.interceptor.BaseInterceptor;
import org.apache.directory.server.core.api.interceptor.Interceptor;
@@ -69,11 +69,24 @@ import org.slf4j.LoggerFactory;
public class KeyDerivationInterceptor extends BaseInterceptor
{
/** The log for this class. */
- private static final Logger log = LoggerFactory.getLogger( KeyDerivationInterceptor.class );
+ private static final Logger LOG = LoggerFactory.getLogger( KeyDerivationInterceptor.class );
+ private static final Logger LOG_KRB = LoggerFactory.getLogger( "KERBEROS" );
/** The service name. */
private static final String NAME = "keyDerivationService";
+ /** The KRB5_KEY attributeType */
+ private AttributeType KRB5_KEY_AT;
+
+ /** The KRB5_PRINCIPAL_NAME_AT attributeType */
+ private AttributeType KRB5_PRINCIPAL_NAME_AT;
+
+ /** The KRB5_KEY_VERSION_NUMBER_AT attributeType */
+ private AttributeType KRB5_KEY_VERSION_NUMBER_AT;
+
+ /** The USER_PASSWORD_AT attributeType */
+ private AttributeType USER_PASSWORD_AT;
+
/**
* Creates an instance of a KeyDerivationInterceptor.
@@ -85,54 +98,76 @@ public class KeyDerivationInterceptor ex
/**
- * Intercept the addition of the 'userPassword' and 'krb5PrincipalName' attributes. Use the 'userPassword'
- * and 'krb5PrincipalName' attributes to derive Kerberos keys for the principal. If the 'userPassword' is
- * the special keyword 'randomKey', set random keys for the principal. Set the key version number (kvno)
- * to '0'.
+ * {@inheritDoc}
+ */
+ public void init( DirectoryService directoryService ) throws LdapException
+ {
+ super.init( directoryService );
+
+ KRB5_KEY_AT = schemaManager.lookupAttributeTypeRegistry( KerberosAttribute.KRB5_KEY_AT );
+ KRB5_PRINCIPAL_NAME_AT = schemaManager.lookupAttributeTypeRegistry( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT );
+ KRB5_KEY_VERSION_NUMBER_AT = schemaManager
+ .lookupAttributeTypeRegistry( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT );
+ USER_PASSWORD_AT = schemaManager
+ .lookupAttributeTypeRegistry( SchemaConstants.USER_PASSWORD_AT );
+
+ LOG_KRB.info( "KeyDerivation Interceptor initialized" );
+ }
+
+
+ /**
+ * Intercepts the addition of the 'userPassword' and 'krb5PrincipalName' attributes.
+ * Uses the 'userPassword' and 'krb5PrincipalName' attributes to derive Kerberos keys
+ * for the principal. If the 'userPassword' is the special keyword 'randomKey', set
+ * random keys for the principal. Set the key version number (kvno) to '0'.
*/
public void add( AddOperationContext addContext ) throws LdapException
{
+ // Bypass the replication events
if ( addContext.isReplEvent() )
{
next( addContext );
+
return;
}
-
+
Dn normName = addContext.getDn();
Entry entry = addContext.getEntry();
- if ( ( entry.get( SchemaConstants.USER_PASSWORD_AT ) != null ) &&
- ( entry.get( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT ) != null ) )
+ if ( ( entry.get( USER_PASSWORD_AT ) != null ) &&
+ ( entry.get( KRB5_PRINCIPAL_NAME_AT ) != null ) )
{
- log.debug( "Adding the entry '{}' for Dn '{}'.", entry, normName.getName() );
+ LOG.debug( "Adding the entry '{}' for Dn '{}'.", entry, normName.getName() );
- BinaryValue userPassword = ( BinaryValue ) entry.get( SchemaConstants.USER_PASSWORD_AT ).get();
+ BinaryValue userPassword = ( BinaryValue ) entry.get( USER_PASSWORD_AT ).get();
String strUserPassword = userPassword.getString();
- if ( log.isDebugEnabled() )
+ if ( LOG.isDebugEnabled() )
{
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
sb.append( "'" + strUserPassword + "' ( " );
sb.append( userPassword );
sb.append( " )" );
- log.debug( "Adding Attribute id : 'userPassword', Values : [ {} ]", sb.toString() );
+ LOG.debug( "Adding Attribute id : 'userPassword', Values : [ {} ]", sb.toString() );
}
- Value<?> principalNameValue = entry.get( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT ).get();
-
- String principalName = principalNameValue.getString();
+ String principalName = entry.get( KRB5_PRINCIPAL_NAME_AT ).getString();
- log.debug( "Got principal '{}' with userPassword '{}'.", principalName, strUserPassword );
+ LOG.debug( "Got principal '{}' with userPassword '{}'.", principalName, strUserPassword );
+ LOG_KRB.debug( "Got principal '{}' with userPassword '{}'.", principalName, strUserPassword );
Map<EncryptionType, EncryptionKey> keys = generateKeys( principalName, strUserPassword );
- entry.put( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, principalName );
- entry.put( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT, "0" );
+ entry.put( KRB5_PRINCIPAL_NAME_AT, principalName );
+ entry.put( KRB5_KEY_VERSION_NUMBER_AT, "0" );
- entry.put( getKeyAttribute( addContext.getSession().getDirectoryService().getSchemaManager(), keys ) );
+ Attribute keyAttribute = getKeyAttribute( keys );
+ entry.put( keyAttribute );
- log.debug( "Adding modified entry '{}' for Dn '{}'.", entry, normName
+ LOG.debug( "Adding modified entry '{}' for Dn '{}'.", entry, normName
+ .getName() );
+ LOG_KRB.debug( "Adding modified entry '{}' for Dn '{}'.", entry, normName
.getName() );
}
@@ -153,12 +188,13 @@ public class KeyDerivationInterceptor ex
*/
public void modify( ModifyOperationContext modContext ) throws LdapException
{
- if( modContext.isReplEvent() )
+ // bypass replication events
+ if ( modContext.isReplEvent() )
{
next( modContext );
return;
}
-
+
ModifySubContext subContext = new ModifySubContext();
detectPasswordModification( modContext, subContext );
@@ -181,11 +217,11 @@ public class KeyDerivationInterceptor ex
* Detect password modification by checking the modify request for the 'userPassword'. Additionally,
* check to see if a 'krb5PrincipalName' was provided.
*
- * @param modContext
- * @param subContext
- * @throws LdapException
+ * @param modContext The original ModifyContext
+ * @param subContext The modification container
+ * @throws LdapException If we get an exception
*/
- void detectPasswordModification( ModifyOperationContext modContext, ModifySubContext subContext )
+ private void detectPasswordModification( ModifyOperationContext modContext, ModifySubContext subContext )
throws LdapException
{
List<Modification> mods = modContext.getModItems();
@@ -195,7 +231,7 @@ public class KeyDerivationInterceptor ex
// Loop over attributes being modified to pick out 'userPassword' and 'krb5PrincipalName'.
for ( Modification mod : mods )
{
- if ( log.isDebugEnabled() )
+ if ( LOG.isDebugEnabled() )
{
switch ( mod.getOperation() )
{
@@ -215,7 +251,7 @@ public class KeyDerivationInterceptor ex
Attribute attr = mod.getAttribute();
- if ( SchemaConstants.USER_PASSWORD_AT_OID.equals( attr.getAttributeType().getOid() ) )
+ if ( USER_PASSWORD_AT.equals( attr.getAttributeType() ) )
{
Object firstValue = attr.get();
String password = null;
@@ -223,30 +259,34 @@ public class KeyDerivationInterceptor ex
if ( firstValue instanceof StringValue )
{
password = ( ( StringValue ) firstValue ).getString();
- log.debug( "{} Attribute id : 'userPassword', Values : [ '{}' ]", operation, password );
+ LOG.debug( "{} Attribute id : 'userPassword', Values : [ '{}' ]", operation, password );
+ LOG_KRB.debug( "{} Attribute id : 'userPassword', Values : [ '{}' ]", operation, password );
}
else if ( firstValue instanceof BinaryValue )
{
password = ( ( BinaryValue ) firstValue ).getString();
- if ( log.isDebugEnabled() )
+ if ( LOG.isDebugEnabled() )
{
StringBuffer sb = new StringBuffer();
sb.append( "'" + password + "' ( " );
sb.append( Strings.dumpBytes( ( ( BinaryValue ) firstValue ).getBytes() ).trim() );
sb.append( " )" );
- log.debug( "{} Attribute id : 'userPassword', Values : [ {} ]", operation, sb.toString() );
+ LOG.debug( "{} Attribute id : 'userPassword', Values : [ {} ]", operation, sb.toString() );
+ LOG_KRB.debug( "{} Attribute id : 'userPassword', Values : [ {} ]", operation, sb.toString() );
}
}
subContext.setUserPassword( password );
- log.debug( "Got userPassword '{}'.", subContext.getUserPassword() );
+ LOG.debug( "Got userPassword '{}'.", subContext.getUserPassword() );
+ LOG_KRB.debug( "Got userPassword '{}'.", subContext.getUserPassword() );
}
- if ( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT_OID.equals( attr.getAttributeType().getOid() ) )
+ if ( KRB5_PRINCIPAL_NAME_AT.equals( attr.getAttributeType() ) )
{
subContext.setPrincipalName( attr.getString() );
- log.debug( "Got principal '{}'.", subContext.getPrincipalName() );
+ LOG.debug( "Got principal '{}'.", subContext.getPrincipalName() );
+ LOG_KRB.debug( "Got principal '{}'.", subContext.getPrincipalName() );
}
}
}
@@ -255,19 +295,19 @@ public class KeyDerivationInterceptor ex
/**
* Lookup the principal's attributes that are relevant to executing key derivation.
*
- * @param modContext
- * @param subContext
- * @throws LdapException
+ * @param modContext The original ModifyContext
+ * @param subContext The modification container
+ * @throws LdapException If we get an exception
*/
- void lookupPrincipalAttributes( ModifyOperationContext modContext, ModifySubContext subContext )
+ private void lookupPrincipalAttributes( ModifyOperationContext modContext, ModifySubContext subContext )
throws LdapException
{
Dn principalDn = modContext.getDn();
LookupOperationContext lookupContext = modContext.newLookupContext( principalDn,
- SchemaConstants.OBJECT_CLASS_AT,
- KerberosAttribute.KRB5_PRINCIPAL_NAME_AT,
- KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT );
+ SchemaConstants.OBJECT_CLASS_AT,
+ KerberosAttribute.KRB5_PRINCIPAL_NAME_AT,
+ KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT );
Entry userEntry = directoryService.getPartitionNexus().lookup( lookupContext );
@@ -276,42 +316,44 @@ public class KeyDerivationInterceptor ex
throw new LdapAuthenticationException( I18n.err( I18n.ERR_512, principalDn ) );
}
- Attribute objectClass = ( ( ClonedServerEntry ) userEntry ).getOriginalEntry().get(
- SchemaConstants.OBJECT_CLASS_AT );
-
- if ( !objectClass.contains( SchemaConstants.KRB5_PRINCIPAL_OC ) )
+ if ( !( ( ClonedServerEntry ) userEntry ).getOriginalEntry().contains( OBJECT_CLASS_AT,
+ SchemaConstants.KRB5_PRINCIPAL_OC ) )
{
return;
}
else
{
subContext.isPrincipal( true );
- log.debug( "Dn {} is a Kerberos principal. Will attempt key derivation.", principalDn.getName() );
+ LOG.debug( "Dn {} is a Kerberos principal. Will attempt key derivation.", principalDn.getName() );
+ LOG_KRB.debug( "Dn {} is a Kerberos principal. Will attempt key derivation.", principalDn.getName() );
}
if ( subContext.getPrincipalName() == null )
{
Attribute principalAttribute = ( ( ClonedServerEntry ) userEntry ).getOriginalEntry().get(
- KerberosAttribute.KRB5_PRINCIPAL_NAME_AT );
+ KRB5_PRINCIPAL_NAME_AT );
String principalName = principalAttribute.getString();
subContext.setPrincipalName( principalName );
- log.debug( "Found principal '{}' from lookup.", principalName );
+ LOG.debug( "Found principal '{}' from lookup.", principalName );
+ LOG_KRB.debug( "Found principal '{}' from lookup.", principalName );
}
Attribute keyVersionNumberAttr = ( ( ClonedServerEntry ) userEntry ).getOriginalEntry().get(
- KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT );
+ KRB5_KEY_VERSION_NUMBER_AT );
if ( keyVersionNumberAttr == null )
{
subContext.setNewKeyVersionNumber( 0 );
- log.debug( "Key version number was null, setting to 0." );
+ LOG.debug( "Key version number was null, setting to 0." );
+ LOG_KRB.debug( "Key version number was null, setting to 0." );
}
else
{
int oldKeyVersionNumber = Integer.valueOf( keyVersionNumberAttr.getString() );
int newKeyVersionNumber = oldKeyVersionNumber + 1;
subContext.setNewKeyVersionNumber( newKeyVersionNumber );
- log.debug( "Found key version number '{}', setting to '{}'.", oldKeyVersionNumber, newKeyVersionNumber );
+ LOG.debug( "Found key version number '{}', setting to '{}'.", oldKeyVersionNumber, newKeyVersionNumber );
+ LOG_KRB.debug( "Found key version number '{}', setting to '{}'.", oldKeyVersionNumber, newKeyVersionNumber );
}
}
@@ -321,8 +363,8 @@ public class KeyDerivationInterceptor ex
*
* If the 'userPassword' is the special keyword 'randomKey', set random keys for the principal.
*
- * @param modContext
- * @param subContext
+ * @param modContext The original ModifyContext
+ * @param subContext The modification container
*/
void deriveKeys( ModifyOperationContext modContext, ModifySubContext subContext ) throws LdapException
{
@@ -332,7 +374,8 @@ public class KeyDerivationInterceptor ex
String userPassword = subContext.getUserPassword();
int kvno = subContext.getNewKeyVersionNumber();
- log.debug( "Got principal '{}' with userPassword '{}'.", principalName, userPassword );
+ LOG.debug( "Got principal '{}' with userPassword '{}'.", principalName, userPassword );
+ LOG_KRB.debug( "Got principal '{}' with userPassword '{}'.", principalName, userPassword );
Map<EncryptionType, EncryptionKey> keys = generateKeys( principalName, userPassword );
@@ -344,39 +387,47 @@ public class KeyDerivationInterceptor ex
newModsList.add( mod );
}
- SchemaManager schemaManager = modContext.getSession()
- .getDirectoryService().getSchemaManager();
-
// Add our modification items.
- newModsList.add(
+ Modification krb5PrincipalName =
new DefaultModification(
ModificationOperation.REPLACE_ATTRIBUTE,
new DefaultAttribute(
- KerberosAttribute.KRB5_PRINCIPAL_NAME_AT,
- schemaManager.lookupAttributeTypeRegistry( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT ),
- principalName ) ) );
- newModsList.add(
+ KRB5_PRINCIPAL_NAME_AT,
+ principalName ) );
+ newModsList.add( krb5PrincipalName );
+
+ Modification krb5KeyVersionNumber =
new DefaultModification(
ModificationOperation.REPLACE_ATTRIBUTE,
new DefaultAttribute(
- KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT,
- schemaManager.lookupAttributeTypeRegistry( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ),
- Integer.toString( kvno ) ) ) );
+ KRB5_KEY_VERSION_NUMBER_AT,
+ Integer.toString( kvno ) ) );
- Attribute attribute = getKeyAttribute( modContext.getSession()
- .getDirectoryService().getSchemaManager(), keys );
+ newModsList.add( krb5KeyVersionNumber );
+
+ Attribute attribute = getKeyAttribute( keys );
newModsList.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attribute ) );
+ LOG.debug( "Added two modifications to the current request : {} and {}", krb5PrincipalName,
+ krb5KeyVersionNumber );
+ LOG_KRB.debug( "Added two modifications to the current request : {} and {}", krb5PrincipalName,
+ krb5KeyVersionNumber );
+
modContext.setModItems( newModsList );
}
- private Attribute getKeyAttribute( SchemaManager schemaManager, Map<EncryptionType, EncryptionKey> keys )
+ /**
+ * Create the KRB5_KEY attribute with all the associated keys.
+ *
+ * @param keys The keys to inject in the attribute
+ * @return The create attribute
+ * @throws LdapException If we had an error while adding a key in the attribute
+ */
+ private Attribute getKeyAttribute( Map<EncryptionType, EncryptionKey> keys )
throws LdapException
{
- Attribute keyAttribute =
- new DefaultAttribute( KerberosAttribute.KRB5_KEY_AT,
- schemaManager.lookupAttributeTypeRegistry( KerberosAttribute.KRB5_KEY_AT ) );
+ Attribute keyAttribute = new DefaultAttribute( KRB5_KEY_AT );
for ( EncryptionKey encryptionKey : keys.values() )
{
@@ -388,7 +439,8 @@ public class KeyDerivationInterceptor ex
}
catch ( EncoderException ioe )
{
- log.error( I18n.err( I18n.ERR_122 ), ioe );
+ LOG.error( I18n.err( I18n.ERR_122 ), ioe );
+ LOG_KRB.error( I18n.err( I18n.ERR_122 ), ioe );
}
}
@@ -396,6 +448,13 @@ public class KeyDerivationInterceptor ex
}
+ /**
+ * Generate the keys.
+ *
+ * @param principalName The Principal
+ * @param userPassword Its password
+ * @return A Map of keys
+ */
private Map<EncryptionType, EncryptionKey> generateKeys( String principalName, String userPassword )
{
if ( userPassword.equalsIgnoreCase( "randomKey" ) )
@@ -407,7 +466,9 @@ public class KeyDerivationInterceptor ex
}
catch ( KerberosException ke )
{
- log.debug( ke.getLocalizedMessage(), ke );
+ LOG.debug( ke.getLocalizedMessage(), ke );
+ LOG_KRB.debug( ke.getLocalizedMessage(), ke );
+
return null;
}
}
@@ -418,11 +479,23 @@ public class KeyDerivationInterceptor ex
}
}
+ /**
+ * A ModifyContext used to store the changes made to the original context. This
+ * is used while processing a ModifyOperation and will be injected in the
+ * original ModifyContext.
+ */
static class ModifySubContext
{
+ /** Tells if this is a principal */
private boolean isPrincipal = false;
+
+ /** The Principal name */
private String principalName;
+
+ /** The User password */
private String userPassword;
+
+ /** The Key version */
private int newKeyVersionNumber = -1;
@@ -476,7 +549,7 @@ public class KeyDerivationInterceptor ex
boolean hasValues()
{
- return userPassword != null && principalName != null && newKeyVersionNumber > -1;
+ return ( userPassword != null ) && ( principalName != null ) && ( newKeyVersionNumber > -1 );
}
}
}