summaryrefslogtreecommitdiff
path: root/lib/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh')
-rw-r--r--lib/ssh/doc/src/notes.xml257
-rw-r--r--lib/ssh/doc/src/ssh.xml40
-rw-r--r--lib/ssh/src/ssh.hrl2
-rw-r--r--lib/ssh/src/ssh_acceptor.erl5
-rw-r--r--lib/ssh/src/ssh_auth.erl361
-rw-r--r--lib/ssh/src/ssh_cli.erl5
-rw-r--r--lib/ssh/src/ssh_client_channel.erl6
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl219
-rw-r--r--lib/ssh/src/ssh_dbg.erl128
-rw-r--r--lib/ssh/src/ssh_message.erl11
-rw-r--r--lib/ssh/src/ssh_options.erl35
-rw-r--r--lib/ssh/src/ssh_sftp.erl4
-rw-r--r--lib/ssh/src/ssh_sftpd.erl4
-rw-r--r--lib/ssh/src/ssh_shell.erl4
-rw-r--r--lib/ssh/src/ssh_transport.erl9
-rw-r--r--lib/ssh/test/.gitignore2
-rw-r--r--lib/ssh/test/Makefile1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server.erl9
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa21
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa.pub1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa2565
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa3846
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa5217
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed255197
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed25519.pub1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed44810
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed448.pub1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa38
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa.pub1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed25519_key7
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed25519_key.pub1
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed448_key10
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed448_key.pub1
-rw-r--r--lib/ssh/test/ssh_agent_SUITE.erl38
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed25519_key7
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed25519_key.pub1
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed448_key10
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed448_key.pub1
-rw-r--r--lib/ssh/test/ssh_agent_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE.erl125
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa20
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa50
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl830
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_dsa21
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_dsa.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_rsa38
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_rsa.pub1
-rw-r--r--lib/ssh/test/ssh_compat_SUITE.erl17
-rw-r--r--lib/ssh/test/ssh_connection_SUITE.erl31
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE.erl9
-rw-r--r--lib/ssh/test/ssh_engine_SUITE.erl21
-rw-r--r--lib/ssh/test/ssh_options_SUITE.erl14
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_dsa21
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_dsa.pub1
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_ecdsa3846
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_ecdsa5217
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_ed255197
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_ed25519.pub1
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_ed44810
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_ed448.pub1
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_rsa38
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_rsa.pub1
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed25519_key7
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed25519_key.pub1
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed448_key10
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed448_key.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE.erl6
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_dsa21
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_dsa.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa3846
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa5217
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_ed255197
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_ed25519.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_ed44810
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_ed448.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_rsa38
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_rsa.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed25519_key7
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed25519_key.pub1
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed448_key10
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed448_key.pub1
-rw-r--r--lib/ssh/test/ssh_pubkey_SUITE.erl129
-rw-r--r--lib/ssh/test/ssh_pubkey_SUITE_data/new_format/id_ed44815
-rw-r--r--lib/ssh/test/ssh_pubkey_SUITE_data/new_format/id_ed448.pub1
-rw-r--r--lib/ssh/test/ssh_pubkey_SUITE_data/new_format/ssh_host_ed448_key15
-rw-r--r--lib/ssh/test/ssh_pubkey_SUITE_data/new_format/ssh_host_ed448_key.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE.erl393
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa12
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa3846
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa5217
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed255197
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed25519.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed44810
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed448.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa27
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed25519_key7
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed25519_key.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed448_key10
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed448_key.pub1
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_sftpd_SUITE.erl8
-rw-r--r--lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl25
-rw-r--r--lib/ssh/test/ssh_test_lib.erl468
-rw-r--r--lib/ssh/test/ssh_test_lib.hrl10
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE.erl66
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ecdsa_key5
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ecdsa_key.pub1
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ed25519_key7
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ed25519_key.pub1
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE.erl4
-rw-r--r--lib/ssh/vsn.mk2
165 files changed, 2548 insertions, 1587 deletions
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 4492b937a2..1cc25c00b3 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -30,6 +30,247 @@
<file>notes.xml</file>
</header>
+<section><title>Ssh 4.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix error in ssh_sftpd typespec.</p>
+ <p>
+ Own Id: OTP-16363</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The plug-in file ssh_file.erl, that is responsible for
+ default file handling, is re-factored, optimized and
+ re-written.</p>
+ <p>
+ Own Id: OTP-11688 Aux Id: OTP-12699 </p>
+ </item>
+ <item>
+ <p>
+ OpenSSH 6.5 introduced a new file representation of keys
+ called <url
+ href="https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.key?annotate=1.1">openssh-key-v1</url>.</p>
+ <p>
+ OTP/SSH had an experimental implementation of this
+ format. That implementation is now improved and supported
+ with the exception of handling encrypted keys.</p>
+ <p>
+ Own Id: OTP-15434</p>
+ </item>
+ <item>
+ <p>
+ TCP/IP port forwarding, a.k.a tunneling a.k.a
+ tcp-forward/direct-tcp is implemented. In the OpenSSH
+ client, this corresponds to the options -L and -R.</p>
+ <p>
+ The client or server listens to a specified socket, and
+ when something connects to it with TCP/IP, that
+ connection is forwarded in an encrypted tunnel to the
+ peer. The peer then connects to a predefined IP/port pair
+ and then acts as a proxy.</p>
+ <p>
+ See the manual, <seemfa
+ marker="ssh:ssh#tcpip_tunnel_to_server/6"><c>ssh:tcpip_tunnel_to_server/6</c></seemfa>
+ and <seemfa
+ marker="ssh:ssh#tcpip_tunnel_from_server/6"><c>ssh:tcpip_tunnel_from_server/6</c></seemfa>.</p>
+ <p>
+ The functionality is disabled per default but can be
+ enabled when starting a daemon.</p>
+ <p>
+ Own Id: OTP-15998 Aux Id: PR-2376, PR-2368 </p>
+ </item>
+ <item>
+ <p>
+ The client-side of the supervisor tree (under sshc_sup)
+ was previously not complete; the channel handling
+ processes were handled with links but had no supervisors.</p>
+ <p>
+ This is now corrected with a client-side supervisor tree
+ under <c>sshc_sup</c>, similar to the server-side
+ supervisor tree under <c>sshd_sup</c>.</p>
+ <p>
+ Own Id: OTP-16026 Aux Id: PR-2368, (OTP-15998) </p>
+ </item>
+ <item>
+ <p>
+ The extension <url
+ href="https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL?annotate=HEAD">posix-rename@openssh.com</url>
+ is added to the <seemfa
+ marker="ssh:ssh_sftp#rename/3">ssh/sftp rename</seemfa>
+ operation.</p>
+ <p>
+ Own Id: OTP-16289 Aux Id: PR-2448 </p>
+ </item>
+ <item>
+ <p>
+ Calls of deprecated functions in the <seeguide
+ marker="crypto:new_api#the-old-api">Old Crypto
+ API</seeguide> are replaced by calls of their <seeguide
+ marker="crypto:new_api#the-new-api">substitutions</seeguide>.</p>
+ <p>
+ Own Id: OTP-16346</p>
+ </item>
+ <item>
+ <p>
+ The default known_hosts file handling is improved to
+ include ports.</p>
+ <p>
+ The handling of the contents in that file is updated to
+ support the <url
+ href="https://man.openbsd.org/sshd#SSH_KNOWN_HOSTS_FILE_FORMAT">full
+ syntax</url>, with exception of 1) the wildcard '?', 2)
+ wildcards in canonical names and 3) the option
+ '@cert-authority'</p>
+ <p>
+ Own Id: OTP-16506</p>
+ </item>
+ <item>
+ <p>
+ The MAC (Message Authorization Code) algorithms</p>
+ <list> <item>hmac-sha1-etm@openssh.com</item>
+ <item>hmac-sha2-256-etm@openssh.com</item>
+ <item>hmac-sha2-512-etm@openssh.com</item> </list> <p>are
+ implemented.</p>
+ <p>
+ Own Id: OTP-16508</p>
+ </item>
+ <item>
+ <p>
+ The key-exchange algorithms
+ <c>'diffie-hellman-group14-sha1'</c> and
+ <c>'diffie-hellman-group-exchange-sha1'</c> are disabled
+ per default. The reason is that SHA1 now is considered
+ insecure.</p>
+ <p>
+ They can be enabled if needed, see <seeapp
+ marker="ssh:SSH_app#algorithms">SSH (App)</seeapp>.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-16509</p>
+ </item>
+ <item>
+ <p>
+ The public key algorithm <c>'ssh-dss'</c> is disabled per
+ default. The reason is that it is now considered as
+ insecure.</p>
+ <p>
+ It can be enabled if needed, see <seeapp
+ marker="ssh:SSH_app#algorithms">SSH (App)</seeapp>.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-16510</p>
+ </item>
+ <item>
+ <p>
+ The public key <c>'ssh-rsa'</c> is now considered as
+ insecure because of its usage of SHA1.</p>
+ <p>
+ It is therefore deprecated and will no longer be enabled
+ per default in OTP-24.0.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-16511</p>
+ </item>
+ <item>
+ <p>
+ An option <seetype
+ marker="ssh:ssh_file#optimize_key_lookup">optimize
+ (optimize_key_lookup)</seetype> is introduced for the
+ file interface ssh_file.erl</p>
+ <p>
+ The option enables the user to select between the default
+ handling which is fast but memory consuming vs memory
+ efficient but not as fast. The effect might be observable
+ only for large files.</p>
+ <p>
+ See the manual for <seemfa
+ marker="ssh:ssh_file#is_host_key/5">ssh_file:is_host_key/5</seemfa>
+ and <seemfa
+ marker="ssh:ssh_file#is_auth_key/3">ssh_file:is_auth_key/3</seemfa>.</p>
+ <p>
+ Own Id: OTP-16512</p>
+ </item>
+ <item>
+ <p>
+ The ssh agent is now implemented in the ssh_agent key
+ callback module. </p>
+ <p>
+ Enable with the the option <c> {key_cb, {ssh_agent,
+ []}}</c> in for example ssh:connect/3.</p>
+ <p>
+ See the <seeerl marker="ssh:ssh_agent">ssh_agent
+ manual</seeerl> for details.</p>
+ <p>
+ Own Id: OTP-16513</p>
+ </item>
+ <item>
+ <p>
+ Algorithm configuration could now be done in a .config
+ file.</p>
+ <p>
+ This is useful for example to enable an algorithm that is
+ disabled by default. It could now be enabled in an
+ .config-file without changing the code,</p>
+ <p>
+ See the SSH User's Guide chapter <seeguide
+ marker="ssh:configurations">"Configuration in
+ SSH"</seeguide>.</p>
+ <p>
+ Own Id: OTP-16540</p>
+ </item>
+ <item>
+ <p>
+ Documented which gen_tcp socket options can't be used in
+ calls to ssh:connect and ssh:daemon.</p>
+ <p>
+ Own Id: OTP-16589</p>
+ </item>
+ <item>
+ <p>
+ Added <seetype
+ marker="ssh:ssh#kb_int_fun_4">kb_int_fun_4()</seetype> to
+ the <seetype
+ marker="ssh:ssh#authentication_daemon_options">authentication_daemon_options()</seetype>
+ to enable generating dynamic keyboard-interactive prompts
+ from the user's state returned from the authentication
+ fun <seetype
+ marker="ssh:ssh#pwdfun_4">pwdfun_4()</seetype>.</p>
+ <p>
+ Own Id: OTP-16622 Aux Id: PR-2604 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.9.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Potential hazard between re-keying decision and socket
+ close.</p>
+ <p>
+ Own Id: OTP-16462 Aux Id: ERIERL-464 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ssh 4.9</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -303,6 +544,22 @@
</section>
+<section><title>Ssh 4.7.6.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Potential hazard between re-keying decision and socket
+ close.</p>
+ <p>
+ Own Id: OTP-16462 Aux Id: ERIERL-464 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ssh 4.7.6.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index ca6a02117b..f7818b809a 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -179,6 +179,17 @@
<p>Options for <seemfa marker="#connect/3">clients</seemfa>.
The individual options are further explained below or by following the hyperlinks.
</p>
+ <p>Note that not every
+ <seetype marker="kernel:gen_tcp#connect_option">gen_tcp:connect_option()</seetype>
+ is accepted. See
+ <seemfa marker="ssh#set_sock_opts/2">set_sock_opts/2</seemfa>
+ for a list of prohibited options.
+ </p>
+ <p>Also note that setting a
+ <seetype marker="kernel:gen_tcp#connect_option">gen_tcp:connect_option()</seetype>
+ could change the socket in a way that impacts the ssh client's behaviour
+ negatively. You use it on your own risk.
+ </p>
</desc>
</datatype>
@@ -341,6 +352,17 @@
<p>Options for <seemfa marker="#daemon/1">daemons</seemfa>.
The individual options are further explained below or by following the hyperlinks.
</p>
+ <p>Note that not every
+ <seetype marker="kernel:gen_tcp#listen_option">gen_tcp:listen_option()</seetype>
+ is accepted. See
+ <seemfa marker="ssh#set_sock_opts/2">set_sock_opts/2</seemfa>
+ for a list of prohibited options.
+ </p>
+ <p>Also note that setting a
+ <seetype marker="kernel:gen_tcp#listen_option">gen_tcp:listen_option()</seetype>
+ could change the socket in a way that impacts the ssh deamon's behaviour
+ negatively. You use it on your own risk.
+ </p>
</desc>
</datatype>
@@ -514,6 +536,7 @@
<name name="prompt_texts"/>
<name name="kb_int_tuple"/>
<name name="kb_int_fun_3"/>
+ <name name="kb_int_fun_4"/>
<name name="pwdfun_2"/>
<name name="pwdfun_4"/>
<desc>
@@ -522,7 +545,7 @@
<item>
<p>Sets the text strings that the daemon sends to the client for presentation to the user when
using <c>keyboard-interactive</c> authentication.</p>
- <p>If the fun/3 is used, it is called when the actual authentication occurs and may therefore
+ <p>If the fun/3 or fun/4 is used, it is called when the actual authentication occurs and may therefore
return dynamic data like time, remote ip etc.</p>
<p>The parameter <c>Echo</c> guides the client about need to hide the password.</p>
<p>The default value is:
@@ -874,7 +897,7 @@
<datatype>
<name name="disconnectfun_common_option"/>
<desc>
- <p>Provides a fun to implement your own logging when the peer disconnects.</p>
+ <p>Provides a fun to implement your own logging or other handling at disconnects.</p>
</desc>
</datatype>
@@ -1221,8 +1244,17 @@
<p>This function calls the
<seemfa marker="kernel:inet#setopts/2">inet:setopts/2</seemfa>, read that documentation and
for <seetype marker="kernel:gen_tcp#option">gen_tcp:option()</seetype>.
- All gen_tcp socket options except <c>active</c>, <c>deliver</c>, <c>mode</c> and <c>packet</c>
- are allowed. The excluded options are reserved by the SSH application.
+ </p>
+ <p>
+ All gen_tcp socket options except
+ </p>
+ <list>
+ <item><c>active</c></item>
+ <item><c>deliver</c></item>
+ <item><c>mode</c> and</item>
+ <item><c>packet</c></item>
+ </list>
+ <p>are allowed. The excluded options are reserved by the SSH application.
</p>
<warning>
<p>This is an extremly dangerous function. You use it on your own risk.</p>
diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl
index ffa2ec8c06..ad90a1a841 100644
--- a/lib/ssh/src/ssh.hrl
+++ b/lib/ssh/src/ssh.hrl
@@ -361,9 +361,11 @@
-type prompt_texts() ::
kb_int_tuple()
| kb_int_fun_3()
+ | kb_int_fun_4()
.
-type kb_int_fun_3() :: fun((Peer::ip_port(), User::string(), Service::string()) -> kb_int_tuple()).
+-type kb_int_fun_4() :: fun((Peer::ip_port(), User::string(), Service::string(), State::any()) -> kb_int_tuple()).
-type kb_int_tuple() :: {Name::string(), Instruction::string(), Prompt::string(), Echo::boolean()}.
-type pwdfun_2() :: fun((User::string(), Password::string()) -> boolean()) .
diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl
index 15e59dd1fe..960058fa38 100644
--- a/lib/ssh/src/ssh_acceptor.erl
+++ b/lib/ssh/src/ssh_acceptor.erl
@@ -217,6 +217,11 @@ ssh_dbg_format(connections, {call, {?MODULE,acceptor_init,
[_Parent, Port, Address, _Opts, _AcceptTimeout]}}) ->
[io_lib:format("Starting LISTENER on ~s:~p\n", [ntoa(Address),Port])
];
+ssh_dbg_format(connections, {return_from, {?MODULE,acceptor_init,5}, _Ret}) ->
+ skip;
+
+ssh_dbg_format(connections, {call, {?MODULE,handle_connection,[_,_,_,_,_]}}) ->
+ skip;
ssh_dbg_format(connections, {return_from, {?MODULE,handle_connection,5}, {error,Error}}) ->
["Starting connection to server failed:\n",
io_lib:format("Error = ~p", [Error])
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl
index a42f034f1b..19df20c9f1 100644
--- a/lib/ssh/src/ssh_auth.erl
+++ b/lib/ssh/src/ssh_auth.erl
@@ -32,10 +32,13 @@
-export([get_public_key/2,
publickey_msg/1, password_msg/1, keyboard_interactive_msg/1,
service_request_msg/1, init_userauth_request_msg/1,
- userauth_request_msg/1, handle_userauth_request/3,
+ userauth_request_msg/1, handle_userauth_request/3, ssh_msg_userauth_result/1,
handle_userauth_info_request/2, handle_userauth_info_response/2
]).
+-behaviour(ssh_dbg).
+-export([ssh_dbg_trace_points/0, ssh_dbg_flags/1, ssh_dbg_on/1, ssh_dbg_off/1, ssh_dbg_format/3]).
+
%%--------------------------------------------------------------------
%%% Internal application API
%%--------------------------------------------------------------------
@@ -110,14 +113,13 @@ password_msg([#ssh{opts = Opts,
not_ok ->
{not_ok, Ssh};
_ ->
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_request{user = User,
- service = Service,
- method = "password",
- data =
- <<?BOOLEAN(?FALSE),
- ?STRING(unicode:characters_to_binary(Password))>>},
- Ssh)
+ {#ssh_msg_userauth_request{user = User,
+ service = Service,
+ method = "password",
+ data =
+ <<?BOOLEAN(?FALSE),
+ ?STRING(unicode:characters_to_binary(Password))>>},
+ Ssh}
end.
%% See RFC 4256 for info on keyboard-interactive
@@ -128,13 +130,12 @@ keyboard_interactive_msg([#ssh{user = User,
not_ok ->
{not_ok,Ssh}; % No need to use a failed pwd once more
_ ->
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_request{user = User,
- service = Service,
- method = "keyboard-interactive",
- data = << ?STRING(<<"">>),
- ?STRING(<<>>) >> },
- Ssh)
+ {#ssh_msg_userauth_request{user = User,
+ service = Service,
+ method = "keyboard-interactive",
+ data = << ?STRING(<<"">>),
+ ?STRING(<<>>) >> },
+ Ssh}
end.
@@ -183,15 +184,14 @@ publickey_msg([SigAlg, #ssh{user = User,
SigBlob = list_to_binary([?string(SigAlgStr),
?binary(Sig)]),
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_request{user = User,
- service = Service,
- method = "publickey",
- data = [?TRUE,
- ?string(SigAlgStr),
- ?binary(PubKeyBlob),
- ?binary(SigBlob)]},
- Ssh);
+ {#ssh_msg_userauth_request{user = User,
+ service = Service,
+ method = "publickey",
+ data = [?TRUE,
+ ?string(SigAlgStr),
+ ?binary(PubKeyBlob),
+ ?binary(SigBlob)]},
+ Ssh};
_ ->
{not_ok, Ssh}
@@ -199,8 +199,8 @@ publickey_msg([SigAlg, #ssh{user = User,
%%%----------------------------------------------------------------
service_request_msg(Ssh) ->
- ssh_transport:ssh_packet(#ssh_msg_service_request{name = "ssh-userauth"},
- Ssh#ssh{service = "ssh-userauth"}).
+ {#ssh_msg_service_request{name = "ssh-userauth"},
+ Ssh#ssh{service = "ssh-userauth"}}.
%%%----------------------------------------------------------------
init_userauth_request_msg(#ssh{opts = Opts} = Ssh) ->
@@ -210,24 +210,23 @@ init_userauth_request_msg(#ssh{opts = Opts} = Ssh) ->
?DISCONNECT(?SSH_DISCONNECT_ILLEGAL_USER_NAME,
"Could not determine the users name");
User ->
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_request{user = User,
- service = "ssh-connection",
- method = "none",
- data = <<>>},
- Ssh#ssh{user = User,
- userauth_preference = method_preference(Ssh#ssh.userauth_pubkeys),
- userauth_methods = none,
- service = "ssh-connection"}
- )
+ {#ssh_msg_userauth_request{user = User,
+ service = "ssh-connection",
+ method = "none",
+ data = <<>>},
+ Ssh#ssh{user = User,
+ userauth_preference = method_preference(Ssh#ssh.userauth_pubkeys),
+ userauth_methods = none,
+ service = "ssh-connection"}
+ }
end.
%%%----------------------------------------------------------------
%%% called by server
handle_userauth_request(#ssh_msg_service_request{name = Name = "ssh-userauth"},
_, Ssh) ->
- {ok, ssh_transport:ssh_packet(#ssh_msg_service_accept{name = Name},
- Ssh#ssh{service = "ssh-connection"})};
+ {ok, {#ssh_msg_service_accept{name = Name},
+ Ssh#ssh{service = "ssh-connection"}}};
handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
@@ -239,12 +238,13 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
case check_password(User, Password, Opts, Ssh) of
{true,Ssh1} ->
{authorized, User,
- ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh1)};
+ {#ssh_msg_userauth_success{}, Ssh1}
+ };
{false,Ssh1} ->
{not_authorized, {User, {error,"Bad user or password"}},
- ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = Methods,
- partial_success = false}, Ssh1)}
+ {#ssh_msg_userauth_failure{authentications = Methods,
+ partial_success = false}, Ssh1}
+ }
end;
handle_userauth_request(#ssh_msg_userauth_request{user = User,
@@ -264,18 +264,18 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
%% or the old password was bad.
{not_authorized, {User, {error,"Password change not supported"}},
- ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = Methods,
- partial_success = false}, Ssh)};
+ {#ssh_msg_userauth_failure{authentications = Methods,
+ partial_success = false}, Ssh}
+ };
handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
method = "none"}, _,
#ssh{userauth_supported_methods = Methods} = Ssh) ->
{not_authorized, {User, undefined},
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_failure{authentications = Methods,
- partial_success = false}, Ssh)};
+ {#ssh_msg_userauth_failure{authentications = Methods,
+ partial_success = false}, Ssh}
+ };
handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
@@ -293,14 +293,14 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
case pre_verify_sig(User, KeyBlob, Opts) of
true ->
{not_authorized, {User, undefined},
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_pk_ok{algorithm_name = binary_to_list(BAlg),
- key_blob = KeyBlob}, Ssh)};
+ {#ssh_msg_userauth_pk_ok{algorithm_name = binary_to_list(BAlg),
+ key_blob = KeyBlob}, Ssh}
+ };
false ->
{not_authorized, {User, undefined},
- ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = Methods,
- partial_success = false}, Ssh)}
+ {#ssh_msg_userauth_failure{authentications = Methods,
+ partial_success = false}, Ssh}
+ }
end;
handle_userauth_request(#ssh_msg_userauth_request{user = User,
@@ -318,13 +318,13 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
BAlg, KeyBlob, SigWLen, Ssh) of
true ->
{authorized, User,
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_success{}, Ssh)};
+ {#ssh_msg_userauth_success{}, Ssh}
+ };
false ->
{not_authorized, {User, undefined},
- ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = Methods,
- partial_success = false}, Ssh)}
+ {#ssh_msg_userauth_failure{authentications = Methods,
+ partial_success = false}, Ssh}
+ }
end;
handle_userauth_request(#ssh_msg_userauth_request{user = User,
@@ -337,9 +337,9 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
case KbTriesLeft of
N when N<1 ->
{not_authorized, {User, {authmethod, "keyboard-interactive"}},
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_failure{authentications = Methods,
- partial_success = false}, Ssh)};
+ {#ssh_msg_userauth_failure{authentications = Methods,
+ partial_success = false}, Ssh}
+ };
_ ->
%% RFC4256
@@ -364,6 +364,9 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
Default;
{_,_,_,_}=V ->
V;
+ F when is_function(F, 4) ->
+ {_,PeerName} = Ssh#ssh.peer,
+ F(PeerName, User, "ssh-connection", Ssh#ssh.pwdfun_user_state);
F when is_function(F) ->
{_,PeerName} = Ssh#ssh.peer,
F(PeerName, User, "ssh-connection")
@@ -381,8 +384,8 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
>>
},
{not_authorized, {User, undefined},
- ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User
- })}
+ {Msg, Ssh#ssh{user = User}}
+ }
end;
handle_userauth_request(#ssh_msg_userauth_request{user = User,
@@ -390,9 +393,9 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
method = Other}, _,
#ssh{userauth_supported_methods = Methods} = Ssh) ->
{not_authorized, {User, {authmethod, Other}},
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_failure{authentications = Methods,
- partial_success = false}, Ssh)}.
+ {#ssh_msg_userauth_failure{authentications = Methods,
+ partial_success = false}, Ssh}
+ }.
%%%----------------------------------------------------------------
@@ -408,9 +411,9 @@ handle_userauth_info_request(#ssh_msg_userauth_info_request{name = Name,
not_ok;
Responses ->
{ok,
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_info_response{num_responses = NumPrompts,
- data = Responses}, Ssh)}
+ {#ssh_msg_userauth_info_response{num_responses = NumPrompts,
+ data = Responses},
+ Ssh}}
end.
%%%----------------------------------------------------------------
@@ -428,32 +431,30 @@ handle_userauth_info_response(#ssh_msg_userauth_info_response{num_responses = 1,
case check_password(User, unicode:characters_to_list(Password), Opts, Ssh) of
{true,Ssh1} when SendOneEmpty==true ->
- Msg = #ssh_msg_userauth_info_request{name = "",
- instruction = "",
- language_tag = "",
- num_prompts = 0,
- data = <<?BOOLEAN(?FALSE)>>
- },
{authorized_but_one_more, User,
- ssh_transport:ssh_packet(Msg, Ssh1)};
+ {#ssh_msg_userauth_info_request{name = "",
+ instruction = "",
+ language_tag = "",
+ num_prompts = 0,
+ data = <<?BOOLEAN(?FALSE)>>
+ },
+ Ssh1}};
{true,Ssh1} ->
{authorized, User,
- ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh1)};
+ {#ssh_msg_userauth_success{}, Ssh1}};
{false,Ssh1} ->
{not_authorized, {User, {error,"Bad user or password"}},
- ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = Methods,
- partial_success = false},
- Ssh1#ssh{kb_tries_left = max(KbTriesLeft-1, 0)}
- )}
+ {#ssh_msg_userauth_failure{authentications = Methods,
+ partial_success = false},
+ Ssh1#ssh{kb_tries_left = max(KbTriesLeft-1, 0)}}}
end;
handle_userauth_info_response({extra,#ssh_msg_userauth_info_response{}},
#ssh{user = User} = Ssh) ->
{authorized, User,
- ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh)};
+ {#ssh_msg_userauth_success{}, Ssh}};
handle_userauth_info_response(#ssh_msg_userauth_info_response{},
_Auth) ->
@@ -619,3 +620,193 @@ write_if_nonempty(_, "") -> ok;
write_if_nonempty(_, <<>>) -> ok;
write_if_nonempty(IoCb, Text) -> IoCb:format("~s~n",[Text]).
+%%%----------------------------------------------------------------
+%%% Called just for the tracer ssh_dbg
+ssh_msg_userauth_result(_R) -> ok.
+
+%%%################################################################
+%%%#
+%%%# Tracing
+%%%#
+
+ssh_dbg_trace_points() -> [authentication].
+
+ssh_dbg_flags(authentication) -> [c].
+
+ssh_dbg_on(authentication) -> dbg:tp(?MODULE, handle_userauth_request, 3, x),
+ dbg:tp(?MODULE, init_userauth_request_msg, 1, x),
+ dbg:tp(?MODULE, ssh_msg_userauth_result, 1, x),
+ dbg:tp(?MODULE, userauth_request_msg, 1, x).
+
+ssh_dbg_off(authentication) -> dbg:ctpg(?MODULE, handle_userauth_request, 3),
+ dbg:ctpg(?MODULE, init_userauth_request_msg, 1),
+ dbg:ctpg(?MODULE, ssh_msg_userauth_result, 1),
+ dbg:ctpg(?MODULE, userauth_request_msg, 1).
+
+
+
+%%% Server ----------------
+ssh_dbg_format(authentication, {call, {?MODULE,handle_userauth_request, [Req,_SessionID,Ssh]}},
+ Stack) ->
+ {skip, [{Req,Ssh}|Stack]};
+
+
+ssh_dbg_format(authentication, {return_from, {?MODULE,handle_userauth_request,3},
+ {ok,{#ssh_msg_service_accept{name=Name},_Ssh}}},
+ [{#ssh_msg_service_request{name=Name},_} | Stack]) ->
+ {skip, Stack};
+
+ssh_dbg_format(authentication, {return_from, {?MODULE,handle_userauth_request,3},
+ {authorized,User,_Repl}},
+ [{#ssh_msg_userauth_request{}=Req,Ssh}|Stack]) ->
+ {["AUTH srvr: Peer client authorized\n",
+ io_lib:format("user = ~p~n", [User]),
+ fmt_req(Req, Ssh)],
+ Stack};
+
+ssh_dbg_format(authentication, {return_from, {?MODULE,handle_userauth_request,3},
+ {not_authorized,{User,_X},_Repl}},
+ [{#ssh_msg_userauth_request{method="none"},Ssh}|Stack]) ->
+ Methods = Ssh#ssh.userauth_supported_methods,
+ {["AUTH srvr: Peer queries auth methods\n",
+ io_lib:format("user = ~p~nsupported methods = ~p ?", [User,Methods])
+ ],
+ Stack};
+
+ssh_dbg_format(authentication, {return_from, {?MODULE,handle_userauth_request,3},
+ {not_authorized,{User,_X}, Repl}
+ },
+ [{#ssh_msg_userauth_request{method = "publickey",
+ data = <<?BYTE(?FALSE), _/binary>>
+ }=Req,Ssh}|Stack]) ->
+ {case Repl of
+ {#ssh_msg_userauth_pk_ok{}, _} ->
+ ["AUTH srvr: Answer - pub key supported\n"];
+ {#ssh_msg_userauth_failure{}, _} ->
+ ["AUTH srvr: Answer - pub key not supported\n"];
+ {Other, _} ->
+ ["AUTH srvr: Answer - strange answer\n",
+ io_lib:format("strange answer = ~p~n",[Other])
+ ]
+ end
+ ++ [io_lib:format("user = ~p~n", [User]),
+ fmt_req(Req, Ssh)],
+ Stack};
+
+
+ssh_dbg_format(authentication, {call, {?MODULE,ssh_msg_userauth_result,[success]}},
+ Stack) ->
+ {["AUTH client: Success"],Stack};
+ssh_dbg_format(authentication, {return_from, {?MODULE,ssh_msg_userauth_result,1}, _Result},
+ Stack) ->
+ {skip, Stack};
+
+ssh_dbg_format(authentication, {return_from, {?MODULE,handle_userauth_request,3},
+ {not_authorized,{User,_X},_Repl}},
+ [{#ssh_msg_userauth_request{}=Req,Ssh}|Stack]) ->
+ {["AUTH srvr: Peer client authorization failed\n",
+ io_lib:format("user = ~p~n", [User]),
+ fmt_req(Req, Ssh)],
+ Stack};
+
+%%% Client ----------------
+ssh_dbg_format(authentication, {call, {?MODULE,init_userauth_request_msg, [#ssh{opts = Opts}]}},
+ Stack) ->
+ {["AUTH client: Service ssh-userauth accepted\n",
+ case ?GET_OPT(user, Opts) of
+ undefined ->
+ io_lib:format("user = undefined *** ERROR ***", []);
+ User ->
+ io_lib:format("user = ~p", [User])
+ end
+ ],
+ Stack};
+ssh_dbg_format(authentication, {return_from, {?MODULE,init_userauth_request_msg,1},
+ {Repl = #ssh_msg_userauth_request{user = User,
+ service = "ssh-connection",
+ method = "none"},
+ _Ssh}},
+ Stack) ->
+ {["AUTH client: Query for accepted methods\n",
+ io_lib:format("user = ~p", [User])],
+ [Repl|Stack]};
+
+ssh_dbg_format(authentication, {call, {?MODULE,userauth_request_msg,
+ [#ssh{userauth_methods = Methods}]}},
+ [ #ssh_msg_userauth_request{user = User,
+ service = "ssh-connection",
+ method = "none"} | Stack]) ->
+ {["AUTH client: Server supports\n",
+ io_lib:format("user = ~p~nmethods = ~p", [User,Methods])],
+ Stack};
+
+ssh_dbg_format(authentication, {call, {?MODULE,userauth_request_msg,[_Ssh]}},
+ Stack) ->
+ {skip,Stack};
+
+ssh_dbg_format(authentication, {return_from, {?MODULE,userauth_request_msg,1},
+ {send_disconnect, _Code, _Ssh}},
+ Stack) ->
+ {skip,Stack};
+ssh_dbg_format(authentication, {return_from, {?MODULE,userauth_request_msg,1},
+ {Method,{_Msg,_Ssh}}},
+ Stack) ->
+ {["AUTH client: Try auth with\n",
+ io_lib:format("method = ~p", [Method])],
+ Stack};
+
+
+
+ssh_dbg_format(authentication, Unhandled, Stack) ->
+ case Unhandled of
+ {call, {?MODULE,_F,_Args}} -> ok;
+ {return_from, {?MODULE,_F,_A}, _Resp} -> ok
+ end,
+ {["UNHANDLED AUTH FORMAT\n",
+ io_lib:format("Unhandled = ~p~nStack = ~p", [Unhandled,Stack])],
+ Stack}.
+
+
+%%% Dbg helpers ----------------
+
+
+fmt_req(#ssh_msg_userauth_request{user = User,
+ service = "ssh-connection",
+ method = Method,
+ data = Data},
+ #ssh{kb_tries_left = KbTriesLeft,
+ userauth_supported_methods = Methods}) ->
+ [io_lib:format("req user = ~p~n"
+ "req method = ~p~n"
+ "supported methods = ~p",
+ [User,Method,Methods]),
+ case Method of
+ "none" -> "";
+ "password" -> fmt_bool(Data);
+ "keyboard-interactive" -> fmt_kb_tries_left(KbTriesLeft);
+ "publickey" -> [case Data of
+ <<?BYTE(_), ?UINT32(ALen), Alg:ALen/binary, _/binary>> ->
+ io_lib:format("~nkey-type = ~p", [Alg]);
+ _ ->
+ ""
+ end];
+ _ -> ""
+ end].
+
+
+fmt_kb_tries_left(N) when is_integer(N)->
+ io_lib:format("~ntries left = ~p", [N-1]).
+
+
+fmt_bool(<<?BYTE(Bool),_/binary>>) ->
+ io_lib:format("~nBool = ~s",
+ [case Bool of
+ ?TRUE -> "true";
+ ?FALSE -> "false";
+ _ -> io_lib:format("? (~p)",[Bool])
+ end]);
+fmt_bool(<<>>) ->
+ "".
+
+
+
diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl
index d6c8cf84ed..729ce67968 100644
--- a/lib/ssh/src/ssh_cli.erl
+++ b/lib/ssh/src/ssh_cli.erl
@@ -663,6 +663,9 @@ ssh_dbg_off(terminate) -> dbg:ctpg(?MODULE, terminate, 2).
ssh_dbg_format(terminate, {call, {?MODULE,terminate, [Reason, State]}}) ->
["Cli Terminating:\n",
io_lib:format("Reason: ~p,~nState:~n~s", [Reason, wr_record(State)])
- ].
+ ];
+ssh_dbg_format(terminate, {return_from, {?MODULE,terminate,2}, _Ret}) ->
+ skip.
+
?wr_record(state).
diff --git a/lib/ssh/src/ssh_client_channel.erl b/lib/ssh/src/ssh_client_channel.erl
index 6de897e1b2..5ffdf49e9b 100644
--- a/lib/ssh/src/ssh_client_channel.erl
+++ b/lib/ssh/src/ssh_client_channel.erl
@@ -419,12 +419,16 @@ ssh_dbg_format(channels, {return_from, {?MODULE,init,1}, {stop,Reason}}) ->
["Server Channel Start FAILED!\n",
io_lib:format("Reason = ~p", [Reason])
];
+
ssh_dbg_format(channels, F) ->
ssh_dbg_format(terminate, F);
+
ssh_dbg_format(terminate, {call, {?MODULE,terminate, [Reason, State]}}) ->
["Server Channel Terminating:\n",
io_lib:format("Reason: ~p,~nState:~n~s", [Reason, wr_record(State)])
];
+ssh_dbg_format(terminate, {return_from, {?MODULE,terminate,2}, _Ret}) ->
+ skip;
ssh_dbg_format(channel_events, {call, {?MODULE,handle_call, [Call,From,State]}}) ->
[hdr("is called", State),
@@ -434,6 +438,7 @@ ssh_dbg_format(channel_events, {return_from, {?MODULE,handle_call,3}, Ret}) ->
["Server Channel call returned:\n",
io_lib:format("~p~n", [ssh_dbg:reduce_state(Ret)])
];
+
ssh_dbg_format(channel_events, {call, {?MODULE,handle_cast, [Cast,State]}}) ->
[hdr("got cast", State),
io_lib:format("Cast: ~p~n", [Cast])
@@ -442,6 +447,7 @@ ssh_dbg_format(channel_events, {return_from, {?MODULE,handle_cast,2}, Ret}) ->
["Server Channel cast returned:\n",
io_lib:format("~p~n", [ssh_dbg:reduce_state(Ret)])
];
+
ssh_dbg_format(channel_events, {call, {?MODULE,handle_info, [Info,State]}}) ->
[hdr("got info", State),
io_lib:format("Info: ~p~n", [Info])
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 3ad7c182d5..5e5ed9b79a 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -63,7 +63,8 @@
adjust_window/3, close/2,
disconnect/4,
get_print_info/1,
- set_sock_opts/2, get_sock_opts/2
+ set_sock_opts/2, get_sock_opts/2,
+ prohibited_sock_option/1
]).
-type connection_ref() :: ssh:connection_ref().
@@ -365,11 +366,11 @@ retrieve(ConnectionHandler, Key) ->
%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
set_sock_opts(ConnectionRef, SocketOptions) ->
try lists:foldr(fun({Name,_Val}, Acc) ->
- case lists:member(Name, [active, deliver, mode, packet]) of
+ case prohibited_sock_option(Name) of
true -> [Name|Acc];
false -> Acc
end
- end, [], SocketOptions)
+ end, [], SocketOptions)
of
[] ->
call(ConnectionRef, {set_sock_opts,SocketOptions});
@@ -380,6 +381,12 @@ set_sock_opts(ConnectionRef, SocketOptions) ->
{error, badarg}
end.
+prohibited_sock_option(active) -> true;
+prohibited_sock_option(deliver) -> true;
+prohibited_sock_option(mode) -> true;
+prohibited_sock_option(packet) -> true;
+prohibited_sock_option(_) -> false.
+
%%--------------------------------------------------------------------
%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
get_sock_opts(ConnectionRef, SocketGetOptions) ->
@@ -818,13 +825,13 @@ handle_event(_, #ssh_msg_kex_dh_gex_reply{} = Msg, {key_exchange_dh_gex_reply,cl
%%% ######## {new_keys, client|server} ####
%% First key exchange round:
-handle_event(_, #ssh_msg_newkeys{} = Msg, {new_keys,client,init}, D) ->
- {ok, Ssh1} = ssh_transport:handle_new_keys(Msg, D#data.ssh_params),
+handle_event(_, #ssh_msg_newkeys{} = Msg, {new_keys,client,init}, D0) ->
+ {ok, Ssh1} = ssh_transport:handle_new_keys(Msg, D0#data.ssh_params),
%% {ok, ExtInfo, Ssh2} = ssh_transport:ext_info_message(Ssh1),
- %% send_bytes(ExtInfo, D),
+ %% send_bytes(ExtInfo, D0),
{MsgReq, Ssh} = ssh_auth:service_request_msg(Ssh1),
- send_bytes(MsgReq, D),
- {next_state, {ext_info,client,init}, D#data{ssh_params=Ssh}};
+ D = send_msg(MsgReq, D0#data{ssh_params = Ssh}),
+ {next_state, {ext_info,client,init}, D};
handle_event(_, #ssh_msg_newkeys{} = Msg, {new_keys,server,init}, D) ->
{ok, Ssh} = ssh_transport:handle_new_keys(Msg, D#data.ssh_params),
@@ -870,8 +877,8 @@ handle_event(_, Msg = #ssh_msg_service_request{name=ServiceName}, StateName = {s
"ssh-userauth" ->
Ssh0 = #ssh{session_id=SessionId} = D0#data.ssh_params,
{ok, {Reply, Ssh}} = ssh_auth:handle_userauth_request(Msg, SessionId, Ssh0),
- send_bytes(Reply, D0),
- {next_state, {userauth,server}, D0#data{ssh_params = Ssh}};
+ D = send_msg(Reply, D0#data{ssh_params = Ssh}),
+ {next_state, {userauth,server}, D};
_ ->
{Shutdown, D} =
@@ -882,10 +889,12 @@ handle_event(_, Msg = #ssh_msg_service_request{name=ServiceName}, StateName = {s
end;
handle_event(_, #ssh_msg_service_accept{name = "ssh-userauth"}, {service_request,client},
- #data{ssh_params = #ssh{service="ssh-userauth"} = Ssh0} = State) ->
+ #data{ssh_params = #ssh{service="ssh-userauth"} = Ssh0} = D0) ->
{Msg, Ssh} = ssh_auth:init_userauth_request_msg(Ssh0),
- send_bytes(Msg, State),
- {next_state, {userauth,client}, State#data{auth_user = Ssh#ssh.user, ssh_params = Ssh}};
+ D = send_msg(Msg, D0#data{ssh_params = Ssh,
+ auth_user = Ssh#ssh.user
+ }),
+ {next_state, {userauth,client}, D};
%%% ######## {userauth, client|server} ####
@@ -901,8 +910,8 @@ handle_event(_,
%% Probably the very first userauth_request but we deny unauthorized login
{not_authorized, _, {Reply,Ssh}} =
ssh_auth:handle_userauth_request(Msg, Ssh0#ssh.session_id, Ssh0),
- send_bytes(Reply, D0),
- {keep_state, D0#data{ssh_params = Ssh}};
+ D = send_msg(Reply, D0#data{ssh_params = Ssh}),
+ {keep_state, D};
{"ssh-connection", "ssh-connection", Method} ->
%% Userauth request with a method like "password" or so
@@ -910,21 +919,24 @@ handle_event(_,
true ->
%% Yepp! we support this method
case ssh_auth:handle_userauth_request(Msg, Ssh0#ssh.session_id, Ssh0) of
- {authorized, User, {Reply, Ssh}} ->
- send_bytes(Reply, D0),
- D0#data.starter ! ssh_connected,
- connected_fun(User, Method, D0),
+ {authorized, User, {Reply, Ssh1}} ->
+ D = #data{ssh_params=Ssh} =
+ send_msg(Reply, D0#data{ssh_params = Ssh1}),
+ D#data.starter ! ssh_connected,
+ connected_fun(User, Method, D),
{next_state, {connected,server},
- D0#data{auth_user = User,
- ssh_params = Ssh#ssh{authenticated = true}}};
+ D#data{auth_user=User,
+ %% Note: authenticated=true MUST NOT be sent
+ %% before send_msg!
+ ssh_params = Ssh#ssh{authenticated = true}}};
{not_authorized, {User, Reason}, {Reply, Ssh}} when Method == "keyboard-interactive" ->
retry_fun(User, Reason, D0),
- send_bytes(Reply, D0),
- {next_state, {userauth_keyboard_interactive,server}, D0#data{ssh_params = Ssh}};
+ D = send_msg(Reply, D0#data{ssh_params = Ssh}),
+ {next_state, {userauth_keyboard_interactive,server}, D};
{not_authorized, {User, Reason}, {Reply, Ssh}} ->
retry_fun(User, Reason, D0),
- send_bytes(Reply, D0),
- {keep_state, D0#data{ssh_params = Ssh}}
+ D = send_msg(Reply, D0#data{ssh_params = Ssh}),
+ {keep_state, D}
end;
false ->
%% No we do not support this method (=/= none)
@@ -952,6 +964,7 @@ handle_event(_, #ssh_msg_ext_info{}=Msg, {userauth,client}, D0) ->
{keep_state, D};
handle_event(_, #ssh_msg_userauth_success{}, {userauth,client}, D=#data{ssh_params = Ssh}) ->
+ ssh_auth:ssh_msg_userauth_result(success),
D#data.starter ! ssh_connected,
{next_state, {connected,client}, D#data{ssh_params=Ssh#ssh{authenticated = true}}};
@@ -983,11 +996,11 @@ handle_event(_, #ssh_msg_userauth_failure{authentications = Methods}, StateName=
StateName, D0#data{ssh_params = Ssh}),
{stop, Shutdown, D};
{"keyboard-interactive", {Msg, Ssh}} ->
- send_bytes(Msg, D0),
- {next_state, {userauth_keyboard_interactive,client}, D0#data{ssh_params = Ssh}};
+ D = send_msg(Msg, D0#data{ssh_params = Ssh}),
+ {next_state, {userauth_keyboard_interactive,client}, D};
{_Method, {Msg, Ssh}} ->
- send_bytes(Msg, D0),
- {keep_state, D0#data{ssh_params = Ssh}}
+ D = send_msg(Msg, D0#data{ssh_params = Ssh}),
+ {keep_state, D}
end;
%%---- banner to client
@@ -1002,39 +1015,46 @@ handle_event(_, #ssh_msg_userauth_banner{message = Msg}, {userauth,client}, D) -
%%% ######## {userauth_keyboard_interactive, client|server}
handle_event(_, #ssh_msg_userauth_info_request{} = Msg, {userauth_keyboard_interactive, client},
- #data{ssh_params = Ssh0} = D) ->
+ #data{ssh_params = Ssh0} = D0) ->
case ssh_auth:handle_userauth_info_request(Msg, Ssh0) of
{ok, {Reply, Ssh}} ->
- send_bytes(Reply, D),
- {next_state, {userauth_keyboard_interactive_info_response,client}, D#data{ssh_params = Ssh}};
+ D = send_msg(Reply, D0#data{ssh_params = Ssh}),
+ {next_state, {userauth_keyboard_interactive_info_response,client}, D};
not_ok ->
- {next_state, {userauth,client}, D, [postpone]}
+ {next_state, {userauth,client}, D0, [postpone]}
end;
-handle_event(_, #ssh_msg_userauth_info_response{} = Msg, {userauth_keyboard_interactive, server}, D) ->
- case ssh_auth:handle_userauth_info_response(Msg, D#data.ssh_params) of
- {authorized, User, {Reply, Ssh}} ->
- send_bytes(Reply, D),
+handle_event(_, #ssh_msg_userauth_info_response{} = Msg, {userauth_keyboard_interactive, server}, D0) ->
+ case ssh_auth:handle_userauth_info_response(Msg, D0#data.ssh_params) of
+ {authorized, User, {Reply, Ssh1}} ->
+ D = #data{ssh_params=Ssh} =
+ send_msg(Reply, D0#data{ssh_params = Ssh1}),
D#data.starter ! ssh_connected,
connected_fun(User, "keyboard-interactive", D),
{next_state, {connected,server}, D#data{auth_user = User,
+ %% Note: authenticated=true MUST NOT be sent
+ %% before send_msg!
ssh_params = Ssh#ssh{authenticated = true}}};
{not_authorized, {User, Reason}, {Reply, Ssh}} ->
- retry_fun(User, Reason, D),
- send_bytes(Reply, D),
- {next_state, {userauth,server}, D#data{ssh_params = Ssh}};
+ retry_fun(User, Reason, D0),
+ D = send_msg(Reply, D0#data{ssh_params = Ssh}),
+ {next_state, {userauth,server}, D};
{authorized_but_one_more, _User, {Reply, Ssh}} ->
- send_bytes(Reply, D),
- {next_state, {userauth_keyboard_interactive_extra,server}, D#data{ssh_params = Ssh}}
+ D = send_msg(Reply, D0#data{ssh_params = Ssh}),
+ {next_state, {userauth_keyboard_interactive_extra,server}, D}
end;
-handle_event(_, #ssh_msg_userauth_info_response{} = Msg, {userauth_keyboard_interactive_extra, server}, D) ->
- {authorized, User, {Reply, Ssh}} = ssh_auth:handle_userauth_info_response({extra,Msg}, D#data.ssh_params),
- send_bytes(Reply, D),
+handle_event(_, #ssh_msg_userauth_info_response{} = Msg, {userauth_keyboard_interactive_extra, server}, D0) ->
+ {authorized, User, {Reply, Ssh1}} =
+ ssh_auth:handle_userauth_info_response({extra,Msg}, D0#data.ssh_params),
+ D = #data{ssh_params=Ssh} =
+ send_msg(Reply, D0#data{ssh_params = Ssh1}),
D#data.starter ! ssh_connected,
connected_fun(User, "keyboard-interactive", D),
{next_state, {connected,server}, D#data{auth_user = User,
+ %% Note: authenticated=true MUST NOT be sent
+ %% before send_msg!
ssh_params = Ssh#ssh{authenticated = true}}};
handle_event(_, #ssh_msg_userauth_failure{}, {userauth_keyboard_interactive, client},
@@ -1144,17 +1164,17 @@ handle_event(internal, {conn_msg,Msg}, StateName, #data{starter = User,
end;
-handle_event(enter, _OldState, {connected,_}=State, D) ->
+handle_event(enter, OldState, {connected,_}=NewState, D) ->
%% Entering the state where re-negotiation is possible
- init_renegotiate_timers(State, D);
+ init_renegotiate_timers(OldState, NewState, D);
-handle_event(enter, _OldState, {ext_info,_,renegotiate}=State, D) ->
+handle_event(enter, OldState, {ext_info,_,renegotiate}=NewState, D) ->
%% Could be hanging in exit_info state if nothing else arrives
- init_renegotiate_timers(State, D);
+ init_renegotiate_timers(OldState, NewState, D);
-handle_event(enter, {connected,_}, State, D) ->
+handle_event(enter, {connected,_}=OldState, NewState, D) ->
%% Exiting the state where re-negotiation is possible
- pause_renegotiate_timers(State, D);
+ pause_renegotiate_timers(OldState, NewState, D);
handle_event(cast, force_renegotiate, StateName, D) ->
handle_event({timeout,renegotiate}, undefined, StateName, D);
@@ -2112,25 +2132,32 @@ start_rekeying(Role, D0) ->
{next_state, {kexinit,Role,renegotiate}, D}.
-init_renegotiate_timers(State, D) ->
+init_renegotiate_timers(_OldState, NewState, D) ->
{RekeyTimeout,_MaxSent} = ?GET_OPT(rekey_limit, (D#data.ssh_params)#ssh.opts),
- {next_state, State, D, [{{timeout,renegotiate}, RekeyTimeout, none},
- {{timeout,check_data_size}, ?REKEY_DATA_TIMOUT, none} ]}.
+ {next_state, NewState, D, [{{timeout,renegotiate}, RekeyTimeout, none},
+ {{timeout,check_data_size}, ?REKEY_DATA_TIMOUT, none} ]}.
-pause_renegotiate_timers(State, D) ->
- {next_state, State, D, [{{timeout,renegotiate}, infinity, none},
- {{timeout,check_data_size}, infinity, none} ]}.
+pause_renegotiate_timers(_OldState, NewState, D) ->
+ {next_state, NewState, D, [{{timeout,renegotiate}, infinity, none},
+ {{timeout,check_data_size}, infinity, none} ]}.
check_data_rekeying(Role, D) ->
- {ok, [{send_oct,SocketSentTotal}]} = inet:getstat(D#data.socket, [send_oct]),
- SentSinceRekey = SocketSentTotal - D#data.last_size_rekey,
- {_RekeyTimeout,MaxSent} = ?GET_OPT(rekey_limit, (D#data.ssh_params)#ssh.opts),
- case check_data_rekeying_dbg(SentSinceRekey, MaxSent) of
- true ->
- start_rekeying(Role, D#data{last_size_rekey = SocketSentTotal});
- _ ->
- %% Not enough data sent for a re-negotiation. Restart timer.
+ case inet:getstat(D#data.socket, [send_oct]) of
+ {ok, [{send_oct,SocketSentTotal}]} ->
+ SentSinceRekey = SocketSentTotal - D#data.last_size_rekey,
+ {_RekeyTimeout,MaxSent} = ?GET_OPT(rekey_limit, (D#data.ssh_params)#ssh.opts),
+ case check_data_rekeying_dbg(SentSinceRekey, MaxSent) of
+ true ->
+ start_rekeying(Role, D#data{last_size_rekey = SocketSentTotal});
+ _ ->
+ %% Not enough data sent for a re-negotiation. Restart timer.
+ {keep_state, D, {{timeout,check_data_size}, ?REKEY_DATA_TIMOUT, none}}
+ end;
+ {error,_} ->
+ %% Socket closed, but before this module has handled that. Maybe
+ %% it is in the message queue.
+ %% Just go on like if there was not enough data transmitted to start re-keying:
{keep_state, D, {{timeout,check_data_size}, ?REKEY_DATA_TIMOUT, none}}
end.
@@ -2489,20 +2516,22 @@ ssh_dbg_flags(disconnect) -> [c].
ssh_dbg_on(connections) -> dbg:tp(?MODULE, init_connection_handler, 3, x),
ssh_dbg_on(terminate);
ssh_dbg_on(connection_events) -> dbg:tp(?MODULE, handle_event, 4, x);
-ssh_dbg_on(renegotiation) -> dbg:tpl(?MODULE, init_renegotiate_timers, 2, x),
- dbg:tpl(?MODULE, pause_renegotiate_timers, 2, x),
+ssh_dbg_on(renegotiation) -> dbg:tpl(?MODULE, init_renegotiate_timers, 3, x),
+ dbg:tpl(?MODULE, pause_renegotiate_timers, 3, x),
dbg:tpl(?MODULE, check_data_rekeying_dbg, 2, x),
- dbg:tpl(?MODULE, start_rekeying, 2, x);
+ dbg:tpl(?MODULE, start_rekeying, 2, x),
+ dbg:tp(?MODULE, renegotiate, 1, x);
ssh_dbg_on(terminate) -> dbg:tp(?MODULE, terminate, 3, x);
ssh_dbg_on(disconnect) -> dbg:tpl(?MODULE, send_disconnect, 7, x).
ssh_dbg_off(disconnect) -> dbg:ctpl(?MODULE, send_disconnect, 7);
ssh_dbg_off(terminate) -> dbg:ctpg(?MODULE, terminate, 3);
-ssh_dbg_off(renegotiation) -> dbg:ctpl(?MODULE, init_renegotiate_timers, 2),
- dbg:ctpl(?MODULE, pause_renegotiate_timers, 2),
+ssh_dbg_off(renegotiation) -> dbg:ctpl(?MODULE, init_renegotiate_timers, 3),
+ dbg:ctpl(?MODULE, pause_renegotiate_timers, 3),
dbg:ctpl(?MODULE, check_data_rekeying_dbg, 2),
- dbg:ctpl(?MODULE, start_rekeying, 2);
+ dbg:ctpl(?MODULE, start_rekeying, 2),
+ dbg:ctpg(?MODULE, renegotiate, 1);
ssh_dbg_off(connection_events) -> dbg:ctpg(?MODULE, handle_event, 4);
ssh_dbg_off(connections) -> dbg:ctpg(?MODULE, init_connection_handler, 3),
ssh_dbg_off(terminate).
@@ -2541,22 +2570,46 @@ ssh_dbg_format(connection_events, {return_from, {?MODULE,handle_event,4}, Ret})
io_lib:format("~p~n", [event_handler_result(Ret)])
];
-ssh_dbg_format(renegotiation, {call, {?MODULE,init_renegotiate_timers,[_State,D]}}) ->
- ["Renegotiation init\n",
- io_lib:format("rekey_limit: ~p ({ms,bytes})~ncheck_data_size: ~p (ms)~n",
- [?GET_OPT(rekey_limit, (D#data.ssh_params)#ssh.opts),
+ssh_dbg_format(renegotiation, {call, {?MODULE,init_renegotiate_timers,[OldState,NewState,D]}}) ->
+ ["Renegotiation: start timer (init_renegotiate_timers)\n",
+ io_lib:format("State: ~p --> ~p~n"
+ "rekey_limit: ~p ({ms,bytes})~n"
+ "check_data_size: ~p (ms)~n",
+ [OldState, NewState,
+ ?GET_OPT(rekey_limit, (D#data.ssh_params)#ssh.opts),
?REKEY_DATA_TIMOUT])
];
-ssh_dbg_format(renegotiation, {call, {?MODULE,pause_renegotiate_timers,[_State,_D]}}) ->
- ["Renegotiation pause\n"];
+ssh_dbg_format(renegotiation, {return_from, {?MODULE,init_renegotiate_timers,3}, _Ret}) ->
+ skip;
+
+ssh_dbg_format(renegotiation, {call, {?MODULE,renegotiate,[ConnectionHandler]}}) ->
+ ["Renegotiation: renegotiation forced\n",
+ io_lib:format("~p:renegotiate(~p) called~n",
+ [?MODULE,ConnectionHandler])
+ ];
+ssh_dbg_format(renegotiation, {return_from, {?MODULE,renegotiate,1}, _Ret}) ->
+ skip;
+
+ssh_dbg_format(renegotiation, {call, {?MODULE,pause_renegotiate_timers,[OldState,NewState,_D]}}) ->
+ ["Renegotiation: pause timers\n",
+ io_lib:format("State: ~p --> ~p~n",
+ [OldState, NewState])
+ ];
+ssh_dbg_format(renegotiation, {return_from, {?MODULE,pause_renegotiate_timers,3}, _Ret}) ->
+ skip;
+
ssh_dbg_format(renegotiation, {call, {?MODULE,start_rekeying,[_Role,_D]}}) ->
- ["Renegotiation start rekeying\n"];
+ ["Renegotiation: start rekeying\n"];
+ssh_dbg_format(renegotiation, {return_from, {?MODULE,start_rekeying,2}, _Ret}) ->
+ skip;
+
ssh_dbg_format(renegotiation, {call, {?MODULE,check_data_rekeying_dbg,[SentSinceRekey, MaxSent]}}) ->
- ["Renegotiation check data sent\n",
+ ["Renegotiation: check size of data sent\n",
io_lib:format("TotalSentSinceRekey: ~p~nMaxBeforeRekey: ~p~nStartRekey: ~p~n",
[SentSinceRekey, MaxSent, SentSinceRekey >= MaxSent])
];
-
+ssh_dbg_format(renegotiation, {return_from, {?MODULE,check_data_rekeying_dbg,2}, _Ret}) ->
+ skip;
ssh_dbg_format(terminate, {call, {?MODULE,terminate, [Reason, StateName, D]}}) ->
@@ -2591,6 +2644,8 @@ ssh_dbg_format(terminate, {call, {?MODULE,terminate, [Reason, StateName, D]}}) -
[Reason, StateName, ExtraInfo, state_data2proplist(D)])
]
end;
+ssh_dbg_format(renegotiation, {return_from, {?MODULE,terminate,3}, _Ret}) ->
+ skip;
ssh_dbg_format(disconnect, {call,{?MODULE,send_disconnect,
[Code, Reason, DetailedText, Module, Line, StateName, _D]}}) ->
@@ -2600,7 +2655,9 @@ ssh_dbg_format(disconnect, {call,{?MODULE,send_disconnect,
" DetailedText =~n"
" ~p",
[Module, Line, StateName, Code, Reason, lists:flatten(DetailedText)])
- ].
+ ];
+ssh_dbg_format(renegotiation, {return_from, {?MODULE,send_disconnect,7}, _Ret}) ->
+ skip.
event_handler_result({next_state, NextState, _NewData}) ->
diff --git a/lib/ssh/src/ssh_dbg.erl b/lib/ssh/src/ssh_dbg.erl
index 1809b14099..f8391224f8 100644
--- a/lib/ssh/src/ssh_dbg.erl
+++ b/lib/ssh/src/ssh_dbg.erl
@@ -54,6 +54,8 @@
start_tracer/0, start_tracer/1,
on/1, on/0,
off/1, off/0,
+ is_on/0,
+ is_off/0,
go_on/0,
%% Circular buffer
cbuf_start/0, cbuf_start/1,
@@ -70,6 +72,9 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
+%% Internal apply_after:
+-export([ets_delete/2]).
+
-include("ssh.hrl").
-include("ssh_transport.hrl").
-include("ssh_connect.hrl").
@@ -82,12 +87,16 @@
-type trace_point() :: atom().
-type trace_points() :: [trace_point()].
+-type stack() :: list(term()).
-callback ssh_dbg_trace_points() -> trace_points().
-callback ssh_dbg_flags(trace_point()) -> [atom()].
-callback ssh_dbg_on(trace_point() | trace_points()) -> term().
-callback ssh_dbg_off(trace_point() | trace_points()) -> term().
--callback ssh_dbg_format(trace_point(), term()) -> iolist().
+-callback ssh_dbg_format(trace_point(), term()) -> iolist() | skip.
+-callback ssh_dbg_format(trace_point(), term(), stack()) -> {iolist() | skip, stack()}.
+
+-optional_callbacks([ssh_dbg_format/2, ssh_dbg_format/3]). % At least one of them are to be used
%%%================================================================
@@ -134,10 +143,13 @@ start_tracer(WriteFun, InitAcc) when is_function(WriteFun, 3) ->
%%%----------------------------------------------------------------
on() -> on(?ALL_DBG_TYPES).
on(Type) -> switch(on, Type).
-
+is_on() -> gen_server:call(?SERVER, get_on, ?CALL_TIMEOUT).
+
off() -> off(?ALL_DBG_TYPES). % A bit overkill...
off(Type) -> switch(off, Type).
+is_off() -> ?ALL_DBG_TYPES -- is_on().
+
go_on() ->
IsOn = gen_server:call(?SERVER, get_on, ?CALL_TIMEOUT),
@@ -174,8 +186,42 @@ reduce_state(T) ->
%%%----------------------------------------------------------------
init(_) ->
+ new_table(),
{ok, #data{}}.
+
+new_table() ->
+ try
+ ets:new(?MODULE, [public, named_table]),
+ ok
+ catch
+ exit:badarg ->
+ ok
+ end.
+
+
+get_proc_stack(Pid) when is_pid(Pid) ->
+ try ets:lookup_element(?MODULE, Pid, 2)
+ catch
+ error:badarg ->
+ %% Non-existing item
+ new_proc(Pid),
+ ets:insert(?MODULE, {Pid,[]}),
+ []
+ end.
+
+
+put_proc_stack(Pid, Data) when is_pid(Pid),
+ is_list(Data) ->
+ ets:insert(?MODULE, {Pid,Data}).
+
+
+new_proc(Pid) when is_pid(Pid) ->
+ gen_server:cast(?SERVER, {new_proc,Pid}).
+
+ets_delete(Tab, Key) ->
+ catch ets:delete(Tab, Key).
+
%%%----------------------------------------------------------------
handle_call({switch,on,Types}, _From, D) ->
NowOn = lists:usort(Types ++ D#data.types_on),
@@ -196,10 +242,20 @@ handle_call(C, _From, D) ->
{reply, {error,{unknown_call,C}}, D}.
+handle_cast({new_proc,Pid}, D) ->
+ monitor(process, Pid),
+ {noreply, D};
+
handle_cast(C, D) ->
io:format('*** Unknown cast: ~p~n',[C]),
{noreply, D}.
+
+handle_info({'DOWN', _MonitorRef, process, Pid, _Info}, D) ->
+ %% Universal real-time synchronization (there might be dbg msgs in the queue to the tracer):
+ timer:apply_after(20000, ?MODULE, ets_delete, [?MODULE, Pid]),
+ {noreply, D};
+
handle_info(C, D) ->
io:format('*** Unknown info: ~p~n',[C]),
{noreply, D}.
@@ -320,20 +376,60 @@ try_all_types_in_all_modules(TypesOn, Arg, WriteFun, Acc0) ->
TS = trace_ts(Arg),
PID = trace_pid(Arg),
INFO = trace_info(Arg),
- lists:foldl(
- fun(Type, Acc1) ->
- lists:foldl(
- fun(SshMod,Acc) ->
- try WriteFun("~n~s ~p ~s~n",
- [lists:flatten(TS),
- PID,
- lists:flatten(SshMod:ssh_dbg_format(Type, INFO))],
- Acc)
- catch
- _:_ -> Acc
- end
- end, Acc1, SshModules)
- end, Acc0, TypesOn).
+ Acc =
+ lists:foldl(
+ fun(Type, Acc1) ->
+ lists:foldl(
+ fun(SshMod,Acc) ->
+ try
+ %% First, call without stack
+ SshMod:ssh_dbg_format(Type, INFO)
+ of
+ skip ->
+ %% Don't try to print this later
+ written;
+ Txt when is_list(Txt) ->
+ write_txt(WriteFun, TS, PID, Txt)
+ catch
+ error:E when E==undef ; E==function_clause ; element(1,E)==case_clause ->
+ try
+ %% then, call with stack
+ STACK = get_proc_stack(PID),
+ SshMod:ssh_dbg_format(Type, INFO, STACK)
+ of
+ {skip, NewStack} ->
+ %% Don't try to print this later
+ put_proc_stack(PID, NewStack),
+ written;
+ {Txt, NewStack} when is_list(Txt) ->
+ put_proc_stack(PID, NewStack),
+ write_txt(WriteFun, TS, PID, Txt)
+ catch
+ _:_ ->
+ %% and finally, signal for special formatting
+ %% if noone else formats it
+ Acc
+ end
+ end
+ end, Acc1, SshModules)
+ end, Acc0, TypesOn),
+ case Acc of
+ Acc0 ->
+ %% INFO :: any()
+ WriteFun("~n~s ~p DEBUG~n~p~n", [lists:flatten(TS),PID,INFO], Acc0);
+ written ->
+ Acc0
+ end.
+
+
+
+write_txt(WriteFun, TS, PID, Txt) when is_list(Txt) ->
+ WriteFun("~n~s ~p ~s~n",
+ [lists:flatten(TS),
+ PID,
+ lists:flatten(Txt)],
+ written % this is returned
+ ).
%%%----------------------------------------------------------------
wr_record(T, Fs, BL) when is_tuple(T) ->
diff --git a/lib/ssh/src/ssh_message.erl b/lib/ssh/src/ssh_message.erl
index 30b0c89144..804775bd75 100644
--- a/lib/ssh/src/ssh_message.erl
+++ b/lib/ssh/src/ssh_message.erl
@@ -762,15 +762,26 @@ ssh_dbg_format(ssh_messages, {call,{?MODULE,encode,[Msg]}}) ->
["Going to send ",Name,":\n",
wr_record(ssh_dbg:shrink_bin(Msg))
];
+ssh_dbg_format(ssh_messages, {return_from, {?MODULE,encode,1}, _Ret}) ->
+ skip;
+
+ssh_dbg_format(ssh_messages, {call, {?MODULE,decode,[_]}}) ->
+ skip;
ssh_dbg_format(ssh_messages, {return_from,{?MODULE,decode,1},Msg}) ->
Name = string:to_upper(atom_to_list(element(1,Msg))),
["Received ",Name,":\n",
wr_record(ssh_dbg:shrink_bin(Msg))
];
+
ssh_dbg_format(raw_messages, {call,{?MODULE,decode,[BytesPT]}}) ->
["Received plain text bytes (shown after decryption):\n",
io_lib:format("~p",[BytesPT])
];
+ssh_dbg_format(raw_messages, {return_from, {?MODULE,decode,1}, _Ret}) ->
+ skip;
+
+ssh_dbg_format(raw_messages, {call, {?MODULE,encode,[_]}}) ->
+ skip;
ssh_dbg_format(raw_messages, {return_from,{?MODULE,encode,1},BytesPT}) ->
["Going to send plain text bytes (shown before encryption):\n",
io_lib:format("~p",[BytesPT])
diff --git a/lib/ssh/src/ssh_options.erl b/lib/ssh/src/ssh_options.erl
index cc9ef565d8..306eb86c23 100644
--- a/lib/ssh/src/ssh_options.erl
+++ b/lib/ssh/src/ssh_options.erl
@@ -261,22 +261,20 @@ config_val(Key, RoleCnfs, Opts) ->
check_fun(Key, Defs) ->
- #{chk := Fun} = maps:get(Key, Defs),
- Fun.
+ case ssh_connection_handler:prohibited_sock_option(Key) of
+ false ->
+ #{chk := Fun} = maps:get(Key, Defs),
+ Fun;
+ true ->
+ fun(_,_) -> forbidden end
+ end.
%%%================================================================
%%%
%%% Check and save one option
%%%
-
-%%% First some prohibited inet options:
-save({K,V}, _, _) when K == reuseaddr ;
- K == active
- ->
- forbidden_option(K, V);
-
-%%% then compatibility conversions:
+%%% First compatibility conversions:
save({allow_user_interaction,V}, Opts, Vals) ->
save({user_interaction,V}, Opts, Vals);
@@ -297,7 +295,12 @@ save({Key,Value}, Defs, OptMap) when is_map(OptMap) ->
{true, ModifiedValue} ->
OptMap#{Key := ModifiedValue};
false ->
- error({eoptions, {Key,Value}, "Bad value"})
+ error({eoptions, {Key,Value}, "Bad value"});
+ forbidden ->
+ error({eoptions, {Key,Value},
+ io_lib:format("The option '~s' is used internally. The "
+ "user is not allowed to specify this option.",
+ [Key])})
catch
%% An unknown Key (= not in the definition map) is
%% regarded as an inet option:
@@ -424,7 +427,8 @@ default(server) ->
check_string(S3) andalso
is_boolean(B);
(F) ->
- check_function3(F)
+ check_function3(F) orelse
+ check_function4(F)
end,
class => user_option
},
@@ -1180,10 +1184,3 @@ error_if_empty([]) ->
ok.
%%%----------------------------------------------------------------
-forbidden_option(K,V) ->
- Txt = io_lib:format("The option '~s' is used internally. The "
- "user is not allowed to specify this option.",
- [K]),
- error({eoptions, {K,V}, Txt}).
-
-%%%----------------------------------------------------------------
diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl
index 9ee6ed68c1..69fff09979 100644
--- a/lib/ssh/src/ssh_sftp.erl
+++ b/lib/ssh/src/ssh_sftp.erl
@@ -1843,7 +1843,9 @@ ssh_dbg_off(terminate) -> dbg:ctpg(?MODULE, terminate, 2).
ssh_dbg_format(terminate, {call, {?MODULE,terminate, [Reason, State]}}) ->
["Sftp Terminating:\n",
io_lib:format("Reason: ~p,~nState:~n~s", [Reason, wr_record(State)])
- ].
+ ];
+ssh_dbg_format(terminate, {return_from, {?MODULE,terminate,2}, _Ret}) ->
+ skip.
?wr_record(state).
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index 78277705d8..158ef3d5ae 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -964,6 +964,8 @@ ssh_dbg_off(terminate) -> dbg:ctpg(?MODULE, terminate, 2).
ssh_dbg_format(terminate, {call, {?MODULE,terminate, [Reason, State]}}) ->
["SftpD Terminating:\n",
io_lib:format("Reason: ~p,~nState:~n~s", [Reason, wr_record(State)])
- ].
+ ];
+ssh_dbg_format(terminate, {return_from, {?MODULE,terminate,2}, _Ret}) ->
+ skip.
?wr_record(state).
diff --git a/lib/ssh/src/ssh_shell.erl b/lib/ssh/src/ssh_shell.erl
index b5862b2395..be8a6aa8cc 100644
--- a/lib/ssh/src/ssh_shell.erl
+++ b/lib/ssh/src/ssh_shell.erl
@@ -200,6 +200,8 @@ ssh_dbg_off(terminate) -> dbg:ctpg(?MODULE, terminate, 2).
ssh_dbg_format(terminate, {call, {?MODULE,terminate, [Reason, State]}}) ->
["Shell Terminating:\n",
io_lib:format("Reason: ~p,~nState:~n~s", [Reason, wr_record(State)])
- ].
+ ];
+ssh_dbg_format(terminate, {return_from, {?MODULE,terminate,2}, _Ret}) ->
+ skip.
?wr_record(state).
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 86d4ef951c..bd901c99e0 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -2172,18 +2172,27 @@ ssh_dbg_off(ssh_messages) -> ssh_dbg_off(hello).
+ssh_dbg_format(hello, {call,{?MODULE,hello_version_msg,[_]}}) ->
+ skip;
ssh_dbg_format(hello, {return_from,{?MODULE,hello_version_msg,1},Hello}) ->
["Going to send hello message:\n",
Hello
];
+
ssh_dbg_format(hello, {call,{?MODULE,handle_hello_version,[Hello]}}) ->
["Received hello message:\n",
Hello
];
+ssh_dbg_format(hello, {return_from,{?MODULE,handle_hello_version,1},_Ret}) ->
+ skip;
+
+ssh_dbg_format(alg, {call,{?MODULE,select_algorithm,[_,_,_,_]}}) ->
+ skip;
ssh_dbg_format(alg, {return_from,{?MODULE,select_algorithm,4},{ok,Alg}}) ->
["Negotiated algorithms:\n",
wr_record(Alg)
];
+
ssh_dbg_format(raw_messages, X) -> ssh_dbg_format(hello, X);
ssh_dbg_format(ssh_messages, X) -> ssh_dbg_format(hello, X).
diff --git a/lib/ssh/test/.gitignore b/lib/ssh/test/.gitignore
index c9d5f086b3..f0adbaf33f 100644
--- a/lib/ssh/test/.gitignore
+++ b/lib/ssh/test/.gitignore
@@ -1,4 +1,6 @@
+*COVER.html
+ssh_sftp_SUITE_data/test_data*
property_test/ssh_eqc_client_server_dirs/system
property_test/ssh_eqc_client_server_dirs/user
diff --git a/lib/ssh/test/Makefile b/lib/ssh/test/Makefile
index aafec6566e..9862071b5f 100644
--- a/lib/ssh/test/Makefile
+++ b/lib/ssh/test/Makefile
@@ -46,6 +46,7 @@ MODULES= \
ssh_protocol_SUITE \
ssh_property_test_SUITE \
ssh_pubkey_SUITE \
+ ssh_renegotiate_SUITE \
ssh_sftp_SUITE \
ssh_sftpd_SUITE \
ssh_sftpd_erlclient_SUITE \
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server.erl b/lib/ssh/test/property_test/ssh_eqc_client_server.erl
index e0b739ab53..66a79c8a17 100644
--- a/lib/ssh/test/property_test/ssh_eqc_client_server.erl
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server.erl
@@ -480,12 +480,9 @@ setup_rsa(Dir) ->
erase_dir(user_dir(Dir)),
file:make_dir(system_dir(Dir)),
file:make_dir(user_dir(Dir)),
-
- file:copy(data_dir(Dir,"id_rsa"), user_dir(Dir,"id_rsa")),
- file:copy(data_dir(Dir,"ssh_host_rsa_key"), system_dir(Dir,"ssh_host_rsa_key")),
- file:copy(data_dir(Dir,"ssh_host_rsa_key"), system_dir(Dir,"ssh_host_rsa_key.pub")),
- ssh_test_lib:setup_rsa_known_host(data_dir(Dir), user_dir(Dir)),
- ssh_test_lib:setup_rsa_auth_keys(data_dir(Dir), user_dir(Dir)).
+ ct:log("Dir = ~p~ndata_dir = ~p~nsystem_dir = ~p~nuser = ~p~n",
+ [Dir,data_dir(Dir),system_dir(Dir),user_dir(Dir)]),
+ ssh_test_lib:setup_all_user_host_keys( data_dir(Dir), user_dir(Dir), system_dir(Dir)).
data_dir(Dir, File) -> filename:join(Dir, File).
system_dir(Dir, File) -> filename:join([Dir, "system", File]).
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa
index d306f8b26e..24628e071b 100644
--- a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa
@@ -1,13 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
-MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
-APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
-/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
-kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
-JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
-OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
-+9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
-uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
-Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
-ZU8w8Q+H7z0j+a+70x2iAw==
+MIIBuwIBAAKBgQDIywHurUpOq6kZuMn+XlRzR4hAxF6qwSkuEqkV7iHnLQ0kIwf3
+uAmjFDhuEsQ8653SLxGVvTNp+KFFgDXiLqgM7TPUwDnpbvzEZHPAU+/zPt4sdY2D
+txBfJwT2SFlK6HPOxOcxdDuD+/a59sh8hk/YVOU7ZTcBVsVG8Got4UcF5QIVAPGd
+CPDQKSTlPiM9OwBB1+9p11k5AoGARLxw4l17mET9cU0uf4Ppe5nsCbODJv44ZrSs
+picvypGVLrLcN5KWbm3vjRFCQ5LFunAG3FwLC2Sh0CH6TemoIfRPsRHR7wvpBGdr
+c693UlMOis/mcmvNMQAzuQNW9WrxdzsvWR/r5s6NEHWqKUJGXSPi2d+Ijq/mCOmI
+hzLzyiACgYEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4
+cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+C
+ROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNgCFEjA7wTC
+sQCY/I35vb6GUJn9tEdP
-----END DSA PRIVATE KEY-----
-
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa.pub
new file mode 100644
index 0000000000..018ef6f537
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_dsa.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAMjLAe6tSk6rqRm4yf5eVHNHiEDEXqrBKS4SqRXuIectDSQjB/e4CaMUOG4SxDzrndIvEZW9M2n4oUWANeIuqAztM9TAOelu/MRkc8BT7/M+3ix1jYO3EF8nBPZIWUroc87E5zF0O4P79rn2yHyGT9hU5TtlNwFWxUbwai3hRwXlAAAAFQDxnQjw0Ckk5T4jPTsAQdfvaddZOQAAAIBEvHDiXXuYRP1xTS5/g+l7mewJs4Mm/jhmtKymJy/KkZUustw3kpZube+NEUJDksW6cAbcXAsLZKHQIfpN6agh9E+xEdHvC+kEZ2tzr3dSUw6Kz+Zya80xADO5A1b1avF3Oy9ZH+vmzo0QdaopQkZdI+LZ34iOr+YI6YiHMvPKIAAAAIEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+CROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNg= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa256 b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa256.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa384 b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa384
new file mode 100644
index 0000000000..4e8aa40959
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCYXb6OSAZyXRfLXOtMo43za197Hdc/T0YKjgQQjwDt6rlRwqTh7v7S
+PV2kXwNGdWigBwYFK4EEACKhZANiAARN2khlJUOOIiwsWHEALwDieeZR96qL4pUd
+ci7aeGaczdUK5jOA9D9zmBZtSYTfO8Cr7ekVghDlcWAIJ/BXcswgQwSEQ6wyfaTF
+8FYfyr4l3u9IirsnyaFzeIgeoNis8Gw=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa384.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa384.pub
new file mode 100644
index 0000000000..41e722e545
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE3aSGUlQ44iLCxYcQAvAOJ55lH3qovilR1yLtp4ZpzN1QrmM4D0P3OYFm1JhN87wKvt6RWCEOVxYAgn8FdyzCBDBIRDrDJ9pMXwVh/KviXe70iKuyfJoXN4iB6g2KzwbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa521 b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa521
new file mode 100644
index 0000000000..7196f46e97
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEFMadoz4ckEcClfqXa2tiUuYkJdDfwq+/iFQcpt8ESuEd26IY/vm47Q
+9UzbPkO4ou8xkNsQ3WvCRQBBWtn5O2kUU6AHBgUrgQQAI6GBiQOBhgAEAde5BRu5
+01/jS0jRk212xsb2DxPrxNpgp6IMCV8TA4Eps+8bSqHB091nLiBcP422HXYfuCd7
+XDjSs8ihcmhp0hCRASLqZR9EzW9W/SOt876May1Huj5X+WSO6RLe7vPn9vmf7kHf
+pip6m7M7qp2qGgQ3q2vRwS2K/O6156ohiOlmuuFs
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa521.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa521.pub
new file mode 100644
index 0000000000..8f059120bc
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHXuQUbudNf40tI0ZNtdsbG9g8T68TaYKeiDAlfEwOBKbPvG0qhwdPdZy4gXD+Nth12H7gne1w40rPIoXJoadIQkQEi6mUfRM1vVv0jrfO+jGstR7o+V/lkjukS3u7z5/b5n+5B36YqepuzO6qdqhoEN6tr0cEtivzuteeqIYjpZrrhbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed25519 b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed25519
new file mode 100644
index 0000000000..401a3e4a9a
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed25519
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDm9P8/gC0IOKmwHLSvkmEtS2Xx0RRqUDqC6wY6UgDVnwAAAJg3+6xpN/us
+aQAAAAtzc2gtZWQyNTUxOQAAACDm9P8/gC0IOKmwHLSvkmEtS2Xx0RRqUDqC6wY6UgDVnw
+AAAEBzC/Z2WGJhZ3l3tIBnUc6DCbp+lXY2yc2RRpWQTdf8sub0/z+ALQg4qbActK+SYS1L
+ZfHRFGpQOoLrBjpSANWfAAAAE3VhYmhuaWxAZWx4YWRsajNxMzIBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed25519.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed25519.pub
new file mode 100644
index 0000000000..a5c03b19c1
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed25519.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOb0/z+ALQg4qbActK+SYS1LZfHRFGpQOoLrBjpSANWf uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed448 b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed448
new file mode 100644
index 0000000000..8ecfd710dc
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed448
@@ -0,0 +1,10 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA53OqeePNaG/NJmoMbELhskKrAHNhLZ6AQm1WjbpMoseNl/OFh
+1xznExpUPqTLX36fHYsAaWRHABQAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADnc6p5481ob80magxsQuGyQqsAc2EtnoBCbVaNukyix42X84WHXHOcTGlQ+pMtf
+fp8diwBpZEcAFAAAAAByzSPST3FCdOdENDI3uTKQ9RH2Ql+Y5kRZ/yA+iYUIP/32
+BQBVOrwOBc0CGEvbicTM1n4YeVEmfrMo3OqeePNaG/NJmoMbELhskKrAHNhLZ6AQ
+m1WjbpMoseNl/OFh1xznExpUPqTLX36fHYsAaWRHABQAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed448.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed448.pub
new file mode 100644
index 0000000000..cec0765a5d
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_ed448.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADnc6p5481ob80magxsQuGyQqsAc2EtnoBCbVaNukyix42X84WHXHOcTGlQ+pMtffp8diwBpZEcAFAA= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa
index 9d7e0dd5fb..2202c2ead8 100644
--- a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa
@@ -1,15 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
-DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
-zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
-AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
-TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
-CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
-SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
-z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
-WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
-sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
-xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
-dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
-ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+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
-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa.pub
new file mode 100644
index 0000000000..b4084d320a
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDO2OLKPa11+SOLR97BZLSQAGDQgAGAbbQ28vU+cckuv3zB7vBbt/ePbsQaNb8Cm7JyxZdcqLQvzary4OJygcdvckjYmRPvSiLTIbUPH/PA8352QDssFPUndQraElMU+GnznkLBj+yz3GkGx3UW/fO4eJ8So0aWN6DU+OZDek2HED8zRplwud8hR1nkev637h6zfNpaji0sEqZm7oGRUZAo8Zd4yQgAy0mUbbiXuooNGRHlNgBlPs/xWfuGe4W4I1uslKbrzoZrAHFNBeibbd2D1RxbGgcHtSIcWhHqPRtABf7hHtsjBy6VENy/OuAK7q7TqgUgvBjsyWzGlf2EZOXX uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key256 b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key256.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key384 b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..fb1a862ded
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDArxbDfh3p1okrD9wQw6jJ4d4DdlBPD5GqXE8bIeRJiK41Sh40LgvPw
+mkqEDSXK++CgBwYFK4EEACKhZANiAAScl43Ih2lWTDKrSox5ve5uiTXil4smsup3
+CfS1XPjKxgBAmlfBim8izbdrT0BFdQzz2joduNMtpt61wO4rGs6jm0UP7Kim9PC7
+Hneb/99fIYopdMH5NMnk60zGO1uZ2vc=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key384.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..428d5fb7d7
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJyXjciHaVZMMqtKjHm97m6JNeKXiyay6ncJ9LVc+MrGAECaV8GKbyLNt2tPQEV1DPPaOh240y2m3rXA7isazqObRQ/sqKb08Lsed5v/318hiil0wfk0yeTrTMY7W5na9w== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key521 b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..3e51ec2ecd
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIB8O1BFkl2HQjQLRLonEZ97da/h39DMa9/0/hvPZWAI8gUPEQcHxRx
+U7b09p3Zh+EBbMFq8+1ae9ds+ZTxE4WFSvKgBwYFK4EEACOhgYkDgYYABAAlWVjq
+Bzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/
+vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5
+ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key521.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..017a29f4da
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAlWVjqBzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed25519_key b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed25519_key
new file mode 100644
index 0000000000..13a8fcf491
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed25519_key
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQAAAJi+h4O7voeD
+uwAAAAtzc2gtZWQyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQ
+AAAEBaOcJfGPNemKc1wPHTCmM4Kwvh6dZ0CqY14UT361UnN0lI66JgZZo72XJ7wGBp+h3W
+TDw/pxXddvaomAIHrIl9AAAAE3VhYmhuaWxAZWx4YWRsajNxMzIBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed25519_key.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed25519_key.pub
new file mode 100644
index 0000000000..156ef4045c
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed25519_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIElI66JgZZo72XJ7wGBp+h3WTDw/pxXddvaomAIHrIl9 uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed448_key b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed448_key
new file mode 100644
index 0000000000..31a7e4e8c3
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed448_key
@@ -0,0 +1,10 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA5X9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2
+m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHl
+D2zR+hq+r+glYYAAAABybIKlYsuAjRDWMr6JyFE+v2ySnzTd+oyfY8mWDvbjSKNS
+jIo/zC8ETjmj/FuUSS+PAy51SaIAmPlbX9dEm1m0Yf0s54fsYWrUah2hNCSFpw4f
+ig6nXYDpZ3jt8SR2m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed448_key.pub b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed448_key.pub
new file mode 100644
index 0000000000..8c390dcb58
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server_dirs/ssh_host_ed448_key.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHlD2zR+hq+r+glYYA=
diff --git a/lib/ssh/test/ssh_agent_SUITE.erl b/lib/ssh/test/ssh_agent_SUITE.erl
index 7efd1c6d88..836a61d389 100644
--- a/lib/ssh/test/ssh_agent_SUITE.erl
+++ b/lib/ssh/test/ssh_agent_SUITE.erl
@@ -48,6 +48,22 @@ init_per_suite(Config) ->
end_per_suite(_Config) ->
ok = ssh:stop().
+init_per_testcase(connect_with_ssh_agent, Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ UserDir = proplists:get_value(priv_dir, Config),
+ AgentUserDir = filename:join(UserDir,"agent"), % just to separate them in the tests
+ % so we know that the right dir is used
+ file:make_dir(AgentUserDir),
+ %% Arrange the host keys in <priv_dir>/system
+ ct:log("Host keys setup for: ~p",
+ [ssh_test_lib:setup_all_host_keys(Config)]),
+ %% Copy the user's files used by the daemon
+ {ok,_} = file:copy(filename:join(DataDir,"authorized_keys"),
+ filename:join(UserDir,"authorized_keys")),
+ %% And copy the user's files used by the agent (and not by the user)
+ {ok,_} = file:copy(filename:join(DataDir,"id_rsa"),
+ filename:join(AgentUserDir,"id_rsa")),
+ Config;
init_per_testcase(_TestCase, Config) ->
Config.
@@ -119,16 +135,18 @@ connect_with_ssh_agent() ->
[{doc, "Connect with RSA key from SSH agent"}].
connect_with_ssh_agent(Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- {ok, SocketPath} = ssh_agent_mock_server:start_link('rsa-sha2-256', DataDir),
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, DataDir},
- {user_dir, DataDir}]),
- ConnectionRef = ssh_test_lib:connect(Host, Port, [{user_dir, DataDir},
- {silently_accept_hosts, true},
- {user_interaction, false},
- {auth_methods, "publickey"},
- {key_cb, {ssh_agent, [{socket_path, SocketPath}]}}
- ]),
+ UserDir = PrivDir = proplists:get_value(priv_dir, Config),
+ AgentUserDir = filename:join(UserDir,"agent"),
+ SystemDir = filename:join(PrivDir, "system"),
+ {ok, SocketPath} = ssh_agent_mock_server:start_link('rsa-sha2-256', AgentUserDir),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir}]),
+ ConnectionRef = ssh_test_lib:connect(Host, Port, [{user_dir, UserDir},
+ {silently_accept_hosts, true},
+ {user_interaction, false},
+ {auth_methods, "publickey"},
+ {key_cb, {ssh_agent, [{socket_path, SocketPath}]}}
+ ]),
ssh:close(ConnectionRef),
ssh:stop_daemon(Pid),
ssh_agent_mock_server:stop(SocketPath).
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..fb1a862ded
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDArxbDfh3p1okrD9wQw6jJ4d4DdlBPD5GqXE8bIeRJiK41Sh40LgvPw
+mkqEDSXK++CgBwYFK4EEACKhZANiAAScl43Ih2lWTDKrSox5ve5uiTXil4smsup3
+CfS1XPjKxgBAmlfBim8izbdrT0BFdQzz2joduNMtpt61wO4rGs6jm0UP7Kim9PC7
+Hneb/99fIYopdMH5NMnk60zGO1uZ2vc=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..428d5fb7d7
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJyXjciHaVZMMqtKjHm97m6JNeKXiyay6ncJ9LVc+MrGAECaV8GKbyLNt2tPQEV1DPPaOh240y2m3rXA7isazqObRQ/sqKb08Lsed5v/318hiil0wfk0yeTrTMY7W5na9w== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..3e51ec2ecd
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIB8O1BFkl2HQjQLRLonEZ97da/h39DMa9/0/hvPZWAI8gUPEQcHxRx
+U7b09p3Zh+EBbMFq8+1ae9ds+ZTxE4WFSvKgBwYFK4EEACOhgYkDgYYABAAlWVjq
+Bzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/
+vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5
+ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..017a29f4da
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAlWVjqBzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed25519_key b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed25519_key
new file mode 100644
index 0000000000..13a8fcf491
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed25519_key
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQAAAJi+h4O7voeD
+uwAAAAtzc2gtZWQyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQ
+AAAEBaOcJfGPNemKc1wPHTCmM4Kwvh6dZ0CqY14UT361UnN0lI66JgZZo72XJ7wGBp+h3W
+TDw/pxXddvaomAIHrIl9AAAAE3VhYmhuaWxAZWx4YWRsajNxMzIBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed25519_key.pub b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed25519_key.pub
new file mode 100644
index 0000000000..156ef4045c
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed25519_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIElI66JgZZo72XJ7wGBp+h3WTDw/pxXddvaomAIHrIl9 uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed448_key b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed448_key
new file mode 100644
index 0000000000..31a7e4e8c3
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed448_key
@@ -0,0 +1,10 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA5X9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2
+m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHl
+D2zR+hq+r+glYYAAAABybIKlYsuAjRDWMr6JyFE+v2ySnzTd+oyfY8mWDvbjSKNS
+jIo/zC8ETjmj/FuUSS+PAy51SaIAmPlbX9dEm1m0Yf0s54fsYWrUah2hNCSFpw4f
+ig6nXYDpZ3jt8SR2m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed448_key.pub b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed448_key.pub
new file mode 100644
index 0000000000..8c390dcb58
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_ed448_key.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHlD2zR+hq+r+glYYA=
diff --git a/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_agent_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE.erl b/lib/ssh/test/ssh_algorithms_SUITE.erl
index 06996d7e48..4832c0ad3b 100644
--- a/lib/ssh/test/ssh_algorithms_SUITE.erl
+++ b/lib/ssh/test/ssh_algorithms_SUITE.erl
@@ -35,7 +35,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap,{seconds,60}}].
+ {timetrap,{seconds,120}}].
all() ->
%% [{group,kex},{group,cipher}... etc
@@ -48,9 +48,9 @@ groups() ->
SshdAlgos = extract_algos(ssh_test_lib:default_algorithms(sshd)),
DoubleAlgos =
- [{Tag, double(Algs)} || {Tag,Algs} <- ErlAlgos,
- length(Algs) > 1,
- lists:member(Tag, two_way_tags())],
+ [{Tag, double(Tag,Algs)} || {Tag,Algs} <- ErlAlgos,
+ length(Algs) > 1,
+ lists:member(Tag, two_way_tags())],
TagGroupSet =
[{Tag, [], group_members_for_tag(Tag,Algs,DoubleAlgos)}
|| {Tag,Algs} <- ErlAlgos,
@@ -60,14 +60,14 @@ groups() ->
TypeSSH = ssh_test_lib:ssh_type(),
AlgoTcSet =
- [{Alg, [parallel], specific_test_cases(Tag,Alg,SshcAlgos,SshdAlgos,TypeSSH)}
+ [{Alg, [], specific_test_cases(Tag,Alg,SshcAlgos,SshdAlgos,TypeSSH)}
|| {Tag,Algs} <- ErlAlgos ++ DoubleAlgos,
Alg <- Algs],
TagGroupSet ++ AlgoTcSet.
tags() -> [kex,cipher,mac,compression,public_key].
-two_way_tags() -> [cipher,mac,compression].
+two_way_tags() -> [cipher,mac,compression, public_key].
%%--------------------------------------------------------------------
init_per_suite(Config) ->
@@ -91,7 +91,10 @@ init_per_suite(Config) ->
ssh_test_lib:installed_ssh_version("TIMEOUT"),
ssh:default_algorithms(),
crypto:info_lib(),
- ssh_test_lib:default_algorithms(sshc),
+ ssh_test_lib:default_algorithms(sshc,
+ %% Use a fake system_dir to enable the test
+ %% daemon to start:
+ [{system_dir,proplists:get_value(data_dir,Config)}]),
ssh_test_lib:default_algorithms(sshd),
{?DEFAULT_DH_GROUP_MIN,?DEFAULT_DH_GROUP_NBITS,?DEFAULT_DH_GROUP_MAX},
public_key:dh_gex_group_sizes(),
@@ -126,22 +129,31 @@ init_per_group(Group, Config) ->
init_per_group(public_key=Tag, Alg, Config) ->
+ PA =
+ case split(Tag, Alg) of
+ [_] ->
+ [Alg];
+ [A1,A2] ->
+ [A1,A2]
+ end,
OtherAlgs = [{T,L} || {T,L} <- ssh_transport:supported_algorithms(), T=/=Tag],
- ct:log("Init tests for public_key ~p~nOtherAlgs=~p",[Alg,OtherAlgs]),
- PrefAlgs = {preferred_algorithms,[{Tag,[Alg]}|OtherAlgs]},
+ ct:log("Init tests for public_key ~p~nOtherAlgs=~p",[PA,OtherAlgs]),
+ PrefAlgs = {preferred_algorithms,[{Tag,PA}|OtherAlgs]},
%% Daemon started later in init_per_testcase
try
- setup_pubkey(Alg,
+ setup_pubkey(PA,
[{pref_algs,PrefAlgs},
- {tag_alg,{Tag,Alg}}
+ {tag_alg,{Tag,PA}}
| Config])
catch
- _:_ -> {skip, io_lib:format("Unsupported: ~p",[Alg])}
+ _C:_E:_S ->
+ ct:log("Exception ~p:~p~n~p",[_C,_E,_S]),
+ {skip, io_lib:format("Unsupported: ~p",[Alg])}
end;
init_per_group(Tag, Alg, Config) ->
PA =
- case split(Alg) of
+ case split(Tag, Alg) of
[_] ->
[Alg];
[A1,A2] ->
@@ -153,7 +165,7 @@ init_per_group(Tag, Alg, Config) ->
PrefAlgs = {preferred_algorithms,[{Tag,PA}|OtherAlgs]},
start_std_daemon([PrefAlgs],
[{pref_algs,PrefAlgs},
- {tag_alg,{Tag,Alg}}
+ {tag_alg,{Tag,[Alg]}}
| Config]).
@@ -173,6 +185,7 @@ init_per_testcase(TC, Config) ->
init_per_testcase(TC, {public_key,Alg}, Config) ->
+ ct:log("init_per_testcase TC=~p, Alg=~p",[TC,Alg]),
ExtraOpts = case TC of
simple_connect ->
[{user_dir, proplists:get_value(priv_dir,Config)}];
@@ -180,21 +193,26 @@ init_per_testcase(TC, {public_key,Alg}, Config) ->
[]
end,
Opts = pubkey_opts(Config) ++ ExtraOpts,
- case {ssh_file:user_key(Alg,Opts), ssh_file:host_key(Alg,Opts)} of
+ {UserAlg,SrvrAlg} =
+ case Alg of
+ [A1,A2] -> {A1,A2};
+ [A0] -> {A0,A0}
+ end,
+ case {ssh_file:user_key(UserAlg,Opts), ssh_file:host_key(SrvrAlg,Opts)} of
{{ok,_}, {ok,_}} ->
start_pubkey_daemon([proplists:get_value(pref_algs,Config)
| ExtraOpts],
[{extra_daemon,true}|Config]);
{{ok,_}, {error,Err}} ->
- ct:log("Alg = ~p~nOpts = ~p",[Alg,Opts]),
+ ct:log("SrvrAlg = ~p~nOpts = ~p",[SrvrAlg,Opts]),
{skip, io_lib:format("No host key: ~p",[Err])};
{{error,Err}, {ok,_}} ->
- ct:log("Alg = ~p~nOpts = ~p",[Alg,Opts]),
+ ct:log("UserAlg = ~p~nOpts = ~p",[UserAlg,Opts]),
{skip, io_lib:format("No user key: ~p",[Err])};
_ ->
- ct:log("Alg = ~p~nOpts = ~p",[Alg,Opts]),
+ ct:log("UserAlg = ~p SrvrAlg = ~p~nOpts = ~p",[UserAlg,SrvrAlg,Opts]),
{skip, "Neither host nor user key"}
end;
@@ -244,17 +262,22 @@ simple_exec(Config) ->
%%--------------------------------------------------------------------
%% A simple exec call
simple_connect(Config) ->
+ ct:log("PrivDir ~p:~n~p~n~nPrivDir/system: ~p",[proplists:get_value(priv_dir,Config),
+ file:list_dir(proplists:get_value(priv_dir,Config)),
+ catch file:list_dir(
+ filename:join(proplists:get_value(priv_dir,Config),
+ system))]),
{Host,Port} = proplists:get_value(srvr_addr, Config),
{preferred_algorithms,AlgEntries} = proplists:get_value(pref_algs, Config),
Opts =
case proplists:get_value(tag_alg, Config) of
- {public_key,Alg} -> [{pref_public_key_algs,[Alg]},
+ {public_key,Alg} -> [{pref_public_key_algs,Alg},
{preferred_algorithms,AlgEntries}];
_ -> [{modify_algorithms,[{append,AlgEntries}]}]
end,
ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port,
[{silently_accept_hosts, true},
- {user_interaction, false} |
+ {user_interaction, false} |
Opts]),
ct:log("~p:~p connected! ~p",[?MODULE,?LINE,ConnectionRef]),
ssh:close(ConnectionRef).
@@ -280,7 +303,7 @@ try_exec_simple_group(Group, Config) ->
%% Testing all default groups
simple_exec_groups() ->
- [{timetrap,{seconds,180}}].
+ [{timetrap,{seconds,240}}].
simple_exec_groups(Config) ->
Sizes = interpolate( public_key:dh_gex_group_sizes() ),
@@ -317,7 +340,10 @@ sshc_simple_exec_os_cmd(Config) ->
Result = ssh_test_lib:open_sshc(Host, Port,
[" -C"
" -o UserKnownHostsFile=",KnownHosts,
+ " -o CheckHostIP=no"
" -o StrictHostKeyChecking=no"
+ " -q"
+ " -x"
],
" 1+1."),
Parent ! {result, self(), Result, "2"}
@@ -342,7 +368,7 @@ sshc_simple_exec_os_cmd(Config) ->
sshd_simple_exec(Config) ->
ClientPubKeyOpts =
case proplists:get_value(tag_alg,Config) of
- {public_key,Alg} -> [{pref_public_key_algs,[Alg]}];
+ {public_key,Alg} -> [{pref_public_key_algs,Alg}];
_ -> []
end,
ConnectionRef = ssh_test_lib:connect(22, [{silently_accept_hosts, true},
@@ -395,13 +421,20 @@ sshd_simple_exec(Config) ->
group_members_for_tag(Tag, Algos, DoubleAlgos) ->
[{group,Alg} || Alg <- Algos++proplists:get_value(Tag,DoubleAlgos,[])].
-double(Algs) -> [concat(A1,A2) || A1 <- Algs,
- A2 <- Algs,
- A1 =/= A2].
+double(Tag, Algs) -> [concat(Tag,A1,A2) || A1 <- Algs,
+ A2 <- Algs,
+ A1 =/= A2].
-concat(A1, A2) -> list_to_atom(lists:concat([A1," + ",A2])).
+concat(Tag, A1, A2) ->
+ list_to_atom(lists:concat(["D: ",Tag," ",A1," + ",A2])).
-split(Alg) -> ssh_test_lib:to_atoms(string:tokens(atom_to_list(Alg), " + ")).
+split(TagA, Alg) ->
+ Tag = atom_to_list(TagA),
+ ssh_test_lib:to_atoms(
+ case string:tokens(atom_to_list(Alg), " ") of
+ ["D:",Tag,A1,"+",A2] ->[A1,A2];
+ Other -> Other
+ end).
specific_test_cases(Tag, Alg, SshcAlgos, SshdAlgos, TypeSSH) ->
case Tag of
@@ -435,7 +468,7 @@ supports(Tag, Alg, Algos) ->
lists:all(fun(A) ->
lists:member(A, proplists:get_value(Tag, Algos,[]))
end,
- split(Alg)).
+ split(Tag, Alg)).
extract_algos(Spec) ->
@@ -475,21 +508,33 @@ pubkey_opts(Config) ->
{system_dir, SystemDir}].
-setup_pubkey(Alg, Config) ->
+setup_pubkey([AlgClient, AlgServer], Config) ->
DataDir = proplists:get_value(data_dir, Config),
UserDir = proplists:get_value(priv_dir, Config),
+ ssh_test_lib:del_dir_contents(UserDir),
+ ok = ssh_test_lib:setup_user_key(AlgClient, DataDir, UserDir),
+ _SysDir = ssh_test_lib:setup_host_key_create_dir(AlgServer, DataDir, UserDir),
+try ct:log("~p:~p AlgClient=~p, AlgServer=~p~nPrivDir ~p:~n~p~n~nSYsDir=~p~nPrivDir/system: ~p",
+ [?MODULE,?LINE,
+ AlgClient, AlgServer,
+ proplists:get_value(priv_dir,Config),
+ file:list_dir(proplists:get_value(priv_dir,Config)),
+ _SysDir,
+ catch file:list_dir(
+ filename:join(proplists:get_value(priv_dir,Config),
+ system))
+ ])
+catch _C:_E:_S ->
+ ct:log("~p:~p ~p:~p~n~p",[?MODULE,?LINE,_C,_E,_S])
+end,
+ Config;
+
+setup_pubkey([Alg], Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
ct:log("Setup keys for ~p",[Alg]),
- case Alg of
- 'ssh-dss' -> ssh_test_lib:setup_dsa(DataDir, UserDir);
- 'ssh-rsa' -> ssh_test_lib:setup_rsa(DataDir, UserDir);
- 'rsa-sha2-256' -> ssh_test_lib:setup_rsa(DataDir, UserDir);
- 'rsa-sha2-512' -> ssh_test_lib:setup_rsa(DataDir, UserDir);
- 'ecdsa-sha2-nistp256' -> ssh_test_lib:setup_ecdsa("256", DataDir, UserDir);
- 'ecdsa-sha2-nistp384' -> ssh_test_lib:setup_ecdsa("384", DataDir, UserDir);
- 'ecdsa-sha2-nistp521' -> ssh_test_lib:setup_ecdsa("521", DataDir, UserDir);
- 'ssh-ed25519' -> ssh_test_lib:setup_eddsa(ed25519, DataDir, UserDir);
- 'ssh-ed448' -> ssh_test_lib:setup_eddsa(ed448, DataDir, UserDir)
- end,
+ ssh_test_lib:setup_user_key(Alg, DataDir, PrivDir),
+ ssh_test_lib:setup_host_key_create_dir(Alg, DataDir, PrivDir),
Config.
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa b/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa
index 273866b2a6..24628e071b 100644
--- a/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa
@@ -1,12 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
-MIIBvAIBAAKBgQDIaRzrxz7bSJXh6z+w1lfTW7sfYNMDNXsfN/nvt6Rqi95K4Q+8
-Xpa+LJ6oZCxfMto8w2fZ6uzikRCgBbvzos6L+GPKWhuaBTT5gYsEFphowWN9uPQy
-BHwRApOkpZNObN+SnMRuO7lYpwMLnYJdLJTCOxam3mfAzTqdCnpgAWAidwIVANFI
-VPGuBxMc84proP+r8X+8hT8RAoGBAI9A+KYH0LLFFIaxgDBA7xnnHIECQrhgiNIN
-QfvFPH1Drf5He50OeXFEvR4gt7f3qScWxLUKrpBysS1huJHiJCOq+iREyfoqjtfc
-zZT01XejDvX5ck+rz/kiWQk9cZwW6lqLtn3GxIcQvOnrzskT7YyFJ7fx3U98PxmY
-qZrXhJEjAoGABFZL6Ztdx9A+7qd5s2A4T7W9fztsm85CxM4MuRuzR2U6zU/Z4D6U
-OXiS9UZsz7yIQQfqrc5IgPmSa5og9oflQnQSQcRrY1XvpYLft1DOkH6+wdFf0OlG
-hIKihHN+jvgbcEmJTHJwsiW2HJCH6qXK33s4lmthEeIqXuZPduaBnGICFQDKLb+y
-afjRTP7FVHq+SBQUy8iqSQ==
+MIIBuwIBAAKBgQDIywHurUpOq6kZuMn+XlRzR4hAxF6qwSkuEqkV7iHnLQ0kIwf3
+uAmjFDhuEsQ8653SLxGVvTNp+KFFgDXiLqgM7TPUwDnpbvzEZHPAU+/zPt4sdY2D
+txBfJwT2SFlK6HPOxOcxdDuD+/a59sh8hk/YVOU7ZTcBVsVG8Got4UcF5QIVAPGd
+CPDQKSTlPiM9OwBB1+9p11k5AoGARLxw4l17mET9cU0uf4Ppe5nsCbODJv44ZrSs
+picvypGVLrLcN5KWbm3vjRFCQ5LFunAG3FwLC2Sh0CH6TemoIfRPsRHR7wvpBGdr
+c693UlMOis/mcmvNMQAzuQNW9WrxdzsvWR/r5s6NEHWqKUJGXSPi2d+Ijq/mCOmI
+hzLzyiACgYEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4
+cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+C
+ROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNgCFEjA7wTC
+sQCY/I35vb6GUJn9tEdP
-----END DSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa.pub
new file mode 100644
index 0000000000..018ef6f537
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAMjLAe6tSk6rqRm4yf5eVHNHiEDEXqrBKS4SqRXuIectDSQjB/e4CaMUOG4SxDzrndIvEZW9M2n4oUWANeIuqAztM9TAOelu/MRkc8BT7/M+3ix1jYO3EF8nBPZIWUroc87E5zF0O4P79rn2yHyGT9hU5TtlNwFWxUbwai3hRwXlAAAAFQDxnQjw0Ckk5T4jPTsAQdfvaddZOQAAAIBEvHDiXXuYRP1xTS5/g+l7mewJs4Mm/jhmtKymJy/KkZUustw3kpZube+NEUJDksW6cAbcXAsLZKHQIfpN6agh9E+xEdHvC+kEZ2tzr3dSUw6Kz+Zya80xADO5A1b1avF3Oy9ZH+vmzo0QdaopQkZdI+LZ34iOr+YI6YiHMvPKIAAAAIEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+CROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNg= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa b/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa
index 1f8577e866..2202c2ead8 100644
--- a/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-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
+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
-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa.pub
new file mode 100644
index 0000000000..b4084d320a
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDO2OLKPa11+SOLR97BZLSQAGDQgAGAbbQ28vU+cckuv3zB7vBbt/ePbsQaNb8Cm7JyxZdcqLQvzary4OJygcdvckjYmRPvSiLTIbUPH/PA8352QDssFPUndQraElMU+GnznkLBj+yz3GkGx3UW/fO4eJ8So0aWN6DU+OZDek2HED8zRplwud8hR1nkev637h6zfNpaji0sEqZm7oGRUZAo8Zd4yQgAy0mUbbiXuooNGRHlNgBlPs/xWfuGe4W4I1uslKbrzoZrAHFNBeibbd2D1RxbGgcHtSIcWhHqPRtABf7hHtsjBy6VENy/OuAK7q7TqgUgvBjsyWzGlf2EZOXX uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index ecec805696..1269ab393e 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -40,103 +40,64 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap,{seconds,40}}].
+ {timetrap,{seconds,90}}].
all() ->
- [{group, all_tests},
- daemon_already_started
+ [{group, all_tests}
].
%%%-define(PARALLEL, ).
-define(PARALLEL, parallel).
groups() ->
- [{all_tests, [?PARALLEL], [{group, ssh_renegotiate_SUITE},
- {group, ssh_basic_SUITE},
- ssh_file_is_host_key,
- ssh_file_is_host_key_misc,
- ssh_file_is_auth_key
- ]},
- {ssh_basic_SUITE, [], [app_test,
- appup_test,
- {group, dsa_key},
- {group, rsa_key},
- {group, ecdsa_sha2_nistp256_key},
- {group, ecdsa_sha2_nistp384_key},
- {group, ecdsa_sha2_nistp521_key},
- {group, ed25519_key},
- {group, ed448_key},
- {group, dsa_pass_key},
- {group, rsa_pass_key},
- {group, ecdsa_sha2_nistp256_pass_key},
- {group, ecdsa_sha2_nistp384_pass_key},
- {group, ecdsa_sha2_nistp521_pass_key},
- {group, host_user_key_differs},
- {group, key_cb},
- {group, internal_error},
- {group, rsa_host_key_is_actualy_ecdsa},
- daemon_already_started,
- double_close,
- daemon_opt_fd,
- multi_daemon_opt_fd,
- packet_size,
- ssh_info_print,
- {group, login_bad_pwd_no_retry},
- shell_exit_status,
- setopts_getopts
- ]},
-
- {ssh_renegotiate_SUITE, [?PARALLEL], [rekey0,
- rekey1,
- rekey2,
- rekey3,
- rekey4,
- rekey_limit_client,
- rekey_limit_daemon,
- rekey_time_limit_client,
- rekey_time_limit_daemon,
- norekey_limit_client,
- norekey_limit_daemon,
- renegotiate1,
- renegotiate2]},
-
- {dsa_key, [], [{group, basic}]},
- {rsa_key, [], [{group, basic}]},
- {ecdsa_sha2_nistp256_key, [], [{group, basic}]},
- {ecdsa_sha2_nistp384_key, [], [{group, basic}]},
- {ecdsa_sha2_nistp521_key, [], [{group, basic}]},
- {ed25519_key, [], [{group, basic}]},
- {ed448_key, [], [{group, basic}]},
- {rsa_host_key_is_actualy_ecdsa, [], [fail_daemon_start]},
- {host_user_key_differs, [?PARALLEL], [exec_key_differs1,
- exec_key_differs2,
- exec_key_differs3,
- exec_key_differs_fail]},
- {dsa_pass_key, [], [pass_phrase]},
- {rsa_pass_key, [], [pass_phrase]},
- {ecdsa_sha2_nistp256_pass_key, [], [pass_phrase]},
- {ecdsa_sha2_nistp384_pass_key, [], [pass_phrase]},
- {ecdsa_sha2_nistp521_pass_key, [], [pass_phrase]},
+ [{all_tests, [?PARALLEL], [{group, sequential},
+ {group, p_basic},
+ {group, internal_error},
+ {group, login_bad_pwd_no_retry},
+ {group, key_cb}
+ ]},
+
+ {sequential, [], [app_test,
+ appup_test,
+ daemon_already_started,
+ daemon_error_closes_port, % Should be re-written..
+ double_close,
+ daemon_opt_fd,
+ multi_daemon_opt_fd,
+ packet_size,
+ ssh_info_print,
+ shell_exit_status,
+ setopts_getopts,
+ known_hosts,
+ ssh_file_is_host_key,
+ ssh_file_is_host_key_misc,
+ ssh_file_is_auth_key
+ ]},
+
{key_cb, [?PARALLEL], [key_callback, key_callback_options]},
- {internal_error, [], [internal_error]},
+
+ {internal_error, [?PARALLEL], [internal_error]},
+
{login_bad_pwd_no_retry, [?PARALLEL], [login_bad_pwd_no_retry1,
- login_bad_pwd_no_retry2,
- login_bad_pwd_no_retry3,
- login_bad_pwd_no_retry4,
- login_bad_pwd_no_retry5
- ]},
+ login_bad_pwd_no_retry2,
+ login_bad_pwd_no_retry3,
+ login_bad_pwd_no_retry4,
+ login_bad_pwd_no_retry5
+ ]},
- {basic, [], [{group,p_basic},
- shell, shell_no_unicode, shell_unicode_string,
- close,
- known_hosts
- ]},
{p_basic, [?PARALLEL], [send, peername_sockname,
- exec, exec_compressed,
- exec_with_io_out, exec_with_io_in,
- cli,
- idle_time_client, idle_time_server, openssh_zlib_basic_test,
- misc_ssh_options, inet_option, inet6_option]}
+ exec, exec_compressed,
+ exec_with_io_out, exec_with_io_in,
+ cli,
+ idle_time_client, idle_time_server, openssh_zlib_basic_test,
+ misc_ssh_options, inet_option, inet6_option
+
+ ,shell,
+ shell_no_unicode,
+ shell_unicode_string,
+ close
+
+ ]}
].
@@ -147,6 +108,8 @@ groups() ->
init_per_suite(Config) ->
?CHECK_CRYPTO(begin
ssh:start(),
+ ct:log("Pub keys setup for: ~p",
+ [ssh_test_lib:setup_all_user_host_keys(Config)]),
Config
end).
@@ -154,282 +117,22 @@ end_per_suite(_Config) ->
ssh:stop().
%%--------------------------------------------------------------------
-init_per_group(ssh_renegotiate_SUITE, Config) ->
- [{preferred_algorithms, ssh:default_algorithms()} | Config];
-init_per_group(dsa_key, Config) ->
- case lists:member('ssh-dss',
- ssh_transport:default_algorithms(public_key)) of
- true ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_dsa(DataDir, PrivDir),
- Config;
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(rsa_key, Config) ->
- case lists:member('ssh-rsa',
- ssh_transport:default_algorithms(public_key)) of
- true ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_rsa(DataDir, PrivDir),
- Config;
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(rsa_host_key_is_actualy_ecdsa, Config) ->
- case
- lists:member('ssh-rsa',
- ssh_transport:default_algorithms(public_key)) and
- lists:member('ecdsa-sha2-nistp256',
- ssh_transport:default_algorithms(public_key))
- of
- true ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_ecdsa("256", DataDir, PrivDir),
- %% The following sets up bad rsa keys:
- begin
- UserDir = PrivDir,
- System = filename:join(UserDir, "system"),
- file:copy(filename:join(DataDir, "id_rsa"), filename:join(UserDir, "id_rsa")),
- file:rename(filename:join(System, "ssh_host_ecdsa_key"), filename:join(System, "ssh_host_rsa_key")),
- file:rename(filename:join(System, "ssh_host_ecdsa_key.pub"), filename:join(System, "ssh_host_rsa_key.pub")),
- ssh_test_lib:setup_rsa_known_host(DataDir, UserDir),
- ssh_test_lib:setup_rsa_auth_keys(DataDir, UserDir)
- end,
- Config;
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(ecdsa_sha2_nistp256_key, Config) ->
- case lists:member('ecdsa-sha2-nistp256',
- ssh_transport:default_algorithms(public_key)) of
- true ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_ecdsa("256", DataDir, PrivDir),
- Config;
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(ecdsa_sha2_nistp384_key, Config) ->
- case lists:member('ecdsa-sha2-nistp384',
- ssh_transport:default_algorithms(public_key)) of
- true ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_ecdsa("384", DataDir, PrivDir),
- Config;
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(ecdsa_sha2_nistp521_key, Config) ->
- case lists:member('ecdsa-sha2-nistp521',
- ssh_transport:default_algorithms(public_key)) of
- true ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_ecdsa("521", DataDir, PrivDir),
- Config;
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(ed25519_key, Config) ->
- case lists:member('ssh-ed25519',
- ssh_transport:default_algorithms(public_key)) of
- true ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_eddsa(ed25519, DataDir, PrivDir),
- Config;
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(ed448_key, Config) ->
- case lists:member('ssh-ed448',
- ssh_transport:default_algorithms(public_key)) of
- true ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_eddsa(ed448, DataDir, PrivDir),
- Config;
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(rsa_pass_key, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- case lists:member('ssh-rsa',
- ssh_transport:default_algorithms(public_key))
- andalso
- ssh_test_lib:setup_rsa_pass_phrase(DataDir, PrivDir, "Password")
- of
- true ->
- [{pass_phrase, {rsa_pass_phrase, "Password"}}| Config];
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(dsa_pass_key, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- case lists:member('ssh-dss',
- ssh_transport:default_algorithms(public_key))
- andalso
- ssh_test_lib:setup_dsa_pass_phrase(DataDir, PrivDir, "Password")
- of
- true ->
- [{pass_phrase, {dsa_pass_phrase, "Password"}}| Config];
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(ecdsa_sha2_nistp256_pass_key, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- case lists:member('ecdsa-sha2-nistp256',
- ssh_transport:default_algorithms(public_key))
- andalso
- ssh_test_lib:setup_ecdsa_pass_phrase("256", DataDir, PrivDir, "Password")
- of
- true ->
- [{pass_phrase, {ecdsa_pass_phrase, "Password"}}| Config];
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(ecdsa_sha2_nistp384_pass_key, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- case lists:member('ecdsa-sha2-nistp384',
- ssh_transport:default_algorithms(public_key))
- andalso
- ssh_test_lib:setup_ecdsa_pass_phrase("384", DataDir, PrivDir, "Password")
- of
- true ->
- [{pass_phrase, {ecdsa_pass_phrase, "Password"}}| Config];
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(ecdsa_sha2_nistp521_pass_key, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- case lists:member('ecdsa-sha2-nistp521',
- ssh_transport:default_algorithms(public_key))
- andalso
- ssh_test_lib:setup_ecdsa_pass_phrase("521", DataDir, PrivDir, "Password")
- of
- true ->
- [{pass_phrase, {ecdsa_pass_phrase, "Password"}}| Config];
- false ->
- {skip, unsupported_pub_key}
- end;
-init_per_group(host_user_key_differs, Config) ->
- Data = proplists:get_value(data_dir, Config),
- Sys = filename:join(proplists:get_value(priv_dir, Config), system_rsa),
- SysUsr = filename:join(Sys, user),
- Usr = filename:join(proplists:get_value(priv_dir, Config), user_ecdsa_256),
- file:make_dir(Sys),
- file:make_dir(SysUsr),
- file:make_dir(Usr),
- file:copy(filename:join(Data, "ssh_host_rsa_key"), filename:join(Sys, "ssh_host_rsa_key")),
- file:copy(filename:join(Data, "ssh_host_rsa_key.pub"), filename:join(Sys, "ssh_host_rsa_key.pub")),
- file:copy(filename:join(Data, "id_ecdsa256"), filename:join(Usr, "id_ecdsa")),
- file:copy(filename:join(Data, "id_ecdsa256.pub"), filename:join(Usr, "id_ecdsa.pub")),
- ssh_test_lib:setup_ecdsa_auth_keys("256", Data, SysUsr),
- ssh_test_lib:setup_rsa_known_host(Sys, Usr),
- Config;
init_per_group(key_cb, Config) ->
case lists:member('ssh-rsa',
- ssh_transport:default_algorithms(public_key)) of
+ ssh_transport:supported_algorithms(public_key)) of
true ->
DataDir = proplists:get_value(data_dir, Config),
PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_rsa(DataDir, PrivDir),
+ ssh_test_lib:setup_user_key('ssh-rsa', DataDir, PrivDir),
+ ssh_test_lib:setup_host_key_create_dir('ssh-rsa', DataDir, PrivDir),
Config;
false ->
{skip, unsupported_pub_key}
end;
-init_per_group(internal_error, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_rsa(DataDir, PrivDir),
- ssh_test_lib:setup_dsa(DataDir, PrivDir),
- ssh_test_lib:setup_ecdsa("256", DataDir, PrivDir),
- %% In the test case the key will be deleted after the daemon start:
- %% ... file:delete(filename:join(PrivDir, "system/ssh_host_dsa_key")),
- Config;
-init_per_group(dir_options, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- %% Make unreadable dir:
- Dir_unreadable = filename:join(PrivDir, "unread"),
- ok = file:make_dir(Dir_unreadable),
- {ok,F1} = file:read_file_info(Dir_unreadable),
- ok = file:write_file_info(Dir_unreadable,
- F1#file_info{mode = F1#file_info.mode band (bnot 8#00444)}),
- %% Make readable file:
- File_readable = filename:join(PrivDir, "file"),
- ok = file:write_file(File_readable, <<>>),
-
- %% Check:
- case {file:read_file_info(Dir_unreadable),
- file:read_file_info(File_readable)} of
- {{ok, Id=#file_info{type=directory, access=Md}},
- {ok, If=#file_info{type=regular, access=Mf}}} ->
- AccessOK =
- case {Md, Mf} of
- {read, _} -> false;
- {read_write, _} -> false;
- {_, read} -> true;
- {_, read_write} -> true;
- _ -> false
- end,
-
- case AccessOK of
- true ->
- %% Save:
- [{unreadable_dir, Dir_unreadable},
- {readable_file, File_readable}
- | Config];
- false ->
- ct:log("File#file_info : ~p~n"
- "Dir#file_info : ~p",[If,Id]),
- {skip, "File or dir mode settings failed"}
- end;
-
- NotDirFile ->
- ct:log("{Dir,File} -> ~p",[NotDirFile]),
- {skip, "File/Dir creation failed"}
- end;
init_per_group(_, Config) ->
Config.
-end_per_group(dsa_key, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:clean_dsa(PrivDir),
- Config;
-end_per_group(rsa_key, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:clean_rsa(PrivDir),
- Config;
-end_per_group(dsa_pass_key, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:clean_dsa(PrivDir),
- Config;
-end_per_group(rsa_pass_key, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:clean_rsa(PrivDir),
- Config;
-end_per_group(key_cb, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:clean_rsa(PrivDir),
- Config;
-end_per_group(internal_error, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:clean_rsa(PrivDir),
- ssh_test_lib:clean_dsa(PrivDir),
- Config;
-
end_per_group(_, Config) ->
Config.
%%--------------------------------------------------------------------
@@ -462,11 +165,6 @@ init_per_testcase(inet6_option, Config) ->
init_per_testcase(_TestCase, Config) ->
Config.
-end_per_testcase(TestCase, Config) when TestCase == server_password_option;
- TestCase == server_userpassword_option ->
- UserDir = filename:join(proplists:get_value(priv_dir, Config), nopubkey),
- ssh_test_lib:del_dirs(UserDir),
- end_per_testcase(Config);
end_per_testcase(TC, Config) when TC==shell_no_unicode ;
TC==shell_unicode_string ->
case proplists:get_value(sftpd, Config) of
@@ -527,6 +225,7 @@ inet_option(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
%%% Test configuring IPv6
+inet6_option() -> [{timetrap,{seconds,30}}].
inet6_option(Config) when is_list(Config) ->
SystemDir = filename:join(proplists:get_value(priv_dir, Config), system),
UserDir = proplists:get_value(priv_dir, Config),
@@ -603,13 +302,16 @@ exec_with_io_out(Config) when is_list(Config) ->
"io:write(hej).", infinity),
case ssh_test_lib:receive_exec_result(
[{ssh_cm, ConnectionRef, {data, ChannelId0, 0, <<"hej">>}},
- {ssh_cm, ConnectionRef, {data, ChannelId0, 0, <<"ok">>}}]) of
+ {ssh_cm, ConnectionRef, {data, ChannelId0, 0, <<"ok">>}},
+ {ssh_cm, ConnectionRef, {eof, ChannelId0}},
+ {ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}},
+ {ssh_cm, ConnectionRef, {closed, ChannelId0}}
+ ]) of
expected ->
ok;
Other0 ->
ct:fail(Other0)
end,
- ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId0),
ssh:close(ConnectionRef),
ssh:stop_daemon(Pid).
@@ -738,81 +440,6 @@ shell(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-%%% Test that we could user different types of host pubkey and user pubkey
-exec_key_differs1(Config) -> exec_key_differs(Config, ['ecdsa-sha2-nistp256']).
-
-exec_key_differs2(Config) -> exec_key_differs(Config, ['ssh-dss','ecdsa-sha2-nistp256']).
-
-exec_key_differs3(Config) -> exec_key_differs(Config, ['ecdsa-sha2-nistp384','ecdsa-sha2-nistp256']).
-
-
-
-exec_key_differs(Config, UserPKAlgs) ->
- case lists:usort(['ssh-rsa'|UserPKAlgs])
- -- ssh_transport:supported_algorithms(public_key)
- of
- [] ->
- process_flag(trap_exit, true),
- SystemDir = filename:join(proplists:get_value(priv_dir, Config), system_rsa),
- SystemUserDir = filename:join(SystemDir, user),
- UserDir = filename:join(proplists:get_value(priv_dir, Config), user_ecdsa_256),
-
- {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, SystemUserDir},
- {preferred_algorithms,
- [{public_key,['ssh-rsa'|UserPKAlgs]}]}]),
- ct:sleep(500),
-
- IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir},
- {preferred_algorithms,[{public_key,['ssh-rsa']}]},
- {pref_public_key_algs,UserPKAlgs}
- ]),
-
-
- receive
- {'EXIT', _, _} ->
- ct:fail(no_ssh_connection);
- ErlShellStart ->
- ct:log("Erlang shell start: ~p~n", [ErlShellStart]),
- do_shell(IO, Shell)
- after
- 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
- end;
-
- UnsupportedPubKeys ->
- {skip, io_lib:format("~p unsupported",[UnsupportedPubKeys])}
- end.
-
-%%--------------------------------------------------------------------
-exec_key_differs_fail(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- SystemDir = filename:join(proplists:get_value(priv_dir, Config), system_rsa),
- SystemUserDir = filename:join(SystemDir, user),
- UserDir = filename:join(proplists:get_value(priv_dir, Config), user_ecdsa_256),
-
- {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, SystemUserDir},
- {preferred_algorithms,
- [{public_key,['ssh-rsa']}]}]),
- ct:sleep(500),
-
- IO = ssh_test_lib:start_io_server(),
- ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir},
- {recv_ext_info, false},
- {preferred_algorithms,[{public_key,['ssh-rsa']}]},
- {pref_public_key_algs,['ssh-dss']}]),
- receive
- {'EXIT', _, _} ->
- ok;
- ErlShellStart ->
- ct:log("Erlang shell start: ~p~n", [ErlShellStart]),
- ct:fail(connection_not_rejected)
- after
- 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
- end.
-
-%%--------------------------------------------------------------------
cli(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(proplists:get_value(priv_dir, Config), system),
@@ -871,6 +498,11 @@ daemon_already_started(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
%%% Test that a failed daemon start does not leave the port open
+
+%%%%%%%%%%%%%%%%%%%%%% REWRITE! %%%%%%%%%%%%%%%%%%%%
+%%% 1) check that {error,_} is not {error,eaddrinuse}
+%%% 2) instead of ssh_test_lib:daemon second time, use gen_tcp:listen
+
daemon_error_closes_port(Config) ->
GoodSystemDir = proplists:get_value(data_dir, Config),
Port = inet_port(),
@@ -886,6 +518,11 @@ daemon_error_closes_port(Config) ->
ssh:stop_daemon(Pid)
end.
+inet_port() ->
+ {ok, Socket} = gen_tcp:listen(0, [{reuseaddr, true}]),
+ {ok, Port} = inet:port(Socket),
+ gen_tcp:close(Socket),
+ Port.
%%--------------------------------------------------------------------
%%% check that known_hosts is updated correctly
@@ -957,7 +594,7 @@ known_hosts(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-ssh_file_is_host_key() -> [{timetrap,{seconds,120}}]. % Some machines are S L O W !
+ssh_file_is_host_key() -> [{timetrap,{seconds,240}}]. % Some machines are S L O W !
ssh_file_is_host_key(Config) ->
Dir = ssh_test_lib:create_random_dir(Config),
ct:log("Dir = ~p", [Dir]),
@@ -1176,12 +813,13 @@ send(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(proplists:get_value(priv_dir, Config), system),
UserDir = proplists:get_value(priv_dir, Config),
-
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {preferred_algorithms, ssh_transport:supported_algorithms()},
{user_dir, UserDir},
{failfun, fun ssh_test_lib:failfun/2}]),
ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ ssh_test_lib:connect(Host, Port, [{preferred_algorithms, ssh_transport:supported_algorithms()},
+ {silently_accept_hosts, true},
{user_dir, UserDir},
{user_interaction, false}]),
{ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
@@ -1191,17 +829,6 @@ send(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-%%%
-fail_daemon_start(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- SystemDir = filename:join(proplists:get_value(priv_dir, Config), system),
- UserDir = proplists:get_value(priv_dir, Config),
-
- {error,_} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {failfun, fun ssh_test_lib:failfun/2}]).
-
-%%--------------------------------------------------------------------
%%% Test ssh:connection_info([peername, sockname])
peername_sockname(Config) when is_list(Config) ->
process_flag(trap_exit, true),
@@ -1646,315 +1273,6 @@ setopts_getopts(Config) ->
ssh:stop_daemon(Pid).
-%%----------------------------------------------------------------------------
-%%% Idle timeout test
-rekey0() -> [{timetrap,{seconds,90}}].
-rekey1() -> [{timetrap,{seconds,90}}].
-rekey2() -> [{timetrap,{seconds,90}}].
-rekey3() -> [{timetrap,{seconds,90}}].
-rekey4() -> [{timetrap,{seconds,90}}].
-
-rekey0(Config) -> rekey_chk(Config, 0, 0).
-rekey1(Config) -> rekey_chk(Config, infinity, 0).
-rekey2(Config) -> rekey_chk(Config, {infinity,infinity}, 0).
-rekey3(Config) -> rekey_chk(Config, 0, infinity).
-rekey4(Config) -> rekey_chk(Config, 0, {infinity,infinity}).
-
-rekey_chk(Config, RLdaemon, RLclient) ->
- {Pid, Host, Port} = ssh_test_lib:std_daemon(Config, [{rekey_limit, RLdaemon}]),
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, RLclient}]),
- Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
-
- %% Make both sides send something:
- {ok, _SftpPid} = ssh_sftp:start_channel(ConnectionRef),
-
- %% Check rekeying
- timer:sleep(?REKEY_DATA_TMO),
- ?wait_match(false, Kex1==ssh_test_lib:get_kex_init(ConnectionRef), [], 2000, 10),
-
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-%%% Test rekeying by data volume
-
-rekey_limit_client() -> [{timetrap,{seconds,400}}].
-rekey_limit_client(Config) ->
- Limit = 6000,
- UserDir = proplists:get_value(priv_dir, Config),
- DataFile = filename:join(UserDir, "rekey.data"),
- Data = lists:duplicate(Limit+10,1),
- Algs = proplists:get_value(preferred_algorithms, Config),
- {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
- {preferred_algorithms,Algs}]),
-
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, Limit},
- {max_random_length_padding,0}]),
- {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
-
- %% Check that it doesn't rekey without data transfer
- Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
- timer:sleep(?REKEY_DATA_TMO),
- true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- %% Check that datatransfer triggers rekeying
- ok = ssh_sftp:write_file(SftpPid, DataFile, Data),
- timer:sleep(?REKEY_DATA_TMO),
- ?wait_match(false, Kex1==(Kex2=ssh_test_lib:get_kex_init(ConnectionRef)), Kex2, 2000, 10),
-
- %% Check that datatransfer continues to trigger rekeying
- ok = ssh_sftp:write_file(SftpPid, DataFile, Data),
- timer:sleep(?REKEY_DATA_TMO),
- ?wait_match(false, Kex2==(Kex3=ssh_test_lib:get_kex_init(ConnectionRef)), Kex3, 2000, 10),
-
- %% Check that it doesn't rekey without data transfer
- timer:sleep(?REKEY_DATA_TMO),
- true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- %% Check that it doesn't rekey on a small datatransfer
- ok = ssh_sftp:write_file(SftpPid, DataFile, "hi\n"),
- timer:sleep(?REKEY_DATA_TMO),
- true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- %% Check that it doesn't rekey without data transfer
- timer:sleep(?REKEY_DATA_TMO),
- true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- ssh_sftp:stop_channel(SftpPid),
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
-
-
-rekey_limit_daemon() -> [{timetrap,{seconds,400}}].
-rekey_limit_daemon(Config) ->
- Limit = 6000,
- UserDir = proplists:get_value(priv_dir, Config),
- DataFile1 = filename:join(UserDir, "rekey1.data"),
- DataFile2 = filename:join(UserDir, "rekey2.data"),
- file:write_file(DataFile1, lists:duplicate(Limit+10,1)),
- file:write_file(DataFile2, "hi\n"),
-
- Algs = proplists:get_value(preferred_algorithms, Config),
- {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{rekey_limit, Limit},
- {max_random_length_padding,0},
- {preferred_algorithms,Algs}]),
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{max_random_length_padding,0}]),
- {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
-
- %% Check that it doesn't rekey without data transfer
- Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
- timer:sleep(?REKEY_DATA_TMO),
- Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
-
- %% Check that datatransfer triggers rekeying
- {ok,_} = ssh_sftp:read_file(SftpPid, DataFile1),
- timer:sleep(?REKEY_DATA_TMO),
- ?wait_match(false, Kex1==(Kex2=ssh_test_lib:get_kex_init(ConnectionRef)), Kex2, 2000, 10),
-
- %% Check that datatransfer continues to trigger rekeying
- {ok,_} = ssh_sftp:read_file(SftpPid, DataFile1),
- timer:sleep(?REKEY_DATA_TMO),
- ?wait_match(false, Kex2==(Kex3=ssh_test_lib:get_kex_init(ConnectionRef)), Kex3, 2000, 10),
-
- %% Check that it doesn't rekey without data transfer
- timer:sleep(?REKEY_DATA_TMO),
- true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- %% Check that it doesn't rekey on a small datatransfer
- {ok,_} = ssh_sftp:read_file(SftpPid, DataFile2),
- timer:sleep(?REKEY_DATA_TMO),
- true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- %% Check that it doesn't rekey without data transfer
- timer:sleep(?REKEY_DATA_TMO),
- true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- ssh_sftp:stop_channel(SftpPid),
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
-
-%%--------------------------------------------------------------------
-%% Check that datatransfer in the other direction does not trigger re-keying
-norekey_limit_client() -> [{timetrap,{seconds,400}}].
-norekey_limit_client(Config) ->
- Limit = 6000,
- UserDir = proplists:get_value(priv_dir, Config),
- DataFile = filename:join(UserDir, "rekey3.data"),
- file:write_file(DataFile, lists:duplicate(Limit+10,1)),
-
- Algs = proplists:get_value(preferred_algorithms, Config),
- {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
- {preferred_algorithms,Algs}]),
-
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, Limit},
- {max_random_length_padding,0}]),
- {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
-
- Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
- timer:sleep(?REKEY_DATA_TMO),
- true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- {ok,_} = ssh_sftp:read_file(SftpPid, DataFile),
- timer:sleep(?REKEY_DATA_TMO),
- true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- ssh_sftp:stop_channel(SftpPid),
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
-%% Check that datatransfer in the other direction does not trigger re-keying
-norekey_limit_daemon() -> [{timetrap,{seconds,400}}].
-norekey_limit_daemon(Config) ->
- Limit = 6000,
- UserDir = proplists:get_value(priv_dir, Config),
- DataFile = filename:join(UserDir, "rekey4.data"),
-
- Algs = proplists:get_value(preferred_algorithms, Config),
- {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{rekey_limit, Limit},
- {max_random_length_padding,0},
- {preferred_algorithms,Algs}]),
-
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{max_random_length_padding,0}]),
- {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
-
- Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
- timer:sleep(?REKEY_DATA_TMO),
- true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- ok = ssh_sftp:write_file(SftpPid, DataFile, lists:duplicate(Limit+10,1)),
- timer:sleep(?REKEY_DATA_TMO),
- true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- ssh_sftp:stop_channel(SftpPid),
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-%%% Test rekeying by time
-
-rekey_time_limit_client() -> [{timetrap,{seconds,400}}].
-rekey_time_limit_client(Config) ->
- Minutes = ?REKEY_DATA_TMO div 60000,
- GB = 1024*1000*1000,
- Algs = proplists:get_value(preferred_algorithms, Config),
- {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
- {preferred_algorithms,Algs}]),
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, {Minutes, GB}},
- {max_random_length_padding,0}]),
- rekey_time_limit(Pid, ConnectionRef).
-
-rekey_time_limit_daemon() -> [{timetrap,{seconds,400}}].
-rekey_time_limit_daemon(Config) ->
- Minutes = ?REKEY_DATA_TMO div 60000,
- GB = 1024*1000*1000,
- Algs = proplists:get_value(preferred_algorithms, Config),
- {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{rekey_limit, {Minutes, GB}},
- {max_random_length_padding,0},
- {preferred_algorithms,Algs}]),
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{max_random_length_padding,0}]),
- rekey_time_limit(Pid, ConnectionRef).
-
-
-rekey_time_limit(Pid, ConnectionRef) ->
- {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
- Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
-
- timer:sleep(5000),
- true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
-
- %% Check that it rekeys when the max time + 30s has passed
- timer:sleep(?REKEY_DATA_TMO + 30*1000),
- ?wait_match(false, Kex1==(Kex2=ssh_test_lib:get_kex_init(ConnectionRef)), Kex2, 2000, 10),
-
- %% Check that it does not rekey when nothing is transferred
- timer:sleep(?REKEY_DATA_TMO + 30*1000),
- ?wait_match(false, Kex2==ssh_test_lib:get_kex_init(ConnectionRef), [], 2000, 10),
-
- ssh_sftp:stop_channel(SftpPid),
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-
-%%% Test rekeying with simultaneous send request
-
-renegotiate1(Config) ->
- UserDir = proplists:get_value(priv_dir, Config),
- DataFile = filename:join(UserDir, "renegotiate1.data"),
-
- Algs = proplists:get_value(preferred_algorithms, Config),
- {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
- {preferred_algorithms,Algs}]),
-
- {ok,RelayPid,_,RPort} = ssh_relay:start_link({0,0,0,0}, 0, Host, DPort),
-
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
- {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
-
- Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
-
- {ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
-
- ok = ssh_sftp:write(SftpPid, Handle, "hi\n"),
-
- ssh_relay:hold(RelayPid, rx, 20, 1000),
- ssh_connection_handler:renegotiate(ConnectionRef),
- spawn(fun() -> ok=ssh_sftp:write(SftpPid, Handle, "another hi\n") end),
-
- timer:sleep(2000),
-
- Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
-
- false = (Kex2 == Kex1),
-
- ssh_relay:stop(RelayPid),
- ssh_sftp:stop_channel(SftpPid),
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-
-%%% Test rekeying with inflight messages from peer
-
-renegotiate2(Config) ->
- UserDir = proplists:get_value(priv_dir, Config),
- DataFile = filename:join(UserDir, "renegotiate2.data"),
-
- Algs = proplists:get_value(preferred_algorithms, Config),
- {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
- {preferred_algorithms,Algs}]),
-
- {ok,RelayPid,_,RPort} = ssh_relay:start_link({0,0,0,0}, 0, Host, DPort),
-
- ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
- {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
-
- Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
-
- {ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
-
- ok = ssh_sftp:write(SftpPid, Handle, "hi\n"),
-
- ssh_relay:hold(RelayPid, rx, 20, infinity),
- spawn(fun() -> ok=ssh_sftp:write(SftpPid, Handle, "another hi\n") end),
- %% need a small pause here to ensure ssh_sftp:write is executed
- ct:sleep(10),
- ssh_connection_handler:renegotiate(ConnectionRef),
- ssh_relay:release(RelayPid, rx),
-
- timer:sleep(2000),
-
- Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
-
- false = (Kex2 == Kex1),
-
- ssh_relay:stop(RelayPid),
- ssh_sftp:stop_channel(SftpPid),
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
@@ -2134,9 +1452,3 @@ new_do_shell_prompt(IO, N, Op, Str, More) ->
ct:log("Matched prompt ~p",[N]),
new_do_shell(IO, N, [{Op,Str}|More]).
-%%--------------------------------------------------------------------
-inet_port() ->
- {ok, Socket} = gen_tcp:listen(0, [{reuseaddr, true}]),
- {ok, Port} = inet:port(Socket),
- gen_tcp:close(Socket),
- Port.
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_dsa b/lib/ssh/test/ssh_basic_SUITE_data/id_dsa
index d306f8b26e..24628e071b 100644
--- a/lib/ssh/test/ssh_basic_SUITE_data/id_dsa
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_dsa
@@ -1,13 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
-MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
-APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
-/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
-kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
-JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
-OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
-+9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
-uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
-Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
-ZU8w8Q+H7z0j+a+70x2iAw==
+MIIBuwIBAAKBgQDIywHurUpOq6kZuMn+XlRzR4hAxF6qwSkuEqkV7iHnLQ0kIwf3
+uAmjFDhuEsQ8653SLxGVvTNp+KFFgDXiLqgM7TPUwDnpbvzEZHPAU+/zPt4sdY2D
+txBfJwT2SFlK6HPOxOcxdDuD+/a59sh8hk/YVOU7ZTcBVsVG8Got4UcF5QIVAPGd
+CPDQKSTlPiM9OwBB1+9p11k5AoGARLxw4l17mET9cU0uf4Ppe5nsCbODJv44ZrSs
+picvypGVLrLcN5KWbm3vjRFCQ5LFunAG3FwLC2Sh0CH6TemoIfRPsRHR7wvpBGdr
+c693UlMOis/mcmvNMQAzuQNW9WrxdzsvWR/r5s6NEHWqKUJGXSPi2d+Ijq/mCOmI
+hzLzyiACgYEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4
+cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+C
+ROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNgCFEjA7wTC
+sQCY/I35vb6GUJn9tEdP
-----END DSA PRIVATE KEY-----
-
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_dsa.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_dsa.pub
new file mode 100644
index 0000000000..018ef6f537
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_dsa.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAMjLAe6tSk6rqRm4yf5eVHNHiEDEXqrBKS4SqRXuIectDSQjB/e4CaMUOG4SxDzrndIvEZW9M2n4oUWANeIuqAztM9TAOelu/MRkc8BT7/M+3ix1jYO3EF8nBPZIWUroc87E5zF0O4P79rn2yHyGT9hU5TtlNwFWxUbwai3hRwXlAAAAFQDxnQjw0Ckk5T4jPTsAQdfvaddZOQAAAIBEvHDiXXuYRP1xTS5/g+l7mewJs4Mm/jhmtKymJy/KkZUustw3kpZube+NEUJDksW6cAbcXAsLZKHQIfpN6agh9E+xEdHvC+kEZ2tzr3dSUw6Kz+Zya80xADO5A1b1avF3Oy9ZH+vmzo0QdaopQkZdI+LZ34iOr+YI6YiHMvPKIAAAAIEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+CROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNg= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_rsa b/lib/ssh/test/ssh_basic_SUITE_data/id_rsa
index 9d7e0dd5fb..2202c2ead8 100644
--- a/lib/ssh/test/ssh_basic_SUITE_data/id_rsa
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_rsa
@@ -1,15 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-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
+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
-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_rsa.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_rsa.pub
new file mode 100644
index 0000000000..b4084d320a
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDO2OLKPa11+SOLR97BZLSQAGDQgAGAbbQ28vU+cckuv3zB7vBbt/ePbsQaNb8Cm7JyxZdcqLQvzary4OJygcdvckjYmRPvSiLTIbUPH/PA8352QDssFPUndQraElMU+GnznkLBj+yz3GkGx3UW/fO4eJ8So0aWN6DU+OZDek2HED8zRplwud8hR1nkev637h6zfNpaji0sEqZm7oGRUZAo8Zd4yQgAy0mUbbiXuooNGRHlNgBlPs/xWfuGe4W4I1uslKbrzoZrAHFNBeibbd2D1RxbGgcHtSIcWhHqPRtABf7hHtsjBy6VENy/OuAK7q7TqgUgvBjsyWzGlf2EZOXX uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_compat_SUITE.erl b/lib/ssh/test/ssh_compat_SUITE.erl
index a8b3508583..f5f0a35bac 100644
--- a/lib/ssh/test/ssh_compat_SUITE.erl
+++ b/lib/ssh/test/ssh_compat_SUITE.erl
@@ -41,7 +41,7 @@
%%--------------------------------------------------------------------
suite() ->
- [{timetrap,{seconds,60}}].
+ [{timetrap,{seconds,90}}].
all() ->
%% [check_docker_present] ++
@@ -534,21 +534,22 @@ result_of_exec(C, Ch, ExitStatus, Acc) ->
chk_all_algos(FunctionName, CommonAlgs, Config, DoTestFun) when is_function(DoTestFun,2) ->
ct:comment("~p algorithms",[length(CommonAlgs)]),
%% Check each algorithm
- Failed =
+ Nmax = length(CommonAlgs),
+ {_N,Failed} =
lists:foldl(
- fun({Tag,Alg}, FailedAlgos) ->
- %% ct:log("Try ~p",[Alg]),
+ fun({Tag,Alg}, {N,FailedAlgos}) ->
+ ct:log("Try ~p ~p/~p",[{Tag,Alg},N,Nmax]),
case DoTestFun(Tag,Alg) of
{ok,C} ->
ssh:close(C),
- FailedAlgos;
+ {N+1,FailedAlgos};
ok ->
- FailedAlgos;
+ {N+1,FailedAlgos};
Other ->
ct:log("FAILED! ~p ~p: ~p",[Tag,Alg,Other]),
- [{Alg,Other}|FailedAlgos]
+ {N+1, [{Alg,Other}|FailedAlgos]}
end
- end, [], CommonAlgs),
+ end, {1,[]}, CommonAlgs),
ct:pal("~s", [format_result_table_use_all_algos(FunctionName, Config, CommonAlgs, Failed)]),
case Failed of
[] ->
diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl
index d428daaf59..c4621723f6 100644
--- a/lib/ssh/test/ssh_connection_SUITE.erl
+++ b/lib/ssh/test/ssh_connection_SUITE.erl
@@ -1270,37 +1270,6 @@ test_exec_is_enabled(ConnectionRef, Exec, Expect) ->
{fail,"Exec Timeout"}
end.
-
-%%%----------------------------------------------------------------
-get_channel_close_sequence(ConnectionRef, ChannelId) ->
- Set = [eof, exit_status, closed],
- get_channel_close_sequence(ConnectionRef, ChannelId, Set).
-
-get_channel_close_sequence(_ConnectionRef, _ChannelId, []) ->
- ok;
-get_channel_close_sequence(ConnectionRef, ChannelId, Set) ->
- receive
- {ssh_cm, ConnectionRef, Event} when element(2,Event) == ChannelId ->
- try lists:member(element(1,Event), Set)
- of
- true ->
- ct:log("get_channel_close_sequence: ~p received", [Event]),
- get_channel_close_sequence(ConnectionRef, Event, Set--[element(1,Event)]);
- false ->
- ct:log("~p:~p Got unexpected ~p~nExpecting ~p",[?MODULE,?LINE,Event,Set]),
- ct:fail("Strange response 1")
- catch
- _ :_ ->
- ct:log("~p:~p Got unexpected ~p~nExpecting ~p",[?MODULE,?LINE,Event,Set]),
- ct:fail("Strange response 2")
- end;
- Msg ->
- ct:log("~p:~p Got unexpected ~p~nExpecting event from the set ~p",[?MODULE,?LINE,Msg,Set]),
- ct:fail("Strange response 3")
- after
- 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
- end.
-
%%%----------------------------------------------------------------
big_cat_rx(ConnectionRef, ChannelId) ->
big_cat_rx(ConnectionRef, ChannelId, []).
diff --git a/lib/ssh/test/ssh_dbg_SUITE.erl b/lib/ssh/test/ssh_dbg_SUITE.erl
index ab7918fa90..8df9c8093a 100644
--- a/lib/ssh/test/ssh_dbg_SUITE.erl
+++ b/lib/ssh/test/ssh_dbg_SUITE.erl
@@ -82,6 +82,8 @@ end_per_testcase(_TC, Config) ->
ok
after 5000 ->
+ ct:log("~p:~p Messages:~n~p",
+ [?MODULE,?LINE, process_info(self(),messages)]),
ssh_dbg:stop(),
ssh:stop_daemon(Pid),
ct:fail("No '~s' debug message",[ExpectPfx])
@@ -448,10 +450,15 @@ dbg_SKIP(Ref, Prefixes) ->
dbg_SKIP(Ref, Prefixes, UnexpectedAcc) ->
receive
+ {Ref, [_, _C, Msg]} when is_tuple(Msg) ->
+ %% filter non ssh_dbg messages, for example from dbg:tp(..) etc
+ dbg_SKIP(Ref, Prefixes, UnexpectedAcc);
{Ref, [_, _C, Msg]=M} ->
case lists:any(
fun(Pfx) ->
- lists:prefix(Pfx, Msg)
+ try lists:prefix(Pfx, Msg)
+ catch _:_ -> false
+ end
end, Prefixes) of
true ->
ct:log("Skip:~n~p", [M]),
diff --git a/lib/ssh/test/ssh_engine_SUITE.erl b/lib/ssh/test/ssh_engine_SUITE.erl
index 3adb23acdb..241fb255cc 100644
--- a/lib/ssh/test/ssh_engine_SUITE.erl
+++ b/lib/ssh/test/ssh_engine_SUITE.erl
@@ -81,7 +81,7 @@ end_per_suite(Config) ->
%%--------------------------------------------------------------------
init_per_group(dsa_key, Config) ->
case lists:member('ssh-dss',
- ssh_transport:default_algorithms(public_key)) of
+ ssh_transport:supported_algorithms(public_key)) of
true ->
start_daemon(Config, 'ssh-dss', "dsa_private_key.pem");
false ->
@@ -89,7 +89,7 @@ init_per_group(dsa_key, Config) ->
end;
init_per_group(rsa_key, Config) ->
case lists:member('ssh-rsa',
- ssh_transport:default_algorithms(public_key)) of
+ ssh_transport:supported_algorithms(public_key)) of
true ->
start_daemon(Config, 'ssh-rsa', "rsa_private_key.pem");
false ->
@@ -102,9 +102,11 @@ start_daemon(Config, KeyType, KeyId) ->
KeyCBOpts = [{engine, proplists:get_value(engine,Config)},
{KeyType, FullKeyId}
],
- Opts = [{key_cb, {ssh_key_cb_engine_keys, KeyCBOpts}}],
+ Opts = [{key_cb, {ssh_key_cb_engine_keys, KeyCBOpts}},
+ {modify_algorithms, [{append, [{public_key,[KeyType]}]}]}
+ ],
{Pid, Host, Port} = ssh_test_lib:std_daemon(Config, Opts),
- [{host_port,{Host,Port}}, {daemon_pid,Pid}| Config].
+ [{host_port,{Host,Port}}, {daemon_pid,Pid}, {key_type,KeyType}| Config].
end_per_group(_, Config) ->
@@ -118,7 +120,11 @@ end_per_group(_, Config) ->
%% A simple exec call
simple_connect(Config) ->
{Host,Port} = proplists:get_value(host_port, Config),
- CRef = ssh_test_lib:std_connect(Config, Host, Port, []),
+ KeyType = proplists:get_value(key_type, Config),
+ Opts = [
+ {modify_algorithms, [{append, [{public_key,[KeyType]}]}]}
+ ],
+ CRef = ssh_test_lib:std_connect(Config, Host, Port, Opts),
ssh:close(CRef).
%%--------------------------------------------------------------------
@@ -146,8 +152,3 @@ load_engine() ->
{error, Error}
end.
-start_std_daemon(Opts, Config) ->
- ct:log("starting std_daemon",[]),
- {Pid, Host, Port} = ssh_test_lib:std_daemon(Config, Opts),
- ct:log("started ~p:~p ~p",[Host,Port,Opts]),
- [{srvr_pid,Pid},{srvr_addr,{Host,Port}} | Config].
diff --git a/lib/ssh/test/ssh_options_SUITE.erl b/lib/ssh/test/ssh_options_SUITE.erl
index 93c4d7b7a7..4368761d02 100644
--- a/lib/ssh/test/ssh_options_SUITE.erl
+++ b/lib/ssh/test/ssh_options_SUITE.erl
@@ -92,7 +92,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap,{seconds,30}}].
+ {timetrap,{seconds,60}}].
all() ->
[connectfun_disconnectfun_server,
@@ -128,9 +128,9 @@ all() ->
id_string_own_string_server_trail_space,
id_string_random_server,
save_accepted_host_option,
- {group, hardening_tests},
config_file,
- config_file_modify_algorithms_order
+ config_file_modify_algorithms_order,
+ {group, hardening_tests}
].
groups() ->
@@ -157,10 +157,8 @@ end_per_suite(_Config) ->
%%--------------------------------------------------------------------
init_per_group(hardening_tests, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_dsa(DataDir, PrivDir),
- ssh_test_lib:setup_rsa(DataDir, PrivDir),
+ ct:log("Pub keys setup for: ~p",
+ [ssh_test_lib:setup_all_user_host_keys(Config)]),
Config;
init_per_group(dir_options, Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
@@ -937,7 +935,7 @@ ssh_connect_arg4_timeout(_Config) ->
Msp = ms_passed(T0),
exit(Server,hasta_la_vista___baby),
Low = 0.9*Timeout,
- High = 2.5*Timeout,
+ High = 4.0*Timeout,
ct:log("Timeout limits: ~.4f - ~.4f ms, timeout "
"was ~.4f ms, expected ~p ms",[Low,High,Msp,Timeout]),
if
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_dsa b/lib/ssh/test/ssh_options_SUITE_data/id_dsa
index d306f8b26e..24628e071b 100644
--- a/lib/ssh/test/ssh_options_SUITE_data/id_dsa
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_dsa
@@ -1,13 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
-MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
-APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
-/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
-kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
-JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
-OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
-+9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
-uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
-Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
-ZU8w8Q+H7z0j+a+70x2iAw==
+MIIBuwIBAAKBgQDIywHurUpOq6kZuMn+XlRzR4hAxF6qwSkuEqkV7iHnLQ0kIwf3
+uAmjFDhuEsQ8653SLxGVvTNp+KFFgDXiLqgM7TPUwDnpbvzEZHPAU+/zPt4sdY2D
+txBfJwT2SFlK6HPOxOcxdDuD+/a59sh8hk/YVOU7ZTcBVsVG8Got4UcF5QIVAPGd
+CPDQKSTlPiM9OwBB1+9p11k5AoGARLxw4l17mET9cU0uf4Ppe5nsCbODJv44ZrSs
+picvypGVLrLcN5KWbm3vjRFCQ5LFunAG3FwLC2Sh0CH6TemoIfRPsRHR7wvpBGdr
+c693UlMOis/mcmvNMQAzuQNW9WrxdzsvWR/r5s6NEHWqKUJGXSPi2d+Ijq/mCOmI
+hzLzyiACgYEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4
+cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+C
+ROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNgCFEjA7wTC
+sQCY/I35vb6GUJn9tEdP
-----END DSA PRIVATE KEY-----
-
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_dsa.pub b/lib/ssh/test/ssh_options_SUITE_data/id_dsa.pub
new file mode 100644
index 0000000000..018ef6f537
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_dsa.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAMjLAe6tSk6rqRm4yf5eVHNHiEDEXqrBKS4SqRXuIectDSQjB/e4CaMUOG4SxDzrndIvEZW9M2n4oUWANeIuqAztM9TAOelu/MRkc8BT7/M+3ix1jYO3EF8nBPZIWUroc87E5zF0O4P79rn2yHyGT9hU5TtlNwFWxUbwai3hRwXlAAAAFQDxnQjw0Ckk5T4jPTsAQdfvaddZOQAAAIBEvHDiXXuYRP1xTS5/g+l7mewJs4Mm/jhmtKymJy/KkZUustw3kpZube+NEUJDksW6cAbcXAsLZKHQIfpN6agh9E+xEdHvC+kEZ2tzr3dSUw6Kz+Zya80xADO5A1b1avF3Oy9ZH+vmzo0QdaopQkZdI+LZ34iOr+YI6YiHMvPKIAAAAIEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+CROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNg= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa384
new file mode 100644
index 0000000000..4e8aa40959
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCYXb6OSAZyXRfLXOtMo43za197Hdc/T0YKjgQQjwDt6rlRwqTh7v7S
+PV2kXwNGdWigBwYFK4EEACKhZANiAARN2khlJUOOIiwsWHEALwDieeZR96qL4pUd
+ci7aeGaczdUK5jOA9D9zmBZtSYTfO8Cr7ekVghDlcWAIJ/BXcswgQwSEQ6wyfaTF
+8FYfyr4l3u9IirsnyaFzeIgeoNis8Gw=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa384.pub
new file mode 100644
index 0000000000..41e722e545
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE3aSGUlQ44iLCxYcQAvAOJ55lH3qovilR1yLtp4ZpzN1QrmM4D0P3OYFm1JhN87wKvt6RWCEOVxYAgn8FdyzCBDBIRDrDJ9pMXwVh/KviXe70iKuyfJoXN4iB6g2KzwbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa521
new file mode 100644
index 0000000000..7196f46e97
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEFMadoz4ckEcClfqXa2tiUuYkJdDfwq+/iFQcpt8ESuEd26IY/vm47Q
+9UzbPkO4ou8xkNsQ3WvCRQBBWtn5O2kUU6AHBgUrgQQAI6GBiQOBhgAEAde5BRu5
+01/jS0jRk212xsb2DxPrxNpgp6IMCV8TA4Eps+8bSqHB091nLiBcP422HXYfuCd7
+XDjSs8ihcmhp0hCRASLqZR9EzW9W/SOt876May1Huj5X+WSO6RLe7vPn9vmf7kHf
+pip6m7M7qp2qGgQ3q2vRwS2K/O6156ohiOlmuuFs
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa521.pub
new file mode 100644
index 0000000000..8f059120bc
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHXuQUbudNf40tI0ZNtdsbG9g8T68TaYKeiDAlfEwOBKbPvG0qhwdPdZy4gXD+Nth12H7gne1w40rPIoXJoadIQkQEi6mUfRM1vVv0jrfO+jGstR7o+V/lkjukS3u7z5/b5n+5B36YqepuzO6qdqhoEN6tr0cEtivzuteeqIYjpZrrhbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_ed25519 b/lib/ssh/test/ssh_options_SUITE_data/id_ed25519
new file mode 100644
index 0000000000..401a3e4a9a
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_ed25519
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDm9P8/gC0IOKmwHLSvkmEtS2Xx0RRqUDqC6wY6UgDVnwAAAJg3+6xpN/us
+aQAAAAtzc2gtZWQyNTUxOQAAACDm9P8/gC0IOKmwHLSvkmEtS2Xx0RRqUDqC6wY6UgDVnw
+AAAEBzC/Z2WGJhZ3l3tIBnUc6DCbp+lXY2yc2RRpWQTdf8sub0/z+ALQg4qbActK+SYS1L
+ZfHRFGpQOoLrBjpSANWfAAAAE3VhYmhuaWxAZWx4YWRsajNxMzIBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_ed25519.pub b/lib/ssh/test/ssh_options_SUITE_data/id_ed25519.pub
new file mode 100644
index 0000000000..a5c03b19c1
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_ed25519.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOb0/z+ALQg4qbActK+SYS1LZfHRFGpQOoLrBjpSANWf uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_ed448 b/lib/ssh/test/ssh_options_SUITE_data/id_ed448
new file mode 100644
index 0000000000..8ecfd710dc
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_ed448
@@ -0,0 +1,10 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA53OqeePNaG/NJmoMbELhskKrAHNhLZ6AQm1WjbpMoseNl/OFh
+1xznExpUPqTLX36fHYsAaWRHABQAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADnc6p5481ob80magxsQuGyQqsAc2EtnoBCbVaNukyix42X84WHXHOcTGlQ+pMtf
+fp8diwBpZEcAFAAAAAByzSPST3FCdOdENDI3uTKQ9RH2Ql+Y5kRZ/yA+iYUIP/32
+BQBVOrwOBc0CGEvbicTM1n4YeVEmfrMo3OqeePNaG/NJmoMbELhskKrAHNhLZ6AQ
+m1WjbpMoseNl/OFh1xznExpUPqTLX36fHYsAaWRHABQAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_ed448.pub b/lib/ssh/test/ssh_options_SUITE_data/id_ed448.pub
new file mode 100644
index 0000000000..cec0765a5d
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_ed448.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADnc6p5481ob80magxsQuGyQqsAc2EtnoBCbVaNukyix42X84WHXHOcTGlQ+pMtffp8diwBpZEcAFAA= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_rsa b/lib/ssh/test/ssh_options_SUITE_data/id_rsa
index 9d7e0dd5fb..2202c2ead8 100644
--- a/lib/ssh/test/ssh_options_SUITE_data/id_rsa
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_rsa
@@ -1,15 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-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
+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
-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_rsa.pub b/lib/ssh/test/ssh_options_SUITE_data/id_rsa.pub
new file mode 100644
index 0000000000..b4084d320a
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDO2OLKPa11+SOLR97BZLSQAGDQgAGAbbQ28vU+cckuv3zB7vBbt/ePbsQaNb8Cm7JyxZdcqLQvzary4OJygcdvckjYmRPvSiLTIbUPH/PA8352QDssFPUndQraElMU+GnznkLBj+yz3GkGx3UW/fO4eJ8So0aWN6DU+OZDek2HED8zRplwud8hR1nkev637h6zfNpaji0sEqZm7oGRUZAo8Zd4yQgAy0mUbbiXuooNGRHlNgBlPs/xWfuGe4W4I1uslKbrzoZrAHFNBeibbd2D1RxbGgcHtSIcWhHqPRtABf7hHtsjBy6VENy/OuAK7q7TqgUgvBjsyWzGlf2EZOXX uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..fb1a862ded
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDArxbDfh3p1okrD9wQw6jJ4d4DdlBPD5GqXE8bIeRJiK41Sh40LgvPw
+mkqEDSXK++CgBwYFK4EEACKhZANiAAScl43Ih2lWTDKrSox5ve5uiTXil4smsup3
+CfS1XPjKxgBAmlfBim8izbdrT0BFdQzz2joduNMtpt61wO4rGs6jm0UP7Kim9PC7
+Hneb/99fIYopdMH5NMnk60zGO1uZ2vc=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..428d5fb7d7
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJyXjciHaVZMMqtKjHm97m6JNeKXiyay6ncJ9LVc+MrGAECaV8GKbyLNt2tPQEV1DPPaOh240y2m3rXA7isazqObRQ/sqKb08Lsed5v/318hiil0wfk0yeTrTMY7W5na9w== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..3e51ec2ecd
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIB8O1BFkl2HQjQLRLonEZ97da/h39DMa9/0/hvPZWAI8gUPEQcHxRx
+U7b09p3Zh+EBbMFq8+1ae9ds+ZTxE4WFSvKgBwYFK4EEACOhgYkDgYYABAAlWVjq
+Bzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/
+vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5
+ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..017a29f4da
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAlWVjqBzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed25519_key b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed25519_key
new file mode 100644
index 0000000000..13a8fcf491
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed25519_key
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQAAAJi+h4O7voeD
+uwAAAAtzc2gtZWQyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQ
+AAAEBaOcJfGPNemKc1wPHTCmM4Kwvh6dZ0CqY14UT361UnN0lI66JgZZo72XJ7wGBp+h3W
+TDw/pxXddvaomAIHrIl9AAAAE3VhYmhuaWxAZWx4YWRsajNxMzIBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed25519_key.pub b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed25519_key.pub
new file mode 100644
index 0000000000..156ef4045c
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed25519_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIElI66JgZZo72XJ7wGBp+h3WTDw/pxXddvaomAIHrIl9 uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed448_key b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed448_key
new file mode 100644
index 0000000000..31a7e4e8c3
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed448_key
@@ -0,0 +1,10 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA5X9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2
+m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHl
+D2zR+hq+r+glYYAAAABybIKlYsuAjRDWMr6JyFE+v2ySnzTd+oyfY8mWDvbjSKNS
+jIo/zC8ETjmj/FuUSS+PAy51SaIAmPlbX9dEm1m0Yf0s54fsYWrUah2hNCSFpw4f
+ig6nXYDpZ3jt8SR2m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed448_key.pub b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed448_key.pub
new file mode 100644
index 0000000000..8c390dcb58
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_ed448_key.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHlD2zR+hq+r+glYYA=
diff --git a/lib/ssh/test/ssh_protocol_SUITE.erl b/lib/ssh/test/ssh_protocol_SUITE.erl
index 228e0dcbd8..3a08523039 100644
--- a/lib/ssh/test/ssh_protocol_SUITE.erl
+++ b/lib/ssh/test/ssh_protocol_SUITE.erl
@@ -907,10 +907,8 @@ stop_apps(_Config) ->
setup_dirs(Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_dsa(DataDir, PrivDir),
- ssh_test_lib:setup_rsa(DataDir, PrivDir),
+ ct:log("Pub keys setup for: ~p",
+ [ssh_test_lib:setup_all_user_host_keys(Config)]),
Config.
system_dir(Config) -> filename:join(proplists:get_value(priv_dir, Config), system).
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa b/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa
index d306f8b26e..24628e071b 100644
--- a/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa
@@ -1,13 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
-MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
-APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
-/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
-kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
-JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
-OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
-+9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
-uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
-Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
-ZU8w8Q+H7z0j+a+70x2iAw==
+MIIBuwIBAAKBgQDIywHurUpOq6kZuMn+XlRzR4hAxF6qwSkuEqkV7iHnLQ0kIwf3
+uAmjFDhuEsQ8653SLxGVvTNp+KFFgDXiLqgM7TPUwDnpbvzEZHPAU+/zPt4sdY2D
+txBfJwT2SFlK6HPOxOcxdDuD+/a59sh8hk/YVOU7ZTcBVsVG8Got4UcF5QIVAPGd
+CPDQKSTlPiM9OwBB1+9p11k5AoGARLxw4l17mET9cU0uf4Ppe5nsCbODJv44ZrSs
+picvypGVLrLcN5KWbm3vjRFCQ5LFunAG3FwLC2Sh0CH6TemoIfRPsRHR7wvpBGdr
+c693UlMOis/mcmvNMQAzuQNW9WrxdzsvWR/r5s6NEHWqKUJGXSPi2d+Ijq/mCOmI
+hzLzyiACgYEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4
+cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+C
+ROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNgCFEjA7wTC
+sQCY/I35vb6GUJn9tEdP
-----END DSA PRIVATE KEY-----
-
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa.pub b/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa.pub
new file mode 100644
index 0000000000..018ef6f537
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAMjLAe6tSk6rqRm4yf5eVHNHiEDEXqrBKS4SqRXuIectDSQjB/e4CaMUOG4SxDzrndIvEZW9M2n4oUWANeIuqAztM9TAOelu/MRkc8BT7/M+3ix1jYO3EF8nBPZIWUroc87E5zF0O4P79rn2yHyGT9hU5TtlNwFWxUbwai3hRwXlAAAAFQDxnQjw0Ckk5T4jPTsAQdfvaddZOQAAAIBEvHDiXXuYRP1xTS5/g+l7mewJs4Mm/jhmtKymJy/KkZUustw3kpZube+NEUJDksW6cAbcXAsLZKHQIfpN6agh9E+xEdHvC+kEZ2tzr3dSUw6Kz+Zya80xADO5A1b1avF3Oy9ZH+vmzo0QdaopQkZdI+LZ34iOr+YI6YiHMvPKIAAAAIEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+CROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNg= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa384
new file mode 100644
index 0000000000..4e8aa40959
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCYXb6OSAZyXRfLXOtMo43za197Hdc/T0YKjgQQjwDt6rlRwqTh7v7S
+PV2kXwNGdWigBwYFK4EEACKhZANiAARN2khlJUOOIiwsWHEALwDieeZR96qL4pUd
+ci7aeGaczdUK5jOA9D9zmBZtSYTfO8Cr7ekVghDlcWAIJ/BXcswgQwSEQ6wyfaTF
+8FYfyr4l3u9IirsnyaFzeIgeoNis8Gw=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa384.pub
new file mode 100644
index 0000000000..41e722e545
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE3aSGUlQ44iLCxYcQAvAOJ55lH3qovilR1yLtp4ZpzN1QrmM4D0P3OYFm1JhN87wKvt6RWCEOVxYAgn8FdyzCBDBIRDrDJ9pMXwVh/KviXe70iKuyfJoXN4iB6g2KzwbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa521
new file mode 100644
index 0000000000..7196f46e97
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEFMadoz4ckEcClfqXa2tiUuYkJdDfwq+/iFQcpt8ESuEd26IY/vm47Q
+9UzbPkO4ou8xkNsQ3WvCRQBBWtn5O2kUU6AHBgUrgQQAI6GBiQOBhgAEAde5BRu5
+01/jS0jRk212xsb2DxPrxNpgp6IMCV8TA4Eps+8bSqHB091nLiBcP422HXYfuCd7
+XDjSs8ihcmhp0hCRASLqZR9EzW9W/SOt876May1Huj5X+WSO6RLe7vPn9vmf7kHf
+pip6m7M7qp2qGgQ3q2vRwS2K/O6156ohiOlmuuFs
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa521.pub
new file mode 100644
index 0000000000..8f059120bc
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHXuQUbudNf40tI0ZNtdsbG9g8T68TaYKeiDAlfEwOBKbPvG0qhwdPdZy4gXD+Nth12H7gne1w40rPIoXJoadIQkQEi6mUfRM1vVv0jrfO+jGstR7o+V/lkjukS3u7z5/b5n+5B36YqepuzO6qdqhoEN6tr0cEtivzuteeqIYjpZrrhbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_ed25519 b/lib/ssh/test/ssh_protocol_SUITE_data/id_ed25519
new file mode 100644
index 0000000000..401a3e4a9a
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_ed25519
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDm9P8/gC0IOKmwHLSvkmEtS2Xx0RRqUDqC6wY6UgDVnwAAAJg3+6xpN/us
+aQAAAAtzc2gtZWQyNTUxOQAAACDm9P8/gC0IOKmwHLSvkmEtS2Xx0RRqUDqC6wY6UgDVnw
+AAAEBzC/Z2WGJhZ3l3tIBnUc6DCbp+lXY2yc2RRpWQTdf8sub0/z+ALQg4qbActK+SYS1L
+ZfHRFGpQOoLrBjpSANWfAAAAE3VhYmhuaWxAZWx4YWRsajNxMzIBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_ed25519.pub b/lib/ssh/test/ssh_protocol_SUITE_data/id_ed25519.pub
new file mode 100644
index 0000000000..a5c03b19c1
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_ed25519.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOb0/z+ALQg4qbActK+SYS1LZfHRFGpQOoLrBjpSANWf uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_ed448 b/lib/ssh/test/ssh_protocol_SUITE_data/id_ed448
new file mode 100644
index 0000000000..8ecfd710dc
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_ed448
@@ -0,0 +1,10 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA53OqeePNaG/NJmoMbELhskKrAHNhLZ6AQm1WjbpMoseNl/OFh
+1xznExpUPqTLX36fHYsAaWRHABQAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADnc6p5481ob80magxsQuGyQqsAc2EtnoBCbVaNukyix42X84WHXHOcTGlQ+pMtf
+fp8diwBpZEcAFAAAAAByzSPST3FCdOdENDI3uTKQ9RH2Ql+Y5kRZ/yA+iYUIP/32
+BQBVOrwOBc0CGEvbicTM1n4YeVEmfrMo3OqeePNaG/NJmoMbELhskKrAHNhLZ6AQ
+m1WjbpMoseNl/OFh1xznExpUPqTLX36fHYsAaWRHABQAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_ed448.pub b/lib/ssh/test/ssh_protocol_SUITE_data/id_ed448.pub
new file mode 100644
index 0000000000..cec0765a5d
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_ed448.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADnc6p5481ob80magxsQuGyQqsAc2EtnoBCbVaNukyix42X84WHXHOcTGlQ+pMtffp8diwBpZEcAFAA= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa b/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa
index 9d7e0dd5fb..2202c2ead8 100644
--- a/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa
@@ -1,15 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-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
+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
-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa.pub b/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa.pub
new file mode 100644
index 0000000000..b4084d320a
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDO2OLKPa11+SOLR97BZLSQAGDQgAGAbbQ28vU+cckuv3zB7vBbt/ePbsQaNb8Cm7JyxZdcqLQvzary4OJygcdvckjYmRPvSiLTIbUPH/PA8352QDssFPUndQraElMU+GnznkLBj+yz3GkGx3UW/fO4eJ8So0aWN6DU+OZDek2HED8zRplwud8hR1nkev637h6zfNpaji0sEqZm7oGRUZAo8Zd4yQgAy0mUbbiXuooNGRHlNgBlPs/xWfuGe4W4I1uslKbrzoZrAHFNBeibbd2D1RxbGgcHtSIcWhHqPRtABf7hHtsjBy6VENy/OuAK7q7TqgUgvBjsyWzGlf2EZOXX uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..fb1a862ded
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDArxbDfh3p1okrD9wQw6jJ4d4DdlBPD5GqXE8bIeRJiK41Sh40LgvPw
+mkqEDSXK++CgBwYFK4EEACKhZANiAAScl43Ih2lWTDKrSox5ve5uiTXil4smsup3
+CfS1XPjKxgBAmlfBim8izbdrT0BFdQzz2joduNMtpt61wO4rGs6jm0UP7Kim9PC7
+Hneb/99fIYopdMH5NMnk60zGO1uZ2vc=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..428d5fb7d7
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJyXjciHaVZMMqtKjHm97m6JNeKXiyay6ncJ9LVc+MrGAECaV8GKbyLNt2tPQEV1DPPaOh240y2m3rXA7isazqObRQ/sqKb08Lsed5v/318hiil0wfk0yeTrTMY7W5na9w== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..3e51ec2ecd
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIB8O1BFkl2HQjQLRLonEZ97da/h39DMa9/0/hvPZWAI8gUPEQcHxRx
+U7b09p3Zh+EBbMFq8+1ae9ds+ZTxE4WFSvKgBwYFK4EEACOhgYkDgYYABAAlWVjq
+Bzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/
+vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5
+ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..017a29f4da
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAlWVjqBzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed25519_key b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed25519_key
new file mode 100644
index 0000000000..13a8fcf491
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed25519_key
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQAAAJi+h4O7voeD
+uwAAAAtzc2gtZWQyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQ
+AAAEBaOcJfGPNemKc1wPHTCmM4Kwvh6dZ0CqY14UT361UnN0lI66JgZZo72XJ7wGBp+h3W
+TDw/pxXddvaomAIHrIl9AAAAE3VhYmhuaWxAZWx4YWRsajNxMzIBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed25519_key.pub b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed25519_key.pub
new file mode 100644
index 0000000000..156ef4045c
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed25519_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIElI66JgZZo72XJ7wGBp+h3WTDw/pxXddvaomAIHrIl9 uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed448_key b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed448_key
new file mode 100644
index 0000000000..31a7e4e8c3
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed448_key
@@ -0,0 +1,10 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA5X9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2
+m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHl
+D2zR+hq+r+glYYAAAABybIKlYsuAjRDWMr6JyFE+v2ySnzTd+oyfY8mWDvbjSKNS
+jIo/zC8ETjmj/FuUSS+PAy51SaIAmPlbX9dEm1m0Yf0s54fsYWrUah2hNCSFpw4f
+ig6nXYDpZ3jt8SR2m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed448_key.pub b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed448_key.pub
new file mode 100644
index 0000000000..8c390dcb58
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_ed448_key.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHlD2zR+hq+r+glYYA=
diff --git a/lib/ssh/test/ssh_pubkey_SUITE.erl b/lib/ssh/test/ssh_pubkey_SUITE.erl
index fbc17e5028..f1afb496c1 100644
--- a/lib/ssh/test/ssh_pubkey_SUITE.erl
+++ b/lib/ssh/test/ssh_pubkey_SUITE.erl
@@ -36,7 +36,8 @@ suite() ->
all() ->
[{group, old_format},
- {group, new_format}
+ {group, new_format},
+ {group, option_space}
].
@@ -51,19 +52,31 @@ all() ->
connect_ecdsa_to_ecdsa
]).
--define(tests_new, [connect_ecdsa_to_ed25519,
- connect_rsa_to_ed25519,
+-define(tests_new, [
connect_dsa_to_ed25519,
- connect_ed25519_to_rsa,
+ connect_dsa_to_ed448,
+ connect_ecdsa_to_ed25519,
+ connect_ecdsa_to_ed448,
connect_ed25519_to_dsa,
connect_ed25519_to_ecdsa,
- connect_ed25519_to_ed25519
- | ?tests_old]).
+ connect_ed25519_to_ed448,
+ connect_ed25519_to_ed25519,
+ connect_ed25519_to_rsa,
+ connect_ed448_to_dsa,
+ connect_ed448_to_ecdsa,
+ connect_ed448_to_ed25519,
+ connect_ed448_to_ed448,
+ connect_ed448_to_rsa,
+ connect_rsa_to_ed25519,
+ connect_rsa_to_ed448
+ | ?tests_old % but taken from the new format directory
+ ]).
groups() ->
- [{new_format, [], ?tests_new},
- {old_format, [], ?tests_old++[{group,passphrase}]},
- {passphrase, [], ?tests_old}
+ [{new_format, [], ?tests_new},
+ {old_format, [], ?tests_old++[{group,passphrase}]},
+ {passphrase, [], ?tests_old},
+ {option_space,[], [{group,new_format}]}
].
%%%----------------------------------------------------------------
@@ -71,7 +84,8 @@ init_per_suite(Config) ->
?CHECK_CRYPTO(
begin
ssh:start(),
- [{client_opts,[]}
+ [{client_opts,[]},
+ {daemon_opts,[]}
| Config]
end).
@@ -89,6 +103,11 @@ init_per_group(old_format, Config) ->
[{fmt,old_format},
{key_src_dir,Dir} | Config];
+init_per_group(option_space, Config) ->
+ extend_optsL([client_opts,daemon_opts],
+ [{key_cb, {ssh_file, [{optimize, space}]}}],
+ Config);
+
init_per_group(passphrase, Config0) ->
case supported(hashs, md5) of
true ->
@@ -110,7 +129,11 @@ extend_opts(OptName, Value, Config) ->
Opts = proplists:get_value(OptName, Config),
replace_opt(OptName, [Value|Opts], Config).
-extend_optsL(OptName, Values, Config) ->
+extend_optsL(OptNames, Values, Config) when is_list(OptNames) ->
+ lists:foldl(fun(N, Cnf) ->
+ extend_optsL(N, Values, Cnf)
+ end, Config, OptNames);
+extend_optsL(OptName, Values, Config) when is_atom(OptName) ->
Opts = proplists:get_value(OptName, Config),
replace_opt(OptName, Values ++ Opts, Config).
@@ -131,6 +154,8 @@ init_per_testcase(connect_rsa_to_ecdsa, Config0) ->
setup_user_system_dir(rsa, ecdsa, Config0);
init_per_testcase(connect_rsa_to_ed25519, Config0) ->
setup_user_system_dir(rsa, ed25519, Config0);
+init_per_testcase(connect_rsa_to_ed448, Config0) ->
+ setup_user_system_dir(rsa, ed448, Config0);
init_per_testcase(connect_dsa_to_rsa, Config0) ->
setup_user_system_dir(dsa, rsa, Config0);
init_per_testcase(connect_dsa_to_dsa, Config0) ->
@@ -139,6 +164,8 @@ init_per_testcase(connect_dsa_to_ecdsa, Config0) ->
setup_user_system_dir(dsa, ecdsa, Config0);
init_per_testcase(connect_dsa_to_ed25519, Config0) ->
setup_user_system_dir(dsa, ed25519, Config0);
+init_per_testcase(connect_dsa_to_ed448, Config0) ->
+ setup_user_system_dir(dsa, ed448, Config0);
init_per_testcase(connect_ecdsa_to_rsa, Config0) ->
setup_user_system_dir(ecdsa, rsa, Config0);
init_per_testcase(connect_ecdsa_to_dsa, Config0) ->
@@ -147,6 +174,8 @@ init_per_testcase(connect_ecdsa_to_ecdsa, Config0) ->
setup_user_system_dir(ecdsa, ecdsa, Config0);
init_per_testcase(connect_ecdsa_to_ed25519, Config0) ->
setup_user_system_dir(ecdsa, ed25519, Config0);
+init_per_testcase(connect_ecdsa_to_ed448, Config0) ->
+ setup_user_system_dir(ecdsa, ed448, Config0);
init_per_testcase(connect_ed25519_to_rsa, Config0) ->
setup_user_system_dir(ed25519, rsa, Config0);
init_per_testcase(connect_ed25519_to_dsa, Config0) ->
@@ -155,6 +184,18 @@ init_per_testcase(connect_ed25519_to_ecdsa, Config0) ->
setup_user_system_dir(ed25519, ecdsa, Config0);
init_per_testcase(connect_ed25519_to_ed25519, Config0) ->
setup_user_system_dir(ed25519, ed25519, Config0);
+init_per_testcase(connect_ed25519_to_ed448, Config0) ->
+ setup_user_system_dir(ed25519, ed448, Config0);
+init_per_testcase(connect_ed448_to_rsa, Config0) ->
+ setup_user_system_dir(ed448, rsa, Config0);
+init_per_testcase(connect_ed448_to_dsa, Config0) ->
+ setup_user_system_dir(ed448, dsa, Config0);
+init_per_testcase(connect_ed448_to_ecdsa, Config0) ->
+ setup_user_system_dir(ed448, ecdsa, Config0);
+init_per_testcase(connect_ed448_to_ed25519, Config0) ->
+ setup_user_system_dir(ed448, ed25519, Config0);
+init_per_testcase(connect_ed448_to_ed448, Config0) ->
+ setup_user_system_dir(ed448, ed448, Config0);
init_per_testcase(_, Config) ->
Config.
@@ -176,6 +217,9 @@ connect_rsa_to_ecdsa(Config) ->
connect_rsa_to_ed25519(Config) ->
try_connect(Config).
+connect_rsa_to_ed448(Config) ->
+ try_connect(Config).
+
connect_dsa_to_rsa(Config) ->
try_connect(Config).
@@ -188,6 +232,9 @@ connect_dsa_to_ecdsa(Config) ->
connect_dsa_to_ed25519(Config) ->
try_connect(Config).
+connect_dsa_to_ed448(Config) ->
+ try_connect(Config).
+
connect_ecdsa_to_rsa(Config) ->
try_connect(Config).
@@ -200,6 +247,9 @@ connect_ecdsa_to_ecdsa(Config) ->
connect_ecdsa_to_ed25519(Config) ->
try_connect(Config).
+connect_ecdsa_to_ed448(Config) ->
+ try_connect(Config).
+
connect_ed25519_to_rsa(Config) ->
try_connect(Config).
@@ -212,6 +262,24 @@ connect_ed25519_to_ecdsa(Config) ->
connect_ed25519_to_ed25519(Config) ->
try_connect(Config).
+connect_ed25519_to_ed448(Config) ->
+ try_connect(Config).
+
+connect_ed448_to_rsa(Config) ->
+ try_connect(Config).
+
+connect_ed448_to_dsa(Config) ->
+ try_connect(Config).
+
+connect_ed448_to_ecdsa(Config) ->
+ try_connect(Config).
+
+connect_ed448_to_ed25519(Config) ->
+ try_connect(Config).
+
+connect_ed448_to_ed448(Config) ->
+ try_connect(Config).
+
%%%----------------------------------------------------------------
try_connect({skip,Reson}) ->
@@ -220,9 +288,12 @@ try_connect(Config) ->
SystemDir = proplists:get_value(system_dir, Config),
UserDir = proplists:get_value(user_dir, Config),
ClientOpts = proplists:get_value(client_opts, Config, []),
+ DaemonOpts = proplists:get_value(daemon_opts, Config, []),
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir}]),
+ {user_dir, UserDir}
+ | DaemonOpts]),
+
C = ssh_test_lib:connect(Host, Port, [{user_dir, UserDir},
{silently_accept_hosts, true},
{user_interaction, false}
@@ -250,18 +321,32 @@ setup_user_system_dir(ClientAlg, ServerAlg, Config) ->
HostSrcFile = filename:join(KeySrcDir, file(host,ServerAlg)),
HostDstFile = filename:join(SystemDir, file(host,ServerAlg)),
- {ok,_} = file:copy(HostSrcFile, HostDstFile),
UserSrcFile = filename:join(KeySrcDir, file(user,ClientAlg)),
UserDstFile = filename:join(UserDir, file(user,ClientAlg)),
- {ok,_} = file:copy(UserSrcFile, UserDstFile),
UserPubSrcFile = filename:join(KeySrcDir, file(user,ClientAlg)++".pub"),
AuthorizedKeys = filename:join(UserDir, "authorized_keys"),
- {ok,_} = file:copy(UserPubSrcFile, AuthorizedKeys),
- [{system_dir,SystemDir},
- {user_dir,UserDir} | Config];
+ try
+ {ok,_} = file:copy(UserSrcFile, UserDstFile),
+ {ok,_} = file:copy(UserPubSrcFile, AuthorizedKeys),
+ {ok,_} = file:copy(HostSrcFile, HostDstFile)
+ of
+ _ ->
+ ModAlgs = [{modify_algorithms,
+ [{append,[{public_key,
+ lists:usort([alg(ClientAlg),
+ alg(ServerAlg)])}]}]}
+ ],
+ [{system_dir,SystemDir},
+ {user_dir,UserDir}
+ | extend_optsL([daemon_opts,client_opts], ModAlgs, Config)]
+ catch
+ error:{badmatch,{error,enoent}}:S ->
+ ct:log("~p:~p Stack:~n~p", [?MODULE,?LINE,S]),
+ {skip, no_key_file_found}
+ end;
false ->
{skip, unsupported_algorithm}
@@ -271,12 +356,20 @@ setup_user_system_dir(ClientAlg, ServerAlg, Config) ->
file(host, dsa) -> "ssh_host_dsa_key";
file(host, ecdsa) -> "ssh_host_ecdsa_key";
file(host, ed25519) -> "ssh_host_ed25519_key";
+file(host, ed448) -> "ssh_host_ed448_key";
file(host, rsa) -> "ssh_host_rsa_key";
file(user, dsa) -> "id_dsa";
file(user, ecdsa) -> "id_ecdsa";
file(user, ed25519) -> "id_ed25519";
+file(user, ed448) -> "id_ed448";
file(user, rsa) -> "id_rsa".
+alg(dsa) -> 'ssh-dss';
+alg(ecdsa) -> 'ecdsa-sha2-nistp256';
+alg(ed25519) -> 'ssh-ed25519';
+alg(ed448) -> 'ssh-ed448';
+alg(rsa) -> 'ssh-rsa'.
+
supported(public_keys, rsa) -> supported(public_key, 'ssh-rsa') orelse
supported(public_key, 'rsa-sha2-256') orelse
@@ -288,7 +381,7 @@ supported(public_keys, ecdsa) -> supported(public_key, 'ecdsa-sha2-nistp256')
supported(public_keys, ed448) -> supported(public_key, 'ssh-ed448');
supported(public_keys, ed25519) -> supported(public_key, 'ssh-ed25519');
supported(Type, Alg) ->
- case proplists:get_value(Type,ssh:default_algorithms()) of
+ case proplists:get_value(Type,ssh_transport:supported_algorithms()) of
undefined ->
lists:member(Alg, crypto:supports(Type));
L ->
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/id_ed448 b/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/id_ed448
new file mode 100644
index 0000000000..fc8e79e8f0
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/id_ed448
@@ -0,0 +1,15 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+A: Key
+SomeKey: Very long \
+line \
+spanning more lines \
+
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA5X9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2
+m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHl
+D2zR+hq+r+glYYAAAABybIKlYsuAjRDWMr6JyFE+v2ySnzTd+oyfY8mWDvbjSKNS
+jIo/zC8ETjmj/FuUSS+PAy51SaIAmPlbX9dEm1m0Yf0s54fsYWrUah2hNCSFpw4f
+ig6nXYDpZ3jt8SR2m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/id_ed448.pub b/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/id_ed448.pub
new file mode 100644
index 0000000000..8c390dcb58
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/id_ed448.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHlD2zR+hq+r+glYYA=
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/ssh_host_ed448_key b/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/ssh_host_ed448_key
new file mode 100644
index 0000000000..fc8e79e8f0
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/ssh_host_ed448_key
@@ -0,0 +1,15 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+A: Key
+SomeKey: Very long \
+line \
+spanning more lines \
+
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA5X9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2
+m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHl
+D2zR+hq+r+glYYAAAABybIKlYsuAjRDWMr6JyFE+v2ySnzTd+oyfY8mWDvbjSKNS
+jIo/zC8ETjmj/FuUSS+PAy51SaIAmPlbX9dEm1m0Yf0s54fsYWrUah2hNCSFpw4f
+ig6nXYDpZ3jt8SR2m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/ssh_host_ed448_key.pub b/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/ssh_host_ed448_key.pub
new file mode 100644
index 0000000000..8c390dcb58
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/new_format/ssh_host_ed448_key.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHlD2zR+hq+r+glYYA=
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE.erl b/lib/ssh/test/ssh_renegotiate_SUITE.erl
new file mode 100644
index 0000000000..b08a5ab1eb
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE.erl
@@ -0,0 +1,393 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2020. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssh_renegotiate_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("kernel/include/inet.hrl").
+-include_lib("kernel/include/file.hrl").
+-include("ssh_test_lib.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(NEWLINE, <<"\r\n">>).
+
+-define(REKEY_DATA_TMO, 1 * 60000). % Should be multiples of 60000
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{seconds,90}}].
+
+all() ->
+ [{group, renegotiate}
+ ].
+
+groups() ->
+ [{renegotiate, [parallel], [rekey0,
+ rekey1,
+ rekey2,
+ rekey3,
+ rekey4,
+ rekey_limit_client,
+ rekey_limit_daemon,
+ rekey_time_limit_client,
+ rekey_time_limit_daemon,
+ norekey_limit_client,
+ norekey_limit_daemon,
+ renegotiate1,
+ renegotiate2]}
+ ].
+
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ ?CHECK_CRYPTO(begin
+ ssh:start(),
+ ct:log("Pub keys setup for: ~p",
+ [ssh_test_lib:setup_all_user_host_keys(Config)]),
+ [{preferred_algorithms,ssh_transport:supported_algorithms()}
+ | Config]
+ end).
+
+end_per_suite(_Config) ->
+ ssh:stop().
+
+
+init_per_group(_, Config) -> Config.
+
+end_per_group(_, Config) -> Config.
+%%----------------------------------------------------------------------------
+%%% Idle timeout test
+rekey0() -> [{timetrap,{seconds,120}}].
+rekey1() -> [{timetrap,{seconds,120}}].
+rekey2() -> [{timetrap,{seconds,120}}].
+rekey3() -> [{timetrap,{seconds,120}}].
+rekey4() -> [{timetrap,{seconds,120}}].
+
+rekey0(Config) -> rekey_chk(Config, 0, 0).
+rekey1(Config) -> rekey_chk(Config, infinity, 0).
+rekey2(Config) -> rekey_chk(Config, {infinity,infinity}, 0).
+rekey3(Config) -> rekey_chk(Config, 0, infinity).
+rekey4(Config) -> rekey_chk(Config, 0, {infinity,infinity}).
+
+rekey_chk(Config, RLdaemon, RLclient) ->
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config, [{rekey_limit, RLdaemon}]),
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, RLclient}]),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
+
+ %% Make both sides send something:
+ {ok, _SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+
+ %% Check rekeying
+ timer:sleep(?REKEY_DATA_TMO),
+ ?wait_match(false, Kex1==ssh_test_lib:get_kex_init(ConnectionRef), [], 2000, 10),
+
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+%%% Test rekeying by data volume
+
+rekey_limit_client() -> [{timetrap,{seconds,500}}].
+rekey_limit_client(Config) ->
+ Limit = 6000,
+ UserDir = proplists:get_value(priv_dir, Config),
+ DataFile = filename:join(UserDir, "rekey.data"),
+ Data = lists:duplicate(Limit+10,1),
+ Algs = proplists:get_value(preferred_algorithms, Config),
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, Limit},
+ {max_random_length_padding,0}]),
+ {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+
+ %% Check that it doesn't rekey without data transfer
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
+ timer:sleep(?REKEY_DATA_TMO),
+ true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ %% Check that datatransfer triggers rekeying
+ ok = ssh_sftp:write_file(SftpPid, DataFile, Data),
+ timer:sleep(?REKEY_DATA_TMO),
+ ?wait_match(false, Kex1==(Kex2=ssh_test_lib:get_kex_init(ConnectionRef)), Kex2, 2000, 10),
+
+ %% Check that datatransfer continues to trigger rekeying
+ ok = ssh_sftp:write_file(SftpPid, DataFile, Data),
+ timer:sleep(?REKEY_DATA_TMO),
+ ?wait_match(false, Kex2==(Kex3=ssh_test_lib:get_kex_init(ConnectionRef)), Kex3, 2000, 10),
+
+ %% Check that it doesn't rekey without data transfer
+ timer:sleep(?REKEY_DATA_TMO),
+ true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ %% Check that it doesn't rekey on a small datatransfer
+ ok = ssh_sftp:write_file(SftpPid, DataFile, "hi\n"),
+ timer:sleep(?REKEY_DATA_TMO),
+ true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ %% Check that it doesn't rekey without data transfer
+ timer:sleep(?REKEY_DATA_TMO),
+ true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+
+
+rekey_limit_daemon() -> [{timetrap,{seconds,500}}].
+rekey_limit_daemon(Config) ->
+ Limit = 6000,
+ UserDir = proplists:get_value(priv_dir, Config),
+ DataFile1 = filename:join(UserDir, "rekey1.data"),
+ DataFile2 = filename:join(UserDir, "rekey2.data"),
+ file:write_file(DataFile1, lists:duplicate(Limit+10,1)),
+ file:write_file(DataFile2, "hi\n"),
+
+ Algs = proplists:get_value(preferred_algorithms, Config),
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{rekey_limit, Limit},
+ {max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{max_random_length_padding,0}]),
+ {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+
+ %% Check that it doesn't rekey without data transfer
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
+ timer:sleep(?REKEY_DATA_TMO),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
+
+ %% Check that datatransfer triggers rekeying
+ {ok,_} = ssh_sftp:read_file(SftpPid, DataFile1),
+ timer:sleep(?REKEY_DATA_TMO),
+ ?wait_match(false, Kex1==(Kex2=ssh_test_lib:get_kex_init(ConnectionRef)), Kex2, 2000, 10),
+
+ %% Check that datatransfer continues to trigger rekeying
+ {ok,_} = ssh_sftp:read_file(SftpPid, DataFile1),
+ timer:sleep(?REKEY_DATA_TMO),
+ ?wait_match(false, Kex2==(Kex3=ssh_test_lib:get_kex_init(ConnectionRef)), Kex3, 2000, 10),
+
+ %% Check that it doesn't rekey without data transfer
+ timer:sleep(?REKEY_DATA_TMO),
+ true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ %% Check that it doesn't rekey on a small datatransfer
+ {ok,_} = ssh_sftp:read_file(SftpPid, DataFile2),
+ timer:sleep(?REKEY_DATA_TMO),
+ true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ %% Check that it doesn't rekey without data transfer
+ timer:sleep(?REKEY_DATA_TMO),
+ true = (Kex3 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
+%% Check that datatransfer in the other direction does not trigger re-keying
+norekey_limit_client() -> [{timetrap,{seconds,500}}].
+norekey_limit_client(Config) ->
+ Limit = 6000,
+ UserDir = proplists:get_value(priv_dir, Config),
+ DataFile = filename:join(UserDir, "rekey3.data"),
+ file:write_file(DataFile, lists:duplicate(Limit+10,1)),
+
+ Algs = proplists:get_value(preferred_algorithms, Config),
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, Limit},
+ {max_random_length_padding,0}]),
+ {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
+ timer:sleep(?REKEY_DATA_TMO),
+ true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ {ok,_} = ssh_sftp:read_file(SftpPid, DataFile),
+ timer:sleep(?REKEY_DATA_TMO),
+ true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%% Check that datatransfer in the other direction does not trigger re-keying
+norekey_limit_daemon() -> [{timetrap,{seconds,500}}].
+norekey_limit_daemon(Config) ->
+ Limit = 6000,
+ UserDir = proplists:get_value(priv_dir, Config),
+ DataFile = filename:join(UserDir, "rekey4.data"),
+
+ Algs = proplists:get_value(preferred_algorithms, Config),
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{rekey_limit, Limit},
+ {max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{max_random_length_padding,0}]),
+ {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
+ timer:sleep(?REKEY_DATA_TMO),
+ true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ ok = ssh_sftp:write_file(SftpPid, DataFile, lists:duplicate(Limit+10,1)),
+ timer:sleep(?REKEY_DATA_TMO),
+ true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+%%% Test rekeying by time
+
+rekey_time_limit_client() -> [{timetrap,{seconds,500}}].
+rekey_time_limit_client(Config) ->
+ Minutes = ?REKEY_DATA_TMO div 60000,
+ GB = 1024*1000*1000,
+ Algs = proplists:get_value(preferred_algorithms, Config),
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, {Minutes, GB}},
+ {max_random_length_padding,0}]),
+ rekey_time_limit(Pid, ConnectionRef).
+
+rekey_time_limit_daemon() -> [{timetrap,{seconds,500}}].
+rekey_time_limit_daemon(Config) ->
+ Minutes = ?REKEY_DATA_TMO div 60000,
+ GB = 1024*1000*1000,
+ Algs = proplists:get_value(preferred_algorithms, Config),
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{rekey_limit, {Minutes, GB}},
+ {max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{max_random_length_padding,0}]),
+ rekey_time_limit(Pid, ConnectionRef).
+
+
+rekey_time_limit(Pid, ConnectionRef) ->
+ {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
+
+ timer:sleep(5000),
+ true = (Kex1 == ssh_test_lib:get_kex_init(ConnectionRef)),
+
+ %% Check that it rekeys when the max time + 30s has passed
+ timer:sleep(?REKEY_DATA_TMO + 30*1000),
+ ?wait_match(false, Kex1==(Kex2=ssh_test_lib:get_kex_init(ConnectionRef)), Kex2, 2000, 10),
+
+ %% Check that it does not rekey when nothing is transferred
+ timer:sleep(?REKEY_DATA_TMO + 30*1000),
+ ?wait_match(false, Kex2==ssh_test_lib:get_kex_init(ConnectionRef), [], 2000, 10),
+
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+
+%%% Test rekeying with simultaneous send request
+
+renegotiate1(Config) ->
+ UserDir = proplists:get_value(priv_dir, Config),
+ DataFile = filename:join(UserDir, "renegotiate1.data"),
+
+ Algs = proplists:get_value(preferred_algorithms, Config),
+ {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+
+ {ok,RelayPid,_,RPort} = ssh_relay:start_link({0,0,0,0}, 0, Host, DPort),
+
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
+ {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
+
+ {ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
+
+ ok = ssh_sftp:write(SftpPid, Handle, "hi\n"),
+
+ ssh_relay:hold(RelayPid, rx, 20, 1000),
+ ssh_connection_handler:renegotiate(ConnectionRef),
+ spawn(fun() -> ok=ssh_sftp:write(SftpPid, Handle, "another hi\n") end),
+
+ timer:sleep(2000),
+
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
+
+ false = (Kex2 == Kex1),
+
+ ssh_relay:stop(RelayPid),
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+
+%%% Test rekeying with inflight messages from peer
+
+renegotiate2(Config) ->
+ UserDir = proplists:get_value(priv_dir, Config),
+ DataFile = filename:join(UserDir, "renegotiate2.data"),
+
+ Algs = proplists:get_value(preferred_algorithms, Config),
+ {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+
+ {ok,RelayPid,_,RPort} = ssh_relay:start_link({0,0,0,0}, 0, Host, DPort),
+
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
+ {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
+
+ {ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
+
+ ok = ssh_sftp:write(SftpPid, Handle, "hi\n"),
+
+ ssh_relay:hold(RelayPid, rx, 20, infinity),
+ spawn(fun() -> ok=ssh_sftp:write(SftpPid, Handle, "another hi\n") end),
+ %% need a small pause here to ensure ssh_sftp:write is executed
+ ct:sleep(10),
+ ssh_connection_handler:renegotiate(ConnectionRef),
+ ssh_relay:release(RelayPid, rx),
+
+ timer:sleep(2000),
+
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
+
+ false = (Kex2 == Kex1),
+
+ ssh_relay:stop(RelayPid),
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa
new file mode 100644
index 0000000000..24628e071b
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQDIywHurUpOq6kZuMn+XlRzR4hAxF6qwSkuEqkV7iHnLQ0kIwf3
+uAmjFDhuEsQ8653SLxGVvTNp+KFFgDXiLqgM7TPUwDnpbvzEZHPAU+/zPt4sdY2D
+txBfJwT2SFlK6HPOxOcxdDuD+/a59sh8hk/YVOU7ZTcBVsVG8Got4UcF5QIVAPGd
+CPDQKSTlPiM9OwBB1+9p11k5AoGARLxw4l17mET9cU0uf4Ppe5nsCbODJv44ZrSs
+picvypGVLrLcN5KWbm3vjRFCQ5LFunAG3FwLC2Sh0CH6TemoIfRPsRHR7wvpBGdr
+c693UlMOis/mcmvNMQAzuQNW9WrxdzsvWR/r5s6NEHWqKUJGXSPi2d+Ijq/mCOmI
+hzLzyiACgYEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4
+cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+C
+ROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNgCFEjA7wTC
+sQCY/I35vb6GUJn9tEdP
+-----END DSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa.pub
new file mode 100644
index 0000000000..018ef6f537
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAMjLAe6tSk6rqRm4yf5eVHNHiEDEXqrBKS4SqRXuIectDSQjB/e4CaMUOG4SxDzrndIvEZW9M2n4oUWANeIuqAztM9TAOelu/MRkc8BT7/M+3ix1jYO3EF8nBPZIWUroc87E5zF0O4P79rn2yHyGT9hU5TtlNwFWxUbwai3hRwXlAAAAFQDxnQjw0Ckk5T4jPTsAQdfvaddZOQAAAIBEvHDiXXuYRP1xTS5/g+l7mewJs4Mm/jhmtKymJy/KkZUustw3kpZube+NEUJDksW6cAbcXAsLZKHQIfpN6agh9E+xEdHvC+kEZ2tzr3dSUw6Kz+Zya80xADO5A1b1avF3Oy9ZH+vmzo0QdaopQkZdI+LZ34iOr+YI6YiHMvPKIAAAAIEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+CROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNg= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa384
new file mode 100644
index 0000000000..4e8aa40959
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCYXb6OSAZyXRfLXOtMo43za197Hdc/T0YKjgQQjwDt6rlRwqTh7v7S
+PV2kXwNGdWigBwYFK4EEACKhZANiAARN2khlJUOOIiwsWHEALwDieeZR96qL4pUd
+ci7aeGaczdUK5jOA9D9zmBZtSYTfO8Cr7ekVghDlcWAIJ/BXcswgQwSEQ6wyfaTF
+8FYfyr4l3u9IirsnyaFzeIgeoNis8Gw=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa384.pub
new file mode 100644
index 0000000000..41e722e545
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE3aSGUlQ44iLCxYcQAvAOJ55lH3qovilR1yLtp4ZpzN1QrmM4D0P3OYFm1JhN87wKvt6RWCEOVxYAgn8FdyzCBDBIRDrDJ9pMXwVh/KviXe70iKuyfJoXN4iB6g2KzwbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa521
new file mode 100644
index 0000000000..7196f46e97
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEFMadoz4ckEcClfqXa2tiUuYkJdDfwq+/iFQcpt8ESuEd26IY/vm47Q
+9UzbPkO4ou8xkNsQ3WvCRQBBWtn5O2kUU6AHBgUrgQQAI6GBiQOBhgAEAde5BRu5
+01/jS0jRk212xsb2DxPrxNpgp6IMCV8TA4Eps+8bSqHB091nLiBcP422HXYfuCd7
+XDjSs8ihcmhp0hCRASLqZR9EzW9W/SOt876May1Huj5X+WSO6RLe7vPn9vmf7kHf
+pip6m7M7qp2qGgQ3q2vRwS2K/O6156ohiOlmuuFs
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa521.pub
new file mode 100644
index 0000000000..8f059120bc
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHXuQUbudNf40tI0ZNtdsbG9g8T68TaYKeiDAlfEwOBKbPvG0qhwdPdZy4gXD+Nth12H7gne1w40rPIoXJoadIQkQEi6mUfRM1vVv0jrfO+jGstR7o+V/lkjukS3u7z5/b5n+5B36YqepuzO6qdqhoEN6tr0cEtivzuteeqIYjpZrrhbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed25519 b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed25519
new file mode 100644
index 0000000000..401a3e4a9a
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed25519
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDm9P8/gC0IOKmwHLSvkmEtS2Xx0RRqUDqC6wY6UgDVnwAAAJg3+6xpN/us
+aQAAAAtzc2gtZWQyNTUxOQAAACDm9P8/gC0IOKmwHLSvkmEtS2Xx0RRqUDqC6wY6UgDVnw
+AAAEBzC/Z2WGJhZ3l3tIBnUc6DCbp+lXY2yc2RRpWQTdf8sub0/z+ALQg4qbActK+SYS1L
+ZfHRFGpQOoLrBjpSANWfAAAAE3VhYmhuaWxAZWx4YWRsajNxMzIBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed25519.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed25519.pub
new file mode 100644
index 0000000000..a5c03b19c1
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed25519.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOb0/z+ALQg4qbActK+SYS1LZfHRFGpQOoLrBjpSANWf uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed448 b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed448
new file mode 100644
index 0000000000..8ecfd710dc
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed448
@@ -0,0 +1,10 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA53OqeePNaG/NJmoMbELhskKrAHNhLZ6AQm1WjbpMoseNl/OFh
+1xznExpUPqTLX36fHYsAaWRHABQAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADnc6p5481ob80magxsQuGyQqsAc2EtnoBCbVaNukyix42X84WHXHOcTGlQ+pMtf
+fp8diwBpZEcAFAAAAAByzSPST3FCdOdENDI3uTKQ9RH2Ql+Y5kRZ/yA+iYUIP/32
+BQBVOrwOBc0CGEvbicTM1n4YeVEmfrMo3OqeePNaG/NJmoMbELhskKrAHNhLZ6AQ
+m1WjbpMoseNl/OFh1xznExpUPqTLX36fHYsAaWRHABQAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed448.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed448.pub
new file mode 100644
index 0000000000..cec0765a5d
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_ed448.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADnc6p5481ob80magxsQuGyQqsAc2EtnoBCbVaNukyix42X84WHXHOcTGlQ+pMtffp8diwBpZEcAFAA= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa
new file mode 100644
index 0000000000..2202c2ead8
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAztjiyj2tdfkji0fewWS0kABg0IABgG20NvL1PnHJLr98we7w
+W7f3j27EGjW/ApuycsWXXKi0L82q8uDicoHHb3JI2JkT70oi0yG1Dx/zwPN+dkA7
+LBT1J3UK2hJTFPhp855CwY/ss9xpBsd1Fv3zuHifEqNGljeg1PjmQ3pNhxA/M0aZ
+cLnfIUdZ5Hr+t+4es3zaWo4tLBKmZu6BkVGQKPGXeMkIAMtJlG24l7qKDRkR5TYA
+ZT7P8Vn7hnuFuCNbrJSm686GawBxTQXom23dg9UcWxoHB7UiHFoR6j0bQAX+4R7b
+IwculRDcvzrgCu6u06oFILwY7MlsxpX9hGTl1wIDAQABAoIBAFeP6pmQeICrYceR
+OhQGLIWVE2bP+VLDnflw6i5v/qlieE6kdm1tOEgorK0nuV9CR81cJdIcvIJL/yTn
+3BR7KdDcwUenrY+rg4h7CWmIrigtK4ilciccDBeS7XAZN8B11GxDv6Cu65XMJU2w
+W7nK8URTE4vRQI1QqS3e26MPAAi/LVOt3ZPI6zg/GHEwnq0IVSQAOndLBr/IWZk5
+SANrkfwX8WS7/UxZgDptT9dyUQ5Pnj5mieTlIvBwyczdhZ7RDa8HdCSHW3xF83V1
+A0pkn6+TRojumYyr4RrPQj6htE64Hgx9w1Dv/UINjPXl5mGlbxQHMWGzlqD/qpyI
+wg7RakECgYEA+9ARZpHfEFz+EEFi8l9J+BtJDo00WaKCOZHh5UJ8W+NreqSd8nSx
+5u6wYwMJjRX2Hwv+FBEhxGbo1+ff6p++cYmiSlDtN2XRCDkBWvvGlxu55BDULrhx
+f8lqaV3XGmOy2rQusp8hiHmkmPJCSVj3oJqQnbqJ2zahXAx1rTPwHqECgYEA0kln
+4h+ZkZ+aldOMGF0d0txTcTqZvsSVKiFTSD9of/fiSDqb6xtLT2+ys6FZoFL9lyK8
+gtqH642CDQ+3WT6Nmn4kMF5HNVpEuCeRDeRhiquWeKaAQDyvZ5ym1+Cn3GhsO7Di
+d2LJKV5hOoN77loVY5nwnUVIJ0h+WLf0T7DTCXcCgYEAiNT7X50MdTvS4splFgcp
+jqRlAn9AXySrVtUqxwVlxhjCIpapLUK0GSTCvEq+OeghIaXGnujgTHUPOaNKTZgY
+SGHdyjxHar7s42b2kZYWx63NSVzLr8eSBTpRlIflhvV+DtGyPmWyNxLCmkmqM2kg
+xii3RL5EgtYgwIAUwdVjOYECgYBRPlsMWfkS8f7fc+PkZdVn6gey71kHAxw+MrHi
+b90H09Vw4nPq2Zi3EAiSrfvanTWsdpcuVw+8See89B16NViwH5wLs+D/E+kI3QCF
+xX6J/NEdu/ZA2zFJbpRnQzyXQyDNzwEv7tKZUQVvfe0boWIyIP99Q48k3jUyQZ/6
+Se6+8QKBgQCXl8H2K3CsZxoujKLb2qoEOPbxJQ2hxoMTS5XuQECReIVsNuptWrur
+DF8WJi/B6AqwRX1P3l56RNwqB1yDBqv0QVLpU7vU/FmWqLWTn0r3AvM74qftvfAE
+oa31wcYoCqPJoKgCG7TThLhNt2v5hL7sVgZNO0ueAiHhJbFLaf7ceg==
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa.pub
new file mode 100644
index 0000000000..b4084d320a
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDO2OLKPa11+SOLR97BZLSQAGDQgAGAbbQ28vU+cckuv3zB7vBbt/ePbsQaNb8Cm7JyxZdcqLQvzary4OJygcdvckjYmRPvSiLTIbUPH/PA8352QDssFPUndQraElMU+GnznkLBj+yz3GkGx3UW/fO4eJ8So0aWN6DU+OZDek2HED8zRplwud8hR1nkev637h6zfNpaji0sEqZm7oGRUZAo8Zd4yQgAy0mUbbiXuooNGRHlNgBlPs/xWfuGe4W4I1uslKbrzoZrAHFNBeibbd2D1RxbGgcHtSIcWhHqPRtABf7hHtsjBy6VENy/OuAK7q7TqgUgvBjsyWzGlf2EZOXX uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..fb1a862ded
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDArxbDfh3p1okrD9wQw6jJ4d4DdlBPD5GqXE8bIeRJiK41Sh40LgvPw
+mkqEDSXK++CgBwYFK4EEACKhZANiAAScl43Ih2lWTDKrSox5ve5uiTXil4smsup3
+CfS1XPjKxgBAmlfBim8izbdrT0BFdQzz2joduNMtpt61wO4rGs6jm0UP7Kim9PC7
+Hneb/99fIYopdMH5NMnk60zGO1uZ2vc=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..428d5fb7d7
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJyXjciHaVZMMqtKjHm97m6JNeKXiyay6ncJ9LVc+MrGAECaV8GKbyLNt2tPQEV1DPPaOh240y2m3rXA7isazqObRQ/sqKb08Lsed5v/318hiil0wfk0yeTrTMY7W5na9w== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..3e51ec2ecd
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIB8O1BFkl2HQjQLRLonEZ97da/h39DMa9/0/hvPZWAI8gUPEQcHxRx
+U7b09p3Zh+EBbMFq8+1ae9ds+ZTxE4WFSvKgBwYFK4EEACOhgYkDgYYABAAlWVjq
+Bzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/
+vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5
+ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..017a29f4da
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAlWVjqBzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed25519_key b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed25519_key
new file mode 100644
index 0000000000..13a8fcf491
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed25519_key
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQAAAJi+h4O7voeD
+uwAAAAtzc2gtZWQyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQ
+AAAEBaOcJfGPNemKc1wPHTCmM4Kwvh6dZ0CqY14UT361UnN0lI66JgZZo72XJ7wGBp+h3W
+TDw/pxXddvaomAIHrIl9AAAAE3VhYmhuaWxAZWx4YWRsajNxMzIBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed25519_key.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed25519_key.pub
new file mode 100644
index 0000000000..156ef4045c
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed25519_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIElI66JgZZo72XJ7wGBp+h3WTDw/pxXddvaomAIHrIl9 uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed448_key b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed448_key
new file mode 100644
index 0000000000..31a7e4e8c3
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed448_key
@@ -0,0 +1,10 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA5X9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2
+m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHl
+D2zR+hq+r+glYYAAAABybIKlYsuAjRDWMr6JyFE+v2ySnzTd+oyfY8mWDvbjSKNS
+jIo/zC8ETjmj/FuUSS+PAy51SaIAmPlbX9dEm1m0Yf0s54fsYWrUah2hNCSFpw4f
+ig6nXYDpZ3jt8SR2m0bHBhvWeD3x5Q9s0foavq/oJWGAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed448_key.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed448_key.pub
new file mode 100644
index 0000000000..8c390dcb58
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_ed448_key.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADlf10SbWbRh/Sznh+xhatRqHaE0JIWnDh+KDqddgOlneO3xJHabRscGG9Z4PfHlD2zR+hq+r+glYYA=
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_sftpd_SUITE.erl b/lib/ssh/test/ssh_sftpd_SUITE.erl
index 852801d013..4edc28aa96 100644
--- a/lib/ssh/test/ssh_sftpd_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_SUITE.erl
@@ -80,9 +80,9 @@ groups() ->
init_per_suite(Config) ->
?CHECK_CRYPTO(
begin
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_dsa(DataDir, PrivDir),
+ ssh:start(),
+ ct:log("Pub keys setup for: ~p",
+ [ssh_test_lib:setup_all_user_host_keys(Config)]),
%% to make sure we don't use public-key-auth
%% this should be tested by other test suites
UserDir = filename:join(proplists:get_value(priv_dir, Config), nopubkey),
@@ -91,8 +91,6 @@ init_per_suite(Config) ->
end).
end_per_suite(Config) ->
- SysDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:clean_dsa(SysDir),
UserDir = filename:join(proplists:get_value(priv_dir, Config), nopubkey),
file:del_dir(UserDir),
ssh:stop().
diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
index dbf79e3537..c4fb21f483 100644
--- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
@@ -64,15 +64,12 @@ init_per_suite(Config) ->
{ok, FileInfo} = file:read_file_info(FileName),
ok = file:write_file_info(FileName,
FileInfo#file_info{mode = 8#400}),
+ ct:log("Pub keys setup for: ~p",
+ [ssh_test_lib:setup_all_user_host_keys(Config)]),
Config
end).
-end_per_suite(Config) ->
- UserDir = filename:join(proplists:get_value(priv_dir, Config), nopubkey),
- file:del_dir(UserDir),
- SysDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:clean_rsa(SysDir),
- ssh_test_lib:clean_dsa(SysDir),
+end_per_suite(_Config) ->
ok.
%%--------------------------------------------------------------------
@@ -83,10 +80,10 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
%%--------------------------------------------------------------------
-
init_per_testcase(TestCase, Config) ->
ssh:start(),
- DataDir = proplists:get_value(data_dir, Config),
+ UserDir = PrivDir = proplists:get_value(priv_dir, Config),
+ SysDir = filename:join(PrivDir,"system"),
Options =
case atom_to_list(TestCase) of
@@ -110,9 +107,10 @@ init_per_testcase(TestCase, Config) ->
[]
end,
- {Sftpd, Host, Port} = ssh_test_lib:daemon([{preferred_algorithms, ssh_transport:supported_algorithms()},
- {system_dir, DataDir},
- {user_dir, DataDir},
+ {Sftpd, Host, Port} = ssh_test_lib:daemon([{preferred_algorithms,
+ ssh_transport:supported_algorithms()},
+ {system_dir, SysDir},
+ {user_dir, UserDir},
{user_passwords, [{?USER,?PASSWD}]}
| Options]),
@@ -120,7 +118,7 @@ init_per_testcase(TestCase, Config) ->
ssh_sftp:start_channel(Host, Port,
[{silently_accept_hosts, true},
{preferred_algorithms, ssh_transport:supported_algorithms()},
- {user_dir, DataDir},
+ {user_dir, UserDir},
{timeout, 30000}]),
TmpConfig = lists:keydelete(sftp, 1, Config),
NewConfig = lists:keydelete(sftpd, 1, TmpConfig),
@@ -178,7 +176,8 @@ quit(Config) when is_list(Config) ->
timer:sleep(5000),
{ok, NewSftp, _Conn} = ssh_sftp:start_channel(Host, Port,
[{silently_accept_hosts, true},
- {preferred_algorithms, ssh_transport:supported_algorithms()},
+ {preferred_algorithms,
+ ssh_transport:supported_algorithms()},
{user_dir, UserDir},
{user, ?USER}, {password, ?PASSWD}]),
diff --git a/lib/ssh/test/ssh_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl
index ebf60bc1d0..f16c0d6278 100644
--- a/lib/ssh/test/ssh_test_lib.erl
+++ b/lib/ssh/test/ssh_test_lib.erl
@@ -294,25 +294,37 @@ rcv_lingering(Timeout) ->
receive_exec_result([]) ->
expected;
receive_exec_result(Msgs) when is_list(Msgs) ->
- ct:log("Expect data! ~p", [Msgs]),
+ ct:log("~p:~p Expect data! ~p", [?MODULE,?FUNCTION_NAME,Msgs]),
receive
Msg ->
- case lists:member(Msg, Msgs) of
+ case lists:member(Msg, Msgs)
+ orelse lists:member({optional,Msg}, Msgs)
+ of
true ->
- ct:log("Collected data ~p", [Msg]),
- receive_exec_result(Msgs--[Msg]);
+ ct:log("~p:~p Collected data ~p", [?MODULE,?FUNCTION_NAME,Msg]),
+ receive_exec_result(Msgs--[Msg,{optional,Msg}]);
false ->
case Msg of
{ssh_cm,_,{data,_,1, Data}} ->
- ct:log("StdErr: ~p~n", [Data]),
+ ct:log("~p:~p StdErr: ~p~n", [?MODULE,?FUNCTION_NAME,Data]),
receive_exec_result(Msgs);
Other ->
- ct:log("Other ~p", [Other]),
+ ct:log("~p:~p Other ~p", [?MODULE,?FUNCTION_NAME,Other]),
{unexpected_msg, Other}
end
end
after
- 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ 30000 ->
+ case lists:all(fun(M) ->
+ is_tuple(M) andalso (element(1,M) == optional)
+ end, Msgs)
+ of
+ false ->
+ ct:fail("timeout ~p:~p",[?MODULE,?FUNCTION_NAME]);
+ true ->
+ ct:log("~p:~p Only optional messages expected!~n ~p", [?MODULE,?FUNCTION_NAME,Msgs]),
+ expected
+ end
end;
receive_exec_result(Msg) ->
receive_exec_result([Msg]).
@@ -325,26 +337,11 @@ receive_exec_result_or_fail(Msg) ->
end.
receive_exec_end(ConnectionRef, ChannelId) ->
- Eof = {ssh_cm, ConnectionRef, {eof, ChannelId}},
- ExitStatus = {ssh_cm, ConnectionRef, {exit_status, ChannelId, 0}},
- Closed = {ssh_cm, ConnectionRef,{closed, ChannelId}},
- case receive_exec_result(ExitStatus) of
- {unexpected_msg, Eof} -> %% Open ssh seems to not allways send these messages
- %% in the same order!
- ct:log("2: Collected data ~p", [Eof]),
- case receive_exec_result(ExitStatus) of
- expected ->
- expected = receive_exec_result(Closed);
- {unexpected_msg, Closed} ->
- ct:log("3: Collected data ~p", [Closed])
- end;
- expected ->
- ct:log("4: Collected data ~p", [ExitStatus]),
- expected = receive_exec_result(Eof),
- expected = receive_exec_result(Closed);
- Other ->
- ct:fail({unexpected_msg, Other})
- end.
+ receive_exec_result(
+ [{ssh_cm, ConnectionRef, {eof, ChannelId}},
+ {optional, {ssh_cm, ConnectionRef, {exit_status, ChannelId, 0}}},
+ {ssh_cm, ConnectionRef, {closed, ChannelId}}
+ ]).
receive_exec_result(Data, ConnectionRef, ChannelId) ->
Eof = {ssh_cm, ConnectionRef, {eof, ChannelId}},
@@ -354,21 +351,6 @@ receive_exec_result(Data, ConnectionRef, ChannelId) ->
expected = receive_exec_result(Closed).
-setup_ssh_auth_keys(RSAFile, DSAFile, Dir) ->
- Entries = ssh_file_entry(RSAFile) ++ ssh_file_entry(DSAFile),
- AuthKeys = public_key:ssh_encode(Entries , auth_keys),
- AuthKeysFile = filename:join(Dir, "authorized_keys"),
- file:write_file(AuthKeysFile, AuthKeys).
-
-ssh_file_entry(PubFile) ->
- case file:read_file(PubFile) of
- {ok, Ssh} ->
- [{Key, _}] = public_key:ssh_decode(Ssh, public_key),
- [{Key, [{comment, "Test"}]}];
- _ ->
- []
- end.
-
failfun(_User, {authmethod,none}) ->
ok;
failfun(User, Reason) ->
@@ -378,236 +360,31 @@ hostname() ->
{ok,Host} = inet:gethostname(),
Host.
-known_hosts(BR) ->
- KnownHosts = ssh_file:file_name(user, "known_hosts", []),
- B = KnownHosts ++ "xxx",
- case BR of
- backup ->
- file:rename(KnownHosts, B);
- restore ->
- file:delete(KnownHosts),
- file:rename(B, KnownHosts)
- end.
-
-setup_dsa(DataDir, UserDir) ->
- file:copy(filename:join(DataDir, "id_dsa"), filename:join(UserDir, "id_dsa")),
- System = filename:join(UserDir, "system"),
- file:make_dir(System),
- file:copy(filename:join(DataDir, "ssh_host_dsa_key"), filename:join(System, "ssh_host_dsa_key")),
- file:copy(filename:join(DataDir, "ssh_host_dsa_key.pub"), filename:join(System, "ssh_host_dsa_key.pub")),
-ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
- setup_dsa_known_host(DataDir, UserDir),
- setup_dsa_auth_keys(DataDir, UserDir).
-
-setup_rsa(DataDir, UserDir) ->
- file:copy(filename:join(DataDir, "id_rsa"), filename:join(UserDir, "id_rsa")),
- System = filename:join(UserDir, "system"),
- file:make_dir(System),
- file:copy(filename:join(DataDir, "ssh_host_rsa_key"), filename:join(System, "ssh_host_rsa_key")),
- file:copy(filename:join(DataDir, "ssh_host_rsa_key.pub"), filename:join(System, "ssh_host_rsa_key.pub")),
-ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
- setup_rsa_known_host(DataDir, UserDir),
- setup_rsa_auth_keys(DataDir, UserDir).
-
-setup_ecdsa(Size, DataDir, UserDir) ->
- file:copy(filename:join(DataDir, "id_ecdsa"++Size), filename:join(UserDir, "id_ecdsa")),
- System = filename:join(UserDir, "system"),
- file:make_dir(System),
- file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size), filename:join(System, "ssh_host_ecdsa_key")),
- file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size++".pub"), filename:join(System, "ssh_host_ecdsa_key.pub")),
-ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
- setup_ecdsa_known_host(Size, System, UserDir),
- setup_ecdsa_auth_keys(Size, DataDir, UserDir).
-
-setup_eddsa(Alg, DataDir, UserDir) ->
- {IdPriv, _IdPub, HostPriv, HostPub} =
- case Alg of
- ed25519 -> {"id_ed25519", "id_ed25519.pub", "ssh_host_ed25519_key", "ssh_host_ed25519_key.pub"};
- ed448 -> {"id_ed448", "id_ed448.pub", "ssh_host_ed448_key", "ssh_host_ed448_key.pub"}
- end,
- file:copy(filename:join(DataDir, IdPriv), filename:join(UserDir, IdPriv)),
- System = filename:join(UserDir, "system"),
- file:make_dir(System),
- file:copy(filename:join(DataDir, HostPriv), filename:join(System, HostPriv)),
- file:copy(filename:join(DataDir, HostPub), filename:join(System, HostPub)),
-ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
- setup_eddsa_known_host(HostPub, DataDir, UserDir),
- setup_eddsa_auth_keys(Alg, DataDir, UserDir).
-
-clean_dsa(UserDir) ->
- del_dirs(filename:join(UserDir, "system")),
- file:delete(filename:join(UserDir,"id_dsa")),
- file:delete(filename:join(UserDir,"known_hosts")),
- file:delete(filename:join(UserDir,"authorized_keys")).
-
-clean_rsa(UserDir) ->
- del_dirs(filename:join(UserDir, "system")),
- file:delete(filename:join(UserDir,"id_rsa")),
- file:delete(filename:join(UserDir,"known_hosts")),
- file:delete(filename:join(UserDir,"authorized_keys")).
-
-setup_dsa_pass_phrase(DataDir, UserDir, Phrase) ->
- try
- {ok, KeyBin} = file:read_file(filename:join(DataDir, "id_dsa")),
- setup_pass_phrase(KeyBin, filename:join(UserDir, "id_dsa"), Phrase),
- System = filename:join(UserDir, "system"),
- file:make_dir(System),
- file:copy(filename:join(DataDir, "ssh_host_dsa_key"), filename:join(System, "ssh_host_dsa_key")),
- file:copy(filename:join(DataDir, "ssh_host_dsa_key.pub"), filename:join(System, "ssh_host_dsa_key.pub")),
- setup_dsa_known_host(DataDir, UserDir),
- setup_dsa_auth_keys(DataDir, UserDir)
- of
- _ -> true
- catch
- _:_ -> false
- end.
+del_dirs(Dir) ->
+ del_dir_contents(Dir),
+ file:del_dir(Dir),
+ ok.
-setup_rsa_pass_phrase(DataDir, UserDir, Phrase) ->
- try
- {ok, KeyBin} = file:read_file(filename:join(DataDir, "id_rsa")),
- setup_pass_phrase(KeyBin, filename:join(UserDir, "id_rsa"), Phrase),
- System = filename:join(UserDir, "system"),
- file:make_dir(System),
- file:copy(filename:join(DataDir, "ssh_host_rsa_key"), filename:join(System, "ssh_host_rsa_key")),
- file:copy(filename:join(DataDir, "ssh_host_rsa_key.pub"), filename:join(System, "ssh_host_rsa_key.pub")),
- setup_rsa_known_host(DataDir, UserDir),
- setup_rsa_auth_keys(DataDir, UserDir)
- of
- _ -> true
- catch
- _:_ -> false
- end.
-setup_ecdsa_pass_phrase(Size, DataDir, UserDir, Phrase) ->
- try
- {ok, KeyBin} =
- case file:read_file(F=filename:join(DataDir, "id_ecdsa"++Size)) of
- {error,E} ->
- ct:log("Failed (~p) to read ~p~nFiles: ~p", [E,F,file:list_dir(DataDir)]),
- file:read_file(filename:join(DataDir, "id_ecdsa"));
- Other ->
- Other
- end,
- setup_pass_phrase(KeyBin, filename:join(UserDir, "id_ecdsa"), Phrase),
- System = filename:join(UserDir, "system"),
- file:make_dir(System),
- file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size), filename:join(System, "ssh_host_ecdsa_key")),
- file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size++".pub"), filename:join(System, "ssh_host_ecdsa_key.pub")),
- setup_ecdsa_known_host(Size, System, UserDir),
- setup_ecdsa_auth_keys(Size, DataDir, UserDir)
- of
- _ -> true
- catch
- _:_ -> false
+del_dir_contents(Dir) ->
+ case file:list_dir(Dir) of
+ {ok, Files} ->
+ do_del_files(Dir, Files);
+ _ ->
+ ok
end.
-setup_pass_phrase(KeyBin, OutFile, Phrase) ->
- [{KeyType, _,_} = Entry0] = public_key:pem_decode(KeyBin),
- Key = public_key:pem_entry_decode(Entry0),
- Salt = crypto:strong_rand_bytes(8),
- Entry = public_key:pem_entry_encode(KeyType, Key,
- {{"DES-CBC", Salt}, Phrase}),
- Pem = public_key:pem_encode([Entry]),
- file:write_file(OutFile, Pem).
-
-setup_dsa_known_host(SystemDir, UserDir) ->
- {ok, SshBin} = file:read_file(filename:join(SystemDir, "ssh_host_dsa_key.pub")),
- [{Key, _}] = public_key:ssh_decode(SshBin, public_key),
- setup_known_hosts(Key, UserDir).
-
-setup_rsa_known_host(SystemDir, UserDir) ->
- {ok, SshBin} = file:read_file(filename:join(SystemDir, "ssh_host_rsa_key.pub")),
- [{Key, _}] = public_key:ssh_decode(SshBin, public_key),
- setup_known_hosts(Key, UserDir).
-
-setup_ecdsa_known_host(_Size, SystemDir, UserDir) ->
- {ok, SshBin} = file:read_file(filename:join(SystemDir, "ssh_host_ecdsa_key.pub")),
- [{Key, _}] = public_key:ssh_decode(SshBin, public_key),
- setup_known_hosts(Key, UserDir).
-
-setup_eddsa_known_host(HostPub, SystemDir, UserDir) ->
- {ok, SshBin} = file:read_file(filename:join(SystemDir, HostPub)),
- [{Key, _}] = public_key:ssh_decode(SshBin, public_key),
- setup_known_hosts(Key, UserDir).
-
-setup_known_hosts(Key, UserDir) ->
- {ok, Hostname} = inet:gethostname(),
- {ok, {A, B, C, D}} = inet:getaddr(Hostname, inet),
- IP = lists:concat([A, ".", B, ".", C, ".", D]),
- HostNames = [{hostnames,[Hostname, IP]}],
- KnownHosts = [{Key, HostNames}],
- KnownHostsEnc = public_key:ssh_encode(KnownHosts, known_hosts),
- KHFile = filename:join(UserDir, "known_hosts"),
- file:write_file(KHFile, KnownHostsEnc).
-
-setup_dsa_auth_keys(Dir, UserDir) ->
- {ok, Pem} = file:read_file(filename:join(Dir, "id_dsa")),
- DSA = public_key:pem_entry_decode(hd(public_key:pem_decode(Pem))),
- PKey = DSA#'DSAPrivateKey'.y,
- P = DSA#'DSAPrivateKey'.p,
- Q = DSA#'DSAPrivateKey'.q,
- G = DSA#'DSAPrivateKey'.g,
- Dss = #'Dss-Parms'{p=P, q=Q, g=G},
- setup_auth_keys([{{PKey, Dss}, [{comment, "Test"}]}], UserDir).
-
-setup_rsa_auth_keys(Dir, UserDir) ->
- {ok, Pem} = file:read_file(filename:join(Dir, "id_rsa")),
- RSA = public_key:pem_entry_decode(hd(public_key:pem_decode(Pem))),
- #'RSAPrivateKey'{publicExponent = E, modulus = N} = RSA,
- PKey = #'RSAPublicKey'{publicExponent = E, modulus = N},
- setup_auth_keys([{ PKey, [{comment, "Test"}]}], UserDir).
-
-setup_ecdsa_auth_keys(Size, Dir, UserDir) ->
- {ok, Pem} =
- case file:read_file(F=filename:join(Dir, "id_ecdsa"++Size)) of
- {error,E} ->
- ct:log("Failed (~p) to read ~p~nFiles: ~p", [E,F,file:list_dir(Dir)]),
- file:read_file(filename:join(Dir, "id_ecdsa"));
- Other ->
- Other
- end,
- ECDSA = public_key:pem_entry_decode(hd(public_key:pem_decode(Pem))),
- #'ECPrivateKey'{publicKey = Q,
- parameters = Param = {namedCurve,_Id0}} = ECDSA,
- PKey = #'ECPoint'{point = Q},
- setup_auth_keys([{ {PKey,Param}, [{comment, "Test"}]}], UserDir).
-
-setup_eddsa_auth_keys(Alg, Dir, UserDir) ->
- SshAlg = case Alg of
- ed25519 -> 'ssh-ed25519';
- ed448 -> 'ssh-ed448'
- end,
- {ok, {ed_pri,Alg,Pub,_}} = ssh_file:user_key(SshAlg, [{user_dir,Dir}]),
- setup_auth_keys([{{ed_pub,Alg,Pub}, [{comment, "Test"}]}], UserDir).
-
-setup_auth_keys(Keys, Dir) ->
- AuthKeys = public_key:ssh_encode(Keys, auth_keys),
- AuthKeysFile = filename:join(Dir, "authorized_keys"),
- ok = file:write_file(AuthKeysFile, AuthKeys),
- AuthKeys.
-
-write_auth_keys(Keys, Dir) ->
- AuthKeysFile = filename:join(Dir, "authorized_keys"),
- file:write_file(AuthKeysFile, Keys).
+do_del_files(Dir, Files) ->
+ lists:foreach(fun(File) ->
+ FullPath = filename:join(Dir,File),
+ case filelib:is_dir(FullPath) of
+ true ->
+ del_dirs(FullPath);
+ false ->
+ file:delete(FullPath)
+ end
+ end, Files).
-del_dirs(Dir) ->
- case file:list_dir(Dir) of
- {ok, []} ->
- file:del_dir(Dir);
- {ok, Files} ->
- lists:foreach(fun(File) ->
- FullPath = filename:join(Dir,File),
- case filelib:is_dir(FullPath) of
- true ->
- del_dirs(FullPath),
- file:del_dir(FullPath);
- false ->
- file:delete(FullPath)
- end
- end, Files);
- _ ->
- ok
- end.
openssh_sanity_check(Config) ->
ssh:start(),
@@ -625,34 +402,6 @@ openssh_sanity_check(Config) ->
{skip, Str}
end.
-openssh_supports(ClientOrServer, Tag, Alg) when ClientOrServer == sshc ;
- ClientOrServer == sshd ->
- SSH_algos = ssh_test_lib:default_algorithms(ClientOrServer),
- L = proplists:get_value(Tag, SSH_algos, []),
- lists:member(Alg, L) orelse
- lists:member(Alg, proplists:get_value(client2server, L, [])) orelse
- lists:member(Alg, proplists:get_value(server2client, L, [])).
-
-%%--------------------------------------------------------------------
-%% Check if we have a "newer" ssh client that supports these test cases
-
-ssh_client_supports_Q() ->
- 0 == check_ssh_client_support2(
- ?MODULE:open_port({spawn, "ssh -Q cipher"})
- ).
-
-check_ssh_client_support2(P) ->
- receive
- {P, {data, _A}} ->
- check_ssh_client_support2(P);
- {P, {exit_status, E}} ->
- ct:log("~p:~p exit_status:~n~p",[?MODULE,?LINE,E]),
- E
- after 5000 ->
- ct:log("Openssh command timed out ~n"),
- -1
- end.
-
%%%--------------------------------------------------------------------
%%% Probe a server or a client about algorithm support
@@ -1189,3 +938,132 @@ mk_dir_path(DirPath) ->
%%ct:log("~p:~p return Other ~p ~ts", [?MODULE,?LINE,Other,DirPath]),
Other
end.
+
+%%%----------------------------------------------------------------
+%%% New
+
+setup_all_user_host_keys(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ setup_all_user_host_keys(DataDir, PrivDir).
+
+setup_all_user_host_keys(DataDir, PrivDir) ->
+ setup_all_user_host_keys(DataDir, PrivDir, filename:join(PrivDir,"system")).
+
+setup_all_user_host_keys(DataDir, UserDir, SysDir) ->
+ lists:foldl(fun(Alg, OkAlgs) ->
+ try
+ ok = ssh_test_lib:setup_user_key(Alg, DataDir, UserDir),
+ ok = ssh_test_lib:setup_host_key(Alg, DataDir, SysDir)
+ of
+ ok -> [Alg|OkAlgs]
+ catch
+ error:{badmatch, {error,enoent}} ->
+ OkAlgs;
+ C:E:S ->
+ ct:log("Exception in ~p:~p for alg ~p: ~p:~p~n~p",
+ [?MODULE,?FUNCTION_NAME,Alg,C,E,S]),
+ OkAlgs
+ end
+ end, [], ssh_transport:supported_algorithms(public_key)).
+
+
+setup_all_host_keys(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ setup_all_host_keys(DataDir, filename:join(PrivDir,"system")).
+
+setup_all_host_keys(DataDir, SysDir) ->
+ lists:foldl(fun(Alg, OkAlgs) ->
+ try
+ ok = ssh_test_lib:setup_host_key(Alg, DataDir, SysDir)
+ of
+ ok -> [Alg|OkAlgs]
+ catch
+ error:{badmatch, {error,enoent}} ->
+ OkAlgs;
+ C:E:S ->
+ ct:log("Exception in ~p:~p for alg ~p: ~p:~p~n~p",
+ [?MODULE,?FUNCTION_NAME,Alg,C,E,S]),
+ OkAlgs
+ end
+ end, [], ssh_transport:supported_algorithms(public_key)).
+
+setup_user_key(SshAlg, DataDir, UserDir) ->
+ file:make_dir(UserDir),
+ %% Copy private user key to user's dir
+ {ok,_} = file:copy(filename:join(DataDir, file_base_name(user_src,SshAlg)),
+ filename:join(UserDir, file_base_name(user,SshAlg))),
+ %% Setup authorized_keys in user's dir
+ {ok,Pub} = file:read_file(filename:join(DataDir, file_base_name(user_src,SshAlg)++".pub")),
+ ok = file:write_file(filename:join(UserDir, "authorized_keys"),
+ io_lib:format("~n~s~n",[Pub]),
+ [append]),
+ ?ct_log_show_file( filename:join(DataDir, file_base_name(user_src,SshAlg)++".pub") ),
+ ?ct_log_show_file( filename:join(UserDir, "authorized_keys") ),
+ ok.
+
+setup_host_key_create_dir(SshAlg, DataDir, BaseDir) ->
+ SysDir = filename:join(BaseDir,"system"),
+ ct:log("~p:~p SshAlg=~p~nDataDir = ~p~nBaseDir = ~p~nSysDir = ~p",[?MODULE,?LINE,SshAlg, DataDir, BaseDir,SysDir]),
+ file:make_dir(SysDir),
+ setup_host_key(SshAlg, DataDir, SysDir),
+ SysDir.
+
+setup_host_key(SshAlg, DataDir, SysDir) ->
+ mk_dir_path(SysDir),
+ %% Copy private host key to system's dir
+ {ok,_} = file:copy(filename:join(DataDir, file_base_name(system_src,SshAlg)),
+ filename:join(SysDir, file_base_name(system,SshAlg))),
+ ?ct_log_show_file( filename:join(SysDir, file_base_name(system,SshAlg)) ),
+ ok.
+
+setup_known_host(SshAlg, DataDir, UserDir) ->
+ {ok,Pub} = file:read_file(filename:join(DataDir, file_base_name(system_src,SshAlg)++".pub")),
+ S = lists:join(" ", lists:reverse(tl(lists:reverse(string:tokens(binary_to_list(Pub), " "))))),
+ ok = file:write_file(filename:join(UserDir, "known_hosts"),
+ io_lib:format("~p~n",[S])),
+ ?ct_log_show_file( filename:join(UserDir, "known_hosts") ),
+ ok.
+
+
+get_addr_str() ->
+ {ok, Hostname} = inet:gethostname(),
+ {ok, {A, B, C, D}} = inet:getaddr(Hostname, inet),
+ IP = lists:concat([A, ".", B, ".", C, ".", D]),
+ lists:concat([Hostname,",",IP]).
+
+
+file_base_name(user, 'ecdsa-sha2-nistp256') -> "id_ecdsa";
+file_base_name(user, 'ecdsa-sha2-nistp384') -> "id_ecdsa";
+file_base_name(user, 'ecdsa-sha2-nistp521') -> "id_ecdsa";
+file_base_name(user, 'rsa-sha2-256' ) -> "id_rsa";
+file_base_name(user, 'rsa-sha2-384' ) -> "id_rsa";
+file_base_name(user, 'rsa-sha2-512' ) -> "id_rsa";
+file_base_name(user, 'ssh-dss' ) -> "id_dsa";
+file_base_name(user, 'ssh-ed25519' ) -> "id_ed25519";
+file_base_name(user, 'ssh-ed448' ) -> "id_ed448";
+file_base_name(user, 'ssh-rsa' ) -> "id_rsa";
+
+file_base_name(user_src, 'ecdsa-sha2-nistp256') -> "id_ecdsa256";
+file_base_name(user_src, 'ecdsa-sha2-nistp384') -> "id_ecdsa384";
+file_base_name(user_src, 'ecdsa-sha2-nistp521') -> "id_ecdsa521";
+file_base_name(user_src, Alg) -> file_base_name(user, Alg);
+
+file_base_name(system, 'ecdsa-sha2-nistp256') -> "ssh_host_ecdsa_key";
+file_base_name(system, 'ecdsa-sha2-nistp384') -> "ssh_host_ecdsa_key";
+file_base_name(system, 'ecdsa-sha2-nistp521') -> "ssh_host_ecdsa_key";
+file_base_name(system, 'rsa-sha2-256' ) -> "ssh_host_rsa_key";
+file_base_name(system, 'rsa-sha2-384' ) -> "ssh_host_rsa_key";
+file_base_name(system, 'rsa-sha2-512' ) -> "ssh_host_rsa_key";
+file_base_name(system, 'ssh-dss' ) -> "ssh_host_dsa_key";
+file_base_name(system, 'ssh-ed25519' ) -> "ssh_host_ed25519_key";
+file_base_name(system, 'ssh-ed448' ) -> "ssh_host_ed448_key";
+file_base_name(system, 'ssh-rsa' ) -> "ssh_host_rsa_key";
+
+file_base_name(system_src, 'ecdsa-sha2-nistp256') -> "ssh_host_ecdsa_key256";
+file_base_name(system_src, 'ecdsa-sha2-nistp384') -> "ssh_host_ecdsa_key384";
+file_base_name(system_src, 'ecdsa-sha2-nistp521') -> "ssh_host_ecdsa_key521";
+file_base_name(system_src, Alg) -> file_base_name(system, Alg).
+
+%%%----------------------------------------------------------------
diff --git a/lib/ssh/test/ssh_test_lib.hrl b/lib/ssh/test/ssh_test_lib.hrl
index b9af2ecb5d..098ee79044 100644
--- a/lib/ssh/test/ssh_test_lib.hrl
+++ b/lib/ssh/test/ssh_test_lib.hrl
@@ -49,3 +49,13 @@
-define(wait_match(Pattern, FunctionCall), ?wait_match(Pattern, FunctionCall, ok) ).
+%%-------------------------------------------------------------------------
+%% Write file into log
+%%-------------------------------------------------------------------------
+
+-define(ct_log_show_file(File),
+ (fun(File__) ->
+ {ok,Contents__} = file:read_file(File__),
+ ct:log("~p:~p Show file~n~s =~n~s~n",
+ [?MODULE,?LINE,File__, Contents__])
+ end)(File)).
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl
index 5aa3824702..426efbb5e3 100644
--- a/lib/ssh/test/ssh_to_openssh_SUITE.erl
+++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl
@@ -81,10 +81,6 @@ end_per_suite(_Config) ->
ok.
init_per_group(erlang_server, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- UserDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_dsa_known_host(DataDir, UserDir),
- ssh_test_lib:setup_rsa_known_host(DataDir, UserDir),
Config;
init_per_group(G, Config) when G==tunnel_distro_server ;
G==tunnel_distro_client ->
@@ -102,11 +98,6 @@ init_per_group(erlang_client, Config) ->
init_per_group(_, Config) ->
Config.
-end_per_group(erlang_server, Config) ->
- UserDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:clean_dsa(UserDir),
- ssh_test_lib:clean_rsa(UserDir),
- Config;
end_per_group(_, Config) ->
Config.
@@ -166,10 +157,16 @@ exec_with_io_in_sshc(Config) when is_list(Config) ->
{failfun, fun ssh_test_lib:failfun/2}]),
ct:sleep(500),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ KnownHosts = filename:join(PrivDir, "known_hosts"),
ExecStr = "\"io:read('% ').\"",
Cmd = "echo howdy. | " ++ ssh_test_lib:open_sshc_cmd(Host, Port,
- " -o StrictHostKeyChecking=no"
- " -x", % Disable X forwarding
+ [" -o UserKnownHostsFile=", KnownHosts,
+ " -o CheckHostIP=no"
+ " -o StrictHostKeyChecking=no"
+ " -q"
+ " -x" % Disable X forwarding
+ ],
ExecStr),
ct:pal("Cmd = ~p~n",[Cmd]),
case os:cmd(Cmd) of
@@ -194,9 +191,15 @@ exec_direct_with_io_in_sshc(Config) when is_list(Config) ->
]),
ct:sleep(500),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ KnownHosts = filename:join(PrivDir, "known_hosts"),
Cmd = "echo ciao. | " ++ ssh_test_lib:open_sshc_cmd(Host, Port,
- " -o StrictHostKeyChecking=no"
- " -x", % Disable X forwarding
+ [" -o UserKnownHostsFile=", KnownHosts,
+ " -o CheckHostIP=no"
+ " -o StrictHostKeyChecking=no"
+ " -q"
+ " -x" % Disable X forwarding
+ ],
"'? '"),
ct:pal("Cmd = ~p~n",[Cmd]),
case os:cmd(Cmd) of
@@ -214,7 +217,6 @@ erlang_server_openssh_client_renegotiate(Config) ->
_PubKeyAlg = ssh_rsa,
SystemDir = proplists:get_value(data_dir, Config),
PrivDir = proplists:get_value(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
{failfun, fun ssh_test_lib:failfun/2}]),
@@ -225,9 +227,13 @@ erlang_server_openssh_client_renegotiate(Config) ->
Data = lists:duplicate(trunc(1.1*RenegLimitK*1024), $a),
ok = file:write_file(DataFile, Data),
+ KnownHosts = filename:join(PrivDir, "known_hosts"),
Cmd = ssh_test_lib:open_sshc_cmd(Host, Port,
[" -o UserKnownHostsFile=", KnownHosts,
- " -o StrictHostKeyChecking=no",
+ " -o CheckHostIP=no"
+ " -o StrictHostKeyChecking=no"
+ " -q"
+ " -x",
" -o RekeyLimit=",integer_to_list(RenegLimitK),"K"]),
@@ -268,7 +274,6 @@ erlang_server_openssh_client_renegotiate(Config) ->
tunnel_out_non_erlclient_erlserver(Config) ->
SystemDir = proplists:get_value(data_dir, Config),
PrivDir = proplists:get_value(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
{_Pid, Host, Port} = ssh_test_lib:daemon([{tcpip_tunnel_out, true},
{system_dir, SystemDir},
@@ -278,9 +283,13 @@ tunnel_out_non_erlclient_erlserver(Config) ->
ListenHost = {127,0,0,1},
ListenPort = 2345,
+ KnownHosts = filename:join(PrivDir, "known_hosts"),
Cmd = ssh_test_lib:open_sshc_cmd(Host, Port,
[" -o UserKnownHostsFile=", KnownHosts,
- " -o StrictHostKeyChecking=no",
+ " -o CheckHostIP=no"
+ " -o StrictHostKeyChecking=no"
+ " -q"
+ " -x",
" -R ",integer_to_list(ListenPort),":127.0.0.1:",integer_to_list(ToPort)]),
spawn(fun() ->
ct:log(["ssh command:\r\n ",Cmd],[]),
@@ -295,7 +304,6 @@ tunnel_out_non_erlclient_erlserver(Config) ->
tunnel_in_non_erlclient_erlserver(Config) ->
SystemDir = proplists:get_value(data_dir, Config),
UserDir = proplists:get_value(priv_dir, Config),
- KnownHosts = filename:join(UserDir, "known_hosts"),
{_Pid, Host, Port} = ssh_test_lib:daemon([{tcpip_tunnel_in, true},
{system_dir, SystemDir},
{failfun, fun ssh_test_lib:failfun/2}]),
@@ -304,10 +312,14 @@ tunnel_in_non_erlclient_erlserver(Config) ->
ListenHost = {127,0,0,1},
ListenPort = 2345,
+ KnownHosts = filename:join(UserDir, "known_hosts"),
Cmd =
ssh_test_lib:open_sshc_cmd(Host, Port,
[" -o UserKnownHostsFile=", KnownHosts,
- " -o StrictHostKeyChecking=no",
+ " -o CheckHostIP=no"
+ " -o StrictHostKeyChecking=no"
+ " -q"
+ " -x",
" -L ",integer_to_list(ListenPort),":127.0.0.1:",integer_to_list(ToPort)]),
spawn(fun() ->
ct:log(["ssh command:\r\n ",Cmd],[]),
@@ -519,22 +531,6 @@ extra_logout() ->
ok
end.
-%%--------------------------------------------------------------------
-%% Check if we have a "newer" ssh client that supports these test cases
-check_ssh_client_support(Config) ->
- case ssh_test_lib:ssh_client_supports_Q() of
- true ->
- ssh:start(),
- Config;
- _ ->
- {skip, "test case not supported by ssh client"}
- end.
-
-comment(AtomList) ->
- ct:comment(
- string:join(lists:map(fun erlang:atom_to_list/1, AtomList),
- ", ")).
-
%%%----------------------------------------------------------------
no_forwarding() ->
%%% Check if the ssh of the OS has tunneling enabled
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ecdsa_key b/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ecdsa_key
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ecdsa_key
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ecdsa_key.pub b/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ecdsa_key.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ecdsa_key.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ed25519_key b/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ed25519_key
new file mode 100644
index 0000000000..13a8fcf491
--- /dev/null
+++ b/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ed25519_key
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQAAAJi+h4O7voeD
+uwAAAAtzc2gtZWQyNTUxOQAAACBJSOuiYGWaO9lye8Bgafod1kw8P6cV3Xb2qJgCB6yJfQ
+AAAEBaOcJfGPNemKc1wPHTCmM4Kwvh6dZ0CqY14UT361UnN0lI66JgZZo72XJ7wGBp+h3W
+TDw/pxXddvaomAIHrIl9AAAAE3VhYmhuaWxAZWx4YWRsajNxMzIBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ed25519_key.pub b/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ed25519_key.pub
new file mode 100644
index 0000000000..156ef4045c
--- /dev/null
+++ b/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_ed25519_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIElI66JgZZo72XJ7wGBp+h3WTDw/pxXddvaomAIHrIl9 uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_upgrade_SUITE.erl b/lib/ssh/test/ssh_upgrade_SUITE.erl
index 4417962d26..78657b2014 100644
--- a/lib/ssh/test/ssh_upgrade_SUITE.erl
+++ b/lib/ssh/test/ssh_upgrade_SUITE.erl
@@ -61,9 +61,7 @@ init_per_suite(Config0) ->
end_per_suite(Config) ->
ct_release_test:cleanup(Config),
- ssh:stop(),
- UserDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:clean_rsa(UserDir).
+ ssh:stop().
init_per_testcase(_TestCase, Config) ->
Config.
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 70307d6039..732c3f8766 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,4 +1,4 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 4.9
+SSH_VSN = 4.10
APP_VSN = "ssh-$(SSH_VSN)"