mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 15:20:54 +03:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d326e5ae4 | ||
|
|
f038b5ce2b | ||
|
|
20879a4aa5 | ||
|
|
516abb0282 | ||
|
|
0ad51709c2 | ||
|
|
c9c68f019e | ||
|
|
fc75f9796c | ||
|
|
61af500c3e | ||
|
|
56553ea086 | ||
|
|
86e6631b1e | ||
|
|
b6f437a932 | ||
|
|
9e3b9f7c24 | ||
|
|
766ab916ee | ||
|
|
cdca43a848 | ||
|
|
3ce7c2ebfb | ||
|
|
ca4e0bf2d7 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,6 +11,7 @@
|
||||
|
||||
# Output dirs
|
||||
target/
|
||||
classes/
|
||||
build/
|
||||
docs/
|
||||
.gradle/
|
||||
|
||||
@@ -79,7 +79,7 @@ compression::
|
||||
`zlib` and `zlib@openssh.com` (delayed zlib)
|
||||
|
||||
private key files::
|
||||
`pkcs8` encoded (what openssh uses)
|
||||
`pkcs5`, `pkcs8`, `openssh-key-v1`
|
||||
|
||||
If you need something that is not included, it shouldn't be too hard to add (do contribute it!)
|
||||
|
||||
@@ -99,6 +99,13 @@ Google Group: http://groups.google.com/group/sshj-users
|
||||
Fork away!
|
||||
|
||||
== Release history
|
||||
SSHJ 0.19.1 (2016-12-30)::
|
||||
* Enabled PKCS5 Key files in DefaultConfig
|
||||
* Merged https://github.com/hierynomus/sshj/pulls/291[#291]: Fixed sshj.properties loading and chained exception messages
|
||||
* Merged https://github.com/hierynomus/sshj/pulls/284[#284]: Correctly catch interrupt in keepalive thread
|
||||
* Fixed https://github.com/hierynomus/sshj/issues/292[#292]: Pass the configured RandomFactory to Diffie Hellmann KEX
|
||||
* Fixed https://github.com/hierynomus/sshj/issues/256[#256]: SSHJ now builds if no git repository present
|
||||
* LocalPortForwarder now correctly interrupts its own thread on close()
|
||||
SSHJ 0.19.0 (2016-11-25)::
|
||||
* Fixed https://github.com/hierynomus/sshj/issues/276[#276]: Add support for ed-25519 and new OpenSSH key format
|
||||
* Fixed https://github.com/hierynomus/sshj/issues/280[#280]: Read version from a generated sshj.properties file to correctly output version during negotiation
|
||||
|
||||
@@ -53,8 +53,12 @@ license {
|
||||
excludes(['**/djb/Curve25519.java', '**/sshj/common/Base64.java'])
|
||||
}
|
||||
|
||||
release {
|
||||
grgit = org.ajoberstar.grgit.Grgit.open(project.projectDir)
|
||||
if (project.file('.git').isDirectory()) {
|
||||
release {
|
||||
grgit = org.ajoberstar.grgit.Grgit.open(project.projectDir)
|
||||
}
|
||||
} else {
|
||||
version = "0.0.0-no.git"
|
||||
}
|
||||
|
||||
// This disables the pedantic doclint feature of JDK8
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<groupId>com.hierynomus</groupId>
|
||||
<artifactId>sshj-examples</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>0.19.0</version>
|
||||
<version>0.19.1</version>
|
||||
|
||||
<name>sshj-examples</name>
|
||||
<description>Examples for SSHv2 library for Java</description>
|
||||
@@ -55,7 +55,7 @@
|
||||
<dependency>
|
||||
<groupId>com.hierynomus</groupId>
|
||||
<artifactId>sshj</artifactId>
|
||||
<version>0.18.0</version>
|
||||
<version>0.19.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -29,6 +29,6 @@ public class StreamCipher extends BaseCipher {
|
||||
|
||||
@Override
|
||||
protected void initCipher(javax.crypto.Cipher cipher, Mode mode, byte[] key, byte[] iv) throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
cipher.init(getMode(mode), getKeySpec(key), new SecureRandom());
|
||||
cipher.init(getMode(mode), getKeySpec(key));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,8 @@ public abstract class KeepAlive extends Thread {
|
||||
}
|
||||
Thread.sleep(hi * 1000);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// Interrupt signal may be catched when sleeping.
|
||||
} catch (Exception e) {
|
||||
// If we weren't interrupted, kill the transport, then this exception was unexpected.
|
||||
// Else we're in shutdown-mode already, so don't forcibly kill the transport.
|
||||
|
||||
@@ -34,6 +34,8 @@ import net.schmizz.sshj.transport.random.JCERandom;
|
||||
import net.schmizz.sshj.transport.random.SingletonRandomFactory;
|
||||
import net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile;
|
||||
import com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile;
|
||||
|
||||
import net.schmizz.sshj.userauth.keyprovider.PKCS5KeyFile;
|
||||
import net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile;
|
||||
import net.schmizz.sshj.userauth.keyprovider.PuTTYKeyFile;
|
||||
import org.slf4j.Logger;
|
||||
@@ -85,7 +87,7 @@ public class DefaultConfig
|
||||
private String readVersionFromProperties() {
|
||||
try {
|
||||
Properties properties = new Properties();
|
||||
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("sshj.properties"));
|
||||
properties.load(DefaultConfig.class.getClassLoader().getResourceAsStream("sshj.properties"));
|
||||
String property = properties.getProperty("sshj.version");
|
||||
return "SSHJ_" + property.replace('-', '_'); // '-' is a disallowed character, see RFC-4253#section-4.2
|
||||
} catch (IOException e) {
|
||||
@@ -122,7 +124,12 @@ public class DefaultConfig
|
||||
|
||||
protected void initFileKeyProviderFactories(boolean bouncyCastleRegistered) {
|
||||
if (bouncyCastleRegistered) {
|
||||
setFileKeyProviderFactories(new OpenSSHKeyV1KeyFile.Factory(), new PKCS8KeyFile.Factory(), new OpenSSHKeyFile.Factory(), new PuTTYKeyFile.Factory());
|
||||
setFileKeyProviderFactories(
|
||||
new OpenSSHKeyV1KeyFile.Factory(),
|
||||
new PKCS8KeyFile.Factory(),
|
||||
new PKCS5KeyFile.Factory(),
|
||||
new OpenSSHKeyFile.Factory(),
|
||||
new PuTTYKeyFile.Factory());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class SSHRuntimeException
|
||||
}
|
||||
|
||||
public SSHRuntimeException(Throwable cause) {
|
||||
this(null, cause);
|
||||
this(cause.getMessage(), cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ public class LocalPortForwarder {
|
||||
private final Connection conn;
|
||||
private final Parameters parameters;
|
||||
private final ServerSocket serverSocket;
|
||||
private Thread runningThread;
|
||||
|
||||
public LocalPortForwarder(Connection conn, Parameters parameters, ServerSocket serverSocket, LoggerFactory loggerFactory) {
|
||||
this.conn = conn;
|
||||
@@ -132,10 +133,20 @@ public class LocalPortForwarder {
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void listen()
|
||||
throws IOException {
|
||||
public void listen() throws IOException {
|
||||
listen(Thread.currentThread());
|
||||
}
|
||||
|
||||
/**
|
||||
* Start listening for incoming connections and forward to remote host as a channel and ensure that the thread is registered.
|
||||
* This is useful if for instance {@link #close() is called from another thread}
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void listen(Thread runningThread) throws IOException {
|
||||
this.runningThread = runningThread;
|
||||
log.info("Listening on {}", serverSocket.getLocalSocketAddress());
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
while (!runningThread.isInterrupted()) {
|
||||
try {
|
||||
final Socket socket = serverSocket.accept();
|
||||
log.debug("Got connection from {}", socket.getRemoteSocketAddress());
|
||||
@@ -162,6 +173,7 @@ public class LocalPortForwarder {
|
||||
if (!serverSocket.isClosed()) {
|
||||
log.info("Closing listener on {}", serverSocket.getLocalSocketAddress());
|
||||
serverSocket.close();
|
||||
runningThread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ public abstract class AbstractDHGex extends AbstractDH {
|
||||
throw new GeneralSecurityException("Server generated gex p is out of range (" + bitLength + " bits)");
|
||||
}
|
||||
log.debug("Received server p bitlength {}", bitLength);
|
||||
dh.init(new DHParameterSpec(p, g));
|
||||
dh.init(new DHParameterSpec(p, g), trans.getConfig().getRandomFactory());
|
||||
log.debug("Sending {}", Message.KEX_DH_GEX_INIT);
|
||||
trans.write(new SSHPacket(Message.KEX_DH_GEX_INIT).putBytes(dh.getE()));
|
||||
return false;
|
||||
|
||||
@@ -15,19 +15,19 @@
|
||||
*/
|
||||
package net.schmizz.sshj.transport.kex;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import org.bouncycastle.asn1.x9.X9ECParameters;
|
||||
import org.bouncycastle.crypto.ec.CustomNamedCurves;
|
||||
import org.bouncycastle.jce.spec.ECParameterSpec;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import net.schmizz.sshj.common.Factory;
|
||||
import net.schmizz.sshj.transport.random.Random;
|
||||
|
||||
public class Curve25519DH extends DHBase {
|
||||
|
||||
|
||||
private byte[] secretKey;
|
||||
|
||||
public Curve25519DH() {
|
||||
@@ -42,10 +42,10 @@ public class Curve25519DH extends DHBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(AlgorithmParameterSpec params) throws GeneralSecurityException {
|
||||
SecureRandom secureRandom = new SecureRandom();
|
||||
public void init(AlgorithmParameterSpec params, Factory<Random> randomFactory) throws GeneralSecurityException {
|
||||
Random random = randomFactory.create();
|
||||
byte[] secretBytes = new byte[32];
|
||||
secureRandom.nextBytes(secretBytes);
|
||||
random.fill(secretBytes);
|
||||
byte[] publicBytes = new byte[32];
|
||||
djb.Curve25519.keygen(publicBytes, null, secretBytes);
|
||||
this.secretKey = Arrays.copyOf(secretBytes, secretBytes.length);
|
||||
|
||||
@@ -45,6 +45,6 @@ public class Curve25519SHA256 extends AbstractDHG {
|
||||
|
||||
@Override
|
||||
protected void initDH(DHBase dh) throws GeneralSecurityException {
|
||||
dh.init(Curve25519DH.getCurve25519Params());
|
||||
dh.init(Curve25519DH.getCurve25519Params(), trans.getConfig().getRandomFactory());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package net.schmizz.sshj.transport.kex;
|
||||
|
||||
import net.schmizz.sshj.common.Factory;
|
||||
import net.schmizz.sshj.common.SSHRuntimeException;
|
||||
import net.schmizz.sshj.common.SecurityUtils;
|
||||
import net.schmizz.sshj.transport.random.Random;
|
||||
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
import javax.crypto.spec.DHPublicKeySpec;
|
||||
@@ -38,7 +40,7 @@ public class DH extends DHBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(AlgorithmParameterSpec params) throws GeneralSecurityException {
|
||||
protected void init(AlgorithmParameterSpec params, Factory<Random> randomFactory) throws GeneralSecurityException {
|
||||
if (!(params instanceof DHParameterSpec)) {
|
||||
throw new SSHRuntimeException("Wrong algorithm parameters for Diffie Hellman");
|
||||
}
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package net.schmizz.sshj.transport.kex;
|
||||
|
||||
import net.schmizz.sshj.common.Factory;
|
||||
import net.schmizz.sshj.common.SSHRuntimeException;
|
||||
import net.schmizz.sshj.common.SecurityUtils;
|
||||
import net.schmizz.sshj.transport.random.Random;
|
||||
|
||||
import javax.crypto.KeyAgreement;
|
||||
import java.math.BigInteger;
|
||||
@@ -42,7 +44,7 @@ abstract class DHBase {
|
||||
|
||||
abstract void computeK(byte[] f) throws GeneralSecurityException;
|
||||
|
||||
protected abstract void init(AlgorithmParameterSpec params) throws GeneralSecurityException;
|
||||
protected abstract void init(AlgorithmParameterSpec params, Factory<Random> randomFactory) throws GeneralSecurityException;
|
||||
|
||||
void setE(byte[] e) {
|
||||
this.e = e;
|
||||
|
||||
@@ -51,6 +51,6 @@ public class DHG1
|
||||
|
||||
@Override
|
||||
protected void initDH(DHBase dh) throws GeneralSecurityException {
|
||||
dh.init(new DHParameterSpec(DHGroupData.P1, DHGroupData.G));
|
||||
dh.init(new DHParameterSpec(DHGroupData.P1, DHGroupData.G), trans.getConfig().getRandomFactory());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,6 @@ public class DHG14
|
||||
|
||||
@Override
|
||||
protected void initDH(DHBase dh) throws GeneralSecurityException {
|
||||
dh.init(new DHParameterSpec(DHGroupData.P14, DHGroupData.G));
|
||||
dh.init(new DHParameterSpec(DHGroupData.P14, DHGroupData.G), trans.getConfig().getRandomFactory());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package net.schmizz.sshj.transport.kex;
|
||||
|
||||
import net.schmizz.sshj.common.Factory;
|
||||
import net.schmizz.sshj.common.SecurityUtils;
|
||||
import net.schmizz.sshj.transport.random.Random;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
@@ -39,7 +41,7 @@ public class ECDH extends DHBase {
|
||||
super("EC", "ECDH");
|
||||
}
|
||||
|
||||
protected void init(AlgorithmParameterSpec params) throws GeneralSecurityException {
|
||||
protected void init(AlgorithmParameterSpec params, Factory<Random> randomFactory) throws GeneralSecurityException {
|
||||
generator.initialize(params);
|
||||
KeyPair keyPair = generator.generateKeyPair();
|
||||
agreement.init(keyPair.getPrivate());
|
||||
|
||||
@@ -79,7 +79,7 @@ public class ECDHNistP extends AbstractDHG {
|
||||
|
||||
@Override
|
||||
protected void initDH(DHBase dh) throws GeneralSecurityException {
|
||||
dh.init(new ECNamedCurveGenParameterSpec(curve));
|
||||
dh.init(new ECNamedCurveGenParameterSpec(curve), trans.getConfig().getRandomFactory());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ package net.schmizz.sshj.transport.random;
|
||||
|
||||
import org.bouncycastle.crypto.prng.RandomGenerator;
|
||||
import org.bouncycastle.crypto.prng.VMPCRandomGenerator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
@@ -27,6 +29,8 @@ import java.security.SecureRandom;
|
||||
public class BouncyCastleRandom
|
||||
implements Random {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BouncyCastleRandom.class);
|
||||
|
||||
/** Named factory for the BouncyCastle <code>Random</code> */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory<Random> {
|
||||
@@ -41,7 +45,10 @@ public class BouncyCastleRandom
|
||||
private final RandomGenerator random = new VMPCRandomGenerator();
|
||||
|
||||
public BouncyCastleRandom() {
|
||||
logger.info("Generating random seed from SecureRandom.");
|
||||
long t = System.currentTimeMillis();
|
||||
byte[] seed = new SecureRandom().generateSeed(8);
|
||||
logger.debug("Creating random seed took {} ms", System.currentTimeMillis() - t);
|
||||
random.addSeedMaterial(seed);
|
||||
}
|
||||
|
||||
@@ -50,4 +57,9 @@ public class BouncyCastleRandom
|
||||
random.nextBytes(bytes, start, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(byte[] bytes) {
|
||||
random.nextBytes(bytes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
package net.schmizz.sshj.transport.random;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** A {@link Random} implementation using the built-in {@link SecureRandom} PRNG. */
|
||||
public class JCERandom
|
||||
implements Random {
|
||||
private static final Logger logger = LoggerFactory.getLogger(JCERandom.class);
|
||||
|
||||
/** Named factory for the JCE {@link Random} */
|
||||
public static class Factory
|
||||
@@ -38,7 +41,14 @@ public class JCERandom
|
||||
}
|
||||
|
||||
private byte[] tmp = new byte[16];
|
||||
private final SecureRandom random = new SecureRandom();
|
||||
private final SecureRandom random;
|
||||
|
||||
JCERandom() {
|
||||
logger.info("Creating new SecureRandom.");
|
||||
long t = System.currentTimeMillis();
|
||||
random = new SecureRandom();
|
||||
logger.debug("Random creation took {} ms", System.currentTimeMillis() - t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given byte-array with random bytes from this PRNG.
|
||||
@@ -49,15 +59,20 @@ public class JCERandom
|
||||
*/
|
||||
@Override
|
||||
public synchronized void fill(byte[] foo, int start, int len) {
|
||||
if (start == 0 && len == foo.length)
|
||||
if (start == 0 && len == foo.length) {
|
||||
random.nextBytes(foo);
|
||||
else
|
||||
} else {
|
||||
synchronized (this) {
|
||||
if (len > tmp.length)
|
||||
tmp = new byte[len];
|
||||
random.nextBytes(tmp);
|
||||
System.arraycopy(tmp, 0, foo, start, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(final byte[] bytes) {
|
||||
random.nextBytes(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,13 @@ package net.schmizz.sshj.transport.random;
|
||||
/** A pseudo random number generator. */
|
||||
public interface Random {
|
||||
|
||||
/**
|
||||
* Fill the array of bytes with random values.
|
||||
*
|
||||
* @param bytes byte array to be filled.
|
||||
*/
|
||||
void fill(byte[] bytes);
|
||||
|
||||
/**
|
||||
* Fill part of bytes with random values.
|
||||
*
|
||||
|
||||
@@ -37,4 +37,8 @@ public class SingletonRandomFactory
|
||||
random.fill(bytes, start, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(final byte[] bytes) {
|
||||
random.fill(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public class KeyProviderUtil {
|
||||
return KeyFormat.OpenSSH;
|
||||
} else if (header.contains("BEGIN PRIVATE KEY") || header.contains("BEGIN ENCRYPTED PRIVATE KEY")) {
|
||||
return KeyFormat.PKCS8;
|
||||
} else {
|
||||
} else {
|
||||
return KeyFormat.PKCS5;
|
||||
}
|
||||
} else if (header.startsWith("PuTTY-User-Key-File-")) {
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C)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.
|
||||
*/
|
||||
package com.hierynomus.sshj.connection.channel.direct
|
||||
|
||||
import com.hierynomus.sshj.test.SshFixture
|
||||
import net.schmizz.sshj.connection.channel.direct.LocalPortForwarder
|
||||
import org.junit.Rule
|
||||
import spock.lang.Specification
|
||||
|
||||
class LocalPortForwarderSpec extends Specification {
|
||||
@Rule
|
||||
SshFixture tunnelFixture = new SshFixture()
|
||||
|
||||
@Rule
|
||||
SshFixture realServer = new SshFixture()
|
||||
|
||||
def "should not hang when disconnect tunnel"() {
|
||||
given:
|
||||
def client = tunnelFixture.setupConnectedDefaultClient()
|
||||
client.authPassword("test", "test")
|
||||
def socket = new ServerSocket(0)
|
||||
def lpf = client.newLocalPortForwarder(new LocalPortForwarder.Parameters("localhost", socket.getLocalPort(), "localhost", realServer.server.port), socket)
|
||||
def thread = new Thread(new Runnable() {
|
||||
@Override
|
||||
void run() {
|
||||
lpf.listen()
|
||||
}
|
||||
})
|
||||
|
||||
when:
|
||||
thread.start()
|
||||
|
||||
then:
|
||||
thread.isAlive()
|
||||
|
||||
when:
|
||||
lpf.close()
|
||||
|
||||
then:
|
||||
socket.isClosed()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C)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.
|
||||
*/
|
||||
package com.hierynomus.sshj.userauth.keyprovider
|
||||
|
||||
import com.hierynomus.sshj.test.SshFixture
|
||||
import net.schmizz.sshj.SSHClient
|
||||
import net.schmizz.sshj.userauth.keyprovider.KeyFormat
|
||||
import org.apache.sshd.server.auth.pubkey.AcceptAllPublickeyAuthenticator
|
||||
import org.junit.Rule
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Unroll
|
||||
|
||||
class FileKeyProviderSpec extends Specification {
|
||||
@Rule
|
||||
SshFixture fixture = new SshFixture(false)
|
||||
|
||||
def setup() {
|
||||
fixture.getServer().setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE)
|
||||
fixture.start()
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
fixture.stopServer()
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "should have #format FileKeyProvider enabled by default"() {
|
||||
given:
|
||||
SSHClient client = fixture.setupConnectedDefaultClient()
|
||||
|
||||
when:
|
||||
client.authPublickey("jeroen", keyfile)
|
||||
|
||||
then:
|
||||
client.isAuthenticated()
|
||||
|
||||
cleanup:
|
||||
client.disconnect()
|
||||
|
||||
where:
|
||||
format | keyfile
|
||||
KeyFormat.PKCS5 | "src/test/resources/keyformats/pkcs5"
|
||||
KeyFormat.OpenSSH | "src/test/resources/keyformats/openssh"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user