Eddy Young
2015-05-22 410c92f5c71c93cd2b4b0a1d9ee4067c34b80c66
Merge branch 'develop' into ticket #57_develop
2 files added
9 files modified
1041 ■■■■■ changed files
.gitignore 1 ●●●● patch | view | raw | blame | history
nbproject/project.xml 135 ●●●●● patch | view | raw | blame | history
src/main/distrib/data/defaults.properties 38 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/guice/WebModule.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/manager/AuthenticationManager.java 48 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/servlet/AccessDeniedServlet.java 63 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/SshDaemon.java 58 ●●●●● patch | view | raw | blame | history
src/test/config/test-gitblit.properties 2 ●●●●● patch | view | raw | blame | history
src/test/java/com/gitblit/tests/AuthenticationManagerTest.java 675 ●●●●● patch | view | raw | blame | history
src/test/java/com/gitblit/tests/JschConfigTestSessionFactory.java 1 ●●●● patch | view | raw | blame | history
src/test/java/com/gitblit/tests/SshUnitTest.java 8 ●●●●● patch | view | raw | blame | history
.gitignore
@@ -28,3 +28,4 @@
/**/.idea
/**/init.lua
/**/session
/nbproject/private
nbproject/project.xml
New file
@@ -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>
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
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);
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.
src/main/java/com/gitblit/servlet/AccessDeniedServlet.java
New file
@@ -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);
    }
}
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());
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
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());
    }
}
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
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;
    }