Stephen Hurd
2018-03-13 01:51:39 UTC
So the first issue is that a read timeout of zero doesn't work... it
appears to be due to select() never being called in ioWait() when
timeout==0... the following patch solves that issue:
--- io/tcp.c.orig      2018-03-12 13:47:37.385998000 -0400
+++ io/tcp.c   2018-03-12 13:48:12.696032000 -0400
@@ -402,7 +402,7 @@
               return( status );
       LOOP_MED( ( selectIterations = 0, status = SOCKET_ERROR ), \
                         isSocketError( status ) && \
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â !checkMonoTimerExpired( &timerInfo ) && \
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (selectIterations == 0 ||
!checkMonoTimerExpired( &timerInfo )) && \
                               selectIterations < 20,
                         selectIterations++ )
               {
Next up is the Go SSH client here:
https://github.com/evanphx/ssh/blob/master/client.go which has a client
identifier of "SSH-2.0-Go", which is too short to be allowed... it says
it's a "Fork of go's ssh lib" which I couldn't find with a quick search,
but I have had clients using it try to connect.
--- session/ssh.c.orig   2018-03-12 21:28:40.049142000 -0400
+++ session/ssh.c   2018-03-12 21:28:57.425639000 -0400
@@ -306,8 +306,8 @@
    /* Make sure that we got enough data to work with. We need at least
      "SSH-" (ID, size SSH_ID_SIZE) + "x.y-" (protocol version) +
"xxxxx"
-Â Â Â Â Â (software version/ID, of which the shortest-known is "ConfD") */
-Â Â Â if( length < SSH_ID_SIZE + 9 || length > SSH_ID_MAX_SIZE )
+Â Â Â Â Â (software version/ID, of which the shortest-known is "Go") */
+Â Â Â if( length < SSH_ID_SIZE + 6 || length > SSH_ID_MAX_SIZE )
       {
       retExt( CRYPT_ERROR_BADDATA,
             ( CRYPT_ERROR_BADDATA, SESSION_ERRINFO,
The final issue I'm having that I don't have a fix for is that the first
time I use cryptPopData() on a new SSH session after pushing some data,
it uses the write timeout rather than the read timeout. I've worked
around it by select()ing for write before calling cryptFlushData(), and
setting the write timeout to zero, but I'm not really crazy about that
as a long-term solution.
appears to be due to select() never being called in ioWait() when
timeout==0... the following patch solves that issue:
--- io/tcp.c.orig      2018-03-12 13:47:37.385998000 -0400
+++ io/tcp.c   2018-03-12 13:48:12.696032000 -0400
@@ -402,7 +402,7 @@
               return( status );
       LOOP_MED( ( selectIterations = 0, status = SOCKET_ERROR ), \
                         isSocketError( status ) && \
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â !checkMonoTimerExpired( &timerInfo ) && \
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (selectIterations == 0 ||
!checkMonoTimerExpired( &timerInfo )) && \
                               selectIterations < 20,
                         selectIterations++ )
               {
Next up is the Go SSH client here:
https://github.com/evanphx/ssh/blob/master/client.go which has a client
identifier of "SSH-2.0-Go", which is too short to be allowed... it says
it's a "Fork of go's ssh lib" which I couldn't find with a quick search,
but I have had clients using it try to connect.
--- session/ssh.c.orig   2018-03-12 21:28:40.049142000 -0400
+++ session/ssh.c   2018-03-12 21:28:57.425639000 -0400
@@ -306,8 +306,8 @@
    /* Make sure that we got enough data to work with. We need at least
      "SSH-" (ID, size SSH_ID_SIZE) + "x.y-" (protocol version) +
"xxxxx"
-Â Â Â Â Â (software version/ID, of which the shortest-known is "ConfD") */
-Â Â Â if( length < SSH_ID_SIZE + 9 || length > SSH_ID_MAX_SIZE )
+Â Â Â Â Â (software version/ID, of which the shortest-known is "Go") */
+Â Â Â if( length < SSH_ID_SIZE + 6 || length > SSH_ID_MAX_SIZE )
       {
       retExt( CRYPT_ERROR_BADDATA,
             ( CRYPT_ERROR_BADDATA, SESSION_ERRINFO,
The final issue I'm having that I don't have a fix for is that the first
time I use cryptPopData() on a new SSH session after pushing some data,
it uses the write timeout rather than the read timeout. I've worked
around it by select()ing for write before calling cryptFlushData(), and
setting the write timeout to zero, but I'm not really crazy about that
as a long-term solution.