Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add password authentication to SSH client #31

Closed
dgjustice opened this issue Oct 15, 2021 · 15 comments
Closed

Add password authentication to SSH client #31

dgjustice opened this issue Oct 15, 2021 · 15 comments

Comments

@dgjustice
Copy link

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
Copy link
Member

hannesm commented Nov 25, 2021

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
Copy link

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
Copy link
Author

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

hannesm added a commit to hannesm/awa-ssh that referenced this issue Feb 21, 2023
This changes the API of Client.make (now receives a variant
`Password of string | `Pubkey of key), and Awa_mirage.Make().client_of_flow as
well.

This does not support the keyboard-interactive authentication mechanism
(RFC 4256) that is commonly used (with e.g. PAM), but only the password
authentication. May be useful for feature parity between server and client, and
for some network devices.
@hannesm
Copy link
Member

hannesm commented Feb 21, 2023

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

  • are you still interested in password authentication?
  • would password mechanism be sufficient for your use-case, or is keyboard-interactive required?
  • would you mind to test client: support for password authentication fixes #31 #51 (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 to check whether this works for you.

@dgjustice
Copy link
Author

@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
Copy link
Member

reynir commented Feb 25, 2023

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
Copy link
Member

hannesm commented Feb 25, 2023

@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
Copy link
Author

@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

Doesn't work:

  • Cisco (NXOS, unexpected state and message)
  • Arista (FIPS mode, KEX error)

@hannesm
Copy link
Member

hannesm commented Mar 1, 2023

@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
Copy link
Author

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
Copy link
Member

hannesm commented Mar 9, 2023

Thanks @dgjustice and sorry for the delay. Could you test once more with ef3be89 for Arista (that should succeed now), and c7bb2d6 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
Copy link
Author

Hannes, Cisco works fine now! 🎉 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
Copy link
Member

hannesm commented Mar 21, 2023

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:

  • adding the packets (USERAUTH_INFO_REQUEST and USERAUTH_INFO_RESPONSE)
  • delay decoding of USERAUTH_PK_OK, since the INFO_REQUEST reuses the same number
  • add the keyboard-interactive state machine, now an userauth_request is sent by the client, then a info_request is expected, and if there's a single prompt, a info_response is sent

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
Copy link
Author

@hannesm Success! 🎉 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 added a commit that referenced this issue Mar 22, 2023
client: support for password authentication fixes #31
@hannesm
Copy link
Member

hannesm commented Mar 22, 2023

Thanks for your feedback :)

hannesm added a commit to hannesm/opam-repository that referenced this issue Mar 22, 2023
CHANGES:

* server: be able to stop using a Lwt_switch.t (mirage/awa-ssh#52 @dinosaure)
* server: add Pty/Set_env/Start_shell events (mirage/awa-ssh#53 @dinosaure)
* client: support password authentication and keyboard-interactive (mirage/awa-ssh#51
  @hannesm, reported by @dgjustice mirage/awa-ssh#31)
* client: add NIST EC curves (mirage/awa-ssh#31 @hannesm)
* client: try public key authenticaion only once (mirage/awa-ssh#50 @reynir @hannesm)
* remove (partially implemented) hostbased authentication (mirage/awa-ssh#31 @hannesm)
* replace deprecated Cstruct.copy by Cstruct.to_string (mirage/awa-ssh#53 @dinosaure)
* remove ppx_cstruct and sexplib dependencies (mirage/awa-ssh#54 @hannesm)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants