Merge branch 'stable-2.7' into stable-2.8

* stable-2.7:
  Bump SSHD version to 0.9.0.201311081

Conflicts:
	gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowConnections.java
	pom.xml

Change-Id: I29487ae1efb5bdf6f18fc76fe14790a530481c9f
This commit is contained in:
Shawn Pearce
2013-11-08 21:16:47 -08:00
8 changed files with 153 additions and 77 deletions

View File

@@ -2507,6 +2507,14 @@ namespace. To alias `replication start` to `gerrit replicate`:
[[sshd]] Section sshd [[sshd]] Section sshd
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
[[sshd.backend]]sshd.backend::
+
Starting from version 0.9.0 Apache SSHD project added support for NIO2
IoSession. To use the new NIO2 session the `backend` option must be set
to `NIO2`.
+
By default, `MINA`.
[[sshd.listenAddress]]sshd.listenAddress:: [[sshd.listenAddress]]sshd.listenAddress::
+ +
Specifies the local addresses the internal SSHD should listen Specifies the local addresses the internal SSHD should listen
@@ -2545,20 +2553,13 @@ of them.
+ +
By default, sshd.listenAddress. By default, sshd.listenAddress.
[[sshd.reuseAddress]]sshd.reuseAddress::
+
If true, permits the daemon to bind to the port even if the port
is already in use. If false, the daemon ensures the port is not
in use before starting. Busy sites may need to set this to true
to permit fast restarts.
+
By default, true.
[[sshd.tcpKeepAlive]]sshd.tcpKeepAlive:: [[sshd.tcpKeepAlive]]sshd.tcpKeepAlive::
+ +
If true, enables TCP keepalive messages to the other side, so If true, enables TCP keepalive messages to the other side, so
the daemon can terminate connections if the peer disappears. the daemon can terminate connections if the peer disappears.
+ +
Only effective when `sshd.backend` is set to `MINA`.
+
By default, true. By default, true.
[[sshd.threads]]sshd.threads:: [[sshd.threads]]sshd.threads::

View File

@@ -0,0 +1,34 @@
// Copyright (C) 2013 The Android Open Source Project
//
// 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.google.gerrit.sshd;
import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.session.ServerSession;
/* Expose addition of close session listeners */
class GerritServerSession extends ServerSession {
GerritServerSession(ServerFactoryManager server,
IoSession ioSession) throws Exception {
super(server, ioSession);
}
void addCloseSessionListener(SshFutureListener<CloseFuture> l) {
closeFuture.addListener(l);
}
}

View File

@@ -15,7 +15,6 @@
package com.google.gerrit.sshd; package com.google.gerrit.sshd;
import static com.google.gerrit.server.ssh.SshAddressesModule.IANA_SSH_PORT; import static com.google.gerrit.server.ssh.SshAddressesModule.IANA_SSH_PORT;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
@@ -35,20 +34,18 @@ import com.google.inject.Singleton;
import com.jcraft.jsch.HostKey; import com.jcraft.jsch.HostKey;
import com.jcraft.jsch.JSchException; import com.jcraft.jsch.JSchException;
import org.apache.mina.core.future.IoFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.SocketSessionConfig; import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.sshd.SshServer; import org.apache.sshd.SshServer;
import org.apache.sshd.common.Channel; import org.apache.sshd.common.Channel;
import org.apache.sshd.common.Cipher; import org.apache.sshd.common.Cipher;
import org.apache.sshd.common.Compression; import org.apache.sshd.common.Compression;
import org.apache.sshd.common.ForwardingFilter;
import org.apache.sshd.common.KeyExchange; import org.apache.sshd.common.KeyExchange;
import org.apache.sshd.common.KeyPairProvider; import org.apache.sshd.common.KeyPairProvider;
import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.Session; import org.apache.sshd.common.Session;
import org.apache.sshd.common.Signature; import org.apache.sshd.common.Signature;
import org.apache.sshd.common.SshdSocketAddress;
import org.apache.sshd.common.cipher.AES128CBC; import org.apache.sshd.common.cipher.AES128CBC;
import org.apache.sshd.common.cipher.AES192CBC; import org.apache.sshd.common.cipher.AES192CBC;
import org.apache.sshd.common.cipher.AES256CBC; import org.apache.sshd.common.cipher.AES256CBC;
@@ -56,6 +53,19 @@ import org.apache.sshd.common.cipher.BlowfishCBC;
import org.apache.sshd.common.cipher.CipherNone; import org.apache.sshd.common.cipher.CipherNone;
import org.apache.sshd.common.cipher.TripleDESCBC; import org.apache.sshd.common.cipher.TripleDESCBC;
import org.apache.sshd.common.compression.CompressionNone; import org.apache.sshd.common.compression.CompressionNone;
import org.apache.sshd.common.file.FileSystemFactory;
import org.apache.sshd.common.file.FileSystemView;
import org.apache.sshd.common.file.SshFile;
import org.apache.sshd.common.forward.DefaultTcpipForwarderFactory;
import org.apache.sshd.common.forward.TcpipServerChannel;
import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.io.IoAcceptor;
import org.apache.sshd.common.io.IoServiceFactory;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.mina.MinaServiceFactory;
import org.apache.sshd.common.io.mina.MinaSession;
import org.apache.sshd.common.io.nio2.Nio2ServiceFactory;
import org.apache.sshd.common.mac.HMACMD5; import org.apache.sshd.common.mac.HMACMD5;
import org.apache.sshd.common.mac.HMACMD596; import org.apache.sshd.common.mac.HMACMD596;
import org.apache.sshd.common.mac.HMACSHA1; import org.apache.sshd.common.mac.HMACSHA1;
@@ -63,26 +73,21 @@ import org.apache.sshd.common.mac.HMACSHA196;
import org.apache.sshd.common.random.BouncyCastleRandom; import org.apache.sshd.common.random.BouncyCastleRandom;
import org.apache.sshd.common.random.JceRandom; import org.apache.sshd.common.random.JceRandom;
import org.apache.sshd.common.random.SingletonRandomFactory; import org.apache.sshd.common.random.SingletonRandomFactory;
import org.apache.sshd.common.session.AbstractSession;
import org.apache.sshd.common.signature.SignatureDSA; import org.apache.sshd.common.signature.SignatureDSA;
import org.apache.sshd.common.signature.SignatureRSA; import org.apache.sshd.common.signature.SignatureRSA;
import org.apache.sshd.common.util.Buffer; import org.apache.sshd.common.util.Buffer;
import org.apache.sshd.common.util.SecurityUtils; import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.server.Command; import org.apache.sshd.server.Command;
import org.apache.sshd.server.CommandFactory; 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.PublickeyAuthenticator;
import org.apache.sshd.server.SshFile;
import org.apache.sshd.server.UserAuth; import org.apache.sshd.server.UserAuth;
import org.apache.sshd.server.auth.UserAuthPublicKey; import org.apache.sshd.server.auth.UserAuthPublicKey;
import org.apache.sshd.server.auth.gss.GSSAuthenticator; import org.apache.sshd.server.auth.gss.GSSAuthenticator;
import org.apache.sshd.server.auth.gss.UserAuthGSS; import org.apache.sshd.server.auth.gss.UserAuthGSS;
import org.apache.sshd.server.channel.ChannelDirectTcpip;
import org.apache.sshd.server.channel.ChannelSession; import org.apache.sshd.server.channel.ChannelSession;
import org.apache.sshd.server.kex.DHG1; import org.apache.sshd.server.kex.DHG1;
import org.apache.sshd.server.kex.DHG14; import org.apache.sshd.server.kex.DHG14;
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.server.session.SessionFactory; import org.apache.sshd.server.session.SessionFactory;
import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -91,7 +96,6 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
@@ -126,6 +130,11 @@ import java.util.List;
public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
private static final Logger log = LoggerFactory.getLogger(SshDaemon.class); private static final Logger log = LoggerFactory.getLogger(SshDaemon.class);
public static enum SshSessionBackend {
MINA,
NIO2
}
private final List<SocketAddress> listen; private final List<SocketAddress> listen;
private final List<String> advertised; private final List<String> advertised;
private final boolean keepAlive; private final boolean keepAlive;
@@ -144,7 +153,6 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
this.listen = listen; this.listen = listen;
this.advertised = advertised; this.advertised = advertised;
reuseAddress = cfg.getBoolean("sshd", "reuseaddress", true);
keepAlive = cfg.getBoolean("sshd", "tcpkeepalive", true); keepAlive = cfg.getBoolean("sshd", "tcpkeepalive", true);
getProperties().put(SERVER_IDENTIFICATION, getProperties().put(SERVER_IDENTIFICATION,
@@ -161,12 +169,6 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
long idleTimeoutSeconds = ConfigUtil.getTimeUnit(cfg, "sshd", null, long idleTimeoutSeconds = ConfigUtil.getTimeUnit(cfg, "sshd", null,
"idleTimeout", 0, SECONDS); "idleTimeout", 0, SECONDS);
if (idleTimeoutSeconds == 0) {
// Since Apache SSHD does not allow to turn off closing idle connections,
// we fake it by using the highest timeout allowed by Apache SSHD, which
// amounts to ~24 days.
idleTimeoutSeconds = MILLISECONDS.toSeconds(Integer.MAX_VALUE);
}
getProperties().put( getProperties().put(
IDLE_TIMEOUT, IDLE_TIMEOUT,
String.valueOf(SECONDS.toMillis(idleTimeoutSeconds))); String.valueOf(SECONDS.toMillis(idleTimeoutSeconds)));
@@ -183,6 +185,14 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
final String kerberosPrincipal = cfg.getString( final String kerberosPrincipal = cfg.getString(
"sshd", null, "kerberosPrincipal"); "sshd", null, "kerberosPrincipal");
SshSessionBackend backend = cfg.getEnum(
"sshd", null, "backend", SshSessionBackend.MINA);
System.setProperty(IoServiceFactory.class.getName(),
backend == SshSessionBackend.MINA
? MinaServiceFactory.class.getName()
: Nio2ServiceFactory.class.getName());
if (SecurityUtils.isBouncyCastleRegistered()) { if (SecurityUtils.isBouncyCastleRegistered()) {
initProviderBouncyCastle(); initProviderBouncyCastle();
} else { } else {
@@ -192,7 +202,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
initMacs(cfg); initMacs(cfg);
initSignatures(); initSignatures();
initChannels(); initChannels();
initForwardingFilter(); initForwarding();
initFileSystemFactory(); initFileSystemFactory();
initSubsystems(); initSubsystems();
initCompression(); initCompression();
@@ -202,24 +212,28 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
setShellFactory(noShell); setShellFactory(noShell);
setSessionFactory(new SessionFactory() { setSessionFactory(new SessionFactory() {
@Override @Override
protected ServerSession createSession(final IoSession io) protected AbstractSession createSession(final IoSession io)
throws Exception { throws Exception {
if (io.getConfig() instanceof SocketSessionConfig) { if (io instanceof MinaSession) {
final SocketSessionConfig c = (SocketSessionConfig) io.getConfig(); if (((MinaSession) io).getSession()
c.setKeepAlive(keepAlive); .getConfig() instanceof SocketSessionConfig) {
((SocketSessionConfig) ((MinaSession) io).getSession()
.getConfig())
.setKeepAlive(keepAlive);
}
} }
final ServerSession s = (ServerSession) super.createSession(io); GerritServerSession s = (GerritServerSession)super.createSession(io);
final int id = idGenerator.next(); int id = idGenerator.next();
final SocketAddress peer = io.getRemoteAddress(); SocketAddress peer = io.getRemoteAddress();
final SshSession sd = new SshSession(id, peer); final SshSession sd = new SshSession(id, peer);
s.setAttribute(SshSession.KEY, sd); s.setAttribute(SshSession.KEY, sd);
// Log a session close without authentication as a failure. // Log a session close without authentication as a failure.
// //
io.getCloseFuture().addListener(new IoFutureListener<IoFuture>() { s.addCloseSessionListener(new SshFutureListener<CloseFuture>() {
@Override @Override
public void operationComplete(IoFuture future) { public void operationComplete(CloseFuture future) {
if (sd.isAuthenticationError()) { if (sd.isAuthenticationError()) {
sshLog.onAuthFail(sd); sshLog.onAuthFail(sd);
} }
@@ -227,6 +241,12 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
}); });
return s; return s;
} }
@Override
protected AbstractSession doCreateSession(IoSession ioSession)
throws Exception {
return new GerritServerSession(server, ioSession);
}
}); });
hostKeys = computeHostKeys(); hostKeys = computeHostKeys();
@@ -245,13 +265,11 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
public synchronized void start() { public synchronized void start() {
if (acceptor == null && !listen.isEmpty()) { if (acceptor == null && !listen.isEmpty()) {
checkConfig(); checkConfig();
if (sessionFactory == null) {
sessionFactory = createSessionFactory();
}
sessionFactory.setServer(this);
acceptor = createAcceptor(); acceptor = createAcceptor();
configure(acceptor);
final SessionFactory handler = getSessionFactory();
handler.setServer(this);
acceptor.setHandler(handler);
try { try {
acceptor.bind(listen); acceptor.bind(listen);
@@ -259,7 +277,8 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
throw new IllegalStateException("Cannot bind to " + addressList(), e); throw new IllegalStateException("Cannot bind to " + addressList(), e);
} }
log.info("Started Gerrit SSHD on " + addressList()); log.info(String.format("Started Gerrit %s on %s",
version, addressList()));
} }
} }
@@ -473,7 +492,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
private void initChannels() { private void initChannels() {
setChannelFactories(Arrays.<NamedFactory<Channel>> asList( setChannelFactories(Arrays.<NamedFactory<Channel>> asList(
new ChannelSession.Factory(), // new ChannelSession.Factory(), //
new ChannelDirectTcpip.Factory() // new TcpipServerChannel.DirectTcpipFactory() //
)); ));
} }
@@ -514,28 +533,29 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener {
setPublickeyAuthenticator(pubkey); setPublickeyAuthenticator(pubkey);
} }
private void initForwardingFilter() { private void initForwarding() {
setForwardingFilter(new ForwardingFilter() { setTcpipForwardingFilter(new ForwardingFilter() {
@Override @Override
public boolean canForwardAgent(ServerSession session) { public boolean canForwardAgent(Session session) {
return false; return false;
} }
@Override @Override
public boolean canForwardX11(ServerSession session) { public boolean canForwardX11(Session session) {
return false; return false;
} }
@Override @Override
public boolean canConnect(InetSocketAddress address, ServerSession session) { public boolean canListen(SshdSocketAddress address, Session session) {
return false; return false;
} }
@Override @Override
public boolean canListen(InetSocketAddress address, ServerSession session) { public boolean canConnect(SshdSocketAddress address, Session session) {
return false; return false;
} }
}); });
setTcpipForwarderFactory(new DefaultTcpipForwarderFactory());
} }
private void initFileSystemFactory() { private void initFileSystemFactory() {

View File

@@ -21,8 +21,8 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.sshd.SshScope.Context; import com.google.gerrit.sshd.SshScope.Context;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.mina.core.future.IoFuture; import org.apache.sshd.common.future.CloseFuture;
import org.apache.mina.core.future.IoFutureListener; import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.KeyPairProvider; import org.apache.sshd.common.KeyPairProvider;
import org.apache.sshd.common.SshException; import org.apache.sshd.common.SshException;
import org.apache.sshd.common.util.Buffer; import org.apache.sshd.common.util.Buffer;
@@ -138,10 +138,11 @@ public class SshUtil {
sshScope.set(old); sshScope.set(old);
} }
session.getIoSession().getCloseFuture().addListener( GerritServerSession s = (GerritServerSession) session;
new IoFutureListener<IoFuture>() { s.addCloseSessionListener(
new SshFutureListener<CloseFuture>() {
@Override @Override
public void operationComplete(IoFuture future) { public void operationComplete(CloseFuture future) {
final Context ctx = sshScope.newContext(null, sd, null); final Context ctx = sshScope.newContext(null, sd, null);
final Context old = sshScope.set(ctx); final Context old = sshScope.set(ctx);
try { try {

View File

@@ -32,8 +32,9 @@ import com.google.gerrit.sshd.SshDaemon;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import org.apache.mina.core.service.IoAcceptor; import org.apache.sshd.common.io.IoAcceptor;
import org.apache.mina.core.session.IoSession; import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.mina.MinaSession;
import org.apache.sshd.server.Environment; import org.apache.sshd.server.Environment;
import org.eclipse.jgit.internal.storage.file.WindowCacheStatAccessor; import org.eclipse.jgit.internal.storage.file.WindowCacheStatAccessor;
import org.kohsuke.args4j.Option; import org.kohsuke.args4j.Option;
@@ -274,8 +275,12 @@ final class ShowCaches extends CacheCommand {
long now = TimeUtil.nowMs(); long now = TimeUtil.nowMs();
Collection<IoSession> list = acceptor.getManagedSessions().values(); Collection<IoSession> list = acceptor.getManagedSessions().values();
long oldest = now; long oldest = now;
for (IoSession s : list) { for (IoSession s : list) {
oldest = Math.min(oldest, s.getCreationTime()); if (s instanceof MinaSession) {
MinaSession minaSession = (MinaSession)s;
oldest = Math.min(oldest, minaSession.getSession().getCreationTime());
}
} }
stdout.format( stdout.format(

View File

@@ -26,8 +26,9 @@ import com.google.gerrit.sshd.SshDaemon;
import com.google.gerrit.sshd.SshSession; import com.google.gerrit.sshd.SshSession;
import com.google.inject.Inject; import com.google.inject.Inject;
import org.apache.mina.core.service.IoAcceptor; import org.apache.sshd.common.io.IoAcceptor;
import org.apache.mina.core.session.IoSession; import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.mina.MinaSession;
import org.apache.sshd.server.Environment; import org.apache.sshd.server.Environment;
import org.apache.sshd.server.session.ServerSession; import org.apache.sshd.server.session.ServerSession;
import org.kohsuke.args4j.Option; import org.kohsuke.args4j.Option;
@@ -84,10 +85,16 @@ final class ShowConnections extends SshCommand {
Collections.sort(list, new Comparator<IoSession>() { Collections.sort(list, new Comparator<IoSession>() {
@Override @Override
public int compare(IoSession arg0, IoSession arg1) { public int compare(IoSession arg0, IoSession arg1) {
if (arg0.getCreationTime() < arg1.getCreationTime()) { if (arg0 instanceof MinaSession) {
return -1; MinaSession mArg0 = (MinaSession) arg0;
} else if (arg0.getCreationTime() > arg1.getCreationTime()) { MinaSession mArg1 = (MinaSession) arg1;
return 1; if (mArg0.getSession().getCreationTime() < mArg1.getSession()
.getCreationTime()) {
return -1;
} else if (mArg0.getSession().getCreationTime() > mArg1.getSession()
.getCreationTime()) {
return 1;
}
} }
return (int) (arg0.getId() - arg1.getId()); return (int) (arg0.getId() - arg1.getId());
} }
@@ -104,8 +111,15 @@ final class ShowConnections extends SshCommand {
SshSession sd = s != null ? s.getAttribute(SshSession.KEY) : null; SshSession sd = s != null ? s.getAttribute(SshSession.KEY) : null;
final SocketAddress remoteAddress = io.getRemoteAddress(); final SocketAddress remoteAddress = io.getRemoteAddress();
final long start = io.getCreationTime(); MinaSession minaSession = io instanceof MinaSession
final long idle = now - io.getLastIoTime(); ? (MinaSession) io
: null;
final long start = minaSession == null
? 0
: minaSession.getSession().getCreationTime();
final long idle = minaSession == null
? now
: now - minaSession.getSession().getLastIoTime();
stdout.print(String.format("%8s %8s %8s %-15.15s %s\n", // stdout.print(String.format("%8s %8s %8s %-15.15s %s\n", //
id(sd), // id(sd), //

View File

@@ -26,7 +26,7 @@ log4j.logger.org.apache.mina=WARN
log4j.logger.org.apache.sshd.common=WARN log4j.logger.org.apache.sshd.common=WARN
log4j.logger.org.apache.sshd.server=WARN log4j.logger.org.apache.sshd.server=WARN
log4j.logger.org.apache.sshd.common.keyprovider.FileKeyPairProvider=INFO log4j.logger.org.apache.sshd.common.keyprovider.FileKeyPairProvider=INFO
log4j.logger.com.google.gerrit.server.ssh.GerritServerSession=WARN log4j.logger.com.google.gerrit.sshd.GerritServerSession=WARN
# Silence non-critical messages from Jetty. # Silence non-critical messages from Jetty.
# #

View File

@@ -8,17 +8,18 @@ EXCLUDE = [
maven_jar( maven_jar(
name = 'core', name = 'core',
id = 'org.apache.mina:mina-core:2.0.5', id = 'org.apache.mina:mina-core:2.0.7',
sha1 = '0e134a3761833a3c28c79331e806f64f985a9eec', sha1 = 'c878e2aa82de748474a624ec3933e4604e446dec',
license = 'Apache2.0', license = 'Apache2.0',
exclude = EXCLUDE, exclude = EXCLUDE,
) )
maven_jar( maven_jar(
name = 'sshd', name = 'sshd',
id = 'org.apache.sshd:sshd-core:0.6.0', id = 'org.apache.sshd:sshd-core:0.9.0.201311081',
sha1 = '2b9a119dd77a1decec78b0c511ba400c8655e96e', sha1 = '38f7ac8602e70fa05fdc6147d204198e9cefe5bc',
license = 'Apache2.0', license = 'Apache2.0',
deps = [':core'], deps = [':core'],
exclude = EXCLUDE, exclude = EXCLUDE,
repository = GERRIT,
) )