@@ -138,27 +138,21 @@ git.sshKeysManager = com.gitblit.transport.ssh.FileKeyManager | |||
# SINCE 1.5.0 | |||
git.sshKeysFolder= ${baseFolder}/ssh | |||
# Use kerberos5 (GSS) authentication | |||
# Use Kerberos5 (GSS) authentication | |||
# | |||
# SINCE 1.7.0 | |||
git.sshWithKrb5 = "false" | |||
git.sshWithKrb5 = false | |||
# The path to a kerberos 5 keytab. | |||
# The path to a Kerberos 5 keytab. | |||
# | |||
# SINCE 1.7.0 | |||
git.sshKrb5Keytab = "" | |||
git.sshKrb5Keytab = | |||
# The service principal name to be used for Kerberos5. The default is host/hostname. | |||
# 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" | |||
git.sshKrb5ServicePrincipalName = | |||
# SSH backend NIO2|MINA. | |||
# |
@@ -23,24 +23,14 @@ 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.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.util.SecurityUtils; | |||
import org.apache.sshd.server.SshServer; | |||
import org.apache.sshd.server.auth.CachingPublicKeyAuthenticator; | |||
import org.apache.sshd.server.auth.UserAuth; | |||
import org.apache.sshd.server.auth.UserAuthKeyboardInteractiveFactory; | |||
import org.apache.sshd.server.auth.UserAuthPasswordFactory; | |||
import org.apache.sshd.server.auth.UserAuthPublicKeyFactory; | |||
import org.apache.sshd.server.auth.gss.GSSAuthenticator; | |||
import org.apache.sshd.server.auth.gss.UserAuthGSSFactory; | |||
import org.bouncycastle.openssl.PEMWriter; | |||
import org.eclipse.jgit.internal.JGitText; | |||
import org.slf4j.Logger; | |||
@@ -130,48 +120,6 @@ public class SshDaemon { | |||
addr = new InetSocketAddress(bindInterface, port); | |||
} | |||
//Will do GSS ? | |||
GSSAuthenticator gssAuthenticator = null; | |||
if(settings.getBoolean(Keys.git.sshWithKrb5, false)) { | |||
gssAuthenticator = new SshKrbAuthenticator(gitblit); | |||
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 UserAuthGSSFactory()); | |||
} | |||
break; | |||
case "publickey": | |||
userAuthFactories.add(new UserAuthPublicKeyFactory()); | |||
break; | |||
case "password": | |||
userAuthFactories.add(new UserAuthPasswordFactory()); | |||
break; | |||
case "keyboard-interactive": | |||
userAuthFactories.add(new UserAuthKeyboardInteractiveFactory()); | |||
break; | |||
default: | |||
log.error("Unknown ssh authenticator: '{}'", authenticatorName); | |||
} | |||
} | |||
// Create the SSH server | |||
sshd = SshServer.setUpDefaultServer(); | |||
sshd.setPort(addr.getPort()); | |||
@@ -179,10 +127,9 @@ public class SshDaemon { | |||
sshd.setKeyPairProvider(hostKeyPairProvider); | |||
sshd.setPublickeyAuthenticator(new CachingPublicKeyAuthenticator(keyAuthenticator)); | |||
sshd.setPasswordAuthenticator(new UsernamePasswordAuthenticator(gitblit)); | |||
if(gssAuthenticator != null) { | |||
sshd.setGSSAuthenticator(gssAuthenticator); | |||
if (settings.getBoolean(Keys.git.sshWithKrb5, false)) { | |||
sshd.setGSSAuthenticator(new SshKrbAuthenticator(settings, gitblit)); | |||
} | |||
sshd.setUserAuthFactories(userAuthFactories); | |||
sshd.setSessionFactory(new SshServerSessionFactory()); | |||
sshd.setFileSystemFactory(new DisabledFilesystemFactory()); | |||
sshd.setTcpipForwardingFilter(new NonForwardingFilter()); |
@@ -15,27 +15,41 @@ | |||
*/ | |||
package com.gitblit.transport.ssh; | |||
import com.gitblit.manager.IAuthenticationManager; | |||
import com.gitblit.models.UserModel; | |||
import java.util.Locale; | |||
import org.apache.sshd.server.auth.gss.GSSAuthenticator; | |||
import org.apache.sshd.server.session.ServerSession; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import com.gitblit.IStoredSettings; | |||
import com.gitblit.Keys; | |||
import com.gitblit.manager.IAuthenticationManager; | |||
import com.gitblit.models.UserModel; | |||
public class SshKrbAuthenticator extends GSSAuthenticator { | |||
protected final Logger log = LoggerFactory.getLogger(getClass()); | |||
protected final IAuthenticationManager authManager; | |||
public SshKrbAuthenticator(IAuthenticationManager authManager) { | |||
public SshKrbAuthenticator(IStoredSettings settings, IAuthenticationManager authManager) { | |||
this.authManager = authManager; | |||
log.info("registry {}", authManager); | |||
String keytabString = settings.getString(Keys.git.sshKrb5Keytab, ""); | |||
if(! keytabString.isEmpty()) { | |||
setKeytabFile(keytabString); | |||
} | |||
String servicePrincipalName = settings.getString(Keys.git.sshKrb5ServicePrincipalName, ""); | |||
if(! servicePrincipalName.isEmpty()) { | |||
setServicePrincipalName(servicePrincipalName); | |||
} | |||
} | |||
@Override | |||
public boolean validateIdentity(ServerSession session, String identity) { | |||
log.info("identify with kerberos {}", identity); | |||
SshDaemonClient client = (SshDaemonClient)session.getAttribute(SshDaemonClient.KEY); | |||
SshDaemonClient client = session.getAttribute(SshDaemonClient.KEY); | |||
if (client.getUser() != null) { | |||
log.info("{} has already authenticated!", identity); | |||
return true; |
@@ -9,8 +9,6 @@ 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 |
@@ -21,7 +21,6 @@ public class JschConfigTestSessionFactory extends JschConfigSessionFactory { | |||
@Override | |||
protected void configure(OpenSshConfig.Host host, Session session) { | |||
session.setConfig("StrictHostKeyChecking", "no"); | |||
session.setConfig("PreferredAuthentications", "password"); | |||
} | |||
@Override |
@@ -27,6 +27,7 @@ import com.gitblit.manager.AuthenticationManager; | |||
import com.gitblit.manager.IRuntimeManager; | |||
import com.gitblit.manager.IUserManager; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.tests.mock.MemorySettings; | |||
import com.gitblit.transport.ssh.SshDaemonClient; | |||
import com.gitblit.transport.ssh.SshKrbAuthenticator; | |||
@@ -39,20 +40,21 @@ public class SshKerberosAuthenticationTest extends GitblitUnitTest { | |||
@Test | |||
public void testUserManager() { | |||
IRuntimeManager rm = Mockito.mock(IRuntimeManager.class); | |||
//Build an UserManager that can build a UserModel | |||
IUserManager im = Mockito.mock(IUserManager.class); | |||
Mockito.doAnswer(new Answer<Object>() { | |||
@Override | |||
public Object answer(InvocationOnMock invocation) { | |||
Object[] args = invocation.getArguments(); | |||
String user = (String) args[0]; | |||
return new UserModel(user); | |||
} | |||
} | |||
}).when(im).getUserModel(Mockito.anyString()); | |||
AuthenticationManager am = new AuthenticationManager(rm, im); | |||
GSSAuthenticator gssAuthenticator = new SshKrbAuthenticator(am); | |||
GSSAuthenticator gssAuthenticator = new SshKrbAuthenticator(new MemorySettings(), am); | |||
ServerSession session = Mockito.mock(ServerSession.class); | |||
@@ -61,12 +63,13 @@ public class SshKerberosAuthenticationTest extends GitblitUnitTest { | |||
SshDaemonClient client = Mockito.mock(SshDaemonClient.class); | |||
Mockito.when(client.getUser()).thenReturn(umw.um); | |||
Mockito.doAnswer(new Answer<Object>() { | |||
@Override | |||
public Object answer(InvocationOnMock invocation) { | |||
Object[] args = invocation.getArguments(); | |||
UserModel um = (UserModel) args[0]; | |||
umw.um = um; | |||
return null; | |||
} | |||
} | |||
}).when(client).setUser(Mockito.any(UserModel.class)); | |||
Mockito.when(session.getAttribute(SshDaemonClient.KEY)).thenReturn(client); |
@@ -24,17 +24,12 @@ 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.client.ServerKeyVerifier; | |||
import org.apache.sshd.client.SshClient; | |||
import org.apache.sshd.client.auth.UserAuth; | |||
import org.apache.sshd.client.auth.UserAuthPublicKeyFactory; | |||
import org.apache.sshd.client.channel.ClientChannel; | |||
import org.apache.sshd.client.session.ClientSession; | |||
import org.apache.sshd.common.NamedFactory; | |||
import org.apache.sshd.common.util.SecurityUtils; | |||
import org.junit.After; | |||
import org.junit.AfterClass; | |||
@@ -107,9 +102,6 @@ public abstract class SshUnitTest extends GitblitUnitTest { | |||
return true; | |||
} | |||
}); | |||
List<NamedFactory<UserAuth>> userAuthFactories = new ArrayList<>(); | |||
userAuthFactories.add(new UserAuthPublicKeyFactory()); | |||
client.setUserAuthFactories(userAuthFactories); | |||
client.start(); | |||
return client; | |||
} |