From 0d232164930581ccc9eac1b54e4c624a62f107bd Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Thu, 10 Apr 2014 18:58:08 -0400 Subject: [PATCH] Pass IGitblit into the SSH command context --- src/main/java/com/gitblit/transport/ssh/SshDaemon.java | 118 +++++++++++++++++++++++++++++++++++----------------------- 1 files changed, 71 insertions(+), 47 deletions(-) diff --git a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java index f0429a7..b6c5d68 100644 --- a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java +++ b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java @@ -24,31 +24,21 @@ 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; import org.slf4j.LoggerFactory; +import com.gitblit.Constants; import com.gitblit.IStoredSettings; import com.gitblit.Keys; -import com.gitblit.git.GitblitReceivePackFactory; -import com.gitblit.git.GitblitUploadPackFactory; -import com.gitblit.git.RepositoryResolver; +import com.gitblit.manager.IAuthenticationManager; 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.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; @@ -68,7 +58,7 @@ 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 @@ -93,7 +83,7 @@ public SshDaemon(IGitblit gitblit, IdGenerator idGenerator) { this.gitblit = gitblit; 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, @@ -108,7 +98,7 @@ backend == SshSessionBackend.MINA ? MinaServiceFactoryFactory.class.getName() : Nio2ServiceFactoryFactory.class.getName()); - + InetSocketAddress addr; if (StringUtils.isEmpty(bindInterface)) { addr = new InetSocketAddress(port); @@ -116,40 +106,47 @@ addr = new InetSocketAddress(bindInterface, port); } + File hostKeyStore = new File(gitblit.getBaseFolder(), HOST_KEY_STORE); + CachingPublicKeyAuthenticator keyAuthenticator = + getPublicKeyAuthenticator(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(keyManager, gitblit)); - sshd.setPasswordAuthenticator(new SshPasswordAuthenticator(gitblit)); - sshd.setSessionFactory(new SshSessionFactory(idGenerator)); + sshd.setKeyPairProvider(new PEMGeneratorHostKeyProvider(hostKeyStore.getPath())); + sshd.setPublickeyAuthenticator(keyAuthenticator); + sshd.setPasswordAuthenticator(new UsernamePasswordAuthenticator(gitblit)); + sshd.setSessionFactory(new SshServerSessionFactory()); sshd.setFileSystemFactory(new DisabledFilesystemFactory()); sshd.setTcpipForwardingFilter(new NonForwardingFilter()); + sshd.setCommandFactory(new SshCommandFactory(gitblit, keyAuthenticator, idGenerator)); + sshd.setShellFactory(new WelcomeShell(settings)); - DispatchCommand gitblitCmd = new DispatchCommand(); - gitblitCmd.registerCommand(CreateRepository.class); - gitblitCmd.registerCommand(VersionCommand.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)); - - SshCommandFactory commandFactory = new SshCommandFactory( - new WorkQueue(idGenerator), - root); - - sshd.setCommandFactory(commandFactory); + String version = Constants.getGitBlitVersion() + " (" + sshd.getVersion() + ")"; + sshd.getProperties().put(SshServer.SERVER_IDENTIFICATION, version); run = new AtomicBoolean(false); + } + + private CachingPublicKeyAuthenticator getPublicKeyAuthenticator( + IKeyManager keyManager, IGitblit gitblit) { + IStoredSettings settings = gitblit.getSettings(); + String clazz = settings.getString(Keys.git.sshPublicKeyAuthenticator, + CachingPublicKeyAuthenticator.class.getName()); + if (StringUtils.isEmpty(clazz)) { + clazz = CachingPublicKeyAuthenticator.class.getName(); + } + try { + Class<CachingPublicKeyAuthenticator> authClass = + (Class<CachingPublicKeyAuthenticator>) Class.forName(clazz); + return authClass.getConstructor( + new Class[] { IKeyManager.class, + IAuthenticationManager.class }).newInstance( + keyManager, gitblit); + } catch (Exception e) { + log.error("failed to create ssh auth manager " + clazz, e); + } + return null; } public String formatUrl(String gituser, String servername, String repository) { @@ -180,9 +177,12 @@ sshd.start(); run.set(true); + String sshBackendStr = gitblit.getSettings().getString(Keys.git.sshBackend, + SshSessionBackend.NIO2.name()); + log.info(MessageFormat.format( - "SSH Daemon is listening on {0}:{1,number,0}", - sshd.getHost(), sshd.getPort())); + "SSH Daemon ({0}) is listening on {1}:{2,number,0}", + sshBackendStr, sshd.getHost(), sshd.getPort())); } /** @return true if this daemon is receiving connections. */ @@ -203,14 +203,15 @@ } } } - + + @SuppressWarnings("unchecked") 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(); @@ -225,7 +226,30 @@ } return keyManager; } - + + @SuppressWarnings("unchecked") + protected IKeyManager getKeyAuthenticator() { + 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. @@ -245,7 +269,7 @@ @Provides @Singleton NullKeyManager provideNullKeyManager() { return new NullKeyManager(); } - + @Provides @Singleton FileKeyManager provideFileKeyManager() { return new FileKeyManager(SshDaemon.this.gitblit); } -- Gitblit v1.9.1