Re: dbclient can't connect to cisco

2018-11-16 Thread Nik Soggia

Il 16/11/18 15:25, Matt Johnston ha scritto:


The problem is that waiting for the remote banner is still adding a round trip of 
delay. That's fine for a local network, but me -> dropbear.nl is half a second, 
that's no good.


As long as we let the Cisco speak first, it is happy.
So why don't we read a env var to optionally wait for incoming data before we 
send our first packet?
All remains the same, we just swap who speaks first: it should not add any 
relevant delay.
Cheers,

TRACE  (6250) 0.000821: -> KEXINIT
TRACE2 (6250) 0.000824: update_timeout limit 0, now 19720, last 19720, timeout 
28800
TRACE  (6250) 0.000833: enter set_connect_fds
TRACE  (6250) 0.000843: setnonblocking: 8
TRACE  (6250) 0.000848: leave setnonblocking
TRACE  (6250) 0.002446: maybe_empty_reply_queue - no data allowed
TRACE  (6250) 0.002484: enter handle_connect_fds
TRACE  (6250) 0.002500: handling 10.36.10.1 port 22 socket 8
TRACE  (6250) 0.002525: update_channel_prio
TRACE  (6250) 0.002543: update_channel_prio: not any
TRACE  (6250) 0.002560: Dropbear priority transitioning 10 -> 11
TRACE  (6250) 0.002612: Couldn't set IPV6_TCLASS (Protocol not available)
TRACE  (6250) 0.002620: leave handle_connect_fds - success
TRACE2 (6250) 0.002624: enter cli_sessionloop

(the patch is here)
TRACE2 (6250) 0.002629: enter wait server
TRACE2 (6250) 0.004485: leave wait server: ok

TRACE2 (6250) 0.004521: exit cli_sessionloop: no real packets yet
TRACE2 (6250) 0.004545: enter write_packet
TRACE2 (6250) 0.004571: write_packet writev #0  type 0 len 26/26
TRACE2 (6250) 0.004591: write_packet writev #1  type 20 len 608/608
TRACE2 (6250) 0.004620: write_packet writev #2  type 30 len 48/48
TRACE  (6250) 0.004688: empty queue dequeing
TRACE2 (6250) 0.004693: leave write_packet
TRACE2 (6250) 0.004700: update_timeout limit 0, now 19720, last 19720, timeout 
28800
TRACE  (6250) 0.004707: enter set_connect_fds
TRACE  (6250) 0.004716: enter ident_readln
TRACE  (6250) 0.004738: leave ident_readln: return 19
TRACE  (6250) 0.004743: remoteident: SSH-2.0-Cisco-1.25
TRACE  (6250) 0.004749: maybe_empty_reply_queue - no data allowed
TRACE  (6250) 0.004754: enter handle_connect_fds
TRACE  (6250) 0.004761: leave handle_connect_fds - end iter
TRACE2 (6250) 0.004765: enter cli_sessionloop
TRACE2 (6250) 0.004770: exit cli_sessionloop: no real packets yet
TRACE2 (6250) 0.004777: update_timeout limit 0, now 19720, last 19720, timeout 
28800
TRACE  (6250) 0.004785: enter set_connect_fds
TRACE2 (6250) 0.006470: enter read_packet
TRACE2 (6250) 0.006512: packet size is 312, block 8 mac 0
TRACE2 (6250) 0.006541: enter decrypt_packet
TRACE2 (6250) 0.006557: leave writemac
TRACE2 (6250) 0.006577: leave decrypt_packet
TRACE2 (6250) 0.006598: leave read_packet
TRACE2 (6250) 0.006617: enter process_packet
TRACE  (6250) 0.006638: process_packet: packet type = 20,  len 308
TRACE  (6250) 0.006661: got expected packet 20 during kexinit
TRACE  (6250) 0.006703: <- KEXINIT


diff -Naubr dropbear-2018.76.old/cli-session.c 
dropbear-2018.76.new/cli-session.c
--- dropbear-2018.76.old/cli-session.c  2018-02-27 15:25:10.0 +0100
+++ dropbear-2018.76.new/cli-session.c  2018-11-16 19:35:07.781047284 +0100
@@ -140,6 +140,7 @@
 #endif
 
 static void cli_session_init(pid_t proxy_cmd_pid) {

+   char *wait;
 
 	cli_ses.state = STATE_NOTHING;

cli_ses.kex_state = KEX_NOTHING;
@@ -174,6 +175,11 @@
ses.packettypes = cli_packettypes;
 
 	ses.isserver = 0;

+   if ((wait = getenv("DROPBEAR_WAIT_SERVER"))) {
+   ses.waitserver = strtol(wait, NULL, 10);
+   } else {
+   ses.waitserver = 0;
+   }
 
 #if DROPBEAR_KEX_FIRST_FOLLOWS

ses.send_kex_first_guess = cli_send_kex_first_guess;
@@ -201,10 +207,23 @@
 /* This function drives the progress of the session - it initiates KEX,
  * service, userauth and channel requests */
 static void cli_sessionloop() {
+   struct timeval wait_to;
+   fd_set wait_fd;
 
 	TRACE2(("enter cli_sessionloop"))
 
 	if (ses.lastpacket == 0) {

+   /* Wait for the server to speak first, making Cisco SSH servers 
happy */
+   if (ses.waitserver > 0) {
+   TRACE2(("enter wait server"))
+   wait_to.tv_sec = ses.waitserver < 600 ? ses.waitserver 
: 600;
+   wait_to.tv_usec = 0;
+   FD_ZERO(_fd);
+   FD_SET(ses.sock_in, _fd);
+   ses.waitserver = select(ses.sock_in + 1, _fd, NULL, 
NULL, _to);
+   TRACE2(("leave wait server: %s", ses.waitserver > 0 ? "ok" : ses.waitserver 
== 0 ? "timeout" : "error"))
+   ses.waitserver = 0;
+   }
TRACE2(("exit cli_sessionloop: no real packets yet"))
return;
}
diff -Naubr dropbear-2018.76.old/session.h dropbear-2018.76.new/session.h
--- dropbear-2018.76.old/session.h  2018-02-27 15:25:12.0 +0100
+++ 

Re: dbclient can't connect to cisco

2018-11-16 Thread Matt Johnston


> On Fri 16/11/2018, at 2:26 am, Nik Soggia  wrote:
> 
> So in the end if I delay the kexinit until there is some data on the wire I 
> will pull the rabbit out of the cylinder.

The problem is that waiting for the remote banner is still adding a round trip 
of delay. That's fine for a local network, but me -> dropbear.nl is half a 
second, that's no good.

Cheers,
Matt

Re: dbclient can't connect to cisco

2018-11-14 Thread Nik Soggia

Il 14/11/18 16:13, Matt Johnston ha scritto:


I'm not keen on changing dbclient, the current implementation saves a network 
roundtrip. It's perfectly reasonable according to the spec. If you have Cisco 
support could you report it to them?


Unfortunately I don't have Cisco support.
I think they did it on purpose, maybe to stop some kind of attack (back 
in the old days sendmail's greet_pause was enough to spot spambots).



rfc4253:
5.2.  New Client, Old Server


RFC's are always right, it's definitely a cisco bug/feature!
I'll try to register and report the problem to them, just for fun.
Thank you,
cheers

--
/\/ / /-<


Re: dbclient can't connect to cisco

2018-11-14 Thread Matt Johnston
On Wed, Nov 14, 2018 at 06:20:59PM +0300, Konstantin Tokarev wrote:
> Note that OpenSSH enables a couple of workarounds for Cisco-1.*
> 
> https://github.com/openssh/openssh-portable/blob/master/compat.c#L88

The tricky thing is that dbclient can't do anything to work around
it here. We haven't yet received the version banner when we
send the first key exchange packet.

Cheers,
Matt


Re: dbclient can't connect to cisco

2018-11-14 Thread Konstantin Tokarev



14.11.2018, 18:16, "Matt Johnston" :
> Hi Nik,
>
>>  dbclient sends "SSH-2.0-dropbear_2018.76\r\n" and kexinit
>>  cisco sends "SSH-2.0-Cisco-1.25\r\n"
>>  then cisco waits "ip ssh time-out" seconds and then closes the TCP socket.
>>
>>  my conjecture is that cisco empties its receive buffer after sendind the 
>> identification string and then waits for the lost kexinit.
>>  To prove my idea I added a sleep() after the first write_packet(), and 
>> dbclient was able to connect to cisco (ios 12.4 and 15.1).
>
> Yes, it seems some Cisco SSH versions are buggy. Older IOS is possibly OK (I 
> did a bit of investigation about a year ago when someone reported similar).
>
> I'm not keen on changing dbclient, the current implementation saves a network 
> roundtrip. It's perfectly reasonable according to the spec. If you have Cisco 
> support could you report it to them?

Note that OpenSSH enables a couple of workarounds for Cisco-1.*

https://github.com/openssh/openssh-portable/blob/master/compat.c#L88

>
> Cheers,
> Matt
>
> rfc4253:
> 5.2. New Client, Old Server
>
>    Since the new client MAY immediately send additional data after its
>    identification string (before receiving the server's identification
>    string), ...

-- 
Regards,
Konstantin



Re: dbclient can't connect to cisco

2018-11-14 Thread Matt Johnston
Hi Nik,

> 
> dbclient sends "SSH-2.0-dropbear_2018.76\r\n" and kexinit
> cisco sends "SSH-2.0-Cisco-1.25\r\n"
> then cisco waits "ip ssh time-out" seconds and then closes the TCP socket.
> 
> my conjecture is that cisco empties its receive buffer after sendind the 
> identification string and then waits for the lost kexinit.
> To prove my idea I added a sleep() after the first write_packet(), and 
> dbclient was able to connect to cisco (ios 12.4 and 15.1).

Yes, it seems some Cisco SSH versions are buggy. Older IOS is possibly OK (I 
did a bit of investigation about a year ago when someone reported similar). 

I'm not keen on changing dbclient, the current implementation saves a network 
roundtrip. It's perfectly reasonable according to the spec. If you have Cisco 
support could you report it to them?

Cheers,
Matt

rfc4253:
5.2.  New Client, Old Server

   Since the new client MAY immediately send additional data after its
   identification string (before receiving the server's identification
   string), ...