mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 23:30:55 +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
|
* @param keepAliveProvider keep-alive provider
|
||||||
*/
|
*/
|
||||||
void setKeepAliveProvider(KeepAliveProvider keepAliveProvider);
|
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<Signature>> signatureFactories;
|
||||||
private List<Factory.Named<FileKeyProvider>> fileKeyProviderFactories;
|
private List<Factory.Named<FileKeyProvider>> fileKeyProviderFactories;
|
||||||
|
|
||||||
|
private boolean waitForServerIdentBeforeSendingClientIdent = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Factory.Named<Cipher>> getCipherFactories() {
|
public List<Factory.Named<Cipher>> getCipherFactories() {
|
||||||
return cipherFactories;
|
return cipherFactories;
|
||||||
@@ -157,4 +159,14 @@ public class ConfigImpl
|
|||||||
public void setKeepAliveProvider(KeepAliveProvider keepAliveProvider) {
|
public void setKeepAliveProvider(KeepAliveProvider keepAliveProvider) {
|
||||||
this.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 {
|
try {
|
||||||
|
|
||||||
log.info("Client identity string: {}", clientID);
|
if (config.isWaitForServerIdentBeforeSendingClientIdent()) {
|
||||||
connInfo.out.write((clientID + "\r\n").getBytes(IOUtils.UTF8));
|
receiveServerIdent();
|
||||||
connInfo.out.flush();
|
sendClientIdent();
|
||||||
|
} else {
|
||||||
// Read server's ID
|
sendClientIdent();
|
||||||
final Buffer.PlainBuffer buf = new Buffer.PlainBuffer();
|
receiveServerIdent();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
log.info("Server identity string: {}", serverID);
|
log.info("Server identity string: {}", serverID);
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -174,6 +170,26 @@ public final class TransportImpl
|
|||||||
reader.start();
|
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
|
* 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".
|
* by the server. It takes the form of, e.g. "SSH-2.0-OpenSSH_ver".
|
||||||
|
|||||||
Reference in New Issue
Block a user