Incorrect identification: line too long
samir0282 opened this issue · 9 comments
Hi,
I am getting following exception while trying to open ssh connection.
Caused by: net.schmizz.sshj.transport.TransportException: Incorrect identification: line too long
at net.schmizz.sshj.transport.TransportImpl.init(TransportImpl.java:164)
at net.schmizz.sshj.SSHClient.onConnect(SSHClient.java:671)
at net.schmizz.sshj.SocketClient.connect(SocketClient.java:71)
at net.schmizz.sshj.SocketClient.connect(SocketClient.java:77)
at net.schmizz.sshj.SocketClient.connect(SocketClient.java:103)
at com.omneon.dam.util.bitspeed.BitSpeedUtil.openConnection(BitSpeedUtil.java:370)
at com.omneon.dam.util.bitspeed.BitSpeedUtil.exists(BitSpeedUtil.java:303)
... 19 more
The application has multiple threads. And each thread is opening its connection separately.
SSH version: OpenSSH_4.5p1, OpenSSL 0.9.8b 04 May 2006
In net.schmizz.sshj.transport.TransportImpl::readIdentification() getting buffer size more than 256 bytes.
I'm not sure if this is your issue, but last time I encountered this was because I was opening too many connections. Many Linux systems have a limit in place for how many unauthenticated SSH sessions can be open. For Debian, this is 10. If I hit a system with more than 10 connections at once, some of them would get a message that they should try again later, causing the exception above. In my case, I got around this by adding some retry logic. You could just as easily adjust the host's SSH settings.
I think it is bug in sshj STATE machine
client should wait for serverID before sending clientID
@Override
public void init(String remoteHost, int remotePort, InputStream in, OutputStream out)
throws TransportException {
connInfo = new ConnInfo(remoteHost, remotePort, in, out);
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()) {
buf.putByte((byte) connInfo.in.read());
}
log.info("Server identity string: {}", serverID);
} catch (IOException e) {
throw new TransportException(e);
}
reader.start();
}
@bk1te No, the both the client and server MUST send the identification according to the RFC. That means that neither should necessarily wait for the other.
Also the length of the buffer is enough according to the specification (i.e. RFC 4253 section 4.2), where it specifies the max length of the identification string is 255 characters including the line terminators.
Some server implementations send crypto info after they receive client id string and in some cases server receives client id before client receives servers one. So when client start reading data it already has server id and crypto info and boom there is an error
I would consider that an error on the server side, as it then clearly does
not adhere to the protocol. Which ssh servers are we taking about? Do you
have any examples?
On Jan 9, 2015 6:11 PM, "bk1te" notifications@github.com wrote:
Some server implementations send crypto info after they receive client id
string and in some cases server receives client id before client receives
servers one. So when client start reading data it already has server id and
crypto info and boom there is an error—
Reply to this email directly or view it on GitHub
#118 (comment).
It is not an error it is just network lag. We could avoid this issue just sending client identification string after we receive server one. It is not big deal but will help other users/.
btw locally i fix this issue that way and doesn`t have this error anymore..
It would be good to make a switch for this behaviour I think, instead of always waiting for the server ident string before sending our own. If we would encounter a server which also waits for the client ident string then we'd be screwed. A switch would be better in this case.
Thanks @bluekeyes For the PR to at least better identify that this happens.