You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tb...@apache.org on 2006/12/12 16:24:14 UTC

svn commit: r486187 [16/49] - in /directory/trunks/triplesec: ./ admin-api/ admin-api/src/ admin-api/src/main/ admin-api/src/main/java/ admin-api/src/main/java/org/ admin-api/src/main/java/org/safehaus/ admin-api/src/main/java/org/safehaus/triplesec/ a...

Added: directory/trunks/triplesec/integration/src/test/resources/server.xml
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/integration/src/test/resources/server.xml?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/integration/src/test/resources/server.xml (added)
+++ directory/trunks/triplesec/integration/src/test/resources/server.xml Tue Dec 12 07:23:31 2006
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
+  "http://www.springframework.org/dtd/spring-beans.dtd">
+
+<beans>
+  <bean id="environment" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
+    <property name="properties">
+      <props>
+        <prop key="java.naming.security.authentication">simple</prop>
+        <prop key="java.naming.security.principal">uid=admin,ou=system</prop>
+        <prop key="java.naming.security.credentials">secret</prop>
+        <prop key="java.naming.provider.url">dc=example,dc=com</prop>
+        <prop key="java.naming.factory.state">org.safehaus.triplesec.store.ProfileStateFactory</prop>
+        <prop key="java.naming.factory.object">org.safehaus.triplesec.store.ProfileObjectFactory</prop>
+
+        <prop key="kdc.primary.realm">EXAMPLE.COM</prop>
+        <prop key="kdc.principal">krbtgt/EXAMPLE.COM@EXAMPLE.COM</prop>
+        <prop key="kdc.encryption.types">des-cbc-md5 des3-cbc-sha1 des3-cbc-md5 des-cbc-md4 des-cbc-crc</prop>
+        <prop key="kdc.entryBaseDn">ou=users,dc=example,dc=com</prop>
+        <prop key="kdc.java.naming.security.credentials">secret</prop>
+
+        <prop key="changepw.entryBaseDn">ou=users,dc=example,dc=com</prop>
+        <prop key="changepw.java.naming.security.credentials">secret</prop>
+        <prop key="changepw.principal">kadmin/changepw@EXAMPLE.COM</prop>
+
+        <!-- All times are in minutes -->
+        <prop key="kdc.allowable.clockskew">5</prop>
+        <prop key="kdc.tgs.maximum.ticket.lifetime">1440</prop>
+        <prop key="kdc.tgs.maximum.renewable.lifetime">10080</prop>
+        <prop key="kdc.pa.enc.timestamp.required">true</prop>
+        <prop key="kdc.tgs.empty.addresses.allowed">true</prop>
+        <prop key="kdc.tgs.forwardable.allowed">true</prop>
+        <prop key="kdc.tgs.proxiable.allowed">true</prop>
+        <prop key="kdc.tgs.postdate.allowed">true</prop>
+        <prop key="kdc.tgs.renewable.allowed">true</prop>
+
+        <prop key="safehaus.entry.basedn">ou=Users,dc=example,dc=com</prop>
+        <prop key="safehaus.load.testdata">true</prop>
+        <prop key="kerberos.sam.type.7">org.safehaus.triplesec.verifier.hotp.DefaultHotpSamVerifier</prop>
+      </props>
+    </property>
+  </bean>
+
+  <bean id="configuration" class="org.safehaus.triplesec.configuration.MutableTriplesecStartupConfiguration">
+    <property name="workingDirectory"><value>partitions</value></property>
+    <property name="allowAnonymousAccess"><value>false</value></property>
+    <property name="accessControlEnabled"><value>true</value></property>
+    <property name="ldapPort"><value>10389</value></property>
+    <property name="enableKerberos"><value>true</value></property>
+    <property name="enableNtp"><value>false</value></property>
+    <property name="enableChangePassword"><value>true</value></property>
+
+    <!-- Uncomment below to have the server load entries on startup!        -->
+    <!-- ldifDirectory property can point to a relative file, directory or  -->
+    <!-- can point to an absolute path to either using the URL path         -->
+    <!-- notation: i.e. file:///Users/jack/apacheds/ldifs                   -->
+
+    <!-- Entries will optionally be filtered using LdifLoadFilters in the   -->
+    <!-- order specified.  The included Krb5KdcEntryFilter will filter      -->
+    <!-- kerberos principals creating keys for them using their             -->
+    <!-- userPassword attribute if present.                                 -->
+
+    <!-- If missing the Triplesec server will use LDIF files under the conf -->
+    <!-- directory where it has been installed.                             -->
+
+    <!--
+    <property name="ldifDirectory">
+      <value>example.ldif</value>
+    </property>
+    -->
+    <property name="ldifFilters">
+      <list>
+        <bean class="org.apache.directory.server.protocol.shared.store.Krb5KdcEntryFilter"/>
+      </list>
+    </property>
+    
+    <property name="activationConfiguration">
+      <bean class="org.safehaus.triplesec.configuration.ActivationConfiguration">
+        <property name="enableDecoyMidlet"><value>true</value></property>
+        <property name="otpLength"><value>6</value></property>
+        <property name="midletNameAttribute"><value>midletNameAttribute</value></property>
+      </bean>  
+    </property>    
+    
+    <property name="smsConfiguration">
+      <bean class="org.safehaus.triplesec.configuration.SmsConfiguration">
+        <property name="smsUsername"><value>hauskeys</value></property>
+        <property name="smsPassword"><value>secret</value></property>
+        <property name="smsAccountName"><value>demo</value></property>
+        <property name="smsTransportUrl"><value>http://www.nbroadcasting.com/customers/messages/Sender.asp</value></property>
+      </bean>  
+    </property>    
+    
+    <property name="smtpConfiguration">
+      <bean class="org.safehaus.triplesec.configuration.SmtpConfiguration">
+        <property name="smtpAuthenticate"><value>false</value></property>
+        <!-- uncomment and set above property if authentication is required by mail server
+        <property name="smtpUsername"><value>hauskeys</value></property>
+        <property name="smtpPassword"><value>secret</value></property>
+        -->
+        <property name="smtpHost"><value>localhost</value></property>
+        <property name="smtpSubject"><value>Triplesec Account Activated</value></property>
+        <property name="smtpFrom"><value>dev@safehaus.org</value></property>
+      </bean>  
+    </property>    
+    
+    <property name="contextPartitionConfigurations">
+      <set>
+        <ref bean="examplePartitionConfiguration"/>
+      </set>
+    </property>
+    
+    <property name="bootstrapSchemas">
+      <set>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CorbaSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CoreSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CosineSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.ApacheSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CollectiveSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.InetorgpersonSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.JavaSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.Krb5kdcSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.SystemSchema"/>
+        <bean class="org.safehaus.triplesec.store.schema.SafehausSchema"/>
+      </set>
+    </property>
+    
+    <property name="extendedOperationHandlers">
+      <list>
+        <bean class="org.apache.directory.server.ldap.support.extended.GracefulShutdownHandler"/>
+        <bean class="org.apache.directory.server.ldap.support.extended.LaunchDiagnosticUiHandler"/>
+      </list>
+    </property>  
+
+    <property name="interceptorConfigurations">
+      <list>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>normalizationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.normalization.NormalizationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>authenticationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.authn.AuthenticationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>referralService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.referral.ReferralService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>authorizationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.authz.AuthorizationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>defaultAuthorizationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.authz.DefaultAuthorizationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>exceptionService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.exception.ExceptionService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>schemaService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.schema.SchemaService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>subentryService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.subtree.SubentryService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>operationalAttributeService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.operational.OperationalAttributeService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>collectiveAttributeService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.collective.CollectiveAttributeService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>eventService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.event.EventService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>policyProtectionService</value></property>
+          <property name="interceptor">
+            <bean class="org.safehaus.triplesec.store.interceptor.PolicyProtectionInterceptor" />
+          </property>
+        </bean>
+      </list>
+    </property>
+  </bean>
+  
+  <bean id="examplePartitionConfiguration" class="org.apache.directory.server.core.configuration.MutablePartitionConfiguration">
+    <property name="name"><value>example</value></property>
+    <property name="suffix"><value>dc=example,dc=com</value></property>
+    <property name="indexedAttributes">
+      <set>
+        <value>objectClass</value>
+        <value>ou</value>
+        <value>dc</value>
+        <value>uid</value>
+        <value>profileId</value>
+        <value>roles</value>
+        <value>grants</value>
+        <value>denials</value>
+        <value>krb5PrincipalName</value>
+      </set>
+    </property>
+    <property name="contextEntry">
+      <value>
+        objectClass: top
+        objectClass: domain
+        objectClass: extensibleObject
+        dc: example
+        administrativeRole: accessControlSpecificArea
+        administrativeRole: collectiveAttributeSpecificArea
+      </value>
+    </property>
+  </bean>
+
+  <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
+    <property name="customEditors">
+      <map>
+        <entry key="javax.naming.directory.Attributes">
+          <bean class="org.apache.directory.server.core.configuration.AttributesPropertyEditor"/>
+        </entry>
+      </map>
+   </property>
+  </bean>
+</beans>

Added: directory/trunks/triplesec/jaas/pom.xml
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/pom.xml?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/pom.xml (added)
+++ directory/trunks/triplesec/jaas/pom.xml Tue Dec 12 07:23:31 2006
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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. 
+-->
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.safehaus.triplesec</groupId>
+    <artifactId>build</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>triplesec-jaas</artifactId>
+  <name>Triplesec JAAS Login Module</name>
+  <packaging>jar</packaging>  
+  <description>
+    A Safehaue Triplsec JAAS LoginModule which accounts for SAM execeptions, and ties
+    in Guardian for authorization.
+  </description>
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>triplesec-crypto</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>triplesec-otp</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>triplesec-guardian-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>nlog4j</artifactId>
+      <version>1.2.25</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+</project>

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/AccountDisabledException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/AccountDisabledException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/AccountDisabledException.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/AccountDisabledException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,46 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+import org.safehaus.otp.HotpErrorConstants;
+
+
+/**
+ * Exception thrown when an account is locked.
+ *
+ * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class AccountDisabledException extends HotpLoginException
+{
+    private static final long serialVersionUID = -4104559423754529984L;
+
+
+    public AccountDisabledException()
+    {
+        super( HotpErrorConstants.DISABLED_VAL, HotpErrorConstants.DISABLED_MSG );
+    }
+
+
+    public AccountDisabledException( String s )
+    {
+        super( HotpErrorConstants.DISABLED_VAL, s );
+    }
+}

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/AccountLockedOutException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/AccountLockedOutException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/AccountLockedOutException.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/AccountLockedOutException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+
+import org.safehaus.otp.HotpErrorConstants;
+
+
+/**
+ * Exception thrown when a HOTP account is locked.
+ *
+ * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class AccountLockedOutException extends HotpLoginException
+{
+    private static final long serialVersionUID = 1L;
+
+
+    public AccountLockedOutException()
+    {
+        super( HotpErrorConstants.LOCKEDOUT_VAL, HotpErrorConstants.LOCKEDOUT_MSG );
+    }
+
+
+    public AccountLockedOutException( String s )
+    {
+        super( HotpErrorConstants.LOCKEDOUT_VAL, s );
+    }
+}

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/HotpLoginException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/HotpLoginException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/HotpLoginException.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/HotpLoginException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,96 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+
+import org.safehaus.otp.HotpErrorConstants;
+
+import javax.security.auth.login.LoginException;
+
+
+/**
+ * A Hotp specific SamException.
+ *
+ * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class HotpLoginException extends LoginException
+{
+    private static final long serialVersionUID = 1L;
+    /** the type of this exception */
+    private final int ordinal;
+
+
+    /**
+     * Creates a HotpLoginException using an ordinal.
+     *
+     * @param ordinal the ordinal for this exception type
+     */
+    public HotpLoginException( int ordinal )
+    {
+        super( ( String ) HotpErrorConstants.getErrorMessage( ordinal ) );
+
+        this.ordinal = ordinal;
+    }
+
+
+    /**
+     * Creates a HotpLoginException using an ordinal with string.  If the String argument
+     * does have a prefix on is inserted based on the ordinal.
+     *
+     * @param ordinal the ordinal for this exception type
+     * @param s an error message string
+     */
+    public HotpLoginException( int ordinal, String s )
+    {
+        super( ! s.startsWith( HotpErrorConstants.PREFIX ) ? HotpErrorConstants.PREFIX + ordinal + "]: " + s : s );
+
+        this.ordinal = ordinal;
+    }
+
+
+    /**
+     * Creates a HotpLoginException from error mesage which must have a prefix.
+     *
+     * @param s an error message string
+     */
+    public HotpLoginException( String s )
+    {
+        super( s );
+
+        if ( ! s.startsWith( HotpErrorConstants.PREFIX ) )
+        {
+            throw new IllegalArgumentException( "Message does not contain the prefix: " + HotpErrorConstants.PREFIX );
+        }
+
+        ordinal = Integer.parseInt( s.split( HotpErrorConstants.PREFIX )[1].split( "]" )[0] );
+    }
+
+
+    /**
+     * Get's the ordinal for this exception type.
+     *
+     * @return the ordinal for this exception type
+     */
+    public int getOrdinal()
+    {
+        return this.ordinal;
+    }
+}

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/OldSafehausLoginModule.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/OldSafehausLoginModule.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/OldSafehausLoginModule.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/OldSafehausLoginModule.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,152 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+
+import java.util.Map;
+
+import javax.security.auth.spi.LoginModule;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+
+import com.sun.security.auth.module.Krb5LoginModule;
+
+import org.safehaus.otp.HotpErrorConstants;
+
+
+/**
+ * A Safehaus login module which emits hotp exception types.
+ *
+ * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class OldSafehausLoginModule implements LoginModule
+{
+    /** the underlying LoginModule is the Krb5LoginModule */
+    LoginModule module = new Krb5LoginModule();
+
+
+    public boolean abort() throws LoginException
+    {
+        try
+        {
+            return module.abort();
+        }
+        catch ( LoginException le )
+        {
+            // the return shuts the compiler up
+
+            return handle( le );
+        }
+    }
+
+
+    public boolean commit() throws LoginException
+    {
+        try
+        {
+            return module.commit();
+        }
+        catch ( LoginException le )
+        {
+            // the return shuts the compiler up
+
+            return handle( le );
+        }
+    }
+
+
+    public boolean login() throws LoginException
+    {
+        try
+        {
+            return module.login();
+        }
+        catch ( LoginException le )
+        {
+            // the return shuts the compiler up
+
+            return handle( le );
+        }
+    }
+
+
+    public boolean logout() throws LoginException
+    {
+        try
+        {
+            return module.logout();
+        }
+        catch ( LoginException le )
+        {
+            // the return shuts the compiler up
+
+            return handle( le );
+        }
+    }
+
+
+    public void initialize( Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options )
+    {
+        module.initialize( subject, callbackHandler, sharedState, options );
+    }
+
+
+    /**
+     * Handles the LoginException by throwing a more specific HOTP exception type if it detects
+     * an embedded ordinal value within the exception message, otherwise it rethrows le itself.
+     *
+     * @param le the initial LoginException thrown
+     * @return never returns - exceptions always thrown
+     * @throws LoginException always but a more specific on if possible
+     */
+    public boolean handle( LoginException le ) throws LoginException
+    {
+        if ( ! HotpErrorConstants.hasEmbeddedOrdinal( le.getMessage() ) )
+        {
+            throw le;
+        }
+
+        int ordinal = HotpErrorConstants.getEmbeddedOrdinal( le.getMessage() );
+
+        switch( ordinal )
+        {
+            case( HotpErrorConstants.HOTPAUTH_FAILURE_VAL ):
+
+                throw new PreauthFailedException();
+
+            case( HotpErrorConstants.LOCKEDOUT_VAL ):
+
+                throw new AccountLockedOutException();
+
+            case( HotpErrorConstants.RESYNCH_INPROGRESS_VAL ):
+
+                throw new ResynchInProgressException();
+
+            case( HotpErrorConstants.RESYNCH_STARTING_VAL ):
+
+                throw new ResynchStartingException();
+
+            default:
+                throw le;
+        }
+    }
+}

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PasscodeCallback.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PasscodeCallback.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PasscodeCallback.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PasscodeCallback.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,45 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+
+import javax.security.auth.callback.Callback;
+
+
+/**
+ * A Callback used to capture the OTP value (passcode) for authentication.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class PasscodeCallback implements Callback
+{
+    String passcode;
+    
+    public void setPasscode( String passcode )
+    {
+        this.passcode = passcode;
+    }
+    
+    public String getPasscode()
+    {
+        return passcode;
+    }
+}
\ No newline at end of file

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PolicyCallback.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PolicyCallback.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PolicyCallback.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PolicyCallback.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+
+import javax.security.auth.callback.Callback;
+
+import org.safehaus.triplesec.guardian.ApplicationPolicy;
+
+
+/**
+ * A Callback used to capture the ApplicationPolicy to use while authenticating
+ * users.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class PolicyCallback implements Callback
+{
+    ApplicationPolicy policy;
+    
+    public void setPolicy( ApplicationPolicy policy )
+    {
+        this.policy = policy;
+    }
+    
+    public ApplicationPolicy getPolicy()
+    {
+        return policy;
+    }
+}
\ No newline at end of file

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PreauthFailedException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PreauthFailedException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PreauthFailedException.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/PreauthFailedException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+
+import org.safehaus.otp.HotpErrorConstants;
+
+
+/**
+ * Exception thrown when a HOTP account is locked.
+ *
+ * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class PreauthFailedException extends HotpLoginException
+{
+    private static final long serialVersionUID = 1L;
+
+
+    public PreauthFailedException()
+    {
+        super( HotpErrorConstants.HOTPAUTH_FAILURE_VAL );
+    }
+
+
+    public PreauthFailedException( String s )
+    {
+        super( HotpErrorConstants.HOTPAUTH_FAILURE_VAL, s );
+    }
+}

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/RealmCallback.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/RealmCallback.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/RealmCallback.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/RealmCallback.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,46 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+
+import javax.security.auth.callback.Callback;
+
+
+/**
+ * The Callback used for capturing the realm associated with the user attempting 
+ * to authenticate.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class RealmCallback implements Callback
+{
+    String realm;
+    
+    public void setRealm( String realm )
+    {
+        this.realm = realm;
+    }
+    
+    public String getRealm()
+    {
+        return realm;
+    }
+}
\ No newline at end of file

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/ResynchInProgressException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/ResynchInProgressException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/ResynchInProgressException.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/ResynchInProgressException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+
+import org.safehaus.otp.HotpErrorConstants;
+
+
+/**
+ * Exception thrown when a HOTP account is locked.
+ *
+ * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class ResynchInProgressException extends HotpLoginException
+{
+    private static final long serialVersionUID = 1L;
+
+
+    public ResynchInProgressException()
+    {
+        super( HotpErrorConstants.RESYNCH_INPROGRESS_VAL, HotpErrorConstants.RESYNCH_INPROGRESS_MSG );
+    }
+
+
+    public ResynchInProgressException( String s )
+    {
+        super( HotpErrorConstants.RESYNCH_INPROGRESS_VAL, s );
+    }
+}

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/ResynchStartingException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/ResynchStartingException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/ResynchStartingException.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/ResynchStartingException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+
+import org.safehaus.otp.HotpErrorConstants;
+
+
+/**
+ * Exception thrown when a HOTP account is locked.
+ *
+ * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class ResynchStartingException extends HotpLoginException
+{
+    private static final long serialVersionUID = 1L;
+
+
+    public ResynchStartingException()
+    {
+        super( HotpErrorConstants.RESYNCH_STARTING_VAL, HotpErrorConstants.RESYNCH_STARTING_MSG );
+    }
+
+
+    public ResynchStartingException( String s )
+    {
+        super( HotpErrorConstants.RESYNCH_STARTING_VAL, s );
+    }
+}

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/SafehausLoginModule.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/SafehausLoginModule.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/SafehausLoginModule.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/SafehausLoginModule.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,421 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.directory.InitialDirContext;
+import javax.security.auth.spi.LoginModule;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+
+import com.sun.security.auth.module.Krb5LoginModule;
+
+import org.safehaus.otp.HotpErrorConstants;
+import org.safehaus.triplesec.guardian.ApplicationPolicy;
+import org.safehaus.triplesec.guardian.Profile;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A Safehaus login module which emits hotp exception types.
+ *
+ * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class SafehausLoginModule implements LoginModule
+{
+    public static final String ALLOW_ADMIN = SafehausLoginModule.class.getName() + ".allowAdmin";
+    private static final Logger log = LoggerFactory.getLogger( SafehausLoginModule.class );
+    
+    /** the underlying LoginModule is the Krb5LoginModule */
+    LoginModule module = new Krb5LoginModule();
+    private NameCallback profileIdCallback;
+    private PasswordCallback passwordCallback;
+    private RealmCallback realmCallback;
+    private PasscodeCallback passcodeCallback;
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+    private Map sharedState;
+    private Map options;
+    private PolicyCallback policyCallback;
+    private Profile profile;
+
+
+    public boolean abort() throws LoginException
+    {
+        try
+        {
+            return module.abort();
+        }
+        catch ( LoginException le )
+        {
+            // the return shuts the compiler up
+
+            return handle( le );
+        }
+    }
+
+
+    public boolean commit() throws LoginException
+    {
+        try
+        {
+            if ( module.commit() )
+            {
+                this.subject.getPrincipals().clear();
+                this.subject.getPrincipals().add( new SafehausPrincipal( this.profile ) );
+                return true;
+            }
+            
+            return false;
+        }
+        catch ( LoginException le )
+        {
+            // the return shuts the compiler up
+
+            return handle( le );
+        }
+    }
+
+
+    public boolean login() throws LoginException
+    {
+        Callback[] callbacks = new Callback[] {
+            profileIdCallback, passwordCallback, realmCallback, passcodeCallback, policyCallback
+        };
+        
+        // -------------------------------------------------------------------
+        // Invoke the handler populate all the parameters we need
+        // -------------------------------------------------------------------
+
+        try
+        {
+            callbackHandler.handle( callbacks );
+        }
+        catch ( Exception e )
+        {
+            log.error( "Callback handler failed.", e );
+            LoginException le = new LoginException( "Callback handler failed." );
+            le.initCause( e );
+            throw le;
+        }
+        
+        // -------------------------------------------------------------------
+        // Collect all the parameters we need and determine what kind of auth
+        // we're going to have to perform.
+        // -------------------------------------------------------------------
+
+        final String profileId = profileIdCallback.getName();
+        if ( profileId == null )
+        {
+            String msg = "Cannot login with null username field.";
+            log.error( msg );
+            throw new NullPointerException( msg );
+        }
+        
+        final char[] password = passwordCallback.getPassword();
+        if ( password == null )
+        {
+            String msg = "Cannot login with null password.";
+            log.error( msg );
+            throw new NullPointerException( msg );
+        }
+        
+        final String realm = realmCallback.getRealm();
+        if ( realm == null )
+        {
+            String msg = "Cannot login with null realm.";
+            log.error( msg );
+            throw new NullPointerException( msg );
+        }
+        
+        final ApplicationPolicy policy = policyCallback.getPolicy();
+        if ( policy == null )
+        {
+            String msg = "Cannot login without a non-null .";
+            log.error( msg );
+            throw new NullPointerException( msg );
+        }
+
+        // -------------------------------------------------------------------
+        // Passcode is optional and may be null, check to make sure we 
+        // get a valid profile back for the profileId and report findings
+        // -------------------------------------------------------------------
+
+        final String passcode = passcodeCallback.getPasscode();
+        this.profile = policy.getProfile( profileId );
+        if ( this.profile == null )
+        {
+            log.info( "Profile " + profileId + " not found for user." );
+            return false;
+        }
+        else if ( profileId.equals( "admin" ) )
+        {
+            if ( ! options.containsKey( ALLOW_ADMIN ) ||
+               ( options.containsKey( ALLOW_ADMIN ) && ! ( ( String ) options.get( ALLOW_ADMIN ) ).equals( "true" ) ) )
+            {
+                throw new LoginException( "Admin authentication has not been enabled." );
+            }
+            
+            // ---------------------------------------------------------------
+            // Do just LDAP auth now but with special DN for the admin user
+            // ---------------------------------------------------------------
+            
+            if ( bindAs( "uid=admin,ou=system", "admin" ) )
+            {
+                this.subject.getPrincipals().add( new SafehausPrincipal( profile ) );
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        else
+        {
+            log.info( "Profile " + profileId + " found for user " + profile.getUserName() );
+        }
+        
+        // If the profile is disabled then throw and exceptions
+        if ( profile.isDisabled() )
+        {
+            throw new AccountDisabledException( "The profile "  + profile.getProfileId() 
+                + " associated with your account for application " 
+                + profile.getApplicationName() + " has been disabled." );
+        }
+        
+        // -------------------------------------------------------------------
+        // Setup for standard login without a keyfob using kerberos: 1-FACTOR
+        // -------------------------------------------------------------------
+
+        CallbackHandler cbHandler;
+        final StringBuffer krb5PrincipalName = new StringBuffer();
+        krb5PrincipalName.append( profile.getUserName() ).append( "@" ).append( realm.toUpperCase() );
+        if ( passcode == null || passcode.length() == 0 )  
+        {
+            cbHandler = new CallbackHandler() 
+            {
+                public void handle( Callback[] callbacks )
+                {
+                    for ( int ii = 0; ii < callbacks.length; ii++ )
+                    {
+                        if ( callbacks[ii] instanceof NameCallback )
+                        {
+                            NameCallback ncb = ( NameCallback ) callbacks[ii];
+                            ncb.setName( krb5PrincipalName.toString() );
+                        }
+
+                        else if ( callbacks[ii] instanceof PasswordCallback )
+                        {
+                            PasswordCallback pcb = ( PasswordCallback ) callbacks[ii];
+                            pcb.setPassword( password );
+                        }
+                    }
+                }
+            };
+        }
+        // -------------------------------------------------------------------
+        // Setup to login with keyfob: 2-FACTOR
+        // -------------------------------------------------------------------
+        else 
+        {
+            cbHandler = new CallbackHandler() 
+            {
+                public void handle( Callback[] callbacks )
+                {
+                    for ( int ii = 0; ii < callbacks.length; ii++ )
+                    {
+                        if ( callbacks[ii] instanceof NameCallback )
+                        {
+                            NameCallback ncb = ( NameCallback ) callbacks[ii];
+                            ncb.setName( krb5PrincipalName.toString() );
+                        }
+
+                        else if ( callbacks[ii] instanceof PasswordCallback )
+                        {
+                            PasswordCallback pcb = ( PasswordCallback ) callbacks[ii];
+                            // Notice we use the passcode instead of the password
+                            pcb.setPassword( passcode.toCharArray() );
+                        }
+                    }
+                }
+            };
+            
+            // ---------------------------------------------------------------
+            // Now we verify the static password using LDAP
+            // ---------------------------------------------------------------
+
+            bindAs( getUserDn( profile.getUserName(), realm ), profile.getUserName() );
+        }
+        
+        try
+        {
+            module.initialize( subject, cbHandler, sharedState, options );
+            return module.login();
+        }
+        catch ( LoginException le )
+        {
+            // the return shuts the compiler up
+            return handle( le );
+        }
+    }
+
+    
+    public boolean bindAs( String principalDn, String userName )
+    {
+        Hashtable env = new Hashtable();
+        for ( Iterator ii = options.keySet().iterator(); ii.hasNext(); /**/ ) 
+        {
+            Object key = ii.next();
+            env.put( key, options.get( key ) );
+        }
+        env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
+        
+        InitialDirContext ctx = null;
+        try
+        {
+            ctx = new InitialDirContext( env );
+            ctx.close();
+            return true;
+        }
+        catch ( NamingException e )
+        {
+            log.error( "Failed to bind to directory as user " + userName, e );
+            return false;
+        }
+        finally
+        {
+            if ( ctx == null )
+            {
+                try
+                {
+                    ctx.close();
+                }
+                catch ( NamingException e )
+                {
+                    log.error( "can't close ldap context", e );
+                }
+            }
+        }
+    }
+    
+    
+    public boolean logout() throws LoginException
+    {
+        try
+        {
+            return module.logout();
+        }
+        catch ( LoginException le )
+        {
+            // the return shuts the compiler up
+            return handle( le );
+        }
+    }
+
+
+    public void initialize( Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options )
+    {
+        // What is the username to the application is really the profileId to us
+        profileIdCallback = new NameCallback( "Username: " ); 
+        passwordCallback = new PasswordCallback( "Password: ", false );
+        realmCallback = new RealmCallback();
+        passcodeCallback = new PasscodeCallback();
+        policyCallback = new PolicyCallback();
+        
+        // Save these values for delayed initialization of the Krb5LoginModule
+        this.subject = subject;
+        this.callbackHandler = callbackHandler;
+        this.sharedState = sharedState;
+        this.options = options;
+    }
+    
+    
+    /**
+     * Handles the LoginException by throwing a more specific HOTP exception type if it detects
+     * an embedded ordinal value within the exception message, otherwise it rethrows le itself.
+     *
+     * @param le the initial LoginException thrown
+     * @return never returns - exceptions always thrown
+     * @throws LoginException always but a more specific on if possible
+     */
+    public boolean handle( LoginException le ) throws LoginException
+    {
+        if ( ! HotpErrorConstants.hasEmbeddedOrdinal( le.getMessage() ) )
+        {
+            throw le;
+        }
+
+        int ordinal = HotpErrorConstants.getEmbeddedOrdinal( le.getMessage() );
+        switch( ordinal )
+        {
+            case( HotpErrorConstants.HOTPAUTH_FAILURE_VAL ):
+                throw new PreauthFailedException();
+            case( HotpErrorConstants.LOCKEDOUT_VAL ):
+                throw new AccountLockedOutException();
+            case( HotpErrorConstants.DISABLED_VAL ):
+                throw new AccountDisabledException();
+            case( HotpErrorConstants.RESYNCH_INPROGRESS_VAL ):
+                throw new ResynchInProgressException();
+            case( HotpErrorConstants.RESYNCH_STARTING_VAL ):
+                throw new ResynchStartingException();
+            default:
+                throw le;
+        }
+    }
+    
+    
+    public static String getUserDn( String username, String realm )
+    {
+        StringBuffer buf = new StringBuffer( realm.length() + username.length() + 5 );
+        buf.append( "uid=" ).append( username ).append( ",ou=users," );
+        if ( realm == null || realm.length() == 0  )
+        {
+            return buf.toString();
+        }
+
+        buf.append( "dc=" );
+        int start = 0, end = 0;
+        // Replace all the '.' by ",dc=". The comma is added because
+        // the string is not supposed to start with a dot, so another
+        // dc=XXXX already exists in any cases.
+        // The realm is also not supposed to finish with a '.'
+        while ( ( end = realm.indexOf( '.', start ) ) != -1 )
+        {
+            buf.append( realm.substring( start, end ) ).append( ",dc=" );
+            start = end + 1;
+        }
+
+        buf.append( realm.substring( start ) );
+        return buf.toString();
+    }
+}

Added: directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/SafehausPrincipal.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/SafehausPrincipal.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/SafehausPrincipal.java (added)
+++ directory/trunks/triplesec/jaas/src/main/java/org/safehaus/triplesec/jaas/SafehausPrincipal.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,61 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+import java.security.Principal;
+
+import org.safehaus.triplesec.guardian.Profile;
+
+
+/**
+ * A security Principal which has a Guardian Authorization Profile associated 
+ * with it.
+ *
+ * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class SafehausPrincipal implements Principal
+{
+    /** the Guardian authorization profile for this principal */
+    private Profile profile;
+
+
+    SafehausPrincipal( Profile profile )
+    {
+        this.profile = profile;
+    }
+    
+    
+    public String getName()
+    {
+        return profile.getProfileId();
+    }
+
+
+    /**
+     * Gets the Guardian authorization profile for this SafehausPrincipal.
+     * 
+     * @return the authorization Profile 
+     */
+    public Profile getAuthorizationProfile()
+    {
+        return profile;
+    }
+}

Added: directory/trunks/triplesec/jaas/src/test/java/org/safehaus/triplesec/jaas/SafehausLoginModuleTest.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/jaas/src/test/java/org/safehaus/triplesec/jaas/SafehausLoginModuleTest.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/jaas/src/test/java/org/safehaus/triplesec/jaas/SafehausLoginModuleTest.java (added)
+++ directory/trunks/triplesec/jaas/src/test/java/org/safehaus/triplesec/jaas/SafehausLoginModuleTest.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.jaas;
+
+
+
+import junit.framework.TestCase;
+
+
+/**
+ * Test cases for the SafehausLoginModule.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class SafehausLoginModuleTest extends TestCase
+{
+    public void testGetUserDn()
+    {
+        String dn = SafehausLoginModule.getUserDn( "akarasulu", "example.com" );
+        assertEquals( "uid=akarasulu,ou=users,dc=example,dc=com", dn );
+    }
+}

Added: directory/trunks/triplesec/main/conf/log4j.properties
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/main/conf/log4j.properties?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/main/conf/log4j.properties (added)
+++ directory/trunks/triplesec/main/conf/log4j.properties Tue Dec 12 07:23:31 2006
@@ -0,0 +1,11 @@
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, A1
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+
+

Added: directory/trunks/triplesec/main/conf/server.ldif
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/main/conf/server.ldif?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/main/conf/server.ldif (added)
+++ directory/trunks/triplesec/main/conf/server.ldif Tue Dec 12 07:23:31 2006
@@ -0,0 +1,185 @@
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you 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. 
+#  
+#
+#   EXAMPLE.COM is freely and reserved for testing according to this RFC:
+#
+#   http://www.rfc-editor.org/rfc/rfc2606.txt
+#
+#
+
+#
+# This ACI allows brouse access to the root suffix and one level below that to anyone.
+# At this level there is nothing critical exposed.  Everything that matters is one or
+# more levels below this.
+#
+
+dn: cn=browseRootAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { maximum 1 }
+prescriptiveACI: { identificationTag "browseRoot", precedence 100, authenticationLevel none, itemOrUserFirst userFirst: { userClasses { allUsers }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantBrowse } } } } }
+
+dn: ou=Users, dc=example, dc=com
+objectclass: top
+objectclass: organizationalunit
+ou: Users
+
+#
+# This ACI allows users to modify a limited set of attributes in their own user
+# entry as well as read, compare those attributes.  The user's entry must be 
+# browseable and the DN must be returnable.
+#
+
+dn: cn=allowSelfModificationsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=users", maximum 1 }
+prescriptiveACI: { identificationTag "allowSelfModifications", precedence 14, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { thisEntry }, userPermissions  {  { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantModify, grantBrowse, grantRead, grantDiscloseOnError } }, { protectedItems {allAttributeValues {userPassword, krb5Key, givenName, cn, commonName, surName, sn, objectClass }}, grantsAndDenials { grantModify, grantAdd, grantRemove, grantRead, grantDiscloseOnError, grantCompare } } } } }
+
+#
+# This ACI allows users to access a limited set of attributes in their own user
+# entry as well as compare those attributes.  The user's entry must be browseable 
+# and the DN must be returnable.
+#
+
+dn: cn=allowSelfAccessAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=users", maximum 1 }
+prescriptiveACI: { identificationTag "allowSelfAccess", precedence 15, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { thisEntry }, userPermissions  {  { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantBrowse, grantRead, grantDiscloseOnError } }, { protectedItems {allAttributeValues {uid, userPassword, givenName, cn, commonName, surName, sn, objectClass, creatorsName, modifiersName, createTimestamp, modifyTimestamp, krb5AccountDisabled, description, apacheSamType }}, grantsAndDenials { grantRead, grantDiscloseOnError, grantCompare } } } } }
+
+dn: ou=Groups, dc=example, dc=com
+objectclass: top
+objectclass: organizationalunit
+ou: Groups
+
+dn: cn=superUsers, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: superUsers
+uniqueMember: uid=admin, ou=system
+
+dn: cn=userAdmins, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: userAdmin
+uniqueMember: uid=admin, ou=system
+
+dn: cn=applicationAdmins, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: applicationAdmin
+uniqueMember: uid=admin, ou=system
+
+dn: cn=groupAdmins, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: groupAdmin
+uniqueMember: uid=admin, ou=system
+
+#
+# This ACI allows members of the superUsers group to have full modify and read access
+# to the entire realm as does the system administrator principal: uid=admin, ou=system.
+#
+# The only thing these users cannot do is modify the system partition.  They are only
+# restricted to superUser rights within this realm partition
+#
+ 
+dn: cn=superUsersAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { }
+prescriptiveACI: { identificationTag "superUsersAci", precedence 20, authenticationLevel simple,  itemOrUserFirst userFirst: { userClasses { userGroup { "cn=superUsers,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues},  grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+#
+# This ACI allows members of the userAdmin group to have full modify and read access
+# to user accounts besides their own.  Hence they can administer users in the system.
+#
+ 
+dn: cn=userAdminsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=users", maximum 1 }
+prescriptiveACI: { identificationTag "userAdminsAci", precedence 16, authenticationLevel simple,  itemOrUserFirst userFirst: { userClasses { userGroup { "cn=userAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues},  grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+
+#
+# This ACI allows members of the applicationAdmin group to have full modify and read access
+# to all applications in the realm.  Adding users to this group is like a wild card for 
+# application access.
+#
+ 
+dn: cn=applicationAdminsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=applications" }
+prescriptiveACI: { identificationTag "applicationAdminsAci", precedence 17, authenticationLevel simple,  itemOrUserFirst userFirst: { userClasses { userGroup { "cn=applicationAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues},  grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+
+#
+# This ACI allows members of the groupAdmins group to have full modify and read access
+# to all groups in the realm other than the superUsers, userAdmins, groupAdmins, and the 
+# applicationAdmins groups.
+#
+# The rational behind this is to prevent these users from changing their or other
+# users' access rights for the entire system by modifying their membership in these 
+# groups. Making someone a groupAdmin should not open the door to their ability to
+# grant themselves or others system wide administrative abilities.
+#
+# Really the groupAdmins group is intended for users that have the ability to manage 
+# group membership in specific application administration groups and that's all.  
+# These types of admins should not have the right to promote others to system level
+# administrators or complete super users.
+#
+ 
+dn: cn=groupAdminsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=groups", specificExclusions { chopBefore: "cn=userAdmins", chopBefore: "cn=groupAdmins", chopBefore: "cn=applicationAdmins", chopBefore: "cn=superUsers" } }
+prescriptiveACI: { identificationTag "groupAdminsAci", precedence 18, authenticationLevel simple,  itemOrUserFirst userFirst: { userClasses { userGroup { "cn=groupAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues},  grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+dn: uid=krbtgt, ou=Users, dc=example,dc=com
+cn: Kerberos Server
+sn: Server
+givenName: Kerberos
+objectClass: top
+objectClass: uidObject
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+objectClass: krb5Principal
+objectClass: krb5KDCEntry
+ou: Users
+uid: krbtgt
+krb5PrincipalName: krbtgt/EXAMPLE.COM@EXAMPLE.COM
+krb5KeyVersionNumber: 0
+mail: admin@example.com
+userPassword: secret
+
+dn: ou=Applications,dc=example,dc=com
+objectClass: top
+objectClass: organizationalunit
+ou: applications

Added: directory/trunks/triplesec/main/conf/server.xml
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/main/conf/server.xml?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/main/conf/server.xml (added)
+++ directory/trunks/triplesec/main/conf/server.xml Tue Dec 12 07:23:31 2006
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
+  "http://www.springframework.org/dtd/spring-beans.dtd">
+
+<beans>
+  <bean id="environment" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
+    <property name="properties">
+      <props>
+        <prop key="java.naming.security.authentication">simple</prop>
+        <prop key="java.naming.security.principal">uid=admin,ou=system</prop>
+        <prop key="java.naming.security.credentials">secret</prop>
+        <prop key="java.naming.provider.url">dc=example,dc=com</prop>
+        <prop key="java.naming.factory.state">org.safehaus.triplesec.store.ProfileStateFactory</prop>
+        <prop key="java.naming.factory.object">org.safehaus.triplesec.store.ProfileObjectFactory</prop>
+
+        <prop key="kdc.primary.realm">EXAMPLE.COM</prop>
+        <prop key="kdc.principal">krbtgt/EXAMPLE.COM@EXAMPLE.COM</prop>
+        <prop key="kdc.encryption.types">des-cbc-md5 des3-cbc-sha1 des3-cbc-md5 des-cbc-md4 des-cbc-crc</prop>
+        <prop key="kdc.entryBaseDn">ou=users,dc=example,dc=com</prop>
+        <prop key="kdc.java.naming.security.credentials">secret</prop>
+
+        <prop key="changepw.entryBaseDn">ou=users,dc=example,dc=com</prop>
+        <prop key="changepw.java.naming.security.credentials">secret</prop>
+        <prop key="changepw.principal">kadmin/changepw@EXAMPLE.COM</prop>
+
+        <!-- All times are in minutes -->
+        <prop key="kdc.allowable.clockskew">5</prop>
+        <prop key="kdc.tgs.maximum.ticket.lifetime">1440</prop>
+        <prop key="kdc.tgs.maximum.renewable.lifetime">10080</prop>
+        <prop key="kdc.pa.enc.timestamp.required">true</prop>
+        <prop key="kdc.tgs.empty.addresses.allowed">true</prop>
+        <prop key="kdc.tgs.forwardable.allowed">true</prop>
+        <prop key="kdc.tgs.proxiable.allowed">true</prop>
+        <prop key="kdc.tgs.postdate.allowed">true</prop>
+        <prop key="kdc.tgs.renewable.allowed">true</prop>
+
+        <prop key="safehaus.entry.basedn">ou=Users,dc=example,dc=com</prop>
+        <prop key="safehaus.load.testdata">true</prop>
+        <prop key="kerberos.sam.type.7">org.safehaus.triplesec.verifier.hotp.DefaultHotpSamVerifier</prop>
+      </props>
+    </property>
+  </bean>
+
+  <bean id="configuration" class="org.safehaus.triplesec.configuration.MutableTriplesecStartupConfiguration">
+    <property name="workingDirectory"><value>partitions</value></property>
+    <property name="allowAnonymousAccess"><value>false</value></property>
+    <property name="accessControlEnabled"><value>true</value></property>
+    <property name="ldapPort"><value>10389</value></property>
+    <property name="enableKerberos"><value>true</value></property>
+    <property name="enableNtp"><value>false</value></property>
+    <property name="enableChangePassword"><value>true</value></property>
+
+    <!-- Uncomment below to have the server load entries on startup!        -->
+    <!-- ldifDirectory property can point to a relative file, directory or  -->
+    <!-- can point to an absolute path to either using the URL path         -->
+    <!-- notation: i.e. file:///Users/jack/apacheds/ldifs                   -->
+
+    <!-- Entries will optionally be filtered using LdifLoadFilters in the   -->
+    <!-- order specified.  The included Krb5KdcEntryFilter will filter      -->
+    <!-- kerberos principals creating keys for them using their             -->
+    <!-- userPassword attribute if present.                                 -->
+
+    <!-- If missing the Triplesec server will use LDIF files under the conf -->
+    <!-- directory where it has been installed.                             -->
+
+    <!--
+    <property name="ldifDirectory">
+      <value>example.ldif</value>
+    </property>
+    -->
+    <property name="ldifFilters">
+      <list>
+        <bean class="org.apache.directory.server.protocol.shared.store.Krb5KdcEntryFilter"/>
+      </list>
+    </property>
+
+    <property name="activationConfiguration">
+      <bean class="org.safehaus.triplesec.configuration.ActivationConfiguration">
+        <property name="enableDecoyMidlet"><value>true</value></property>
+        <property name="otpLength"><value>6</value></property>
+        <property name="midletNameAttribute"><value>midletNameAttribute</value></property>
+      </bean>  
+    </property>    
+    
+    <property name="smsConfiguration">
+      <bean class="org.safehaus.triplesec.configuration.SmsConfiguration">
+        <property name="smsUsername"><value>hauskeys</value></property>
+        <property name="smsPassword"><value>secret</value></property>
+        <property name="smsAccountName"><value>demo</value></property>
+        <property name="smsTransportUrl"><value>http://www.nbroadcasting.com/customers/messages/Sender.asp</value></property>
+      </bean>  
+    </property>    
+    
+    <property name="smtpConfiguration">
+      <bean class="org.safehaus.triplesec.configuration.SmtpConfiguration">
+        <property name="smtpAuthenticate"><value>false</value></property>
+        <!-- uncomment and set above property if authentication is required by mail server
+             <property name="smtpUsername"><value>hauskeys</value></property>
+             <property name="smtpPassword"><value>secret</value></property>
+             -->
+             <property name="smtpHost"><value>localhost</value></property>
+             <property name="smtpSubject"><value>Triplesec Account Activated</value></property>
+             <property name="smtpFrom"><value>dev@safehaus.org</value></property>
+           </bean>  
+         </property>    
+         
+    <property name="contextPartitionConfigurations">
+      <set>
+        <ref bean="examplePartitionConfiguration"/>
+      </set>
+    </property>
+    <property name="bootstrapSchemas">
+      <set>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CorbaSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CoreSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CosineSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.ApacheSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CollectiveSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.InetorgpersonSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.JavaSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.Krb5kdcSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.SystemSchema"/>
+        <bean class="org.safehaus.triplesec.store.schema.SafehausSchema"/>
+      </set>
+    </property>
+    
+    <property name="extendedOperationHandlers">
+      <list>
+        <bean class="org.apache.directory.server.ldap.support.extended.GracefulShutdownHandler"/>
+        <bean class="org.apache.directory.server.ldap.support.extended.LaunchDiagnosticUiHandler"/>
+      </list>
+    </property>  
+
+    <property name="interceptorConfigurations">
+      <list>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>normalizationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.normalization.NormalizationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>authenticationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.authn.AuthenticationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>referralService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.referral.ReferralService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>authorizationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.authz.AuthorizationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>DefaultAuthorizationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.authz.DefaultAuthorizationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>exceptionService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.exception.ExceptionService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>schemaService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.schema.SchemaService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>subentryService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.subtree.SubentryService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>operationalAttributeService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.operational.OperationalAttributeService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>collectiveAttributeService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.collective.CollectiveAttributeService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>eventService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.event.EventService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>policyProtectionService</value></property>
+          <property name="interceptor">
+            <bean class="org.safehaus.triplesec.store.interceptor.PolicyProtectionInterceptor" />
+          </property>
+        </bean>
+      </list>
+    </property>
+  </bean>
+  
+  <bean id="examplePartitionConfiguration" class="org.apache.directory.server.core.configuration.MutablePartitionConfiguration">
+    <property name="name"><value>example</value></property>
+    <property name="suffix"><value>dc=example,dc=com</value></property>
+    <property name="indexedAttributes">
+      <set>
+        <value>objectClass</value>
+        <value>ou</value>
+        <value>dc</value>
+        <value>uid</value>
+        <value>profileId</value>
+        <value>roles</value>
+        <value>grants</value>
+        <value>denials</value>
+        <value>krb5PrincipalName</value>
+      </set>
+    </property>
+    <property name="contextEntry">
+      <value>
+        objectClass: top
+        objectClass: domain
+        objectClass: extensibleObject
+        dc: example
+        administrativeRole: accessControlSpecificArea
+        administrativeRole: collectiveAttributeSpecificArea
+      </value>
+    </property>
+  </bean>
+
+  <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
+    <property name="customEditors">
+      <map>
+        <entry key="javax.naming.directory.Attributes">
+          <bean class="org.apache.directory.server.core.configuration.AttributesPropertyEditor"/>
+        </entry>
+      </map>
+   </property>
+  </bean>
+</beans>