]> source.dussan.org Git - gitblit.git/commitdiff
Adding Kerberos5/GSS authentication to ssh 254/head 47/247/1
authorFabrice Bacchella <fbacchella@spamcop.net>
Mon, 4 May 2015 09:52:12 +0000 (11:52 +0200)
committerFabrice Bacchella <fbacchella@spamcop.net>
Mon, 4 May 2015 09:52:12 +0000 (11:52 +0200)
Adding the possibility to define authentication method order for ssh

src/main/distrib/data/defaults.properties
src/main/java/com/gitblit/transport/ssh/SshDaemon.java
src/test/config/test-gitblit.properties
src/test/java/com/gitblit/tests/JschConfigTestSessionFactory.java
src/test/java/com/gitblit/tests/SshUnitTest.java

index 0857ccf66f6805b0ba679b87f9d71eb5e0b0c356..ee97cb68648ad87f0562a6a3c9df528540182966 100644 (file)
@@ -126,6 +126,28 @@ git.sshKeysManager = com.gitblit.transport.ssh.FileKeyManager
 # 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.
index 9667154f8f4e0b6ea1e93365dc19c228d39f7a83..ec7d7c36a40ea34db346c61698ea0f8a18bb1d23 100644 (file)
@@ -23,15 +23,25 @@ import java.net.InetSocketAddress;
 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 @@ public class SshDaemon {
                } 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 @@ public class SshDaemon {
                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());
index 78e9ab957c926d4a37d132c9bc8c03eac163cdd9..398047c1d44e8e309a4b78dc008d0f962761586a 100644 (file)
@@ -9,6 +9,8 @@ git.enableGitServlet = true
 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
index 5d24b4017e7c9e22f1833f4750da0c8438d29ecb..421f3366611d41cdcab53cfb27c6c0dbddb56f3c 100644 (file)
@@ -21,6 +21,7 @@ public class JschConfigTestSessionFactory extends JschConfigSessionFactory {
     @Override\r
     protected void configure(OpenSshConfig.Host host, Session session) {\r
         session.setConfig("StrictHostKeyChecking", "no");\r
+        session.setConfig("PreferredAuthentications", "password");\r
     }\r
 \r
     @Override\r
index 43b51b744fde891588b86b1d5f2eee8ec1254d3c..3def700db6e401a1b75e77c5acbc507f884237a6 100644 (file)
@@ -24,13 +24,18 @@ import java.net.SocketAddress;
 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 @@ public abstract class SshUnitTest extends GitblitUnitTest {
                                return true;
                        }
                });
+               List<NamedFactory<UserAuth>> userAuthFactories = new ArrayList<>();
+               userAuthFactories.add(new UserAuthPublicKey.Factory());
+               client.setUserAuthFactories(userAuthFactories);
                client.start();
                return client;
        }