fix SFTP test
This commit is contained in:
parent
be26f3e231
commit
5cf088bd12
6 changed files with 128 additions and 109 deletions
|
@ -1,40 +0,0 @@
|
||||||
package org.apache.sshd.fs.test;
|
|
||||||
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import org.apache.sshd.client.ClientBuilder;
|
|
||||||
import org.apache.sshd.client.SshClient;
|
|
||||||
import org.apache.sshd.fs.SftpFileSystem;
|
|
||||||
import org.apache.sshd.fs.SftpFileSystemProvider;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.security.KeyPair;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import org.xbib.net.security.PrivateKeyReader;
|
|
||||||
|
|
||||||
public class SFTPFileSystemTest {
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(SFTPFileSystemTest.class.getName());
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testXbib() throws Exception {
|
|
||||||
Map<String, String> env = new HashMap<>();
|
|
||||||
env.put("username", "joerg");
|
|
||||||
URI uri = URI.create("sftp://xbib.org");
|
|
||||||
SshClient sshClient = ClientBuilder.builder().build();
|
|
||||||
Path privateKeyPath = Paths.get(System.getProperty("user.home") + "/.ssh/id_ed25519");
|
|
||||||
PrivateKeyReader privateKeyReader = new PrivateKeyReader();
|
|
||||||
KeyPair keyPair = privateKeyReader.generateFrom(Files.newInputStream(privateKeyPath), null);
|
|
||||||
sshClient.addPublicKeyIdentity(keyPair);
|
|
||||||
sshClient.setNioWorkers(1);
|
|
||||||
sshClient.start();
|
|
||||||
SftpFileSystem fileSystem = new SftpFileSystemProvider(sshClient).newFileSystem(uri, env);
|
|
||||||
fileSystem.close();
|
|
||||||
// ...
|
|
||||||
sshClient.stop();
|
|
||||||
sshClient.close();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package org.apache.sshd.fs.test;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import org.apache.sshd.client.ClientBuilder;
|
||||||
|
import org.apache.sshd.client.SshClient;
|
||||||
|
import org.apache.sshd.fs.SftpFileSystem;
|
||||||
|
import org.apache.sshd.fs.SftpFileSystemProvider;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.xbib.net.security.PrivateKeyReader;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
public class SftpWithPrivateKeyReaderTest {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(SftpWithPrivateKeyReaderTest.class.getName());
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testXbib() throws Exception {
|
||||||
|
Map<String, String> env = new HashMap<>();
|
||||||
|
env.put("username", "joerg");
|
||||||
|
URI uri = URI.create("sftp://xbib.org");
|
||||||
|
Path privateKeyPath = Paths.get(System.getProperty("user.home") + "/.ssh/id_ed25519");
|
||||||
|
PrivateKeyReader privateKeyReader = new PrivateKeyReader();
|
||||||
|
try (InputStream inputStream = Files.newInputStream(privateKeyPath);
|
||||||
|
SshClient sshClient = ClientBuilder.builder().build()) {
|
||||||
|
KeyPair keyPair = privateKeyReader.readKeyPair(inputStream, null);
|
||||||
|
sshClient.addPublicKeyIdentity(keyPair);
|
||||||
|
sshClient.setNioWorkers(1);
|
||||||
|
sshClient.start();
|
||||||
|
SftpFileSystem fileSystem = new SftpFileSystemProvider(sshClient).newFileSystem(uri, env);
|
||||||
|
assertTrue(Files.exists(fileSystem.getDefaultDir()));
|
||||||
|
try (Stream<Path> stream = Files.list(fileSystem.getDefaultDir())) {
|
||||||
|
stream.forEach(p -> logger.log(Level.INFO, "p = " + p));
|
||||||
|
}
|
||||||
|
fileSystem.close();
|
||||||
|
sshClient.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDionysos() throws Exception {
|
||||||
|
Map<String, String> env = new HashMap<>();
|
||||||
|
env.put("username", "joerg");
|
||||||
|
URI uri = URI.create("sftp://dionysos");
|
||||||
|
Path privateKeyPath = Paths.get(System.getProperty("user.home") + "/.ssh/id_ed25519");
|
||||||
|
PrivateKeyReader privateKeyReader = new PrivateKeyReader();
|
||||||
|
try (InputStream inputStream = Files.newInputStream(privateKeyPath);
|
||||||
|
SshClient sshClient = ClientBuilder.builder().build()) {
|
||||||
|
KeyPair keyPair = privateKeyReader.readKeyPair(inputStream, null);
|
||||||
|
sshClient.addPublicKeyIdentity(keyPair);
|
||||||
|
sshClient.setNioWorkers(1);
|
||||||
|
sshClient.start();
|
||||||
|
SftpFileSystem fileSystem = new SftpFileSystemProvider(sshClient).newFileSystem(uri, env);
|
||||||
|
assertTrue(Files.exists(fileSystem.getDefaultDir()));
|
||||||
|
try (Stream<Path> stream = Files.list(fileSystem.getDefaultDir())) {
|
||||||
|
stream.forEach(p -> logger.log(Level.INFO, "p = " + p));
|
||||||
|
}
|
||||||
|
fileSystem.close();
|
||||||
|
sshClient.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -42,7 +42,6 @@ import org.apache.sshd.common.signature.SignatureFactory;
|
||||||
import org.apache.sshd.common.util.GenericUtils;
|
import org.apache.sshd.common.util.GenericUtils;
|
||||||
import org.apache.sshd.common.util.ValidateUtils;
|
import org.apache.sshd.common.util.ValidateUtils;
|
||||||
import org.apache.sshd.common.util.buffer.Buffer;
|
import org.apache.sshd.common.util.buffer.Buffer;
|
||||||
import org.apache.sshd.common.util.buffer.BufferUtils;
|
|
||||||
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
|
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,18 +94,13 @@ public class UserAuthPublicKey extends AbstractUserAuth implements SignatureFact
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
throw new RuntimeSshException(e);
|
throw new RuntimeSshException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
PublicKeyAuthenticationReporter reporter = session.getPublicKeyAuthenticationReporter();
|
PublicKeyAuthenticationReporter reporter = session.getPublicKeyAuthenticationReporter();
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
|
|
||||||
if (reporter != null) {
|
if (reporter != null) {
|
||||||
reporter.signalAuthenticationExhausted(session, service);
|
reporter.signalAuthenticationExhausted(session, service);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
KeyPair keyPair;
|
KeyPair keyPair;
|
||||||
try {
|
try {
|
||||||
keyPair = current.getKeyIdentity();
|
keyPair = current.getKeyIdentity();
|
||||||
|
|
|
@ -34,6 +34,7 @@ import java.security.interfaces.DSAPrivateKey;
|
||||||
import java.security.interfaces.DSAPublicKey;
|
import java.security.interfaces.DSAPublicKey;
|
||||||
import java.security.interfaces.ECPrivateKey;
|
import java.security.interfaces.ECPrivateKey;
|
||||||
import java.security.interfaces.ECPublicKey;
|
import java.security.interfaces.ECPublicKey;
|
||||||
|
import java.security.interfaces.EdECPublicKey;
|
||||||
import java.security.interfaces.RSAPrivateCrtKey;
|
import java.security.interfaces.RSAPrivateCrtKey;
|
||||||
import java.security.interfaces.RSAPublicKey;
|
import java.security.interfaces.RSAPublicKey;
|
||||||
import java.security.spec.DSAPrivateKeySpec;
|
import java.security.spec.DSAPrivateKeySpec;
|
||||||
|
@ -877,68 +878,60 @@ public abstract class Buffer implements Readable {
|
||||||
|
|
||||||
public void putRawPublicKeyBytes(PublicKey key) {
|
public void putRawPublicKeyBytes(PublicKey key) {
|
||||||
Objects.requireNonNull(key, "No key");
|
Objects.requireNonNull(key, "No key");
|
||||||
if (key instanceof RSAPublicKey) {
|
switch (key) {
|
||||||
RSAPublicKey rsaPub = (RSAPublicKey) key;
|
case RSAPublicKey rsaPub -> {
|
||||||
|
putMPInt(rsaPub.getPublicExponent());
|
||||||
putMPInt(rsaPub.getPublicExponent());
|
putMPInt(rsaPub.getModulus());
|
||||||
putMPInt(rsaPub.getModulus());
|
|
||||||
} else if (key instanceof DSAPublicKey) {
|
|
||||||
DSAPublicKey dsaPub = (DSAPublicKey) key;
|
|
||||||
DSAParams dsaParams = dsaPub.getParams();
|
|
||||||
|
|
||||||
putMPInt(dsaParams.getP());
|
|
||||||
putMPInt(dsaParams.getQ());
|
|
||||||
putMPInt(dsaParams.getG());
|
|
||||||
putMPInt(dsaPub.getY());
|
|
||||||
} else if (key instanceof ECPublicKey) {
|
|
||||||
ECPublicKey ecKey = (ECPublicKey) key;
|
|
||||||
ECParameterSpec ecParams = ecKey.getParams();
|
|
||||||
ECCurves curve = ECCurves.fromCurveParameters(ecParams);
|
|
||||||
if (curve == null) {
|
|
||||||
throw new BufferException("Unsupported EC curve parameters");
|
|
||||||
}
|
}
|
||||||
|
case DSAPublicKey dsaPub -> {
|
||||||
byte[] ecPoint = ECCurves.encodeECPoint(ecKey.getW(), ecParams);
|
DSAParams dsaParams = dsaPub.getParams();
|
||||||
putString(curve.getName());
|
putMPInt(dsaParams.getP());
|
||||||
putBytes(ecPoint);
|
putMPInt(dsaParams.getQ());
|
||||||
} else if (SecurityUtils.EDDSA.equals(key.getAlgorithm())) {
|
putMPInt(dsaParams.getG());
|
||||||
SecurityUtils.putRawEDDSAPublicKey(this, key);
|
putMPInt(dsaPub.getY());
|
||||||
} else if (key instanceof OpenSshCertificate) {
|
}
|
||||||
OpenSshCertificate cert = (OpenSshCertificate) key;
|
case ECPublicKey ecKey -> {
|
||||||
|
ECParameterSpec ecParams = ecKey.getParams();
|
||||||
putBytes(cert.getNonce());
|
ECCurves curve = ECCurves.fromCurveParameters(ecParams);
|
||||||
putRawPublicKeyBytes(cert.getServerHostKey());
|
if (curve == null) {
|
||||||
putLong(cert.getSerial());
|
throw new BufferException("Unsupported EC curve parameters");
|
||||||
putInt(cert.getType());
|
}
|
||||||
putString(cert.getId());
|
byte[] ecPoint = ECCurves.encodeECPoint(ecKey.getW(), ecParams);
|
||||||
|
putString(curve.getName());
|
||||||
ByteArrayBuffer tmpBuffer = new ByteArrayBuffer();
|
putBytes(ecPoint);
|
||||||
tmpBuffer.putStringList(cert.getPrincipals(), false);
|
}
|
||||||
putBytes(tmpBuffer.getCompactData());
|
case EdECPublicKey edECPublicKey -> {
|
||||||
|
byte[] b = edECPublicKey.getEncoded();
|
||||||
putLong(cert.getValidAfter());
|
putBytes(b);
|
||||||
putLong(cert.getValidBefore());
|
}
|
||||||
putNameList(cert.getCriticalOptions());
|
case OpenSshCertificate cert -> {
|
||||||
putNameList(cert.getExtensions());
|
putBytes(cert.getNonce());
|
||||||
putString(cert.getReserved());
|
putRawPublicKeyBytes(cert.getServerHostKey());
|
||||||
|
putLong(cert.getSerial());
|
||||||
tmpBuffer = new ByteArrayBuffer(); // TODO tmpBuffer.clear() instead of allocate new buffer
|
putInt(cert.getType());
|
||||||
tmpBuffer.putRawPublicKey(cert.getCaPubKey());
|
putString(cert.getId());
|
||||||
putBytes(tmpBuffer.getCompactData());
|
ByteArrayBuffer tmpBuffer = new ByteArrayBuffer();
|
||||||
|
tmpBuffer.putStringList(cert.getPrincipals(), false);
|
||||||
putBytes(cert.getSignature());
|
putBytes(tmpBuffer.getCompactData());
|
||||||
} else {
|
putLong(cert.getValidAfter());
|
||||||
throw new BufferException("Unsupported raw public key algorithm: " + key.getAlgorithm());
|
putLong(cert.getValidBefore());
|
||||||
|
putNameList(cert.getCriticalOptions());
|
||||||
|
putNameList(cert.getExtensions());
|
||||||
|
putString(cert.getReserved());
|
||||||
|
tmpBuffer = new ByteArrayBuffer(); // TODO tmpBuffer.clear() instead of allocate new buffer
|
||||||
|
tmpBuffer.putRawPublicKey(cert.getCaPubKey());
|
||||||
|
putBytes(tmpBuffer.getCompactData());
|
||||||
|
putBytes(cert.getSignature());
|
||||||
|
}
|
||||||
|
default -> throw new BufferException("Unsupported raw public key algorithm: " + key.getAlgorithm());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putKeyPair(KeyPair kp) {
|
public void putKeyPair(KeyPair kp) {
|
||||||
PublicKey pubKey = kp.getPublic();
|
PublicKey pubKey = kp.getPublic();
|
||||||
PrivateKey prvKey = kp.getPrivate();
|
PrivateKey prvKey = kp.getPrivate();
|
||||||
if (prvKey instanceof RSAPrivateCrtKey) {
|
if (prvKey instanceof RSAPrivateCrtKey rsaPrv) {
|
||||||
RSAPublicKey rsaPub = (RSAPublicKey) pubKey;
|
RSAPublicKey rsaPub = (RSAPublicKey) pubKey;
|
||||||
RSAPrivateCrtKey rsaPrv = (RSAPrivateCrtKey) prvKey;
|
|
||||||
|
|
||||||
putString(KeyPairProvider.SSH_RSA);
|
putString(KeyPairProvider.SSH_RSA);
|
||||||
putMPInt(rsaPub.getPublicExponent());
|
putMPInt(rsaPub.getPublicExponent());
|
||||||
putMPInt(rsaPub.getModulus());
|
putMPInt(rsaPub.getModulus());
|
||||||
|
@ -946,26 +939,22 @@ public abstract class Buffer implements Readable {
|
||||||
putMPInt(rsaPrv.getCrtCoefficient());
|
putMPInt(rsaPrv.getCrtCoefficient());
|
||||||
putMPInt(rsaPrv.getPrimeQ());
|
putMPInt(rsaPrv.getPrimeQ());
|
||||||
putMPInt(rsaPrv.getPrimeP());
|
putMPInt(rsaPrv.getPrimeP());
|
||||||
} else if (pubKey instanceof DSAPublicKey) {
|
} else if (pubKey instanceof DSAPublicKey dsaPub) {
|
||||||
DSAPublicKey dsaPub = (DSAPublicKey) pubKey;
|
|
||||||
DSAParams dsaParams = dsaPub.getParams();
|
DSAParams dsaParams = dsaPub.getParams();
|
||||||
DSAPrivateKey dsaPrv = (DSAPrivateKey) prvKey;
|
DSAPrivateKey dsaPrv = (DSAPrivateKey) prvKey;
|
||||||
|
|
||||||
putString(KeyPairProvider.SSH_DSS);
|
putString(KeyPairProvider.SSH_DSS);
|
||||||
putMPInt(dsaParams.getP());
|
putMPInt(dsaParams.getP());
|
||||||
putMPInt(dsaParams.getQ());
|
putMPInt(dsaParams.getQ());
|
||||||
putMPInt(dsaParams.getG());
|
putMPInt(dsaParams.getG());
|
||||||
putMPInt(dsaPub.getY());
|
putMPInt(dsaPub.getY());
|
||||||
putMPInt(dsaPrv.getX());
|
putMPInt(dsaPrv.getX());
|
||||||
} else if (pubKey instanceof ECPublicKey) {
|
} else if (pubKey instanceof ECPublicKey ecPub) {
|
||||||
ECPublicKey ecPub = (ECPublicKey) pubKey;
|
|
||||||
ECPrivateKey ecPriv = (ECPrivateKey) prvKey;
|
ECPrivateKey ecPriv = (ECPrivateKey) prvKey;
|
||||||
ECParameterSpec ecParams = ecPub.getParams();
|
ECParameterSpec ecParams = ecPub.getParams();
|
||||||
ECCurves curve = ECCurves.fromCurveParameters(ecParams);
|
ECCurves curve = ECCurves.fromCurveParameters(ecParams);
|
||||||
if (curve == null) {
|
if (curve == null) {
|
||||||
throw new BufferException("Unsupported EC curve parameters");
|
throw new BufferException("Unsupported EC curve parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] ecPoint = ECCurves.encodeECPoint(ecPub.getW(), ecParams);
|
byte[] ecPoint = ECCurves.encodeECPoint(ecPub.getW(), ecParams);
|
||||||
putString(curve.getKeyType());
|
putString(curve.getKeyType());
|
||||||
putString(curve.getName());
|
putString(curve.getName());
|
||||||
|
|
|
@ -123,8 +123,10 @@ public final class SecurityUtils {
|
||||||
* Comma separated list of fully qualified {@link SecurityProviderRegistrar}s to automatically register
|
* Comma separated list of fully qualified {@link SecurityProviderRegistrar}s to automatically register
|
||||||
*/
|
*/
|
||||||
public static final String SECURITY_PROVIDER_REGISTRARS = "org.apache.sshd.security.registrars";
|
public static final String SECURITY_PROVIDER_REGISTRARS = "org.apache.sshd.security.registrars";
|
||||||
public static final List<String> DEFAULT_SECURITY_PROVIDER_REGISTRARS = Collections.unmodifiableList(
|
|
||||||
Arrays.asList("org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderRegistrar"));
|
public static final List<String> DEFAULT_SECURITY_PROVIDER_REGISTRARS =
|
||||||
|
List.of("org.apache.sshd.common.util.security.edec.EdECSecurityProviderRegistrar");
|
||||||
|
//Collections.unmodifiableList(Arrays.asList("org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderRegistrar"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* System property used to control whether Elliptic Curves are supported or not. If not set then the support is
|
* System property used to control whether Elliptic Curves are supported or not. If not set then the support is
|
||||||
|
|
|
@ -16,7 +16,7 @@ dependencyResolutionManagement {
|
||||||
versionCatalogs {
|
versionCatalogs {
|
||||||
libs {
|
libs {
|
||||||
version('gradle', '8.7')
|
version('gradle', '8.7')
|
||||||
version('net', '4.4.0')
|
version('net', '4.6.0')
|
||||||
library('net-security', 'org.xbib', 'net-security').versionRef('net')
|
library('net-security', 'org.xbib', 'net-security').versionRef('net')
|
||||||
library('maverick-synergy-client', 'com.sshtools', 'maverick-synergy-client').version('3.1.1')
|
library('maverick-synergy-client', 'com.sshtools', 'maverick-synergy-client').version('3.1.1')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue