mirage / awa-ssh

Purely functional SSH library in ocaml.
ISC License
104 stars 12 forks source link

Add password authentication to SSH client #31

Closed dgjustice closed 1 year ago

dgjustice commented 2 years ago

I finally have some time over the next couple weeks to work on this. The client works well out of the box, and I was able to connect with a password with simple modifications (to a linux host, I don't have a vendor network box handy at the moment). The trouble is trying to port this into the existing client in a way that works. Per RFC4252: "The client MAY send several authentication requests without waiting for responses from previous requests." When I send a single auth request, I don't have a problem, but the event loop seems to have trouble when it receives more than one reply. Using the following in handle_auth_failure,

    let met = Ssh.Pubkey (pub, None) in
    let metp = Ssh.Password ("supers3cr3t", None) in
    Ok ({ t with state = Userauth_request met },
        [ Ssh.Msg_userauth_request (t.user, service, metp); Ssh.Msg_userauth_request (t.user, service, met) ],

I get back:

awa_test_client.exe: [DEBUG] <<< (Msg_unimplemented 7)
awa_test_client.exe: [DEBUG] unexpected (Msg_unimplemented 7)

The unimplemented number is 6 or 7 depending on the auth order. I am not very strong with OCaml, but I would love to try and tackle this if you don't mind providing some pointers along the way. Thanks!

hannesm commented 2 years ago

You could try only the password authentication?

The Msg_unimplemented 7 originates from lib/ssh.ml, where there is a "type message_id" that carries the numbers on the wire -- 1 is disconnect. According to https://www.iana.org/assignments/ssh-parameters/ssh-parameters.xhtml#ssh-parameters-1 7 is SSH_MSG_EXT_INFO (see https://www.rfc-editor.org/rfc/rfc8308.html) that should then be handled (or ignored).

slipalong commented 1 year ago

Hi, do you happen to have an example client code using simple username / password auth? Im trying write a network automation program, but Im new to ocaml.

dgjustice commented 1 year ago

@slipalong I have changed jobs and laptops since I last looked at this, and I don't have the code handy.

hannesm commented 1 year ago

Half a year later, I managed to get #51 into shape. Please let me know what you think about it:

dgjustice commented 1 year ago

@hannesm Thank you for following up on this. I haven't had the opportunity to work with ocaml for some time, but I am still interested in this project. I am having trouble getting it to build.

[nix-shell:~/go/src/github.com/mirage/awa-ssh]$ dune exec test/awa_test_client.exe
File "test/awa_test_client.ml", line 42, characters 36-70:
42 |   Mirage_crypto_rng_unix.initialize (module Mirage_crypto_rng.Fortuna);
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression is packed module, but the expected type is unit

Do you have any idea how I can fix this? Thanks!

reynir commented 1 year ago

You need to upgrade mirage-crypto-rng to >=0.11.0. See here for information the breaking change https://github.com/mirage/mirage-crypto/blob/main/CHANGES.md#v0110-2023-02-09

hannesm commented 1 year ago

@dgjustice as @reynir mentioned, there are two paths forward: upgrade mirage-crypto-rng to 0.11.0, or revert that change (and replace the line with Mirage_crypto_rng_unix.initialize ().

dgjustice commented 1 year ago

@hannesm I think the PR is fine. The two that don't work are probably not issues with the password implementation. Network operating systems are notoriously finicky due to how they are implemented.

Works:

Doesn't work:

hannesm commented 1 year ago

@dgjustice

@hannesm I think the PR is fine. The two that don't work are probably not issues with the password implementation. Network operating systems are notoriously finicky due to how they are implemented.

Works:

* Juniper

great to hear!

Doesn't work:

* Cisco (NXOS, unexpected state and message)

Would you mind to post or upload here a log with more verbose output (awa_test_client -v -v ...)

* Arista (FIPS mode, KEX error)

Could you as well post or upload a log with verbose output?

dgjustice commented 1 year ago

The Arista case appears to be an algorithm problem, but the Cisco case appears to be much simpler (and the same problem Arista will no doubt face after the algorithm issue is sorted). I think it would be possible to implement something along the lines of keyboard interactive auth in a similar manner to what you can do in Go. Here is a gist I wrote after running into a very similar issue. From there, you can simply issue ->command <-response over a session. One of the devs at Arista told me the auth issue is because some network devices implement this layer outside of a regular shell such as bash and use a proprietary daemon.

Arista

dune exec -- test/awa_test_client.exe -v -v --password $(pass show pw)
gpg: WARNING: server 'gpg-agent' is older than us (2.2.27 < 2.3.7)
gpg: problem with fast path key listing: IPC parameter error - ignored
Done: 22% (26/116, 90 left) (jobs: 0)awa_test_client.exe: [INFO] using password authentication
awa_test_client.exe: [DEBUG] >>> (Msg_version SSH-2.0-awa_ssh_0.1)
awa_test_client.exe: [DEBUG] >>> (Msg_kexinit
 ((cookie "\230g7?\191\234\207gwNM\t\177h4\189")
  (kex_algs
   (curve25519-sha256 diffie-hellman-group14-sha256
    diffie-hellman-group-exchange-sha256 diffie-hellman-group14-sha1
    diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha1))
  (server_host_key_algs (ssh-ed25519 rsa-sha2-256 rsa-sha2-512 ssh-rsa))
  (encryption_algs_ctos
   (chacha20-poly1305@openssh.com aes128-ctr aes192-ctr aes256-ctr aes128-cbc
    aes192-cbc aes256-cbc))
  (encryption_algs_stoc
   (chacha20-poly1305@openssh.com aes128-ctr aes192-ctr aes256-ctr aes128-cbc
    aes192-cbc aes256-cbc))
  (mac_algs_ctos
   (hmac-md5 hmac-sha1 hmac-sha2-256 hmac-sha2-512 hmac-sha1-96 hmac-md5-96))
  (mac_algs_stoc
   (hmac-md5 hmac-sha1 hmac-sha2-256 hmac-sha2-512 hmac-sha1-96 hmac-md5-96))
  (compression_algs_ctos (none)) (compression_algs_stoc (none))
  (languages_ctos ()) (languages_stoc ()) (first_kex_packet_follows false)
  (rawkex
   "\020\230g7?\191\234\207gwNM\t\177h4\189\000\000\000\174curve25519-sha256,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1\000\000\000-ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rsa\000\000\000_chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc\000\000\000_chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc\000\000\000Ghmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-sha1-96,hmac-md5-96\000\000\000Ghmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-sha1-96,hmac-md5-96\000\000\000\004none\000\000\000\004none\000\000\000\000\000\000\000\000\000\000\000\000\000")))
awa_test_client.exe: [DEBUG] read 21 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_version SSH-2.0-OpenSSH_7.8)
awa_test_client.exe: [DEBUG] read 520 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_kexinit
 ((cookie "\\\027\240xN\248\180[\014\208\206\218s\189\128A")
  (kex_algs (ecdh-sha2-nistp521))
  (server_host_key_algs (rsa-sha2-512 rsa-sha2-256 ssh-rsa))
  (encryption_algs_ctos
   (aes256-gcm@openssh.com aes128-gcm@openssh.com aes256-ctr aes192-ctr
    aes128-ctr))
  (encryption_algs_stoc
   (aes256-gcm@openssh.com aes128-gcm@openssh.com aes256-ctr aes192-ctr
    aes128-ctr))
  (mac_algs_ctos
   (hmac-sha2-512-etm@openssh.com hmac-sha2-256-etm@openssh.com hmac-sha2-512
    hmac-sha2-256 hmac-sha1))
  (mac_algs_stoc
   (hmac-sha2-512-etm@openssh.com hmac-sha2-256-etm@openssh.com hmac-sha2-512
    hmac-sha2-256 hmac-sha1))
  (compression_algs_ctos (none zlib@openssh.com))
  (compression_algs_stoc (none zlib@openssh.com)) (languages_ctos (""))
  (languages_stoc ("")) (first_kex_packet_follows false)
  (rawkex
   "\020\\\027\240xN\248\180[\014\208\206\218s\189\128A\000\000\000\018ecdh-sha2-nistp521\000\000\000!rsa-sha2-512,rsa-sha2-256,ssh-rsa\000\000\000Naes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr\000\000\000Naes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr\000\000\000ahmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-sha1\000\000\000ahmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-sha1\000\000\000\021none,zlib@openssh.com\000\000\000\021none,zlib@openssh.com\000\000\000\000\000\000\000\000\000\000\000\000\000")))
awa_test_client: Can't agree on kex algorithm

Cisco NXOS

dune exec -- test/awa_test_client.exe -v -v --password $(pass show pw)
gpg: WARNING: server 'gpg-agent' is older than us (2.2.27 < 2.3.7)
gpg: problem with fast path key listing: IPC parameter error - ignored
Done: 22% (26/116, 90 left) (jobs: 0)awa_test_client.exe: [INFO] using password authentication
awa_test_client.exe: [DEBUG] >>> (Msg_version SSH-2.0-awa_ssh_0.1)
awa_test_client.exe: [DEBUG] >>> (Msg_kexinit
 ((cookie "\158\156@1\026\133\203\007\175\206\1920\244b`\186")
  (kex_algs
   (curve25519-sha256 diffie-hellman-group14-sha256
    diffie-hellman-group-exchange-sha256 diffie-hellman-group14-sha1
    diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha1))
  (server_host_key_algs (ssh-ed25519 rsa-sha2-256 rsa-sha2-512 ssh-rsa))
  (encryption_algs_ctos
   (chacha20-poly1305@openssh.com aes128-ctr aes192-ctr aes256-ctr aes128-cbc
    aes192-cbc aes256-cbc))
  (encryption_algs_stoc
   (chacha20-poly1305@openssh.com aes128-ctr aes192-ctr aes256-ctr aes128-cbc
    aes192-cbc aes256-cbc))
  (mac_algs_ctos
   (hmac-md5 hmac-sha1 hmac-sha2-256 hmac-sha2-512 hmac-sha1-96 hmac-md5-96))
  (mac_algs_stoc
   (hmac-md5 hmac-sha1 hmac-sha2-256 hmac-sha2-512 hmac-sha1-96 hmac-md5-96))
  (compression_algs_ctos (none)) (compression_algs_stoc (none))
  (languages_ctos ()) (languages_stoc ()) (first_kex_packet_follows false)
  (rawkex
   "\020\158\156@1\026\133\203\007\175\206\1920\244b`\186\000\000\000\174curve25519-sha256,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1\000\000\000-ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rsa\000\000\000_chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc\000\000\000_chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc\000\000\000Ghmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-sha1-96,hmac-md5-96\000\000\000Ghmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-sha1-96,hmac-md5-96\000\000\000\004none\000\000\000\004none\000\000\000\000\000\000\000\000\000\000\000\000\000")))
awa_test_client.exe: [DEBUG] read 26 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_version "SSH-2.0-OpenSSH_7.2 FIPS")
awa_test_client.exe: [DEBUG] read 360 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_kexinit
 ((cookie "\243\023\146$\142a\180\198\145\223\144'\146:\188\182")
  (kex_algs
   (diffie-hellman-group14-sha1 ecdh-sha2-nistp256 ecdh-sha2-nistp384))
  (server_host_key_algs (ssh-rsa))
  (encryption_algs_ctos
   (aes128-ctr aes192-ctr aes256-ctr aes128-gcm@openssh.com
    aes256-gcm@openssh.com))
  (encryption_algs_stoc
   (aes128-ctr aes192-ctr aes256-ctr aes128-gcm@openssh.com
    aes256-gcm@openssh.com))
  (mac_algs_ctos (hmac-sha1)) (mac_algs_stoc (hmac-sha1))
  (compression_algs_ctos (none zlib@openssh.com))
  (compression_algs_stoc (none zlib@openssh.com)) (languages_ctos (""))
  (languages_stoc ("")) (first_kex_packet_follows false)
  (rawkex
   "\020\243\023\146$\142a\180\198\145\223\144'\146:\188\182\000\000\000Adiffie-hellman-group14-sha1,ecdh-sha2-nistp256,ecdh-sha2-nistp384\000\000\000\007ssh-rsa\000\000\000Naes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com\000\000\000Naes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com\000\000\000\thmac-sha1\000\000\000\thmac-sha1\000\000\000\021none,zlib@openssh.com\000\000\000\021none,zlib@openssh.com\000\000\000\000\000\000\000\000\000\000\000\000\000")))
awa_test_client.exe: [INFO] negotiated: kex diffie-hellman-group14-sha1 host key alg ssh-rsa
enc ctos aes128-ctr stoc aes128-ctr
mac ctos hmac-sha1 stoc hmac-sha1
compression ctos none stoc none
awa_test_client.exe: [DEBUG] >>> (Msg_kexdh_init
 7991813200367996465060955171989141410410361485141114727224356887548661636432587097333909360232217571930351836580200391436821608595877820030865624064603171675163059432215520599004154864511232179544638829210722850620747018795425391287679119492737485879072302221841390483823805810399675025592716082756051633976436321306890343382950846302147618153877521308143494944490488908249633644118818363409860011896820399656698228246628798223681520649479529363437620239214371777554510302711174170013358752330364955193579481112690469339749101003535060831657156617465246027460457938660781935349821060541215951860754769347812854923397)
awa_test_client.exe: [DEBUG] read 592 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_kex MSG_KEX_1
  "\000\000\000\151\000\000\000\007ssh-rsa\000\000\000\003\001\000\001\000\000\000\129\000\174F\248\031\129\132\2426\012\153\200_\237\019j\209\243J\233c\250\188DW\186[\004\b\203\248<\178\002\208\153\183\209\154y\185\208\149\025\173\213\"<\005\182:\140\000\147r7\195M\143%\241\022\167\135\138\241s\155\144\238\187\182\167\147\152\005\254\227\187\247\255\1583\143\187\224G\129\254\250\253\006xV\195W\025\128\014\239x\178\225\142`\147\191\213dD\139\158K\1447\219\226V\161\011n\221\0210\213\173(\018\197\000\000\000\255A\206\006\212\129`\019\191\002\\\173\136\163\012\191\223\181\132J\007\230\130\169\201\021\200\172\018M\t\208y\144\203\132\153\219\220\249\bq\221\222RE\247\181\221h\222\134-\223\134W.aJ\199\b\161\221:\029\167\018C\168W@\137\2239\181\022\211=+\205\183\249\149OO\175\182\197V\204\190q\016]a2.\017$;0fo\r\012\t\156d4,>\176\174\242;\165\208\137\208\149\003\030.\004\169\160\001\241\224\151\198/I[\1908M\199\177\254x-\223|\207*\175\2387\238\bQ\023\016|\137\021\179F\022\2010\030;4\227A\030\007\160?\161m\156s\2552:\210\011A\229\161S\030\021\199\215\251\151\175r\146F\164\020\251\176)y\142\138hy\146(Rs\018\227\0144\154\233\003:\183\228\178^\172\bn\216\188}\000\180\207]\027\182\020Z\189R\012\145\182Z.\188\132\190=\020\227\153\209\230CkA\133\228\208\000\000\000\143\000\000\000\007ssh-rsa\000\000\000\128(\012)\234\198\144qM\129\142/\179\168(\226\213\23910\142{B\148~\r_\181\188\127\158\149\203\248\183\220<\018$\236\000\165m\188|fN~\011\212\209\004\184\2420@\023\
 \n\003\224\214\197\029~\229\180D$&\231_!|\0226\247\231M13\195\029\246/\239\\\1773A\136H\174>\160U\246Z\203~'\234<5G\188\168\1424\145\254,\141T\165\239S~\255\133\153\174\004\171C\173w\223\221\222")
awa_test_client.exe: [WARNING] NO AUTHENTICATOR
awa_test_client.exe: [INFO] verified kexdh_reply!
awa_test_client.exe: [DEBUG] >>> Msg_newkeys
awa_test_client.exe: [DEBUG] rotating ctos keys
awa_test_client.exe: [DEBUG] <<< Msg_newkeys
awa_test_client.exe: [DEBUG] rotating stoc keys
awa_test_client.exe: [DEBUG] >>> (Msg_service_request ssh-userauth)
awa_test_client.exe: [DEBUG] read 52 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_service_accept ssh-userauth)
awa_test_client.exe: [DEBUG] >>> (Msg_userauth_request (djustice ssh-connection Authnone))
awa_test_client.exe: [DEBUG] read 152 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_userauth_banner ("User Access Verification\n" ""))
awa_test_client.exe: [DEBUG] unexpected (Msg_userauth_banner ("User Access Verification\n" ""))
awa_test_client: unexpected state and message
hannesm commented 1 year ago

Thanks @dgjustice and sorry for the delay. Could you test once more with https://github.com/mirage/awa-ssh/pull/51/commits/ef3be89b7b723ce9ec8a669d5ae1011ab0470454 for Arista (that should succeed now), and https://github.com/mirage/awa-ssh/pull/51/commits/c7bb2d60060337da33c9543797953982ba256733 for Cisco NXOS -- both commits are pushed to the same branch (instructions: git clone -b client-password-auth https://github.com/hannesm/awa-ssh.git -- then use dune exec test/awa_test_client.exe --password my_password).

If the authentication fails, could you please re-run with verbose level and post the log here? Thanks a lot! :)

dgjustice commented 1 year ago

Hannes, Cisco works fine now! :tada: Arista is still failing, but it appears to be much later in the process. I tried adding a "keyboard-interactive" auth method, but my Ocaml and SSH protocol skills leave a lot to be desired. I added an entry for keyboard-interactive under the auth methods and tried to blindly return the password, but it doesn't work. I assume this struct needs to be handled some way and the debug2: userauth_kbdint message. If you have any pointers, I can try to figure it out. Thanks!

Done: 22% (26/116, 90 left) (jobs: 0)awa_test_client.exe: [INFO] using password authentication
awa_test_client.exe: [DEBUG] >>> (Msg_version SSH-2.0-awa_ssh_0.1)
awa_test_client.exe: [DEBUG] >>> (Msg_kexinit
 ((cookie "\134B\014\241\208\rj\174,\211\237\173l\031\220S")
  (kex_algs
   (curve25519-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384
    ecdh-sha2-nistp521 diffie-hellman-group14-sha256
    diffie-hellman-group-exchange-sha256 diffie-hellman-group14-sha1
    diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha1))
  (server_host_key_algs (ssh-ed25519 rsa-sha2-256 rsa-sha2-512 ssh-rsa))
  (encryption_algs_ctos
   (chacha20-poly1305@openssh.com aes128-ctr aes192-ctr aes256-ctr aes128-cbc
    aes192-cbc aes256-cbc))
  (encryption_algs_stoc
   (chacha20-poly1305@openssh.com aes128-ctr aes192-ctr aes256-ctr aes128-cbc
    aes192-cbc aes256-cbc))
  (mac_algs_ctos
   (hmac-md5 hmac-sha1 hmac-sha2-256 hmac-sha2-512 hmac-sha1-96 hmac-md5-96))
  (mac_algs_stoc
   (hmac-md5 hmac-sha1 hmac-sha2-256 hmac-sha2-512 hmac-sha1-96 hmac-md5-96))
  (compression_algs_ctos (none)) (compression_algs_stoc (none))
  (languages_ctos ()) (languages_stoc ()) (first_kex_packet_follows false)
  (rawkex
   "\020\134B\014\241\208\rj\174,\211\237\173l\031\220S\000\000\000\231curve25519-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1\000\000\000-ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rsa\000\000\000_chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr
,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc\000\000\000_chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc\000\000\000Ghmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-sha1-96,hmac-md5-96\000\000\000Ghmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-sha1-96,hmac-md5-96\000\000\000\004none\000\000\000\004none\000\000\000\000\000\000\000\000\000\000\000\000\000")))
awa_test_client.exe: [DEBUG] read 21 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_version SSH-2.0-OpenSSH_7.8)
awa_test_client.exe: [DEBUG] read 520 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_kexinit
 ((cookie "\197\141GcO\148\155 \186\147\244o\201\011\247\136")
  (kex_algs (ecdh-sha2-nistp521))
  (server_host_key_algs (rsa-sha2-512 rsa-sha2-256 ssh-rsa))
  (encryption_algs_ctos
   (aes256-gcm@openssh.com aes128-gcm@openssh.com aes256-ctr aes192-ctr
    aes128-ctr))
  (encryption_algs_stoc
   (aes256-gcm@openssh.com aes128-gcm@openssh.com aes256-ctr aes192-ctr
    aes128-ctr))
  (mac_algs_ctos
   (hmac-sha2-512-etm@openssh.com hmac-sha2-256-etm@openssh.com hmac-sha2-512
    hmac-sha2-256 hmac-sha1))
  (mac_algs_stoc
   (hmac-sha2-512-etm@openssh.com hmac-sha2-256-etm@openssh.com hmac-sha2-512
    hmac-sha2-256 hmac-sha1))
  (compression_algs_ctos (none zlib@openssh.com))
  (compression_algs_stoc (none zlib@openssh.com)) (languages_ctos (""))
  (languages_stoc ("")) (first_kex_packet_follows false)
  (rawkex
   "\020\197\141GcO\148\155 \186\147\244o\201\011\247\136\000\000\000\018ecdh-sha2-nistp521\000\000\000!rsa-sha2-512,rsa-sha2-256,ssh-rsa\000\000\000Naes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr\000\000\000Naes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr\000\000\000ahmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac
-sha1\000\000\000ahmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-sha1\000\000\000\021none,zlib@openssh.com\000\000\000\021none,zlib@openssh.com\000\000\000\000\000\000\000\000\000\000\000\000\000")))
awa_test_client.exe: [INFO] negotiated: kex ecdh-sha2-nistp521 host key alg rsa-sha2-256
enc ctos aes128-ctr stoc aes128-ctr
mac ctos hmac-sha1 stoc hmac-sha1
compression ctos none stoc none
awa_test_client.exe: [DEBUG] >>> (Msg_kexecdh_init
 3091534304859961885169967757863193839063621825601457178783828243203515937503159273997647453106588386783317222133004800909627434065488228831031803129381383237896773105310257029241390133295616306161301290413108954012044550220580460238999619788453872998352314592284259701517677856573465174229310978030780624608889814802594)
awa_test_client.exe: [DEBUG] read 728 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_kex MSG_KEX_1
  "\000\000\001\023\000\000\000\007ssh-rsa\000\000\000\003\001\000\001\000\000\001\001\000\148\015\141z\206\196\230u\232\210\016*-\202\241\016\221\230&\016\235\224>\203(&\138\162\141\231\222\206{R\194_P\000\152\250/\157*?\130\189M\245\145\244\189F\239\251\250\173\210mTu\163\140\\\219\190\247\133\199frS7v\141\030\153\132b%\242\156\186\252\181\223R\223\152OY\
 \nxo\151Td\"\135j\198\238\253\135Y\234\130A\1297\249\226\202\141\149\231Sr\225\254?\223@6G\145*\179^\229\168o\143>\159\218\023!\2153\023]\196\187\245\167\251L\2319\181\204\003\030\246\231\019\229\252F9\r\140\238\014\132\2129m/l\173\243\017HO\016\162\149\181\239\219p\017\247\024}io\189\154\b\193\182lW\242[\142)J\025\2385+\182\248\211\200\021{\017\018\019\174\015\025\t\251\140\186\210\133\241\176:o\187\142\193z\011\002Y\1
84\r\175\007\218\173\002\158\147,\222\132\234\235\205X\254\147\007\207\255\023\127\000\000\000\133\004\000\211\017{I\172Ev\163\"0\203\137zU\148\226_m\016~4\144\1918\197\226aF'\220n\011\209\236\238\168\200\198\132vN\175?O\165.\150\244\190\210P\253\005P\1297\220\222\237\255+\019\193\241\201\001\169\176\142C\131\176\233\200\221/\240\255\129!,e\194d}.\198\127\025\019V!\014\233\1785\020\2197\180i[\240\159G\208ed1m\188$\018\22
5\159\163\226\199\1814\243%#~-\0072\255U=s\000\000\001\020\000\000\000\012rsa-sha2-256\000\000\001\000s\192\217\133~?\242\186\211\189!y\028\232\004\138\134\219\212VN\193e&)\127h\142f\155\188\004)\221|\243\175?\011\175\158aO\143\185{k+\030\016qN\208\204\163p\143\218\144L\165\029\249\031)0\237xqn\2399<\247\151\181\026\192\185\
 \n\197\196y\004\170l#e\244Gy\191\024\136\155\187\255\215\128m\245\205T\128v\019\210\167\026\014\139!\020\002KhU\242\133\211\213\024\129K\248\158\174\242E\011,ei\134n\204/\016uNJF0\199\147\183\208\170\161\195\204\011\235!\163\129K\150s\174h\243\196c/\204yZn\156\166FY\244O?\237\169\188\001t\206\162\026L\174\1463\219\016|\215\235O>\196\169\174I\250\159\254C;\222\167 \027\239\171\220\202\233\177\239\197\197s\140\022\030\175
\212\017\143\220&v%\228\192c\246B]\136\145-F\163\172\253;'\203\157\138\137\228\137\189\137&\136\203\178")
awa_test_client.exe: [WARNING] NO AUTHENTICATOR
awa_test_client.exe: [INFO] verified kexdh_reply!
awa_test_client.exe: [DEBUG] >>> Msg_newkeys
awa_test_client.exe: [DEBUG] rotating ctos keys
awa_test_client.exe: [DEBUG] <<< Msg_newkeys
awa_test_client.exe: [DEBUG] rotating stoc keys
awa_test_client.exe: [DEBUG] >>> (Msg_service_request ssh-userauth)
awa_test_client.exe: [DEBUG] read 52 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_service_accept ssh-userauth)
awa_test_client.exe: [DEBUG] >>> (Msg_userauth_request (djustice ssh-connection Authnone))
awa_test_client.exe: [DEBUG] read 68 bytes
awa_test_client.exe: [DEBUG] <<< (Msg_userauth_failure ((publickey keyboard-interactive) false))
awa_test_client: no supported authentication methods left
hannesm commented 1 year ago

Dear @dgjustice, thanks for your patience and log output. I just pushed some more commits to my branch, and now Arista should as well work.

Since you asked "I added an entry for keyboard-interactive under the auth methods and tried to blindly return the password, but it doesn't work. I assume this struct needs to be handled some way and the debug2: userauth_kbdint message. If you have any pointers, I can try to figure it out. Thanks!"

Indeed, what is needed is a bit more, RFC 4256 specifies the keyboard-interactive authentication method that is now implemented. This involved:

So, this does not support the entirety of keyboard-interactive authentication (namely, stuff like multiple passwords, two-factor authentication, required password change are not supported). But for the basic use case "I want to connect to my network equipment" it should be fine.

As mentioned above, thanks for your patience. If you've some spare minutes to fetch my branch (sorry, I force-pushed since I also rebased it onto the main branch) and test it with your network equipment, that'd be lovely.

dgjustice commented 1 year ago

@hannesm Success! :tada: I think we can call this one closed if you are happy with it. Thanks for all the hard work! I am going to have to dust off my Ocaml knowledge and give this a try.

dune exec -- test/awa_test_client.exe --password $(pass show password)
gpg: WARNING: server 'gpg-agent' is older than us (2.2.27 < 2.3.7)
gpg: problem with fast path key listing: IPC parameter error - ignored
Done: 22% (26/116, 90 left) (jobs: 0)awa_test_client.exe: [WARNING] NO AUTHENTICATOR
channel data: Arista DCS-7050SX3-48YC8-F
Hardware version: 11.15
Serial number: JPE
Hardware MAC address: 948e.
System MAC address: 948e.

Software image version: 4.26.5M
Architecture: i686
Internal build version: 4.26.5M-26324336.4265M
Internal build ID: 7ce73a6f-37ff-442b-a278-488b828c4149
Image format version: 1.0

Uptime: 5 days, 15 hours and 33 minutes
Total memory: 8147156 kB
Free memory: 6005380 kB

all good disconnected
hannesm commented 1 year ago

Thanks for your feedback :)