From e8a521447d50355cc6dd96d9b21f48688309f5e8 Mon Sep 17 00:00:00 2001 From: David Ostrovsky Date: Mon, 7 Dec 2015 15:01:03 +0900 Subject: [PATCH] Update sshd-core to 1.0.0 and mina to 2.10 This version includes several bug fixes and improvements. See the release note [1] for details. Many packages have been renamed, and some classes removed. FileKeyPairProvider was removed from the SSHD library, so we need to borrow it from the previous release. We preserve the license, that is the same as Gerrit Code Review, the header and the indentation. Compilation warnings are fixed, mostly by adding missing @Override annotations. [1] https://issues.apache.org/jira/secure/ReleaseNote.jspa?version=12323302&styleName=Html&projectId=12310849 Change-Id: If047c3a279fc9c98a59ac3102b0db3f5f2fdae48 --- .../InMemoryTestingDatabaseModule.java | 2 +- .../com/google/gerrit/pgm/init/InitSshd.java | 2 +- gerrit-sshd/BUCK | 1 + .../gerrit/sshd/DatabasePubKeyAuth.java | 8 +- .../gerrit/sshd/FileKeyPairProvider.java | 150 +++++++++++++ .../gerrit/sshd/GerritServerSession.java | 4 +- .../google/gerrit/sshd/HostKeyProvider.java | 5 +- .../com/google/gerrit/sshd/SshDaemon.java | 212 ++++++++++-------- .../google/gerrit/sshd/SshHostKeyModule.java | 2 +- .../com/google/gerrit/sshd/SshModule.java | 2 +- .../com/google/gerrit/sshd/SshSession.java | 2 +- .../java/com/google/gerrit/sshd/SshUtil.java | 8 +- .../gerrit/sshd/commands/CloseConnection.java | 8 +- .../gerrit/sshd/commands/ShowConnections.java | 4 +- lib/mina/BUCK | 8 +- 15 files changed, 294 insertions(+), 124 deletions(-) create mode 100644 gerrit-sshd/src/main/java/com/google/gerrit/sshd/FileKeyPairProvider.java diff --git a/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java b/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java index 672a5a736e..686bca7da3 100644 --- a/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java +++ b/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java @@ -41,7 +41,7 @@ import com.google.inject.Provides; import com.google.inject.Singleton; import com.google.inject.TypeLiteral; -import org.apache.sshd.common.KeyPairProvider; +import org.apache.sshd.common.keyprovider.KeyPairProvider; import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; import org.eclipse.jgit.lib.Config; diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitSshd.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitSshd.java index c654c8de09..bdebd6ca43 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitSshd.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitSshd.java @@ -144,7 +144,7 @@ class InitSshd implements InitStep { System.err.print(" rsa(simple)..."); System.err.flush(); p = new SimpleGeneratorHostKeyProvider(); - p.setPath(tmpkey.toAbsolutePath().toString()); + p.setPath(tmpkey.toAbsolutePath()); p.setAlgorithm("RSA"); p.loadKeys(); // forces the key to generate. chmod(0600, tmpkey); diff --git a/gerrit-sshd/BUCK b/gerrit-sshd/BUCK index 260b557252..457f12e0a5 100644 --- a/gerrit-sshd/BUCK +++ b/gerrit-sshd/BUCK @@ -32,6 +32,7 @@ java_library( '//lib/jgit:jgit-archive', ], provided_deps = [ + '//lib/bouncycastle:bcpkix', '//lib/bouncycastle:bcprov', ], visibility = ['PUBLIC'], diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java index 3ce454528c..5c4498854d 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java @@ -27,10 +27,10 @@ import com.google.gerrit.server.config.SitePaths; import com.google.inject.Inject; import org.apache.commons.codec.binary.Base64; -import org.apache.sshd.common.KeyPairProvider; import org.apache.sshd.common.SshException; -import org.apache.sshd.common.util.Buffer; -import org.apache.sshd.server.PublickeyAuthenticator; +import org.apache.sshd.common.keyprovider.KeyPairProvider; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; +import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator; import org.apache.sshd.server.session.ServerSession; import org.eclipse.jgit.lib.Config; import org.slf4j.Logger; @@ -195,7 +195,7 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator { try { byte[] bin = Base64.decodeBase64(line.getBytes(ISO_8859_1)); - keys.add(new Buffer(bin).getRawPublicKey()); + keys.add(new ByteArrayBuffer(bin).getRawPublicKey()); } catch (RuntimeException | SshException e) { logBadKey(path, line, e); } diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/FileKeyPairProvider.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/FileKeyPairProvider.java new file mode 100644 index 0000000000..8966b5f2cf --- /dev/null +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/FileKeyPairProvider.java @@ -0,0 +1,150 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.keyprovider.AbstractKeyPairProvider; +import org.apache.sshd.common.util.SecurityUtils; +import org.bouncycastle.openssl.PEMDecryptorProvider; +import org.bouncycastle.openssl.PEMEncryptedKeyPair; +import org.bouncycastle.openssl.PEMKeyPair; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.openssl.PasswordFinder; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; +import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; + +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.security.KeyPair; +import java.util.Arrays; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * This host key provider loads private keys from the specified files. + * + * Note that this class has a direct dependency on BouncyCastle and won't work + * unless it has been correctly registered as a security provider. + * + * @author Apache MINA SSHD Project + */ +public class FileKeyPairProvider extends AbstractKeyPairProvider { + + private String[] files; + private PasswordFinder passwordFinder; + + public FileKeyPairProvider() { + } + + public FileKeyPairProvider(String[] files) { + this.files = files; + } + + public FileKeyPairProvider(String[] files, PasswordFinder passwordFinder) { + this.files = files; + this.passwordFinder = passwordFinder; + } + + public String[] getFiles() { + return files; + } + + public void setFiles(String[] files) { + this.files = files; + } + + public PasswordFinder getPasswordFinder() { + return passwordFinder; + } + + public void setPasswordFinder(PasswordFinder passwordFinder) { + this.passwordFinder = passwordFinder; + } + + @Override + public Iterable loadKeys() { + if (!SecurityUtils.isBouncyCastleRegistered()) { + throw new IllegalStateException("BouncyCastle must be registered as a JCE provider"); + } + return new Iterable() { + @Override + public Iterator iterator() { + return new Iterator() { + private final Iterator iterator = Arrays.asList(files).iterator(); + private KeyPair nextKeyPair; + private boolean nextKeyPairSet = false; + @Override + public boolean hasNext() { + return nextKeyPairSet || setNextObject(); + } + @Override + public KeyPair next() { + if (!nextKeyPairSet) { + if (!setNextObject()) { + throw new NoSuchElementException(); + } + } + nextKeyPairSet = false; + return nextKeyPair; + } + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + private boolean setNextObject() { + while (iterator.hasNext()) { + String file = iterator.next(); + nextKeyPair = doLoadKey(file); + if (nextKeyPair != null) { + nextKeyPairSet = true; + return true; + } + } + return false; + } + + }; + } + }; + } + + protected KeyPair doLoadKey(String file) { + try (PEMParser r = new PEMParser(new InputStreamReader( + new FileInputStream(file)))) { + Object o = r.readObject(); + JcaPEMKeyConverter pemConverter = new JcaPEMKeyConverter(); + pemConverter.setProvider("BC"); + if (passwordFinder != null && o instanceof PEMEncryptedKeyPair) { + JcePEMDecryptorProviderBuilder decryptorBuilder = new JcePEMDecryptorProviderBuilder(); + PEMDecryptorProvider pemDecryptor = decryptorBuilder.build(passwordFinder.getPassword()); + o = pemConverter.getKeyPair(((PEMEncryptedKeyPair) o).decryptKeyPair(pemDecryptor)); + } + + if (o instanceof PEMKeyPair) { + o = pemConverter.getKeyPair((PEMKeyPair)o); + return (KeyPair) o; + } else if (o instanceof KeyPair) { + return (KeyPair) o; + } + } catch (Exception e) { + log.warn("Unable to read key " + file, e); + } + return null; + } + +} diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/GerritServerSession.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/GerritServerSession.java index b7f7c22202..403470dda7 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/GerritServerSession.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/GerritServerSession.java @@ -18,10 +18,10 @@ 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; +import org.apache.sshd.server.session.ServerSessionImpl; /* Expose addition of close session listeners */ -class GerritServerSession extends ServerSession { +class GerritServerSession extends ServerSessionImpl { GerritServerSession(ServerFactoryManager server, IoSession ioSession) throws Exception { diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java index 3e6e2f5821..41640e8eda 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java @@ -19,8 +19,7 @@ import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.ProvisionException; -import org.apache.sshd.common.KeyPairProvider; -import org.apache.sshd.common.keyprovider.FileKeyPairProvider; +import org.apache.sshd.common.keyprovider.KeyPairProvider; import org.apache.sshd.common.util.SecurityUtils; import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; @@ -54,7 +53,7 @@ class HostKeyProvider implements Provider { if (Files.exists(objKey)) { if (stdKeys.isEmpty()) { SimpleGeneratorHostKeyProvider p = new SimpleGeneratorHostKeyProvider(); - p.setPath(objKey.toAbsolutePath().toString()); + p.setPath(objKey.toAbsolutePath()); return p; } else { diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshDaemon.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshDaemon.java index 923d0f0943..db440657f0 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshDaemon.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshDaemon.java @@ -41,36 +41,15 @@ import com.jcraft.jsch.HostKey; import com.jcraft.jsch.JSchException; 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.ForwardingFilter; -import org.apache.sshd.common.KeyExchange; -import org.apache.sshd.common.KeyPairProvider; +import org.apache.sshd.common.BaseBuilder; import org.apache.sshd.common.NamedFactory; -import org.apache.sshd.common.Random; -import org.apache.sshd.common.RequestHandler; -import org.apache.sshd.common.Session; -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.AES128CTR; -import org.apache.sshd.common.cipher.AES192CBC; -import org.apache.sshd.common.cipher.AES256CBC; -import org.apache.sshd.common.cipher.AES256CTR; -import org.apache.sshd.common.cipher.ARCFOUR128; -import org.apache.sshd.common.cipher.ARCFOUR256; -import org.apache.sshd.common.cipher.BlowfishCBC; -import org.apache.sshd.common.cipher.CipherNone; -import org.apache.sshd.common.cipher.TripleDESCBC; -import org.apache.sshd.common.compression.CompressionNone; -import org.apache.sshd.common.compression.CompressionZlib; +import org.apache.sshd.common.channel.RequestHandler; +import org.apache.sshd.common.cipher.Cipher; +import org.apache.sshd.common.compression.BuiltinCompressions; +import org.apache.sshd.common.compression.Compression; 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; @@ -79,36 +58,32 @@ import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.io.mina.MinaServiceFactoryFactory; import org.apache.sshd.common.io.mina.MinaSession; import org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory; -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.mac.HMACSHA256; -import org.apache.sshd.common.mac.HMACSHA512; -import org.apache.sshd.common.random.BouncyCastleRandom; -import org.apache.sshd.common.random.JceRandom; +import org.apache.sshd.common.kex.BuiltinDHFactories; +import org.apache.sshd.common.keyprovider.KeyPairProvider; +import org.apache.sshd.common.mac.Mac; +import org.apache.sshd.common.random.JceRandomFactory; +import org.apache.sshd.common.random.Random; import org.apache.sshd.common.random.SingletonRandomFactory; import org.apache.sshd.common.session.AbstractSession; import org.apache.sshd.common.session.ConnectionService; -import org.apache.sshd.common.signature.SignatureDSA; -import org.apache.sshd.common.signature.SignatureECDSA; -import org.apache.sshd.common.signature.SignatureRSA; -import org.apache.sshd.common.util.Buffer; +import org.apache.sshd.common.session.Session; import org.apache.sshd.common.util.SecurityUtils; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; import org.apache.sshd.server.Command; import org.apache.sshd.server.CommandFactory; -import org.apache.sshd.server.PublickeyAuthenticator; -import org.apache.sshd.server.UserAuth; -import org.apache.sshd.server.auth.UserAuthPublicKey; +import org.apache.sshd.server.ServerBuilder; +import org.apache.sshd.server.SshServer; +import org.apache.sshd.server.auth.UserAuth; +import org.apache.sshd.server.auth.UserAuthPublicKeyFactory; import org.apache.sshd.server.auth.gss.GSSAuthenticator; -import org.apache.sshd.server.auth.gss.UserAuthGSS; -import org.apache.sshd.server.channel.ChannelSession; +import org.apache.sshd.server.auth.gss.UserAuthGSSFactory; +import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator; +import org.apache.sshd.server.forward.ForwardingFilter; import org.apache.sshd.server.global.CancelTcpipForwardHandler; import org.apache.sshd.server.global.KeepAliveHandler; import org.apache.sshd.server.global.NoMoreSessionsHandler; import org.apache.sshd.server.global.TcpipForwardHandler; -import org.apache.sshd.server.kex.DHG1; -import org.apache.sshd.server.kex.DHG14; import org.apache.sshd.server.session.SessionFactory; import org.bouncycastle.crypto.prng.RandomGenerator; import org.bouncycastle.crypto.prng.VMPCRandomGenerator; @@ -122,6 +97,13 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.UnknownHostException; +import java.nio.file.FileStore; +import java.nio.file.FileSystem; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.WatchService; +import java.nio.file.attribute.UserPrincipalLookupService; +import java.nio.file.spi.FileSystemProvider; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.PublicKey; @@ -130,8 +112,8 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; /** @@ -319,7 +301,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { @Override protected AbstractSession doCreateSession(IoSession ioSession) throws Exception { - return new GerritServerSession(server, ioSession); + return new GerritServerSession(getServer(), ioSession); } }); setGlobalRequestHandlers(Arrays.> asList( @@ -365,7 +347,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { } sshDaemonLog.info(String.format("Started Gerrit %s on %s", - version, addressList())); + getVersion(), addressList())); } } @@ -379,7 +361,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { try { daemonAcceptor.close(true).await(); sshDaemonLog.info("Stopped Gerrit SSHD"); - } catch (InterruptedException e) { + } catch (IOException e) { sshDaemonLog.warn("Exception caught while closing", e); } finally { daemonAcceptor = null; @@ -403,7 +385,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { final List keys = myHostKeys(); final List r = new ArrayList<>(); for (final PublicKey pub : keys) { - final Buffer buf = new Buffer(); + final Buffer buf = new ByteArrayBuffer(); buf.putRawPublicKey(pub); final byte[] keyBin = buf.getCompactData(); @@ -446,13 +428,18 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { } private void initProviderBouncyCastle(Config cfg) { - setKeyExchangeFactories(Arrays.> asList( - new DHG14.Factory(), new DHG1.Factory())); + setKeyExchangeFactories( + NamedFactory.Utils.setUpTransformedFactories(true, + Collections.unmodifiableList(Arrays.asList( + BuiltinDHFactories.dhg14, + BuiltinDHFactories.dhg1 + )), + ServerBuilder.DH2KEX)); NamedFactory factory; if (cfg.getBoolean("sshd", null, "testUseInsecureRandom", false)) { factory = new InsecureBouncyCastleRandom.Factory(); } else { - factory = new BouncyCastleRandom.Factory(); + factory = SecurityUtils.getRandomFactory(); } setRandomFactory(new SingletonRandomFactory(factory)); } @@ -482,6 +469,11 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { random.nextBytes(bytes, start, len); } + @Override + public void fill(byte[] bytes) { + random.nextBytes(bytes); + } + @Override public int random(int n) { if (n > 0) { @@ -512,23 +504,19 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { } private void initProviderJce() { - setKeyExchangeFactories(Arrays - .> asList(new DHG1.Factory())); - setRandomFactory(new SingletonRandomFactory(new JceRandom.Factory())); + setKeyExchangeFactories( + NamedFactory.Utils.setUpTransformedFactories(true, + Collections.unmodifiableList(Arrays.asList( + BuiltinDHFactories.dhg1 + )), + ServerBuilder.DH2KEX)); + setKeyExchangeFactories(ServerBuilder.setUpDefaultKeyExchanges(true)); + setRandomFactory(new SingletonRandomFactory(JceRandomFactory.INSTANCE)); } @SuppressWarnings("unchecked") private void initCiphers(final Config cfg) { - final List> a = new LinkedList<>(); - a.add(new AES128CBC.Factory()); - a.add(new TripleDESCBC.Factory()); - a.add(new BlowfishCBC.Factory()); - a.add(new AES192CBC.Factory()); - a.add(new AES256CBC.Factory()); - a.add(new AES128CTR.Factory()); - a.add(new AES256CTR.Factory()); - a.add(new ARCFOUR256.Factory()); - a.add(new ARCFOUR128.Factory()); + final List> a = BaseBuilder.setUpDefaultCiphers(true); for (Iterator> i = a.iterator(); i.hasNext();) { final NamedFactory f = i.next(); @@ -548,19 +536,15 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { } a.add(null); - a.add(new CipherNone.Factory()); setCipherFactories(filter(cfg, "cipher", (NamedFactory[])a.toArray(new NamedFactory[a.size()]))); } - private void initMacs(final Config cfg) { + @SuppressWarnings("unchecked") + private void initMacs(Config cfg) { + List> m = BaseBuilder.setUpDefaultMacs(true); setMacFactories(filter(cfg, "mac", - new HMACMD5.Factory(), - new HMACSHA1.Factory(), - new HMACMD596.Factory(), - new HMACSHA196.Factory(), - new HMACSHA256.Factory(), - new HMACSHA512.Factory())); + (NamedFactory[]) m.toArray(new NamedFactory[m.size()]))); } @SafeVarargs @@ -633,12 +617,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { } private void initSignatures() { - setSignatureFactories(Arrays.> asList( - new SignatureDSA.Factory(), - new SignatureRSA.Factory(), - new SignatureECDSA.NISTP256Factory(), - new SignatureECDSA.NISTP384Factory(), - new SignatureECDSA.NISTP521Factory())); + setSignatureFactories(BaseBuilder.setUpDefaultSignatures(true)); } private void initCompression(boolean enableCompression) { @@ -646,7 +625,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { Lists.newArrayList(); // Always support no compression over SSHD. - compressionFactories.add(new CompressionNone.Factory()); + compressionFactories.add(BuiltinCompressions.none); // In the general case, we want to disable transparent compression, since // the majority of our data transfer is highly compressed Git pack files @@ -661,17 +640,14 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { // receive-packs. if (enableCompression) { - compressionFactories.add(new CompressionZlib.Factory()); + compressionFactories.add(BuiltinCompressions.zlib); } setCompressionFactories(compressionFactories); } private void initChannels() { - setChannelFactories(Arrays.> asList( - new ChannelSession.Factory(), // - new TcpipServerChannel.DirectTcpipFactory() // - )); + setChannelFactories(ServerBuilder.DEFAULT_CHANNEL_FACTORIES); } private void initSubsystems() { @@ -683,8 +659,8 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { String kerberosKeytab, String kerberosPrincipal) { List> authFactories = Lists.newArrayList(); if (kerberosKeytab != null) { - authFactories.add(new UserAuthGSS.Factory()); - sshDaemonLog.info("Enabling kerberos with keytab " + kerberosKeytab); + authFactories.add(UserAuthGSSFactory.INSTANCE); + log.info("Enabling kerberos with keytab " + kerberosKeytab); if (!new File(kerberosKeytab).canRead()) { sshDaemonLog.error("Keytab " + kerberosKeytab + " does not exist or is not readable; further errors are possible"); @@ -706,7 +682,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { kerberosAuthenticator.setServicePrincipalName(kerberosPrincipal); setGSSAuthenticator(kerberosAuthenticator); } - authFactories.add(new UserAuthPublicKey.Factory()); + authFactories.add(UserAuthPublicKeyFactory.INSTANCE); setUserAuthFactories(authFactories); setPublickeyAuthenticator(pubkey); } @@ -729,7 +705,7 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { } @Override - public boolean canConnect(SshdSocketAddress address, Session session) { + public boolean canConnect(Type type, SshdSocketAddress address, Session session) { return false; } }); @@ -739,22 +715,66 @@ public class SshDaemon extends SshServer implements SshInfo, LifecycleListener { private void initFileSystemFactory() { setFileSystemFactory(new FileSystemFactory() { @Override - public FileSystemView createFileSystemView(Session session) + public FileSystem createFileSystem(Session session) throws IOException { - return new FileSystemView() { + return new FileSystem() { @Override - public SshFile getFile(SshFile baseDir, String file) { + public void close() throws IOException { + } + + @Override + public Iterable getFileStores() { return null; } @Override - public SshFile getFile(String file) { + public Path getPath(String arg0, String... arg1) { return null; } @Override - public FileSystemView getNormalizedView() { - return this; + public PathMatcher getPathMatcher(String arg0) { + return null; + } + + @Override + public Iterable getRootDirectories() { + return null; + } + + @Override + public String getSeparator() { + return null; + } + + @Override + public UserPrincipalLookupService getUserPrincipalLookupService() { + return null; + } + + @Override + public boolean isOpen() { + return false; + } + + @Override + public boolean isReadOnly() { + return false; + } + + @Override + public WatchService newWatchService() throws IOException { + return null; + } + + @Override + public FileSystemProvider provider() { + return null; + } + + @Override + public Set supportedFileAttributeViews() { + return null; } }; } diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshHostKeyModule.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshHostKeyModule.java index fdf34a2956..2f88fa97d6 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshHostKeyModule.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshHostKeyModule.java @@ -18,7 +18,7 @@ import static com.google.inject.Scopes.SINGLETON; import com.google.inject.AbstractModule; -import org.apache.sshd.common.KeyPairProvider; +import org.apache.sshd.common.keyprovider.KeyPairProvider; public class SshHostKeyModule extends AbstractModule { @Override diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java index 7dd12b0cfd..974b233d97 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java @@ -37,8 +37,8 @@ import com.google.inject.internal.UniqueAnnotations; import com.google.inject.servlet.RequestScoped; import org.apache.sshd.server.CommandFactory; -import org.apache.sshd.server.PublickeyAuthenticator; import org.apache.sshd.server.auth.gss.GSSAuthenticator; +import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator; import org.eclipse.jgit.lib.Config; import java.net.SocketAddress; diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshSession.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshSession.java index 6285b205be..00fb2907cc 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshSession.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshSession.java @@ -17,7 +17,7 @@ package com.google.gerrit.sshd; import com.google.gerrit.server.AccessPath; import com.google.gerrit.server.CurrentUser; -import org.apache.sshd.common.Session.AttributeKey; +import org.apache.sshd.common.session.Session.AttributeKey; import java.net.InetAddress; import java.net.InetSocketAddress; diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshUtil.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshUtil.java index cca426d487..ad938f8d65 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshUtil.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshUtil.java @@ -21,11 +21,11 @@ import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.sshd.SshScope.Context; import org.apache.commons.codec.binary.Base64; -import org.apache.sshd.common.KeyPairProvider; import org.apache.sshd.common.SshException; import org.apache.sshd.common.future.CloseFuture; import org.apache.sshd.common.future.SshFutureListener; -import org.apache.sshd.common.util.Buffer; +import org.apache.sshd.common.keyprovider.KeyPairProvider; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; import org.apache.sshd.server.session.ServerSession; import org.eclipse.jgit.lib.Constants; @@ -59,7 +59,7 @@ public class SshUtil { throw new InvalidKeySpecException("No key string"); } final byte[] bin = Base64.decodeBase64(Constants.encodeASCII(s)); - return new Buffer(bin).getRawPublicKey(); + return new ByteArrayBuffer(bin).getRawPublicKey(); } catch (RuntimeException | SshException e) { throw new InvalidKeySpecException("Cannot parse key", e); } @@ -96,7 +96,7 @@ public class SshUtil { } final PublicKey key = - new Buffer(Base64.decodeBase64(Constants.encodeASCII(strBuf + new ByteArrayBuffer(Base64.decodeBase64(Constants.encodeASCII(strBuf .toString()))).getRawPublicKey(); if (key instanceof RSAPublicKey) { strBuf.insert(0, KeyPairProvider.SSH_RSA + " "); diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CloseConnection.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CloseConnection.java index af772f8e95..d641c6afb5 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CloseConnection.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CloseConnection.java @@ -28,12 +28,13 @@ import com.google.inject.Inject; import org.apache.sshd.common.future.CloseFuture; import org.apache.sshd.common.io.IoAcceptor; import org.apache.sshd.common.io.IoSession; -import org.apache.sshd.server.session.ServerSession; +import org.apache.sshd.common.session.AbstractSession; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -67,8 +68,7 @@ final class CloseConnection extends SshCommand { boolean connectionFound = false; int id = (int) Long.parseLong(sessionId, 16); for (IoSession io : acceptor.getManagedSessions().values()) { - ServerSession serverSession = - (ServerSession) ServerSession.getSession(io, true); + AbstractSession serverSession = AbstractSession.getSession(io, true); SshSession sshSession = serverSession != null ? serverSession.getAttribute(SshSession.KEY) @@ -81,7 +81,7 @@ final class CloseConnection extends SshCommand { try { future.await(); stdout.println("closed connection " + sessionId); - } catch (InterruptedException e) { + } catch (IOException e) { log.warn("Wait for connection to close interrupted: " + e.getMessage()); } diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowConnections.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowConnections.java index 8ac98875ba..5ff5c51457 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowConnections.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowConnections.java @@ -33,8 +33,8 @@ import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.io.mina.MinaAcceptor; import org.apache.sshd.common.io.mina.MinaSession; import org.apache.sshd.common.io.nio2.Nio2Acceptor; +import org.apache.sshd.common.session.AbstractSession; import org.apache.sshd.server.Environment; -import org.apache.sshd.server.session.ServerSession; import org.kohsuke.args4j.Option; import java.io.IOException; @@ -112,7 +112,7 @@ final class ShowConnections extends SshCommand { "Session", "Start", "Idle", "User", "Remote Host")); stdout.print("--------------------------------------------------------------\n"); for (final IoSession io : list) { - ServerSession s = (ServerSession) ServerSession.getSession(io, true); + AbstractSession s = AbstractSession.getSession(io, true); SshSession sd = s != null ? s.getAttribute(SshSession.KEY) : null; final SocketAddress remoteAddress = io.getRemoteAddress(); diff --git a/lib/mina/BUCK b/lib/mina/BUCK index 0c9b41ea75..902e4197ea 100644 --- a/lib/mina/BUCK +++ b/lib/mina/BUCK @@ -8,8 +8,8 @@ EXCLUDE = [ maven_jar( name = 'sshd', - id = 'org.apache.sshd:sshd-core:0.14.0', - sha1 = 'cb12fa1b1b07fb5ce3aa4f99b189743897bd4fca', + id = 'org.apache.sshd:sshd-core:1.0.0', + sha1 = '448ae95811a993575cc465e1c60ef741632b2ce8', license = 'Apache2.0', deps = [':core'], exclude = EXCLUDE, @@ -17,8 +17,8 @@ maven_jar( maven_jar( name = 'core', - id = 'org.apache.mina:mina-core:2.0.8', - sha1 = 'd6ff69fa049aeaecdf0c04cafbb1ab53b7487883', + id = 'org.apache.mina:mina-core:2.0.10', + sha1 = 'a1cb1136b104219d6238de886bf5a3ea4554eb58', license = 'Apache2.0', exclude = EXCLUDE, )