Index: testsuite/imports/server-config.xml
===================================================================
--- testsuite/imports/server-config.xml	(revision 113475)
+++ testsuite/imports/server-config.xml	(working copy)
@@ -1531,6 +1531,15 @@
        <jvmarg value="-XX:-UseGCOverheadLimit" />
        <sysproperty key="org.apache.commons.logging.use_tccl" value="true"/>
     </server>
+    <server name="negotiation" host="${node0}">
+       <jvmarg value="-Xms128m" />
+       <jvmarg value="-Xmx512m" />
+       <jvmarg value="-XX:MaxPermSize=512m" />
+       <jvmarg value="-XX:-UseGCOverheadLimit" />
+       <sysproperty key="sun.security.krb5.debug" value="true"/>
+       <sysproperty key="gsstestserver.port" value="${gsstestserver.port}"/>
+       <sysproperty key="java.security.krb5.conf" value="${jboss.dist}${/}server${/}negotiation${/}krb5.conf"/>
+    </server>
    </server:config>
 
     <!-- A macro for printing sleep before going into sleep
Index: testsuite/imports/test-jars.xml
===================================================================
--- testsuite/imports/test-jars.xml	(revision 113475)
+++ testsuite/imports/test-jars.xml	(working copy)
@@ -58,6 +58,7 @@
    <import file="sections/mdb.xml"/>
    <import file="sections/mdbsessionpoolclear.xml"/>
    <import file="sections/naming.xml"/>
+   <import file="sections/negotiation.xml"/>
    <import file="sections/perf.xml"/>
    <import file="sections/pooled.xml"/>
    <import file="sections/profileservice.xml"/>
@@ -158,6 +159,7 @@
         _jars-mdbsessionpoolclear,
         _jars-messagedriven,
         _jars-naming,
+        _jars-negotiation,
         _jars-perf,
         _jars-pooled,
    	  _jars-profileservice,
Index: testsuite/imports/sections/negotiation.xml
===================================================================
--- testsuite/imports/sections/negotiation.xml	(revision 0)
+++ testsuite/imports/sections/negotiation.xml	(revision 0)
@@ -0,0 +1,56 @@
+<project name="tests-jboss-negotiation-jars">
+	<target name="_jars-negotiation">
+		<!-- prepare application archives for the JBoss Negotiation tests -->
+		
+		<mkdir dir="${build.lib}" />
+
+		<war destfile="${build.lib}/spnego-web-test.war" webxml="${build.resources}/org/jboss/test/security/negotiation/spnego-web.xml">
+			<webinf dir="${build.resources}/org/jboss/test/security/negotiation">
+				<include name="jboss-web.xml" />
+			</webinf>
+			<fileset dir="${build.resources}/org/jboss/test/security/negotiation">
+				<include name="index.txt" />
+			</fileset>
+			<classes dir="${build.resources}/org/jboss/test/security/negotiation">
+				<include name="*.properties" />
+			</classes>
+			<classes dir="${build.classes}">
+				<include name="org/jboss/test/security/negotiation/PropagateIdentityServlet*"/>
+				<include name="org/jboss/test/security/negotiation/GSSTestServer*"/>
+				<include name="org/jboss/test/security/negotiation/GSSTestClient*"/>
+			</classes>
+		</war>
+
+		<war destfile="${build.lib}/spnego-form-web-test.war" webxml="${build.resources}/org/jboss/test/security/negotiation/fallback/spnego-form-web.xml">
+	    	<webinf dir="${build.resources}/org/jboss/test/security/negotiation/fallback">
+	    		<include name="jboss-web.xml" />
+	    	</webinf>
+			
+			<fileset dir="${build.resources}/org/jboss/test/security/negotiation">
+				<include name="index.txt" />
+			</fileset>
+			<classes dir="${build.resources}/org/jboss/test/security/negotiation/fallback">
+				<include name="*.properties" />
+			</classes>
+			<classes dir="${build.resources}/org/jboss/test/security/negotiation">
+				<include name="*.properties" />
+			</classes>
+			<fileset dir="${build.resources}/web/programmatic">
+				<include name="*.html" />
+			</fileset>
+		</war>
+
+		<jar destfile="${build.lib}/spnego-ejb3-test.jar">
+			<metainf dir="${build.resources}/org/jboss/test/security/negotiation">
+				<include name="jboss.xml" />
+			</metainf>
+			<fileset dir="${build.resources}/org/jboss/test/security/negotiation">
+				<include name="*.properties" />
+			</fileset>
+			<fileset dir="${build.classes}">
+				<include name="org/jboss/test/security/ejb3/SimpleStatelessSessionBean.*" />
+				<include name="org/jboss/test/security/ejb3/SimpleSession.*" />
+			</fileset>
+		</jar>
+	</target>
+</project>
\ No newline at end of file
Index: testsuite/build.xml
===================================================================
--- testsuite/build.xml	(revision 113475)
+++ testsuite/build.xml	(working copy)
@@ -142,6 +142,7 @@
       <path refid="apache.xerces.classpath"/>
       <path refid="org.apache.santuario.classpath"/>
       <path refid="dom4j.dom4j.classpath"/>
+      <path refid="jaxen.jaxen.classpath"/>
       <path refid="httpunit.httpunit.classpath"/>
       <path refid="ibm.wsdl4j.classpath"/>
       <path refid="jacorb.jacorb.classpath"/>
@@ -220,7 +221,10 @@
       <!-- jbossts crash recovery tests need server manager -->
       <path refid="jboss.server.manager.classpath"/>
       <path refid="jboss.jbossts.classpath"/>
-
+   	  <!-- JBoss Negotiation -->
+   	  <path refid="jboss.jboss.negotiation.classpath"/>
+   	  <path refid="apacheds.apacheds.classpath"/>
+   	  <path refid="apache.httpcomponents.classpath"/>
    </path>
 
    <property name="jboss.dist.client" value="${jboss.dist}/client" />
@@ -707,6 +711,12 @@
       <path refid="thirdparty.classpath"/>
    </path>
 
+   <!-- Configure ports, which should be used by JBoss Negotiation (Kerberos) test applications.
+        They have to be set before importing server-config.xml because of their usage in "negotiation" server config.
+   -->
+   <property name="kerberosControl.port" value="10951" />
+   <property name="gsstestserver.port" value="10952" />
+	
    <!-- Import the jboss server run targets -->
    <import file="imports/server-config.xml"/>
 
@@ -1724,6 +1734,7 @@
       <antcall target="tests-jacc-security"/>
       <antcall target="tests-jacc-securitymgr"/>
       <antcall target="tests-jacc-security-allstarrole"/>
+      <antcall target="tests-jboss-negotiation"/>
 <!--
       <antcall target="tests-security-jaspi-unit"/>
 -->
@@ -5309,5 +5320,205 @@
    </target>
    
    <target name="check-build-type"><echo message="build.ewp is ${build.ewp} and version is ${version} and version.name is ${version.name}"/></target>
+
+	
+	<target name="tests-jboss-negotiation" description="Tests JBoss Negotiation" depends="init">
+	
+		<delete dir="${jboss.dist}${/}server${/}negotiation" quiet="true" />
+
+		<create-config baseconf="default" newconf="negotiation">
+			<patternset>
+				<include name="conf/**" />
+				<include name="deployers/**" />
+				<include name="deploy/**" />
+				<include name="lib/**" />
+			</patternset>
+		</create-config>
+	
+		<!-- Setup Negotiation configuration. We need to retrieve cannonical host 
+			name, therefor the Java is used for the configuration. -->
+		<java classname="org.jboss.test.security.negotiation.NegotiationSetup" fork="true">
+			<sysproperty key="build.testlog" value="${build.testlog}" />
+			<sysproperty key="jboss.bind.address" value="${node0}" />
+			<sysproperty key="jboss.server.home.dir" value="${jboss.dist}/server/negotiation" />
+			<classpath>
+				<pathelement location="${build.resources}" />
+				<pathelement location="${build.classes}" />
+				<path refid="thirdparty.classpath" />
+			</classpath>
+		</java>
 		
+		<parallel>
+			<!-- Start KDC Server -->
+			<java classname="org.jboss.test.security.negotiation.KerberosServerControl" fork="true">
+				<sysproperty key="build.testlog" value="${build.testlog}" />
+				<sysproperty key="kerberos.bind.address" value="${node0}" />
+				<sysproperty key="kerberosControl.port" value="${kerberosControl.port}" />
+				<classpath>
+					<pathelement location="${build.resources}" />
+					<pathelement location="${build.classes}" />
+					<path refid="thirdparty.classpath" />
+				</classpath>
+				<!-- LDIF file to import -->
+				<arg value="${build.resources}/org/jboss/test/security/negotiation/KerberosTest.ldif" />
+			</java>
+	
+			<sequential>
+				<!-- wait for KDC control task -->
+				<waitfor maxwait="10" maxwaitunit="second">
+		            <socket server="${node0}" port="${kerberosControl.port}"/>
+				</waitfor>
+				<!-- start GSSTestServer for testing identity propagation -->
+				<java classname="org.jboss.test.security.negotiation.GSSTestServer" fork="true">
+					<sysproperty key="gsstestserver.port" value="${gsstestserver.port}" />
+					<sysproperty key="java.security.krb5.conf"
+						value="${jboss.dist}${/}server${/}negotiation${/}krb5.conf" />
+	
+					<classpath>
+						<pathelement location="${build.resources}" />
+						<pathelement location="${build.classes}" />
+						<path refid="thirdparty.classpath" />
+					</classpath>
+				</java>
+			</sequential>
+	
+			<sequential>
+				<!-- wait for KDC control task and GSSTestServer  -->
+				<waitfor maxwait="10" maxwaitunit="second">
+					<and>
+			            <socket server="${node0}" port="${kerberosControl.port}"/>
+			            <socket server="${node0}" port="${gsstestserver.port}"/>
+					</and>
+				</waitfor>
+
+				<server:start name="negotiation" />
+	
+				<junit dir="${module.output}" printsummary="true" haltonerror="false"
+					haltonfailure="false" fork="true" timeout="200000" jvm="${junit.jvm}">
+					<!--
+					<jvmarg value="-Xdebug" />
+					<jvmarg value="-Xnoagent" />
+					<jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8686" />
+					 -->
+					
+					<jvmarg line="${junit.jvm.options}" />
+	
+					<sysproperty key="jboss.server.home.dir"
+						value="${jboss.dist}${/}server${/}negotiation" />
+					<sysproperty key="java.naming.provider.url" value="${node0.jndi.url}" />
+					<sysproperty key="jbosstest.server.host" value="${node0}" />
+					<sysproperty key="jboss.home" file="${project.root}" />
+					<sysproperty key="jboss.thirdparty.dir" file="${project.root}/thirdparty" />
+					<sysproperty key="jboss.tools.dir" file="${project.root}/tools" />
+					<sysproperty key="jbosstest.deploy.dir" file="${build.lib}" />
+					<sysproperty key="build.testlog" value="${build.testlog}" />
+					<sysproperty key="log4j.configuration" value="file:${build.resources}/log4j.xml" />
+					<sysproperty key="org.jboss.security.negotiation.server.principal"
+						value="HTTP/localhost" />
+	
+					<sysproperty key="org.jboss.security.negotiation.server.principal" value="HTTP/localhost" />
+					<sysproperty key="sun.security.krb5.debug" value="true" />
+					<sysproperty key="java.security.krb5.conf" value="${jboss.dist}${/}server${/}negotiation${/}krb5.conf" />
+	
+					<classpath>
+						<pathelement location="${build.resources}" />
+						<pathelement location="${build.classes}" />
+						<path refid="apache.httpcomponents.classpath" />
+						<fileset dir="${jboss.dist.client}">
+							<include name="**/*.jar" />
+						</fileset>
+						<fileset dir="${jboss.dist.common.lib}">
+							<include name="**/*.jar" />
+						</fileset>
+						<pathelement path="${jboss.test.lib}/jboss-test.jar" />
+						<path refid="apache.codec.classpath" />
+						<path refid="apache.lang.classpath" />
+						<path refid="junit.junit.classpath" />
+					</classpath>
+	
+					<formatter classname="org.jboss.ant.taskdefs.XMLJUnitMultipleResultFormatter"
+						usefile="${junit.formatter.usefile}" extension="-tests-security-manager.xml" />
+	
+					<batchtest todir="${build.reports}" haltonerror="false" haltonfailure="false" fork="true">
+						<fileset dir="${build.classes}">
+							<include name="**/NegotiationTestCase.class" />
+						</fileset>
+					</batchtest>
+				</junit>
+				<junit dir="${module.output}" printsummary="true" haltonerror="false"
+					haltonfailure="false" fork="true" timeout="200000" jvm="${junit.jvm}">
+					<jvmarg line="${junit.jvm.options}" />
+	
+					<sysproperty key="jboss.server.home.dir"
+						value="${jboss.dist}${/}server${/}negotiation" />
+					<sysproperty key="java.naming.provider.url" value="${node0.jndi.url}" />
+					<sysproperty key="jbosstest.server.host" value="${node0}" />
+					<sysproperty key="jboss.home" file="${project.root}" />
+					<sysproperty key="jboss.thirdparty.dir" file="${project.root}/thirdparty" />
+					<sysproperty key="jboss.tools.dir" file="${project.root}/tools" />
+					<sysproperty key="jbosstest.deploy.dir" file="${build.lib}" />
+					<sysproperty key="build.testlog" value="${build.testlog}" />
+					<sysproperty key="log4j.configuration" value="file:${build.resources}/log4j.xml" />
+					<sysproperty key="org.jboss.security.negotiation.server.principal"
+						value="HTTP/localhost" />
+	
+					<sysproperty key="org.jboss.security.negotiation.server.principal" value="HTTP/localhost" />
+					<sysproperty key="sun.security.krb5.debug" value="true" />
+					<sysproperty key="java.security.krb5.conf" value="${jboss.dist}${/}server${/}negotiation${/}notforwardable.krb5.conf" />
+	
+					<classpath>
+						<pathelement location="${build.resources}" />
+						<pathelement location="${build.classes}" />
+						<path refid="apache.httpcomponents.classpath" />
+						<fileset dir="${jboss.dist.client}">
+							<include name="**/*.jar" />
+						</fileset>
+						<fileset dir="${jboss.dist.common.lib}">
+							<include name="**/*.jar" />
+						</fileset>
+						<pathelement path="${jboss.test.lib}/jboss-test.jar" />
+						<path refid="apache.codec.classpath" />
+						<path refid="apache.lang.classpath" />
+						<path refid="junit.junit.classpath" />
+					</classpath>
+	
+					<formatter classname="org.jboss.ant.taskdefs.XMLJUnitMultipleResultFormatter"
+						usefile="${junit.formatter.usefile}" extension="-tests-security-manager.xml" />
+	
+					<batchtest todir="${build.reports}" haltonerror="false" haltonfailure="false" fork="true">
+						<fileset dir="${build.classes}">
+							<include name="**/Negotiation2TestCase.class" />
+						</fileset>
+					</batchtest>
+				</junit>	
+				<echo>Waiting for server to shutdown...</echo>
+				<server:stop name="negotiation" />
+				
+				<!-- stop the GSSTestServer -->
+				<java classname="org.jboss.test.security.negotiation.GSSTestServer">
+					<sysproperty key="gsstestserver.port" value="${gsstestserver.port}" />
+					<classpath>
+						<pathelement location="${build.resources}" />
+						<pathelement location="${build.classes}" />
+						<path refid="thirdparty.classpath" />
+					</classpath>
+					<arg value="stop" />
+				</java>
+	
+				<!-- stop the Kerberos -->
+				<java classname="org.jboss.test.security.negotiation.KerberosServerControl">
+					<sysproperty key="build.testlog" value="${build.testlog}" />
+					<sysproperty key="kerberosControl.port" value="${kerberosControl.port}" />
+					<classpath>
+						<pathelement location="${build.resources}" />
+						<pathelement location="${build.classes}" />
+						<path refid="thirdparty.classpath" />
+					</classpath>
+					<arg value="stop" />
+				</java>
+			</sequential>
+		</parallel>
+		<!-- TODO test when Kerberos server is down -->
+	</target>
+	
 </project>
Index: testsuite/.classpath
===================================================================
--- testsuite/.classpath	(revision 113475)
+++ testsuite/.classpath	(working copy)
@@ -62,5 +62,9 @@
 	<classpathentry kind="lib" path="/thirdparty/jboss/jbossts/lib/jbossjts-integration.jar"/>
 	<classpathentry kind="lib" path="/thirdparty/hibernate/lib/hibernate-jbosscache2.jar" sourcepath="/thirdparty/hibernate/lib/hibernate-jbosscache2-sources.jar"/>
 	<classpathentry kind="lib" path="/thirdparty/jboss/common-beans/lib/jboss-common-beans.jar"/>
+	<classpathentry kind="lib" path="/thirdparty/apache-httpcomponents/lib/httpclient.jar"/>
+	<classpathentry kind="lib" path="/thirdparty/apache-httpcomponents/lib/httpcore.jar"/>
+	<classpathentry kind="lib" path="/thirdparty/apache-httpcomponents/lib/httpmime.jar"/>
+	<classpathentry kind="lib" path="/thirdparty/apacheds/lib/apacheds-all.jar"/>
 	<classpathentry kind="output" path="output/eclipse-classes"/>
 </classpath>
Index: testsuite/src/resources/org/jboss/test/security/negotiation/auth.conf
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/auth.conf	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/auth.conf	(revision 0)
@@ -0,0 +1,58 @@
+spnego-ejb-test-client {
+	com.sun.security.auth.module.Krb5LoginModule required
+	storeKey=true
+	useKeyTab=true
+	refreshKrb5Config=true
+				<module-option name="principal">${principal}</module-option>
+				<module-option name="keyTab">${keyTab}</module-option>
+				<module-option name="doNotPrompt">true</module-option>
+				<module-option name="debug">true</module-option>
+			</login-module> 
+   org.jboss.security.ClientLoginModule  required
+	;
+};
+
+// Used by the org.jboss.test.naming.test.SimpleUnitTestCase
+testLoginInitialContext {
+   org.jboss.security.auth.spi.UsersRolesLoginModule required
+   ;
+   org.jboss.security.ClientLoginModule  required
+   ;
+};
+
+// Used by the org.jboss.test.naming.test.SimpleUnitTestCase
+testSecureHttpInvoker {
+   org.jboss.security.auth.spi.UsersRolesLoginModule required
+   ;
+   org.jboss.security.ClientLoginModule  required
+   ;
+};
+
+spec-test {
+    org.jboss.security.ClientLoginModule  required
+	;
+};
+
+spec-test-multi-threaded {
+    org.jboss.security.ClientLoginModule  required
+        multi-threaded=true
+  ;
+};
+
+srp-test {
+    // Put your login modules that work without jBoss here
+    org.jboss.security.srp.jaas.SRPLoginModule required
+	password-stacking="useFirstPass"
+	principalClassName="org.jboss.security.SimplePrincipal"
+	srpServerJndiName="SRPServerInterface"
+	debug=true
+	;
+
+    // jBoss LoginModule
+    org.jboss.security.ClientLoginModule  required
+	password-stacking="useFirstPass"
+	;
+
+    // Put your login modules that need jBoss here
+};
+ 
Index: testsuite/src/resources/org/jboss/test/security/negotiation/spnego-web.xml
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/spnego-web.xml	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/spnego-web.xml	(revision 0)
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
+   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+	<description>SPNEGO test</description>
+
+	<servlet>
+		<servlet-name>PropagateIdentityServlet</servlet-name>
+		<servlet-class>org.jboss.test.security.negotiation.PropagateIdentityServlet</servlet-class>
+	</servlet>
+
+	<servlet-mapping>
+		<servlet-name>PropagateIdentityServlet</servlet-name>
+		<url-pattern>/propagateIdentity</url-pattern>
+	</servlet-mapping>
+
+	<!-- The Welcome File List -->
+	<welcome-file-list>
+		<welcome-file>index.txt</welcome-file>
+	</welcome-file-list>
+
+	<security-constraint>
+		<web-resource-collection>
+			<web-resource-name>All resources</web-resource-name>
+			<url-pattern>/*</url-pattern>
+		</web-resource-collection>
+		<auth-constraint>
+			<description>Only users in AuthorizedUser role can access secure content</description>
+			<role-name>AuthorizedUser</role-name>
+		</auth-constraint>
+	</security-constraint>
+	
+	<security-constraint>
+		<web-resource-collection>
+			<web-resource-name>All resources</web-resource-name>
+			<url-pattern>/propagateIdentity</url-pattern>
+		</web-resource-collection>
+		<auth-constraint>
+			<role-name>*</role-name>
+		</auth-constraint>
+	</security-constraint>
+
+	<security-role>
+		<role-name>AuthorizedUser</role-name>
+	</security-role>
+	<security-role>
+		<role-name>Users</role-name>
+	</security-role>
+	
+	<login-config>
+		<auth-method>SPNEGO</auth-method>
+	</login-config>
+</web-app>
Index: testsuite/src/resources/org/jboss/test/security/negotiation/index.txt
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/index.txt	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/index.txt	(revision 0)
@@ -0,0 +1 @@
+OK
\ No newline at end of file
Index: testsuite/src/resources/org/jboss/test/security/negotiation/krb5.conf
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/krb5.conf	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/krb5.conf	(revision 0)
@@ -0,0 +1,18 @@
+[libdefaults]
+	default_realm = JBOSS.ORG
+	default_tgs_enctypes = des-cbc-md5,des3-cbc-sha1-kd
+	default_tkt_enctypes = des-cbc-md5,des3-cbc-sha1-kd
+	kdc_timeout = 5000
+	dns_lookup_realm = false
+	dns_lookup_kdc = false
+	allow_weak_crypto = yes
+	forwardable = ${forwardable}
+
+[realms]
+	JBOSS.ORG = {
+		kdc = ${hostname}:6088
+	}
+
+[login]
+	krb4_convert = true
+	krb4_get_tickets = false
Index: testsuite/src/resources/org/jboss/test/security/negotiation/KerberosTest.ldif
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/KerberosTest.ldif	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/KerberosTest.ldif	(revision 0)
@@ -0,0 +1,82 @@
+dn: ou=Users,dc=jboss,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: Users
+
+dn: uid=krbtgt,ou=Users,dc=jboss,dc=org
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: KDC Service
+sn: Service
+uid: krbtgt
+userPassword: secret
+krb5PrincipalName: krbtgt/JBOSS.ORG@JBOSS.ORG
+krb5KeyVersionNumber: 0
+
+dn: uid=ldap,ou=Users,dc=jboss,dc=org
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: LDAP
+sn: Service
+uid: ldap
+userPassword: randall
+krb5PrincipalName: ldap/${hostname}@JBOSS.ORG
+krb5KeyVersionNumber: 0
+
+dn: uid=HTTP,ou=Users,dc=jboss,dc=org
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: HTTP
+sn: Service
+uid: HTTP
+userPassword: httppwd
+krb5PrincipalName: HTTP/${hostname}@JBOSS.ORG
+krb5KeyVersionNumber: 0
+
+dn: uid=hnelson,ou=Users,dc=jboss,dc=org
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: Horatio Nelson
+sn: Nelson
+uid: hnelson
+userPassword: secret
+krb5PrincipalName: hnelson@JBOSS.ORG
+krb5KeyVersionNumber: 0
+
+dn: uid=jduke,ou=Users,dc=jboss,dc=org
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: Java Duke
+sn: duke
+uid: jduke
+userPassword: theduke
+krb5PrincipalName: jduke@JBOSS.ORG
+krb5KeyVersionNumber: 0
+
+dn: uid=gsstestserver,ou=Users,dc=jboss,dc=org
+objectClass: top
+objectClass: person
+objectClass: inetOrgPerson
+objectClass: krb5principal
+objectClass: krb5kdcentry
+cn: gsstestserver
+sn: Service
+uid: gsstestserver
+userPassword: gsstestpwd
+krb5PrincipalName: gsstestserver/xxx@JBOSS.ORG
+krb5KeyVersionNumber: 0
Index: testsuite/src/resources/org/jboss/test/security/negotiation/jboss-web.xml
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/jboss-web.xml	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/jboss-web.xml	(revision 0)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE jboss-web
+    PUBLIC "-//JBoss//DTD Web Application 2.3V2//EN"
+    "http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd">
+
+<jboss-web>
+    <security-domain>SPNEGO</security-domain>
+</jboss-web>
Index: testsuite/src/resources/org/jboss/test/security/negotiation/users.properties
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/users.properties	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/users.properties	(revision 0)
@@ -0,0 +1 @@
+# don't need any user listed here
\ No newline at end of file
Index: testsuite/src/resources/org/jboss/test/security/negotiation/jboss.xml
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/jboss.xml	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/jboss.xml	(revision 0)
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE jboss PUBLIC
+      "-//JBoss//DTD JBOSS 5.0//EN"
+      "http://www.jboss.org/j2ee/dtd/jboss_5_0.dtd">
+<jboss>
+   <security-domain>SPNEGO</security-domain>
+</jboss>
Index: testsuite/src/resources/org/jboss/test/security/negotiation/roles.properties
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/roles.properties	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/roles.properties	(revision 0)
@@ -0,0 +1,5 @@
+#Users role checked/used in JBoss Negotiation Toolkit
+#AuthorizedUser role is used in the SPNEGO test
+#Administrator & RegularUser roles are used in the SimpleStatelessSessionBean class
+hnelson@JBOSS.ORG=Users,RegularUser
+jduke@JBOSS.ORG=Users,AuthorizedUser,Administrator
Index: testsuite/src/resources/org/jboss/test/security/negotiation/fallback/spnego-form-web.xml
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/fallback/spnego-form-web.xml	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/fallback/spnego-form-web.xml	(revision 0)
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
+   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+	<description>SPNEGO test</description>
+
+	<!-- The Welcome File List -->
+	<welcome-file-list>
+		<welcome-file>index.txt</welcome-file>
+	</welcome-file-list>
+
+	<security-constraint>
+		<display-name>protected</display-name>
+		<web-resource-collection>
+			<web-resource-name>All resources</web-resource-name>
+			<url-pattern>/*</url-pattern>
+		</web-resource-collection>
+		<auth-constraint>
+			<description>Only users in AuthorizedUser role can access secure content</description>
+			<role-name>AuthorizedUser</role-name>
+		</auth-constraint>
+	</security-constraint>
+
+	<security-role>
+		<role-name>AuthorizedUser</role-name>
+	</security-role>
+
+	<login-config>
+		<auth-method>SPNEGO</auth-method>
+		<realm-name>SPNEGO</realm-name>
+		<form-login-config>
+			<form-login-page>/login.html</form-login-page>
+			<form-error-page>/error.html</form-error-page>
+		</form-login-config>
+	</login-config>
+</web-app>
Index: testsuite/src/resources/org/jboss/test/security/negotiation/fallback/fallback-users.properties
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/fallback/fallback-users.properties	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/fallback/fallback-users.properties	(revision 0)
@@ -0,0 +1,3 @@
+# passwords for FORM fallback
+jduke@JBOSS.ORG=fallback
+hnelson@JBOSS.ORG=terces
\ No newline at end of file
Index: testsuite/src/resources/org/jboss/test/security/negotiation/fallback/jboss-web.xml
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/fallback/jboss-web.xml	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/fallback/jboss-web.xml	(revision 0)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE jboss-web
+    PUBLIC "-//JBoss//DTD Web Application 2.3V2//EN"
+    "http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd">
+
+<jboss-web>
+    <security-domain>SPNEGO-with-fallback</security-domain>
+</jboss-web>
Index: testsuite/src/resources/org/jboss/test/security/negotiation/fallback/fallback-roles.properties
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/fallback/fallback-roles.properties	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/fallback/fallback-roles.properties	(revision 0)
@@ -0,0 +1 @@
+#FORM authn fallback
Index: testsuite/src/resources/org/jboss/test/security/negotiation/negotiation-test-jboss-beans.xml
===================================================================
--- testsuite/src/resources/org/jboss/test/security/negotiation/negotiation-test-jboss-beans.xml	(revision 0)
+++ testsuite/src/resources/org/jboss/test/security/negotiation/negotiation-test-jboss-beans.xml	(revision 0)
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+
+	<application-policy xmlns="urn:jboss:security-beans:1.0"
+		name="host">
+		<authentication>
+			<login-module code="com.sun.security.auth.module.Krb5LoginModule"
+				flag="required">
+				<module-option name="storeKey">true</module-option>
+				<module-option name="useKeyTab">true</module-option>
+				<module-option name="refreshKrb5Config">true</module-option>
+				<module-option name="principal">${principal}</module-option>
+				<module-option name="keyTab">${keyTab}</module-option>
+				<module-option name="doNotPrompt">true</module-option>
+				<module-option name="debug">true</module-option>
+			</login-module>
+		</authentication>
+	</application-policy>
+
+	<application-policy xmlns="urn:jboss:security-beans:1.0"
+		name="SPNEGO">
+		<authentication>
+			<login-module code="org.jboss.security.negotiation.spnego.SPNEGOLoginModule" flag="requisite">
+				<module-option name="password-stacking">useFirstPass</module-option>
+				<module-option name="serverSecurityDomain">host</module-option>
+			</login-module>
+			<login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
+				<module-option name="password-stacking">useFirstPass</module-option>
+			</login-module>
+		</authentication>
+	</application-policy>
+	
+	<application-policy xmlns="urn:jboss:security-beans:1.0"
+		name="SPNEGO-with-fallback">
+		<authentication>
+			<login-module code="org.jboss.security.negotiation.spnego.SPNEGOLoginModule" flag="requisite">
+				<module-option name="password-stacking">useFirstPass</module-option>
+				<module-option name="serverSecurityDomain">host</module-option>
+				<module-option name="usernamePasswordDomain">FORM-as-fallback</module-option>
+			</login-module>
+			<login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
+				<module-option name="password-stacking">useFirstPass</module-option>
+			</login-module>
+		</authentication>
+	</application-policy>
+	
+	<application-policy xmlns="urn:jboss:security-beans:1.0"
+		name="FORM-as-fallback">
+		<authentication>
+			<login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
+				<module-option name="usersProperties">fallback-users.properties</module-option>
+				<module-option name="rolesProperties">fallback-roles.properties</module-option>
+			</login-module>
+		</authentication>
+	</application-policy>
+</deployment>
\ No newline at end of file
Index: testsuite/src/resources/log4j.xml
===================================================================
--- testsuite/src/resources/log4j.xml	(revision 113475)
+++ testsuite/src/resources/log4j.xml	(working copy)
@@ -121,6 +121,10 @@
     <priority value="INFO" />
   </category>
 
+  <category name="org.apache.directory">
+    <priority value="WARN" />
+  </category>
+
   <!-- Increase the priority threshold for the DefaultDS category
   <category name="DefaultDS">
     <priority value="FATAL"/>
Index: testsuite/src/resources/test-configs/negotiation/deploy/ejb3-connectors-jboss-beans.xml
===================================================================
--- testsuite/src/resources/test-configs/negotiation/deploy/ejb3-connectors-jboss-beans.xml	(revision 0)
+++ testsuite/src/resources/test-configs/negotiation/deploy/ejb3-connectors-jboss-beans.xml	(revision 0)
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  EJB3 Connectors
+
+-->
+
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+    <!--  We don't want the AOPDependencyBuilder  -->
+    <annotation>@org.jboss.aop.microcontainer.annotations.DisableAOP</annotation>
+
+  <!--
+
+    JBoss Remoting Connector
+
+    Note: Bean Name "org.jboss.ejb3.RemotingConnector" is used
+    as a lookup value; alter only after checking java references
+    to this key.
+
+  -->
+  <bean name="org.jboss.ejb3.RemotingConnector"
+    class="org.jboss.remoting.transport.Connector">
+
+    <property name="invokerLocator">
+
+      <value-factory bean="ServiceBindingManager"
+        method="getStringBinding">
+        <parameter>
+          jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3
+        </parameter>
+        <parameter>
+          <null />
+        </parameter>
+        <parameter>socket://${jboss.bind.address}:${port}?socketFactory=org.jboss.security.negotiation.net.SPNEGOSocketFactory&amp;useAllSocketFactoryParams=true</parameter>
+        <parameter>
+          <null />
+        </parameter>
+        <parameter>3873</parameter>
+      </value-factory>
+
+    </property>
+    <property name="serverConfiguration">
+      <inject bean="ServerConfiguration" />
+    </property>
+    <property name="serverSocketFactory">
+      <inject bean="SPNEGOServerSocketFactory" />
+    </property>
+  </bean>
+
+  <bean name="SPNEGOServerSocketFactory" class="org.jboss.security.negotiation.net.SPNEGOServerSocketFactory">
+    <constructor>
+      <parameter>SPNEGO</parameter>
+      <parameter>host</parameter>
+    </constructor>
+  </bean>
+
+  <!-- Remoting Server Configuration -->
+  <bean name="ServerConfiguration"
+    class="org.jboss.remoting.ServerConfiguration">
+    <property name="invocationHandlers">
+      <map keyClass="java.lang.String" valueClass="java.lang.String">
+        <entry>
+          <key>AOP</key>
+          <value>
+            org.jboss.aspects.remoting.AOPRemotingInvocationHandler
+          </value>
+        </entry>
+      </map>
+    </property>
+  </bean>
+
+</deployment>
\ No newline at end of file

Property changes on: testsuite/src/resources/test-configs/negotiation/deploy/ejb3-connectors-jboss-beans.xml
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: testsuite/src/main/org/jboss/test/security/test/NegotiationTestCase.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/test/NegotiationTestCase.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/test/NegotiationTestCase.java	(revision 0)
@@ -0,0 +1,222 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.test;
+
+import java.io.File;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.logging.Logger;
+import org.jboss.test.JBossTestCase;
+import org.jboss.test.security.ejb3.SimpleSession;
+import org.jboss.test.security.negotiation.GSSTestServer;
+import org.jboss.test.security.negotiation.KerberosServerControl;
+import org.jboss.test.security.negotiation.NegotiationUtils;
+import org.jboss.test.security.negotiation.PropagateIdentityServlet;
+
+/**
+ * A JBoss Negotiation tests. Two processes must be started before this TC runs - KDC Server ({@link KerberosServerControl}) and
+ * sample server for testing identity propagation ({@link GSSTestServer}).
+ * 
+ * @author Josef Cacek
+ */
+public class NegotiationTestCase extends JBossTestCase {
+
+    private static Logger LOGGER = Logger.getLogger(NegotiationTestCase.class);
+
+    protected static final File JBOSS_SERVER_HOME = new File(System.getProperty("jboss.server.home.dir"));
+    protected static final String NAMING_PROVIDER_URL = System.getProperty("java.naming.provider.url");
+    protected static final String WAR_NAME = "spnego-web-test";
+    protected static final String WAR_NAME_FORM_FALLBACK = "spnego-form-web-test";
+    protected static final String JAR_NAME = "spnego-ejb3-test";
+
+    // Constructors ----------------------------------------------------------
+
+    /**
+     * Create a new NegotiationTestCase.
+     * 
+     * @param testName
+     */
+    public NegotiationTestCase(String testName) {
+        super(testName);
+    }
+
+    // Public methods --------------------------------------------------------
+
+    /**
+     * Tests identity propagation by requesting {@link PropagateIdentityServlet}.
+     * 
+     * @throws Exception
+     */
+    public void testIdentityPropagation() throws Exception {
+        LOGGER.info("Testing web access.");
+
+        final String warName = WAR_NAME + ".war";
+        undeploy(warName);
+        deploy(warName);
+
+        final String webURL = "http://" + getServerHost() + ":" + Integer.getInteger("web.port", 8080) + "/" + WAR_NAME
+                + "/propagateIdentity";
+        assertEquals("Unexpected response body", "jduke@JBOSS.ORG",
+                NegotiationUtils.makeHttpCall(webURL, "jduke", "theduke", HttpServletResponse.SC_OK));
+        assertEquals("Unexpected response body", "hnelson@JBOSS.ORG",
+                NegotiationUtils.makeHttpCall(webURL, "hnelson", "secret", HttpServletResponse.SC_OK));
+    }
+
+    /**
+     * Tests web SPNEGO authentication.
+     * 
+     * @throws Exception
+     */
+    public void testWebAccess() throws Exception {
+        LOGGER.info("Testing web access.");
+
+        final String warName = WAR_NAME + ".war";
+        undeploy(warName);
+        deploy(warName);
+
+        final String webURL = "http://" + getServerHost() + ":" + Integer.getInteger("web.port", 8080) + "/" + WAR_NAME
+                + "/index.txt";
+        final String responseBody = NegotiationUtils.makeHttpCall(webURL, "jduke", "theduke", HttpServletResponse.SC_OK);
+        assertEquals("Unexpected response body", "OK", responseBody);
+        NegotiationUtils.makeHttpCall(webURL, "hnelson", "secret", HttpServletResponse.SC_FORBIDDEN);
+        try {
+            NegotiationUtils.makeHttpCall(webURL, "jduke", "secret", HttpServletResponse.SC_UNAUTHORIZED);
+            fail("Login using a wrong password must fail.");
+        } catch (Exception e) {
+            //exception expected
+        }
+    }
+
+    /**
+     * Tests web SPNEGO authentication with FORM method fallback.
+     * 
+     * @throws Exception
+     */
+    public void testFormFallback() throws Exception {
+        LOGGER.info("Testing web access.");
+
+        final String warName = WAR_NAME_FORM_FALLBACK + ".war";
+        undeploy(warName);
+        deploy(warName);
+
+        final String contextUrl = "http://" + getServerHost() + ":" + Integer.getInteger("web.port", 8080) + "/"
+                + WAR_NAME_FORM_FALLBACK;
+
+        String responseBody = NegotiationUtils.makeHttpCallWoSPNEGO(contextUrl, "/index.txt", "jduke@JBOSS.ORG", "fallback",
+                HttpServletResponse.SC_OK);
+        assertEquals("Unexpected response body", "OK", responseBody);
+
+        responseBody = NegotiationUtils.makeHttpCallWithFallback(contextUrl, "/index.txt", "jduke@JBOSS.ORG", "fallback",
+                HttpServletResponse.SC_OK);
+        assertEquals("Unexpected response body", "OK", responseBody);
+    }
+
+    /**
+     * Tests EJB authentication using SPNEGO.
+     * 
+     * @throws Exception
+     */
+    public void testEjbAccess() throws Exception {
+        LOGGER.info("Testing EJB3 access.");
+
+        final String jarName = JAR_NAME + ".jar";
+        undeploy(jarName);
+        deploy(jarName);
+
+        final Properties env = new Properties();
+        env.put(Context.PROVIDER_URL, NAMING_PROVIDER_URL);
+        env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
+        env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
+
+        //hnelson - regular user
+        Configuration.setConfiguration(new Krb5LoginConfiguration("hnelson", new File(JBOSS_SERVER_HOME, "hnelson.keytab")));
+        InitialContext ctx = new InitialContext(env);
+        SimpleSession session = (SimpleSession) ctx.lookup("SimpleStatelessSessionBean/remote");
+        Principal principal = session.invokeRegularMethod();
+        ctx.close();
+        assertEquals("User's principal name doesn't match.", "hnelson@JBOSS.ORG", principal.getName());
+        //TODO try to call invokeAdministrativeMethod() - should fail (but for now it hangs-up and test fails on timeout)
+
+        //jduke - administrator
+        Configuration.setConfiguration(new Krb5LoginConfiguration("jduke", new File(JBOSS_SERVER_HOME, "jduke.keytab")));
+        ctx = new InitialContext(env);
+        session = (SimpleSession) ctx.lookup("SimpleStatelessSessionBean/remote");
+        principal = session.invokeAdministrativeMethod();
+        ctx.close();
+        assertEquals("User's principal name doesn't match.", "jduke@JBOSS.ORG", principal.getName());
+    }
+
+    // Embedded classes ------------------------------------------------------
+
+    /**
+     * Simple Krb5LoginModule configuration.
+     */
+    public static class Krb5LoginConfiguration extends Configuration {
+
+        /** The list with configuration entries. */
+        private final AppConfigurationEntry[] configList = new AppConfigurationEntry[1];
+
+        public Krb5LoginConfiguration(String principal, File keyTab) {
+            final Map<String, Object> options = new HashMap<String, Object>();
+            final String loginModule;
+            if (System.getProperty("java.vendor").startsWith("IBM")) {
+                loginModule = "com.ibm.security.auth.module.Krb5LoginModule";
+                options.put("noAddress", "true");
+            } else {
+                loginModule = "com.sun.security.auth.module.Krb5LoginModule";
+            }
+            options.put("refreshKrb5Config", "true");
+            options.put("storeKey", "true");
+            options.put("useKeyTab", "true");
+            options.put("doNotPrompt", "true");
+            options.put("debug", "true");
+
+            options.put("principal", principal);
+            options.put("keyTab", keyTab.getAbsolutePath());
+
+            configList[0] = new AppConfigurationEntry(loginModule, AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                    options);
+        }
+
+        /**
+         * Interface method requiring us to return all the LoginModules we know about.
+         * 
+         * @param applicationName the application name
+         * @return the configuration entry
+         */
+        @Override
+        public AppConfigurationEntry[] getAppConfigurationEntry(String applicationName) {
+            // We will ignore the applicationName, since we want all apps to use Kerberos V5
+            return configList;
+        }
+
+    }
+}
Index: testsuite/src/main/org/jboss/test/security/test/Negotiation2TestCase.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/test/Negotiation2TestCase.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/test/Negotiation2TestCase.java	(revision 0)
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.test;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.logging.Logger;
+import org.jboss.test.JBossTestCase;
+import org.jboss.test.security.negotiation.NegotiationUtils;
+import org.jboss.test.security.negotiation.PropagateIdentityServlet;
+
+/**
+ * Negotiation propagation test which should be run with the forwardable=false in [libdefaults] krb5.conf.
+ * 
+ * @author Josef Cacek
+ */
+public class Negotiation2TestCase extends JBossTestCase {
+
+    private static Logger LOGGER = Logger.getLogger(Negotiation2TestCase.class);
+
+    // Constructors ----------------------------------------------------------
+
+    /**
+     * Create a new Negotiation2TestCase.
+     * 
+     * @param testName
+     */
+    public Negotiation2TestCase(String testName) {
+        super(testName);
+    }
+
+    // Public methods --------------------------------------------------------
+
+    /**
+     * Tests if 401 (SC_UNAUTHORIZED) is returned from {@link PropagateIdentityServlet}, when the kerberos tickets are not
+     * forwardable.
+     * 
+     * @throws Exception
+     */
+    public void testIdentityPropagation() throws Exception {
+        LOGGER.info("Testing web access.");
+
+        final String warName = NegotiationTestCase.WAR_NAME + ".war";
+        undeploy(warName);
+        deploy(warName);
+
+        final String webURL = "http://" + getServerHost() + ":" + Integer.getInteger("web.port", 8080) + "/"
+                + NegotiationTestCase.WAR_NAME + "/propagateIdentity";
+        NegotiationUtils.makeHttpCall(webURL, "jduke", "theduke", HttpServletResponse.SC_UNAUTHORIZED);
+        NegotiationUtils.makeHttpCall(webURL, "hnelson", "secret", HttpServletResponse.SC_UNAUTHORIZED);
+    }
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/NegotiationUtils.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/NegotiationUtils.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/NegotiationUtils.java	(revision 0)
@@ -0,0 +1,361 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.ProtocolException;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.RedirectStrategy;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.params.AuthPolicy;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.DefaultRedirectStrategy;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
+import org.jboss.logging.Logger;
+import org.jboss.security.auth.callback.UsernamePasswordHandler;
+
+/**
+ * This class contains helper methods for SPNEGO.
+ * 
+ * @author Josef Cacek
+ */
+public class NegotiationUtils {
+    private static Logger LOGGER = Logger.getLogger(NegotiationUtils.class);
+
+    /** The REDIRECT_STRATEGY */
+    private final static RedirectStrategy REDIRECT_STRATEGY = new DefaultRedirectStrategy() {
+        @Override
+        public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) {
+            boolean isRedirect = false;
+            try {
+                isRedirect = super.isRedirected(request, response, context);
+            } catch (ProtocolException e) {
+                e.printStackTrace();
+            }
+            if (!isRedirect) {
+                final int responseCode = response.getStatusLine().getStatusCode();
+                isRedirect = (responseCode == 301 || responseCode == 302);
+            }
+            return isRedirect;
+        }
+    };
+
+    // Public methods --------------------------------------------------------
+
+    /**
+     * Returns response body for the given URL request as a String. It also checks if the returned HTTP status code is the
+     * expected one. If the server returns {@link HttpServletResponse#SC_UNAUTHORIZED} and an username is provided, then the
+     * given user is authenticated against Kerberos and a new request is executed under the new subject.
+     * 
+     * @param url requesting URL
+     * @param user Username
+     * @param pass Password
+     * @param expectedStatusCode expected status code returned from the requested server
+     * @return HTTP response body
+     * @throws ClientProtocolException
+     * @throws IOException
+     * @throws URISyntaxException
+     * @throws PrivilegedActionException
+     * @throws LoginException
+     */
+    public static String makeHttpCall(final String url, final String user, final String pass, final int expectedStatusCode)
+            throws ClientProtocolException, IOException, URISyntaxException, PrivilegedActionException, LoginException {
+        LOGGER.info("Requesting URL: " + url);
+        final DefaultHttpClient httpClient = new DefaultHttpClient();
+        try {
+            httpClient.getAuthSchemes().register(AuthPolicy.SPNEGO, new JBossNegotiateSchemeFactory(true));
+            httpClient.getCredentialsProvider().setCredentials(new AuthScope(null, -1, null), new NullHCCredentials());
+
+            final HttpGet httpGet = new HttpGet(url);
+            final HttpResponse response = httpClient.execute(httpGet);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (HttpServletResponse.SC_UNAUTHORIZED != statusCode || StringUtils.isEmpty(user)) {
+                assertEquals("Unexpected HTTP response status code.", expectedStatusCode, statusCode);
+                return EntityUtils.toString(response.getEntity());
+            }
+            final HttpEntity entity = response.getEntity();
+            final Header[] authnHeaders = response.getHeaders("WWW-Authenticate");
+            assertTrue("WWW-Authenticate header is present", authnHeaders != null && authnHeaders.length > 0);
+            final Set<String> authnHeaderValues = new HashSet<String>();
+            for (final Header header : authnHeaders) {
+                authnHeaderValues.add(header.getValue());
+            }
+            assertTrue("WWW-Authenticate: Negotiate header is missing", authnHeaderValues.contains("Negotiate"));
+
+            LOGGER.debug("HTTP response was SC_UNAUTHORIZED, let's authenticate the user " + user);
+            if (entity != null)
+                EntityUtils.consume(entity);
+
+            // Use our custom configuration to avoid reliance on external config
+            Configuration.setConfiguration(new Krb5LoginConfiguration());
+            // 1. Authenticate to Kerberos.
+            final LoginContext lc = new LoginContext(NegotiationUtils.class.getName(), new UsernamePasswordHandler(user, pass));
+            lc.login();
+
+            // 2. Perform the work as authenticated Subject.
+            final String responseBody = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<String>() {
+                public String run() throws Exception {
+                    final HttpResponse response = httpClient.execute(httpGet);
+                    int statusCode = response.getStatusLine().getStatusCode();
+                    assertEquals("Unexpected status code returned after the authentication.", expectedStatusCode, statusCode);
+                    return EntityUtils.toString(response.getEntity());
+                }
+            });
+            lc.logout();
+            return responseBody;
+        } finally {
+            // When HttpClient instance is no longer needed,
+            // shut down the connection manager to ensure
+            // immediate deallocation of all system resources
+            httpClient.getConnectionManager().shutdown();
+        }
+    }
+
+    /**
+     * Creates request against SPNEGO protected web-app with FORM fallback. It tries to login using SPNEGO first - if it fails,
+     * FORM is used.
+     * 
+     * @param contextUrl
+     * @param page
+     * @param user
+     * @param pass
+     * @param expectedStatusCode
+     * @return
+     * @throws ClientProtocolException
+     * @throws IOException
+     * @throws URISyntaxException
+     * @throws PrivilegedActionException
+     * @throws LoginException
+     */
+    public static String makeHttpCallWithFallback(final String contextUrl, final String page, final String user,
+            final String pass, final int expectedStatusCode) throws ClientProtocolException, IOException, URISyntaxException,
+            PrivilegedActionException, LoginException {
+        final String url = contextUrl + page;
+        LOGGER.info("Requesting URL: " + url);
+        final DefaultHttpClient httpClient = new DefaultHttpClient();
+        httpClient.setRedirectStrategy(REDIRECT_STRATEGY);
+        String unauthorizedPageBody = null;
+        try {
+            httpClient.getAuthSchemes().register(AuthPolicy.SPNEGO, new JBossNegotiateSchemeFactory(true));
+            httpClient.getCredentialsProvider().setCredentials(new AuthScope(null, -1, null), new NullHCCredentials());
+
+            final HttpGet httpGet = new HttpGet(url);
+            final HttpResponse response = httpClient.execute(httpGet);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (HttpServletResponse.SC_UNAUTHORIZED != statusCode || StringUtils.isEmpty(user)) {
+                assertEquals("Unexpected HTTP response status code.", expectedStatusCode, statusCode);
+                return EntityUtils.toString(response.getEntity());
+            }
+            final Header[] authnHeaders = response.getHeaders("WWW-Authenticate");
+            assertTrue("WWW-Authenticate header is present", authnHeaders != null && authnHeaders.length > 0);
+            final Set<String> authnHeaderValues = new HashSet<String>();
+            for (final Header header : authnHeaders) {
+                authnHeaderValues.add(header.getValue());
+            }
+            assertTrue("WWW-Authenticate: Negotiate header is missing", authnHeaderValues.contains("Negotiate"));
+
+            LOGGER.debug("HTTP response was SC_UNAUTHORIZED, let's authenticate the user " + user);
+            unauthorizedPageBody = EntityUtils.toString(response.getEntity());
+
+            // Use our custom configuration to avoid reliance on external config
+            Configuration.setConfiguration(new Krb5LoginConfiguration());
+            // 1. Authenticate to Kerberos.
+            final LoginContext lc = new LoginContext(NegotiationUtils.class.getName(), new UsernamePasswordHandler(user, pass));
+            lc.login();
+
+            // 2. Perform the work as authenticated Subject.
+            final String responseBody = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<String>() {
+                public String run() throws Exception {
+                    final HttpResponse response = httpClient.execute(httpGet);
+                    int statusCode = response.getStatusLine().getStatusCode();
+                    assertEquals("Unexpected status code returned after the authentication.", expectedStatusCode, statusCode);
+                    return EntityUtils.toString(response.getEntity());
+                }
+            });
+            lc.logout();
+            return responseBody;
+        } catch (LoginException e) {
+            assertNotNull(unauthorizedPageBody);
+            assertTrue(unauthorizedPageBody.contains("j_security_check"));
+
+            HttpPost httpPost = new HttpPost(StringUtils.stripEnd(contextUrl, "/") + "/j_security_check");
+            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
+            nameValuePairs.add(new BasicNameValuePair("j_username", user));
+            nameValuePairs.add(new BasicNameValuePair("j_password", pass));
+            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
+            final HttpResponse response = httpClient.execute(httpPost);
+            int statusCode = response.getStatusLine().getStatusCode();
+            assertEquals("Unexpected status code returned after the authentication.", expectedStatusCode, statusCode);
+            return EntityUtils.toString(response.getEntity());
+        } finally {
+            // When HttpClient instance is no longer needed,
+            // shut down the connection manager to ensure
+            // immediate deallocation of all system resources
+            httpClient.getConnectionManager().shutdown();
+        }
+    }
+
+    /**
+     * Creates request against SPNEGO protected web-app with FORM fallback. It doesn't try to login using SPNEGO - it uses FORM
+     * authn directly.
+     * 
+     * @param contextUrl
+     * @param page
+     * @param user
+     * @param pass
+     * @param expectedStatusCode
+     * @return
+     * @throws ClientProtocolException
+     * @throws IOException
+     * @throws URISyntaxException
+     * @throws PrivilegedActionException
+     * @throws LoginException
+     */
+    public static String makeHttpCallWoSPNEGO(final String contextUrl, final String page, final String user, final String pass,
+            final int expectedStatusCode) throws ClientProtocolException, IOException, URISyntaxException,
+            PrivilegedActionException, LoginException {
+        final String url = contextUrl + page;
+        LOGGER.info("Requesting URL: " + url);
+        final DefaultHttpClient httpClient = new DefaultHttpClient();
+        httpClient.setRedirectStrategy(REDIRECT_STRATEGY);
+        String unauthorizedPageBody = null;
+        try {
+            final HttpGet httpGet = new HttpGet(url);
+            HttpResponse response = httpClient.execute(httpGet);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (HttpServletResponse.SC_UNAUTHORIZED != statusCode || StringUtils.isEmpty(user)) {
+                assertEquals("Unexpected HTTP response status code.", expectedStatusCode, statusCode);
+                return EntityUtils.toString(response.getEntity());
+            }
+            final Header[] authnHeaders = response.getHeaders("WWW-Authenticate");
+            assertTrue("WWW-Authenticate header is present", authnHeaders != null && authnHeaders.length > 0);
+            final Set<String> authnHeaderValues = new HashSet<String>();
+            for (final Header header : authnHeaders) {
+                authnHeaderValues.add(header.getValue());
+            }
+            assertTrue("WWW-Authenticate: Negotiate header is missing", authnHeaderValues.contains("Negotiate"));
+
+            LOGGER.debug("HTTP response was SC_UNAUTHORIZED, let's authenticate the user " + user);
+            unauthorizedPageBody = EntityUtils.toString(response.getEntity());
+
+            assertNotNull(unauthorizedPageBody);
+            assertTrue(unauthorizedPageBody.contains("j_security_check"));
+
+            HttpPost httpPost = new HttpPost(StringUtils.stripEnd(contextUrl, "/") + "/j_security_check");
+            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
+            nameValuePairs.add(new BasicNameValuePair("j_username", user));
+            nameValuePairs.add(new BasicNameValuePair("j_password", pass));
+            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
+            response = httpClient.execute(httpPost);
+            statusCode = response.getStatusLine().getStatusCode();
+            assertEquals("Unexpected status code returned after the authentication.", expectedStatusCode, statusCode);
+            return EntityUtils.toString(response.getEntity());
+        } finally {
+            // When HttpClient instance is no longer needed,
+            // shut down the connection manager to ensure
+            // immediate deallocation of all system resources
+            httpClient.getConnectionManager().shutdown();
+        }
+    }
+
+    /**
+     * Sets or removes (in case value==null) a system property. It's only a helper method, which avoids
+     * {@link NullPointerException} thrown from {@link System#setProperty(String, String)} method, when the value is
+     * <code>null</code>.
+     * 
+     * @param key property name
+     * @param value property value
+     * @return the previous string value of the system property
+     */
+    public static String setSystemProperty(final String key, final String value) {
+        return value == null ? System.clearProperty(key) : System.setProperty(key, value);
+    }
+
+    // Embedded classes ------------------------------------------------------
+    /**
+     * Simple Krb5LoginModule configuration.
+     */
+    public static class Krb5LoginConfiguration extends Configuration {
+
+        /** The list with configuration entries. */
+        private static final AppConfigurationEntry[] configList = new AppConfigurationEntry[1];
+
+        static {
+            final Map<String, Object> options = new HashMap<String, Object>();
+            final String loginModule;
+            if (System.getProperty("java.vendor").startsWith("IBM")) {
+                loginModule = "com.ibm.security.auth.module.Krb5LoginModule";
+                options.put("noAddress", "true");
+            } else {
+                loginModule = "com.sun.security.auth.module.Krb5LoginModule";
+            }
+            options.put("refreshKrb5Config", "true");
+
+            configList[0] = new AppConfigurationEntry(loginModule, AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                    options);
+        }
+
+        /**
+         * Interface method requiring us to return all the LoginModules we know about.
+         * 
+         * @param applicationName the application name
+         * @return the configuration entry
+         */
+        @Override
+        public AppConfigurationEntry[] getAppConfigurationEntry(String applicationName) {
+            // We will ignore the applicationName, since we want all apps to use Kerberos V5
+            return configList;
+        }
+    }
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/PropagateIdentityServlet.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/PropagateIdentityServlet.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/PropagateIdentityServlet.java	(revision 0)
@@ -0,0 +1,79 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.jboss.logging.Logger;
+import org.jboss.security.negotiation.DelegationCredentialContext;
+
+/**
+ * A PropagateServlet for testing Kerberos identity propagation in JBoss Negotiation.
+ * 
+ * @author Josef Cacek
+ */
+public class PropagateIdentityServlet extends HttpServlet {
+    private static final long serialVersionUID = 1L;
+
+    private static Logger LOGGER = Logger.getLogger(PropagateIdentityServlet.class);
+
+    // Protected methods -----------------------------------------------------
+
+    /**
+     * Retrieves a {@link GSSCredential} from {@link DelegationCredentialContext#getDelegCredential()}. If it's null error 401
+     * (SC_UNAUTHORIZED) is returned, otherwise {@link GSSTestClient} is used retrieve name of propagated identity from
+     * {@link GSSTestServer}.
+     * 
+     * @param req
+     * @param resp
+     * @throws ServletException
+     * @throws IOException
+     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        LOGGER.debug("New request comming.");
+        final GSSCredential credential = DelegationCredentialContext.getDelegCredential();
+        if (credential == null) {
+            resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "GSSCredential not found");
+        } else {
+            resp.setContentType("text/plain");
+            final PrintWriter writer = resp.getWriter();
+            final GSSTestClient client = new GSSTestClient("localhost", GSSTestServer.PORT,
+                    GSSTestServer.PRINCIPAL);
+            try {
+                writer.print(client.getName(credential));
+            } catch (GSSException e) {
+                throw new ServletException("Propagation failed.", e);
+            }
+        }
+
+    }
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/NegotiationSetup.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/NegotiationSetup.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/NegotiationSetup.java	(revision 0)
@@ -0,0 +1,251 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.text.StrSubstitutor;
+import org.apache.directory.server.kerberos.shared.crypto.encryption.KerberosKeyFactory;
+import org.apache.directory.server.kerberos.shared.keytab.Keytab;
+import org.apache.directory.server.kerberos.shared.keytab.KeytabEntry;
+import org.apache.directory.shared.kerberos.KerberosTime;
+import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
+import org.apache.directory.shared.kerberos.components.EncryptionKey;
+import org.apache.log4j.Logger;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.XPath;
+import org.dom4j.io.SAXReader;
+
+/**
+ * A simple application which configures "negotiation" profile in the JBoss AS. It generates KeyTab files, krb5.conf files,
+ * registers SPNEGO authenticator and security domains.
+ * 
+ * @author Josef Cacek
+ */
+public class NegotiationSetup {
+
+    private static final Logger LOGGER = Logger.getLogger(NegotiationSetup.class);
+
+    public static final String KRB5_CONF = "krb5.conf";
+
+    private static final String HTTP_KEYTAB = "http.keytab";
+    private static final String JBOSS_BEANS = "negotiation-test-jboss-beans.xml";
+
+    private final String canonicalHost;
+    private final File serverHomeFile;
+    private final File serverKeytabFile;
+    private final Map<String, String> replacementsMap;
+    private final String serverPrincipalName;
+
+    // Constructors ----------------------------------------------------------
+
+    /**
+     * Create a new NegotiationSetup.
+     */
+    public NegotiationSetup() {
+        canonicalHost = getCannonicalHost(System.getProperty("jboss.bind.address", "localhost"));
+
+        serverHomeFile = new File(System.getProperty("jboss.server.home.dir"));
+        LOGGER.info("Server home dir: " + serverHomeFile.getAbsolutePath());
+        if (!serverHomeFile.isDirectory()) {
+            throw new IllegalStateException("Server home not found - " + serverHomeFile.getAbsolutePath());
+        }
+        serverKeytabFile = new File(serverHomeFile, HTTP_KEYTAB);
+
+        serverPrincipalName = "HTTP/" + canonicalHost + "@JBOSS.ORG";
+
+        replacementsMap = new HashMap<String, String>();
+        replacementsMap.put("principal", serverPrincipalName);
+        replacementsMap.put("hostname", canonicalHost);
+        replacementsMap.put("keyTab", serverKeytabFile.getAbsolutePath());
+
+    }
+
+    // Public methods --------------------------------------------------------
+
+    /**
+     * The main - exit code is 1 if an Exception occurs.
+     * 
+     * @param args
+     */
+    public static void main(String args[]) {
+        NegotiationSetup ns = new NegotiationSetup();
+        try {
+            ns.createKrb5Confs();
+            ns.createKeytabFiles();
+            ns.registerSPNEGOAuthenticator();
+            ns.createJBossBeansXML();
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+    }
+
+    // Private methods -------------------------------------------------------
+
+    /**
+     * Creates krb5.conf files from a template.
+     * 
+     * @throws IOException
+     * @throws DocumentException
+     */
+    private final void createKrb5Confs() throws IOException, DocumentException {
+        final Map<String, String> krb5ConfReplacements = new HashMap<String, String>(replacementsMap);
+        krb5ConfReplacements.put("forwardable", "true");
+        FileUtils.write(new File(serverHomeFile, KRB5_CONF), StrSubstitutor.replace(
+                IOUtils.toString(getClass().getResourceAsStream(KRB5_CONF), "UTF-8"), krb5ConfReplacements), "UTF-8");
+        krb5ConfReplacements.put("forwardable", "false");
+        FileUtils.write(new File(serverHomeFile, "notforwardable." + KRB5_CONF), StrSubstitutor.replace(
+                IOUtils.toString(getClass().getResourceAsStream(KRB5_CONF), "UTF-8"), krb5ConfReplacements), "UTF-8");
+    }
+
+    /**
+     * Creates keytab files.
+     * 
+     * @throws IOException
+     * @throws DocumentException
+     */
+    private final void createKeytabFiles() throws IOException, DocumentException {
+        createKeytabFile(serverPrincipalName, "httppwd", serverKeytabFile);
+        createKeytabFile("jduke@JBOSS.ORG", "theduke", new File(serverHomeFile, "jduke.keytab"));
+        createKeytabFile("hnelson@JBOSS.ORG", "secret", new File(serverHomeFile, "hnelson.keytab"));
+    }
+
+    /**
+     * Creates a custom -jboss-beans.xml file from a template.
+     * 
+     * @throws IOException
+     */
+    private void createJBossBeansXML() throws IOException {
+        final File jbossBeansFile = new File(serverHomeFile, "deploy/" + JBOSS_BEANS);
+        FileUtils
+                .write(jbossBeansFile, StrSubstitutor.replace(
+                        IOUtils.toString(getClass().getResourceAsStream(JBOSS_BEANS), "UTF-8"), replacementsMap), "UTF-8");
+    }
+
+    /**
+     * Creates one Keytab file for given principal-password pair.
+     * 
+     * @param principalName
+     * @param password
+     * @param keytabFile
+     * @throws IOException
+     * @throws DocumentException
+     */
+    private static final void createKeytabFile(String principalName, String password, File keytabFile) throws IOException,
+            DocumentException {
+        final KerberosTime timeStamp = new KerberosTime();
+        final long principalType = 1L; //KRB5_NT_PRINCIPAL
+
+        final Keytab keytab = Keytab.getInstance();
+        final List<KeytabEntry> entries = new ArrayList<KeytabEntry>();
+        for (Map.Entry<EncryptionType, EncryptionKey> keyEntry : KerberosKeyFactory.getKerberosKeys(principalName, password)
+                .entrySet()) {
+            final EncryptionKey key = keyEntry.getValue();
+            final byte keyVersion = (byte) key.getKeyVersion();
+            entries.add(new KeytabEntry(principalName, principalType, timeStamp, keyVersion, key));
+        }
+        keytab.setEntries(entries);
+        keytab.write(keytabFile);
+    }
+
+    /**
+     * Registers SPNEGO authenticator in war-deployers-jboss-beans.xml.
+     * 
+     * @throws DocumentException
+     * @throws IOException
+     */
+    private final void registerSPNEGOAuthenticator() throws DocumentException, IOException {
+        //edit authenticators
+        //<entry>
+        //  <key>SPNEGO</key>
+        //  <value>org.jboss.security.negotiation.NegotiationAuthenticator</value>
+        //</entry>
+        final File warDeployersFile = new File(serverHomeFile,
+                "deployers/jbossweb.deployer/META-INF/war-deployers-jboss-beans.xml");
+
+        final Map<String, String> namespaceUris = new HashMap<String, String>();
+        namespaceUris.put("bean-deployer", "urn:jboss:bean-deployer:2.0");
+
+        System.out.println("Editing " + warDeployersFile.getAbsolutePath());
+        final Document document = new SAXReader().read(warDeployersFile);
+
+        //Workaround for JBPAPP-9544 - remove picketlink authenticator
+        XPath xPath = DocumentHelper
+                .createXPath("//bean-deployer:property[@name='authenticators']/bean-deployer:map/bean-deployer:entry[bean-deployer:key/text()='SECURITY_DOMAIN']");
+        xPath.setNamespaceURIs(namespaceUris);
+        Element picketlinkAuhemticatorEl = (Element) xPath.selectSingleNode(document);
+        if (picketlinkAuhemticatorEl != null) {
+            picketlinkAuhemticatorEl.getParent().remove(picketlinkAuhemticatorEl);
+        }
+
+        //Add SPNEGO
+        xPath = DocumentHelper
+                .createXPath("//bean-deployer:property[@name='authenticators']/bean-deployer:map/bean-deployer:entry/bean-deployer:key[text()='SPNEGO']");
+        xPath.setNamespaceURIs(namespaceUris);
+
+        if (xPath.selectNodes(document).isEmpty()) {
+            xPath = DocumentHelper.createXPath("//bean-deployer:property[@name='authenticators']/bean-deployer:map");
+            xPath.setNamespaceURIs(namespaceUris);
+
+            Element authenticatorsMapEl = (Element) xPath.selectSingleNode(document);
+            Element entryEl = authenticatorsMapEl.addElement("entry");
+            Element keyEl = entryEl.addElement("key");
+            keyEl.setText("SPNEGO");
+            Element valueEl = entryEl.addElement("value");
+            valueEl.setText("org.jboss.security.negotiation.NegotiationAuthenticator");
+        }
+        final FileWriter fileWriter = new FileWriter(warDeployersFile);
+        document.write(fileWriter);
+        fileWriter.close();
+    }
+
+    /**
+     * Returns canonical hostname form of the given host address.
+     * 
+     * @param host address
+     * @return
+     */
+    private static final String getCannonicalHost(String host) {
+        try {
+            host = InetAddress.getByName(host).getCanonicalHostName();
+        } catch (UnknownHostException e) {
+            LOGGER.warn("Unable to get cannonical host name", e);
+        }
+        return host.toLowerCase(Locale.ENGLISH);
+    }
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/KDCServerAnnotationProcessor.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/KDCServerAnnotationProcessor.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/KDCServerAnnotationProcessor.java	(revision 0)
@@ -0,0 +1,128 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.AnnotationUtils;
+import org.apache.directory.server.core.api.DirectoryService;
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.server.kerberos.kdc.KdcServer;
+import org.apache.directory.server.protocol.shared.transport.TcpTransport;
+import org.apache.directory.server.protocol.shared.transport.Transport;
+import org.apache.directory.server.protocol.shared.transport.UdpTransport;
+import org.apache.mina.util.AvailablePortFinder;
+
+/**
+ * Annotation processor for creating Kerberos servers - based on original implementation in
+ * {@link org.apache.directory.server.factory.ServerAnnotationProcessor}. This implementation only adds a workaround for
+ * https://issues.apache.org/jira/browse/DIRKRB-85<br/>
+ * Use this class together with {@link ExtCreateKdcServer} annotation.
+ * 
+ * @author Josef Cacek
+ * @see ExtCreateKdcServer
+ */
+public class KDCServerAnnotationProcessor {
+
+    // Public methods --------------------------------------------------------
+
+    /**
+     * Creates and starts KdcServer based on configuration from {@link ExtCreateKdcServer} annotation.
+     * 
+     * @param directoryService
+     * @param startPort start port number used for searching free ports in case the transport has no port number preconfigured.
+     * @param address if not null, use this bind address instead of the value configured in {@link Transport} annotation.
+     * @return
+     * @throws Exception
+     */
+    public static KdcServer getKdcServer(DirectoryService directoryService, int startPort, String address) throws Exception {
+        final ExtCreateKdcServer createKdcServer = (ExtCreateKdcServer) AnnotationUtils.getInstance(ExtCreateKdcServer.class);
+        return createKdcServer(createKdcServer, directoryService, startPort, address);
+    }
+
+    // Private methods -------------------------------------------------------
+
+    /**
+     * Creates and starts {@link KdcServer} instance based on given configuration.
+     * 
+     * @param createKdcServer
+     * @param directoryService
+     * @param startPort
+     * @return
+     */
+    private static KdcServer createKdcServer(ExtCreateKdcServer createKdcServer, DirectoryService directoryService,
+            int startPort, String bindAddress) {
+        if (createKdcServer == null) {
+            return null;
+        }
+        KdcServer kdcServer = new KdcServer();
+        kdcServer.setServiceName(createKdcServer.name());
+        kdcServer.setKdcPrincipal(createKdcServer.kdcPrincipal());
+        kdcServer.setPrimaryRealm(createKdcServer.primaryRealm());
+        kdcServer.setMaximumTicketLifetime(createKdcServer.maxTicketLifetime());
+        kdcServer.setMaximumRenewableLifetime(createKdcServer.maxRenewableLifetime());
+        kdcServer.setSearchBaseDn(createKdcServer.searchBaseDn());
+        kdcServer.setPaEncTimestampRequired(false);
+
+        CreateTransport[] transportBuilders = createKdcServer.transports();
+
+        if (transportBuilders == null) {
+            // create only UDP transport if none specified
+            UdpTransport defaultTransport = new UdpTransport(AvailablePortFinder.getNextAvailable(startPort));
+            kdcServer.addTransports(defaultTransport);
+        } else if (transportBuilders.length > 0) {
+            for (CreateTransport transportBuilder : transportBuilders) {
+                String protocol = transportBuilder.protocol();
+                int port = transportBuilder.port();
+                int nbThreads = transportBuilder.nbThreads();
+                int backlog = transportBuilder.backlog();
+                final String address = bindAddress != null ? bindAddress : transportBuilder.address();
+
+                if (port == -1) {
+                    port = AvailablePortFinder.getNextAvailable(startPort);
+                    startPort = port + 1;
+                }
+
+                if (protocol.equalsIgnoreCase("TCP")) {
+                    Transport tcp = new TcpTransport(address, port, nbThreads, backlog);
+                    kdcServer.addTransports(tcp);
+                } else if (protocol.equalsIgnoreCase("UDP")) {
+                    UdpTransport udp = new UdpTransport(address, port);
+                    kdcServer.addTransports(udp);
+                } else {
+                    throw new IllegalArgumentException(I18n.err(I18n.ERR_689, protocol));
+                }
+            }
+        }
+
+        kdcServer.setDirectoryService(directoryService);
+
+        // Launch the server
+        try {
+            kdcServer.start();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return kdcServer;
+    }
+
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/GSSTestServer.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/GSSTestServer.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/GSSTestServer.java	(revision 0)
@@ -0,0 +1,234 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.MessageProp;
+import org.jboss.security.auth.callback.UsernamePasswordHandler;
+
+/**
+ * A sample server application for testing Kerberos identity propagation.
+ * 
+ * @author Josef Cacek
+ */
+public class GSSTestServer {
+
+    public static final String PROPERTY_PORT = "gsstestserver.port";
+    public static final String PROPERTY_PRINCIPAL = "gsstestserver.principal";
+    public static final String PROPERTY_PASSWORD = "gsstestserver.password";
+
+    public static final int PORT = Integer.getInteger(PROPERTY_PORT, 10961);
+    public static final String PRINCIPAL = System.getProperty(PROPERTY_PRINCIPAL, "gsstestserver/xxx@JBOSS.ORG");
+    public static final String PASSWORD = System.getProperty(PROPERTY_PASSWORD, "gsstestpwd");
+
+    public static final String CHAR_ENC = "UTF-8";
+    public static final int CMD_NOOP = 0;
+    public static final int CMD_NAME = 1;
+    public static final int CMD_STOP = 2;
+
+    public static final int SOCKET_TIMEOUT = 30 * 1000; //30s
+
+    // Public methods --------------------------------------------------------
+
+    /**
+     * The Main.
+     * 
+     * @param args
+     */
+    public static void main(String[] args) {
+        final GSSTestServer gssTestServer = new GSSTestServer();
+        if (args.length > 0 && "stop".equals(args[0])) {
+            gssTestServer.stop();
+        } else {
+            try {
+                gssTestServer.start();
+            } catch (Exception e) {
+                e.printStackTrace();
+                System.exit(1);
+            }
+        }
+    }
+
+    /**
+     * Sends STOP ({@link #CMD_STOP}) command to a running server.
+     */
+    private void stop() {
+        System.out.println("Sending STOP command GSSTestServer.");
+        // Create an unbound socket
+        final Socket socket = new Socket();
+        try {
+            socket.connect(new InetSocketAddress(InetAddress.getLocalHost(), PORT), SOCKET_TIMEOUT);
+            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
+            dos.writeInt(CMD_STOP);
+            dos.flush();
+            System.out.println("STOP command sent.");
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                socket.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Authenticates this server in Kerberos KDC.
+     * 
+     * @throws LoginException
+     * @throws PrivilegedActionException
+     */
+    private void start() throws LoginException, PrivilegedActionException {
+        System.out.println("Starting GSSTestServer - login");
+        // Use our custom configuration to avoid reliance on external config
+        Configuration.setConfiguration(new Configuration() {
+            @Override
+            public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+                final Map<String, Object> options = new HashMap<String, Object>();
+                options.put("refreshKrb5Config", "true");
+                options.put("storeKey", "true");
+                return new AppConfigurationEntry[] { new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
+                        AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) };
+            }
+
+        });
+        // 1. Authenticate to Kerberos.
+        final LoginContext lc = new LoginContext("foo", new UsernamePasswordHandler(PRINCIPAL, PASSWORD));
+        lc.login();
+        System.out.println("Authentication succeed");
+        // 2. Perform the work as authenticated Subject.
+        final String finishMsg = Subject.doAs(lc.getSubject(), new ServerAction());
+        System.out.println("Server stopped with result: " + (finishMsg == null ? "OK" : finishMsg));
+        lc.logout();
+
+    }
+
+    // Embedded classes ------------------------------------------------------
+    /**
+     * A ServerAction which creates a ServerSocket and waits for clients. It sends back the authenticated client name.
+     * 
+     * @author Josef Cacek
+     */
+    private class ServerAction implements PrivilegedAction<String> {
+
+        public String run() {
+            final GSSManager gssManager = GSSManager.getInstance();
+            try {
+                final ServerSocket serverSocket = new ServerSocket(PORT);
+                System.out.println("Server started on port " + PORT);
+                int command = CMD_NOOP;
+                do {
+                    Socket socket = null;
+                    GSSContext gssContext = null;
+                    try {
+                        System.out.println("Waiting for client connection");
+                        socket = serverSocket.accept();
+                        System.out.println("Client connected");
+                        gssContext = gssManager.createContext((GSSCredential) null);
+                        final DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
+                        final DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
+
+                        command = dataInputStream.readInt();
+                        System.out.println("Command code: " + command);
+                        if (command == CMD_NAME) {
+                            while (!gssContext.isEstablished()) {
+                                final byte[] inToken = new byte[dataInputStream.readInt()];
+                                dataInputStream.readFully(inToken);
+                                final byte[] outToken = gssContext.acceptSecContext(inToken, 0, inToken.length);
+
+                                if (outToken != null) {
+                                    dataOutputStream.writeInt(outToken.length);
+                                    dataOutputStream.write(outToken);
+                                    dataOutputStream.flush();
+                                }
+                            }
+                            final String clientName = gssContext.getSrcName().toString();
+                            System.out.println("Context Established with Client " + clientName);
+
+                            //encrypt
+                            final MessageProp msgProp = new MessageProp(true);
+                            final byte[] clientNameBytes = clientName.getBytes(CHAR_ENC);
+                            final byte[] outToken = gssContext.wrap(clientNameBytes, 0, clientNameBytes.length, msgProp);
+
+                            dataOutputStream.writeInt(outToken.length);
+                            dataOutputStream.write(outToken);
+                            dataOutputStream.flush();
+                            System.out.println("Client name was returned as the token value.");
+                        }
+                    } catch (EOFException e) {
+                        System.err.println("Client didn't send a correct message.");
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    } catch (GSSException e) {
+                        e.printStackTrace();
+                    } finally {
+                        if (gssContext != null) {
+                            try {
+                                gssContext.dispose();
+                            } catch (GSSException e) {
+                                e.printStackTrace();
+                            }
+                        }
+                        if (socket != null) {
+                            try {
+                                socket.close();
+                            } catch (IOException e) {
+                                e.printStackTrace();
+                            }
+                        }
+
+                    }
+                } while (command != CMD_STOP);
+                System.out.println("Stop command received.");
+            } catch (IOException e) {
+                e.printStackTrace();
+                return e.getMessage();
+            }
+            return null;
+        }
+
+    }
+
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/NullHCCredentials.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/NullHCCredentials.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/NullHCCredentials.java	(revision 0)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import java.security.Principal;
+
+import org.apache.http.auth.Credentials;
+
+/**
+ * An empty Apache HTTPClient {@link Credentials} implementation, used for SPNEGO authentications.
+ * 
+ * @author Josef Cacek
+ */
+public class NullHCCredentials implements Credentials {
+
+    // Public methods --------------------------------------------------------
+
+    /**
+     * Returns <code>null</code> as the Principal.
+     * 
+     * @return
+     * @see org.apache.http.auth.Credentials#getUserPrincipal()
+     */
+    public Principal getUserPrincipal() {
+        return null;
+    }
+
+    /**
+     * Returns <code>null</code> as the password.
+     * 
+     * @return
+     * @see org.apache.http.auth.Credentials#getPassword()
+     */
+    public String getPassword() {
+        return null;
+    }
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/KerberosServerControl.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/KerberosServerControl.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/KerberosServerControl.java	(revision 0)
@@ -0,0 +1,236 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.text.StrSubstitutor;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.ContextEntry;
+import org.apache.directory.server.core.annotations.CreateDS;
+import org.apache.directory.server.core.annotations.CreateIndex;
+import org.apache.directory.server.core.annotations.CreatePartition;
+import org.apache.directory.server.core.api.DirectoryService;
+import org.apache.directory.server.core.factory.DSAnnotationProcessor;
+import org.apache.directory.server.core.kerberos.KeyDerivationInterceptor;
+import org.apache.directory.server.kerberos.kdc.KdcServer;
+import org.apache.directory.shared.ldap.model.entry.DefaultEntry;
+import org.apache.directory.shared.ldap.model.ldif.LdifEntry;
+import org.apache.directory.shared.ldap.model.ldif.LdifReader;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Small application which starts/stops ApacheDS (directory service and Kerberos) and imports LDIFs provided as program
+ * arguments.
+ * <p>
+ * Use system property <code>kerberosControl.port</code> to change port on which is running this control process. The default is
+ * 10959.
+ * 
+ * @author Josef Cacek
+ */
+//@formatter:off
+@CreateDS( 
+  name = "JBossDS",
+  partitions =
+  {
+      @CreatePartition(
+          name = "jboss",
+          suffix = "dc=jboss,dc=org",
+          contextEntry = @ContextEntry( 
+              entryLdif =
+                  "dn: dc=jboss,dc=org\n" +
+                  "dc: jboss\n" +
+                  "objectClass: top\n" +
+                  "objectClass: domain\n\n" ),
+          indexes = 
+          {
+              @CreateIndex( attribute = "objectClass" ),
+              @CreateIndex( attribute = "dc" ),
+              @CreateIndex( attribute = "ou" )
+          })
+  },
+  additionalInterceptors = { KeyDerivationInterceptor.class })     
+@ExtCreateKdcServer(primaryRealm = "JBOSS.ORG",
+  kdcPrincipal = "krbtgt/JBOSS.ORG@JBOSS.ORG",
+  searchBaseDn = "dc=jboss,dc=org",
+  transports = 
+  { 
+      @CreateTransport(protocol = "UDP", port = 6088)
+  })
+//@formatter:on
+public class KerberosServerControl {
+
+    private static Logger LOGGER = LoggerFactory.getLogger(KerberosServerControl.class);
+    private static final int SOCKET_TIMEOUT = 2000; // 2 seconds
+
+    public static final String STOP_CMD = "stop";
+    public static final int SERVER_PORT = Integer.getInteger("kerberosControl.port", 10959);
+
+    private DirectoryService directoryService;
+    private KdcServer kdcServer;
+    private final String canonicalHost;
+
+    // Constructors ----------------------------------------------------------
+    /**
+     * Create a new KerberosServerControl.
+     */
+    public KerberosServerControl() {
+        canonicalHost = getCannonicalHost(System.getProperty("kerberos.bind.address", "localhost"));
+    }
+
+    // Public methods --------------------------------------------------------
+
+    /**
+     * The main.
+     * 
+     * @param args
+     */
+    public static void main(String[] args) {
+        try {
+            if (args.length == 1 && STOP_CMD.equals(args[0])) {
+                System.out.println("Sending STOP command to Kerberos controll process.");
+                SocketAddress sockaddr = new InetSocketAddress(InetAddress.getLocalHost(), SERVER_PORT);
+                // Create an unbound socket
+                Socket sock = new Socket();
+                sock.connect(sockaddr, SOCKET_TIMEOUT);
+                BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
+                wr.write(STOP_CMD);
+                wr.close();
+                sock.close();
+            } else {
+                System.out.println("Starting Kerberos controll process.");
+                KerberosServerControl ns = new KerberosServerControl();
+                ns.startKDC(args);
+                ns.waitForStop();
+                ns.stopKDC();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+    }
+
+    // Protected methods -----------------------------------------------------
+
+    /**
+     * Creates a server socket and only waits for the stop command from a client.
+     * 
+     * @throws Exception
+     */
+    protected void waitForStop() throws Exception {
+        final ServerSocket srv = new ServerSocket(SERVER_PORT);
+        boolean isStop = false;
+        do {
+            // Wait for connection from client.
+            Socket socket = srv.accept();
+            System.out.println("Incomming connection.");
+            socket.setSoTimeout(SOCKET_TIMEOUT);
+            BufferedReader rd = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+            try {
+                isStop = STOP_CMD.equals(rd.readLine());
+            } finally {
+                rd.close();
+            }
+            System.out.println("Stop command: " + isStop);
+            socket.close();
+        } while (!isStop);
+    }
+
+    /**
+     * Creates and starts ApacheDS services.
+     * 
+     * @param args
+     * @throws Exception
+     */
+    protected void startKDC(final String[] args) throws Exception {
+        directoryService = DSAnnotationProcessor.getDirectoryService();
+
+        if (args != null && args.length > 0) {
+            final Map<String, String> map = new HashMap<String, String>();
+            map.put("hostname", canonicalHost);
+            for (String ldifFile : args) {
+
+                final String ldifContent = StrSubstitutor.replace(FileUtils.readFileToString(new File(ldifFile), "UTF-8"), map);
+                LOGGER.debug(ldifContent);
+                final SchemaManager schemaManager = directoryService.getSchemaManager();
+                try {
+                    for (LdifEntry ldifEntry : new LdifReader(IOUtils.toInputStream(ldifContent))) {
+                        directoryService.getAdminSession().add(new DefaultEntry(schemaManager, ldifEntry.getEntry()));
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    throw e;
+                }
+            }
+        }
+        kdcServer = KDCServerAnnotationProcessor.getKdcServer(directoryService, 1024, canonicalHost);
+    }
+
+    /**
+     * Stops ApacheDS services and does some clean-up.
+     * 
+     * @throws Exception
+     */
+    protected void stopKDC() throws Exception {
+        System.out.println("Stopping Kerberos server.");
+        kdcServer.stop();
+        System.out.println("Stopping Directory service.");
+        directoryService.shutdown();
+        System.out.println("Removing Directory service workfiles.");
+        FileUtils.deleteDirectory(directoryService.getInstanceLayout().getInstanceDirectory());
+    }
+
+    // Private methods -------------------------------------------------------
+
+    /**
+     * Returns canonical hostname form of the given host address.
+     * 
+     * @param host address
+     * @return
+     */
+    private static final String getCannonicalHost(String host) {
+        try {
+            host = InetAddress.getByName(host).getCanonicalHostName();
+        } catch (UnknownHostException e) {
+            LOGGER.warn("Unable to get cannonical host name", e);
+        }
+        return host.toLowerCase(Locale.ENGLISH);
+    }
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/JBossNegotiateScheme.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/JBossNegotiateScheme.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/JBossNegotiateScheme.java	(revision 0)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import org.apache.http.impl.auth.SPNegoScheme;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+
+/**
+ * SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) authentication scheme. It's based on SPNegoScheme class from
+ * Apache HC, but fixes DEFAULT_LIFETIME problem with IBM JDK.
+ * 
+ * @author Josef Cacek
+ */
+public class JBossNegotiateScheme extends SPNegoScheme {
+
+    /** The DEFAULT_LIFETIME */
+    private static final int DEFAULT_LIFETIME = 5 * 60;
+
+    /**
+     * Create a new JBossNegotiateScheme.
+     * 
+     */
+    public JBossNegotiateScheme() {
+        super();
+    }
+
+    /**
+     * Create a new JBossNegotiateScheme.
+     * 
+     * @param stripPort
+     */
+    public JBossNegotiateScheme(boolean stripPort) {
+        super(stripPort);
+    }
+
+    /**
+     * 
+     * @param input
+     * @param oid
+     * @param authServer
+     * @return
+     * @throws GSSException
+     * @see org.apache.http.impl.auth.GGSSchemeBase#generateGSSToken(byte[], org.ietf.jgss.Oid, java.lang.String)
+     */
+    @Override
+    protected byte[] generateGSSToken(final byte[] input, final Oid oid, final String authServer) throws GSSException {
+        byte[] token = input;
+        if (token == null) {
+            token = new byte[0];
+        }
+        GSSManager manager = getManager();
+        GSSName serverName = manager.createName("HTTP@" + authServer, GSSName.NT_HOSTBASED_SERVICE);
+        GSSContext gssContext = manager.createContext(serverName.canonicalize(oid), oid, null, DEFAULT_LIFETIME);
+        gssContext.requestMutualAuth(true);
+        gssContext.requestCredDeleg(true);
+        return gssContext.initSecContext(token, 0, token.length);
+    }
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/AnnotationLiteral.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/AnnotationLiteral.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/AnnotationLiteral.java	(revision 0)
@@ -0,0 +1,276 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.test.security.negotiation;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+
+/**
+ * <p>
+ * Supports inline instantiation of annotation type instances. Originally comes the implementation from the JBoss AS 7
+ * implementation of CDI API.
+ * </p>
+ * 
+ * <p>
+ * An instance of an annotation type may be obtained by subclassing <tt>AnnotationLiteral</tt>.
+ * </p>
+ * 
+ * <pre>
+ * public abstract class PayByQualifier extends AnnotationLiteral&lt;PayBy&gt; implements PayBy {
+ * }
+ * </pre>
+ * 
+ * <pre>
+ * PayBy paybyCheque = new PayByQualifier() {
+ *     public PaymentMethod value() {
+ *         return CHEQUE;
+ *     }
+ * };
+ * </pre>
+ * 
+ * @author Pete Muir
+ * @author Gavin King
+ */
+public abstract class AnnotationLiteral<T extends Annotation> implements Annotation, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private transient Class<T> annotationType;
+    private transient Method[] members;
+
+    protected AnnotationLiteral() {
+    }
+
+    private Method[] getMembers() {
+        if (members == null) {
+            members = annotationType().getDeclaredMethods();
+            if (members.length > 0 && !annotationType().isAssignableFrom(this.getClass())) {
+                throw new RuntimeException(getClass() + " does not implement the annotation type with members "
+                        + annotationType().getName());
+            }
+        }
+        return members;
+    }
+
+    private static Class<?> getAnnotationLiteralSubclass(Class<?> clazz) {
+        Class<?> superclass = clazz.getSuperclass();
+        if (superclass.equals(AnnotationLiteral.class)) {
+            return clazz;
+        } else if (superclass.equals(Object.class)) {
+            return null;
+        } else {
+            return (getAnnotationLiteralSubclass(superclass));
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> Class<T> getTypeParameter(Class<?> annotationLiteralSuperclass) {
+        Type type = annotationLiteralSuperclass.getGenericSuperclass();
+        if (type instanceof ParameterizedType) {
+            ParameterizedType parameterizedType = (ParameterizedType) type;
+            if (parameterizedType.getActualTypeArguments().length == 1) {
+                return (Class<T>) parameterizedType.getActualTypeArguments()[0];
+            }
+        }
+        return null;
+    }
+
+    public Class<? extends Annotation> annotationType() {
+        if (annotationType == null) {
+            Class<?> annotationLiteralSubclass = getAnnotationLiteralSubclass(this.getClass());
+            if (annotationLiteralSubclass == null) {
+                throw new RuntimeException(getClass() + "is not a subclass of AnnotationLiteral");
+            }
+            annotationType = getTypeParameter(annotationLiteralSubclass);
+            if (annotationType == null) {
+                throw new RuntimeException(getClass() + " does not specify the type parameter T of AnnotationLiteral<T>");
+            }
+        }
+        return annotationType;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder string = new StringBuilder();
+        string.append('@').append(annotationType().getName()).append('(');
+        for (int i = 0; i < getMembers().length; i++) {
+            string.append(getMembers()[i].getName()).append('=');
+            Object value = invoke(getMembers()[i], this);
+            assertMemberValueNotNull(getMembers()[i], this, value);
+            if (value instanceof boolean[]) {
+                appendInBraces(string, Arrays.toString((boolean[]) value));
+            } else if (value instanceof byte[]) {
+                appendInBraces(string, Arrays.toString((byte[]) value));
+            } else if (value instanceof short[]) {
+                appendInBraces(string, Arrays.toString((short[]) value));
+            } else if (value instanceof int[]) {
+                appendInBraces(string, Arrays.toString((int[]) value));
+            } else if (value instanceof long[]) {
+                appendInBraces(string, Arrays.toString((long[]) value));
+            } else if (value instanceof float[]) {
+                appendInBraces(string, Arrays.toString((float[]) value));
+            } else if (value instanceof double[]) {
+                appendInBraces(string, Arrays.toString((double[]) value));
+            } else if (value instanceof char[]) {
+                appendInBraces(string, Arrays.toString((char[]) value));
+            } else if (value instanceof String[]) {
+                String[] strings = (String[]) value;
+                String[] quoted = new String[strings.length];
+                for (int j = 0; j < strings.length; j++) {
+                    quoted[j] = "\"" + strings[j] + "\"";
+                }
+                appendInBraces(string, Arrays.toString(quoted));
+            } else if (value instanceof Class<?>[]) {
+                Class<?>[] classes = (Class<?>[]) value;
+                String[] names = new String[classes.length];
+                for (int j = 0; j < classes.length; j++) {
+                    names[j] = classes[j].getName() + ".class";
+                }
+                appendInBraces(string, Arrays.toString(names));
+            } else if (value instanceof Object[]) {
+                appendInBraces(string, Arrays.toString((Object[]) value));
+            } else if (value instanceof String) {
+                string.append('"').append(value).append('"');
+            } else if (value instanceof Class<?>) {
+                string.append(((Class<?>) value).getName()).append(".class");
+            } else {
+                string.append(value);
+            }
+            if (i < getMembers().length - 1) {
+                string.append(", ");
+            }
+        }
+        return string.append(')').toString();
+    }
+
+    private void appendInBraces(StringBuilder buf, String s) {
+        buf.append('{').append(s.substring(1, s.length() - 1)).append('}');
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof Annotation) {
+            Annotation that = (Annotation) other;
+            if (this.annotationType().equals(that.annotationType())) {
+                for (Method member : getMembers()) {
+                    Object thisValue = invoke(member, this);
+                    assertMemberValueNotNull(member, this, thisValue);
+                    Object thatValue = invoke(member, that);
+                    assertMemberValueNotNull(member, this, thatValue);
+                    if (thisValue instanceof byte[] && thatValue instanceof byte[]) {
+                        if (!Arrays.equals((byte[]) thisValue, (byte[]) thatValue))
+                            return false;
+                    } else if (thisValue instanceof short[] && thatValue instanceof short[]) {
+                        if (!Arrays.equals((short[]) thisValue, (short[]) thatValue))
+                            return false;
+                    } else if (thisValue instanceof int[] && thatValue instanceof int[]) {
+                        if (!Arrays.equals((int[]) thisValue, (int[]) thatValue))
+                            return false;
+                    } else if (thisValue instanceof long[] && thatValue instanceof long[]) {
+                        if (!Arrays.equals((long[]) thisValue, (long[]) thatValue))
+                            return false;
+                    } else if (thisValue instanceof float[] && thatValue instanceof float[]) {
+                        if (!Arrays.equals((float[]) thisValue, (float[]) thatValue))
+                            return false;
+                    } else if (thisValue instanceof double[] && thatValue instanceof double[]) {
+                        if (!Arrays.equals((double[]) thisValue, (double[]) thatValue))
+                            return false;
+                    } else if (thisValue instanceof char[] && thatValue instanceof char[]) {
+                        if (!Arrays.equals((char[]) thisValue, (char[]) thatValue))
+                            return false;
+                    } else if (thisValue instanceof boolean[] && thatValue instanceof boolean[]) {
+                        if (!Arrays.equals((boolean[]) thisValue, (boolean[]) thatValue))
+                            return false;
+                    } else if (thisValue instanceof Object[] && thatValue instanceof Object[]) {
+                        if (!Arrays.equals((Object[]) thisValue, (Object[]) thatValue))
+                            return false;
+                    } else {
+                        if (!thisValue.equals(thatValue))
+                            return false;
+                    }
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        int hashCode = 0;
+        for (Method member : getMembers()) {
+            int memberNameHashCode = 127 * member.getName().hashCode();
+            Object value = invoke(member, this);
+            assertMemberValueNotNull(member, this, value);
+            int memberValueHashCode;
+            if (value instanceof boolean[]) {
+                memberValueHashCode = Arrays.hashCode((boolean[]) value);
+            } else if (value instanceof short[]) {
+                memberValueHashCode = Arrays.hashCode((short[]) value);
+            } else if (value instanceof int[]) {
+                memberValueHashCode = Arrays.hashCode((int[]) value);
+            } else if (value instanceof long[]) {
+                memberValueHashCode = Arrays.hashCode((long[]) value);
+            } else if (value instanceof float[]) {
+                memberValueHashCode = Arrays.hashCode((float[]) value);
+            } else if (value instanceof double[]) {
+                memberValueHashCode = Arrays.hashCode((double[]) value);
+            } else if (value instanceof byte[]) {
+                memberValueHashCode = Arrays.hashCode((byte[]) value);
+            } else if (value instanceof char[]) {
+                memberValueHashCode = Arrays.hashCode((char[]) value);
+            } else if (value instanceof Object[]) {
+                memberValueHashCode = Arrays.hashCode((Object[]) value);
+            } else {
+                memberValueHashCode = value.hashCode();
+            }
+            hashCode += memberNameHashCode ^ memberValueHashCode;
+        }
+        return hashCode;
+    }
+
+    private static Object invoke(Method method, Object instance) {
+        try {
+            if (!method.isAccessible())
+                method.setAccessible(true);
+            return method.invoke(instance);
+        } catch (IllegalArgumentException e) {
+            throw new RuntimeException("Error checking value of member method " + method.getName() + " on "
+                    + method.getDeclaringClass(), e);
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException("Error checking value of member method " + method.getName() + " on "
+                    + method.getDeclaringClass(), e);
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException("Error checking value of member method " + method.getName() + " on "
+                    + method.getDeclaringClass(), e);
+        }
+    }
+
+    private static void assertMemberValueNotNull(Method member, Annotation instance, Object value) {
+        if (value == null) {
+            throw new IllegalArgumentException("Annotation member " + instance.getClass().getName() + "." + member.getName()
+                    + " must not be null");
+        }
+    }
+
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/ManagedCreateLdapServer.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/ManagedCreateLdapServer.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/ManagedCreateLdapServer.java	(revision 0)
@@ -0,0 +1,325 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.annotations.SaslMechanism;
+
+/**
+ * A helper implementation of {@link CreateLdapServer} annotation which allows to configure values.
+ * 
+ * @author Josef Cacek
+ */
+public class ManagedCreateLdapServer extends AnnotationLiteral<CreateLdapServer> implements CreateLdapServer {
+
+    private static final long serialVersionUID = 1L;
+
+    /** The instance name */
+    private String name;
+    /** The transports to use, default to LDAP */
+    private CreateTransport[] transports;
+    /** The LdapServer factory */
+    private Class<?> factory;
+    /** The maximum size limit. */
+    private long maxSizeLimit;
+    /** The maximum time limit. */
+    private int maxTimeLimit;
+    /** Tells if anonymous access are allowed or not. */
+    private boolean allowAnonymousAccess;
+    /** The external keyStore file to use, default to the empty string */
+    private String keyStore;
+    /** The certificate password in base64, default to the empty string */
+    private String certificatePassword;
+    /** name of the classes implementing extended operations */
+    private Class<?>[] extendedOpHandlers;
+    /** supported set of SASL mechanisms */
+    private SaslMechanism[] saslMechanisms;
+    /** NTLM provider class, default value is a invalid class */
+    private Class<?> ntlmProvider;
+    /** The name of this host, validated during SASL negotiation. */
+    private String saslHost;
+    /** The service principal, used by GSSAPI. */
+    private String saslPrincipal;
+
+    // Constructors ----------------------------------------------------------
+
+    /**
+     * Create a new ManagedCreateLdapServer.
+     * 
+     * @param createLdapServer
+     * @param saslHost
+     * @param saslPrincipal
+     */
+    public ManagedCreateLdapServer(CreateLdapServer createLdapServer) {
+        name = createLdapServer.name();
+        transports = createLdapServer.transports();
+        factory = createLdapServer.factory();
+        maxSizeLimit = createLdapServer.maxSizeLimit();
+        maxTimeLimit = createLdapServer.maxTimeLimit();
+        allowAnonymousAccess = createLdapServer.allowAnonymousAccess();
+        keyStore = createLdapServer.keyStore();
+        certificatePassword = createLdapServer.certificatePassword();
+        extendedOpHandlers = createLdapServer.extendedOpHandlers();
+        saslMechanisms = createLdapServer.saslMechanisms();
+        ntlmProvider = createLdapServer.ntlmProvider();
+        saslHost = createLdapServer.saslHost();
+        saslPrincipal = createLdapServer.saslPrincipal();
+    }
+
+    // Public methods --------------------------------------------------------
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#name()
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#transports()
+     */
+    public CreateTransport[] transports() {
+        return transports;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#factory()
+     */
+    public Class<?> factory() {
+        return factory;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#maxSizeLimit()
+     */
+    public long maxSizeLimit() {
+        return maxSizeLimit;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#maxTimeLimit()
+     */
+    public int maxTimeLimit() {
+        return maxTimeLimit;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#allowAnonymousAccess()
+     */
+    public boolean allowAnonymousAccess() {
+        return allowAnonymousAccess;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#keyStore()
+     */
+    public String keyStore() {
+        return keyStore;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#certificatePassword()
+     */
+    public String certificatePassword() {
+        return certificatePassword;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#extendedOpHandlers()
+     */
+    public Class<?>[] extendedOpHandlers() {
+        return extendedOpHandlers;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#saslMechanisms()
+     */
+    public SaslMechanism[] saslMechanisms() {
+        return saslMechanisms;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#ntlmProvider()
+     */
+    public Class<?> ntlmProvider() {
+        return ntlmProvider;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#saslHost()
+     */
+    public String saslHost() {
+        return saslHost;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateLdapServer#saslPrincipal()
+     */
+    public String saslPrincipal() {
+        return saslPrincipal;
+    }
+
+    /**
+     * Set the name.
+     * 
+     * @param name The name to set.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Set the transports.
+     * 
+     * @param transports The transports to set.
+     */
+    public void setTransports(CreateTransport[] transports) {
+        this.transports = transports;
+    }
+
+    /**
+     * Set the factory.
+     * 
+     * @param factory The factory to set.
+     */
+    public void setFactory(Class<?> factory) {
+        this.factory = factory;
+    }
+
+    /**
+     * Set the maxSizeLimit.
+     * 
+     * @param maxSizeLimit The maxSizeLimit to set.
+     */
+    public void setMaxSizeLimit(long maxSizeLimit) {
+        this.maxSizeLimit = maxSizeLimit;
+    }
+
+    /**
+     * Set the maxTimeLimit.
+     * 
+     * @param maxTimeLimit The maxTimeLimit to set.
+     */
+    public void setMaxTimeLimit(int maxTimeLimit) {
+        this.maxTimeLimit = maxTimeLimit;
+    }
+
+    /**
+     * Set the allowAnonymousAccess.
+     * 
+     * @param allowAnonymousAccess The allowAnonymousAccess to set.
+     */
+    public void setAllowAnonymousAccess(boolean allowAnonymousAccess) {
+        this.allowAnonymousAccess = allowAnonymousAccess;
+    }
+
+    /**
+     * Set the keyStore.
+     * 
+     * @param keyStore The keyStore to set.
+     */
+    public void setKeyStore(String keyStore) {
+        this.keyStore = keyStore;
+    }
+
+    /**
+     * Set the certificatePassword.
+     * 
+     * @param certificatePassword The certificatePassword to set.
+     */
+    public void setCertificatePassword(String certificatePassword) {
+        this.certificatePassword = certificatePassword;
+    }
+
+    /**
+     * Set the extendedOpHandlers.
+     * 
+     * @param extendedOpHandlers The extendedOpHandlers to set.
+     */
+    public void setExtendedOpHandlers(Class<?>[] extendedOpHandlers) {
+        this.extendedOpHandlers = extendedOpHandlers;
+    }
+
+    /**
+     * Set the saslMechanisms.
+     * 
+     * @param saslMechanisms The saslMechanisms to set.
+     */
+    public void setSaslMechanisms(SaslMechanism[] saslMechanisms) {
+        this.saslMechanisms = saslMechanisms;
+    }
+
+    /**
+     * Set the ntlmProvider.
+     * 
+     * @param ntlmProvider The ntlmProvider to set.
+     */
+    public void setNtlmProvider(Class<?> ntlmProvider) {
+        this.ntlmProvider = ntlmProvider;
+    }
+
+    /**
+     * Set the saslHost.
+     * 
+     * @param saslHost The saslHost to set.
+     */
+    public void setSaslHost(String saslHost) {
+        this.saslHost = saslHost;
+    }
+
+    /**
+     * Set the saslPrincipal.
+     * 
+     * @param saslPrincipal The saslPrincipal to set.
+     */
+    public void setSaslPrincipal(String saslPrincipal) {
+        this.saslPrincipal = saslPrincipal;
+    }
+
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/GSSTestClient.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/GSSTestClient.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/GSSTestClient.java	(revision 0)
@@ -0,0 +1,139 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.MessageProp;
+import org.ietf.jgss.Oid;
+
+/**
+ * A client for {@link GSSTestServer}.
+ * 
+ * @author Josef Cacek
+ */
+public class GSSTestClient {
+
+    private final static Oid KRB5_OID;
+    static {
+        try {
+            KRB5_OID = new Oid("1.2.840.113554.1.2.2");
+        } catch (GSSException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private final String host;
+    private final int port;
+    private final String spn;
+
+    // Constructors ----------------------------------------------------------
+
+    /**
+     * Create a new GSSTestClient.
+     * 
+     * @param serverHost
+     * @param serverPort
+     * @param spn Service Principal Name
+     */
+    public GSSTestClient(String serverHost, int serverPort, String spn) {
+        this.host = serverHost;
+        this.port = serverPort;
+        this.spn = spn;
+    }
+
+    // Public methods --------------------------------------------------------
+
+    /**
+     * Retrieves the name of calling identity (based on given gssCredential) retrieved from {@link GSSTestServer}.
+     * 
+     * @param gssCredential
+     * @return
+     * @throws IOException
+     * @throws GSSException
+     */
+    public String getName(final GSSCredential gssCredential) throws IOException, GSSException {
+        // Create an unbound socket
+        System.out.println("GSSCredential used:\n" + gssCredential);
+        final Socket socket = new Socket();
+        GSSContext gssContext = null;
+        try {
+            socket.connect(new InetSocketAddress(host, port), GSSTestServer.SOCKET_TIMEOUT);
+            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
+            DataInputStream dis = new DataInputStream(socket.getInputStream());
+            System.out.println("Sending NAME command.");
+            dos.writeInt(GSSTestServer.CMD_NAME);
+            dos.flush();
+
+            GSSManager manager = GSSManager.getInstance();
+            gssContext = manager.createContext(manager.createName(spn, null), KRB5_OID, gssCredential,
+                    GSSContext.DEFAULT_LIFETIME);
+
+            //            gssContext.requestCredDeleg(true);
+            gssContext.requestMutualAuth(true);
+            gssContext.requestConf(true);
+            gssContext.requestInteg(true);
+
+            byte[] token = new byte[0];
+            while (!gssContext.isEstablished()) {
+                token = gssContext.initSecContext(token, 0, token.length);
+                if (token != null) {
+                    dos.writeInt(token.length);
+                    dos.write(token);
+                    dos.flush();
+                }
+                if (!gssContext.isEstablished()) {
+                    token = new byte[dis.readInt()];
+                    dis.readFully(token);
+                }
+            }
+
+            token = new byte[dis.readInt()];
+            dis.readFully(token);
+            MessageProp msgProp = new MessageProp(false);
+            final byte[] nameBytes = gssContext.unwrap(token, 0, token.length, msgProp);
+            return new String(nameBytes, GSSTestServer.CHAR_ENC);
+        } finally {
+            try {
+                socket.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            if (gssContext != null) {
+                try {
+                    gssContext.dispose();
+                } catch (GSSException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+}
Index: testsuite/src/main/org/jboss/test/security/negotiation/ExtCreateKdcServer.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/ExtCreateKdcServer.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/ExtCreateKdcServer.java	(revision 0)
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.directory.server.annotations.CreateTransport;
+
+/**
+ * A annotation used to define a KDC server configuration. This is only a copy of an original
+ * {@link org.apache.directory.server.annotations.CreateKdcServer} annotation, which adds {@link #searchBaseDn()} attribute.
+ * It's only a workaround for ApacheDS issue https://issues.apache.org/jira/browse/DIRKRB-85
+ * 
+ * @author Josef Cacek
+ * @see KDCServerAnnotationProcessor
+ */
+@Documented
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD, ElementType.TYPE })
+public @interface ExtCreateKdcServer {
+    /** The instance name */
+    String name() default "DefaultKrbServer";
+
+    /** The transports to use, default to LDAP */
+    CreateTransport[] transports() default {};
+
+    /** The default kdc realm */
+    String primaryRealm() default "EXAMPLE.COM";
+
+    String searchBaseDn() default "ou=users,dc=example,dc=com";
+
+    /** The default kdc service principal */
+    String kdcPrincipal() default "krbtgt/EXAMPLE.COM@EXAMPLE.COM";
+
+    /** The maximum ticket lifetime. */
+    long maxTicketLifetime() default 24 * 60 * 60 * 1000; //default = 1 day
+
+    /** The maximum renewable lifetime. */
+    long maxRenewableLifetime() default 7 * 24 * 60 * 60 * 1000; //default = 7 days
+}
\ No newline at end of file
Index: testsuite/src/main/org/jboss/test/security/negotiation/JBossNegotiateSchemeFactory.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/JBossNegotiateSchemeFactory.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/JBossNegotiateSchemeFactory.java	(revision 0)
@@ -0,0 +1,50 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import org.apache.http.annotation.Immutable;
+import org.apache.http.auth.AuthScheme;
+import org.apache.http.impl.auth.SPNegoSchemeFactory;
+import org.apache.http.params.HttpParams;
+
+/**
+ * SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) authentication scheme factory. Provides
+ * {@link JBossNegotiateScheme} instances.
+ * 
+ * @author Josef Cacek
+ */
+@Immutable
+public class JBossNegotiateSchemeFactory extends SPNegoSchemeFactory {
+
+    // Constructors ----------------------------------------------------------
+
+    public JBossNegotiateSchemeFactory(boolean stripPort) {
+        super(stripPort);
+    }
+
+    // Public methods --------------------------------------------------------
+
+    @Override
+    public AuthScheme newInstance(final HttpParams params) {
+        return new JBossNegotiateScheme(isStripPort());
+    }
+}
\ No newline at end of file
Index: testsuite/src/main/org/jboss/test/security/negotiation/ManagedCreateTransport.java
===================================================================
--- testsuite/src/main/org/jboss/test/security/negotiation/ManagedCreateTransport.java	(revision 0)
+++ testsuite/src/main/org/jboss/test/security/negotiation/ManagedCreateTransport.java	(revision 0)
@@ -0,0 +1,195 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.security.negotiation;
+
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.annotations.TransportType;
+
+/**
+ * A helper implementation of {@link CreateTransport} annotation which allows to configure values.
+ * 
+ * @author Josef Cacek
+ */
+public class ManagedCreateTransport extends AnnotationLiteral<CreateTransport> implements CreateTransport {
+
+    private static final long serialVersionUID = 1L;
+
+    /** The name for this protocol */
+    private String protocol;
+    /** The transport type (TCP or UDP) Default to TCP */
+    private TransportType type;
+    /** The port to use, default to a bad value so that we know we have to pick one random available port */
+    private int port;
+    /** The InetAddress for this transport. Default to localhost */
+    private String address;
+    /** The backlog. Default to 50 */
+    private int backlog;
+    /** A flag to tell if the transport is SSL based. Default to false */
+    private boolean ssl;
+    /** The number of threads to use. Default to 3 */
+    private int nbThreads;
+
+    // Constructors ----------------------------------------------------------
+
+    /**
+     * Create a new ManagedCreateTransport.
+     * 
+     * @param createLdapServer
+     */
+    public ManagedCreateTransport(final CreateTransport original) {
+        protocol = original.protocol();
+        type = original.type();
+        port = original.port();
+        address = original.address();
+        backlog = original.backlog();
+        ssl = original.ssl();
+        nbThreads = original.nbThreads();
+    }
+
+    // Public methods --------------------------------------------------------
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateTransport#protocol()
+     */
+    public String protocol() {
+        return protocol;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateTransport#type()
+     */
+    public TransportType type() {
+        return type;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateTransport#port()
+     */
+    public int port() {
+        return port;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateTransport#address()
+     */
+    public String address() {
+        return address;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateTransport#backlog()
+     */
+    public int backlog() {
+        return backlog;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateTransport#ssl()
+     */
+    public boolean ssl() {
+        return ssl;
+    }
+
+    /**
+     * 
+     * @return
+     * @see org.apache.directory.server.annotations.CreateTransport#nbThreads()
+     */
+    public int nbThreads() {
+        return nbThreads;
+    }
+
+    /**
+     * Set the protocol.
+     * 
+     * @param protocol The protocol to set.
+     */
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    /**
+     * Set the type.
+     * 
+     * @param type The type to set.
+     */
+    public void setType(TransportType type) {
+        this.type = type;
+    }
+
+    /**
+     * Set the port.
+     * 
+     * @param port The port to set.
+     */
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    /**
+     * Set the address.
+     * 
+     * @param address The address to set.
+     */
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    /**
+     * Set the backlog.
+     * 
+     * @param backlog The backlog to set.
+     */
+    public void setBacklog(int backlog) {
+        this.backlog = backlog;
+    }
+
+    /**
+     * Set the ssl.
+     * 
+     * @param ssl The ssl to set.
+     */
+    public void setSsl(boolean ssl) {
+        this.ssl = ssl;
+    }
+
+    /**
+     * Set the nbThreads.
+     * 
+     * @param nbThreads The nbThreads to set.
+     */
+    public void setNbThreads(int nbThreads) {
+        this.nbThreads = nbThreads;
+    }
+}

Property changes on: thirdparty
___________________________________________________________________
Modified: svn:ignore
   - antlr
apache-avalon
apache-avalon-logkit
apache-bcel
apache-beanutils
apache-bsf
apache-codec
apache-collections
apache-digester
apache-discovery
apache-fileupload
apache-httpclient
apache-jaxme
apache-lang
apache-log4j
apache-logging
apache-modeler
apache-myfaces
apache-pool
apache-scout
apache-slide
apache-struts
apache-taglibs
apache-tomcat
apache-validator
apache-velocity
apache-vfs
apache-xalan
apache-xerces
apache-xmlsec
asm
beanshell
cglib
codehaus-stax
commons-el
dom4j
easymock
ehcache
gjt-jpl-util
gnu-getopt
hibernate
hibernate-annotations
hibernate-entitymanager
hibernate-validator
hsqldb
ibm-wsdl4j
jacorb
javassist
jaxen
jboss
jbpm
jbpm-bpel
jfreechart
jgroups
joesnmp
juddi
junit
junitejb
licenses
objectweb-joramtests
odmg
opensaml
oswego-concurrent
qdox
quartz
sleepycat
spring
struts-test-case
sun-jaf
sun-javacc
sun-javamail
sun-jaxb
sun-jaxp
sun-jmf
sun-jmx
sun-jsf
sun-jstl
sun-servlet
sun-xacml
target
trove
validation-api
wutka-dtdparser
xdoclet
xmlunit-xmlunit
libraries.ent
sun-opends
testsuite-libraries.ent
woodstox
stax-api
httpunit
nekohtml
sun-jaxws
snmptrapappender
wscommons-policy
hibernate-commons-annotations
hibernate-validator
apache-maven-ant-tasks
osgi
sun-fi
xalan
struts
javax
bsh
rhino
xerces
aopalliance
log4j
ant
org
commons-validator
oro
commons-io
jtidy
net
xml-apis
commons-logging
classworlds
urbanophile
tjws
com
xml-security
stax
webbeans-deployer
dependency-maven-plugin-markers
hibernate-validator-legacy
weld-deployer
saaj
jsr181
regexp
jaxws

   + antlr
apache-avalon
apache-avalon-logkit
apache-bcel
apache-beanutils
apache-bsf
apache-codec
apache-collections
apache-digester
apache-discovery
apache-fileupload
apache-httpclient
apache-jaxme
apache-lang
apache-log4j
apache-logging
apache-modeler
apache-myfaces
apache-pool
apache-scout
apache-slide
apache-struts
apache-taglibs
apache-tomcat
apache-validator
apache-velocity
apache-vfs
apache-xalan
apache-xerces
apache-xmlsec
asm
beanshell
cglib
codehaus-stax
commons-el
dom4j
easymock
ehcache
gjt-jpl-util
gnu-getopt
hibernate
hibernate-annotations
hibernate-entitymanager
hibernate-validator
hsqldb
ibm-wsdl4j
jacorb
javassist
jaxen
jboss
jbpm
jbpm-bpel
jfreechart
jgroups
joesnmp
juddi
junit
junitejb
licenses
objectweb-joramtests
odmg
opensaml
oswego-concurrent
qdox
quartz
sleepycat
spring
struts-test-case
sun-jaf
sun-javacc
sun-javamail
sun-jaxb
sun-jaxp
sun-jmf
sun-jmx
sun-jsf
sun-jstl
sun-servlet
sun-xacml
target
trove
validation-api
wutka-dtdparser
xdoclet
xmlunit-xmlunit
libraries.ent
sun-opends
testsuite-libraries.ent
woodstox
stax-api
httpunit
nekohtml
sun-jaxws
snmptrapappender
wscommons-policy
hibernate-commons-annotations
hibernate-validator
apache-maven-ant-tasks
osgi
sun-fi
xalan
struts
javax
bsh
rhino
xerces
aopalliance
log4j
ant
org
commons-validator
oro
commons-io
jtidy
net
xml-apis
commons-logging
classworlds
urbanophile
tjws
com
xml-security
stax
webbeans-deployer
dependency-maven-plugin-markers
hibernate-validator-legacy
weld-deployer
saaj
jsr181
regexp
jaxws
apacheds
apache-httpcomponents


Index: thirdparty/pom.xml
===================================================================
--- thirdparty/pom.xml	(revision 113475)
+++ thirdparty/pom.xml	(working copy)
@@ -1110,7 +1110,35 @@
                  <componentId>jacorb</componentId>
               </mapping>
            </dependency>
-            <!-- End mapped dependecies -->
+           <dependency>
+             <groupId>org.apache.directory.server</groupId>
+             <artifactId>apacheds-all</artifactId>
+             <mapping>
+               <componentId>apacheds</componentId>
+             </mapping>
+           </dependency>
+           <dependency>
+             <groupId>org.apache.httpcomponents</groupId>
+             <artifactId>httpcore</artifactId>
+             <mapping>
+               <componentId>apache-httpcomponents</componentId>
+             </mapping>
+           </dependency>
+           <dependency>
+             <groupId>org.apache.httpcomponents</groupId>
+             <artifactId>httpclient</artifactId>
+             <mapping>
+               <componentId>apache-httpcomponents</componentId>
+             </mapping>
+           </dependency>
+           <dependency>
+             <groupId>org.apache.httpcomponents</groupId>
+             <artifactId>httpmime</artifactId>
+             <mapping>
+               <componentId>apache-httpcomponents</componentId>
+             </mapping>
+           </dependency>           
+           <!-- End mapped dependecies -->
             
           </mappedDependencies>
         </configuration>
@@ -2222,6 +2250,22 @@
       <artifactId>cobertura</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-all</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpcore</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpclient</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents</groupId>
+      <artifactId>httpmime</artifactId>
+    </dependency>
   </dependencies>
   
   <profiles>

Property changes on: ds-builder
___________________________________________________________________
Added: svn:ignore
   + output


Index: component-matrix/pom.xml
===================================================================
--- component-matrix/pom.xml	(revision 113475)
+++ component-matrix/pom.xml	(working copy)
@@ -105,6 +105,8 @@
     <version.sun.jaxb.api>2.1</version.sun.jaxb.api>
     <version.xdoclet>1.2.3</version.xdoclet>
     <version.xjavadoc>1.1</version.xjavadoc>
+    <version.apacheds>2.0.0-M7</version.apacheds>
+    <version.org.apache.httpcomponents>4.2.1</version.org.apache.httpcomponents>
   </properties>
 
   <!-- Dependency Management -->
@@ -2303,6 +2305,52 @@
         <version>1.9.3</version>
       </dependency>
 
+        <dependency>
+            <groupId>org.apache.directory.server</groupId>
+            <artifactId>apacheds-all</artifactId>
+            <version>${version.apacheds}</version>
+            <scope>test</scope>
+        </dependency>
+        
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpclient</artifactId>
+        <version>${version.org.apache.httpcomponents}</version>
+        <scope>test</scope>
+        <exclusions>
+          <exclusion>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpcore</artifactId>
+        <version>${version.org.apache.httpcomponents}</version>
+        <scope>test</scope>
+        <exclusions>
+          <exclusion>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpmime</artifactId>
+        <version>${version.org.apache.httpcomponents}</version>
+        <scope>test</scope>
+        <exclusions>
+          <exclusion>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+
     </dependencies>
 
   </dependencyManagement>
