From 410c92f5c71c93cd2b4b0a1d9ee4067c34b80c66 Mon Sep 17 00:00:00 2001
From: Eddy Young <jeyoung@priscimon.com>
Date: Fri, 22 May 2015 03:47:09 -0400
Subject: [PATCH] Merge branch 'develop' into ticket-57_develop

---
 nbproject/project.xml                                             |  135 +++++++
 src/main/java/com/gitblit/guice/WebModule.java                    |   12 
 src/test/java/com/gitblit/tests/JschConfigTestSessionFactory.java |    1 
 src/test/java/com/gitblit/tests/SshUnitTest.java                  |    8 
 src/main/java/com/gitblit/servlet/AccessDeniedServlet.java        |   63 +++
 .gitignore                                                        |    1 
 src/main/java/com/gitblit/transport/ssh/SshDaemon.java            |   58 +++
 src/test/java/com/gitblit/tests/AuthenticationManagerTest.java    |  675 ++++++++++++++++++++++++++++++++++++
 src/main/java/com/gitblit/manager/AuthenticationManager.java      |   48 ++
 src/main/distrib/data/defaults.properties                         |   38 ++
 src/test/config/test-gitblit.properties                           |    2 
 11 files changed, 1,023 insertions(+), 18 deletions(-)

diff --git a/.gitignore b/.gitignore
index 4cb4116..7405aa8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,3 +28,4 @@
 /**/.idea
 /**/init.lua
 /**/session
+/nbproject/private
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644
index 0000000..d037929
--- /dev/null
+++ b/nbproject/project.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.ant.freeform</type>
+    <configuration>
+        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+            <name>gitblit</name>
+        </general-data>
+        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/2">
+            <!-- Do not use Project Properties customizer when editing this file manually. 
+ To prevent the customizer from showing, create nbproject/project.properties file and enter 
+auxiliary.show.customizer=false 
+property there. Adding 
+auxiliary.show.customizer.message=<message>
+ will show your customized message when someone attempts to open the customizer.  -->
+            <name>gitblit</name>
+            <properties/>
+            <folders>
+                <source-folder>
+                    <label>gitblit</label>
+                    <location>.</location>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+                <source-folder>
+                    <label>src\main\bugtraq</label>
+                    <type>java</type>
+                    <location>src/main/bugtraq</location>
+                    <excludes>*.html</excludes>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+                <source-folder>
+                    <label>src\main\java</label>
+                    <type>java</type>
+                    <location>src/main/java</location>
+                    <excludes>*.html</excludes>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+                <source-folder>
+                    <label>src\test\bugtraq</label>
+                    <type>java</type>
+                    <location>src/test/bugtraq</location>
+                    <excludes>*.html</excludes>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+                <source-folder>
+                    <label>src\test\java</label>
+                    <type>java</type>
+                    <location>src/test/java</location>
+                    <excludes>*.html</excludes>
+                    <encoding>UTF-8</encoding>
+                </source-folder>
+            </folders>
+            <ide-actions>
+                <action name="build">
+                    <target>compile</target>
+                </action>
+                <action name="clean">
+                    <target>clean</target>
+                </action>
+                <action name="javadoc">
+                    <target>buildAll</target>
+                </action>
+                <action name="run">
+                    <target>run</target>
+                </action>
+                <action name="test">
+                    <target>test</target>
+                </action>
+                <action name="rebuild">
+                    <target>clean</target>
+                    <target>compile</target>
+                </action>
+            </ide-actions>
+            <view>
+                <items>
+                    <source-folder style="packages">
+                        <label>src\main\bugtraq</label>
+                        <location>src/main/bugtraq</location>
+                        <excludes>*.html</excludes>
+                    </source-folder>
+                    <source-folder style="packages">
+                        <label>src\main\java</label>
+                        <location>src/main/java</location>
+                        <excludes>*.html</excludes>
+                    </source-folder>
+                    <source-folder style="packages">
+                        <label>src\test\bugtraq</label>
+                        <location>src/test/bugtraq</location>
+                        <excludes>*.html</excludes>
+                    </source-folder>
+                    <source-folder style="packages">
+                        <label>src\test\java</label>
+                        <location>src/test/java</location>
+                        <excludes>*.html</excludes>
+                    </source-folder>
+                    <source-file>
+                        <location>build.xml</location>
+                    </source-file>
+                </items>
+                <context-menu>
+                    <ide-action name="build"/>
+                    <ide-action name="rebuild"/>
+                    <ide-action name="clean"/>
+                    <ide-action name="javadoc"/>
+                    <ide-action name="run"/>
+                    <ide-action name="test"/>
+                </context-menu>
+            </view>
+            <subprojects/>
+        </general-data>
+        <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
+            <compilation-unit>
+                <package-root>src/main/bugtraq</package-root>
+                <classpath mode="compile">ext/JavaEWAH-0.7.9.jar;ext/annotations-12.0.jar;ext/aopalliance-1.0.jar;ext/args4j-2.0.29.jar;ext/asm-4.1.jar;ext/asm-analysis-4.1.jar;ext/asm-tree-4.1.jar;ext/asm-util-4.1.jar;ext/bcmail-jdk15on-1.51.jar;ext/bcpkix-jdk15on-1.51.jar;ext/bcprov-jdk15on-1.51.jar;ext/cglib-nodep-2.1_3.jar;ext/commons-codec-1.7.jar;ext/commons-compress-1.4.1.jar;ext/commons-exec-1.1.jar;ext/commons-io-2.2.jar;ext/commons-logging-1.1.1.jar;ext/commons-pool2-2.0.jar;ext/confluence-core-1.4.jar;ext/dagger-1.1.0.jar;ext/dagger-compiler-1.1.0.jar;ext/force-partner-api-24.0.0.jar;ext/force-wsc-24.0.0.jar;ext/freemarker-2.3.22.jar;ext/groovy-all-2.4.1.jar;ext/gson-2.3.1.jar;ext/guava-18.0.jar;ext/guice-4.0-beta5.jar;ext/guice-servlet-4.0-gb1.jar;ext/hamcrest-core-1.3.jar;ext/httpclient-4.1.3.jar;ext/httpcore-4.1.4.jar;ext/ivy-2.2.0.jar;ext/jakarta-regexp-1.4.jar;ext/javawriter-2.1.1.jar;ext/javax.inject-1.jar;ext/javax.mail-1.5.1.jar;ext/javax.servlet-api-3.1.0.jar;ext/jcalendar-1.3.2.jar;ext/jdom-1.0.jar;ext/jedis-2.6.2.jar;ext/jetty-all-9.2.10.v20150310.jar;ext/jetty-all-9.2.9.v20150224.jar;ext/jna-4.1.0.jar;ext/jna-platform-4.1.0.jar;ext/js-1.7R2.jar;ext/jsch-0.1.50.jar;ext/json-20080701.jar;ext/jsoup-1.7.3.jar;ext/junit-4.11.jar;ext/libpam4j-1.8.jar;ext/log4j-1.2.17.jar;ext/lucene-analyzers-common-4.10.0.jar;ext/lucene-core-4.10.0.jar;ext/lucene-highlighter-4.10.0.jar;ext/lucene-memory-4.10.0.jar;ext/lucene-queries-4.10.0.jar;ext/lucene-queryparser-4.10.0.jar;ext/lucene-sandbox-4.10.0.jar;ext/mediawiki-core-1.4.jar;ext/mina-core-2.0.9.jar;ext/org.eclipse.jgit-3.5.1.201410131835-r.jar;ext/org.eclipse.jgit-3.7.0.201502260915-r.jar;ext/org.eclipse.jgit.http.server-3.5.1.201410131835-r.jar;ext/org.eclipse.jgit.http.server-3.7.0.201502260915-r.jar;ext/parboiled-core-1.1.6.jar;ext/parboiled-java-1.1.6.jar;ext/pegdown-1.4.2.jar;ext/pf4j-0.9.0.jar;ext/platform-3.4.0.jar;ext/platform-3.5.0.jar;ext/rome-0.9.jar;ext/selenium-api-2.28.0.jar;ext/selenium-firefox-driver-2.28.0.jar;ext/selenium-java-2.28.0.jar;ext/selenium-remote-driver-2.28.0.jar;ext/selenium-support-2.28.0.jar;ext/slf4j-api-1.7.10.jar;ext/slf4j-log4j12-1.7.10.jar;ext/sshd-core-0.14.0.jar;ext/textile-core-1.4.jar;ext/tika-core-1.5.jar;ext/tracwiki-core-1.4.jar;ext/twiki-core-1.4.jar;ext/unboundid-ldapsdk-2.3.8.jar;ext/waffle-jna-1.7.3.jar;ext/wicket-1.4.21.jar;ext/wicket-auth-roles-1.4.21.jar;ext/wicket-extensions-1.4.21.jar;ext/wikitext-core-1.4.jar;ext/xz-1.0.jar</classpath>
+                <source-level>1.7</source-level>
+            </compilation-unit>
+            <compilation-unit>
+                <package-root>src/main/java</package-root>
+                <classpath mode="compile">ext/JavaEWAH-0.7.9.jar;ext/annotations-12.0.jar;ext/aopalliance-1.0.jar;ext/args4j-2.0.29.jar;ext/asm-4.1.jar;ext/asm-analysis-4.1.jar;ext/asm-tree-4.1.jar;ext/asm-util-4.1.jar;ext/bcmail-jdk15on-1.51.jar;ext/bcpkix-jdk15on-1.51.jar;ext/bcprov-jdk15on-1.51.jar;ext/cglib-nodep-2.1_3.jar;ext/commons-codec-1.7.jar;ext/commons-compress-1.4.1.jar;ext/commons-exec-1.1.jar;ext/commons-io-2.2.jar;ext/commons-logging-1.1.1.jar;ext/commons-pool2-2.0.jar;ext/confluence-core-1.4.jar;ext/dagger-1.1.0.jar;ext/dagger-compiler-1.1.0.jar;ext/force-partner-api-24.0.0.jar;ext/force-wsc-24.0.0.jar;ext/freemarker-2.3.22.jar;ext/groovy-all-2.4.1.jar;ext/gson-2.3.1.jar;ext/guava-18.0.jar;ext/guice-4.0-beta5.jar;ext/guice-servlet-4.0-gb1.jar;ext/hamcrest-core-1.3.jar;ext/httpclient-4.1.3.jar;ext/httpcore-4.1.4.jar;ext/ivy-2.2.0.jar;ext/jakarta-regexp-1.4.jar;ext/javawriter-2.1.1.jar;ext/javax.inject-1.jar;ext/javax.mail-1.5.1.jar;ext/javax.servlet-api-3.1.0.jar;ext/jcalendar-1.3.2.jar;ext/jdom-1.0.jar;ext/jedis-2.6.2.jar;ext/jetty-all-9.2.10.v20150310.jar;ext/jetty-all-9.2.9.v20150224.jar;ext/jna-4.1.0.jar;ext/jna-platform-4.1.0.jar;ext/js-1.7R2.jar;ext/jsch-0.1.50.jar;ext/json-20080701.jar;ext/jsoup-1.7.3.jar;ext/junit-4.11.jar;ext/libpam4j-1.8.jar;ext/log4j-1.2.17.jar;ext/lucene-analyzers-common-4.10.0.jar;ext/lucene-core-4.10.0.jar;ext/lucene-highlighter-4.10.0.jar;ext/lucene-memory-4.10.0.jar;ext/lucene-queries-4.10.0.jar;ext/lucene-queryparser-4.10.0.jar;ext/lucene-sandbox-4.10.0.jar;ext/mediawiki-core-1.4.jar;ext/mina-core-2.0.9.jar;ext/org.eclipse.jgit-3.5.1.201410131835-r.jar;ext/org.eclipse.jgit-3.7.0.201502260915-r.jar;ext/org.eclipse.jgit.http.server-3.5.1.201410131835-r.jar;ext/org.eclipse.jgit.http.server-3.7.0.201502260915-r.jar;ext/parboiled-core-1.1.6.jar;ext/parboiled-java-1.1.6.jar;ext/pegdown-1.4.2.jar;ext/pf4j-0.9.0.jar;ext/platform-3.4.0.jar;ext/platform-3.5.0.jar;ext/rome-0.9.jar;ext/selenium-api-2.28.0.jar;ext/selenium-firefox-driver-2.28.0.jar;ext/selenium-java-2.28.0.jar;ext/selenium-remote-driver-2.28.0.jar;ext/selenium-support-2.28.0.jar;ext/slf4j-api-1.7.10.jar;ext/slf4j-log4j12-1.7.10.jar;ext/sshd-core-0.14.0.jar;ext/textile-core-1.4.jar;ext/tika-core-1.5.jar;ext/tracwiki-core-1.4.jar;ext/twiki-core-1.4.jar;ext/unboundid-ldapsdk-2.3.8.jar;ext/waffle-jna-1.7.3.jar;ext/wicket-1.4.21.jar;ext/wicket-auth-roles-1.4.21.jar;ext/wicket-extensions-1.4.21.jar;ext/wikitext-core-1.4.jar;ext/xz-1.0.jar;src/main/bugtraq</classpath>
+                <source-level>1.7</source-level>
+            </compilation-unit>
+            <compilation-unit>
+                <package-root>src/test/bugtraq</package-root>
+                <unit-tests/>
+                <classpath mode="compile">ext/JavaEWAH-0.7.9.jar;ext/annotations-12.0.jar;ext/aopalliance-1.0.jar;ext/args4j-2.0.29.jar;ext/asm-4.1.jar;ext/asm-analysis-4.1.jar;ext/asm-tree-4.1.jar;ext/asm-util-4.1.jar;ext/bcmail-jdk15on-1.51.jar;ext/bcpkix-jdk15on-1.51.jar;ext/bcprov-jdk15on-1.51.jar;ext/cglib-nodep-2.1_3.jar;ext/commons-codec-1.7.jar;ext/commons-compress-1.4.1.jar;ext/commons-exec-1.1.jar;ext/commons-io-2.2.jar;ext/commons-logging-1.1.1.jar;ext/commons-pool2-2.0.jar;ext/confluence-core-1.4.jar;ext/dagger-1.1.0.jar;ext/dagger-compiler-1.1.0.jar;ext/force-partner-api-24.0.0.jar;ext/force-wsc-24.0.0.jar;ext/freemarker-2.3.22.jar;ext/groovy-all-2.4.1.jar;ext/gson-2.3.1.jar;ext/guava-18.0.jar;ext/guice-4.0-beta5.jar;ext/guice-servlet-4.0-gb1.jar;ext/hamcrest-core-1.3.jar;ext/httpclient-4.1.3.jar;ext/httpcore-4.1.4.jar;ext/ivy-2.2.0.jar;ext/jakarta-regexp-1.4.jar;ext/javawriter-2.1.1.jar;ext/javax.inject-1.jar;ext/javax.mail-1.5.1.jar;ext/javax.servlet-api-3.1.0.jar;ext/jcalendar-1.3.2.jar;ext/jdom-1.0.jar;ext/jedis-2.6.2.jar;ext/jetty-all-9.2.10.v20150310.jar;ext/jetty-all-9.2.9.v20150224.jar;ext/jna-4.1.0.jar;ext/jna-platform-4.1.0.jar;ext/js-1.7R2.jar;ext/jsch-0.1.50.jar;ext/json-20080701.jar;ext/jsoup-1.7.3.jar;ext/junit-4.11.jar;ext/libpam4j-1.8.jar;ext/log4j-1.2.17.jar;ext/lucene-analyzers-common-4.10.0.jar;ext/lucene-core-4.10.0.jar;ext/lucene-highlighter-4.10.0.jar;ext/lucene-memory-4.10.0.jar;ext/lucene-queries-4.10.0.jar;ext/lucene-queryparser-4.10.0.jar;ext/lucene-sandbox-4.10.0.jar;ext/mediawiki-core-1.4.jar;ext/mina-core-2.0.9.jar;ext/org.eclipse.jgit-3.5.1.201410131835-r.jar;ext/org.eclipse.jgit-3.7.0.201502260915-r.jar;ext/org.eclipse.jgit.http.server-3.5.1.201410131835-r.jar;ext/org.eclipse.jgit.http.server-3.7.0.201502260915-r.jar;ext/parboiled-core-1.1.6.jar;ext/parboiled-java-1.1.6.jar;ext/pegdown-1.4.2.jar;ext/pf4j-0.9.0.jar;ext/platform-3.4.0.jar;ext/platform-3.5.0.jar;ext/rome-0.9.jar;ext/selenium-api-2.28.0.jar;ext/selenium-firefox-driver-2.28.0.jar;ext/selenium-java-2.28.0.jar;ext/selenium-remote-driver-2.28.0.jar;ext/selenium-support-2.28.0.jar;ext/slf4j-api-1.7.10.jar;ext/slf4j-log4j12-1.7.10.jar;ext/sshd-core-0.14.0.jar;ext/textile-core-1.4.jar;ext/tika-core-1.5.jar;ext/tracwiki-core-1.4.jar;ext/twiki-core-1.4.jar;ext/unboundid-ldapsdk-2.3.8.jar;ext/waffle-jna-1.7.3.jar;ext/wicket-1.4.21.jar;ext/wicket-auth-roles-1.4.21.jar;ext/wicket-extensions-1.4.21.jar;ext/wikitext-core-1.4.jar;ext/xz-1.0.jar;src/main/bugtraq</classpath>
+                <source-level>1.7</source-level>
+            </compilation-unit>
+            <compilation-unit>
+                <package-root>src/test/java</package-root>
+                <unit-tests/>
+                <classpath mode="compile">ext/JavaEWAH-0.7.9.jar;ext/annotations-12.0.jar;ext/aopalliance-1.0.jar;ext/args4j-2.0.29.jar;ext/asm-4.1.jar;ext/asm-analysis-4.1.jar;ext/asm-tree-4.1.jar;ext/asm-util-4.1.jar;ext/bcmail-jdk15on-1.51.jar;ext/bcpkix-jdk15on-1.51.jar;ext/bcprov-jdk15on-1.51.jar;ext/cglib-nodep-2.1_3.jar;ext/commons-codec-1.7.jar;ext/commons-compress-1.4.1.jar;ext/commons-exec-1.1.jar;ext/commons-io-2.2.jar;ext/commons-logging-1.1.1.jar;ext/commons-pool2-2.0.jar;ext/confluence-core-1.4.jar;ext/dagger-1.1.0.jar;ext/dagger-compiler-1.1.0.jar;ext/force-partner-api-24.0.0.jar;ext/force-wsc-24.0.0.jar;ext/freemarker-2.3.22.jar;ext/groovy-all-2.4.1.jar;ext/gson-2.3.1.jar;ext/guava-18.0.jar;ext/guice-4.0-beta5.jar;ext/guice-servlet-4.0-gb1.jar;ext/hamcrest-core-1.3.jar;ext/httpclient-4.1.3.jar;ext/httpcore-4.1.4.jar;ext/ivy-2.2.0.jar;ext/jakarta-regexp-1.4.jar;ext/javawriter-2.1.1.jar;ext/javax.inject-1.jar;ext/javax.mail-1.5.1.jar;ext/javax.servlet-api-3.1.0.jar;ext/jcalendar-1.3.2.jar;ext/jdom-1.0.jar;ext/jedis-2.6.2.jar;ext/jetty-all-9.2.10.v20150310.jar;ext/jetty-all-9.2.9.v20150224.jar;ext/jna-4.1.0.jar;ext/jna-platform-4.1.0.jar;ext/js-1.7R2.jar;ext/jsch-0.1.50.jar;ext/json-20080701.jar;ext/jsoup-1.7.3.jar;ext/junit-4.11.jar;ext/libpam4j-1.8.jar;ext/log4j-1.2.17.jar;ext/lucene-analyzers-common-4.10.0.jar;ext/lucene-core-4.10.0.jar;ext/lucene-highlighter-4.10.0.jar;ext/lucene-memory-4.10.0.jar;ext/lucene-queries-4.10.0.jar;ext/lucene-queryparser-4.10.0.jar;ext/lucene-sandbox-4.10.0.jar;ext/mediawiki-core-1.4.jar;ext/mina-core-2.0.9.jar;ext/org.eclipse.jgit-3.5.1.201410131835-r.jar;ext/org.eclipse.jgit-3.7.0.201502260915-r.jar;ext/org.eclipse.jgit.http.server-3.5.1.201410131835-r.jar;ext/org.eclipse.jgit.http.server-3.7.0.201502260915-r.jar;ext/parboiled-core-1.1.6.jar;ext/parboiled-java-1.1.6.jar;ext/pegdown-1.4.2.jar;ext/pf4j-0.9.0.jar;ext/platform-3.4.0.jar;ext/platform-3.5.0.jar;ext/rome-0.9.jar;ext/selenium-api-2.28.0.jar;ext/selenium-firefox-driver-2.28.0.jar;ext/selenium-java-2.28.0.jar;ext/selenium-remote-driver-2.28.0.jar;ext/selenium-support-2.28.0.jar;ext/slf4j-api-1.7.10.jar;ext/slf4j-log4j12-1.7.10.jar;ext/sshd-core-0.14.0.jar;ext/textile-core-1.4.jar;ext/tika-core-1.5.jar;ext/tracwiki-core-1.4.jar;ext/twiki-core-1.4.jar;ext/unboundid-ldapsdk-2.3.8.jar;ext/waffle-jna-1.7.3.jar;ext/wicket-1.4.21.jar;ext/wicket-auth-roles-1.4.21.jar;ext/wicket-extensions-1.4.21.jar;ext/wikitext-core-1.4.jar;ext/xz-1.0.jar;src/main/java</classpath>
+                <source-level>1.7</source-level>
+            </compilation-unit>
+        </java-data>
+    </configuration>
+</project>
diff --git a/src/main/distrib/data/defaults.properties b/src/main/distrib/data/defaults.properties
index 0857ccf..59fa399 100644
--- a/src/main/distrib/data/defaults.properties
+++ b/src/main/distrib/data/defaults.properties
@@ -126,6 +126,28 @@
 # SINCE 1.5.0
 git.sshKeysFolder= ${baseFolder}/ssh
 
+# Use kerberos5 (GSS) authentication
+#
+# SINCE 1.7.0
+git.sshWithKrb5 = "false"
+
+# The path to a kerberos 5 keytab.
+#
+# SINCE 1.7.0
+git.sshKrb5Keytab = ""
+
+# The service principal name to be used for Kerberos5.  The default is host/hostname.
+#
+# SINCE 1.7.0
+git.sshKrb5ServicePrincipalName = ""
+
+# A comma-separated list of authentication method. They will be tried in
+# the given order. Possible values are 
+# "gssapi-with-mic", "publickey", "keyboard-interactive" or "password"
+#
+# SINCE 1.7.0
+git.sshAuthenticatorsOrder = "password,keyboard-interactive,publickey"
+
 # SSH backend NIO2|MINA.
 #
 # The Apache Mina project recommends using the NIO2 backend.
@@ -1610,6 +1632,22 @@
 # SINCE 1.3.0
 realm.container.autoCreateAccounts = false
 
+# A set of mapping used to map HTTP session attributes to user informations
+# They are used if realm.container.autoCreateAccounts is set to true and
+# the webapp container used can fill the session with user informations
+#
+# SINCE 1.7.0
+realm.container.autoAccounts.displayName = 
+realm.container.autoAccounts.emailAddress = 
+realm.container.autoAccounts.locale = 
+
+# If the user's created by the webapp container is given this role,
+# the user created will be a admin user.
+#
+# SINCE 1.7.0
+realm.container.autoAccounts.adminRole = 
+
+
 # Allow or prohibit Windows guest account logins
 #
 # SINCE 1.3.0
diff --git a/src/main/java/com/gitblit/guice/WebModule.java b/src/main/java/com/gitblit/guice/WebModule.java
index 5b56918..c6172c3 100644
--- a/src/main/java/com/gitblit/guice/WebModule.java
+++ b/src/main/java/com/gitblit/guice/WebModule.java
@@ -19,6 +19,7 @@
 import java.util.Map;
 
 import com.gitblit.Constants;
+import com.gitblit.servlet.AccessDeniedServlet;
 import com.gitblit.servlet.BranchGraphServlet;
 import com.gitblit.servlet.DownloadZipFilter;
 import com.gitblit.servlet.DownloadZipServlet;
@@ -70,6 +71,17 @@
 		serve("/robots.txt").with(RobotsTxtServlet.class);
 		serve("/logo.png").with(LogoServlet.class);
 
+		/* Prevent accidental access to 'resources' such as GitBlit java classes
+		 *
+		 * In the GO setup the JAR containing the application and the WAR injected
+		 * into Jetty are the same file. However Jetty expects to serve the entire WAR
+		 * contents, except the WEB-INF folder. Thus, all java binary classes in the
+		 * JAR are served by default as is they were legitimate resources.
+		 *
+		 * The below servlet mappings prevent that behavior
+		 */
+		serve(fuzzy("/com/")).with(AccessDeniedServlet.class);
+
 		// global filters
 		filter(ALL).through(ProxyFilter.class);
 		filter(ALL).through(EnforceAuthenticationFilter.class);
diff --git a/src/main/java/com/gitblit/manager/AuthenticationManager.java b/src/main/java/com/gitblit/manager/AuthenticationManager.java
index 29221e6..cbf0a1b 100644
--- a/src/main/java/com/gitblit/manager/AuthenticationManager.java
+++ b/src/main/java/com/gitblit/manager/AuthenticationManager.java
@@ -215,6 +215,29 @@
 						user.displayName = username;
 						user.password = Constants.EXTERNAL_ACCOUNT;
 						user.accountType = AccountType.CONTAINER;
+						
+						// Try to extract user's informations for the session
+						// it uses "realm.container.autoAccounts.*" as the attribute name to look for
+						HttpSession session = httpRequest.getSession();
+						String emailAddress = resolveAttribute(session, Keys.realm.container.autoAccounts.emailAddress);
+						if(emailAddress != null) {
+							user.emailAddress = emailAddress;
+						}
+						String displayName = resolveAttribute(session, Keys.realm.container.autoAccounts.displayName);
+						if(displayName != null) {
+							user.displayName = displayName;
+						}
+						String userLocale = resolveAttribute(session, Keys.realm.container.autoAccounts.locale);
+						if(userLocale != null) {
+							user.getPreferences().setLocale(userLocale);
+						}
+						String adminRole = settings.getString(Keys.realm.container.autoAccounts.adminRole, null);
+						if(adminRole != null && ! adminRole.isEmpty()) {
+							if(httpRequest.isUserInRole(adminRole)) {
+								user.canAdmin = true;
+							}
+						}
+						
 						userManager.updateUserModel(user);
 						flagSession(httpRequest, AuthenticationType.CONTAINER);
 						logger.debug(MessageFormat.format("{0} authenticated and created by servlet container principal from {1}",
@@ -293,6 +316,31 @@
 		}
 		return null;
 	}
+	
+	/**
+	 * Extract given attribute from the session and return it's content
+	 * it return null if attributeMapping is empty, or if the value is
+	 * empty
+	 * 
+	 * @param session The user session
+	 * @param attributeMapping
+	 * @return
+	 */
+	private String resolveAttribute(HttpSession session, String attributeMapping) {
+		String attributeName = settings.getString(attributeMapping, null);
+		if(StringUtils.isEmpty(attributeName)) {
+			return null;
+		}
+		Object attributeValue = session.getAttribute(attributeName);
+		if(attributeValue == null) {
+			return null;
+		}
+		String value = attributeValue.toString();
+		if(value.isEmpty()) {
+			return null;
+		}
+		return value;
+	}
 
 	/**
 	 * Authenticate a user based on a public key.
diff --git a/src/main/java/com/gitblit/servlet/AccessDeniedServlet.java b/src/main/java/com/gitblit/servlet/AccessDeniedServlet.java
new file mode 100644
index 0000000..ae0797e
--- /dev/null
+++ b/src/main/java/com/gitblit/servlet/AccessDeniedServlet.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2015 Jean-Baptiste Mayer
+ *
+ * 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 com.gitblit.servlet;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.google.inject.Singleton;
+
+/**
+ * Access-denied Servlet.
+ * 
+ * This servlet serves only 404 Not Found error replies.
+ * 
+ * This servlet is used to override the container's default behavior to serve
+ * all contents of the application's WAR. We can selectively prevent access to
+ * a specific path simply by mapping this servlet onto specific paths.
+ * 
+ * 
+ * @author Jean-Baptiste Mayer
+ *
+ */
+@Singleton
+public class AccessDeniedServlet extends HttpServlet {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -3239463647917811122L;
+
+	@Override
+	protected void doPost(HttpServletRequest request, HttpServletResponse response)
+			throws ServletException, java.io.IOException {
+		processRequest(request, response);
+	}
+
+	@Override
+	protected void doGet(HttpServletRequest request, HttpServletResponse response)
+			throws ServletException, IOException {
+		processRequest(request, response);
+	}
+
+	private void processRequest(HttpServletRequest request,
+			HttpServletResponse response) {
+		response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+	}
+}
diff --git a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
index 9667154..ec7d7c3 100644
--- a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
+++ b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
@@ -23,15 +23,25 @@
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.sshd.SshServer;
+import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.io.IoServiceFactoryFactory;
 import org.apache.sshd.common.io.mina.MinaServiceFactoryFactory;
 import org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory;
 import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
 import org.apache.sshd.common.util.SecurityUtils;
 import org.apache.sshd.server.auth.CachingPublicKeyAuthenticator;
+import org.apache.sshd.server.UserAuth;
+import org.apache.sshd.server.auth.UserAuthKeyboardInteractive;
+import org.apache.sshd.server.auth.UserAuthPassword;
+import org.apache.sshd.server.auth.UserAuthPublicKey;
+import org.apache.sshd.server.auth.gss.GSSAuthenticator;
+import org.apache.sshd.server.auth.gss.UserAuthGSS;
 import org.bouncycastle.openssl.PEMWriter;
 import org.eclipse.jgit.internal.JGitText;
 import org.slf4j.Logger;
@@ -120,7 +130,49 @@
 		} else {
 			addr = new InetSocketAddress(bindInterface, port);
 		}
-
+		
+		//Will do GSS ?
+		GSSAuthenticator gssAuthenticator = null;
+		if(settings.getBoolean(Keys.git.sshWithKrb5, false)) {
+			gssAuthenticator = new GSSAuthenticator();
+			String keytabString = settings.getString(Keys.git.sshKrb5Keytab,
+					"");
+			if(! keytabString.isEmpty()) {
+				gssAuthenticator.setKeytabFile(keytabString);
+			}
+			String servicePrincipalName = settings.getString(Keys.git.sshKrb5ServicePrincipalName,
+					"");
+			if(! servicePrincipalName.isEmpty()) {
+				gssAuthenticator.setServicePrincipalName(servicePrincipalName);
+			}			
+		}
+		
+		//Sort the authenticators for sshd
+		List<NamedFactory<UserAuth>> userAuthFactories = new ArrayList<>();
+		String sshAuthenticatorsOrderString = settings.getString(Keys.git.sshAuthenticatorsOrder,
+				"password,keyboard-interactive,publickey");
+		for(String authenticator: sshAuthenticatorsOrderString.split(",")) {
+			String authenticatorName = authenticator.trim().toLowerCase(Locale.US);
+			switch (authenticatorName) {
+			case "gssapi-with-mic":
+				if(gssAuthenticator != null) {
+					userAuthFactories.add(new UserAuthGSS.Factory());					
+				}
+				break;
+			case "publickey":
+				userAuthFactories.add(new UserAuthPublicKey.Factory());
+				break;
+			case "password":
+				userAuthFactories.add(new UserAuthPassword.Factory());
+				break;
+			case "keyboard-interactive":
+				userAuthFactories.add(new UserAuthKeyboardInteractive.Factory());
+				break;
+			default:
+				log.error("Unknown ssh authenticator: '{}'", authenticatorName);
+			}
+		}
+		
 		// Create the SSH server
 		sshd = SshServer.setUpDefaultServer();
 		sshd.setPort(addr.getPort());
@@ -128,6 +180,10 @@
 		sshd.setKeyPairProvider(hostKeyPairProvider);
 		sshd.setPublickeyAuthenticator(new CachingPublicKeyAuthenticator(keyAuthenticator));
 		sshd.setPasswordAuthenticator(new UsernamePasswordAuthenticator(gitblit));
+		if(gssAuthenticator != null) {
+			sshd.setGSSAuthenticator(gssAuthenticator);
+		}
+		sshd.setUserAuthFactories(userAuthFactories);
 		sshd.setSessionFactory(new SshServerSessionFactory());
 		sshd.setFileSystemFactory(new DisabledFilesystemFactory());
 		sshd.setTcpipForwardingFilter(new NonForwardingFilter());
diff --git a/src/test/config/test-gitblit.properties b/src/test/config/test-gitblit.properties
index 78e9ab9..398047c 100644
--- a/src/test/config/test-gitblit.properties
+++ b/src/test/config/test-gitblit.properties
@@ -9,6 +9,8 @@
 git.daemonPort = 8300
 git.sshPort = 29418
 git.sshKeysManager = com.gitblit.transport.ssh.MemoryKeyManager
+git.sshWithKrb5 = true
+git.sshAuthenticatorsOrder = password, publickey,gssapi-with-mic,invalid
 groovy.scriptsFolder = src/main/distrib/data/groovy
 groovy.preReceiveScripts = blockpush
 groovy.postReceiveScripts = sendmail
diff --git a/src/test/java/com/gitblit/tests/AuthenticationManagerTest.java b/src/test/java/com/gitblit/tests/AuthenticationManagerTest.java
index 0cdee6c..d6ca89c 100644
--- a/src/test/java/com/gitblit/tests/AuthenticationManagerTest.java
+++ b/src/test/java/com/gitblit/tests/AuthenticationManagerTest.java
@@ -15,15 +15,44 @@
  */
 package com.gitblit.tests;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionContext;
+import javax.servlet.http.HttpUpgradeHandler;
+import javax.servlet.http.Part;
 
 import org.junit.Test;
 
+import com.gitblit.IUserService;
+import com.gitblit.Keys;
 import com.gitblit.manager.AuthenticationManager;
 import com.gitblit.manager.IAuthenticationManager;
-import com.gitblit.manager.IUserManager;
+import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.RuntimeManager;
 import com.gitblit.manager.UserManager;
+import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.tests.mock.MemorySettings;
 import com.gitblit.utils.XssFilter;
@@ -35,27 +64,596 @@
  * @author James Moger
  *
  */
+@SuppressWarnings("deprecation")
 public class AuthenticationManagerTest extends GitblitUnitTest {
 
-	IUserManager users;
+	UserManager users;
 
-    MemorySettings getSettings() {
-    	return new MemorySettings(new HashMap<String, Object>());
-    }
+	private static final class DummyHttpServletRequest implements HttpServletRequest {
 
-    IAuthenticationManager newAuthenticationManager() {
-    	XssFilter xssFilter = new AllowXssFilter();
-    	RuntimeManager runtime = new RuntimeManager(getSettings(), xssFilter, GitBlitSuite.BASEFOLDER).start();
-    	users = new UserManager(runtime, null).start();
-    	AuthenticationManager auth = new AuthenticationManager(runtime, users).start();
-    	return auth;
-    }
+		@Override
+		public Object getAttribute(String name) {
+			return null;
+		}
 
-    @Test
-    public void testAuthenticate() throws Exception {
-    	IAuthenticationManager auth = newAuthenticationManager();
+		@Override
+		public Enumeration<String> getAttributeNames() {
+			return null;
+		}
 
-    	UserModel user = new UserModel("sunnyjim");
+		@Override
+		public String getCharacterEncoding() {
+			return null;
+		}
+
+		@Override
+		public void setCharacterEncoding(String env)
+				throws UnsupportedEncodingException {
+		}
+
+		@Override
+		public int getContentLength() {
+			return 0;
+		}
+
+		@Override
+		public long getContentLengthLong() {
+			return 0;
+		}
+
+		@Override
+		public String getContentType() {
+			return null;
+		}
+
+		@Override
+		public ServletInputStream getInputStream() throws IOException {
+			return null;
+		}
+
+		@Override
+		public String getParameter(String name) {
+			return null;
+		}
+
+		@Override
+		public Enumeration<String> getParameterNames() {
+			return null;
+		}
+
+		@Override
+		public String[] getParameterValues(String name) {
+			return null;
+		}
+
+		@Override
+		public Map<String, String[]> getParameterMap() {
+			return null;
+		}
+
+		@Override
+		public String getProtocol() {
+			return null;
+		}
+
+		@Override
+		public String getScheme() {
+			return null;
+		}
+
+		@Override
+		public String getServerName() {
+			return null;
+		}
+
+		@Override
+		public int getServerPort() {
+			return 0;
+		}
+
+		@Override
+		public BufferedReader getReader() throws IOException {
+			return null;
+		}
+
+		@Override
+		public String getRemoteAddr() {
+			return null;
+		}
+
+		@Override
+		public String getRemoteHost() {
+			return null;
+		}
+
+		@Override
+		public void setAttribute(String name, Object o) {
+		}
+
+		@Override
+		public void removeAttribute(String name) {
+		}
+
+		@Override
+		public Locale getLocale() {
+			return null;
+		}
+
+		@Override
+		public Enumeration<Locale> getLocales() {
+			return null;
+		}
+
+		@Override
+		public boolean isSecure() {
+			return false;
+		}
+
+		@Override
+		public RequestDispatcher getRequestDispatcher(String path) {
+			return null;
+		}
+
+		@Override
+		public String getRealPath(String path) {
+			return null;
+		}
+
+		@Override
+		public int getRemotePort() {
+			return 0;
+		}
+
+		@Override
+		public String getLocalName() {
+			return null;
+		}
+
+		@Override
+		public String getLocalAddr() {
+			return null;
+		}
+
+		@Override
+		public int getLocalPort() {
+			return 0;
+		}
+
+		@Override
+		public ServletContext getServletContext() {
+			return null;
+		}
+
+		@Override
+		public AsyncContext startAsync() throws IllegalStateException {
+			return null;
+		}
+
+		@Override
+		public AsyncContext startAsync(ServletRequest servletRequest,
+				ServletResponse servletResponse)
+						throws IllegalStateException {
+			return null;
+		}
+
+		@Override
+		public boolean isAsyncStarted() {
+			return false;
+		}
+
+		@Override
+		public boolean isAsyncSupported() {
+			return false;
+		}
+
+		@Override
+		public AsyncContext getAsyncContext() {
+			return null;
+		}
+
+		@Override
+		public DispatcherType getDispatcherType() {
+			return null;
+		}
+
+		@Override
+		public String getAuthType() {
+			return null;
+		}
+
+		@Override
+		public Cookie[] getCookies() {
+			return null;
+		}
+
+		@Override
+		public long getDateHeader(String name) {
+			return 0;
+		}
+
+		@Override
+		public String getHeader(String name) {
+			return null;
+		}
+
+		@Override
+		public Enumeration<String> getHeaders(String name) {
+			return null;
+		}
+
+		@Override
+		public Enumeration<String> getHeaderNames() {
+			return null;
+		}
+
+		@Override
+		public int getIntHeader(String name) {
+			return 0;
+		}
+
+		@Override
+		public String getMethod() {
+			return null;
+		}
+
+		@Override
+		public String getPathInfo() {
+			return null;
+		}
+
+		@Override
+		public String getPathTranslated() {
+			return null;
+		}
+
+		@Override
+		public String getContextPath() {
+			return null;
+		}
+
+		@Override
+		public String getQueryString() {
+			return null;
+		}
+
+		@Override
+		public String getRemoteUser() {
+			return null;
+		}
+
+		@Override
+		public boolean isUserInRole(String role) {
+			if(role != null && "admin".equals(role)) {
+				return true;
+			}
+			return false;
+		}
+
+		@Override
+		public Principal getUserPrincipal() {
+			return new Principal(){
+				@Override
+				public String getName() {
+					return "sunnyjim";
+				}
+
+			};
+		}
+
+		@Override
+		public String getRequestedSessionId() {
+			return null;
+		}
+
+		@Override
+		public String getRequestURI() {
+			return null;
+		}
+
+		@Override
+		public StringBuffer getRequestURL() {
+			return null;
+		}
+
+		@Override
+		public String getServletPath() {
+			return null;
+		}
+
+		@Override
+		public HttpSession getSession(boolean create) {
+			return null;
+		}
+
+		final Map<String, Object> sessionAttributes = new HashMap<String, Object>();
+		@Override
+		public HttpSession getSession() {
+			return new HttpSession() {
+
+				@Override
+				public long getCreationTime() {
+					return 0;
+				}
+
+				@Override
+				public String getId() {
+					return null;
+				}
+
+				@Override
+				public long getLastAccessedTime() {
+					return 0;
+				}
+
+				@Override
+				public ServletContext getServletContext() {
+					return null;
+				}
+
+				@Override
+				public void setMaxInactiveInterval(int interval) {
+				}
+
+				@Override
+				public int getMaxInactiveInterval() {
+					return 0;
+				}
+
+				@Override
+				public HttpSessionContext getSessionContext() {
+					return null;
+				}
+
+				@Override
+				public Object getAttribute(String name) {
+					return sessionAttributes.get(name);
+				}
+
+				@Override
+				public Object getValue(String name) {
+					return null;
+				}
+
+				@Override
+				public Enumeration<String> getAttributeNames() {
+					return Collections.enumeration(sessionAttributes.keySet());
+				}
+
+				@Override
+				public String[] getValueNames() {
+					return null;
+				}
+
+				@Override
+				public void setAttribute(String name,
+						Object value) {
+				}
+
+				@Override
+				public void putValue(String name, Object value) {
+				}
+
+				@Override
+				public void removeAttribute(String name) {
+				}
+
+				@Override
+				public void removeValue(String name) {
+				}
+
+				@Override
+				public void invalidate() {
+				}
+
+				@Override
+				public boolean isNew() {
+					return false;
+				}
+
+			};
+		}
+
+		@Override
+		public String changeSessionId() {
+			return null;
+		}
+
+		@Override
+		public boolean isRequestedSessionIdValid() {
+			return false;
+		}
+
+		@Override
+		public boolean isRequestedSessionIdFromCookie() {
+			return false;
+		}
+
+		@Override
+		public boolean isRequestedSessionIdFromURL() {
+			return false;
+		}
+
+		@Override
+		public boolean isRequestedSessionIdFromUrl() {
+			return false;
+		}
+
+		@Override
+		public boolean authenticate(HttpServletResponse response)
+				throws IOException, ServletException {
+			return false;
+		}
+
+		@Override
+		public void login(String username, String password)
+				throws ServletException {
+		}
+
+		@Override
+		public void logout() throws ServletException {
+		}
+
+		@Override
+		public Collection<Part> getParts() throws IOException,
+		ServletException {
+			return null;
+		}
+
+		@Override
+		public Part getPart(String name) throws IOException,
+		ServletException {
+			return null;
+		}
+
+		@Override
+		public <T extends HttpUpgradeHandler> T upgrade(
+				Class<T> handlerClass) throws IOException,
+				ServletException {
+			return null;
+		}
+
+	}
+
+	HashMap<String, Object> settings = new HashMap<String, Object>();
+
+	MemorySettings getSettings() {
+		return new MemorySettings(settings);
+	}
+
+	IAuthenticationManager newAuthenticationManager() {
+		XssFilter xssFilter = new AllowXssFilter();
+		RuntimeManager runtime = new RuntimeManager(getSettings(), xssFilter, GitBlitSuite.BASEFOLDER).start();
+		users = new UserManager(runtime, null).start();
+		final Map<String, UserModel> virtualUsers = new HashMap<String, UserModel>();
+		users.setUserService(new IUserService() {
+
+			@Override
+			public void setup(IRuntimeManager runtimeManager) {
+			}
+
+			@Override
+			public String getCookie(UserModel model) {
+				return null;
+			}
+
+			@Override
+			public UserModel getUserModel(char[] cookie) {
+				return null;
+			}
+
+			@Override
+			public UserModel getUserModel(String username) {
+				return virtualUsers.get(username);
+			}
+
+			@Override
+			public boolean updateUserModel(UserModel model) {
+				virtualUsers.put(model.username, model);
+				return true;
+			}
+
+			@Override
+			public boolean updateUserModels(Collection<UserModel> models) {
+				return false;
+			}
+
+			@Override
+			public boolean updateUserModel(String username, UserModel model) {
+				virtualUsers.put(username, model);
+				return true;
+			}
+
+			@Override
+			public boolean deleteUserModel(UserModel model) {
+				return false;
+			}
+
+			@Override
+			public boolean deleteUser(String username) {
+				return false;
+			}
+
+			@Override
+			public List<String> getAllUsernames() {
+				return null;
+			}
+
+			@Override
+			public List<UserModel> getAllUsers() {
+				return null;
+			}
+
+			@Override
+			public List<String> getAllTeamNames() {
+				return null;
+			}
+
+			@Override
+			public List<TeamModel> getAllTeams() {
+				return null;
+			}
+
+			@Override
+			public List<String> getTeamNamesForRepositoryRole(String role) {
+				return null;
+			}
+
+			@Override
+			public TeamModel getTeamModel(String teamname) {
+				return null;
+			}
+
+			@Override
+			public boolean updateTeamModel(TeamModel model) {
+				return false;
+			}
+
+			@Override
+			public boolean updateTeamModels(Collection<TeamModel> models) {
+				return false;
+			}
+
+			@Override
+			public boolean updateTeamModel(String teamname, TeamModel model) {
+				return false;
+			}
+
+			@Override
+			public boolean deleteTeamModel(TeamModel model) {
+				return false;
+			}
+
+			@Override
+			public boolean deleteTeam(String teamname) {
+				return false;
+			}
+
+			@Override
+			public List<String> getUsernamesForRepositoryRole(String role) {
+				return null;
+			}
+
+			@Override
+			public boolean renameRepositoryRole(String oldRole,
+					String newRole) {
+				return false;
+			}
+
+			@Override
+			public boolean deleteRepositoryRole(String role) {
+				return false;
+			}
+
+		});
+		AuthenticationManager auth = new AuthenticationManager(runtime, users).start();
+		return auth;
+	}
+
+	@Test
+	public void testAuthenticate() throws Exception {
+		IAuthenticationManager auth = newAuthenticationManager();
+
+		UserModel user = new UserModel("sunnyjim");
 		user.password = "password";
 		users.updateUserModel(user);
 
@@ -65,5 +663,48 @@
 		users.updateUserModel(user);
 		assertNull(auth.authenticate(user.username, user.password.toCharArray()));
 		users.deleteUserModel(user);
-    }
+	}
+
+	@Test
+	public void testContenairAuthenticate() throws Exception {
+		settings.put(Keys.realm.container.autoCreateAccounts, "true");
+		settings.put(Keys.realm.container.autoAccounts.displayName, "displayName");
+		settings.put(Keys.realm.container.autoAccounts.emailAddress, "emailAddress");
+		settings.put(Keys.realm.container.autoAccounts.adminRole, "admin");
+		settings.put(Keys.realm.container.autoAccounts.locale, "locale");
+
+		DummyHttpServletRequest request = new DummyHttpServletRequest();
+		request.sessionAttributes.put("displayName", "Sunny Jim");
+		request.sessionAttributes.put("emailAddress", "Jim.Sunny@gitblit.com");
+		request.sessionAttributes.put("locale", "it");
+
+		IAuthenticationManager auth = newAuthenticationManager();
+
+		UserModel user = auth.authenticate(request);
+
+		assertTrue(user.canAdmin);
+		assertEquals("Sunny Jim", user.displayName);
+		assertEquals("Jim.Sunny@gitblit.com", user.emailAddress);
+		assertEquals(Locale.ITALIAN, user.getPreferences().getLocale());
+	}
+
+	@Test
+	public void testContenairAuthenticateEmpty() throws Exception {
+		settings.put(Keys.realm.container.autoCreateAccounts, "true");
+		settings.put(Keys.realm.container.autoAccounts.displayName, "displayName");
+		settings.put(Keys.realm.container.autoAccounts.emailAddress, "emailAddress");
+		settings.put(Keys.realm.container.autoAccounts.adminRole, "notAdmin");
+
+		DummyHttpServletRequest request = new DummyHttpServletRequest();
+
+		IAuthenticationManager auth = newAuthenticationManager();
+
+		UserModel user = auth.authenticate(request);
+
+		assertFalse(user.canAdmin);
+		assertEquals("sunnyjim", user.displayName);
+		assertNull(user.emailAddress);
+		assertNull(user.getPreferences().getLocale());
+	}
+
 }
diff --git a/src/test/java/com/gitblit/tests/JschConfigTestSessionFactory.java b/src/test/java/com/gitblit/tests/JschConfigTestSessionFactory.java
index 5d24b40..421f336 100644
--- a/src/test/java/com/gitblit/tests/JschConfigTestSessionFactory.java
+++ b/src/test/java/com/gitblit/tests/JschConfigTestSessionFactory.java
@@ -21,6 +21,7 @@
     @Override
     protected void configure(OpenSshConfig.Host host, Session session) {
         session.setConfig("StrictHostKeyChecking", "no");
+        session.setConfig("PreferredAuthentications", "password");
     }
 
     @Override
diff --git a/src/test/java/com/gitblit/tests/SshUnitTest.java b/src/test/java/com/gitblit/tests/SshUnitTest.java
index 43b51b7..3def700 100644
--- a/src/test/java/com/gitblit/tests/SshUnitTest.java
+++ b/src/test/java/com/gitblit/tests/SshUnitTest.java
@@ -24,13 +24,18 @@
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.sshd.ClientChannel;
 import org.apache.sshd.ClientSession;
 import org.apache.sshd.SshClient;
 import org.apache.sshd.client.ServerKeyVerifier;
+import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.util.SecurityUtils;
+import org.apache.sshd.client.UserAuth;
+import org.apache.sshd.client.auth.UserAuthPublicKey;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -102,6 +107,9 @@
 				return true;
 			}
 		});
+		List<NamedFactory<UserAuth>> userAuthFactories = new ArrayList<>();
+		userAuthFactories.add(new UserAuthPublicKey.Factory());
+		client.setUserAuthFactories(userAuthFactories);
 		client.start();
 		return client;
 	}

--
Gitblit v1.9.1