mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-08 16:18:05 +03:00
Fix race condition causing SSH_MSG_UNIMPLEMENTED occasionally during key exchange (#851)
* Fix race condition causing SSH_MSG_UNIMPLEMENTED occasionally during key exchange * unit tests * fix unit tests --------- Co-authored-by: Jeroen van Erp <jeroen@hierynomus.com>
This commit is contained in:
@@ -810,12 +810,7 @@ public class SSHClient
|
||||
ThreadNameProvider.setThreadName(conn.getKeepAlive(), trans);
|
||||
keepAliveThread.start();
|
||||
}
|
||||
if (trans.isKeyExchangeRequired()) {
|
||||
log.debug("Initiating Key Exchange for new connection");
|
||||
doKex();
|
||||
} else {
|
||||
log.debug("Key Exchange already completed for new connection");
|
||||
}
|
||||
doKex();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -136,13 +136,25 @@ final class KeyExchanger
|
||||
void startKex(boolean waitForDone)
|
||||
throws TransportException {
|
||||
if (!kexOngoing.getAndSet(true)) {
|
||||
done.clear();
|
||||
sendKexInit();
|
||||
if (isKeyExchangeAllowed()) {
|
||||
log.debug("Initiating key exchange");
|
||||
done.clear();
|
||||
sendKexInit();
|
||||
} else {
|
||||
kexOngoing.set(false);
|
||||
}
|
||||
}
|
||||
if (waitForDone)
|
||||
waitForDone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Key exchange can be initiated exactly once while connecting or later after authentication when re-keying.
|
||||
*/
|
||||
private boolean isKeyExchangeAllowed() {
|
||||
return !isKexDone() || transport.isAuthenticated();
|
||||
}
|
||||
|
||||
void waitForDone()
|
||||
throws TransportException {
|
||||
done.await(transport.getTimeoutMs(), TimeUnit.MILLISECONDS);
|
||||
|
||||
@@ -71,13 +71,6 @@ public interface Transport
|
||||
void doKex()
|
||||
throws TransportException;
|
||||
|
||||
/**
|
||||
* Is Key Exchange required based on current transport status
|
||||
*
|
||||
* @return Key Exchange required status
|
||||
*/
|
||||
boolean isKeyExchangeRequired();
|
||||
|
||||
/** @return the version string used by this client to identify itself to an SSH server, e.g. "SSHJ_3_0" */
|
||||
String getClientVersion();
|
||||
|
||||
|
||||
@@ -254,16 +254,6 @@ public final class TransportImpl
|
||||
kexer.startKex(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Key Exchange required returns true when Key Exchange is not done and when Key Exchange is not ongoing
|
||||
*
|
||||
* @return Key Exchange required status
|
||||
*/
|
||||
@Override
|
||||
public boolean isKeyExchangeRequired() {
|
||||
return !kexer.isKexDone() && !kexer.isKexOngoing();
|
||||
}
|
||||
|
||||
public boolean isKexDone() {
|
||||
return kexer.isKexDone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user