.classpath
@@ -52,6 +52,8 @@ <classpathentry kind="lib" path="ext/bcprov-jdk15on-1.49.jar" sourcepath="ext/src/bcprov-jdk15on-1.49.jar" /> <classpathentry kind="lib" path="ext/bcmail-jdk15on-1.49.jar" sourcepath="ext/src/bcmail-jdk15on-1.49.jar" /> <classpathentry kind="lib" path="ext/bcpkix-jdk15on-1.49.jar" sourcepath="ext/src/bcpkix-jdk15on-1.49.jar" /> <classpathentry kind="lib" path="ext/sshd-core-0.6.0.jar" sourcepath="ext/src/sshd-core-0.6.0.jar" /> <classpathentry kind="lib" path="ext/mina-core-2.0.2.jar" sourcepath="ext/src/mina-core-2.0.2.jar" /> <classpathentry kind="lib" path="ext/rome-0.9.jar" sourcepath="ext/src/rome-0.9.jar" /> <classpathentry kind="lib" path="ext/jdom-1.0.jar" sourcepath="ext/src/jdom-1.0.jar" /> <classpathentry kind="lib" path="ext/gson-1.7.2.jar" sourcepath="ext/src/gson-1.7.2.jar" /> build.moxie
@@ -109,6 +109,7 @@ bouncycastle.version : 1.49 selenium.version : 2.28.0 wikitext.version : 1.4 sshd.version: 0.6.0 } # Dependencies @@ -155,6 +156,7 @@ - compile 'org.bouncycastle:bcprov-jdk15on:${bouncycastle.version}' :war :authority - compile 'org.bouncycastle:bcmail-jdk15on:${bouncycastle.version}' :war :authority - compile 'org.bouncycastle:bcpkix-jdk15on:${bouncycastle.version}' :war :authority - compile 'org.apache.sshd:sshd-core:${sshd.version}' :war !org.easymock - compile 'rome:rome:0.9' :war :manager :api - compile 'com.google.code.gson:gson:1.7.2' :war :fedclient :manager :api - compile 'org.codehaus.groovy:groovy-all:${groovy.version}' :war gitblit.iml
@@ -529,6 +529,28 @@ </library> </orderEntry> <orderEntry type="module-library"> <library name="sshd-core-0.6.0.jar"> <CLASSES> <root url="jar://$MODULE_DIR$/ext/sshd-core-0.6.0.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> <root url="jar://$MODULE_DIR$/ext/src/sshd-core-0.6.0.jar!/" /> </SOURCES> </library> </orderEntry> <orderEntry type="module-library"> <library name="mina-core-2.0.2.jar"> <CLASSES> <root url="jar://$MODULE_DIR$/ext/mina-core-2.0.2.jar!/" /> </CLASSES> <JAVADOC /> <SOURCES> <root url="jar://$MODULE_DIR$/ext/src/mina-core-2.0.2.jar!/" /> </SOURCES> </library> </orderEntry> <orderEntry type="module-library"> <library name="rome-0.9.jar"> <CLASSES> <root url="jar://$MODULE_DIR$/ext/rome-0.9.jar!/" /> src/main/distrib/data/gitblit.properties
@@ -93,6 +93,23 @@ # RESTART REQUIRED git.daemonPort = 9418 # The port for serving the SSH service. <= 0 disables this service. # On Unix/Linux systems, ports < 1024 require root permissions. # Recommended value: 29418 # # SINCE 1.5.0 # RESTART REQUIRED git.sshPort = 29418 # Specify the interface for the SSH daemon to bind its service. # You may specify an ip or an empty value to bind to all interfaces. # Specifying localhost will result in Gitblit ONLY listening to requests to # localhost. # # SINCE 1.5.0 # RESTART REQUIRED git.sshBindInterface = localhost # 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://. src/main/java/com/gitblit/GitBlitServer.java
@@ -385,6 +385,7 @@ settings.overrideSetting(Keys.realm.userService, params.userService); settings.overrideSetting(Keys.git.repositoriesFolder, params.repositoriesFolder); settings.overrideSetting(Keys.git.daemonPort, params.gitPort); settings.overrideSetting(Keys.git.sshPort, params.sshPort); // Start up an in-memory LDAP server, if configured try { @@ -678,6 +679,9 @@ @Option(name = "--gitPort", usage = "Git Daemon port to serve. (port <= 0 will disable this connector)", metaVar="PORT") public Integer gitPort = FILESETTINGS.getInteger(Keys.git.daemonPort, 9418); @Option(name = "--sshPort", usage = "Git SSH port to serve. (port <= 0 will disable this connector)", metaVar = "PORT") public Integer sshPort = FILESETTINGS.getInteger(Keys.git.sshPort, 29418); @Option(name = "--alias", usage = "Alias of SSL certificate in keystore for serving https.", metaVar="ALIAS") public String alias = FILESETTINGS.getString(Keys.server.certificateAlias, ""); src/main/java/com/gitblit/manager/ServicesManager.java
@@ -42,6 +42,7 @@ import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; import com.gitblit.service.FederationPullService; import com.gitblit.transport.ssh.SshDaemon; import com.gitblit.utils.StringUtils; import com.gitblit.utils.TimeUtils; @@ -67,6 +68,8 @@ private GitDaemon gitDaemon; private SshDaemon sshDaemon; public ServicesManager(IGitblit gitblit) { this.settings = gitblit.getSettings(); this.gitblit = gitblit; @@ -77,6 +80,7 @@ configureFederation(); configureFanout(); configureGitDaemon(); configureSshDaemon(); return this; } @@ -138,6 +142,20 @@ } } protected void configureSshDaemon() { int port = settings.getInteger(Keys.git.sshPort, 0); String bindInterface = settings.getString(Keys.git.sshBindInterface, "localhost"); if (port > 0) { try { sshDaemon = new SshDaemon(gitblit); sshDaemon.start(); } catch (IOException e) { sshDaemon = null; logger.error(MessageFormat.format("Failed to start SSH daemon on {0}:{1,number,0}", bindInterface, port), e); } } } protected void configureFanout() { // startup Fanout PubSub service if (settings.getInteger(Keys.fanout.port, 0) > 0) { src/main/java/com/gitblit/transport/ssh/AbstractSshCommand.java
New file @@ -0,0 +1,75 @@ /* * 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.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.sshd.server.Command; import org.apache.sshd.server.Environment; import org.apache.sshd.server.ExitCallback; import org.apache.sshd.server.SessionAware; import org.apache.sshd.server.session.ServerSession; /** * * @author Eric Myrhe * */ abstract class AbstractSshCommand implements Command, SessionAware { protected InputStream in; protected OutputStream out; protected OutputStream err; protected ExitCallback exit; protected ServerSession session; @Override public void setInputStream(InputStream in) { this.in = in; } @Override public void setOutputStream(OutputStream out) { this.out = out; } @Override public void setErrorStream(OutputStream err) { this.err = err; } @Override public void setExitCallback(ExitCallback exit) { this.exit = exit; } @Override public void setSession(final ServerSession session) { this.session = session; } @Override public void destroy() {} @Override public abstract void start(Environment env) throws IOException; } src/main/java/com/gitblit/transport/ssh/SshCommandFactory.java
New file @@ -0,0 +1,164 @@ /* * 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.io.IOException; import java.util.Scanner; import org.apache.sshd.server.Command; import org.apache.sshd.server.CommandFactory; import org.apache.sshd.server.Environment; import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.PacketLineOut; import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.ServiceMayNotContinueException; import org.eclipse.jgit.transport.UploadPack; import org.eclipse.jgit.transport.resolver.ReceivePackFactory; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.eclipse.jgit.transport.resolver.UploadPackFactory; import com.gitblit.git.RepositoryResolver; /** * * @author Eric Myhre * */ public class SshCommandFactory implements CommandFactory { public SshCommandFactory(RepositoryResolver<SshDaemonClient> repositoryResolver, UploadPackFactory<SshDaemonClient> uploadPackFactory, ReceivePackFactory<SshDaemonClient> receivePackFactory) { this.repositoryResolver = repositoryResolver; this.uploadPackFactory = uploadPackFactory; this.receivePackFactory = receivePackFactory; } private RepositoryResolver<SshDaemonClient> repositoryResolver; private UploadPackFactory<SshDaemonClient> uploadPackFactory; private ReceivePackFactory<SshDaemonClient> receivePackFactory; @Override public Command createCommand(final String commandLine) { Scanner commandScanner = new Scanner(commandLine); final String command = commandScanner.next(); final String argument = commandScanner.nextLine(); if ("git-upload-pack".equals(command)) return new UploadPackCommand(argument); if ("git-receive-pack".equals(command)) return new ReceivePackCommand(argument); return new NonCommand(); } public abstract class RepositoryCommand extends AbstractSshCommand { protected final String repositoryName; public RepositoryCommand(String repositoryName) { this.repositoryName = repositoryName; } @Override public void start(Environment env) throws IOException { Repository db = null; try { SshDaemonClient client = session.getAttribute(SshDaemonClient.ATTR_KEY); db = selectRepository(client, repositoryName); if (db == null) return; run(client, db); exit.onExit(0); } catch (ServiceNotEnabledException e) { // Ignored. Client cannot use this repository. } catch (ServiceNotAuthorizedException e) { // Ignored. Client cannot use this repository. } finally { if (db != null) db.close(); exit.onExit(1); } } protected Repository selectRepository(SshDaemonClient client, String name) throws IOException { try { return openRepository(client, name); } catch (ServiceMayNotContinueException e) { // An error when opening the repo means the client is expecting a ref // advertisement, so use that style of error. PacketLineOut pktOut = new PacketLineOut(out); pktOut.writeString("ERR " + e.getMessage() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ return null; } } protected Repository openRepository(SshDaemonClient client, String name) throws ServiceMayNotContinueException { // Assume any attempt to use \ was by a Windows client // and correct to the more typical / used in Git URIs. // name = name.replace('\\', '/'); // ssh://git@thishost/path should always be name="/path" here // if (!name.startsWith("/")) //$NON-NLS-1$ return null; try { return repositoryResolver.open(client, name.substring(1)); } catch (RepositoryNotFoundException e) { // null signals it "wasn't found", which is all that is suitable // for the remote client to know. return null; } catch (ServiceNotEnabledException e) { // null signals it "wasn't found", which is all that is suitable // for the remote client to know. return null; } } protected abstract void run(SshDaemonClient client, Repository db) throws IOException, ServiceNotEnabledException, ServiceNotAuthorizedException; } public class UploadPackCommand extends RepositoryCommand { public UploadPackCommand(String repositoryName) { super(repositoryName); } @Override protected void run(SshDaemonClient client, Repository db) throws IOException, ServiceNotEnabledException, ServiceNotAuthorizedException { UploadPack up = uploadPackFactory.create(client, db); up.upload(in, out, null); } } public class ReceivePackCommand extends RepositoryCommand { public ReceivePackCommand(String repositoryName) { super(repositoryName); } @Override protected void run(SshDaemonClient client, Repository db) throws IOException, ServiceNotEnabledException, ServiceNotAuthorizedException { ReceivePack rp = receivePackFactory.create(client, db); rp.receive(in, out, null); } } public static class NonCommand extends AbstractSshCommand { @Override public void start(Environment env) { exit.onExit(127); } } } src/main/java/com/gitblit/transport/ssh/SshCommandServer.java
New file @@ -0,0 +1,217 @@ /* * 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.io.IOException; import java.net.InetSocketAddress; import java.security.InvalidKeyException; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.apache.mina.core.future.IoFuture; import org.apache.mina.core.future.IoFutureListener; import org.apache.mina.core.session.IoSession; import org.apache.mina.transport.socket.SocketSessionConfig; import org.apache.sshd.SshServer; import org.apache.sshd.common.Channel; import org.apache.sshd.common.Cipher; import org.apache.sshd.common.Compression; import org.apache.sshd.common.KeyExchange; import org.apache.sshd.common.KeyPairProvider; import org.apache.sshd.common.Mac; import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.Session; import org.apache.sshd.common.Signature; import org.apache.sshd.common.cipher.AES128CBC; import org.apache.sshd.common.cipher.AES192CBC; import org.apache.sshd.common.cipher.AES256CBC; import org.apache.sshd.common.cipher.BlowfishCBC; import org.apache.sshd.common.cipher.TripleDESCBC; import org.apache.sshd.common.compression.CompressionNone; import org.apache.sshd.common.mac.HMACMD5; import org.apache.sshd.common.mac.HMACMD596; import org.apache.sshd.common.mac.HMACSHA1; import org.apache.sshd.common.mac.HMACSHA196; import org.apache.sshd.common.random.BouncyCastleRandom; import org.apache.sshd.common.random.SingletonRandomFactory; import org.apache.sshd.common.signature.SignatureDSA; import org.apache.sshd.common.signature.SignatureRSA; import org.apache.sshd.common.util.SecurityUtils; import org.apache.sshd.server.CommandFactory; import org.apache.sshd.server.FileSystemFactory; import org.apache.sshd.server.FileSystemView; import org.apache.sshd.server.ForwardingFilter; import org.apache.sshd.server.PublickeyAuthenticator; import org.apache.sshd.server.SshFile; import org.apache.sshd.server.UserAuth; import org.apache.sshd.server.auth.UserAuthPublicKey; import org.apache.sshd.server.channel.ChannelDirectTcpip; import org.apache.sshd.server.channel.ChannelSession; import org.apache.sshd.server.kex.DHG1; import org.apache.sshd.server.kex.DHG14; import org.apache.sshd.server.session.ServerSession; import org.apache.sshd.server.session.SessionFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Eric Myhre * */ public class SshCommandServer extends SshServer { private static final Logger log = LoggerFactory.getLogger(SshCommandServer.class); public SshCommandServer() { setSessionFactory(new SessionFactory() { @Override protected ServerSession createSession(final IoSession io) throws Exception { log.info("connection accepted on " + io); if (io.getConfig() instanceof SocketSessionConfig) { final SocketSessionConfig c = (SocketSessionConfig) io.getConfig(); c.setKeepAlive(true); } final ServerSession s = (ServerSession) super.createSession(io); s.setAttribute(SshDaemonClient.ATTR_KEY, new SshDaemonClient()); io.getCloseFuture().addListener(new IoFutureListener<IoFuture>() { @Override public void operationComplete(IoFuture future) { log.info("connection closed on " + io); } }); return s; } }); } /** * Performs most of default configuration (setup random sources, setup ciphers, * etc; also, support for forwarding and filesystem is explicitly disallowed). * * {@link #setKeyPairProvider(KeyPairProvider)} and * {@link #setPublickeyAuthenticator(PublickeyAuthenticator)} are left for you. * And applying {@link #setCommandFactory(CommandFactory)} is probably wise if you * want something to actually happen when users do successfully authenticate. */ @SuppressWarnings("unchecked") public void setup() { if (!SecurityUtils.isBouncyCastleRegistered()) throw new RuntimeException("BC crypto not available"); setKeyExchangeFactories(Arrays.<NamedFactory<KeyExchange>>asList( new DHG14.Factory(), new DHG1.Factory()) ); setRandomFactory(new SingletonRandomFactory(new BouncyCastleRandom.Factory())); setupCiphers(); setCompressionFactories(Arrays.<NamedFactory<Compression>>asList( new CompressionNone.Factory()) ); setMacFactories(Arrays.<NamedFactory<Mac>>asList( new HMACMD5.Factory(), new HMACSHA1.Factory(), new HMACMD596.Factory(), new HMACSHA196.Factory()) ); setChannelFactories(Arrays.<NamedFactory<Channel>>asList( new ChannelSession.Factory(), new ChannelDirectTcpip.Factory()) ); setSignatureFactories(Arrays.<NamedFactory<Signature>>asList( new SignatureDSA.Factory(), new SignatureRSA.Factory()) ); setFileSystemFactory(new FileSystemFactory() { @Override public FileSystemView createFileSystemView(Session session) throws IOException { return new FileSystemView() { @Override public SshFile getFile(SshFile baseDir, String file) { return null; } @Override public SshFile getFile(String file) { return null; } }; } }); setForwardingFilter(new ForwardingFilter() { @Override public boolean canForwardAgent(ServerSession session) { return false; } @Override public boolean canForwardX11(ServerSession session) { return false; } @Override public boolean canConnect(InetSocketAddress address, ServerSession session) { return false; } @Override public boolean canListen(InetSocketAddress address, ServerSession session) { return false; } }); setUserAuthFactories(Arrays.<NamedFactory<UserAuth>>asList( new UserAuthPublicKey.Factory()) ); } protected void setupCiphers() { List<NamedFactory<Cipher>> avail = new LinkedList<NamedFactory<Cipher>>(); avail.add(new AES128CBC.Factory()); avail.add(new TripleDESCBC.Factory()); avail.add(new BlowfishCBC.Factory()); avail.add(new AES192CBC.Factory()); avail.add(new AES256CBC.Factory()); for (Iterator<NamedFactory<Cipher>> i = avail.iterator(); i.hasNext();) { final NamedFactory<Cipher> f = i.next(); try { final Cipher c = f.create(); final byte[] key = new byte[c.getBlockSize()]; final byte[] iv = new byte[c.getIVSize()]; c.init(Cipher.Mode.Encrypt, key, iv); } catch (InvalidKeyException e) { i.remove(); } catch (Exception e) { i.remove(); } } setCipherFactories(avail); } } src/main/java/com/gitblit/transport/ssh/SshDaemon.java
New file @@ -0,0 +1,159 @@ /* * 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.io.File; import java.io.IOException; import java.net.InetSocketAddress; import java.text.MessageFormat; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.transport.resolver.ReceivePackFactory; import org.eclipse.jgit.transport.resolver.UploadPackFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.IGitblit; import com.gitblit.utils.StringUtils; /** * Manager for the ssh transport. Roughly analogous to the * {@link com.gitblit.git.GitDaemon} class. * * @author Eric Myhre * */ public class SshDaemon { private final Logger logger = LoggerFactory.getLogger(SshDaemon.class); /** * 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 what the git * protocol itself defaults to if it sees and ssh url without a port. */ public static final int DEFAULT_PORT = 22; private static final String HOST_KEY_STORE = "sshKeyStore.pem"; private InetSocketAddress myAddress; private AtomicBoolean run; private SshCommandServer sshd; private RepositoryResolver<SshDaemonClient> repositoryResolver; private UploadPackFactory<SshDaemonClient> uploadPackFactory; private ReceivePackFactory<SshDaemonClient> receivePackFactory; /** * Construct the Gitblit SSH daemon. * * @param gitblit */ public SshDaemon(IGitblit gitblit) { IStoredSettings settings = gitblit.getSettings(); int port = settings.getInteger(Keys.git.sshPort, 0); String bindInterface = settings.getString(Keys.git.sshBindInterface, "localhost"); if (StringUtils.isEmpty(bindInterface)) { myAddress = new InetSocketAddress(port); } else { myAddress = new InetSocketAddress(bindInterface, port); } sshd = new SshCommandServer(); sshd.setPort(myAddress.getPort()); sshd.setHost(myAddress.getHostName()); sshd.setup(); sshd.setKeyPairProvider(new PEMGeneratorHostKeyProvider(new File(gitblit.getBaseFolder(), HOST_KEY_STORE).getPath())); sshd.setPublickeyAuthenticator(new SshKeyAuthenticator(gitblit)); run = new AtomicBoolean(false); repositoryResolver = new RepositoryResolver<SshDaemonClient>(gitblit); uploadPackFactory = new GitblitUploadPackFactory<SshDaemonClient>(gitblit); receivePackFactory = new GitblitReceivePackFactory<SshDaemonClient>(gitblit); sshd.setCommandFactory(new SshCommandFactory( repositoryResolver, uploadPackFactory, receivePackFactory )); } public int getPort() { return myAddress.getPort(); } public String formatUrl(String gituser, String servername, String repository) { if (getPort() == DEFAULT_PORT) { // standard port return MessageFormat.format("{0}@{1}/{2}", gituser, servername, repository); } else { // non-standard port return MessageFormat.format("ssh://{0}@{1}:{2,number,0}/{3}", gituser, servername, getPort(), repository); } } /** * Start this daemon on a background thread. * * @throws IOException * the server socket could not be opened. * @throws IllegalStateException * the daemon is already running. */ public synchronized void start() throws IOException { if (run.get()) { throw new IllegalStateException(JGitText.get().daemonAlreadyRunning); } sshd.start(); run.set(true); logger.info(MessageFormat.format("SSH Daemon is listening on {0}:{1,number,0}", myAddress.getAddress().getHostAddress(), myAddress.getPort())); } /** @return true if this daemon is receiving connections. */ public boolean isRunning() { return run.get(); } /** Stop this daemon. */ public synchronized void stop() { if (run.get()) { logger.info("SSH Daemon stopping..."); run.set(false); try { sshd.stop(); } catch (InterruptedException e) { logger.error("SSH Daemon stop interrupted", e); } } } } src/main/java/com/gitblit/transport/ssh/SshDaemonClient.java
New file @@ -0,0 +1,37 @@ /* * 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.net.InetAddress; import org.apache.sshd.common.Session.AttributeKey; /** * * @author Eric Myrhe * */ public class SshDaemonClient { public static final AttributeKey<SshDaemonClient> ATTR_KEY = new AttributeKey<SshDaemonClient>(); public InetAddress getRemoteAddress() { return null; } public String getRemoteUser() { return null; } } src/main/java/com/gitblit/transport/ssh/SshKeyAuthenticator.java
New file @@ -0,0 +1,43 @@ /* * 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 org.apache.sshd.server.PublickeyAuthenticator; import org.apache.sshd.server.session.ServerSession; import com.gitblit.manager.IGitblit; /** * * @author Eric Myrhe * */ public class SshKeyAuthenticator implements PublickeyAuthenticator { protected final IGitblit gitblit; public SshKeyAuthenticator(IGitblit gitblit) { this.gitblit = gitblit; } @Override public boolean authenticate(String username, PublicKey key, ServerSession session) { // TODO actually authenticate return true; } }