From 5eafd9b6f046a03eca0576ae14673be674b9ce01 Mon Sep 17 00:00:00 2001 From: David Ostrovsky <david@ostrovsky.org> Date: Thu, 10 Apr 2014 18:58:08 -0400 Subject: [PATCH] Add set account SSH command --- src/main/java/com/gitblit/transport/ssh/SshDaemon.java | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 102 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java index 42ee67a..f2e1db7 100644 --- a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java +++ b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java @@ -21,7 +21,15 @@ import java.text.MessageFormat; import java.util.concurrent.atomic.AtomicBoolean; +import javax.inject.Singleton; + import org.apache.sshd.SshServer; +import org.apache.sshd.common.io.IoServiceFactory; +import org.apache.sshd.common.io.IoServiceFactoryFactory; +import org.apache.sshd.common.io.mina.MinaServiceFactory; +import org.apache.sshd.common.io.mina.MinaServiceFactoryFactory; +import org.apache.sshd.common.io.nio2.Nio2ServiceFactory; +import org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory; import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider; import org.eclipse.jgit.internal.JGitText; import org.slf4j.Logger; @@ -35,14 +43,21 @@ import com.gitblit.manager.IGitblit; import com.gitblit.transport.ssh.commands.CreateRepository; import com.gitblit.transport.ssh.commands.DispatchCommand; +import com.gitblit.transport.ssh.commands.Receive; +import com.gitblit.transport.ssh.commands.SetAccountCommand; +import com.gitblit.transport.ssh.commands.Upload; import com.gitblit.transport.ssh.commands.VersionCommand; import com.gitblit.utils.IdGenerator; import com.gitblit.utils.StringUtils; import com.gitblit.utils.WorkQueue; +import dagger.Module; +import dagger.ObjectGraph; +import dagger.Provides; + /** * Manager for the ssh transport. Roughly analogous to the - * {@link com.gitblit.git.GitDaemon} class. + * {@link com.gitblit.transport.git.GitDaemon} class. * * @author Eric Myhre * @@ -51,6 +66,10 @@ private final Logger log = LoggerFactory.getLogger(SshDaemon.class); + public static enum SshSessionBackend { + MINA, NIO2 + } + /** * 22: IANA assigned port number for ssh. Note that this is a distinct * concept from gitblit's default conf for ssh port -- this "default" is @@ -63,12 +82,9 @@ private final AtomicBoolean run; - @SuppressWarnings("unused") private final IGitblit gitblit; - - private final IdGenerator idGenerator; - private final SshServer sshd; + private final ObjectGraph injector; /** * Construct the Gitblit SSH daemon. @@ -77,13 +93,23 @@ */ public SshDaemon(IGitblit gitblit, IdGenerator idGenerator) { this.gitblit = gitblit; - this.idGenerator = idGenerator; - + this.injector = ObjectGraph.create(new SshModule()); + IStoredSettings settings = gitblit.getSettings(); int port = settings.getInteger(Keys.git.sshPort, 0); String bindInterface = settings.getString(Keys.git.sshBindInterface, "localhost"); + IKeyManager keyManager = getKeyManager(); + + String sshBackendStr = settings.getString(Keys.git.sshBackend, + SshSessionBackend.NIO2.name()); + SshSessionBackend backend = SshSessionBackend.valueOf(sshBackendStr); + System.setProperty(IoServiceFactoryFactory.class.getName(), + backend == SshSessionBackend.MINA + ? MinaServiceFactoryFactory.class.getName() + : Nio2ServiceFactoryFactory.class.getName()); + InetSocketAddress addr; if (StringUtils.isEmpty(bindInterface)) { addr = new InetSocketAddress(port); @@ -91,27 +117,40 @@ addr = new InetSocketAddress(bindInterface, port); } + SshKeyAuthenticator publickeyAuthenticator = new SshKeyAuthenticator( + keyManager, gitblit); sshd = SshServer.setUpDefaultServer(); sshd.setPort(addr.getPort()); sshd.setHost(addr.getHostName()); sshd.setKeyPairProvider(new PEMGeneratorHostKeyProvider(new File( gitblit.getBaseFolder(), HOST_KEY_STORE).getPath())); - sshd.setPublickeyAuthenticator(new SshKeyAuthenticator(gitblit)); + sshd.setPublickeyAuthenticator(publickeyAuthenticator); sshd.setPasswordAuthenticator(new SshPasswordAuthenticator(gitblit)); sshd.setSessionFactory(new SshSessionFactory(idGenerator)); sshd.setFileSystemFactory(new DisabledFilesystemFactory()); - sshd.setForwardingFilter(new NonForwardingFilter()); + sshd.setTcpipForwardingFilter(new NonForwardingFilter()); - DispatchCommand dispatcher = new DispatchCommand(); - dispatcher.registerCommand(CreateRepository.class); - dispatcher.registerCommand(VersionCommand.class); + DispatchCommand gitblitCmd = new DispatchCommand(); + gitblitCmd.registerCommand(CreateRepository.class); + gitblitCmd.registerCommand(VersionCommand.class); + gitblitCmd.registerCommand(SetAccountCommand.class); + + DispatchCommand gitCmd = new DispatchCommand(); + gitCmd.registerCommand(Upload.class); + gitCmd.registerCommand(Receive.class); + + DispatchCommand root = new DispatchCommand(); + root.registerDispatcher("gitblit", gitblitCmd); + root.registerDispatcher("git", gitCmd); + + root.setRepositoryResolver(new RepositoryResolver<SshSession>(gitblit)); + root.setUploadPackFactory(new GitblitUploadPackFactory<SshSession>(gitblit)); + root.setReceivePackFactory(new GitblitReceivePackFactory<SshSession>(gitblit)); + root.setAuthenticator(publickeyAuthenticator); SshCommandFactory commandFactory = new SshCommandFactory( - new RepositoryResolver<SshSession>(gitblit), - new GitblitUploadPackFactory<SshSession>(gitblit), - new GitblitReceivePackFactory<SshSession>(gitblit), new WorkQueue(idGenerator), - dispatcher); + root); sshd.setCommandFactory(commandFactory); @@ -169,4 +208,51 @@ } } } + + protected IKeyManager getKeyManager() { + IKeyManager keyManager = null; + IStoredSettings settings = gitblit.getSettings(); + String clazz = settings.getString(Keys.git.sshKeysManager, FileKeyManager.class.getName()); + if (StringUtils.isEmpty(clazz)) { + clazz = FileKeyManager.class.getName(); + } + try { + Class<? extends IKeyManager> managerClass = (Class<? extends IKeyManager>) Class.forName(clazz); + keyManager = injector.get(managerClass).start(); + if (keyManager.isReady()) { + log.info("{} is ready.", keyManager); + } else { + log.warn("{} is disabled.", keyManager); + } + } catch (Exception e) { + log.error("failed to create ssh key manager " + clazz, e); + keyManager = injector.get(NullKeyManager.class).start(); + } + return keyManager; + } + + /** + * A nested Dagger graph is used for constructor dependency injection of + * complex classes. + * + * @author James Moger + * + */ + @Module( + library = true, + injects = { + NullKeyManager.class, + FileKeyManager.class + } + ) + class SshModule { + + @Provides @Singleton NullKeyManager provideNullKeyManager() { + return new NullKeyManager(); + } + + @Provides @Singleton FileKeyManager provideFileKeyManager() { + return new FileKeyManager(SshDaemon.this.gitblit); + } + } } -- Gitblit v1.9.1