mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 15:20:54 +03:00
Implemented switch for waiting on server ident before sending client ident. (Fixes #118)
This commit is contained in:
@@ -155,4 +155,24 @@ public interface Config {
|
||||
* @param keepAliveProvider keep-alive provider
|
||||
*/
|
||||
void setKeepAliveProvider(KeepAliveProvider keepAliveProvider);
|
||||
|
||||
/**
|
||||
* Gets whether the client should first wait for a received server ident, before sending the client ident.
|
||||
* <p/>
|
||||
* <stong>NB:</stong> This is non-standard behaviour, and can potentially deadlock if the server also waits on the client ident.
|
||||
*
|
||||
* The default value is set to false.
|
||||
*
|
||||
* @return Whether to first wait for the server ident.
|
||||
*/
|
||||
boolean isWaitForServerIdentBeforeSendingClientIdent();
|
||||
|
||||
/**
|
||||
* Sets whether the SSH client should wait for a received server ident, before sending the client ident.
|
||||
* <p/>
|
||||
* <stong>NB:</stong> This is non-standard behaviour, and can potentially deadlock if the server also waits on the client ident.
|
||||
|
||||
* @param waitForServerIdentBeforeSendingClientIdent Whether to wait for the server ident.
|
||||
*/
|
||||
void setWaitForServerIdentBeforeSendingClientIdent(boolean waitForServerIdentBeforeSendingClientIdent);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ public class ConfigImpl
|
||||
private List<Factory.Named<Signature>> signatureFactories;
|
||||
private List<Factory.Named<FileKeyProvider>> fileKeyProviderFactories;
|
||||
|
||||
private boolean waitForServerIdentBeforeSendingClientIdent = false;
|
||||
|
||||
@Override
|
||||
public List<Factory.Named<Cipher>> getCipherFactories() {
|
||||
return cipherFactories;
|
||||
@@ -157,4 +159,14 @@ public class ConfigImpl
|
||||
public void setKeepAliveProvider(KeepAliveProvider keepAliveProvider) {
|
||||
this.keepAliveProvider = keepAliveProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWaitForServerIdentBeforeSendingClientIdent() {
|
||||
return waitForServerIdentBeforeSendingClientIdent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWaitForServerIdentBeforeSendingClientIdent(boolean waitForServerIdentBeforeSendingClientIdent) {
|
||||
this.waitForServerIdentBeforeSendingClientIdent = waitForServerIdentBeforeSendingClientIdent;
|
||||
}
|
||||
}
|
||||
@@ -152,19 +152,15 @@ public final class TransportImpl
|
||||
|
||||
try {
|
||||
|
||||
log.info("Client identity string: {}", clientID);
|
||||
connInfo.out.write((clientID + "\r\n").getBytes(IOUtils.UTF8));
|
||||
connInfo.out.flush();
|
||||
|
||||
// Read server's ID
|
||||
final Buffer.PlainBuffer buf = new Buffer.PlainBuffer();
|
||||
while ((serverID = readIdentification(buf)).isEmpty()) {
|
||||
int b = connInfo.in.read();
|
||||
if (b == -1)
|
||||
throw new TransportException("Server closed connection during identification exchange");
|
||||
buf.putByte((byte) b);
|
||||
if (config.isWaitForServerIdentBeforeSendingClientIdent()) {
|
||||
receiveServerIdent();
|
||||
sendClientIdent();
|
||||
} else {
|
||||
sendClientIdent();
|
||||
receiveServerIdent();
|
||||
}
|
||||
|
||||
|
||||
log.info("Server identity string: {}", serverID);
|
||||
|
||||
} catch (IOException e) {
|
||||
@@ -174,6 +170,26 @@ public final class TransportImpl
|
||||
reader.start();
|
||||
}
|
||||
|
||||
private void receiveServerIdent() throws IOException {
|
||||
final Buffer.PlainBuffer buf = new Buffer.PlainBuffer();
|
||||
while ((serverID = readIdentification(buf)).isEmpty()) {
|
||||
int b = connInfo.in.read();
|
||||
if (b == -1)
|
||||
throw new TransportException("Server closed connection during identification exchange");
|
||||
buf.putByte((byte) b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive the server identification string.
|
||||
* @throws IOException If there was an error writing to the outputstream.
|
||||
*/
|
||||
private void sendClientIdent() throws IOException {
|
||||
log.info("Client identity string: {}", clientID);
|
||||
connInfo.out.write((clientID + "\r\n").getBytes(IOUtils.UTF8));
|
||||
connInfo.out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the identification string from the SSH server. This is the very first string that is sent upon connection
|
||||
* by the server. It takes the form of, e.g. "SSH-2.0-OpenSSH_ver".
|
||||
|
||||
Reference in New Issue
Block a user