Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 27990 invoked from network); 12 Dec 2006 15:26:47 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 12 Dec 2006 15:26:47 -0000 Received: (qmail 49959 invoked by uid 500); 12 Dec 2006 15:26:54 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 49923 invoked by uid 500); 12 Dec 2006 15:26:54 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 49889 invoked by uid 99); 12 Dec 2006 15:26:54 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 12 Dec 2006 07:26:54 -0800 X-ASF-Spam-Status: No, hits=-9.2 required=10.0 tests=ALL_TRUSTED,MAILTO_TO_SPAM_ADDR,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 12 Dec 2006 07:26:39 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id F1B331A9895; Tue, 12 Dec 2006 07:24:41 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r486187 [37/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... Date: Tue, 12 Dec 2006 15:24:14 -0000 To: commits@directory.apache.org From: tbennett@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20061212152441.F1B331A9895@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: directory/trunks/triplesec/tools/src/main/java/org/safehaus/triplesec/tools/Tools.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/tools/src/main/java/org/safehaus/triplesec/tools/Tools.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/tools/src/main/java/org/safehaus/triplesec/tools/Tools.java (added) +++ directory/trunks/triplesec/tools/src/main/java/org/safehaus/triplesec/tools/Tools.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,146 @@ +/* + * 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.tools; + + +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +import org.apache.commons.cli.CommandLine; +import org.apache.directory.server.configuration.ServerStartupConfiguration; +import org.apache.directory.server.tools.BaseCommand; +import org.apache.directory.server.tools.ToolCommand; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.FileSystemXmlApplicationContext; + + +/** + * The main() application which executes command targets. + */ +public class Tools +{ + public static void main( String[] args ) throws Exception + { + BaseCommand tools = getInstance(); + + if ( !BaseCommand.hasBannerOption( args ) ) + { + tools.printBanner(); + } + + if ( args.length == 0 ) + { + System.err.println( "Type " + tools.getProductCommand() + " help for usage." ); + System.exit( 1 ); + } + + // help is a special command + String command = args[0].toLowerCase(); + if ( "help".equals( command ) ) + { + CommandLine cmdline = tools.getCommandLine( command, args ); + if ( cmdline.getArgs().length > 1 ) + { + tools.helpOnCommand( cmdline.getArgs()[1] ); + System.exit( 0 ); + } + else + { + tools.printUsage(); + System.exit( 0 ); + } + } + else if ( command.equals( "-version" ) ) + { + System.out.println( tools.getProductCommand() + " version " + tools.getProductVersion() ); + System.exit( 0 ); + } + + ToolCommand cmd = ( ToolCommand ) tools.getCommands().get( command ); + if ( cmd == null ) + { + System.err.println( "Unknown command: " + args[0] ); + System.err.println( "Type " + tools.getProductCommand() + " help for usage." ); + System.exit( 1 ); + } + + CommandLine cmdline = tools.getCommandLine( command, args ); + if ( cmdline.hasOption( 'd' ) ) + { + cmd.setDebugEnabled( true ); + BaseCommand.dumpArgs( "raw command line arguments: ", args ); + BaseCommand.dumpArgs( "parsed arguments: ", cmdline.getArgs() ); + } + + cmd.setQuietEnabled( cmdline.hasOption( 'q' ) ); + cmd.setDebugEnabled( cmdline.hasOption( 'd' ) ); + cmd.setVerboseEnabled( cmdline.hasOption( 'v' ) ); + cmd.setVersion( tools.getProductVersion() ); + if ( cmdline.getOptionValue( 'i' ) != null ) + { + cmd.setLayout( cmdline.getOptionValue( 'i' ) ); + if ( !cmd.isQuietEnabled() ) + { + System.out.println( "loading settings from: " + cmd.getLayout().getConfigurationFile() ); + } + ApplicationContext factory = null; + URL configUrl = cmd.getLayout().getConfigurationFile().toURL(); + factory = new FileSystemXmlApplicationContext( configUrl.toString() ); + cmd.setConfiguration( ( ServerStartupConfiguration ) factory.getBean( "configuration" ) ); + } + else if ( cmdline.hasOption( 'c' ) ) + { + System.err.println( "forced configuration load (-c) requires the -i option" ); + System.exit( 1 ); + } + + cmd.execute( cmdline ); + } + + + public static BaseCommand getInstance() throws InstantiationException, IllegalAccessException, ClassNotFoundException + { + Properties props = new Properties(); + try + { + props.load( Tools.class.getResourceAsStream( "product.properties" ) ); + } + catch ( IOException e ) + { + e.printStackTrace(); + } + + String productVersion = props.getProperty( "product.version", "UNKNOWN" ); + String productUrl = props.getProperty( "product.url", "http://triplesec.safehaus.org" ); + String productDisplayName = props.getProperty( "product.display.name", "Triplesec Strong Identity Server" ); + String productCommand = props.getProperty( "product.command", "triplesec-tools" ); + String productBanner = props.getProperty( "product.banner", "Triplesec Strong Identity Server" ); + String productClass = props.getProperty( "product.class", "org.apache.directory.server.tools.BaseCommand" ); + + BaseCommand baseCommand = ( BaseCommand ) Class.forName( productClass ).newInstance(); + baseCommand.setProductBanner( productBanner ); + baseCommand.setProductDisplayName( productDisplayName ); + baseCommand.setProductUrl( productUrl ); + baseCommand.setProductVersion( productVersion ); + baseCommand.setProductCommand( productCommand ); + return baseCommand; + } +} Added: directory/trunks/triplesec/tools/src/main/manifest/MANIFEST.MF URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/tools/src/main/manifest/MANIFEST.MF?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/tools/src/main/manifest/MANIFEST.MF (added) +++ directory/trunks/triplesec/tools/src/main/manifest/MANIFEST.MF Tue Dec 12 07:23:31 2006 @@ -0,0 +1,40 @@ +Manifest-Version: 1.0 +Main-Class: org.safehaus.triplesec.tools.Tools +Class-Path: logger.jar daemon.jar bootstrapper.jar + ../lib/antlr-2.7.2.jar + ../lib/apacheds-core-1.0-RC3.jar + ../lib/apacheds-core-shared-1.0-RC3.jar + ../lib/apacheds-kerberos-shared-1.0-RC3.jar + ../lib/apacheds-protocol-changepw-1.0-RC3.jar + ../lib/apacheds-protocol-shared-1.0-RC3.jar + ../lib/apacheds-protocol-kerberos-1.0-RC3.jar + ../lib/apacheds-protocol-ldap-1.0-RC3.jar + ../lib/apacheds-protocol-ntp-1.0-RC3.jar + ../lib/apacheds-server-jndi-1.0-RC3.jar + ../lib/apacheds-server-main-1.0-RC3.jar + ../lib/tools/apacheds-server-tools-1.0-RC3.jar + ../lib/tools/commons-cli-1.0.jar + ../lib/commons-collections-3.1.jar + ../lib/commons-lang-2.0.jar + ../lib/commons-logging-1.0.4.jar + ../lib/jdbm-1.0.jar + ../lib/lcrypto-jdk14-131.jar + ../lib/mina-core-0.9.4.jar + ../lib/mina-filter-codec-asn1-0.9.4.jar + ../lib/mina-filter-ssl-0.9.4.jar + ../lib/shared-asn1-0.9.5.1.jar + ../lib/shared-ldap-0.9.5.1.jar + ../lib/spring-beans-1.2.6.jar + ../lib/spring-context-1.2.6.jar + ../lib/spring-core-1.2.6.jar + ../lib/triplesec-crypto-0.7.1.jar + ../lib/triplesec-configuration-0.7.1.jar + ../lib/triplesec-main-0.7.1.jar + ../lib/triplesec-otp-0.7.1.jar + ../lib/triplesec-profile-0.7.1.jar + ../lib/triplesec-store-0.7.1.jar + ../lib/triplesec-testdata-0.7.1.jar + ../lib/triplesec-verifier-0.7.1.jar +Specification-Title: triplesec-tools +Specification-Version: 1.0 + Added: directory/trunks/triplesec/tools/src/main/resources/org/safehaus/triplesec/tools/product.properties URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/tools/src/main/resources/org/safehaus/triplesec/tools/product.properties?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/tools/src/main/resources/org/safehaus/triplesec/tools/product.properties (added) +++ directory/trunks/triplesec/tools/src/main/resources/org/safehaus/triplesec/tools/product.properties Tue Dec 12 07:23:31 2006 @@ -0,0 +1,4 @@ +product.version=${pom.version} +product.command=triplesec-tools +product.display.name=Triplesec Server +product.url=http://triplesec.safehaus.org \ No newline at end of file Added: directory/trunks/triplesec/utils-hauskeys/HausKeys.jar URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/utils-hauskeys/HausKeys.jar?view=auto&rev=486187 ============================================================================== Binary file - no diff available. Propchange: directory/trunks/triplesec/utils-hauskeys/HausKeys.jar ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: directory/trunks/triplesec/utils-hauskeys/pom.xml URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/utils-hauskeys/pom.xml?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/utils-hauskeys/pom.xml (added) +++ directory/trunks/triplesec/utils-hauskeys/pom.xml Tue Dec 12 07:23:31 2006 @@ -0,0 +1,79 @@ + + + + 4.0.0 + + org.safehaus.triplesec + build + 1.0-SNAPSHOT + + triplesec-utils-hauskeys + Triplesec Utilities for Hauskeys Midlet + + Utility classes and resources for generating hauskeys midlets. + + jar + + + + ${pom.groupId} + triplesec-otp + ${pom.version} + test + + + + ${pom.groupId} + triplesec-testdata + ${pom.version} + test + + + + ant + ant + 1.6.5 + + + + + + + maven-surefire-plugin + + + + tmpDirectory + ${basedir}/target/temp + + + hauskeysSrcFile + ${basedir}/HausKeys.jar + + + dstDirectory + ${basedir}/target/midlets + + + + + + + Added: directory/trunks/triplesec/utils-hauskeys/src/main/java/org/safehaus/triplesec/utils/hauskeys/HauskeysMidletBuilder.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/utils-hauskeys/src/main/java/org/safehaus/triplesec/utils/hauskeys/HauskeysMidletBuilder.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/utils-hauskeys/src/main/java/org/safehaus/triplesec/utils/hauskeys/HauskeysMidletBuilder.java (added) +++ directory/trunks/triplesec/utils-hauskeys/src/main/java/org/safehaus/triplesec/utils/hauskeys/HauskeysMidletBuilder.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,211 @@ +/* + * 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.utils.hauskeys; + + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.Random; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Delete; +import org.apache.tools.ant.taskdefs.Expand; +import org.apache.tools.ant.taskdefs.Jar; +import org.apache.tools.ant.taskdefs.Manifest; +import org.apache.tools.ant.taskdefs.ManifestException; +import org.apache.tools.ant.taskdefs.Move; + + +/** + * Bean which gathers properties and builds a hauskeys midlet using a template jar. + * + * @author Alex Karasulu + * @version $Rev$ + */ +public class HauskeysMidletBuilder +{ + private String midletName; + private String hotpInfo; + private File tmpDirectory = new File( System.getProperty( "java.io.tmpdir" ) ); + private File hauskeysSrcFile; + private File hauskeysDstFile; + + + public void build() throws IOException, ManifestException + { + File mydir = new File( tmpDirectory, "hauskeys" ); + if ( ! mydir.exists() ) + { + mydir.mkdirs(); + } + + // compute a random string for destination directory + StringBuffer buf = new StringBuffer(); + Random rand = new Random(); + while ( buf.length() <= 8 ) + { + int ch = rand.nextInt() % 123; + if ( ( ch > 64 && ch < 91 ) || ( ch > 96 && ch < 123 ) || ( ch > 47 && ch < 58 ) ) + { + buf.append( ( char ) ch ); + } + } + String destDirName = buf.append( "." ).append( System.currentTimeMillis() ).toString(); + + // create the temp directory destination and unjar + File destDir = new File( mydir, destDirName ); + Project project = new Project(); + Expand expand = new Expand(); + expand.setProject( project ); + expand.setDest( destDir ); + expand.setSrc( hauskeysSrcFile ); + expand.execute(); + + // remove the old HOTP-INFO file to create new one later + File hotpInfoFile = getHotpInfoFile( destDir ); + Delete delete = new Delete(); + delete.setProject( project ); + delete.setFile( hotpInfoFile ); + delete.execute(); + + // write new file with new content + OutputStream out = new FileOutputStream( hotpInfoFile ); + out.write( hotpInfo.getBytes( "UTF-8" ) ); + out.flush(); + out.close(); + + // read manifest file in for modifications + File manifestFile = new File( new File( destDir, "META-INF" ), "MANIFEST.MF" ); + Manifest manifest = new Manifest( new FileReader( manifestFile ) ); + delete = new Delete(); + delete.setProject( project ); + delete.setFile( manifestFile ); + delete.execute(); + + // modify manifest for midlet name and dump it back out + manifest.getMainSection().getAttribute( "MIDlet-Name" ).setValue( midletName ); + PrintWriter pw = new PrintWriter( new FileWriter( manifestFile ) ); + manifest.write( pw ); + pw.flush(); + pw.close(); + + // jar up contents of the temp directory + Jar jar = new Jar(); + jar.setProject( project ); + jar.setBasedir( destDir ); + jar.setManifest( manifestFile ); + File jarFile = new File( mydir, destDirName + ".jar" ); + jar.setDestFile( jarFile ); + jar.execute(); + + // move the generate jar file to the destFile + Move mv = new Move(); + mv.setProject( project ); + mv.setFile( jarFile ); + mv.setFailOnError( true ); + mv.setTofile( hauskeysDstFile ); + mv.execute(); + + // delete the temporary jarFile and tempDir + delete = new Delete(); + delete.setProject( project ); + delete.setFile( jarFile ); + delete.execute(); + delete = new Delete(); + delete.setProject( project ); + delete.setDir( destDir ); + delete.execute(); + } + + + private static File getHotpInfoFile( File jarBase ) + { + File f = new File( jarBase, "org" ); + f = new File( f, "safehaus" ); + f = new File( f, "midlets" ); + f = new File( f, "HOTP-INFO" ); + return f; + } + + + public void setHotpInfo( String hotpInfo ) + { + this.hotpInfo = hotpInfo; + } + + + public String getHotpInfo() + { + return hotpInfo; + } + + + public void setMidletName( String midletName ) + { + this.midletName = midletName; + } + + + public String getMidletName() + { + return midletName; + } + + + public void setTmpDirectory( File tmpDirectory ) + { + this.tmpDirectory = tmpDirectory; + } + + + public File getTmpDirectory() + { + return tmpDirectory; + } + + + public void setHauskeysSrcFile( File hauskeysSrcFile ) + { + this.hauskeysSrcFile = hauskeysSrcFile; + } + + + public File getHauskeysSrcFile() + { + return hauskeysSrcFile; + } + + + public void setHauskeysDstFile( File hauskeysDstFile ) + { + this.hauskeysDstFile = hauskeysDstFile; + } + + + public File getHauskeysDstFile() + { + return hauskeysDstFile; + } +} Added: directory/trunks/triplesec/utils-hauskeys/src/main/java/org/safehaus/triplesec/utils/hauskeys/JadFileUtils.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/utils-hauskeys/src/main/java/org/safehaus/triplesec/utils/hauskeys/JadFileUtils.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/utils-hauskeys/src/main/java/org/safehaus/triplesec/utils/hauskeys/JadFileUtils.java (added) +++ directory/trunks/triplesec/utils-hauskeys/src/main/java/org/safehaus/triplesec/utils/hauskeys/JadFileUtils.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,100 @@ +/* + * 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.utils.hauskeys; + + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + + +/** + * Utility class for generating a JAD file. + * + *

Usage

+ *

+ * Use this utility class to generate or modify existing jad files like so: + *

+ * + *
+ *    Map jadAttrs = JadFileUtils.getJadAttributes( jadFile );
+ *    jadAttrs.put( "Midlet-Name", "YourHauskeys" );
+ *    jadAttrs.put( "Midlet-Jar-URL", "HausKeys.jar" );
+ *    jadAttrs.put( "Midlet-Jar-Size", String.valueOf( jarFile.length() ) );
+ *    String jadContent = JadFileUtils.getJadContentFor( jadAttrs );
+ *    FileWriter fw = new FileWriter( newJadFile );
+ *    fw.write( jadContent );
+ *    fw.flush();
+ *    fw.close();
+ * 
+ * + * @author Alex Karasulu + * @version $Rev$ + */ +public class JadFileUtils +{ + public static final String JAD_CONTENT_TYPE = "text/vnd.sun.j2me.app-descriptor"; + + + public static String getJadContentFor( Map attributes ) + { + StringBuffer buf = new StringBuffer(); + Iterator list = attributes.keySet().iterator(); + boolean isFirstPass = true; + while ( list.hasNext() ) + { + String key = ( String ) list.next(); + String value = String.valueOf( attributes.get( key ) ); + if ( isFirstPass ) + { + isFirstPass = false; + buf.append( key ); + buf.append( ": " ); + buf.append( value ); + } + else + { + buf.append( "\n" ); + buf.append( key ); + buf.append( ": " ); + buf.append( value ); + } + } + return buf.toString(); + } + + + public static Map getJadAttributes( File jadFile ) throws IOException + { + Map attributes = new HashMap(); + BufferedReader in = new BufferedReader( new FileReader( jadFile ) ); + String line = null; + while ( ( line = in.readLine() ) != null ) + { + String[] tuple = line.split( ":" ); + attributes.put( tuple[0].trim(), tuple[1].trim() ); + } + return attributes; + } +} Added: directory/trunks/triplesec/utils-hauskeys/src/test/java/org/safehaus/triplesec/utils/hauskeys/HauskeysMidletBuilderTest.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/utils-hauskeys/src/test/java/org/safehaus/triplesec/utils/hauskeys/HauskeysMidletBuilderTest.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/utils-hauskeys/src/test/java/org/safehaus/triplesec/utils/hauskeys/HauskeysMidletBuilderTest.java (added) +++ directory/trunks/triplesec/utils-hauskeys/src/test/java/org/safehaus/triplesec/utils/hauskeys/HauskeysMidletBuilderTest.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,89 @@ +/* + * 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.utils.hauskeys; + + +import java.io.File; + +import org.safehaus.otp.HotpAttributes; +import org.safehaus.otp.HotpAttributesCipher; +import org.safehaus.profile.ProfileTestData; +import org.safehaus.profile.ServerProfile; + +import junit.framework.TestCase; + + +/** + * Tests the midlet builder. + * + * @author Alex Karasulu + * @version $Rev$ + */ +public class HauskeysMidletBuilderTest extends TestCase +{ + File tmpDirectory = null; + File hauskeysSrcFile = null; + File dstDirectory = null; + + + public HauskeysMidletBuilderTest() + { + tmpDirectory = new File( System.getProperty( "tmpDirectory" ) ); + hauskeysSrcFile = new File( System.getProperty( "hauskeysSrcFile" ) ); + dstDirectory = new File( System.getProperty( "dstDirectory" ) ); + } + + + public void testBuild() throws Exception + { + HauskeysMidletBuilder builder = new HauskeysMidletBuilder(); + builder.setHauskeysDstFile( new File( dstDirectory, "testBuild.jar" ) ); + builder.setHauskeysSrcFile( hauskeysSrcFile ); + builder.setTmpDirectory( tmpDirectory ); + builder.setHotpInfo( "ssssssssssssssssssssssssss" ); + builder.setMidletName( "testBuild" ); + builder.build(); + assertTrue( new File( dstDirectory, "testBuild.jar" ).exists() ); + } + + + public void testBuildDemoMidlets() throws Exception + { + for ( int ii = 0; ii < ProfileTestData.PROFILES.length; ii++ ) + { + ServerProfile profile = ProfileTestData.PROFILES[ii]; + HotpAttributes attrs = new HotpAttributes( 6, profile.getFactor(), profile.getSecret() ); + String hotpInfo = HotpAttributesCipher.encrypt( profile.getTokenPin(), attrs ); + HotpAttributes decrypted = HotpAttributesCipher.decrypt( "1234", hotpInfo ); + + assertEquals( attrs.getFactor(), decrypted.getFactor() ); + assertEquals( attrs.getSize(), decrypted.getSize() ); + + HauskeysMidletBuilder builder = new HauskeysMidletBuilder(); + builder.setHauskeysDstFile( new File( dstDirectory, profile.getLabel() + ".jar" ) ); + builder.setHauskeysSrcFile( hauskeysSrcFile ); + builder.setTmpDirectory( tmpDirectory ); + builder.setHotpInfo( hotpInfo ); + builder.setMidletName( profile.getLabel() ); + builder.build(); + assertTrue( new File( dstDirectory, profile.getLabel() + ".jar" ).exists() ); + } + } +} Added: directory/trunks/triplesec/verifier/generate-hotp-HOWTO.txt URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/generate-hotp-HOWTO.txt?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/generate-hotp-HOWTO.txt (added) +++ directory/trunks/triplesec/verifier/generate-hotp-HOWTO.txt Tue Dec 12 07:23:31 2006 @@ -0,0 +1,6 @@ +There is a test account and maven goal you can use to generate HOTP values. +Just issue a 'maven generate' to create the next HOTP value for principal +akarasulu@EXAMPLE.COM. + + -Alex + Added: directory/trunks/triplesec/verifier/pom.xml URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/pom.xml?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/pom.xml (added) +++ directory/trunks/triplesec/verifier/pom.xml Tue Dec 12 07:23:31 2006 @@ -0,0 +1,135 @@ + + + + 4.0.0 + + org.safehaus.triplesec + build + 1.0-SNAPSHOT + + triplesec-verifier + Triplesec SAM Verifier + + The Verifier for the SAM Subsystem + + jar + + + ${project.groupId} + triplesec-store + ${project.version} + + + ${project.groupId} + triplesec-otp + ${project.version} + + + org.apache.directory.server + apacheds-kerberos-shared + 1.0-SNAPSHOT + + + org.apache.directory.server + apacheds-protocol-kerberos + 1.0-SNAPSHOT + + + org.apache.directory.server + apacheds-core-unit + 1.0-SNAPSHOT + test + + + org.slf4j + nlog4j + 1.2.25 + provided + + + + + + no-integration-tests + + true + + + + + maven-surefire-plugin + + + **/*ITest.java + **/*IntegrationTest.java + + + + + maven-antrun-plugin + + + validate + + + +================================================================= + W A R N I N G + ------------- + +Integration tests have been disabled. To enable integration +tests run maven with the -Dintegration switch. +================================================================= + + + + + run + + + + + + + + + integration + + integration + + + + + maven-surefire-plugin + + + + workingDirectory + ${basedir}/target/server-work + + + + + + + + + + Added: directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountDisabledException.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountDisabledException.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountDisabledException.java (added) +++ directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountDisabledException.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,50 @@ +/* + * 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.verifier.hotp; + + +import org.safehaus.otp.HotpErrorConstants; + + +/** + * Exception thrown when an account has been disabled. + * + * @version $Rev$ + */ +public class AccountDisabledException extends HotpException +{ + private static final long serialVersionUID = -6514661763410788170L; + public AccountDisabledException() + { + super( HotpErrorConstants.DISABLED_VAL, HotpErrorConstants.DISABLED_MSG ); + } + + + public AccountDisabledException( Throwable throwable ) + { + super( HotpErrorConstants.DISABLED_VAL, HotpErrorConstants.DISABLED_MSG, throwable ); + } + + + public AccountDisabledException( String s, Throwable throwable ) + { + super( HotpErrorConstants.DISABLED_VAL, s, throwable ); + } +} Added: directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountInactiveException.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountInactiveException.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountInactiveException.java (added) +++ directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountInactiveException.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,52 @@ +/* + * 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.verifier.hotp; + + +import org.safehaus.otp.HotpErrorConstants; + + +/** + * Exception thrown when a HOTP account has been deactivated or has not been activated yet. + * + * @version $Rev$ + */ +public class AccountInactiveException extends HotpException +{ + private static final long serialVersionUID = -5526582031617488434L; + + + public AccountInactiveException() + { + super( HotpErrorConstants.INACTIVE_VAL, HotpErrorConstants.INACTIVE_MSG ); + } + + + public AccountInactiveException( Throwable throwable ) + { + super( HotpErrorConstants.INACTIVE_VAL, HotpErrorConstants.INACTIVE_MSG, throwable ); + } + + + public AccountInactiveException( String s, Throwable throwable ) + { + super( HotpErrorConstants.INACTIVE_VAL, s, throwable ); + } +} Added: directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountLockedOutException.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountLockedOutException.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountLockedOutException.java (added) +++ directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/AccountLockedOutException.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,52 @@ +/* + * 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.verifier.hotp; + + +import org.safehaus.otp.HotpErrorConstants; + + +/** + * Exception thrown when a HOTP account is locked. + * + * @version $Rev$ + */ +public class AccountLockedOutException extends HotpException +{ + private static final long serialVersionUID = -5526582031617488434L; + + + public AccountLockedOutException() + { + super( HotpErrorConstants.LOCKEDOUT_VAL, HotpErrorConstants.LOCKEDOUT_MSG ); + } + + + public AccountLockedOutException( Throwable throwable ) + { + super( HotpErrorConstants.LOCKEDOUT_VAL, HotpErrorConstants.LOCKEDOUT_MSG, throwable ); + } + + + public AccountLockedOutException( String s, Throwable throwable ) + { + super( HotpErrorConstants.LOCKEDOUT_VAL, s, throwable ); + } +} Added: directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/DefaultHotpSamVerifier.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/DefaultHotpSamVerifier.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/DefaultHotpSamVerifier.java (added) +++ directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/DefaultHotpSamVerifier.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,404 @@ +/* + * 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.verifier.hotp; + + +import javax.naming.NamingException; +import javax.naming.directory.DirContext; +import javax.security.auth.kerberos.KerberosKey; +import javax.security.auth.kerberos.KerberosPrincipal; + +import org.apache.directory.server.kerberos.shared.messages.value.SamType; +import org.apache.directory.server.kerberos.sam.KeyIntegrityChecker; +import org.apache.directory.server.kerberos.sam.SamException; + +import org.safehaus.otp.Hotp; +import org.safehaus.otp.ResynchParameters; +import org.safehaus.profile.ServerProfile; +import org.safehaus.profile.BaseServerProfileModifier; +import org.safehaus.triplesec.store.ServerProfileStore; +import org.safehaus.triplesec.store.DefaultServerProfileStore; + + +/** + * A HOTP based SAM verifier. + * + * @author Alex Karasulu + * @version $Rev$ + */ +public class DefaultHotpSamVerifier implements HotpSamVerifier +{ + /** + * For now we hardcode the HOTP_SIZE to 6 but we can use the realm info + * or profile specific info to determine size to use dynamically at runtime. + */ + public static final int HOTP_SIZE = 6; + + /** Message for failure to access properties */ + public static final String FAILED_PROP_ACCESS_MSG = "Failed to open safehaus store properties"; + + /** Message for store initialization failures */ + private static final String FAILED_INITIALIZING_STORE = "Failed initializing store"; + + /** temporary property key which controls the use of alternate monitor */ + private static final String MONITOR_PROP = "org.safehaus.verifier.monitor"; + + /** the safehaus (hotp) profile store */ + ServerProfileStore store = null; + + /** checks keys based on hotp values for integrity */ + KeyIntegrityChecker keyChecker = null; + + /** the verification process monitor */ + private HotpMonitor monitor = findHotpMonitor(); + + /** The context under which users are stored for the realm*/ + private DirContext userContext; + + + // ----------------------------------------------------------------------- + // SamVerifier Method Implementations + // ----------------------------------------------------------------------- + + + public void setUserContext( DirContext userContext ) + { + this.userContext = userContext; + } + + + /** + * Starts up the verifier by initializing the profile store using + * the provided environment properties. + * + * @throws SamException if there are problems initializing the store + */ + public void startup() throws SamException + { + // Check if userContext is set + + if ( this.userContext == null ) + { + throw new SamException( getSamType(), "User context has not been initialized!" ); + } + + // Initialize the profile store using context + + try + { + store = new DefaultServerProfileStore( userContext ); + store.init(); + } + catch ( NamingException e ) + { + throw new SamException( getSamType(), FAILED_INITIALIZING_STORE, e ); + } + + // Make sure KeyIntegrityChecker has been set + + if ( keyChecker == null ) + { + throw new SamException( getSamType(), "KeyIntegrityChecker not set!" ); + } + } + + + public void shutdown() + { + this.userContext = null; + this.store = null; + this.monitor = null; + this.keyChecker = null; + } + + + public void setIntegrityChecker( KeyIntegrityChecker keyChecker ) + { + this.keyChecker = keyChecker; + } + + + public KerberosKey verify( KerberosPrincipal principal, byte[] sad ) throws SamException + { + monitor.verifying( principal ); + + try + { + ServerProfile p = store.getProfile( principal ); + if ( p == null ) + { + throw new SamException( getSamType(), "Principal " + principal + " not found in store!" ); + } + + ResynchParameters params = getResychParameters( p ); + + // ------------------------------------------------------------ + // blow chunks for accounts that are inactive or disabled + // ------------------------------------------------------------ + + if ( ! p.isActive() ) + { + throw new AccountInactiveException(); + } + + if ( p.isDisabled() ) + { + throw new AccountDisabledException(); + } + + // ------------------------------------------------------------ + // blow chunks for accounts that are locked out + // ------------------------------------------------------------ + + if ( p.getFailuresInEpoch() >= params.getLockoutCount() ) + { + monitor.accountLocked( p, params ); + + throw new AccountLockedOutException(); + } + + // ------------------------------------------------------------ + // let generate and verify if client value is valid + // ------------------------------------------------------------ + + byte[] secret = p.getSecret(); + String serverValue = Hotp.generate( secret, p.getFactor(), HOTP_SIZE ); + KerberosKey serverKey = new KerberosKey( principal, serverValue.toCharArray(), "DES" ); + + if ( keyChecker.checkKeyIntegrity( sad, serverKey ) ) + { + monitor.integrityCheckPassed( p ); + + BaseServerProfileModifier modifier = new BaseServerProfileModifier( p ); + + modifier.setFactor( p.getFactor() + 1 ); + + // ------------------------------------------------------------ + // let's check to see if the client is under resynch process + // ------------------------------------------------------------ + + if ( p.getResynchCount() > 0 ) + { + // -------------------------------------------------------- + // if client must continue process we generate exception + // -------------------------------------------------------- + + if ( p.getResynchCount() < params.getNumResyncValidations() - 1 ) + { + modifier.setResynchCount( p.getResynchCount() + 1 ); + store.update( principal, modifier.getServerProfile() ); + monitor.resynchInProgress( p, params ); + throw new ResynchInProgressException(); + } + + // -------------------------------------------------------- + // the client has successfully completed resynch process + // -------------------------------------------------------- + + monitor.resynchCompleted( p, params ); + modifier.setResynchCount( -1 ); + } + + store.update( principal, modifier.getServerProfile() ); + + return serverKey; + } + + monitor.integrityCheckFailed( p ); + + // ---------------------------------------------------------------- + // client gave incorrect value so we check if resynch is possible + // ---------------------------------------------------------------- + // o if we find a match in window, + // + advance factor to one past the val that made curr client val + // + increment the resynch count so we can terminate resynch proc + // + update the profile with new values in store + // + blow stack to show we've started resync process + // ---------------------------------------------------------------- + + monitor.checkingLookahead( p, params ); + KerberosKey[] window = getWindow( principal, p, params.getLookaheadSize() ); + BaseServerProfileModifier modifier = new BaseServerProfileModifier( p ); + + for ( int ii = 0; ii < window.length; ii++ ) + { + if ( keyChecker.checkKeyIntegrity( sad, window[ii] ) ) + { + modifier.setFactor( p.getFactor() + ii + 2 ); + modifier.setResynchCount( 1 ); + store.update( principal, modifier.getServerProfile() ); + monitor.initiatingResynch( p, params ); + throw new ResynchStartingException(); + } + } + + // ---------------------------------------------------------------- + // client gave incorrect value and resynch is not at all possible + // ---------------------------------------------------------------- + // o moving factor does NOT increment but the failure count does + // o we update profile and throw an exception to indicate failure + // ---------------------------------------------------------------- + + modifier.setFailuresInEpoch( p.getFailuresInEpoch() + 1 ); + monitor.verificationFailed( p, params ); + store.update( principal, modifier.getServerProfile() ); + throw new PreauthFailedException(); + } + catch ( NamingException e ) + { + String msg = "Failed to access profile for " + principal.getName(); + + throw new SamException( getSamType(), msg, e ); + } + } + + + public final SamType getSamType() + { + return SamType.PA_SAM_TYPE_APACHE; + } + + + public HotpMonitor getHotpMonitor() + { + return this.monitor; + } + + + public void setHotpMonitor( HotpMonitor monitor ) + { + if ( monitor == null ) + { + this.monitor = findHotpMonitor(); + } + else + { + this.monitor = monitor; + } + } + + + /** + * Used by test cases. + * + * @return returns the store for testing purposes only + */ + ServerProfileStore getStore() + { + return this.store; + } + + + /** + * Generates a window of Hotp values as KerberosKeys used to determine if a + * moving factor resynchronization is required. The values start with the + * next factor value in the profile. + * + * @param principal the kerberos principal associated with the profile + * @param p the server side safehaus (hotp) profile + * @param size the size of the resynchronization window + * @return the hotp values as KerberosKeys for the window + */ + private KerberosKey[] getWindow( KerberosPrincipal principal, ServerProfile p, int size ) + { + KerberosKey[] window = new KerberosKey[size]; + + byte[] secret = p.getSecret(); + + for ( int ii = 0; ii < size; ii++ ) + { + String hotp = Hotp.generate( secret, p.getFactor() + ii + 1, HOTP_SIZE ); + + window[ii] = new KerberosKey( principal, hotp.toCharArray(), "DES" ); + } + + return window; + } + + + /** + * Gets an alternative monitor if one exists, otherwise an adapter is used. + */ + public static HotpMonitor findHotpMonitor() + { + String fqcn = null; + + fqcn = System.getProperty( MONITOR_PROP ); + + if ( fqcn == null ) + { + return new HotpMonitorAdapter(); + } + + try + { + Class c = Class.forName( fqcn ); + + if ( c != null ) + { + HotpMonitor alt = ( HotpMonitor ) c.newInstance(); + + if ( alt != null ) + { + return alt; + } + } + } + catch ( ClassNotFoundException e ) + { + e.printStackTrace(); + } + catch ( IllegalAccessException e ) + { + e.printStackTrace(); + } + catch ( InstantiationException e ) + { + e.printStackTrace(); + } + + return new HotpMonitorAdapter(); + } + + + /** + * Gets the resynch parameters for a specific profile or its domain if + * available. If a profile does not contain resynch parameters it's domain + * will be consulted. If the domain does not contain the properties then + * the defaults will be used. + * + * @param p the user's server side profile + * @return the resynch parameters to use + */ + private ResynchParameters getResychParameters( ServerProfile p ) + { + ResynchParameters params = null; + + if ( p == null ) + { + params = ResynchParameters.DEFAULTS; + } + + // replace code here to search for parameters + params = ResynchParameters.DEFAULTS; + + return params; + } +} Added: directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpException.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpException.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpException.java (added) +++ directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpException.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,162 @@ +/* + * 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.verifier.hotp; + + +import org.apache.directory.server.kerberos.shared.messages.value.SamType; +import org.apache.directory.server.kerberos.sam.SamException; + +import org.safehaus.otp.HotpErrorConstants; + + +/** + * A Hotp specific SamException. + * + * @author Alex Karasulu + * @version $Rev$ + */ +public class HotpException extends SamException +{ + private static final long serialVersionUID = -798453831733119227L; + /** the type of this exception */ + private final int ordinal; + + + /** + * Creates a HotpException using an ordinal. + * + * @param ordinal the ordinal for this exception type + */ + public HotpException( int ordinal ) + { + super( SamType.PA_SAM_TYPE_APACHE, ( String ) HotpErrorConstants.getErrorMessage( ordinal ) ); + this.ordinal = ordinal; + } + + + /** + * Creates a HotpException using an ordinal with underlying exception. + * + * @param ordinal the ordinal for this exception type + * @param throwable the underlying exception + */ + public HotpException( int ordinal, Throwable throwable ) + { + super( SamType.PA_SAM_TYPE_APACHE, ( String ) HotpErrorConstants.getErrorMessage( ordinal ), throwable ); + + this.ordinal = ordinal; + } + + + /** + * Creates a HotpException 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 HotpException( int ordinal, String s ) + { + super( SamType.PA_SAM_TYPE_APACHE, ! s.startsWith( HotpErrorConstants.PREFIX ) ? HotpErrorConstants.PREFIX + ordinal + "]: " + s : s ); + + this.ordinal = ordinal; + } + + + /** + * Creates a HotpException using an ordinal with underlying exception and error mesage. + * + * @param ordinal the ordinal for this exception type + * @param s an error message string + * @param throwable the underlying exception + */ + public HotpException( int ordinal, String s, Throwable throwable ) + { + super( SamType.PA_SAM_TYPE_APACHE, ! s.startsWith( HotpErrorConstants.PREFIX ) ? HotpErrorConstants.PREFIX + ordinal + "]: " + s : s, throwable ); + + this.ordinal = ordinal; + } + + + /** + * Creates a HotpException from error mesage which must have a prefix. + * + * @param s an error message string + */ + public HotpException( String s ) + { + super( SamType.PA_SAM_TYPE_APACHE, s ); + + if ( ! s.startsWith( HotpErrorConstants.PREFIX ) ) + { + throw new IllegalArgumentException( "Message does not contain the prefix: " + HotpErrorConstants.PREFIX ); + } + + ordinal = HotpErrorConstants.getOrdinal( s ); + } + + + /** + * Creates a HotpException from another exception however it's message must have a prefix. + * + * @param throwable the underlying exception + */ + public HotpException( Throwable throwable ) + { + super( SamType.PA_SAM_TYPE_APACHE, throwable ); + + if ( ! throwable.getMessage().startsWith( HotpErrorConstants.PREFIX ) ) + { + throw new IllegalArgumentException( "Throwable's message does not contain the prefix: " + HotpErrorConstants.PREFIX ); + } + + ordinal = HotpErrorConstants.getOrdinal( throwable.getMessage() ); + } + + + /** + * Creates a HotpException from error mesage which must have a prefix. + * + * @param s an error message string + * @param throwable the underlying exception + */ + public HotpException( String s, Throwable throwable ) + { + super( SamType.PA_SAM_TYPE_APACHE, s, throwable ); + + if ( ! s.startsWith( HotpErrorConstants.PREFIX ) ) + { + throw new IllegalArgumentException( "Message does not contain the prefix: " + HotpErrorConstants.PREFIX ); + } + + ordinal = HotpErrorConstants.getOrdinal( s ); + } + + + /** + * 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/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpMonitor.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpMonitor.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpMonitor.java (added) +++ directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpMonitor.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,62 @@ +/* + * 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.verifier.hotp; + + +import javax.security.auth.kerberos.KerberosPrincipal; + +import org.safehaus.profile.ServerProfile; +import org.safehaus.otp.ResynchParameters; + + +/** + * An interface for monitoring the HotpSamVerifier using callbacks. + * + * @author Apache Directory Project + * @version $Rev$ + */ +public interface HotpMonitor +{ + void verificationFailed( ServerProfile p, ResynchParameters params ); + + + void initiatingResynch( ServerProfile p, ResynchParameters params ); + + + void checkingLookahead( ServerProfile p, ResynchParameters params ); + + + void integrityCheckFailed( ServerProfile p ); + + + void resynchCompleted( ServerProfile p, ResynchParameters params ); + + + void resynchInProgress( ServerProfile p, ResynchParameters params ); + + + void integrityCheckPassed( ServerProfile p ); + + + void accountLocked( ServerProfile p, ResynchParameters params ); + + + void verifying( KerberosPrincipal principal ); +} Added: directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpMonitorAdapter.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpMonitorAdapter.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpMonitorAdapter.java (added) +++ directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpMonitorAdapter.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,81 @@ +/* + * 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.verifier.hotp; + + +import javax.security.auth.kerberos.KerberosPrincipal; + +import org.safehaus.profile.ServerProfile; +import org.safehaus.otp.ResynchParameters; +import org.safehaus.triplesec.verifier.hotp.HotpMonitor; + + +/** + * A 'do nothing' adapter for HotpMonitor interface. At a minimum exceptions + * are printed to standard err to avoid silencing critical alerts. + * + * @version $Rev$ + */ +public class HotpMonitorAdapter implements HotpMonitor +{ + public void verificationFailed( ServerProfile p, ResynchParameters params ) + { + } + + + public void initiatingResynch( ServerProfile p, ResynchParameters params ) + { + } + + + public void checkingLookahead( ServerProfile p, ResynchParameters params ) + { + } + + + public void integrityCheckFailed( ServerProfile p ) + { + } + + + public void resynchCompleted( ServerProfile p, ResynchParameters params ) + { + } + + + public void resynchInProgress( ServerProfile p, ResynchParameters params ) + { + } + + + public void integrityCheckPassed( ServerProfile p ) + { + } + + + public void accountLocked( ServerProfile p, ResynchParameters params ) + { + } + + + public void verifying( KerberosPrincipal principal ) + { + } +} Added: directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpSamVerifier.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpSamVerifier.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpSamVerifier.java (added) +++ directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/HotpSamVerifier.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,41 @@ +/* + * 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.verifier.hotp; + + +import org.apache.directory.server.kerberos.sam.SamVerifier; +import org.safehaus.triplesec.verifier.hotp.HotpMonitor; + + +/** + * Specialized version of the SamVerifier which exposes a monitor interface. + * + * @version $Rev$ + */ +public interface HotpSamVerifier extends SamVerifier +{ + /** + * Gets the monitor that receives notable events within the hotp + * verification process. + * + * @return the monitor for the HOTP verification workflow + */ + HotpMonitor getHotpMonitor(); +} Added: directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/PreauthFailedException.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/PreauthFailedException.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/PreauthFailedException.java (added) +++ directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/PreauthFailedException.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,53 @@ +/* + * 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.verifier.hotp; + + +import org.safehaus.otp.HotpErrorConstants; +import org.safehaus.triplesec.verifier.hotp.HotpException; + + +/** + * Exception thrown when a HOTP account is locked. + * + * @version $Rev$ + */ +public class PreauthFailedException extends HotpException +{ + private static final long serialVersionUID = 3995853734626716589L; + + + public PreauthFailedException() + { + super( HotpErrorConstants.HOTPAUTH_FAILURE_VAL, HotpErrorConstants.HOTPAUTH_FAILURE_MSG ); + } + + + public PreauthFailedException( Throwable throwable ) + { + super( HotpErrorConstants.HOTPAUTH_FAILURE_VAL, HotpErrorConstants.HOTPAUTH_FAILURE_MSG, throwable ); + } + + + public PreauthFailedException( String s, Throwable throwable ) + { + super( HotpErrorConstants.HOTPAUTH_FAILURE_VAL, s, throwable ); + } +} Added: directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/ResynchInProgressException.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/ResynchInProgressException.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/ResynchInProgressException.java (added) +++ directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/ResynchInProgressException.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,53 @@ +/* + * 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.verifier.hotp; + + +import org.safehaus.otp.HotpErrorConstants; +import org.safehaus.triplesec.verifier.hotp.HotpException; + + +/** + * Exception thrown when a HOTP account is locked. + * + * @version $Rev$ + */ +public class ResynchInProgressException extends HotpException +{ + private static final long serialVersionUID = 3398366394639243079L; + + + public ResynchInProgressException() + { + super( HotpErrorConstants.RESYNCH_INPROGRESS_VAL, HotpErrorConstants.RESYNCH_INPROGRESS_MSG ); + } + + + public ResynchInProgressException( Throwable throwable ) + { + super( HotpErrorConstants.RESYNCH_INPROGRESS_VAL, HotpErrorConstants.RESYNCH_INPROGRESS_MSG, throwable ); + } + + + public ResynchInProgressException( String s, Throwable throwable ) + { + super( HotpErrorConstants.RESYNCH_INPROGRESS_VAL, s, throwable ); + } +} Added: directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/ResynchStartingException.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/ResynchStartingException.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/ResynchStartingException.java (added) +++ directory/trunks/triplesec/verifier/src/main/java/org/safehaus/triplesec/verifier/hotp/ResynchStartingException.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,53 @@ +/* + * 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.verifier.hotp; + + +import org.safehaus.otp.HotpErrorConstants; +import org.safehaus.triplesec.verifier.hotp.HotpException; + + +/** + * Exception thrown when a HOTP account is locked. + * + * @version $Rev$ + */ +public class ResynchStartingException extends HotpException +{ + private static final long serialVersionUID = -6737173851940225520L; + + + public ResynchStartingException() + { + super( HotpErrorConstants.RESYNCH_STARTING_VAL, HotpErrorConstants.RESYNCH_STARTING_MSG ); + } + + + public ResynchStartingException( Throwable throwable ) + { + super( HotpErrorConstants.RESYNCH_STARTING_VAL, HotpErrorConstants.RESYNCH_STARTING_MSG, throwable ); + } + + + public ResynchStartingException( String s, Throwable throwable ) + { + super( HotpErrorConstants.RESYNCH_STARTING_VAL, s, throwable ); + } +} Added: directory/trunks/triplesec/verifier/src/test/java/org/safehaus/triplesec/verifier/hotp/GenerateHotp.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/verifier/src/test/java/org/safehaus/triplesec/verifier/hotp/GenerateHotp.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/verifier/src/test/java/org/safehaus/triplesec/verifier/hotp/GenerateHotp.java (added) +++ directory/trunks/triplesec/verifier/src/test/java/org/safehaus/triplesec/verifier/hotp/GenerateHotp.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,184 @@ +/* + * 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.verifier.hotp; + + +import java.io.File; +import java.util.*; + +import javax.security.auth.kerberos.KerberosPrincipal; +import javax.naming.NamingException; +import javax.naming.Context; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttributes; + +import org.safehaus.triplesec.store.*; +import org.safehaus.triplesec.store.schema.SafehausSchema; +import org.safehaus.profile.ServerProfile; +import org.safehaus.profile.BaseServerProfileModifier; +import org.safehaus.otp.Hotp; +import org.safehaus.otp.Base64; +import org.apache.directory.server.core.schema.bootstrap.*; +import org.apache.directory.server.core.configuration.MutableStartupConfiguration; +import org.apache.directory.server.core.configuration.MutablePartitionConfiguration; +import org.apache.directory.server.core.configuration.Configuration; +import org.apache.directory.shared.ldap.message.LockableAttributesImpl; +import org.apache.directory.shared.ldap.message.LockableAttributeImpl; +import org.apache.directory.server.protocol.shared.store.Krb5KdcEntryFilter; +import org.apache.directory.server.protocol.shared.store.LdifFileLoader; + + +/** + * Generates the next Hotp value and updates the store. Running test cases + * will effect the values stored within the store. Deleting the store will + * reinitialize the store. + * + * @author Apache Directory Project + * @version $Rev$ + */ +public class GenerateHotp +{ + public static final KerberosPrincipal DEFAULT_PRINCIPAL = new KerberosPrincipal( "akarasulu@EXAMPLE.COM" ); + + + public static void main( String[] args ) + { + KerberosPrincipal principal = null; + + try + { + principal = DEFAULT_PRINCIPAL; + + MutableStartupConfiguration config = new MutableStartupConfiguration(); + + MutablePartitionConfiguration partConfig = new MutablePartitionConfiguration(); + partConfig.setName( "example" ); + + HashSet indices = new HashSet(); + indices.add( "dc" ); + indices.add( "ou" ); + indices.add( "objectClass" ); + indices.add( "krb5PrincipalName" ); + indices.add( "uid" ); + partConfig.setIndexedAttributes( indices ); + + partConfig.setSuffix( "dc=example,dc=com" ); + + LockableAttributesImpl attrs = new LockableAttributesImpl(); + LockableAttributeImpl attr = new LockableAttributeImpl( "objectClass" ); + attr.add( "top" ); + attr.add( "domain" ); + attrs.put( attr ); + attrs.put( "dc", "example" ); + partConfig.setContextEntry( attrs ); + + Set schemas = new HashSet(); + schemas.add( new SystemSchema() ); + schemas.add( new SafehausSchema() ); + schemas.add( new ApacheSchema() ); + schemas.add( new CoreSchema() ); + schemas.add( new CosineSchema() ); + schemas.add( new InetorgpersonSchema() ); + schemas.add( new Krb5kdcSchema() ); + config.setBootstrapSchemas( schemas ); + config.setContextPartitionConfigurations( Collections.singleton( partConfig ) ); + + partConfig.setSuffix( "dc=example,dc=com" ); + + Hashtable env = new Hashtable(); + env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.directory.server.core.jndi.CoreContextFactory" ); + env.put( Context.PROVIDER_URL, "dc=example,dc=com" ); + env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" ); + env.put( Context.SECURITY_AUTHENTICATION, "simple" ); + env.put( Context.SECURITY_CREDENTIALS, "secret" ); + env.put( Configuration.JNDI_KEY, config ); + env.put( Context.STATE_FACTORIES, ProfileStateFactory.class.getName() ); + env.put( Context.OBJECT_FACTORIES, ProfileObjectFactory.class.getName() ); + + DirContext userContext = new InitialDirContext( env ); + try + { + userContext = ( DirContext ) userContext.lookup( "ou=users" ); + } + catch ( NamingException e ) + { + Attributes users = new BasicAttributes( "objectClass", "top", true ); + users.get( "objectClass" ).add( "organizationalUnit" ); + attrs.put( "ou", "users" ); + userContext = userContext.createSubcontext( "ou=users", attrs ); + } + + ServerProfileStore store = new DefaultServerProfileStore( userContext ); + store.init(); + + List filters = Collections.singletonList( new Krb5KdcEntryFilter() ); + LdifFileLoader loader = new LdifFileLoader( userContext, new File( "safehaus.ldif" ), filters, + GenerateHotp.class.getClassLoader() ); + loader.execute(); + + if ( args.length > 0 ) + { + principal = new KerberosPrincipal( args[0] ); + } + + ServerProfile p = store.getProfile( principal ); + + if ( p == null ) + { + System.err.println( "Principal " + principal + " not found!" ); + + System.exit( -1 ); + } + + BaseServerProfileModifier modifier = new BaseServerProfileModifier( p ); + System.out.println( "Secret hex = " + getHex( p.getSecret() ) ); + System.out.println( "Secret base64 = " + new String( Base64.encode( p.getSecret() ) ) ); + System.out.println( "Moving factor = " + p.getFactor() ); + String hotp = Hotp.generate( p.getSecret(), p.getFactor(), DefaultHotpSamVerifier.HOTP_SIZE ); + modifier.incrementFactor(); + store.update( principal, modifier.getServerProfile() ); + System.out.println( "The next HOTP value for principal " + principal + " is " + hotp ); + } + catch ( NamingException e ) + { + System.err.println( "Failed while accessing or updating principal " + principal + " in store!" ); + + System.exit( -3 ); + } + } + + + public static final char[] HEXCHARS = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + static String getHex( byte[] bytes ) + { + StringBuffer buf = new StringBuffer(); + + for ( int ii = 0; ii < bytes.length; ii++ ) + { + buf.append( HEXCHARS[ ( bytes[ii] & 0x70 ) >> 4] ); + buf.append( HEXCHARS[bytes[ii] & 0x0f] ); + } + + return buf.toString(); + } +}