From: James Moger Date: Tue, 18 Mar 2014 01:30:46 +0000 (-0400) Subject: Elevate the public key manager to a top-level manager X-Git-Tag: v1.5.0~68^2~72 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=245836904ba5cecdc31773cf7c9616396c8ad8c0;p=gitblit.git Elevate the public key manager to a top-level manager --- diff --git a/src/main/distrib/data/gitblit.properties b/src/main/distrib/data/gitblit.properties index 52bb252b..64a52f5c 100644 --- a/src/main/distrib/data/gitblit.properties +++ b/src/main/distrib/data/gitblit.properties @@ -129,11 +129,6 @@ git.sshKeysFolder= ${baseFolder}/ssh # SINCE 1.5.0 git.sshBackend = NIO2 -# SSH public key authenticator -# -# SINCE 1.5.0 -git.sshPublicKeyAuthenticator = com.gitblit.transport.ssh.CachingPublicKeyAuthenticator - # Allow push/pull over http/https with JGit servlet. # If you do NOT want to allow Git clients to clone/push to Gitblit set this # to false. You might want to do this if you are only using ssh:// or git://. diff --git a/src/main/java/com/gitblit/DaggerModule.java b/src/main/java/com/gitblit/DaggerModule.java index 5ae8b253..b109f1db 100644 --- a/src/main/java/com/gitblit/DaggerModule.java +++ b/src/main/java/com/gitblit/DaggerModule.java @@ -32,6 +32,11 @@ import com.gitblit.manager.ProjectManager; import com.gitblit.manager.RepositoryManager; import com.gitblit.manager.RuntimeManager; import com.gitblit.manager.UserManager; +import com.gitblit.transport.ssh.FileKeyManager; +import com.gitblit.transport.ssh.IPublicKeyManager; +import com.gitblit.transport.ssh.MemoryKeyManager; +import com.gitblit.transport.ssh.NullKeyManager; +import com.gitblit.utils.StringUtils; import com.gitblit.wicket.GitBlitWebApp; import dagger.Module; @@ -53,6 +58,7 @@ import dagger.Provides; INotificationManager.class, IUserManager.class, IAuthenticationManager.class, + IPublicKeyManager.class, IRepositoryManager.class, IProjectManager.class, IFederationManager.class, @@ -62,7 +68,7 @@ import dagger.Provides; // the Gitblit Wicket app GitBlitWebApp.class - } + } ) public class DaggerModule { @@ -91,6 +97,31 @@ public class DaggerModule { userManager); } + @Provides @Singleton IPublicKeyManager providePublicKeyManager( + IStoredSettings settings, + IRuntimeManager runtimeManager) { + + String clazz = settings.getString(Keys.git.sshKeysManager, FileKeyManager.class.getName()); + if (StringUtils.isEmpty(clazz)) { + clazz = FileKeyManager.class.getName(); + } + if (FileKeyManager.class.getName().equals(clazz)) { + return new FileKeyManager(runtimeManager); + } else if (NullKeyManager.class.getName().equals(clazz)) { + return new NullKeyManager(); + } else if (MemoryKeyManager.class.getName().equals(clazz)) { + return new MemoryKeyManager(); + } else { + try { + Class mgrClass = Class.forName(clazz); + return (IPublicKeyManager) mgrClass.newInstance(); + } catch (Exception e) { + + } + return null; + } + } + @Provides @Singleton IRepositoryManager provideRepositoryManager( IRuntimeManager runtimeManager, IUserManager userManager) { @@ -127,6 +158,7 @@ public class DaggerModule { INotificationManager notificationManager, IUserManager userManager, IAuthenticationManager authenticationManager, + IPublicKeyManager publicKeyManager, IRepositoryManager repositoryManager, IProjectManager projectManager, IFederationManager federationManager) { @@ -136,6 +168,7 @@ public class DaggerModule { notificationManager, userManager, authenticationManager, + publicKeyManager, repositoryManager, projectManager, federationManager); @@ -146,6 +179,7 @@ public class DaggerModule { INotificationManager notificationManager, IUserManager userManager, IAuthenticationManager authenticationManager, + IPublicKeyManager publicKeyManager, IRepositoryManager repositoryManager, IProjectManager projectManager, IFederationManager federationManager, @@ -156,6 +190,7 @@ public class DaggerModule { notificationManager, userManager, authenticationManager, + publicKeyManager, repositoryManager, projectManager, federationManager, diff --git a/src/main/java/com/gitblit/FederationClient.java b/src/main/java/com/gitblit/FederationClient.java index 792a6382..d20025f0 100644 --- a/src/main/java/com/gitblit/FederationClient.java +++ b/src/main/java/com/gitblit/FederationClient.java @@ -97,7 +97,7 @@ public class FederationClient { UserManager users = new UserManager(runtime).start(); RepositoryManager repositories = new RepositoryManager(runtime, users).start(); FederationManager federation = new FederationManager(runtime, notifications, repositories).start(); - IGitblit gitblit = new GitblitManager(runtime, notifications, users, null, repositories, null, federation); + IGitblit gitblit = new GitblitManager(runtime, notifications, users, null, null, repositories, null, federation); FederationPullService puller = new FederationPullService(gitblit, federation.getFederationRegistrations()) { @Override diff --git a/src/main/java/com/gitblit/GitBlit.java b/src/main/java/com/gitblit/GitBlit.java index 817d18cb..b223d03c 100644 --- a/src/main/java/com/gitblit/GitBlit.java +++ b/src/main/java/com/gitblit/GitBlit.java @@ -41,6 +41,7 @@ import com.gitblit.tickets.FileTicketService; import com.gitblit.tickets.ITicketService; import com.gitblit.tickets.NullTicketService; import com.gitblit.tickets.RedisTicketService; +import com.gitblit.transport.ssh.IPublicKeyManager; import com.gitblit.utils.StringUtils; import dagger.Module; @@ -67,6 +68,7 @@ public class GitBlit extends GitblitManager { INotificationManager notificationManager, IUserManager userManager, IAuthenticationManager authenticationManager, + IPublicKeyManager publicKeyManager, IRepositoryManager repositoryManager, IProjectManager projectManager, IFederationManager federationManager) { @@ -75,6 +77,7 @@ public class GitBlit extends GitblitManager { notificationManager, userManager, authenticationManager, + publicKeyManager, repositoryManager, projectManager, federationManager); @@ -262,7 +265,7 @@ public class GitBlit extends GitblitManager { FileTicketService.class, BranchTicketService.class, RedisTicketService.class - } + } ) class GitBlitModule { diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java index 97e8efc9..8856715a 100644 --- a/src/main/java/com/gitblit/manager/GitblitManager.java +++ b/src/main/java/com/gitblit/manager/GitblitManager.java @@ -69,6 +69,7 @@ import com.gitblit.models.SettingModel; import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; import com.gitblit.tickets.ITicketService; +import com.gitblit.transport.ssh.IPublicKeyManager; import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.HttpUtils; import com.gitblit.utils.JsonUtils; @@ -107,6 +108,8 @@ public class GitblitManager implements IGitblit { protected final IAuthenticationManager authenticationManager; + protected final IPublicKeyManager publicKeyManager; + protected final IRepositoryManager repositoryManager; protected final IProjectManager projectManager; @@ -118,6 +121,7 @@ public class GitblitManager implements IGitblit { INotificationManager notificationManager, IUserManager userManager, IAuthenticationManager authenticationManager, + IPublicKeyManager publicKeyManager, IRepositoryManager repositoryManager, IProjectManager projectManager, IFederationManager federationManager) { @@ -127,6 +131,7 @@ public class GitblitManager implements IGitblit { this.notificationManager = notificationManager; this.userManager = userManager; this.authenticationManager = authenticationManager; + this.publicKeyManager = publicKeyManager; this.repositoryManager = repositoryManager; this.projectManager = projectManager; this.federationManager = federationManager; @@ -524,6 +529,11 @@ public class GitblitManager implements IGitblit { throw new RuntimeException("This class does not have a ticket service!"); } + @Override + public IPublicKeyManager getPublicKeyManager() { + return publicKeyManager; + } + /* * ISTOREDSETTINGS * diff --git a/src/main/java/com/gitblit/manager/IGitblit.java b/src/main/java/com/gitblit/manager/IGitblit.java index 50210e9d..f4221cf9 100644 --- a/src/main/java/com/gitblit/manager/IGitblit.java +++ b/src/main/java/com/gitblit/manager/IGitblit.java @@ -27,6 +27,7 @@ import com.gitblit.models.RepositoryUrl; import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; import com.gitblit.tickets.ITicketService; +import com.gitblit.transport.ssh.IPublicKeyManager; public interface IGitblit extends IManager, IRuntimeManager, @@ -109,4 +110,11 @@ public interface IGitblit extends IManager, */ ITicketService getTicketService(); + /** + * Returns the SSH public key manager. + * + * @return the SSH public key manager + */ + IPublicKeyManager getPublicKeyManager(); + } \ No newline at end of file diff --git a/src/main/java/com/gitblit/servlet/GitblitContext.java b/src/main/java/com/gitblit/servlet/GitblitContext.java index d4ec9671..cf8bba01 100644 --- a/src/main/java/com/gitblit/servlet/GitblitContext.java +++ b/src/main/java/com/gitblit/servlet/GitblitContext.java @@ -47,6 +47,7 @@ import com.gitblit.manager.IProjectManager; import com.gitblit.manager.IRepositoryManager; import com.gitblit.manager.IRuntimeManager; import com.gitblit.manager.IUserManager; +import com.gitblit.transport.ssh.IPublicKeyManager; import com.gitblit.utils.ContainerUtils; import com.gitblit.utils.StringUtils; @@ -149,7 +150,7 @@ public class GitblitContext extends DaggerContext { String contextRealPath = context.getRealPath("/"); File contextFolder = (contextRealPath != null) ? new File(contextRealPath) : null; - // if the base folder dosen't match the default assume they don't want to use express, + // if the base folder dosen't match the default assume they don't want to use express, // this allows for other containers to customise the basefolder per context. String defaultBase = Constants.contextFolder$ + "/WEB-INF/data"; String base = lookupBaseFolderFromJndi(); @@ -178,6 +179,7 @@ public class GitblitContext extends DaggerContext { startManager(injector, INotificationManager.class); startManager(injector, IUserManager.class); startManager(injector, IAuthenticationManager.class); + startManager(injector, IPublicKeyManager.class); startManager(injector, IRepositoryManager.class); startManager(injector, IProjectManager.class); startManager(injector, IFederationManager.class); diff --git a/src/main/java/com/gitblit/transport/ssh/CachingPublicKeyAuthenticator.java b/src/main/java/com/gitblit/transport/ssh/CachingPublicKeyAuthenticator.java index 7d6066c7..0120fa65 100644 --- a/src/main/java/com/gitblit/transport/ssh/CachingPublicKeyAuthenticator.java +++ b/src/main/java/com/gitblit/transport/ssh/CachingPublicKeyAuthenticator.java @@ -34,23 +34,23 @@ import com.gitblit.models.UserModel; import com.google.common.base.Preconditions; /** - * + * * @author Eric Myrhe - * + * */ public class CachingPublicKeyAuthenticator implements PublickeyAuthenticator, SessionListener { protected final Logger log = LoggerFactory.getLogger(getClass()); - protected final IKeyManager keyManager; + protected final IPublicKeyManager keyManager; protected final IAuthenticationManager authManager; private final Map> cache = new ConcurrentHashMap>(); - public CachingPublicKeyAuthenticator(IKeyManager keyManager, + public CachingPublicKeyAuthenticator(IPublicKeyManager keyManager, IAuthenticationManager authManager) { this.keyManager = keyManager; this.authManager = authManager; @@ -101,16 +101,15 @@ public class CachingPublicKeyAuthenticator implements PublickeyAuthenticator, return false; } - public IKeyManager getKeyManager() { - return keyManager; - } - + @Override public void sessionCreated(Session session) { } + @Override public void sessionEvent(Session sesssion, Event event) { } + @Override public void sessionClosed(Session session) { cache.remove(session); } diff --git a/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java b/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java index ae0bc9cf..defb4a3e 100644 --- a/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java +++ b/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java @@ -35,12 +35,12 @@ import com.google.common.base.Joiner; import com.google.common.io.Files; /** - * Manages SSH keys on the filesystem. + * Manages public keys on the filesystem. * * @author James Moger * */ -public class FileKeyManager extends IKeyManager { +public class FileKeyManager extends IPublicKeyManager { protected final IRuntimeManager runtimeManager; @@ -59,6 +59,7 @@ public class FileKeyManager extends IKeyManager { @Override public FileKeyManager start() { + log.info(toString()); return this; } diff --git a/src/main/java/com/gitblit/transport/ssh/IKeyManager.java b/src/main/java/com/gitblit/transport/ssh/IKeyManager.java deleted file mode 100644 index 12fce3df..00000000 --- a/src/main/java/com/gitblit/transport/ssh/IKeyManager.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.gitblit.transport.ssh; - -import java.security.PublicKey; -import java.text.MessageFormat; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; - -/** - * - * @author James Moger - * - */ -public abstract class IKeyManager { - - protected final Logger log = LoggerFactory.getLogger(getClass()); - - protected final LoadingCache> keyCache = CacheBuilder - .newBuilder(). - expireAfterAccess(15, TimeUnit.MINUTES). - maximumSize(100) - .build(new CacheLoader>() { - @Override - public List load(String username) { - return getKeysImpl(username); - } - }); - - public abstract IKeyManager start(); - - public abstract boolean isReady(); - - public abstract IKeyManager stop(); - - public final List getKeys(String username) { - try { - if (isStale(username)) { - keyCache.invalidate(username); - } - return keyCache.get(username); - } catch (ExecutionException e) { - log.error(MessageFormat.format("failed to retrieve keys for {0}", username), e); - } - return null; - } - - protected abstract boolean isStale(String username); - - protected abstract List getKeysImpl(String username); - - public abstract boolean addKey(String username, String data); - - public abstract boolean removeKey(String username, String data); - - public abstract boolean removeAllKeys(String username); -} diff --git a/src/main/java/com/gitblit/transport/ssh/IPublicKeyManager.java b/src/main/java/com/gitblit/transport/ssh/IPublicKeyManager.java new file mode 100644 index 00000000..5857a599 --- /dev/null +++ b/src/main/java/com/gitblit/transport/ssh/IPublicKeyManager.java @@ -0,0 +1,82 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.gitblit.transport.ssh; + +import java.security.PublicKey; +import java.text.MessageFormat; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.gitblit.manager.IManager; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +/** + * Parent class for public key managers. + * + * @author James Moger + * + */ +public abstract class IPublicKeyManager implements IManager { + + protected final Logger log = LoggerFactory.getLogger(getClass()); + + protected final LoadingCache> keyCache = CacheBuilder + .newBuilder(). + expireAfterAccess(15, TimeUnit.MINUTES). + maximumSize(100) + .build(new CacheLoader>() { + @Override + public List load(String username) { + return getKeysImpl(username); + } + }); + + @Override + public abstract IPublicKeyManager start(); + + public abstract boolean isReady(); + + @Override + public abstract IPublicKeyManager stop(); + + public final List getKeys(String username) { + try { + if (isStale(username)) { + keyCache.invalidate(username); + } + return keyCache.get(username); + } catch (ExecutionException e) { + log.error(MessageFormat.format("failed to retrieve keys for {0}", username), e); + } + return null; + } + + protected abstract boolean isStale(String username); + + protected abstract List getKeysImpl(String username); + + public abstract boolean addKey(String username, String data); + + public abstract boolean removeKey(String username, String data); + + public abstract boolean removeAllKeys(String username); +} diff --git a/src/main/java/com/gitblit/transport/ssh/MemoryKeyManager.java b/src/main/java/com/gitblit/transport/ssh/MemoryKeyManager.java new file mode 100644 index 00000000..26bd021a --- /dev/null +++ b/src/main/java/com/gitblit/transport/ssh/MemoryKeyManager.java @@ -0,0 +1,98 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.gitblit.transport.ssh; + +import java.security.PublicKey; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Memory public key manager. + * + * @author James Moger + * + */ +public class MemoryKeyManager extends IPublicKeyManager { + + Map> keys; + + public MemoryKeyManager() { + keys = new HashMap>(); + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } + + @Override + public MemoryKeyManager start() { + log.info(toString()); + return this; + } + + @Override + public boolean isReady() { + return true; + } + + @Override + public MemoryKeyManager stop() { + return this; + } + + @Override + protected boolean isStale(String username) { + return false; + } + + @Override + protected List getKeysImpl(String username) { + String id = username.toLowerCase(); + if (keys.containsKey(id)) { + return keys.get(id); + } + return null; + } + + @Override + public boolean addKey(String username, String data) { + return false; + } + + @Override + public boolean removeKey(String username, String data) { + return false; + } + + @Override + public boolean removeAllKeys(String username) { + String id = username.toLowerCase(); + keys.remove(id.toLowerCase()); + return true; + } + + /* Test method for populating the memory key manager */ + public void addKey(String username, PublicKey key) { + String id = username.toLowerCase(); + if (!keys.containsKey(id)) { + keys.put(id, new ArrayList()); + } + keys.get(id).add(key); + } +} diff --git a/src/main/java/com/gitblit/transport/ssh/NullKeyManager.java b/src/main/java/com/gitblit/transport/ssh/NullKeyManager.java index c76728d8..25860d6c 100644 --- a/src/main/java/com/gitblit/transport/ssh/NullKeyManager.java +++ b/src/main/java/com/gitblit/transport/ssh/NullKeyManager.java @@ -19,12 +19,12 @@ import java.security.PublicKey; import java.util.List; /** - * Rejects all SSH key management requests. + * Rejects all public key management requests. * * @author James Moger * */ -public class NullKeyManager extends IKeyManager { +public class NullKeyManager extends IPublicKeyManager { public NullKeyManager() { } @@ -36,6 +36,7 @@ public class NullKeyManager extends IKeyManager { @Override public NullKeyManager start() { + log.info(toString()); return this; } diff --git a/src/main/java/com/gitblit/transport/ssh/SshCommandFactory.java b/src/main/java/com/gitblit/transport/ssh/SshCommandFactory.java index de7aad1f..2b2093ea 100644 --- a/src/main/java/com/gitblit/transport/ssh/SshCommandFactory.java +++ b/src/main/java/com/gitblit/transport/ssh/SshCommandFactory.java @@ -52,14 +52,10 @@ public class SshCommandFactory implements CommandFactory { private static final Logger logger = LoggerFactory.getLogger(SshCommandFactory.class); private final IGitblit gitblit; - private final CachingPublicKeyAuthenticator keyAuthenticator; private final ScheduledExecutorService startExecutor; - public SshCommandFactory(IGitblit gitblit, - CachingPublicKeyAuthenticator keyAuthenticator, - IdGenerator idGenerator) { + public SshCommandFactory(IGitblit gitblit, IdGenerator idGenerator) { this.gitblit = gitblit; - this.keyAuthenticator = keyAuthenticator; int threads = 2;// cfg.getInt("sshd","commandStartThreads", 2); WorkQueue workQueue = new WorkQueue(idGenerator); @@ -84,8 +80,6 @@ public class SshCommandFactory implements CommandFactory { root.registerDispatcher(user, GitblitDispatchCommand.class); root.registerDispatcher(user, GitDispatchCommand.class); - root.setAuthenticator(keyAuthenticator); - return root; } diff --git a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java index b6c5d680..da9a3726 100644 --- a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java +++ b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java @@ -21,8 +21,6 @@ import java.net.InetSocketAddress; 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.IoServiceFactoryFactory; import org.apache.sshd.common.io.mina.MinaServiceFactoryFactory; @@ -35,15 +33,10 @@ import org.slf4j.LoggerFactory; import com.gitblit.Constants; import com.gitblit.IStoredSettings; import com.gitblit.Keys; -import com.gitblit.manager.IAuthenticationManager; import com.gitblit.manager.IGitblit; import com.gitblit.utils.IdGenerator; import com.gitblit.utils.StringUtils; -import dagger.Module; -import dagger.ObjectGraph; -import dagger.Provides; - /** * Manager for the ssh transport. Roughly analogous to the * {@link com.gitblit.transport.git.GitDaemon} class. @@ -73,7 +66,6 @@ public class SshDaemon { private final IGitblit gitblit; private final SshServer sshd; - private final ObjectGraph injector; /** * Construct the Gitblit SSH daemon. @@ -82,15 +74,12 @@ public class SshDaemon { */ 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, "localhost"); - IKeyManager keyManager = getKeyManager(); - String sshBackendStr = settings.getString(Keys.git.sshBackend, SshSessionBackend.NIO2.name()); SshSessionBackend backend = SshSessionBackend.valueOf(sshBackendStr); @@ -108,7 +97,7 @@ public class SshDaemon { File hostKeyStore = new File(gitblit.getBaseFolder(), HOST_KEY_STORE); CachingPublicKeyAuthenticator keyAuthenticator = - getPublicKeyAuthenticator(keyManager, gitblit); + new CachingPublicKeyAuthenticator(gitblit.getPublicKeyManager(), gitblit); sshd = SshServer.setUpDefaultServer(); sshd.setPort(addr.getPort()); @@ -119,7 +108,7 @@ public class SshDaemon { sshd.setSessionFactory(new SshServerSessionFactory()); sshd.setFileSystemFactory(new DisabledFilesystemFactory()); sshd.setTcpipForwardingFilter(new NonForwardingFilter()); - sshd.setCommandFactory(new SshCommandFactory(gitblit, keyAuthenticator, idGenerator)); + sshd.setCommandFactory(new SshCommandFactory(gitblit, idGenerator)); sshd.setShellFactory(new WelcomeShell(settings)); String version = Constants.getGitBlitVersion() + " (" + sshd.getVersion() + ")"; @@ -128,27 +117,6 @@ public class SshDaemon { 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 authClass = - (Class) 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) { if (sshd.getPort() == DEFAULT_PORT) { // standard port @@ -203,75 +171,4 @@ public class SshDaemon { } } } - - @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 managerClass = (Class) 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; - } - - @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 managerClass = (Class) 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); - } - } } diff --git a/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java b/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java index 38f1a48f..dd581f4d 100644 --- a/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java +++ b/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java @@ -32,8 +32,6 @@ import org.slf4j.LoggerFactory; import com.gitblit.models.UserModel; import com.gitblit.transport.ssh.CommandMetaData; -import com.gitblit.transport.ssh.CachingPublicKeyAuthenticator; -import com.gitblit.transport.ssh.gitblit.BaseKeyCommand; import com.gitblit.utils.StringUtils; import com.gitblit.utils.cli.SubcommandHandler; import com.google.common.base.Charsets; @@ -252,16 +250,5 @@ public abstract class DispatchCommand extends BaseCommand { cmd.setOutputStream(out); cmd.setErrorStream(err); cmd.setExitCallback(exit); - - if (cmd instanceof BaseKeyCommand) { - BaseKeyCommand k = (BaseKeyCommand) cmd; - k.setAuthenticator(authenticator); - } - } - - private CachingPublicKeyAuthenticator authenticator; - - public void setAuthenticator(CachingPublicKeyAuthenticator authenticator) { - this.authenticator = authenticator; } } diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/BaseKeyCommand.java b/src/main/java/com/gitblit/transport/ssh/gitblit/BaseKeyCommand.java index 09099578..1b7bac11 100644 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/BaseKeyCommand.java +++ b/src/main/java/com/gitblit/transport/ssh/gitblit/BaseKeyCommand.java @@ -21,8 +21,7 @@ import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.List; -import com.gitblit.transport.ssh.IKeyManager; -import com.gitblit.transport.ssh.CachingPublicKeyAuthenticator; +import com.gitblit.transport.ssh.IPublicKeyManager; import com.gitblit.transport.ssh.commands.SshCommand; import com.google.common.base.Charsets; @@ -53,12 +52,7 @@ abstract class BaseKeyCommand extends SshCommand { return sshKeys; } - protected CachingPublicKeyAuthenticator authenticator; - public void setAuthenticator(CachingPublicKeyAuthenticator authenticator) { - this.authenticator = authenticator; - } - - protected IKeyManager getKeyManager() { - return authenticator.getKeyManager(); + protected IPublicKeyManager getKeyManager() { + return ctx.getGitblit().getPublicKeyManager(); } } diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java index 445335ff..6e8aa05f 100644 --- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java +++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java @@ -39,6 +39,7 @@ import com.gitblit.manager.IRepositoryManager; import com.gitblit.manager.IRuntimeManager; import com.gitblit.manager.IUserManager; import com.gitblit.tickets.ITicketService; +import com.gitblit.transport.ssh.IPublicKeyManager; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.pages.ActivityPage; import com.gitblit.wicket.pages.BlamePage; @@ -95,6 +96,8 @@ public class GitBlitWebApp extends WebApplication { private final IAuthenticationManager authenticationManager; + private final IPublicKeyManager publicKeyManager; + private final IRepositoryManager repositoryManager; private final IProjectManager projectManager; @@ -108,6 +111,7 @@ public class GitBlitWebApp extends WebApplication { INotificationManager notificationManager, IUserManager userManager, IAuthenticationManager authenticationManager, + IPublicKeyManager publicKeyManager, IRepositoryManager repositoryManager, IProjectManager projectManager, IFederationManager federationManager, @@ -119,6 +123,7 @@ public class GitBlitWebApp extends WebApplication { this.notificationManager = notificationManager; this.userManager = userManager; this.authenticationManager = authenticationManager; + this.publicKeyManager = publicKeyManager; this.repositoryManager = repositoryManager; this.projectManager = projectManager; this.federationManager = federationManager; @@ -280,6 +285,10 @@ public class GitBlitWebApp extends WebApplication { return authenticationManager; } + public IPublicKeyManager keys() { + return publicKeyManager; + } + public IRepositoryManager repositories() { return repositoryManager; } diff --git a/src/test/config/test-gitblit.properties b/src/test/config/test-gitblit.properties index 7d8e9a79..1a52eaf4 100644 --- a/src/test/config/test-gitblit.properties +++ b/src/test/config/test-gitblit.properties @@ -8,7 +8,7 @@ git.searchRepositoriesSubfolders = true git.enableGitServlet = true git.daemonPort = 8300 git.sshPort = 29418 -git.sshPublicKeyAuthenticator = com.gitblit.tests.BogusPublicKeyAuthenticator +git.sshKeysManager = com.gitblit.transport.ssh.MemoryKeyManager groovy.scriptsFolder = src/main/distrib/data/groovy groovy.preReceiveScripts = blockpush groovy.postReceiveScripts = sendmail diff --git a/src/test/java/com/gitblit/tests/BogusPublicKeyAuthenticator.java b/src/test/java/com/gitblit/tests/BogusPublicKeyAuthenticator.java deleted file mode 100644 index 80be1a01..00000000 --- a/src/test/java/com/gitblit/tests/BogusPublicKeyAuthenticator.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.tests; - -import java.security.PublicKey; - -import org.apache.sshd.server.session.ServerSession; - -import com.gitblit.manager.IAuthenticationManager; -import com.gitblit.transport.ssh.CachingPublicKeyAuthenticator; -import com.gitblit.transport.ssh.IKeyManager; - -public class BogusPublicKeyAuthenticator extends CachingPublicKeyAuthenticator { - - public BogusPublicKeyAuthenticator(IKeyManager keyManager, - IAuthenticationManager authManager) { - super(keyManager, authManager); - } - - @Override - protected boolean doAuthenticate(String username, PublicKey suppliedKey, - ServerSession session) { - // TODO(davido): put authenticated user in session - return true; - } -} diff --git a/src/test/java/com/gitblit/tests/GitBlitSuite.java b/src/test/java/com/gitblit/tests/GitBlitSuite.java index 17d609e7..b8d3b181 100644 --- a/src/test/java/com/gitblit/tests/GitBlitSuite.java +++ b/src/test/java/com/gitblit/tests/GitBlitSuite.java @@ -61,7 +61,7 @@ import com.gitblit.utils.JGitUtils; MarkdownUtilsTest.class, JGitUtilsTest.class, SyndicationUtilsTest.class, DiffUtilsTest.class, MetricUtilsTest.class, X509UtilsTest.class, GitBlitTest.class, FederationTests.class, RpcTests.class, GitServletTest.class, GitDaemonTest.class, - GroovyScriptTest.class, LuceneExecutorTest.class, RepositoryModelTest.class, SshDaemonTest.class, + SshDaemonTest.class, GroovyScriptTest.class, LuceneExecutorTest.class, RepositoryModelTest.class, FanoutServiceTest.class, Issue0259Test.class, Issue0271Test.class, HtpasswdAuthenticationTest.class, ModelUtilsTest.class, JnaUtilsTest.class, LdapSyncServiceTest.class, FileTicketServiceTest.class, BranchTicketServiceTest.class, RedisTicketServiceTest.class, AuthenticationManagerTest.class }) @@ -78,20 +78,12 @@ public class GitBlitSuite { static int port = 8280; static int gitPort = 8300; static int shutdownPort = 8281; - static int sshPort = 29418; - -// Overriding of keys doesn't seem to work -// static { -// try { -// sshPort = SshUtils.getFreePort(); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// } + static int sshPort = 39418; public static String url = "http://localhost:" + port; public static String gitServletUrl = "http://localhost:" + port + "/git"; public static String gitDaemonUrl = "git://localhost:" + gitPort; + public static String sshDaemonUrl = "ssh://admin@localhost:" + sshPort; public static String account = "admin"; public static String password = "admin"; @@ -149,9 +141,7 @@ public class GitBlitSuite { "" + shutdownPort, "--gitPort", "" + gitPort, "--repositoriesFolder", "\"" + GitBlitSuite.REPOSITORIES.getAbsolutePath() + "\"", "--userService", GitBlitSuite.USERSCONF.getAbsolutePath(), "--settings", GitBlitSuite.SETTINGS.getAbsolutePath(), - "--baseFolder", "data"); - // doesn't work - //, "--sshPort", "" + sshPort); + "--baseFolder", "data", "--sshPort", "" + sshPort); } }); diff --git a/src/test/java/com/gitblit/tests/SshDaemonTest.java b/src/test/java/com/gitblit/tests/SshDaemonTest.java index 5294f691..45d31c29 100644 --- a/src/test/java/com/gitblit/tests/SshDaemonTest.java +++ b/src/test/java/com/gitblit/tests/SshDaemonTest.java @@ -26,11 +26,15 @@ import org.apache.sshd.ClientChannel; import org.apache.sshd.ClientSession; import org.apache.sshd.SshClient; import org.apache.sshd.common.KeyPairProvider; +import org.junit.After; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import com.gitblit.Constants; +import com.gitblit.transport.ssh.IPublicKeyManager; +import com.gitblit.transport.ssh.MemoryKeyManager; public class SshDaemonTest extends GitblitUnitTest { @@ -50,6 +54,27 @@ public class SshDaemonTest extends GitblitUnitTest { } } + protected MemoryKeyManager getKeyManager() { + IPublicKeyManager mgr = gitblit().getPublicKeyManager(); + if (mgr instanceof MemoryKeyManager) { + return (MemoryKeyManager) gitblit().getPublicKeyManager(); + } else { + throw new RuntimeException("unexpected key manager type " + mgr.getClass().getName()); + } + } + + @Before + public void prepare() { + MemoryKeyManager keyMgr = getKeyManager(); + keyMgr.addKey("admin", pair.getPublic()); + } + + @After + public void tearDown() { + MemoryKeyManager keyMgr = getKeyManager(); + keyMgr.removeAllKeys("admin"); + } + @Test public void testPublicKeyAuthentication() throws Exception { SshClient client = SshClient.setUpDefaultClient();