diff options
author | Ingela Anderton Andin <[email protected]> | 2012-01-16 11:47:14 +0100 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2012-01-16 11:47:14 +0100 |
commit | 7f2d2fcf317a4aa62c7b8b037c95b538df2f0313 (patch) | |
tree | f3f20c252fc39b08d2ffde72c9905ea21775f267 | |
parent | 93a45ba0dae6628a3af67d4832db94b728aded4c (diff) | |
parent | f8815dc88bd86d6508d2a3dad031ea939fb2b443 (diff) | |
download | otp-7f2d2fcf317a4aa62c7b8b037c95b538df2f0313.tar.gz otp-7f2d2fcf317a4aa62c7b8b037c95b538df2f0313.tar.bz2 otp-7f2d2fcf317a4aa62c7b8b037c95b538df2f0313.zip |
Merge branch 'maint'
20 files changed, 289 insertions, 550 deletions
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl index 5ea0d98980..73b60057cc 100644 --- a/lib/ssh/test/ssh_basic_SUITE.erl +++ b/lib/ssh/test/ssh_basic_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -41,9 +41,20 @@ init_per_suite(Config) -> case catch crypto:start() of ok -> - Dir = ?config(priv_dir, Config), - {ok, _} = ssh_test_lib:get_id_keys(Dir), - ssh_test_lib:make_dsa_files(Config), + DataDir = ?config(data_dir, Config), + UserDir = ?config(priv_dir, Config), + ssh_test_lib:copyfile(DataDir, UserDir, "id_rsa"), + ssh_test_lib:copyfile(DataDir, UserDir, "id_dsa"), + RSAFile = filename:join(DataDir, "id_rsa.pub"), + DSAFile = filename:join(DataDir, "id_dsa.pub"), + {ok, Ssh1} = file:read_file(RSAFile), + {ok, Ssh2} = file:read_file(DSAFile), + [{RSA, _}] = public_key:ssh_decode(Ssh1,public_key), + [{DSA, _}] = public_key:ssh_decode(Ssh2,public_key), + AuthKeys = public_key:ssh_encode([{RSA, [{comment, "Test"}]}, + {DSA,[{comment, "Test"}]}], auth_keys), + AuthKeysFile = filename:join(UserDir, "authorized_keys"), + file:write_file(AuthKeysFile, AuthKeys), Config; _Else -> {skip, "Crypto could not be started!"} @@ -56,9 +67,7 @@ init_per_suite(Config) -> %% Description: Cleanup after the whole suite %%-------------------------------------------------------------------- end_per_suite(Config) -> - Dir = ?config(priv_dir, Config), crypto:stop(), - ssh_test_lib:remove_id_keys(Dir), ok. %%-------------------------------------------------------------------- @@ -75,7 +84,6 @@ end_per_suite(Config) -> %% Description: Initialization before each test case %%-------------------------------------------------------------------- init_per_testcase(_TestCase, Config) -> - ssh_test_lib:known_hosts(backup), ssh:start(), Config. @@ -87,9 +95,16 @@ init_per_testcase(_TestCase, Config) -> %% A list of key/value pairs, holding the test case configuration. %% Description: Cleanup after each test case %%-------------------------------------------------------------------- -end_per_testcase(_TestCase, _Config) -> + +end_per_testcase(TestCase, Config) when TestCase == server_password_option; + TestCase == server_userpassword_option -> + UserDir = filename:join(?config(priv_dir, Config), nopubkey), + file:del_dir(UserDir), + end_per_testcase(Config); +end_per_testcase(_TestCase, Config) -> + end_per_testcase(Config). +end_per_testcase(Config) -> ssh:stop(), - ssh_test_lib:known_hosts(restore), ok. %%-------------------------------------------------------------------- @@ -101,9 +116,8 @@ end_per_testcase(_TestCase, _Config) -> %% Description: Returns a list of all test cases in this test suite %%-------------------------------------------------------------------- all() -> - [exec, exec_compressed, shell, daemon_already_started, - server_password_option, server_userpassword_option, - known_hosts]. + [exec, exec_compressed, shell, daemon_already_started, + server_password_option, server_userpassword_option, known_hosts]. groups() -> []. @@ -136,10 +150,14 @@ exec(suite) -> exec(Config) when is_list(Config) -> process_flag(trap_exit, true), SystemDir = ?config(data_dir, Config), + UserDir = ?config(priv_dir, Config), + {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, + {user_dir, UserDir}, {failfun, fun ssh_test_lib:failfun/2}]), ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true}, + {user_dir, UserDir}, {user_interaction, false}]), {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity), success = ssh_connection:exec(ConnectionRef, ChannelId0, @@ -178,12 +196,15 @@ exec_compressed(suite) -> exec_compressed(Config) when is_list(Config) -> process_flag(trap_exit, true), SystemDir = ?config(data_dir, Config), - {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, + UserDir = ?config(priv_dir, Config), + + {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir}, {compression, zlib}, {failfun, fun ssh_test_lib:failfun/2}]), ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true}, + {user_dir, UserDir}, {user_interaction, false}]), {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity), success = ssh_connection:exec(ConnectionRef, ChannelId, @@ -209,12 +230,14 @@ shell(suite) -> shell(Config) when is_list(Config) -> process_flag(trap_exit, true), SystemDir = ?config(data_dir, Config), - {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, + UserDir = ?config(priv_dir, Config), + + {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir}, {failfun, fun ssh_test_lib:failfun/2}]), test_server:sleep(500), IO = ssh_test_lib:start_io_server(), - Shell = ssh_test_lib:start_shell(Port, IO), + Shell = ssh_test_lib:start_shell(Port, IO, UserDir), receive ErlShellStart -> test_server:format("Erlang shell start: ~p~n", [ErlShellStart]) @@ -291,8 +314,9 @@ server_password_option(doc) -> server_password_option(suite) -> []; server_password_option(Config) when is_list(Config) -> - UserDir = ?config(data_dir, Config), % to make sure we don't use - SysDir = ?config(data_dir, Config), % public-key-auth + UserDir = filename:join(?config(priv_dir, Config), nopubkey), % to make sure we don't use public-key-auth + file:make_dir(UserDir), + SysDir = ?config(data_dir, Config), {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir}, {password, "morot"}]), @@ -321,8 +345,9 @@ server_userpassword_option(doc) -> server_userpassword_option(suite) -> []; server_userpassword_option(Config) when is_list(Config) -> - UserDir = ?config(data_dir, Config), % to make sure we don't use - SysDir = ?config(data_dir, Config), % public-key-auth + UserDir = filename:join(?config(priv_dir, Config), nopubkey), % to make sure we don't use public-key-auth + file:make_dir(UserDir), + SysDir = ?config(data_dir, Config), {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir}, {user_passwords, [{"vego", "morot"}]}]), @@ -361,10 +386,10 @@ known_hosts(doc) -> known_hosts(suite) -> []; known_hosts(Config) when is_list(Config) -> - SystemDir = ?config(data_dir, Config), + DataDir = ?config(data_dir, Config), UserDir = ?config(priv_dir, Config), - - {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, + + {Pid, Host, Port} = ssh_test_lib:daemon([{user_dir, UserDir},{system_dir, DataDir}, {failfun, fun ssh_test_lib:failfun/2}]), KnownHosts = filename:join(UserDir, "known_hosts"), diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_dsa b/lib/ssh/test/ssh_basic_SUITE_data/id_dsa new file mode 100644 index 0000000000..d306f8b26e --- /dev/null +++ b/lib/ssh/test/ssh_basic_SUITE_data/id_dsa @@ -0,0 +1,13 @@ +-----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== +-----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..9406116777 --- /dev/null +++ b/lib/ssh/test/ssh_basic_SUITE_data/id_dsa.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAN+LZ+VJNlmh/BPjJBPQ2KRf8sY1PtQ94H9cRZ7/Gi8RgISV9pAA8WLFe8SBfCiiOZnmSJBErMszf3AE/SM8REtudld844PQ8OfDSFoyHt0PtcpUyh38SKBWAd/+oF0zYzzLPWz+tEXufVSktLKnOIqOTMKbsmhJDbNtYg92YEhfAAAAFQDID5Ka+0qtzu7B3W/A+tNQ0Y6BMQAAAIAw5DEN8HYV3yi7Pob3p/9Q7NEwj8p2/yRhgpYkgZj6lFiss/JjNR4nOfBmt44mCtzMBf6W4ecoVYnYOeTkLJ5eTrtayvukn/gwEwM4p4hLRLyqhIE3z4qunv1+AD7JLch+puQku0u7gQFoJfiYpAhfj76Tjh3hTmVzym372GUQjwAAAIEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+euEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AXCy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34= Dsa diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_rsa b/lib/ssh/test/ssh_basic_SUITE_data/id_rsa new file mode 100644 index 0000000000..79968bdd7d --- /dev/null +++ b/lib/ssh/test/ssh_basic_SUITE_data/id_rsa @@ -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_basic_SUITE_data/id_rsa.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_rsa.pub new file mode 100644 index 0000000000..95bce6bc61 --- /dev/null +++ b/lib/ssh/test/ssh_basic_SUITE_data/id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q== ingela@dain diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_dsa_key new file mode 100644 index 0000000000..d306f8b26e --- /dev/null +++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_dsa_key @@ -0,0 +1,13 @@ +-----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== +-----END DSA PRIVATE KEY----- + diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_rsa_key new file mode 100644 index 0000000000..79968bdd7d --- /dev/null +++ b/lib/ssh/test/ssh_basic_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_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl index c96b6de3ea..a9a568ced6 100644 --- a/lib/ssh/test/ssh_sftp_SUITE.erl +++ b/lib/ssh/test/ssh_sftp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2011. All Rights Reserved. +%% Copyright Ericsson AB 2005-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -50,7 +50,6 @@ init_per_suite(Config) -> {ok,ok} -> Dir = ?config(priv_dir, Config), {ok, _} = ssh_test_lib:get_id_keys(Dir), - ssh_test_lib:make_dsa_files(Config), Config; {ok,_} -> {skip,"Could not start ssh!"}; @@ -94,13 +93,14 @@ init_per_testcase(_Case, Config) -> SysDir = ?config(data_dir, Config), Host = ssh_test_lib:hostname(), + %% Run test against openssh server if available Sftp = case (catch ssh_sftp:start_channel(Host, [{user_dir, Dir}, {user_interaction, false}, {silently_accept_hosts, true}])) of {ok, ChannelPid, Connection} -> {ChannelPid, Connection}; - _Error -> + _Error -> %% Start own sftp server {_Sftpd, _Host, _Port} = ssh_test_lib:daemon(Host, ?SFPD_PORT, [{system_dir, SysDir}, diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/id_rsa b/lib/ssh/test/ssh_sftp_SUITE_data/id_rsa deleted file mode 100644 index 7e3f885f5d..0000000000 --- a/lib/ssh/test/ssh_sftp_SUITE_data/id_rsa +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIICWwIBAAKBgQDLKYTdRnGzphcN+pF8UuI3sYB7rxZUHbOT87K3vh8XOLkDOsS3 -8VREtNS8Wb3uYXsRtyDoUvrLIDnyllOfJSDupWLr4ibckUZd/nhFAaC6WryVmH6k -GlQLLp9KU+vcn2DwYeo14gbwHYDB3pmv4CWAlnO1m/BkX4aLz1zC314OkQIBIwKB -gD/Z2UzboBPjvhpWEHeHw3CW3zzQoJ4X9pw2peH57IOkHOPCA0/A3/hWFvleCH4e -owWRU3w3ViKVGYbBh/7RJ5rllN+ENUmVn536srJTxLKUtvb5jRGj3W6EWgAGHSUB -hm83Kt9Lb5hprL7dPrNGvSseBm/LQSfBQ4vUUyiVRKGPAkEA/rPxWoLdBBP+FZtE -fGzz9izPM6Fe6o8ZGNZIlRBProOhgEvvIqdgzQWObgLVVrw+M/YApPpiYS3PEmWj -b2b+jwJBAMwyYeL6coKTl8swDu8HvLnshgUFJFTtHhOTXsKtXQNI1b24xhUrB3Sb -X8fmoByyRNRpOfvg4Jdqi3Z6KfIcsN8CQQDEfC83McBw3DkJWoVKCugVrYnmACSm -USH9N5cT6AL0VupNB2C0VTwL37cEaJXyc/V4ipLIaWHV8CNl9qKmZWVJAkEAurG4 -lQI8zyfbPW3EgsU+1d+QeZ5NGnJkpC73jWtNudwxIn0M4CdXRgpmMxwAGjyWs5No -Nr75OfsDKn5SPHIAywJAKrtONlOizgDiG3EvAXZlwFtOb+HkQ7lrFwczrQu9m7yi -brSAcnTrLKI6CrR33b/QJLvb9C/HTEZojFABGq8M7A== ------END RSA PRIVATE KEY----- diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/id_rsa.pub b/lib/ssh/test/ssh_sftp_SUITE_data/id_rsa.pub deleted file mode 100644 index 77f57de4af..0000000000 --- a/lib/ssh/test/ssh_sftp_SUITE_data/id_rsa.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAyymE3UZxs6YXDfqRfFLiN7GAe68WVB2zk/Oyt74fFzi5AzrEt/FURLTUvFm97mF7Ebcg6FL6yyA58pZTnyUg7qVi6+Im3JFGXf54RQGgulq8lZh+pBpUCy6fSlPr3J9g8GHqNeIG8B2Awd6Zr+AlgJZztZvwZF+Gi89cwt9eDpE= jakob@balin diff --git a/lib/ssh/test/ssh_sftpd_SUITE.erl b/lib/ssh/test/ssh_sftpd_SUITE.erl index bfe54a3e75..0873348be0 100644 --- a/lib/ssh/test/ssh_sftpd_SUITE.erl +++ b/lib/ssh/test/ssh_sftpd_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2011. All Rights Reserved. +%% Copyright Ericsson AB 2006-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -53,16 +53,15 @@ %% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- init_per_suite(Config) -> - case {catch ssh:stop(),catch crypto:start()} of - {ok,ok} -> - ssh_test_lib:make_dsa_files(Config), + case (catch crypto:start()) of + ok -> + ssh:start(), + DataDir = ?config(data_dir, Config), + UserDir = ?config(priv_dir, Config), + ssh_test_lib:setup_dsa(UserDir, DataDir), Config; - {ok,_} -> - {skip,"Could not start ssh!"}; - {_,ok} -> - {skip,"Could not start crypto!"}; - {_,_} -> - {skip,"Could not start crypto and ssh!"} + _ -> + {skip,"Could not start ssh!"} end. %%-------------------------------------------------------------------- @@ -71,7 +70,10 @@ init_per_suite(Config) -> %% A list of key/value pairs, holding the test case configuration. %% Description: Cleanup after the whole suite %%-------------------------------------------------------------------- -end_per_suite(_Config) -> +end_per_suite(Config) -> + UserDir = ?config(priv_dir, Config), + ssh_test_lib:clean_dsa(UserDir), + ssh:stop(), crypto:stop(), ok. diff --git a/lib/ssh/test/ssh_sftpd_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_sftpd_SUITE_data/ssh_host_dsa_key new file mode 100644 index 0000000000..51ab6fbd88 --- /dev/null +++ b/lib/ssh/test/ssh_sftpd_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_sftpd_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_sftpd_SUITE_data/ssh_host_dsa_key.pub new file mode 100644 index 0000000000..4dbb1305b0 --- /dev/null +++ b/lib/ssh/test/ssh_sftpd_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_sftpd_erlclient_SUITE.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl index 2209af05d5..c63ad7de73 100644 --- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl +++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -48,13 +48,14 @@ init_per_suite(Config) -> case catch crypto:start() of ok -> DataDir = ?config(data_dir, Config), + UserDir = ?config(priv_dir, Config), FileAlt = filename:join(DataDir, "ssh_sftpd_file_alt.erl"), c:c(FileAlt), FileName = filename:join(DataDir, "test.txt"), {ok, FileInfo} = file:read_file_info(FileName), ok = file:write_file_info(FileName, FileInfo#file_info{mode = 8#400}), - ssh_test_lib:make_dsa_files(Config), + ssh_test_lib:setup_dsa(DataDir, UserDir), Config; _Else -> {skip,"Could not start ssh!"} @@ -66,7 +67,9 @@ init_per_suite(Config) -> %% A list of key/value pairs, holding the test case configuration. %% Description: Cleanup after the whole suite %%-------------------------------------------------------------------- -end_per_suite(_Config) -> +end_per_suite(Config) -> + UserDir = ?config(priv_dir, Config), + ssh_test_lib:clean_dsa(UserDir), crypto:stop(), ok. @@ -85,7 +88,7 @@ end_per_suite(_Config) -> %%-------------------------------------------------------------------- init_per_testcase(TestCase, Config) -> ssh:start(), - DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), Options = case atom_to_list(TestCase) of @@ -95,8 +98,7 @@ init_per_testcase(TestCase, Config) -> ssh_sftpd_file_alt}]), [{user_passwords,[{?USER, ?PASSWD}]}, {pwdfun, fun(_,_) -> true end}, - {system_dir, DataDir}, - {user_dir, DataDir}, + {system_dir, PrivDir}, {subsystems, [Spec]}]; "root_dir" -> Privdir = ?config(priv_dir, Config), @@ -105,23 +107,20 @@ init_per_testcase(TestCase, Config) -> Spec = ssh_sftpd:subsystem_spec([{root,Root}]), [{user_passwords,[{?USER, ?PASSWD}]}, {pwdfun, fun(_,_) -> true end}, - {system_dir, DataDir}, - {user_dir, DataDir}, + {system_dir, PrivDir}, {subsystems, [Spec]}]; "list_dir_limited" -> Spec = ssh_sftpd:subsystem_spec([{max_files,1}]), [{user_passwords,[{?USER, ?PASSWD}]}, {pwdfun, fun(_,_) -> true end}, - {system_dir, DataDir}, - {user_dir, DataDir}, + {system_dir, PrivDir}, {subsystems, [Spec]}]; _ -> [{user_passwords,[{?USER, ?PASSWD}]}, {pwdfun, fun(_,_) -> true end}, - {user_dir, DataDir}, - {system_dir, DataDir}] + {system_dir, PrivDir}] end, {Sftpd, Host, _Port} = ssh_test_lib:daemon(any, ?SSHD_PORT, Options), @@ -131,8 +130,7 @@ init_per_testcase(TestCase, Config) -> [{silently_accept_hosts, true}, {user, ?USER}, {password, ?PASSWD}, {pwdfun, fun(_,_) -> true end}, - {system_dir, DataDir}, - {user_dir, DataDir}, + {user_dir, PrivDir}, {timeout, 30000}]), TmpConfig = lists:keydelete(sftp, 1, Config), NewConfig = lists:keydelete(sftpd, 1, TmpConfig), diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_host_dsa_key new file mode 100644 index 0000000000..51ab6fbd88 --- /dev/null +++ b/lib/ssh/test/ssh_sftpd_erlclient_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_sftpd_erlclient_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_host_dsa_key.pub new file mode 100644 index 0000000000..4dbb1305b0 --- /dev/null +++ b/lib/ssh/test/ssh_sftpd_erlclient_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_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl index 425fae22c1..f4e95f9bfb 100644 --- a/lib/ssh/test/ssh_test_lib.erl +++ b/lib/ssh/test/ssh_test_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% Copyright Ericsson AB 2004-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -68,15 +68,11 @@ daemon(Host, Port, Options) -> Error end. +start_shell(Port, IOServer, UserDir) -> + spawn_link(?MODULE, init_shell, [Port, IOServer, [{user_dir, UserDir}]]). - - -start_shell(Port, IOServer) -> - spawn_link(?MODULE, init_shell, [Port, IOServer]). - -init_shell(Port, IOServer) -> +init_shell(Port, IOServer, UserDir) -> Host = hostname(), - UserDir = get_user_dir(), Options = [{user_interaction, false}, {silently_accept_hosts, true}] ++ UserDir, group_leader(IOServer, self()), @@ -139,12 +135,18 @@ reply(TestCase, Result) -> receive_exec_result(Msg) -> test_server:format("Expect data! ~p", [Msg]), receive + {ssh_cm,_,{data,_,1, Data}} -> + test_server:format("StdErr: ~p~n", [Data]), + receive_exec_result(Msg); Msg -> test_server:format("1: Collected data ~p", [Msg]), expected; Other -> + test_server:format("Other ~p", [Other]), {unexpected_msg, Other} end. + + receive_exec_end(ConnectionRef, ChannelId) -> Eof = {ssh_cm, ConnectionRef, {eof, ChannelId}}, ExitStatus = {ssh_cm, ConnectionRef, {exit_status, ChannelId, 0}}, @@ -198,9 +200,16 @@ remove_id_keys(Dir) -> file:delete(filename:join(Dir, "id_rsa")), file:delete(filename:join(Dir, "id_dsa")). -copyfile(SrcDir, DstDir, Fn) -> - file:copy(filename:join(SrcDir, Fn), - filename:join(DstDir, Fn)). +copyfile(SrcDir, DstDir, FileName) -> + Dest = filename:join(DstDir, FileName), + Result = file:copy(filename:join(SrcDir, FileName), Dest), + {ok, Pem} = file:read_file(Dest), + case public_key:pem_decode(Pem) of + [{_,_, not_encrypted}] -> + Result; + _ -> + {error, "Has pass phrase can not be used by automated test case"} + end. failfun(_User, {authmethod,none}) -> ok; @@ -222,39 +231,11 @@ known_hosts(BR) -> file:rename(B, KnownHosts) end. - -get_user_dir() -> - case os:type() of - {win32, _} -> - [{user_dir, filename:join([os:getenv("HOME"), ".ssh"])}]; - _ -> - [] - end. - - -make_dsa_cert_files(Config) -> - make_dsa_cert_files("", Config). - -make_dsa_cert_files(RoleStr, Config) -> - - CaInfo = {CaCert, _} = make_cert([{key, dsa}]), - {Cert, CertKey} = make_cert([{key, dsa}, {issuer, CaInfo}]), - CaCertFile = filename:join([?config(data_dir, Config), - RoleStr, "dsa_cacerts.pem"]), - CertFile = filename:join([?config(data_dir, Config), - RoleStr, "dsa_cert.pem"]), - KeyFile = filename:join([?config(data_dir, Config), - RoleStr, "dsa_key.pem"]), - - der_to_pem(CaCertFile, [{'Certificate', CaCert, not_encrypted}]), - der_to_pem(CertFile, [{'Certificate', Cert, not_encrypted}]), - der_to_pem(KeyFile, [CertKey]), - {CaCertFile, CertFile, KeyFile}. - -make_dsa_files(Config) -> - make_dsa_files(Config, rfc4716_public_key). -make_dsa_files(Config, Type) -> - {DSA, EncodedKey} = ssh_test_lib:gen_dsa(128, 20), +setup_dsa(DataDir, UserDir) -> + ssh_test_lib:copyfile(DataDir, UserDir, "ssh_host_dsa_key"), + ssh_test_lib:copyfile(DataDir, UserDir, "ssh_host_dsa_key.pub"), + {ok, Pem} = file:read_file(filename:join(UserDir, "ssh_host_dsa_key")), + DSA = public_key:pem_entry_decode(hd(public_key:pem_decode(Pem))), PKey = DSA#'DSAPrivateKey'.y, P = DSA#'DSAPrivateKey'.p, Q = DSA#'DSAPrivateKey'.q, @@ -263,422 +244,13 @@ make_dsa_files(Config, Type) -> {ok, Hostname} = inet:gethostname(), {ok, {A, B, C, D}} = inet:getaddr(Hostname, inet), IP = lists:concat([A, ".", B, ".", C, ".", D]), - Attributes = [], % Could be [{comment,"user@" ++ Hostname}], HostNames = [{hostnames,[IP, IP]}], - PublicKey = [{{PKey, Dss}, Attributes}], KnownHosts = [{{PKey, Dss}, HostNames}], - KnownHostsEnc = public_key:ssh_encode(KnownHosts, known_hosts), - KnownHosts = public_key:ssh_decode(KnownHostsEnc, known_hosts), - - PublicKeyEnc = public_key:ssh_encode(PublicKey, Type), -% PublicKey = public_key:ssh_decode(PublicKeyEnc, Type), - - SystemTmpDir = ?config(data_dir, Config), - filelib:ensure_dir(SystemTmpDir), - file:make_dir(SystemTmpDir), - - DSAFile = filename:join(SystemTmpDir, "ssh_host_dsa_key.pub"), - file:delete(DSAFile), - - DSAPrivateFile = filename:join(SystemTmpDir, "ssh_host_dsa_key"), - file:delete(DSAPrivateFile), - - KHFile = filename:join(SystemTmpDir, "known_hosts"), - file:delete(KHFile), - - PemBin = public_key:pem_encode([EncodedKey]), - - file:write_file(DSAFile, PublicKeyEnc), - file:write_file(KHFile, KnownHostsEnc), - file:write_file(DSAPrivateFile, PemBin), - ok. - -%%-------------------------------------------------------------------- -%% Create and return a der encoded certificate -%% Option Default -%% ------------------------------------------------------- -%% digest sha1 -%% validity {date(), date() + week()} -%% version 3 -%% subject [] list of the following content -%% {name, Name} -%% {email, Email} -%% {city, City} -%% {state, State} -%% {org, Org} -%% {org_unit, OrgUnit} -%% {country, Country} -%% {serial, Serial} -%% {title, Title} -%% {dnQualifer, DnQ} -%% issuer = {Issuer, IssuerKey} true (i.e. a ca cert is created) -%% (obs IssuerKey migth be {Key, Password} -%% key = KeyFile|KeyBin|rsa|dsa Subject PublicKey rsa or dsa generates key -%% -%% -%% (OBS: The generated keys are for testing only) -%% make_cert([{::atom(), ::term()}]) -> {Cert::binary(), Key::binary()} -%%-------------------------------------------------------------------- -make_cert(Opts) -> - SubjectPrivateKey = get_key(Opts), - {TBSCert, IssuerKey} = make_tbs(SubjectPrivateKey, Opts), - Cert = public_key:pkix_sign(TBSCert, IssuerKey), - true = verify_signature(Cert, IssuerKey, undef), %% verify that the keys where ok - {Cert, encode_key(SubjectPrivateKey)}. - -%%-------------------------------------------------------------------- -%% Writes cert files in Dir with FileName and FileName ++ Suffix -%% write_cert(::string(), ::string(), {Cert,Key}) -> ok -%%-------------------------------------------------------------------- -write_cert(Dir, FileName, Suffix, {Cert, Key = {_,_,not_encrypted}}) when is_binary(Cert) -> - ok = der_to_pem(filename:join(Dir, FileName), - [{'Certificate', Cert, not_encrypted}]), - ok = der_to_pem(filename:join(Dir, FileName ++ Suffix), [Key]). - -%%-------------------------------------------------------------------- -%% Creates a rsa key (OBS: for testing only) -%% the size are in bytes -%% gen_rsa(::integer()) -> {::atom(), ::binary(), ::opaque()} -%%-------------------------------------------------------------------- -gen_rsa(Size) when is_integer(Size) -> - Key = gen_rsa2(Size), - {Key, encode_key(Key)}. - -%%-------------------------------------------------------------------- -%% Creates a dsa key (OBS: for testing only) -%% the sizes are in bytes -%% gen_dsa(::integer()) -> {::atom(), ::binary(), ::opaque()} -%%-------------------------------------------------------------------- -gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) -> - Key = gen_dsa2(LSize, NSize), - {Key, encode_key(Key)}. - -%%-------------------------------------------------------------------- -%% Verifies cert signatures -%% verify_signature(::binary(), ::tuple()) -> ::boolean() -%%-------------------------------------------------------------------- -verify_signature(DerEncodedCert, DerKey, _KeyParams) -> - Key = decode_key(DerKey), - case Key of - #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} -> - public_key:pkix_verify(DerEncodedCert, - #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}); - #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y} -> - public_key:pkix_verify(DerEncodedCert, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}) - end. - -%%%%%%%%%%%%%%%%%%%%%%%%% Implementation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -get_key(Opts) -> - case proplists:get_value(key, Opts) of - undefined -> make_key(rsa, Opts); - rsa -> make_key(rsa, Opts); - dsa -> make_key(dsa, Opts); - Key -> - Password = proplists:get_value(password, Opts, no_passwd), - decode_key(Key, Password) - end. - -decode_key({Key, Pw}) -> - decode_key(Key, Pw); -decode_key(Key) -> - decode_key(Key, no_passwd). - - -decode_key(#'RSAPublicKey'{} = Key,_) -> - Key; -decode_key(#'RSAPrivateKey'{} = Key,_) -> - Key; -decode_key(#'DSAPrivateKey'{} = Key,_) -> - Key; -decode_key(PemEntry = {_,_,_}, Pw) -> - public_key:pem_entry_decode(PemEntry, Pw); -decode_key(PemBin, Pw) -> - [KeyInfo] = public_key:pem_decode(PemBin), - decode_key(KeyInfo, Pw). - -encode_key(Key = #'RSAPrivateKey'{}) -> - {ok, Der} = 'OTP-PUB-KEY':encode('RSAPrivateKey', Key), - {'RSAPrivateKey', list_to_binary(Der), not_encrypted}; -encode_key(Key = #'DSAPrivateKey'{}) -> - {ok, Der} = 'OTP-PUB-KEY':encode('DSAPrivateKey', Key), - {'DSAPrivateKey', list_to_binary(Der), not_encrypted}. - -make_tbs(SubjectKey, Opts) -> - Version = list_to_atom("v"++integer_to_list(proplists:get_value(version, Opts, 3))), - - IssuerProp = proplists:get_value(issuer, Opts, true), - {Issuer, IssuerKey} = issuer(IssuerProp, Opts, SubjectKey), - - {Algo, Parameters} = sign_algorithm(IssuerKey, Opts), - - SignAlgo = #'SignatureAlgorithm'{algorithm = Algo, - parameters = Parameters}, - Subject = case IssuerProp of - true -> %% Is a Root Ca - Issuer; - _ -> - subject(proplists:get_value(subject, Opts),false) - end, - - {#'OTPTBSCertificate'{serialNumber = trunc(random:uniform()*100000000)*10000 + 1, - signature = SignAlgo, - issuer = Issuer, - validity = validity(Opts), - subject = Subject, - subjectPublicKeyInfo = publickey(SubjectKey), - version = Version, - extensions = extensions(Opts) - }, IssuerKey}. - -issuer(true, Opts, SubjectKey) -> - %% Self signed - {subject(proplists:get_value(subject, Opts), true), SubjectKey}; -issuer({Issuer, IssuerKey}, _Opts, _SubjectKey) when is_binary(Issuer) -> - {issuer_der(Issuer), decode_key(IssuerKey)}; -issuer({File, IssuerKey}, _Opts, _SubjectKey) when is_list(File) -> - {ok, [{cert, Cert, _}|_]} = pem_to_der(File), - {issuer_der(Cert), decode_key(IssuerKey)}. - -issuer_der(Issuer) -> - Decoded = public_key:pkix_decode_cert(Issuer, otp), - #'OTPCertificate'{tbsCertificate=Tbs} = Decoded, - #'OTPTBSCertificate'{subject=Subject} = Tbs, - Subject. - -subject(undefined, IsRootCA) -> - User = if IsRootCA -> "RootCA"; true -> os:getenv("USER") end, - Opts = [{email, User ++ "@erlang.org"}, - {name, User}, - {city, "Stockholm"}, - {country, "SE"}, - {org, "erlang"}, - {org_unit, "testing dep"}], - subject(Opts); -subject(Opts, _) -> - subject(Opts). - -subject(SubjectOpts) when is_list(SubjectOpts) -> - Encode = fun(Opt) -> - {Type,Value} = subject_enc(Opt), - [#'AttributeTypeAndValue'{type=Type, value=Value}] - end, - {rdnSequence, [Encode(Opt) || Opt <- SubjectOpts]}. - -%% Fill in the blanks -subject_enc({name, Name}) -> {?'id-at-commonName', {printableString, Name}}; -subject_enc({email, Email}) -> {?'id-emailAddress', Email}; -subject_enc({city, City}) -> {?'id-at-localityName', {printableString, City}}; -subject_enc({state, State}) -> {?'id-at-stateOrProvinceName', {printableString, State}}; -subject_enc({org, Org}) -> {?'id-at-organizationName', {printableString, Org}}; -subject_enc({org_unit, OrgUnit}) -> {?'id-at-organizationalUnitName', {printableString, OrgUnit}}; -subject_enc({country, Country}) -> {?'id-at-countryName', Country}; -subject_enc({serial, Serial}) -> {?'id-at-serialNumber', Serial}; -subject_enc({title, Title}) -> {?'id-at-title', {printableString, Title}}; -subject_enc({dnQualifer, DnQ}) -> {?'id-at-dnQualifier', DnQ}; -subject_enc(Other) -> Other. - - -extensions(Opts) -> - case proplists:get_value(extensions, Opts, []) of - false -> - asn1_NOVALUE; - Exts -> - lists:flatten([extension(Ext) || Ext <- default_extensions(Exts)]) - end. - -default_extensions(Exts) -> - Def = [{key_usage,undefined}, - {subject_altname, undefined}, - {issuer_altname, undefined}, - {basic_constraints, default}, - {name_constraints, undefined}, - {policy_constraints, undefined}, - {ext_key_usage, undefined}, - {inhibit_any, undefined}, - {auth_key_id, undefined}, - {subject_key_id, undefined}, - {policy_mapping, undefined}], - Filter = fun({Key, _}, D) -> lists:keydelete(Key, 1, D) end, - Exts ++ lists:foldl(Filter, Def, Exts). - -extension({_, undefined}) -> []; -extension({basic_constraints, Data}) -> - case Data of - default -> - #'Extension'{extnID = ?'id-ce-basicConstraints', - extnValue = #'BasicConstraints'{cA=true}, - critical=true}; - false -> - []; - Len when is_integer(Len) -> - #'Extension'{extnID = ?'id-ce-basicConstraints', - extnValue = #'BasicConstraints'{cA=true, pathLenConstraint=Len}, - critical=true}; - _ -> - #'Extension'{extnID = ?'id-ce-basicConstraints', - extnValue = Data} - end; -extension({Id, Data, Critical}) -> - #'Extension'{extnID = Id, extnValue = Data, critical = Critical}. - - -publickey(#'RSAPrivateKey'{modulus=N, publicExponent=E}) -> - Public = #'RSAPublicKey'{modulus=N, publicExponent=E}, - Algo = #'PublicKeyAlgorithm'{algorithm= ?rsaEncryption, parameters='NULL'}, - #'OTPSubjectPublicKeyInfo'{algorithm = Algo, - subjectPublicKey = Public}; -publickey(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) -> - Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-dsa', - parameters={params, #'Dss-Parms'{p=P, q=Q, g=G}}}, - #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y}. - -validity(Opts) -> - DefFrom0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())-1), - DefTo0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())+7), - {DefFrom, DefTo} = proplists:get_value(validity, Opts, {DefFrom0, DefTo0}), - Format = fun({Y,M,D}) -> lists:flatten(io_lib:format("~w~2..0w~2..0w000000Z",[Y,M,D])) end, - #'Validity'{notBefore={generalTime, Format(DefFrom)}, - notAfter ={generalTime, Format(DefTo)}}. - -sign_algorithm(#'RSAPrivateKey'{}, Opts) -> - Type = case proplists:get_value(digest, Opts, sha1) of - sha1 -> ?'sha1WithRSAEncryption'; - sha512 -> ?'sha512WithRSAEncryption'; - sha384 -> ?'sha384WithRSAEncryption'; - sha256 -> ?'sha256WithRSAEncryption'; - md5 -> ?'md5WithRSAEncryption'; - md2 -> ?'md2WithRSAEncryption' - end, - {Type, 'NULL'}; -sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) -> - {?'id-dsa-with-sha1', {params,#'Dss-Parms'{p=P, q=Q, g=G}}}. - -make_key(rsa, _Opts) -> - %% (OBS: for testing only) - gen_rsa2(64); -make_key(dsa, _Opts) -> - gen_dsa2(128, 20). %% Bytes i.e. {1024, 160} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% RSA key generation (OBS: for testing only) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --define(SMALL_PRIMES, [65537,97,89,83,79,73,71,67,61,59,53, - 47,43,41,37,31,29,23,19,17,13,11,7,5,3]). - -gen_rsa2(Size) -> - P = prime(Size), - Q = prime(Size), - N = P*Q, - Tot = (P - 1) * (Q - 1), - [E|_] = lists:dropwhile(fun(Candidate) -> (Tot rem Candidate) == 0 end, ?SMALL_PRIMES), - {D1,D2} = extended_gcd(E, Tot), - D = erlang:max(D1,D2), - case D < E of - true -> - gen_rsa2(Size); - false -> - {Co1,Co2} = extended_gcd(Q, P), - Co = erlang:max(Co1,Co2), - #'RSAPrivateKey'{version = 'two-prime', - modulus = N, - publicExponent = E, - privateExponent = D, - prime1 = P, - prime2 = Q, - exponent1 = D rem (P-1), - exponent2 = D rem (Q-1), - coefficient = Co - } - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% DSA key generation (OBS: for testing only) -%% See http://en.wikipedia.org/wiki/Digital_Signature_Algorithm -%% and the fips_186-3.pdf -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -gen_dsa2(LSize, NSize) -> - Q = prime(NSize), %% Choose N-bit prime Q - X0 = prime(LSize), - P0 = prime((LSize div 2) +1), - - %% Choose L-bit prime modulus P such that p-1 is a multiple of q. - case dsa_search(X0 div (2*Q*P0), P0, Q, 1000) of - error -> - gen_dsa2(LSize, NSize); - P -> - G = crypto:mod_exp(2, (P-1) div Q, P), % Choose G a number whose multiplicative order modulo p is q. - %% such that This may be done by setting g = h^(p-1)/q mod p, commonly h=2 is used. - - X = prime(20), %% Choose x by some random method, where 0 < x < q. - Y = crypto:mod_exp(G, X, P), %% Calculate y = g^x mod p. - - #'DSAPrivateKey'{version=0, p=P, q=Q, g=G, y=Y, x=X} - end. - -%% See fips_186-3.pdf -dsa_search(T, P0, Q, Iter) when Iter > 0 -> - P = 2*T*Q*P0 + 1, - case is_prime(crypto:mpint(P), 50) of - true -> P; - false -> dsa_search(T+1, P0, Q, Iter-1) - end; -dsa_search(_,_,_,_) -> - error. - - -%%%%%%% Crypto Math %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -prime(ByteSize) -> - Rand = odd_rand(ByteSize), - crypto:erlint(prime_odd(Rand, 0)). - -prime_odd(Rand, N) -> - case is_prime(Rand, 50) of - true -> - Rand; - false -> - NotPrime = crypto:erlint(Rand), - prime_odd(crypto:mpint(NotPrime+2), N+1) - end. - -%% see http://en.wikipedia.org/wiki/Fermat_primality_test -is_prime(_, 0) -> true; -is_prime(Candidate, Test) -> - CoPrime = odd_rand(<<0,0,0,4, 10000:32>>, Candidate), - case crypto:mod_exp(CoPrime, Candidate, Candidate) of - CoPrime -> is_prime(Candidate, Test-1); - _ -> false - end. - -odd_rand(Size) -> - Min = 1 bsl (Size*8-1), - Max = (1 bsl (Size*8))-1, - odd_rand(crypto:mpint(Min), crypto:mpint(Max)). - -odd_rand(Min,Max) -> - Rand = <<Sz:32, _/binary>> = crypto:rand_uniform(Min,Max), - BitSkip = (Sz+4)*8-1, - case Rand of - Odd = <<_:BitSkip, 1:1>> -> Odd; - Even = <<_:BitSkip, 0:1>> -> - crypto:mpint(crypto:erlint(Even)+1) - end. - -extended_gcd(A, B) -> - case A rem B of - 0 -> - {0, 1}; - N -> - {X, Y} = extended_gcd(B, N), - {Y, X-Y*(A div B)} - end. - -pem_to_der(File) -> - {ok, PemBin} = file:read_file(File), - public_key:pem_decode(PemBin). + KHFile = filename:join(UserDir, "known_hosts"), + file:write_file(KHFile, KnownHostsEnc). -der_to_pem(File, Entries) -> - PemBin = public_key:pem_encode(Entries), - file:write_file(File, PemBin). +clean_dsa(UserDir) -> + file:delete(filename:join(UserDir, "ssh_host_dsa_key")), + file:delete(filename:join(UserDir, "ssh_host_dsa_key.pub")), + file:delete(filename:join(UserDir, "known_hosts")). diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl index f959d50484..53d04620c5 100644 --- a/lib/ssh/test/ssh_to_openssh_SUITE.erl +++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -42,8 +42,12 @@ init_per_suite(Config) -> case catch crypto:start() of ok -> - ssh_test_lib:make_dsa_files(Config), - Config; + case gen_tcp:connect("localhost", 22, []) of + {error,econnrefused} -> + {skip,"No openssh deamon"}; + _ -> + Config + end; _Else -> {skip,"Could not start crypto!"} end. @@ -100,26 +104,43 @@ all() -> false -> {skip, "openSSH not installed on host"}; _ -> - [erlang_shell_client_openssh_server, - erlang_client_openssh_server_exec, - erlang_client_openssh_server_exec_compressed, - erlang_server_openssh_client_exec, - erlang_server_openssh_client_exec_compressed, - erlang_client_openssh_server_setenv, - erlang_client_openssh_server_publickey_rsa, - erlang_client_openssh_server_publickey_dsa, - erlang_server_openssh_client_pulic_key_dsa, - erlang_client_openssh_server_password] + [{group, erlang_client}, + {group, erlang_server} + ] end. groups() -> - []. - -init_per_group(_GroupName, Config) -> - Config. + [{erlang_client, [], [erlang_shell_client_openssh_server, + erlang_client_openssh_server_exec, + erlang_client_openssh_server_exec_compressed, + erlang_client_openssh_server_setenv, + erlang_client_openssh_server_publickey_rsa, + erlang_client_openssh_server_publickey_dsa, + erlang_client_openssh_server_password]}, + {erlang_server, [], [erlang_server_openssh_client_exec, + erlang_server_openssh_client_exec_compressed, + erlang_server_openssh_client_pulic_key_dsa, + erlang_client_openssh_server_password]} + ]. + +init_per_group(erlang_server, Config) -> + DataDir = ?config(data_dir, Config), + UserDir = ?config(priv_dir, Config), + ssh_test_lib:setup_dsa(DataDir, UserDir), + Config; +init_per_group(_, Config) -> + Dir = ?config(priv_dir, Config), + {ok, _} = ssh_test_lib:get_id_keys(Dir), + Config. -end_per_group(_GroupName, Config) -> - Config. +end_per_group(erlang_server, Config) -> + UserDir = ?config(priv_dir, Config), + ssh_test_lib:clean_dsa(UserDir), + Config; +end_per_group(_, Config) -> + Dir = ?config(priv_dir, Config), + ssh_test_lib:remove_id_keys(Dir), + Config. %% TEST cases starts here. %%-------------------------------------------------------------------- @@ -131,8 +152,9 @@ erlang_shell_client_openssh_server(suite) -> erlang_shell_client_openssh_server(Config) when is_list(Config) -> process_flag(trap_exit, true), + UserDir = ?config(priv_dir, Config), IO = ssh_test_lib:start_io_server(), - Shell = ssh_test_lib:start_shell(?SSH_DEFAULT_PORT, IO), + Shell = ssh_test_lib:start_shell(?SSH_DEFAULT_PORT, IO, UserDir), IO ! {input, self(), "echo Hej\n"}, receive_hej(), IO ! {input, self(), "exit\n"}, @@ -228,7 +250,7 @@ erlang_server_openssh_client_exec(suite) -> []; erlang_server_openssh_client_exec(Config) when is_list(Config) -> - SystemDir = ?config(data_dir, Config), + SystemDir = ?config(priv_dir, Config), {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, {failfun, fun ssh_test_lib:failfun/2}]), @@ -257,7 +279,7 @@ erlang_server_openssh_client_exec_compressed(suite) -> []; erlang_server_openssh_client_exec_compressed(Config) when is_list(Config) -> - SystemDir = ?config(data_dir, Config), + SystemDir = ?config(priv_dir, Config), {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, {compression, zlib}, {failfun, fun ssh_test_lib:failfun/2}]), @@ -346,7 +368,9 @@ erlang_client_openssh_server_publickey_rsa(Config) when is_list(Config) -> ok = ssh:close(ConnectionRef), ok = file:delete(filename:join(UserDir, "id_rsa")); {error, enoent} -> - {skip, "no ~/.ssh/id_rsa"} + {skip, "no ~/.ssh/id_rsa"}; + {error, Reason} -> + {skip, Reason} end. %%-------------------------------------------------------------------- @@ -372,7 +396,9 @@ erlang_client_openssh_server_publickey_dsa(Config) when is_list(Config) -> ok = ssh:close(ConnectionRef), ok = file:delete(filename:join(UserDir, "id_dsa")); {error, enoent} -> - {skip, "no ~/.ssh/id_dsa"} + {skip, "no ~/.ssh/id_dsa"}; + {error, Reason} -> + {skip, Reason} end. %%-------------------------------------------------------------------- @@ -383,7 +409,7 @@ erlang_server_openssh_client_pulic_key_dsa(suite) -> []; erlang_server_openssh_client_pulic_key_dsa(Config) when is_list(Config) -> - SystemDir = ?config(data_dir, Config), + SystemDir = ?config(priv_dir, Config), {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, {public_key_alg, ssh_dsa}, {failfun, fun ssh_test_lib:failfun/2}]), diff --git a/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_dsa_key new file mode 100644 index 0000000000..51ab6fbd88 --- /dev/null +++ b/lib/ssh/test/ssh_to_openssh_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_to_openssh_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_to_openssh_SUITE_data/ssh_host_dsa_key.pub new file mode 100644 index 0000000000..4dbb1305b0 --- /dev/null +++ b/lib/ssh/test/ssh_to_openssh_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 ---- |