Set list of offered SSH authentication methods.

Make the SSH authentication methods used by the server configurable,
so that for example password authentication can be turned off.

For this, a `git.sshAuthenticationMethods` setting is added which is a space
separated list of authentication method names. Only the methods listed will
be enabled in the server.
This is modeled after the option of the same name from sshd_config, but it
does not offer listing multiple required methods. It leaves the door open,
though, for a later extension to support such a multi-factor authentication.

Since this also includes Kerberos authentication with GSS API, this obsoletes
the `git.sshWithKrb5` property. The latter is removed. Instead, to enable
Kerberos5 authentication, add the method name `gssapi-with-mic` to the
authentication methods list.
diff --git a/src/main/distrib/data/defaults.properties b/src/main/distrib/data/defaults.properties
index 0c7d6cd..f0c59f6 100644
--- a/src/main/distrib/data/defaults.properties
+++ b/src/main/distrib/data/defaults.properties
@@ -138,10 +138,25 @@
 # SINCE 1.5.0
 git.sshKeysFolder= ${baseFolder}/ssh
 
-# Use Kerberos5 (GSS) authentication
+
+# Authentication methods offered by the SSH server.
+# Space separated list of authentication method names that the
+# server shall offer. The default is "publickey password".
 #
-# SINCE 1.7.0
-git.sshWithKrb5 = false
+# Valid authentication method names are:
+#   publickey             - authenticate with SSH public key
+#   password              - authenticate with username, password
+#   keyboard-interactive  - currently synonym to 'password'
+#   gssapi-with-mic       - GSS API Kerberos 5 authentication
+#
+# This setting obsoletes the "git.sshWithKrb5" setting. To enable
+# Kerberos5 (GSS) authentication, add 'gssapi-with-mic' to the list.
+#
+# SINCE 1.9.0
+# RESTART REQUIRED
+# SPACE-DELIMITED
+git.sshAuthenticationMethods = publickey password
+
 
 # The path to a Kerberos 5 keytab.
 #
diff --git a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
index 5a94c9a..3189058 100644
--- a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
+++ b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
@@ -23,6 +23,7 @@
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.text.MessageFormat;
+import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.sshd.common.io.IoServiceFactoryFactory;
@@ -55,6 +56,13 @@
 
 	private final Logger log = LoggerFactory.getLogger(SshDaemon.class);
 
+	private static final String AUTH_PUBLICKEY = "publickey";
+	private static final String AUTH_PASSWORD = "password";
+	private static final String AUTH_KBD_INTERACTIVE = "keyboard-interactive";
+	private static final String AUTH_GSSAPI = "gssapi-with-mic";
+
+
+
 	public static enum SshSessionBackend {
 		MINA, NIO2
 	}
@@ -97,9 +105,6 @@
 		FileKeyPairProvider hostKeyPairProvider = new FileKeyPairProvider();
 		hostKeyPairProvider.setFiles(new String [] { rsaKeyStore.getPath(), dsaKeyStore.getPath(), dsaKeyStore.getPath() });
 
-		// Client public key authenticator
-		SshKeyAuthenticator keyAuthenticator =
-				new SshKeyAuthenticator(gitblit.getPublicKeyManager(), gitblit);
 
 		// Configure the preferred SSHD backend
 		String sshBackendStr = settings.getString(Keys.git.sshBackend,
@@ -125,11 +130,34 @@
 		sshd.setPort(addr.getPort());
 		sshd.setHost(addr.getHostName());
 		sshd.setKeyPairProvider(hostKeyPairProvider);
-		sshd.setPublickeyAuthenticator(new CachingPublicKeyAuthenticator(keyAuthenticator));
-		sshd.setPasswordAuthenticator(new UsernamePasswordAuthenticator(gitblit));
-		if (settings.getBoolean(Keys.git.sshWithKrb5, false)) {
-			sshd.setGSSAuthenticator(new SshKrbAuthenticator(settings, gitblit));
+
+		List<String> authMethods = settings.getStrings(Keys.git.sshAuthenticationMethods);
+		if (authMethods.isEmpty()) {
+			authMethods.add(AUTH_PUBLICKEY);
+			authMethods.add(AUTH_PASSWORD);
 		}
+		// Keep backward compatibility with old setting files that use the git.sshWithKrb5 setting.
+		if (settings.getBoolean("git.sshWithKrb5", false) && !authMethods.contains(AUTH_GSSAPI)) {
+			authMethods.add(AUTH_GSSAPI);
+			log.warn("git.sshWithKrb5 is obsolete!");
+			log.warn("Please add {} to {} in gitblit.properties!", AUTH_GSSAPI, Keys.git.sshAuthenticationMethods);
+			settings.overrideSetting(Keys.git.sshAuthenticationMethods,
+					settings.getString(Keys.git.sshAuthenticationMethods, AUTH_PUBLICKEY + " " + AUTH_PASSWORD) + " " + AUTH_GSSAPI);
+		}
+		if (authMethods.contains(AUTH_PUBLICKEY)) {
+			SshKeyAuthenticator keyAuthenticator = new SshKeyAuthenticator(gitblit.getPublicKeyManager(), gitblit);
+			sshd.setPublickeyAuthenticator(new CachingPublicKeyAuthenticator(keyAuthenticator));
+			log.info("SSH: adding public key authentication method.");
+		}
+		if (authMethods.contains(AUTH_PASSWORD) || authMethods.contains(AUTH_KBD_INTERACTIVE)) {
+			sshd.setPasswordAuthenticator(new UsernamePasswordAuthenticator(gitblit));
+			log.info("SSH: adding password authentication method.");
+		}
+		if (authMethods.contains(AUTH_GSSAPI)) {
+			sshd.setGSSAuthenticator(new SshKrbAuthenticator(settings, gitblit));
+			log.info("SSH: adding GSSAPI authentication method.");
+		}
+
 		sshd.setSessionFactory(new SshServerSessionFactory());
 		sshd.setFileSystemFactory(new DisabledFilesystemFactory());
 		sshd.setTcpipForwardingFilter(new NonForwardingFilter());