Upgraded Apache SSHD to 1.0.0

This commit is contained in:
Jeroen van Erp
2015-11-03 13:43:00 +01:00
parent 75c0ae9a83
commit 7973cb1ff6
12 changed files with 64 additions and 246 deletions

View File

@@ -53,7 +53,7 @@ dependencies {
testCompile "junit:junit:4.11"
testCompile "org.mockito:mockito-core:1.9.5"
testCompile "org.apache.sshd:sshd-core:0.11.0"
testCompile "org.apache.sshd:sshd-core:1.0.0"
testRuntime "ch.qos.logback:logback-classic:1.1.2"
}

View File

@@ -135,7 +135,7 @@ public enum KeyType {
BigInteger bigY = new BigInteger(1, y);
X9ECParameters ecParams = NISTNamedCurves.getByName("p-256");
ECPoint pPublicPoint = ecParams.getCurve().createPoint(bigX, bigY, false);
ECPoint pPublicPoint = ecParams.getCurve().createPoint(bigX, bigY);
ECParameterSpec spec = new ECParameterSpec(ecParams.getCurve(),
ecParams.getG(), ecParams.getN());
ECPublicKeySpec publicSpec = new ECPublicKeySpec(pPublicPoint, spec);

View File

@@ -2,8 +2,6 @@ package net.schmizz.sshj.transport.kex;
import net.schmizz.sshj.common.SSHRuntimeException;
import net.schmizz.sshj.common.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigInteger;
import java.security.GeneralSecurityException;

View File

@@ -7,7 +7,6 @@ import net.schmizz.sshj.transport.digest.SHA512;
import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
import java.security.GeneralSecurityException;
import java.security.spec.ECGenParameterSpec;
public class ECDHNistP extends AbstractDHG {

View File

@@ -24,6 +24,8 @@ public class SFTPClientTest {
SSHClient sshClient = fixture.setupConnectedDefaultClient();
sshClient.authPassword("test", "test");
SFTPClient sftpClient = sshClient.newSFTPClient();
// TODO workaround for bug in Mina 1.0.0 --> Should be fixed in 1.1.0
sftpClient.getFileTransfer().setPreserveAttributes(false);
File file = temp.newFile("source.txt");
FileUtil.writeToFile(file, "This is the source");
try {

View File

@@ -3,21 +3,19 @@ package com.hierynomus.sshj.test;
import net.schmizz.sshj.Config;
import net.schmizz.sshj.DefaultConfig;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.transport.TransportException;
import net.schmizz.sshj.userauth.UserAuthException;
import net.schmizz.sshj.util.gss.BogusGSSAuthenticator;
import org.apache.sshd.SshServer;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
import org.apache.sshd.common.keyprovider.AbstractClassLoadableResourceKeyPairProvider;
import org.apache.sshd.common.util.OsUtils;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.server.Command;
import org.apache.sshd.server.CommandFactory;
import org.apache.sshd.server.PasswordAuthenticator;
import org.apache.sshd.server.channel.ChannelSession;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.password.PasswordAuthenticator;
import org.apache.sshd.server.command.ScpCommandFactory;
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.server.sftp.SftpSubsystem;
import org.apache.sshd.server.shell.ProcessShellFactory;
import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory;
import org.junit.rules.ExternalResource;
import java.io.IOException;
@@ -31,7 +29,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
* Can be used as a rule to ensure the server is teared down after each test.
*/
public class SshFixture extends ExternalResource {
public static final String hostkey = "src/test/resources/hostkey.pem";
public static final String hostkey = "hostkey.pem";
public static final String fingerprint = "ce:a7:c1:cf:17:3f:96:49:6a:53:1a:05:0b:ba:90:db";
private SshServer server = defaultSshServer();
@@ -60,8 +58,9 @@ public class SshFixture extends ExternalResource {
}
public void start() throws IOException {
server.start();
started.set(true);
if (!started.getAndSet(true)) {
server.start();
}
}
public SSHClient setupConnectedDefaultClient() throws IOException {
@@ -96,7 +95,9 @@ public class SshFixture extends ExternalResource {
private SshServer defaultSshServer() {
SshServer sshServer = SshServer.setUpDefaultServer();
sshServer.setPort(randomPort());
sshServer.setKeyPairProvider(new FileKeyPairProvider(new String[]{hostkey}));
AbstractClassLoadableResourceKeyPairProvider fileKeyPairProvider = SecurityUtils.createClassLoadableResourceKeyPairProvider();
fileKeyPairProvider.setResources(Collections.singletonList(hostkey));
sshServer.setKeyPairProvider(fileKeyPairProvider);
sshServer.setPasswordAuthenticator(new PasswordAuthenticator() {
@Override
public boolean authenticate(String username, String password, ServerSession session) {
@@ -104,18 +105,15 @@ public class SshFixture extends ExternalResource {
}
});
sshServer.setGSSAuthenticator(new BogusGSSAuthenticator());
sshServer.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
sshServer.setCommandFactory(new ScpCommandFactory(new CommandFactory() {
sshServer.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
ScpCommandFactory commandFactory = new ScpCommandFactory();
commandFactory.setDelegateCommandFactory(new CommandFactory() {
@Override
public Command createCommand(String command) {
EnumSet<ProcessShellFactory.TtyOptions> ttyOptions;
if (OsUtils.isUNIX()) {
ttyOptions = EnumSet.of(ProcessShellFactory.TtyOptions.ONlCr);
} else {
ttyOptions = EnumSet.of(ProcessShellFactory.TtyOptions.Echo, ProcessShellFactory.TtyOptions.ICrNl, ProcessShellFactory.TtyOptions.ONlCr);
}
return new ProcessShellFactory(command.split(" "), ttyOptions).create();
return new ProcessShellFactory(command.split(" ")).create();
}
}));
});
sshServer.setCommandFactory(commandFactory);
return sshServer;
}
@@ -150,10 +148,10 @@ public class SshFixture extends ExternalResource {
}
public void stopServer() {
if (started.get()) {
if (started.getAndSet(false)) {
try {
server.stop();
} catch (InterruptedException e) {
server.stop(true);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

View File

@@ -8,13 +8,16 @@ import net.schmizz.sshj.common.Factory;
import net.schmizz.sshj.transport.kex.DHGexSHA1;
import net.schmizz.sshj.transport.kex.DHGexSHA256;
import net.schmizz.sshj.transport.kex.ECDHNistP;
import org.apache.sshd.common.KeyExchange;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.server.kex.*;
import org.apache.sshd.common.kex.BuiltinDHFactories;
import org.apache.sshd.server.kex.DHGEXServer;
import org.apache.sshd.server.kex.DHGServer;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Collections;
@@ -22,6 +25,8 @@ import java.util.Collections;
import static org.hamcrest.MatcherAssert.assertThat;
public class KeyExchangeTest {
private static final Logger logger = LoggerFactory.getLogger(KeyExchangeTest.class);
@Rule
public SshFixture fixture = new SshFixture(false);
@@ -32,31 +37,40 @@ public class KeyExchangeTest {
@Test
public void shouldKexWithDiffieHellmanGroupExchangeSha1() throws IOException {
setupAndCheckKex(new DHGEX.Factory(), new DHGexSHA1.Factory());
setupAndCheckKex(DHGEXServer.newFactory(BuiltinDHFactories.dhgex), new DHGexSHA1.Factory());
}
@Test
public void shouldKexWithDiffieHellmanGroupExchangeSha256() throws IOException {
setupAndCheckKex(new DHGEX256.Factory(), new DHGexSHA256.Factory());
setupAndCheckKex(DHGEXServer.newFactory(BuiltinDHFactories.dhgex256), new DHGexSHA256.Factory());
}
@Test
public void shouldKexWithEllipticCurveDiffieHellmanNistP256() throws IOException {
setupAndCheckKex(new ECDHP256.Factory(), new ECDHNistP.Factory256());
attemptKex(100, DHGServer.newFactory(BuiltinDHFactories.ecdhp256), new ECDHNistP.Factory256());
}
@Test
public void shouldKexWithEllipticCurveDiffieHellmanNistP384() throws IOException {
setupAndCheckKex(new ECDHP384.Factory(), new ECDHNistP.Factory384());
attemptKex(100, DHGServer.newFactory(BuiltinDHFactories.ecdhp384), new ECDHNistP.Factory384());
}
@Test
@Category({KnownFailingTests.class})
public void shouldKexWithEllipticCurveDiffieHellmanNistP521() throws IOException {
setupAndCheckKex(new ECDHP521.Factory(), new ECDHNistP.Factory521());
attemptKex(100, DHGServer.newFactory(BuiltinDHFactories.ecdhp521), new ECDHNistP.Factory521());
}
private void setupAndCheckKex(NamedFactory<KeyExchange> serverFactory,
private void attemptKex(int times, NamedFactory<org.apache.sshd.common.kex.KeyExchange> serverFactory,
Factory.Named<net.schmizz.sshj.transport.kex.KeyExchange> clientFactory) throws IOException {
for (int i = 0; i < times; i++) {
logger.info("--> Attempt {}", i);
setupAndCheckKex(serverFactory, clientFactory);
}
}
private void setupAndCheckKex(NamedFactory<org.apache.sshd.common.kex.KeyExchange> serverFactory,
Factory.Named<net.schmizz.sshj.transport.kex.KeyExchange> clientFactory) throws IOException {
fixture.getServer().setKeyExchangeFactories(Collections.singletonList(serverFactory));
fixture.start();
@@ -65,5 +79,7 @@ public class KeyExchangeTest {
SSHClient sshClient = fixture.connectClient(fixture.setupClient(config));
assertThat("should be connected", sshClient.isConnected());
sshClient.disconnect();
// fixture.stopServer();
fixture.stopClient();
}
}

View File

@@ -15,7 +15,7 @@
*/
package net.schmizz.sshj;
import net.schmizz.sshj.util.BasicFixture;
import com.hierynomus.sshj.test.SshFixture;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,15 +26,17 @@ public class LoadsOfConnects {
protected final Logger log = LoggerFactory.getLogger(getClass());
private final BasicFixture fixture = new BasicFixture();
private final SshFixture fixture = new SshFixture();
@Test
public void loadsOfConnects()
throws IOException, InterruptedException {
for (int i = 0; i < 1000; i++) {
System.out.println("Try " + i);
fixture.init(false);
fixture.done();
fixture.start();
fixture.setupConnectedDefaultClient();
fixture.stopClient();
fixture.stopServer();
}
}

View File

@@ -15,9 +15,9 @@
*/
package net.schmizz.sshj;
import com.hierynomus.sshj.test.SshFixture;
import net.schmizz.sshj.transport.TransportException;
import net.schmizz.sshj.userauth.UserAuthException;
import net.schmizz.sshj.util.BasicFixture;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -29,18 +29,20 @@ import static org.junit.Assert.assertTrue;
/* Kinda basic right now */
public class SmokeTest {
private final BasicFixture fixture = new BasicFixture();
private final SshFixture fixture = new SshFixture();
@Before
public void setUp()
throws IOException {
fixture.init(false);
fixture.start();
fixture.setupConnectedDefaultClient();
}
@After
public void tearDown()
throws IOException, InterruptedException {
fixture.done();
fixture.stopClient();
fixture.stopServer();
}
@Test
@@ -52,7 +54,7 @@ public class SmokeTest {
@Test
public void authenticated()
throws UserAuthException, TransportException {
fixture.dummyAuth();
fixture.getClient().authPassword("dummy", "dummy");
assertTrue(fixture.getClient().isAuthenticated());
}

View File

@@ -1,155 +0,0 @@
/**
* Copyright 2009 sshj contributors
*
* 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.
*/
/*
* Copyright 2010, 2011 sshj contributors
*
* 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 net.schmizz.sshj.util;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.transport.TransportException;
import net.schmizz.sshj.userauth.UserAuthException;
import org.apache.sshd.SshServer;
import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
import org.apache.sshd.server.PasswordAuthenticator;
import org.apache.sshd.server.auth.gss.GSSAuthenticator;
import org.apache.sshd.server.session.ServerSession;
import java.io.IOException;
import java.net.ServerSocket;
public class BasicFixture {
public static final String hostkey = "src/test/resources/hostkey.pem";
public static final String fingerprint = "ce:a7:c1:cf:17:3f:96:49:6a:53:1a:05:0b:ba:90:db";
public static final String hostname = "localhost";
public final int port = gimmeAPort();
private GSSAuthenticator gssAuthenticator;
private SSHClient client;
private SshServer server;
private boolean clientRunning = false;
private boolean serverRunning = false;
private static int gimmeAPort() {
try {
ServerSocket s = null;
try {
s = new ServerSocket(0);
return s.getLocalPort();
} finally {
if (s != null)
s.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void init()
throws IOException {
init(false);
}
public void init(boolean authenticate)
throws IOException {
startServer();
startClient(authenticate);
}
public void done()
throws InterruptedException, IOException {
stopClient();
stopServer();
}
public void startServer()
throws IOException {
server = SshServer.setUpDefaultServer();
server.setPort(port);
server.setKeyPairProvider(new FileKeyPairProvider(new String[]{hostkey}));
server.setPasswordAuthenticator(new PasswordAuthenticator() {
@Override
public boolean authenticate(String u, String p, ServerSession s) {
return false;
}
});
server.setGSSAuthenticator(gssAuthenticator);
server.start();
serverRunning = true;
}
public void stopServer()
throws InterruptedException {
if (serverRunning) {
server.stop();
serverRunning = false;
}
}
public SshServer getServer() {
return server;
}
public void startClient(boolean authenticate)
throws IOException {
client = new SSHClient();
client.addHostKeyVerifier(fingerprint);
client.connect(hostname, port);
if (authenticate)
dummyAuth();
clientRunning = true;
}
public void stopClient()
throws IOException {
if (clientRunning) {
client.disconnect();
clientRunning = false;
}
}
public SSHClient getClient() {
return client;
}
public void setGssAuthenticator(GSSAuthenticator gssAuthenticator) {
this.gssAuthenticator = gssAuthenticator;
}
public void dummyAuth()
throws UserAuthException, TransportException {
server.setPasswordAuthenticator(new BogusPasswordAuthenticator());
client.authPassword("same", "same");
}
}

View File

@@ -1,45 +0,0 @@
/**
* Copyright 2009 sshj contributors
*
* 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.
*/
/*
* Copyright 2010, 2011 sshj contributors
*
* 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 net.schmizz.sshj.util;
import org.apache.sshd.server.PasswordAuthenticator;
import org.apache.sshd.server.session.ServerSession;
/** Successfully authenticates when username == password. */
public class BogusPasswordAuthenticator
implements PasswordAuthenticator {
@Override
public boolean authenticate(String username, String password, ServerSession s) {
return username.equals(password);
}
}

View File

@@ -52,6 +52,7 @@ public class SCPFileTransferTest {
public void shouldSCPUploadFile() throws IOException {
SCPFileTransfer scpFileTransfer = sshClient.newSCPFileTransfer();
assertFalse(targetFile.exists());
assertTrue(targetDir.exists());
scpFileTransfer.upload(sourceFile.getAbsolutePath(), targetDir.getAbsolutePath());
assertTrue(targetFile.exists());
}