mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-08 16:18:05 +03:00
Try all public key algorithms available for a specific key type in SSH_MSG_USERAUTH_REQUEST. (#763)
This commit is contained in:
@@ -28,6 +28,7 @@ import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
|||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/** Transport layer of the SSH protocol. */
|
/** Transport layer of the SSH protocol. */
|
||||||
@@ -224,5 +225,5 @@ public interface Transport
|
|||||||
void die(Exception e);
|
void die(Exception e);
|
||||||
|
|
||||||
KeyAlgorithm getHostKeyAlgorithm();
|
KeyAlgorithm getHostKeyAlgorithm();
|
||||||
KeyAlgorithm getClientKeyAlgorithm(KeyType keyType) throws TransportException;
|
List<KeyAlgorithm> getClientKeyAlgorithms(KeyType keyType) throws TransportException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
@@ -637,15 +638,18 @@ public final class TransportImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyAlgorithm getClientKeyAlgorithm(KeyType keyType) throws TransportException {
|
public List<KeyAlgorithm> getClientKeyAlgorithms(KeyType keyType) throws TransportException {
|
||||||
List<Factory.Named<KeyAlgorithm>> factories = getConfig().getKeyAlgorithms();
|
List<Factory.Named<KeyAlgorithm>> factories = getConfig().getKeyAlgorithms();
|
||||||
|
List<KeyAlgorithm> available = new ArrayList<>();
|
||||||
if (factories != null)
|
if (factories != null)
|
||||||
for (Factory.Named<KeyAlgorithm> f : factories)
|
for (Factory.Named<KeyAlgorithm> f : factories)
|
||||||
if (
|
if (
|
||||||
f instanceof KeyAlgorithms.Factory && ((KeyAlgorithms.Factory) f).getKeyType().equals(keyType)
|
f instanceof KeyAlgorithms.Factory && ((KeyAlgorithms.Factory) f).getKeyType().equals(keyType)
|
||||||
|| !(f instanceof KeyAlgorithms.Factory) && f.getName().equals(keyType.toString())
|
|| !(f instanceof KeyAlgorithms.Factory) && f.getName().equals(keyType.toString())
|
||||||
)
|
)
|
||||||
return f.create();
|
available.add(f.create());
|
||||||
throw new TransportException("Cannot find an available KeyAlgorithm for type " + keyType);
|
if (available.isEmpty())
|
||||||
|
throw new TransportException("Cannot find an available KeyAlgorithm for type " + keyType);
|
||||||
|
return available;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,17 +27,36 @@ import net.schmizz.sshj.userauth.keyprovider.KeyProvider;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
public abstract class KeyedAuthMethod
|
public abstract class KeyedAuthMethod
|
||||||
extends AbstractAuthMethod {
|
extends AbstractAuthMethod {
|
||||||
|
|
||||||
protected final KeyProvider kProv;
|
protected final KeyProvider kProv;
|
||||||
|
private Queue<KeyAlgorithm> available;
|
||||||
|
|
||||||
public KeyedAuthMethod(String name, KeyProvider kProv) {
|
public KeyedAuthMethod(String name, KeyProvider kProv) {
|
||||||
super(name);
|
super(name);
|
||||||
this.kProv = kProv;
|
this.kProv = kProv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private KeyAlgorithm getPublicKeyAlgorithm(KeyType keyType) throws TransportException {
|
||||||
|
if (available == null) {
|
||||||
|
available = new LinkedList<>(params.getTransport().getClientKeyAlgorithms(keyType));
|
||||||
|
}
|
||||||
|
return available.peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldRetry() {
|
||||||
|
if (available != null) {
|
||||||
|
available.poll();
|
||||||
|
return !available.isEmpty();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected SSHPacket putPubKey(SSHPacket reqBuf)
|
protected SSHPacket putPubKey(SSHPacket reqBuf)
|
||||||
throws UserAuthException {
|
throws UserAuthException {
|
||||||
PublicKey key;
|
PublicKey key;
|
||||||
@@ -50,7 +69,7 @@ public abstract class KeyedAuthMethod
|
|||||||
// public key as 2 strings: [ key type | key blob ]
|
// public key as 2 strings: [ key type | key blob ]
|
||||||
KeyType keyType = KeyType.fromKey(key);
|
KeyType keyType = KeyType.fromKey(key);
|
||||||
try {
|
try {
|
||||||
KeyAlgorithm ka = params.getTransport().getClientKeyAlgorithm(keyType);
|
KeyAlgorithm ka = getPublicKeyAlgorithm(keyType);
|
||||||
if (ka != null) {
|
if (ka != null) {
|
||||||
reqBuf.putString(ka.getKeyAlgorithm())
|
reqBuf.putString(ka.getKeyAlgorithm())
|
||||||
.putString(new Buffer.PlainBuffer().putPublicKey(key).getCompactData());
|
.putString(new Buffer.PlainBuffer().putPublicKey(key).getCompactData());
|
||||||
@@ -74,7 +93,7 @@ public abstract class KeyedAuthMethod
|
|||||||
final KeyType kt = KeyType.fromKey(key);
|
final KeyType kt = KeyType.fromKey(key);
|
||||||
Signature signature;
|
Signature signature;
|
||||||
try {
|
try {
|
||||||
signature = params.getTransport().getClientKeyAlgorithm(kt).newSignature();
|
signature = getPublicKeyAlgorithm(kt).newSignature();
|
||||||
} catch (TransportException e) {
|
} catch (TransportException e) {
|
||||||
throw new UserAuthException("No KeyAlgorithm configured for key " + kt);
|
throw new UserAuthException("No KeyAlgorithm configured for key " + kt);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user