Skip to content

Commit

Permalink
Implemented switch for waiting on server ident before sending client …
Browse files Browse the repository at this point in the history
…ident. (Fixes #118)
  • Loading branch information
hierynomus committed Mar 18, 2016
1 parent 3c230a0 commit 5040348
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 12 deletions.
20 changes: 20 additions & 0 deletions src/main/java/net/schmizz/sshj/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
14 changes: 13 additions & 1 deletion src/main/java/net/schmizz/sshj/ConfigImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -157,4 +159,14 @@ public KeepAliveProvider getKeepAliveProvider() {
public void setKeepAliveProvider(KeepAliveProvider keepAliveProvider) {
this.keepAliveProvider = keepAliveProvider;
}
}

@Override
public boolean isWaitForServerIdentBeforeSendingClientIdent() {
return waitForServerIdentBeforeSendingClientIdent;
}

@Override
public void setWaitForServerIdentBeforeSendingClientIdent(boolean waitForServerIdentBeforeSendingClientIdent) {
this.waitForServerIdentBeforeSendingClientIdent = waitForServerIdentBeforeSendingClientIdent;
}
}
38 changes: 27 additions & 11 deletions src/main/java/net/schmizz/sshj/transport/TransportImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,19 +152,15 @@ public void init(String remoteHost, int remotePort, InputStream in, OutputStream

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) {
Expand All @@ -174,6 +170,26 @@ public void init(String remoteHost, int remotePort, InputStream in, OutputStream
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".
Expand Down

0 comments on commit 5040348

Please sign in to comment.