You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2007/02/20 17:51:34 UTC

svn commit: r509642 [1/2] - in /incubator/qpid/trunk/qpid/java: ./ client-java14/ client-java14/etc/ client-java14/src/ client-java14/src/main/ client-java14/src/main/assembly/ client-java14/src/main/java/ client-java14/src/main/java/org/ client-java14...

Author: rgreig
Date: Tue Feb 20 08:51:32 2007
New Revision: 509642

URL: http://svn.apache.org/viewvc?view=rev&rev=509642
Log:
(Path submitted by Rupert Smith) Qpid-338. Custom SASL implementation for Java 1.4 retrotranslation of the Java client.

Added:
    incubator/qpid/trunk/qpid/java/client-java14/
    incubator/qpid/trunk/qpid/java/client-java14/README.txt
    incubator/qpid/trunk/qpid/java/client-java14/client-java14.iml
    incubator/qpid/trunk/qpid/java/client-java14/etc/
    incubator/qpid/trunk/qpid/java/client-java14/etc/sasl.properties
    incubator/qpid/trunk/qpid/java/client-java14/pom.xml
    incubator/qpid/trunk/qpid/java/client-java14/src/
    incubator/qpid/trunk/qpid/java/client-java14/src/main/
    incubator/qpid/trunk/qpid/java/client-java14/src/main/assembly/
    incubator/qpid/trunk/qpid/java/client-java14/src/main/assembly/client-java14-bin.xml
    incubator/qpid/trunk/qpid/java/client-java14/src/main/java/
    incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/
    incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/
    incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/
    incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/
    incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/ClientFactoryImpl.java
    incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/CramMD5Client.java
    incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/PlainClient.java
    incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/Provider.java
    incubator/qpid/trunk/qpid/java/client-java14/src/test/
    incubator/qpid/trunk/qpid/java/client-java14/src/test/java/
    incubator/qpid/trunk/qpid/java/client-java14/src/test/java/org/
    incubator/qpid/trunk/qpid/java/client-java14/src/test/java/org/apache/
    incubator/qpid/trunk/qpid/java/client-java14/src/test/java/org/apache/qpid/
    incubator/qpid/trunk/qpid/java/client-java14/src/test/java/org/apache/qpid/test/
    incubator/qpid/trunk/qpid/java/client-java14/src/test/java/org/apache/qpid/test/integration/
    incubator/qpid/trunk/qpid/java/client-java14/src/test/java/org/apache/qpid/test/integration/client/
    incubator/qpid/trunk/qpid/java/client-java14/src/test/java/org/apache/qpid/test/integration/client/ConnectionTest.java
    incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java
    incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/util/PrettyPrintingUtils.java
Modified:
    incubator/qpid/trunk/qpid/java/client/distribution/pom.xml
    incubator/qpid/trunk/qpid/java/client/pom.xml
    incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
    incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.java
    incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
    incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
    incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
    incubator/qpid/trunk/qpid/java/common/pom.xml
    incubator/qpid/trunk/qpid/java/pom.xml

Added: incubator/qpid/trunk/qpid/java/client-java14/README.txt
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client-java14/README.txt?view=auto&rev=509642
==============================================================================
--- incubator/qpid/trunk/qpid/java/client-java14/README.txt (added)
+++ incubator/qpid/trunk/qpid/java/client-java14/README.txt Tue Feb 20 08:51:32 2007
@@ -0,0 +1,33 @@
+An implementation of SASL is provided here, for the PLAIN and CRAM-MD5 mechanisms as well as maven assembly
+instructions for producing a backported Java client for Java 1.4. In order to use the custom SASL implementation
+on JRE 1.4 the following steps must be taken:
+
+ * Install the SASL JSR-28 API jar.
+ * Install the qpid-client-java14 jar or set it up as a dynamically registered SASL provider.
+ * Set up java.security to add the SASL provider to the list of security providers if hte SASL implemenation jar was installed as an extension.
+
+Installing the SASL JSR-28 API jar.
+
+ Download, http://www.worldspot.com/jsr28/v1.1/download/sasl.jar, and copy it to the JAVA_HOME\lib\ext directory.
+
+Install or set up the qpid-client-java14 jar.
+
+ Copy the output jar for this project, qpid-client-java14-1.0-incubating-M2-SNAPSHOT.jar, to JAVA_HOME\lib\ext. 
+ 
+ OR
+ 
+ Create a properties file and register the SASL implementations in the jar so that Qpids dynamic SASL registry can find them. In a properties file
+ add the lines:
+
+  PLAIN=org.apache.qpid.sasl.ClientFactoryImpl
+  CRAM-MD5=org.apache.qpid.sasl.ClientFactoryImpl
+
+ Place this somewhere on the classpath and put the qpid-client-java14-1.0-incubating-M2-SNAPSHOT.jar on the classpath too. When starting your application
+ pass in the system property amq.dynamicsaslregistrar.properties and set it to point to the location of the properties file.
+
+Set up the SASL provider.
+
+ You only need to do this if the custom SASL jar, qpid-client-java14-1.0-incubating-M2-SNAPSHOT.jar, was copied to JAVA_HOME\lib\ext. 
+ Add the following line to JAVA_HOME\lib\security\java.security file (where n is the providers preference order):
+
+ security.provider.n=org.apache.qpid.sasl.Provider
\ No newline at end of file

Added: incubator/qpid/trunk/qpid/java/client-java14/client-java14.iml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client-java14/client-java14.iml?view=auto&rev=509642
==============================================================================
--- incubator/qpid/trunk/qpid/java/client-java14/client-java14.iml (added)
+++ incubator/qpid/trunk/qpid/java/client-java14/client-java14.iml Tue Feb 20 08:51:32 2007
@@ -0,0 +1,469 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module version="4" relativePaths="true" type="JAVA_MODULE">
+  <component name="ModuleRootManager" />
+  <component name="NewModuleRootManager">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <exclude-output />
+    <exclude-exploded />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="qpid-client" />
+    <orderEntry type="module" module-name="qpid-common" />
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/concurrent/concurrent/1.3.2/concurrent-1.3.2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/junit/junit/3.8.1/junit-3.8.1-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/relaxngDatatype/relaxngDatatype/20020414/relaxngDatatype-20020414.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/relaxngDatatype/relaxngDatatype/20020414/relaxngDatatype-20020414-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/apache/mina/mina-core/1.0.0/mina-core-1.0.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/apache/mina/mina-core/1.0.0/mina-core-1.0.0-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/isorelax/isorelax/20020414/isorelax-20020414.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/isorelax/isorelax/20020414/isorelax-20020414-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.jar!/" />
+        </CLASSES>
+        <JAVADOC>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4-javadoc.jar!/" />
+        </JAVADOC>
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/log4j/log4j/1.2.12/log4j-1.2.12.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/xdoclet/xdoclet-xjavadoc-uc/1.2b2/xdoclet-xjavadoc-uc-1.2b2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/xdoclet/xdoclet-xdoclet-module/1.2b2/xdoclet-xdoclet-module-1.2b2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-lang/commons-lang/2.1/commons-lang-2.1.jar!/" />
+        </CLASSES>
+        <JAVADOC>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-lang/commons-lang/2.1/commons-lang-2.1-javadoc.jar!/" />
+        </JAVADOC>
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-lang/commons-lang/2.1/commons-lang-2.1-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-collections/commons-collections/3.1/commons-collections-3.1.jar!/" />
+        </CLASSES>
+        <JAVADOC>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-collections/commons-collections/3.1/commons-collections-3.1-javadoc.jar!/" />
+        </JAVADOC>
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-collections/commons-collections/3.1/commons-collections-3.1-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-digester/commons-digester/1.6/commons-digester-1.6.jar!/" />
+        </CLASSES>
+        <JAVADOC>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-digester/commons-digester/1.6/commons-digester-1.6-javadoc.jar!/" />
+        </JAVADOC>
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-digester/commons-digester/1.6/commons-digester-1.6-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/xerces/xercesImpl/2.3.0/xercesImpl-2.3.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-cli/commons-cli/1.0/commons-cli-1.0.jar!/" />
+        </CLASSES>
+        <JAVADOC>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-cli/commons-cli/1.0/commons-cli-1.0-javadoc.jar!/" />
+        </JAVADOC>
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-cli/commons-cli/1.0/commons-cli-1.0-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/easymock/easymock/2.2/easymock-2.2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/easymock/easymock/2.2/easymock-2.2-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/msv/msv/20020414/msv-20020414.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/msv/msv/20020414/msv-20020414-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/backport-util-concurrent/backport-util-concurrent/2.2/backport-util-concurrent-2.2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/backport-util-concurrent/backport-util-concurrent/2.2/backport-util-concurrent-2.2-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3.jar!/" />
+        </CLASSES>
+        <JAVADOC>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3-javadoc.jar!/" />
+        </JAVADOC>
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/apache/mina/mina-filter-ssl/1.0.0/mina-filter-ssl-1.0.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/apache/mina/mina-filter-ssl/1.0.0/mina-filter-ssl-1.0.0-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/apache/geronimo/specs/geronimo-jms_1.1_spec/1.0/geronimo-jms_1.1_spec-1.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/oro/oro/2.0.7/oro-2.0.7.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/javax/servlet/servlet-api/2.3/servlet-api-2.3.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/javax/servlet/servlet-api/2.3/servlet-api-2.3-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/xalan/xalan/2.5.1/xalan-2.5.1.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/xalan/xalan/2.5.1/xalan-2.5.1-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/easymock/easymockclassextension/2.2/easymockclassextension-2.2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/easymock/easymockclassextension/2.2/easymockclassextension-2.2-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-configuration/commons-configuration/1.2/commons-configuration-1.2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-configuration/commons-configuration/1.2/commons-configuration-1.2-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/exolabcore/exolabcore/0.3.7/exolabcore-0.3.7.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/apache/mina/mina-java5/1.0.0/mina-java5-1.0.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/apache/mina/mina-java5/1.0.0/mina-java5-1.0.0-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/ant/ant/1.5.3-1/ant-1.5.3-1.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/ant/ant/1.5.3-1/ant-1.5.3-1-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/jaxen/jaxen/1.0-FCS/jaxen-1.0-FCS.jar!/" />
+        </CLASSES>
+        <JAVADOC>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/jaxen/jaxen/1.0-FCS/jaxen-1.0-FCS-javadoc.jar!/" />
+        </JAVADOC>
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/jaxen/jaxen/1.0-FCS/jaxen-1.0-FCS-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/xdoclet/xdoclet/1.2b2/xdoclet-1.2b2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/slf4j/slf4j-simple/1.0/slf4j-simple-1.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/org/slf4j/slf4j-simple/1.0/slf4j-simple-1.0-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/castor/castor/0.9.5/castor-0.9.5.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/castor/castor/0.9.5/castor-0.9.5-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-beanutils/commons-beanutils/1.6/commons-beanutils-1.6.jar!/" />
+        </CLASSES>
+        <JAVADOC>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-beanutils/commons-beanutils/1.6/commons-beanutils-1.6-javadoc.jar!/" />
+        </JAVADOC>
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/xml-apis/xml-apis/1.0.b2/xml-apis-1.0.b2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/xml-apis/xml-apis/1.0.b2/xml-apis-1.0.b2-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-beanutils/commons-beanutils-core/1.7.0/commons-beanutils-core-1.7.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/ant/ant-optional/1.5.3-1/ant-optional-1.5.3-1.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/commons-logging/commons-logging-api/1.0.4/commons-logging-api-1.0.4.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/dom4j/dom4j/1.4/dom4j-1.4.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/dom4j/dom4j/1.4/dom4j-1.4-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/saxpath/saxpath/1.0-FCS/saxpath-1.0-FCS.jar!/" />
+        </CLASSES>
+        <JAVADOC>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/saxpath/saxpath/1.0-FCS/saxpath-1.0-FCS-javadoc.jar!/" />
+        </JAVADOC>
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/saxpath/saxpath/1.0-FCS/saxpath-1.0-FCS-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/jmscts/jmscts/0.5-b2/jmscts-0.5-b2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../../../.m2/repository/net/sf/retrotranslator/retrotranslator-runtime/1.2.1/retrotranslator-runtime-1.2.1.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+    <orderEntryProperties />
+  </component>
+</module>
+

Added: incubator/qpid/trunk/qpid/java/client-java14/etc/sasl.properties
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client-java14/etc/sasl.properties?view=auto&rev=509642
==============================================================================
--- incubator/qpid/trunk/qpid/java/client-java14/etc/sasl.properties (added)
+++ incubator/qpid/trunk/qpid/java/client-java14/etc/sasl.properties Tue Feb 20 08:51:32 2007
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+PLAIN=org.apache.qpid.sasl.ClientFactoryImpl
+CRAM-MD5=org.apache.qpid.sasl.ClientFactoryImpl

Added: incubator/qpid/trunk/qpid/java/client-java14/pom.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client-java14/pom.xml?view=auto&rev=509642
==============================================================================
--- incubator/qpid/trunk/qpid/java/client-java14/pom.xml (added)
+++ incubator/qpid/trunk/qpid/java/client-java14/pom.xml Tue Feb 20 08:51:32 2007
@@ -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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.qpid</groupId>
+    <artifactId>qpid-client-java14</artifactId>
+    <packaging>jar</packaging>
+    <version>1.0-incubating-M2-SNAPSHOT</version>
+    <name>Qpid Client for Java 1.4</name>
+    <url>http://cwiki.apache.org/confluence/display/qpid</url>
+
+    <parent>
+        <groupId>org.apache.qpid</groupId>
+        <artifactId>qpid</artifactId>
+        <version>1.0-incubating-M2-SNAPSHOT</version>
+    </parent>
+
+    <properties>
+        <topDirectoryLocation>..</topDirectoryLocation>
+        <java.source.version>1.4</java.source.version>
+        <qpid.version>${pom.version}</qpid.version>
+        <qpid.targetDir>${project.build.directory}</qpid.targetDir>
+        <qpid.root>${basedir}/..</qpid.root>
+        <sasl.properties>${basedir}/etc/sasl.properties</sasl.properties>
+        <jvm.1.4.bin>path/to/java1.4</jvm.1.4.bin>
+    </properties>
+
+    <dependencies>
+
+        <!-- Use the java 1.4 retrotranslated client. -->
+        <dependency>
+            <groupId>org.apache.qpid</groupId>
+            <artifactId>qpid-client</artifactId>
+            <type>jar</type>
+            <version>${pom.version}</version>
+            <classifier>java14</classifier>
+        </dependency>
+
+        <!-- Use the java 1.4 retrotranslated common library. -->
+        <dependency>
+            <groupId>org.apache.qpid</groupId>
+            <artifactId>qpid-common</artifactId>
+            <type>jar</type>
+            <version>${pom.version}</version>
+            <classifier>java14</classifier>
+        </dependency>
+
+        <dependency>
+            <groupId>net.sf.retrotranslator</groupId>
+            <artifactId>retrotranslator-runtime</artifactId>
+            <scope>package</scope>
+        </dependency>
+
+        <!-- Test dependencies. -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+
+            <!-- Sets up the compiler plugin to compile on 1.4 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${java.source.version}</source>
+                    <target>${java.source.version}</target>
+                </configuration>
+            </plugin>
+
+            <!-- Sets up the assembly plugin to use the assembly directions to build a 1.4 compatable client. -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>${assembly.version}</version>
+                <goals>
+                    <goal>single</goal>
+                </goals>
+                <configuration>
+                    <descriptors>
+                        <descriptor>src/main/assembly/client-java14-bin.xml</descriptor>
+                    </descriptors>
+                    <finalName>qpid-${pom.version}</finalName>
+                    <outputDirectory>${qpid.targetDir}</outputDirectory>
+                    <tarLongFileMode>gnu</tarLongFileMode>
+                </configuration>
+            </plugin>
+
+            <!-- Sets up surefire to run during the integration-test phase instead of the test phase. -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>surefire-it</id>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                        <configuration>
+                            <skip>false</skip>
+                            <forkMode>once</forkMode>
+                            <jvm>${jvm.1.4.bin}</jvm>
+                            <systemProperties>
+                                <property>
+                                    <name>amqj.logging.level</name>
+                                    <value>${amqj.logging.level}</value>
+                                </property>
+                                <property>
+                                    <name>log4j.configuration</name>
+                                    <value>${log4j.configuration}</value>
+                                </property>
+                                <property>
+                                    <name>amq.dynamicsaslregistrar.properties</name>
+                                    <value>${sasl.properties}</value>
+                                </property>
+                            </systemProperties>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+        </plugins>
+    </build>
+</project>

Added: incubator/qpid/trunk/qpid/java/client-java14/src/main/assembly/client-java14-bin.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client-java14/src/main/assembly/client-java14-bin.xml?view=auto&rev=509642
==============================================================================
--- incubator/qpid/trunk/qpid/java/client-java14/src/main/assembly/client-java14-bin.xml (added)
+++ incubator/qpid/trunk/qpid/java/client-java14/src/main/assembly/client-java14-bin.xml Tue Feb 20 08:51:32 2007
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<!-- Assembly instructions for a client that runs on Java 1.4 -->
+<assembly>
+  <id>java-client-java14-bin</id>
+  <includeBaseDirectory>false</includeBaseDirectory>
+  <formats>
+    <format>tar.gz</format>
+    <format>zip</format>
+  </formats>
+
+  <fileSets>
+      <fileSet>
+          <!-- Apache license files -->
+          <directory>../resources</directory>
+          <outputDirectory>qpid-${qpid.version}</outputDirectory>
+          <includes>
+              <include>DISCLAIMER</include>
+              <include>LICENSE.txt</include>
+              <include>NOTICE.txt</include>
+              <include>README.txt</include>
+          </includes>
+      </fileSet>
+
+      <fileSet>
+          <directory>../release-docs</directory>
+          <outputDirectory>qpid-${qpid.version}/docs</outputDirectory>
+          <includes>
+              <include>RELEASE_NOTES.txt</include>
+          </includes>
+      </fileSet>
+
+  </fileSets>
+
+  <dependencySets>
+      <dependencySet>
+          <outputDirectory>qpid-${qpid.version}/lib</outputDirectory>
+          <unpack>false</unpack>
+          <excludes>
+              <!-- Exclude the Java 5 built client and common. The java 1.4 retrotranslated versions are used instead. -->
+             <exclude>org.apache.qpid:qpid-client:jar</exclude>
+             <exclude>org.apache.qpid:qpid-common:jar</exclude>
+
+             <!-- Mina SSL support only available in Java 5. No SSL on 1.4. -->
+             <exclude>org.apache.mina:mina-java5</exclude>
+             <exclude>org.apache.mina:mina-filter-ssl</exclude>
+          </excludes>         
+      </dependencySet>
+  </dependencySets>
+</assembly>
+
+

Added: incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/ClientFactoryImpl.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/ClientFactoryImpl.java?view=auto&rev=509642
==============================================================================
--- incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/ClientFactoryImpl.java (added)
+++ incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/ClientFactoryImpl.java Tue Feb 20 08:51:32 2007
@@ -0,0 +1,343 @@
+/*
+ *
+ * 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.apache.qpid.sasl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.security.auth.callback.*;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslClientFactory;
+import javax.security.sasl.SaslException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.util.PrettyPrintingUtils;
+
+/**
+ * Implements a factory for generating Sasl client implementations.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Provide a list of supported encryption mechansims that meet a defined set of Sasl properties.
+ * <tr><td> Provide the best matching supported Sasl mechanism to a preference ordered list of mechanisms and Sasl
+ *          properties.
+ * <tr><td> Perform username and password request call backs. <td> CallBackHandler
+ * </table>
+ */
+public class ClientFactoryImpl implements SaslClientFactory
+{
+    //private static final Logger log = Logger.getLogger(ClientFactoryImpl.class);
+
+    /** Holds the names of the supported encryption mechanisms. */
+    private static final String[] SUPPORTED_MECHANISMS = { "CRAM-MD5", "PLAIN" };
+
+    /** Defines index of the CRAM-MD5 mechanism within the supported mechanisms. */
+    private static final int CRAM_MD5 = 0;
+
+    /** Defines index of the PLAIN mechanism within the supported mechanisms. */
+    private static final int PLAIN = 1;
+
+    /** Bit mapping of the no plain text policy. */
+    private static final int NOPLAINTEXT = 0x0001;
+
+    /** Bit mapping of the no susceptible active attacks policy. */
+    private static final int NOACTIVE = 0x0002;
+
+    /** Bit mapping of the no susceptible to dictionary attacks policy. */
+    private static final int NODICTIONARY = 0x0004;
+
+    /** Bit mapping of the must use forward secrecy between sessions policy. */
+    private static final int FORWARD_SECRECY = 0x0008;
+
+    /** Bit mapping of the no anonymous logins policy. */
+    private static final int NOANONYMOUS = 0x0010;
+
+    /** Bit mapping of the must pass credentials policy. */
+    private static final int PASS_CREDENTIALS = 0x0020;
+
+    /** Defines a mapping from supported mechanisms to supported policy flags. */
+    private static final int[] SUPPPORTED_MECHANISMS_POLICIES =
+        {
+            NOPLAINTEXT | NOANONYMOUS, // CRAM-MD5
+            NOANONYMOUS // PLAIN
+        };
+
+    /**
+     * Creates a SaslClient using the parameters supplied.
+     *
+     * @param mechanisms      The non-null list of mechanism names to try. Each is the IANA-registered name of a SASL
+     *                        mechanism. (e.g. "GSSAPI", "CRAM-MD5").
+     * @param authorizationId The possibly null protocol-dependent identification to be used for authorization.
+     *                        If null or empty, the server derives an authorization ID from the client's authentication
+     *                        credentials. When the SASL authentication completes successfully, the specified entity is
+     *                        granted access.
+     * @param protocol        The non-null string name of the protocol for which the authentication is being performed
+     *                        (e.g., "ldap").
+     * @param serverName      The non-null fully qualified host name of the server to authenticate to.
+     * @param props           The possibly null set of properties used to select the SASL mechanism and to configure the
+     *                        authentication exchange of the selected mechanism. See the <tt>Sasl</tt> class for a list
+     *                        of standard properties. Other, possibly mechanism-specific, properties can be included.
+     *                        Properties not relevant to the selected mechanism are ignored.
+     * @param cbh             The possibly null callback handler to used by the SASL mechanisms to get further
+     *                        information from the application/library to complete the authentication. For example, a
+     *                        SASL mechanism might require the authentication ID, password and realm from the caller.
+     *                        The authentication ID is requested by using a <tt>NameCallback</tt>.
+     *                        The password is requested by using a <tt>PasswordCallback</tt>.
+     *                        The realm is requested by using a <tt>RealmChoiceCallback</tt> if there is a list
+     *                        of realms to choose from, and by using a <tt>RealmCallback</tt> if
+     *                        the realm must be entered.
+     *
+     * @return A possibly null <tt>SaslClient</tt> created using the parameters supplied. If null, this factory cannot
+     *         produce a <tt>SaslClient</tt> using the parameters supplied.
+     *
+     * @throws javax.security.sasl.SaslException If cannot create a <tt>SaslClient</tt> because of an error.
+     */
+    public SaslClient createSaslClient(String[] mechanisms, String authorizationId, String protocol, String serverName,
+                                       Map props, CallbackHandler cbh) throws SaslException
+    {
+        /*log.debug("public SaslClient createSaslClient(String[] mechanisms = " + PrettyPrintingUtils.printArray(mechanisms)
+                  + ", String authorizationId = " + authorizationId + ", String protocol = " + protocol
+                  + ", String serverName = " + serverName + ", Map props = " + props + ", CallbackHandler cbh): called");*/
+
+        // Get a list of all supported mechanisms that matched the required properties.
+        String[] matchingMechanisms = getMechanismNames(props);
+        //log.debug("matchingMechanisms = " + PrettyPrintingUtils.printArray(matchingMechanisms));
+
+        // Scan down the list of mechanisms until the first one that matches one of the matching supported mechanisms
+        // is found.
+        String chosenMechanism = null;
+
+        for (int i = 0; i < mechanisms.length; i++)
+        {
+            String mechanism = mechanisms[i];
+
+            for (int j = 0; j < matchingMechanisms.length; j++)
+            {
+                String matchingMechanism = matchingMechanisms[j];
+
+                if (mechanism.equals(matchingMechanism))
+                {
+                    chosenMechanism = mechanism;
+
+                    break;
+                }
+            }
+
+            // Stop scanning if a match has been found.
+            if (chosenMechanism != null)
+            {
+                break;
+            }
+        }
+
+        // Check that a matching mechanism was found or return null otherwise.
+        if (chosenMechanism == null)
+        {
+            //log.debug("No matching mechanism could be found.");
+
+            return null;
+        }
+
+        // Instantiate an appropriate client type for the chosen mechanism.
+        if (chosenMechanism.equals(SUPPORTED_MECHANISMS[CRAM_MD5]))
+        {
+            Object[] uinfo = getUserInfo("CRAM-MD5", authorizationId, cbh);
+
+            //log.debug("Using CRAM-MD5 mechanism.");
+
+            return new CramMD5Client((String) uinfo[0], (byte[]) uinfo[1]);
+        }
+        else
+        {
+            Object[] uinfo = getUserInfo("PLAIN", authorizationId, cbh);
+
+            //log.debug("Using PLAIN mechanism.");
+
+            return new PlainClient(authorizationId, (String) uinfo[0], (byte[]) uinfo[1]);
+        }
+    }
+
+    /**
+     * Returns an array of names of mechanisms that match the specified
+     * mechanism selection policies.
+     *
+     * @param props The possibly null set of properties used to specify the
+     *              security policy of the SASL mechanisms. For example, if <tt>props</tt>
+     *              contains the <tt>Sasl.POLICY_NOPLAINTEXT</tt> property with the value
+     *              <tt>"true"</tt>, then the factory must not return any SASL mechanisms
+     *              that are susceptible to simple plain passive attacks.
+     *              See the <tt>Sasl</tt> class for a complete list of policy properties.
+     *              Non-policy related properties, if present in <tt>props</tt>, are ignored.
+     *
+     * @return A non-null array containing a IANA-registered SASL mechanism names.
+     */
+    public String[] getMechanismNames(Map props)
+    {
+        //log.debug("public String[] getMechanismNames(Map props = " + props + "): called");
+
+        // Used to build up the valid mechanisms in.
+        List validMechanisms = new ArrayList();
+
+        // Transform the Sasl properties into a set of bit mapped flags indicating the required properties of the
+        // encryption mechanism employed.
+        int requiredFlags = bitMapSaslProperties(props);
+        //log.debug("requiredFlags = " + requiredFlags);
+
+        // Scan down the list of supported mechanisms filtering in only those that satisfy all of the desired
+        // encryption properties.
+        for (int i = 0; i < SUPPORTED_MECHANISMS.length; i++)
+        {
+            int mechanismFlags = SUPPPORTED_MECHANISMS_POLICIES[i];
+            //log.debug("mechanismFlags = " + mechanismFlags);
+
+            // Check if the current mechanism contains all of the required flags.
+            if ((requiredFlags & ~mechanismFlags) == 0)
+            {
+                //log.debug("Mechanism " + SUPPORTED_MECHANISMS[i] + " meets the required properties.");
+                validMechanisms.add(SUPPORTED_MECHANISMS[i]);
+            }
+        }
+
+        String[] result = (String[]) validMechanisms.toArray(new String[validMechanisms.size()]);
+
+        //log.debug("result = " + PrettyPrintingUtils.printArray(result));
+
+        return result;
+    }
+
+    /**
+     * Transforms a set of Sasl properties, defined using the property names in javax.security.sasl.Sasl, into
+     * a bit mapped set of property flags encoded using the bit mapping constants defined in this class.
+     *
+     * @param properties The Sasl properties to bit map.
+     *
+     * @return A set of bit mapped properties encoded in an integer.
+     */
+    private int bitMapSaslProperties(Map properties)
+    {
+        //log.debug("private int bitMapSaslProperties(Map properties = " + properties + "): called");
+
+        int result = 0;
+
+        // No flags set if no properties are set.
+        if (properties == null)
+        {
+            return result;
+        }
+
+        if ("true".equalsIgnoreCase((String) properties.get(Sasl.POLICY_NOPLAINTEXT)))
+        {
+            result |= NOPLAINTEXT;
+        }
+
+        if ("true".equalsIgnoreCase((String) properties.get(Sasl.POLICY_NOACTIVE)))
+        {
+            result |= NOACTIVE;
+        }
+
+        if ("true".equalsIgnoreCase((String) properties.get(Sasl.POLICY_NODICTIONARY)))
+        {
+            result |= NODICTIONARY;
+        }
+
+        if ("true".equalsIgnoreCase((String) properties.get(Sasl.POLICY_NOANONYMOUS)))
+        {
+            result |= NOANONYMOUS;
+        }
+
+        if ("true".equalsIgnoreCase((String) properties.get(Sasl.POLICY_FORWARD_SECRECY)))
+        {
+            result |= FORWARD_SECRECY;
+        }
+
+        if ("true".equalsIgnoreCase((String) properties.get(Sasl.POLICY_PASS_CREDENTIALS)))
+        {
+            result |= PASS_CREDENTIALS;
+        }
+
+        return result;
+    }
+
+    /**
+     * Uses the specified call back handler to query for the users log in name and password.
+     *
+     * @param prefix          A prefix to prepend onto the username and password queries.
+     * @param authorizationId The default autorhization name.
+     * @param cbh             The call back handler.
+     *
+     * @return The username and password from the callback.
+     *
+     * @throws SaslException If the callback fails for any reason.
+     */
+    private Object[] getUserInfo(String prefix, String authorizationId, CallbackHandler cbh) throws SaslException
+    {
+        // Check that the callback handler is defined.
+        if (cbh == null)
+        {
+            throw new SaslException("Callback handler to get username/password required.");
+        }
+
+        try
+        {
+            String userPrompt = prefix + " authentication id: ";
+            String passwdPrompt = prefix + " password: ";
+
+            NameCallback ncb =
+                (authorizationId == null) ? new NameCallback(userPrompt) : new NameCallback(userPrompt, authorizationId);
+            PasswordCallback pcb = new PasswordCallback(passwdPrompt, false);
+
+            // Ask the call back handler to get the users name and password.
+            cbh.handle(new Callback[] { ncb, pcb });
+
+            char[] pw = pcb.getPassword();
+
+            byte[] bytepw;
+            String authId;
+
+            if (pw != null)
+            {
+                bytepw = new String(pw).getBytes("UTF8");
+                pcb.clearPassword();
+            }
+            else
+            {
+                bytepw = null;
+            }
+
+            authId = ncb.getName();
+
+            return new Object[] { authId, bytepw };
+        }
+        catch (IOException e)
+        {
+            throw new SaslException("Cannot get password.", e);
+        }
+        catch (UnsupportedCallbackException e)
+        {
+            throw new SaslException("Cannot get userid/password.", e);
+        }
+    }
+}

Added: incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/CramMD5Client.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/CramMD5Client.java?view=auto&rev=509642
==============================================================================
--- incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/CramMD5Client.java (added)
+++ incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/CramMD5Client.java Tue Feb 20 08:51:32 2007
@@ -0,0 +1,349 @@
+/*
+ *
+ * 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.apache.qpid.sasl;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+
+/**
+ * Implements the CRAM-MD5 SASL mechanism.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Concatenate the user id and password hashed by a challenge string as the challenge response.
+ * <tr><td> Ensure password is wiped once a challenge has been processed.
+ * </table>
+ *
+ * @author Rupert Smith
+ */
+public class CramMD5Client implements SaslClient
+{
+    /** Defines the HMAC block size. */
+    private static final int MD5_BLOCKSIZE = 64;
+
+    /** Flag used to indicate that the authentication has completed. */
+    private boolean completed = false;
+
+    private String authenticationId;
+    private byte[] password;
+
+    /**
+     * Creates a PLAIN SASL client for an authorization id, authentication id and password.
+     *
+     * @param authenticationId The authentication id.
+     * @param password         The password.
+     *
+     * @throws SaslException If the authentication id or password is null.
+     */
+    CramMD5Client(String authenticationId, byte[] password) throws SaslException
+    {
+        // Check that a username and password are specified.
+        if ((authenticationId == null) || (password == null))
+        {
+            throw new SaslException("CRAM: authentication id and password must be specified");
+        }
+
+        // Keep the log in credentials.
+        this.authenticationId = authenticationId;
+        this.password = password;
+    }
+
+    /**
+     * Returns the IANA-registered mechanism name of this SASL client. (e.g. "CRAM-MD5", "GSSAPI").
+     *
+     * @return A non-null string representing the IANA-registered mechanism name.
+     */
+    public String getMechanismName()
+    {
+        return "CRAM-MD5";
+    }
+
+    /**
+     * Determines whether this mechanism has an optional initial response. If true, caller should call
+     * <tt>evaluateChallenge()</tt> with an empty array to get the initial response.
+     *
+     * <p/>CRAM-MD5 has no intial response.
+     *
+     * @return true if this mechanism has an initial response.
+     */
+    public boolean hasInitialResponse()
+    {
+        return false;
+    }
+
+    /**
+     * Evaluates the challenge data and generates a response. If a challenge is received from the server during the
+     * authentication process, this method is called to prepare an appropriate next response to submit to the server.
+     *
+     * <p/>The initial response for the SASL command, for the CRAM-MD5 mechanism is the concatenation of authentication
+     * ID and password HMAC-MD5 hashed by the server challenge.
+     *
+     * @param challenge The non-null challenge sent from the server. The challenge array may have zero length.
+     *
+     * @return The possibly null reponse to send to the server. It is null if the challenge accompanied a "SUCCESS"
+     *         status and the challenge only contains data for the client to update its state and no response
+     *         needs to be sent to the server. The response is a zero-length byte array if the client is to send a
+     *         response with no data.
+     *
+     * @throws javax.security.sasl.SaslException If an error occurred while processing the challenge or generating a
+     *                                           response.
+     */
+    public byte[] evaluateChallenge(byte[] challenge) throws SaslException
+    {
+        // Check that the authentication has not already been performed.
+        if (completed)
+        {
+            throw new IllegalStateException("CRAM-MD5 authentication already completed.");
+        }
+
+        // Check if the password is null, this will be the case if a previous attempt to authenticated failed.
+        if (password == null)
+        {
+            throw new IllegalStateException("CRAM-MD5 authentication previously aborted due to error.");
+        }
+
+        // Generate a keyed-MD5 digest from the user's password keyed by the challenge bytes.
+        try
+        {
+            String digest = hmac_md5(password, challenge);
+            String result = authenticationId + " " + digest;
+
+            completed = true;
+
+            return result.getBytes("UTF8");
+        }
+        catch (java.security.NoSuchAlgorithmException e)
+        {
+            throw new SaslException("MD5 algorithm not available on platform", e);
+        }
+        catch (java.io.UnsupportedEncodingException e)
+        {
+            throw new SaslException("UTF8 not available on platform", e);
+        }
+        finally
+        {
+            clearPassword();
+        }
+    }
+
+    /**
+     * Determines whether the authentication exchange has completed. This method may be called at any time, but
+     * typically, it will not be called until the caller has received indication from the server (in a protocol-specific
+     * manner) that the exchange has completed.
+     *
+     * @return true if the authentication exchange has completed; false otherwise.
+     */
+    public boolean isComplete()
+    {
+        return completed;
+    }
+
+    /**
+     * Unwraps a byte array received from the server. This method can be called only after the authentication exchange
+     * has completed (i.e., when <tt>isComplete()</tt> returns true) and only if the authentication exchange has
+     * negotiated integrity and/or privacy as the quality of protection; otherwise, an <tt>IllegalStateException</tt> is
+     * thrown.
+     *
+     * <p/><tt>incoming</tt> is the contents of the SASL buffer as defined in RFC 2222 without the leading four octet
+     * field that represents the length. <tt>offset</tt> and <tt>len</tt> specify the portion of <tt>incoming</tt>
+     * to use.
+     *
+     * @param incoming A non-null byte array containing the encoded bytes from the server.
+     * @param offset   The starting position at <tt>incoming</tt> of the bytes to use.
+     * @param len      The number of bytes from <tt>incoming</tt> to use.
+     *
+     * @return A non-null byte array containing the decoded bytes.
+     *
+     * @throws javax.security.sasl.SaslException If <tt>incoming</tt> cannot be successfully unwrapped.
+     * @throws IllegalStateException If the authentication exchange has not completed, or if the negotiated quality of
+     *                               protection has neither integrity nor privacy.
+     */
+    public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
+    {
+        throw new SaslException("CRAM-MD5 does not support quality of protection.");
+    }
+
+    /**
+     * Wraps a byte array to be sent to the server. This method can be called only after the authentication exchange has
+     * completed (i.e., when <tt>isComplete()</tt> returns true) and only if the authentication exchange has negotiated
+     * integrity and/or privacy as the quality of protection; otherwise, an <tt>IllegalStateException</tt> is thrown.
+     *
+     * <p/>The result of this method will make up the contents of the SASL buffer as defined in RFC 2222 without the
+     * leading four octet field that represents the length. <tt>offset</tt> and <tt>len</tt> specify the portion of
+     * <tt>outgoing</tt> to use.
+     *
+     * @param outgoing A non-null byte array containing the bytes to encode.
+     * @param offset   The starting position at <tt>outgoing</tt> of the bytes to use.
+     * @param len      The number of bytes from <tt>outgoing</tt> to use.
+     *
+     * @return A non-null byte array containing the encoded bytes.
+     *
+     * @throws javax.security.sasl.SaslException If <tt>outgoing</tt> cannot be successfully wrapped.
+     * @throws IllegalStateException If the authentication exchange has not completed, or if the negotiated quality of
+     *                               protection has neither integrity nor privacy.
+     */
+    public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
+    {
+        throw new SaslException("CRAM-MD5 does not support quality of protection.");
+    }
+
+    /**
+     * Retrieves the negotiated property. This method can be called only after the authentication exchange has
+     * completed (i.e., when <tt>isComplete()</tt> returns true); otherwise, an <tt>IllegalStateException</tt> is thrown.
+     *
+     * @param propName The non-null property name.
+     *
+     * @return The value of the negotiated property. If null, the property was not negotiated or is not applicable to
+     *         this mechanism.
+     *
+     * @throws IllegalStateException If this authentication exchange has not completed.
+     */
+    public Object getNegotiatedProperty(String propName)
+    {
+        if (completed)
+        {
+            if (propName.equals(Sasl.QOP))
+            {
+                return "auth";
+            }
+            else
+            {
+                return null;
+            }
+        }
+        else
+        {
+            throw new IllegalStateException("CRAM-MD5 authentication not completed");
+        }
+    }
+
+    /**
+     * Disposes of any system resources or security-sensitive information the SaslClient might be using. Invoking this
+     * method invalidates the SaslClient instance. This method is idempotent.
+     *
+     * @throws javax.security.sasl.SaslException If a problem was encountered while disposing the resources.
+     */
+    public void dispose() throws SaslException
+    { }
+
+    /*
+     * Hashes its input arguments according to HMAC-MD5 (RFC 2104) and returns the resulting digest in its ASCII
+     * representation.
+     *
+     * <p/> The HMAC-MD5 function is described as follows:
+     * <p/><pre>
+     *     MD5(key XOR opad, MD5(key XOR ipad, text))
+     * </pre>
+     *
+     * <p/>Where key is an n byte key, ipad is the byte 0x36 repeated 64 times, opad is the byte 0x5c repeated 64 times
+     * and text is the data to be protected.
+     *
+     * @param key  The key to hash by.
+     * @param text The plain text to hash.
+     *
+     * @return The hashed text.
+     *
+     * @throws NoSuchAlgorithmException If the Java platform does not supply an MD5 implementation.
+     */
+    private static final String hmac_md5(byte[] key, byte[] text) throws NoSuchAlgorithmException
+    {
+        MessageDigest md5 = MessageDigest.getInstance("MD5");
+
+        /* digest the key if longer than 64 bytes */
+        if (key.length > 64)
+        {
+            key = md5.digest(key);
+        }
+
+        byte[] ipad = new byte[MD5_BLOCKSIZE]; /* inner padding */
+        byte[] opad = new byte[MD5_BLOCKSIZE]; /* outer padding */
+        byte[] digest;
+        int i;
+
+        /* store key in pads */
+        for (i = 0; i < MD5_BLOCKSIZE; i++)
+        {
+            for (; i < key.length; i++)
+            {
+                ipad[i] = key[i];
+                opad[i] = key[i];
+            }
+
+            ipad[i] = 0x00;
+            opad[i] = 0x00;
+        }
+
+        /* XOR key with pads */
+        for (i = 0; i < MD5_BLOCKSIZE; i++)
+        {
+            ipad[i] ^= 0x36;
+            opad[i] ^= 0x5c;
+        }
+
+        /* inner MD5 */
+        md5.update(ipad);
+        md5.update(text);
+        digest = md5.digest();
+
+        /* outer MD5 */
+        md5.update(opad);
+        md5.update(digest);
+        digest = md5.digest();
+
+        // Get character representation of digest
+        StringBuffer digestString = new StringBuffer();
+
+        for (i = 0; i < digest.length; i++)
+        {
+            if ((digest[i] & 0x000000ff) < 0x10)
+            {
+                digestString.append("0" + Integer.toHexString(digest[i] & 0x000000ff));
+            }
+            else
+            {
+                digestString.append(Integer.toHexString(digest[i] & 0x000000ff));
+            }
+        }
+
+        return (digestString.toString());
+    }
+
+    /**
+     * Overwrites the password with zeros.
+     */
+    private void clearPassword()
+    {
+        if (password != null)
+        {
+            // Zero out password.
+            for (int i = 0; i < password.length; i++)
+            {
+                password[i] = (byte) 0;
+            }
+
+            password = null;
+        }
+    }
+}

Added: incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/PlainClient.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/PlainClient.java?view=auto&rev=509642
==============================================================================
--- incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/PlainClient.java (added)
+++ incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/PlainClient.java Tue Feb 20 08:51:32 2007
@@ -0,0 +1,277 @@
+/*
+ *
+ * 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.apache.qpid.sasl;
+
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+
+/**
+ * Implements the PLAIN SASL mechanism.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Concatenate the user id and password in plain text as the challenge respose.
+ * <tr><td> Ensure password is wiped once a challenge has been processed.
+ * </table>
+ *
+ * @author Rupert Smith
+ */
+public class PlainClient implements SaslClient
+{
+    /** Flag used to indicate that the authentication has completed. */
+    private boolean completed = false;
+
+    private String authorizationId;
+    private String authenticationId;
+    private byte[] password;
+
+    private static byte SEPERATOR = 0; // US-ASCII <NUL>
+
+    /**
+     * Creates a PLAIN SASL client for an authorization id, authentication id and password.
+     *
+     * @param authorizationId  The authorization id. May be null.
+     * @param authenticationId The authentication id.
+     * @param password         The password.
+     *
+     * @throws SaslException If the authentication id or password is null.
+     */
+    PlainClient(String authorizationId, String authenticationId, byte[] password) throws SaslException
+    {
+        // Check that a username and password are specified.
+        if ((authenticationId == null) || (password == null))
+        {
+            throw new SaslException("PLAIN: authentication ID and password must be specified");
+        }
+
+        // Keep the log in credentials.
+        this.authorizationId = authorizationId;
+        this.authenticationId = authenticationId;
+        this.password = password;
+    }
+
+    /**
+     * Returns the IANA-registered mechanism name of this SASL client. (e.g. "CRAM-MD5", "GSSAPI").
+     *
+     * @return A non-null string representing the IANA-registered mechanism name.
+     */
+    public String getMechanismName()
+    {
+        return "PLAIN";
+    }
+
+    /**
+     * Determines whether this mechanism has an optional initial response. If true, caller should call
+     * <tt>evaluateChallenge()</tt> with an empty array to get the initial response.
+     *
+     * @return true if this mechanism has an initial response.
+     */
+    public boolean hasInitialResponse()
+    {
+        return true;
+    }
+
+    /**
+     * Evaluates the challenge data and generates a response. If a challenge is received from the server during the
+     * authentication process, this method is called to prepare an appropriate next response to submit to the server.
+     *
+     * <p/>The initial response for the SASL command, for the PLAIN mechanism is the concatenation of authorization ID,
+     * authentication ID and password, with each component separated by the US-ASCII <NUL> byte.
+     *
+     * @param challenge The non-null challenge sent from the server. The challenge array may have zero length.
+     *
+     * @return The possibly null reponse to send to the server. It is null if the challenge accompanied a "SUCCESS"
+     *         status and the challenge only contains data for the client to update its state and no response
+     *         needs to be sent to the server. The response is a zero-length byte array if the client is to send a
+     *         response with no data.
+     *
+     * @throws javax.security.sasl.SaslException If an error occurred while processing the challenge or generating a
+     *                                           response.
+     */
+    public byte[] evaluateChallenge(byte[] challenge) throws SaslException
+    {
+        // Check that the authentication has not already been performed.
+        if (completed)
+        {
+            throw new IllegalStateException("PLAIN authentication already completed");
+        }
+
+        try
+        {
+            // Get the authorization and authentication ids in bytes.
+            byte[] authorizationBytes = (authorizationId != null) ? authorizationId.getBytes("UTF8") : null;
+            byte[] authenticationBytes = authenticationId.getBytes("UTF8");
+
+            // Create an array big enough to hold the results.
+            byte[] result =
+                new byte[password.length + authenticationBytes.length + 2
+                                    + ((authorizationBytes == null) ? 0 : authorizationBytes.length)];
+
+            // Copy the authorization id, authentication id and password into the results.
+            int pos = 0;
+            if (authorizationBytes != null)
+            {
+                System.arraycopy(authorizationBytes, 0, result, 0, authorizationBytes.length);
+                pos = authorizationBytes.length;
+            }
+
+            result[pos++] = SEPERATOR;
+            System.arraycopy(authenticationBytes, 0, result, pos, authenticationBytes.length);
+
+            pos += authenticationBytes.length;
+            result[pos++] = SEPERATOR;
+
+            System.arraycopy(password, 0, result, pos, password.length);
+
+            completed = true;
+
+            return result;
+        }
+        catch (java.io.UnsupportedEncodingException e)
+        {
+            throw new SaslException("Cannot get UTF-8 encoding of ids", e);
+        }
+        finally
+        {
+            clearPassword();
+        }
+    }
+
+    /**
+     * Determines whether the authentication exchange has completed. This method may be called at any time, but
+     * typically, it will not be called until the caller has received indication from the server (in a protocol-specific
+     * manner) that the exchange has completed.
+     *
+     * @return true if the authentication exchange has completed; false otherwise.
+     */
+    public boolean isComplete()
+    {
+        return completed;
+    }
+
+    /**
+     * Unwraps a byte array received from the server. This method can be called only after the authentication exchange has
+     * completed (i.e., when <tt>isComplete()</tt> returns true) and only if the authentication exchange has negotiated
+     * integrity and/or privacy as the quality of protection; otherwise, an <tt>IllegalStateException</tt> is thrown.
+     *
+     * <p/><tt>incoming</tt> is the contents of the SASL buffer as defined in RFC 2222 without the leading four octet
+     * field that represents the length. <tt>offset</tt> and <tt>len</tt> specify the portion of <tt>incoming</tt>
+     * to use.
+     *
+     * @param incoming A non-null byte array containing the encoded bytes
+     *                 from the server.
+     * @param offset   The starting position at <tt>incoming</tt> of the bytes to use.
+     * @param len      The number of bytes from <tt>incoming</tt> to use.
+     *
+     * @return A non-null byte array containing the decoded bytes.
+     *
+     * @throws javax.security.sasl.SaslException If <tt>incoming</tt> cannot be successfully unwrapped.
+     * @throws IllegalStateException If the authentication exchange has not completed, or if the negotiated quality of
+     *                               protection has neither integrity nor privacy.
+     */
+    public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
+    {
+        throw new SaslException("PLAIN does not support quality of protection.");
+    }
+
+    /**
+     * Wraps a byte array to be sent to the server. This method can be called only after the authentication exchange has
+     * completed (i.e., when <tt>isComplete()</tt> returns true) and only if the authentication exchange has negotiated
+     * integrity and/or privacy as the quality of protection; otherwise, an <tt>IllegalStateException</tt> is thrown.
+     *
+     * <p/>The result of this method will make up the contents of the SASL buffer as defined in RFC 2222 without the
+     * leading four octet field that represents the length. <tt>offset</tt> and <tt>len</tt> specify the portion of
+     * <tt>outgoing</tt> to use.
+     *
+     * @param outgoing A non-null byte array containing the bytes to encode.
+     * @param offset   The starting position at <tt>outgoing</tt> of the bytes to use.
+     * @param len      The number of bytes from <tt>outgoing</tt> to use.
+     *
+     * @return A non-null byte array containing the encoded bytes.
+     *
+     * @throws javax.security.sasl.SaslException If <tt>outgoing</tt> cannot be successfully wrapped.
+     * @throws IllegalStateException If the authentication exchange has not completed, or if the negotiated quality of
+     *                               protection has neither integrity nor privacy.
+     */
+    public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
+    {
+        throw new SaslException("PLAIN does not support quality of protection.");
+    }
+
+    /**
+     * Retrieves the negotiated property. This method can be called only after the authentication exchange has
+     * completed (i.e., when <tt>isComplete()</tt> returns true); otherwise, an <tt>IllegalStateException</tt> is thrown.
+     *
+     * @param propName The non-null property name.
+     *
+     * @return The value of the negotiated property. If null, the property was not negotiated or is not applicable to
+     *         this mechanism.
+     *
+     * @throws IllegalStateException If this authentication exchange has not completed.
+     */
+    public Object getNegotiatedProperty(String propName)
+    {
+        if (completed)
+        {
+            if (propName.equals(Sasl.QOP))
+            {
+                return "auth";
+            }
+            else
+            {
+                return null;
+            }
+        }
+        else
+        {
+            throw new IllegalStateException("PLAIN authentication not completed");
+        }
+    }
+
+    /**
+     * Disposes of any system resources or security-sensitive information the SaslClient might be using. Invoking this
+     * method invalidates the SaslClient instance. This method is idempotent.
+     *
+     * @throws javax.security.sasl.SaslException If a problem was encountered while disposing the resources.
+     */
+    public void dispose() throws SaslException
+    {
+        clearPassword();
+    }
+
+    /**
+     * Overwrites the password with zeros.
+     */
+    private void clearPassword()
+    {
+        if (password != null)
+        {
+            // Zero out password.
+            for (int i = 0; i < password.length; i++)
+            {
+                password[i] = (byte) 0;
+            }
+
+            password = null;
+        }
+    }
+}

Added: incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/Provider.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/Provider.java?view=auto&rev=509642
==============================================================================
--- incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/Provider.java (added)
+++ incubator/qpid/trunk/qpid/java/client-java14/src/main/java/org/apache/qpid/sasl/Provider.java Tue Feb 20 08:51:32 2007
@@ -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.apache.qpid.sasl;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.apache.log4j.Logger;
+
+/**
+ * A SASL provider for Java 1.4. Declares the capabilities of this implementation, which supports PLAIN and CRAM-MD5
+ * client implementations only.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Declare PLAIN SASL support.
+ * <tr><td> Declare CRAM-MD5 SASL support.
+ * </table>
+ */
+public class Provider extends java.security.Provider
+{
+    //Logger log = Logger.getLogger(Provider.class);
+
+    private static final String info = "Qpid SASL provider" + "(implements client mechanisms for: PLAIN, CRAM-MD5)";
+
+    public Provider()
+    {
+        super("QpidSASL", 1.4, info);
+
+        //log.debug("public Provider(): called");
+
+        AccessController.doPrivileged(new PrivilegedAction()
+            {
+                public Object run()
+                {
+                    put("SaslClientFactory.PLAIN", "org.apache.qpid.sasl.ClientFactoryImpl");
+                    put("SaslClientFactory.CRAM-MD5", "org.apache.qpid.sasl.ClientFactoryImpl");
+
+                    return null;
+                }
+            });
+    }
+}

Added: incubator/qpid/trunk/qpid/java/client-java14/src/test/java/org/apache/qpid/test/integration/client/ConnectionTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client-java14/src/test/java/org/apache/qpid/test/integration/client/ConnectionTest.java?view=auto&rev=509642
==============================================================================
--- incubator/qpid/trunk/qpid/java/client-java14/src/test/java/org/apache/qpid/test/integration/client/ConnectionTest.java (added)
+++ incubator/qpid/trunk/qpid/java/client-java14/src/test/java/org/apache/qpid/test/integration/client/ConnectionTest.java Tue Feb 20 08:51:32 2007
@@ -0,0 +1,66 @@
+/*
+ *
+ * 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.apache.qpid.test.integration.client;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.NDC;
+
+import org.apache.qpid.client.AMQConnection;
+
+/**
+ * Implements a trivial broker connection test, to a broker on the default port on localhost, to check that SASL
+ * authentication works.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Check that a connection to a broker can be established.
+ * </table>
+ */
+public class ConnectionTest extends TestCase
+{
+    private String BROKER_URL = "tcp://localhost:5672";
+
+    public ConnectionTest(String name)
+    {
+        super(name);
+    }
+
+    /** Check that a connection to a broker can be established. */
+    public void testConnection() throws Exception
+    {
+        // Open a connection to the broker and close it again.
+        AMQConnection conn = new AMQConnection(BROKER_URL, "guest", "guest", "clientid", "test");
+        conn.close();
+    }
+
+    protected void setUp()
+    {
+        NDC.push(getName());
+    }
+
+    protected void tearDown()
+    {
+        NDC.pop();
+    }
+}

Modified: incubator/qpid/trunk/qpid/java/client/distribution/pom.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/distribution/pom.xml?view=diff&rev=509642&r1=509641&r2=509642
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/distribution/pom.xml (original)
+++ incubator/qpid/trunk/qpid/java/client/distribution/pom.xml Tue Feb 20 08:51:32 2007
@@ -48,20 +48,6 @@
             <type>jar</type>
             <version>${pom.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.qpid</groupId>
-            <artifactId>qpid-client</artifactId>
-            <type>jar</type>
-            <version>${pom.version}</version>
-	    <classifier>java1.4</classifier>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.qpid</groupId>
-            <artifactId>qpid-common</artifactId>
-            <type>jar</type>
-            <version>${pom.version}</version>
-	    <classifier>java1.4</classifier>
-        </dependency>
     </dependencies>
 
     <build>
@@ -119,7 +105,6 @@
                         <configuration>
                             <descriptors>
                                 <descriptor>src/main/assembly/client-bin.xml</descriptor>
-                                <descriptor>src/main/assembly/client-java1.4-bin.xml</descriptor>
                                 <descriptor>src/main/assembly/client-src.xml</descriptor>
                             </descriptors>
                             <finalName>qpid-${pom.version}</finalName>