diff options
Diffstat (limited to 'lib/ssh/test/ssh_basic_SUITE.erl')
-rw-r--r-- | lib/ssh/test/ssh_basic_SUITE.erl | 303 |
1 files changed, 231 insertions, 72 deletions
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl index 73b60057cc..c5019425cd 100644 --- a/lib/ssh/test/ssh_basic_SUITE.erl +++ b/lib/ssh/test/ssh_basic_SUITE.erl @@ -41,20 +41,6 @@ init_per_suite(Config) -> case catch crypto:start() of ok -> - 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!"} @@ -66,7 +52,8 @@ 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) -> + ssh:stop(), crypto:stop(), ok. @@ -99,11 +86,11 @@ init_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), + ssh_test_lib:del_dirs(UserDir), end_per_testcase(Config); end_per_testcase(_TestCase, Config) -> end_per_testcase(Config). -end_per_testcase(Config) -> +end_per_testcase(_Config) -> ssh:stop(), ok. @@ -116,31 +103,109 @@ end_per_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]. + [app_test, + {group, dsa_key}, + {group, rsa_key}, + {group, dsa_pass_key}, + {group, rsa_pass_key}, + {group, internal_error}, + daemon_already_started, + server_password_option, server_userpassword_option, + close]. groups() -> - []. - -init_per_group(_GroupName, Config) -> - Config. + [{dsa_key, [], [exec, exec_compressed, shell, known_hosts]}, + {rsa_key, [], [exec, exec_compressed, shell, known_hosts]}, + {dsa_pass_key, [], [pass_phrase]}, + {rsa_pass_key, [], [pass_phrase]}, + {internal_error, [], [internal_error]} + ]. + +init_per_group(dsa_key, Config) -> + DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + ssh_test_lib:setup_dsa(DataDir, PrivDir), + Config; +init_per_group(rsa_key, Config) -> + DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + ssh_test_lib:setup_rsa(DataDir, PrivDir), + Config; +init_per_group(rsa_pass_key, Config) -> + DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + ssh_test_lib:setup_rsa_pass_pharse(DataDir, PrivDir, "Password"), + [{pass_phrase, {rsa_pass_phrase, "Password"}}| Config]; +init_per_group(dsa_pass_key, Config) -> + DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + ssh_test_lib:setup_dsa_pass_pharse(DataDir, PrivDir, "Password"), + [{pass_phrase, {dsa_pass_phrase, "Password"}}| Config]; +init_per_group(internal_error, Config) -> + DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + ssh_test_lib:setup_dsa(DataDir, PrivDir), + file:delete(filename:join(PrivDir, "system/ssh_host_dsa_key")), + Config; +init_per_group(_, Config) -> + Config. -end_per_group(_GroupName, Config) -> - Config. +end_per_group(dsa_key, Config) -> + PrivDir = ?config(priv_dir, Config), + ssh_test_lib:clean_dsa(PrivDir), + Config; +end_per_group(rsa_key, Config) -> + PrivDir = ?config(priv_dir, Config), + ssh_test_lib:clean_rsa(PrivDir), + Config; +end_per_group(dsa_pass_key, Config) -> + PrivDir = ?config(priv_dir, Config), + ssh_test_lib:clean_dsa(PrivDir), + Config; +end_per_group(rsa_pass_key, Config) -> + PrivDir = ?config(priv_dir, Config), + ssh_test_lib:clean_rsa(PrivDir), + Config; +end_per_group(internal_error, Config) -> + PrivDir = ?config(priv_dir, Config), + ssh_test_lib:clean_dsa(PrivDir), + Config; + +end_per_group(_, Config) -> + Config. %% Test cases starts here. %%-------------------------------------------------------------------- -sign_and_verify_rsa(doc) -> - ["Test api function ssh:sign_data and ssh:verify_data"]; - -sign_and_verify_rsa(suite) -> +app_test(suite) -> + []; +app_test(doc) -> + ["Application consistency test."]; +app_test(Config) when is_list(Config) -> + ?t:app_test(ssh), + ok. +%%-------------------------------------------------------------------- +misc_ssh_options(doc) -> + ["Test that we can set some misc options not tested elsewhere, " + "some options not yet present are not decided if we should support or " + "if they need thier own test case."]; +misc_ssh_options(suite) -> []; -sign_and_verify_rsa(Config) when is_list(Config) -> - Data = ssh:sign_data(<<"correct data">>, "ssh-rsa"), - ok = ssh:verify_data(<<"correct data">>, Data, "ssh-rsa"), - {error,invalid_signature} = ssh:verify_data(<<"incorrect data">>, Data,"ssh-rsa"). +misc_ssh_options(Config) when is_list(Config) -> + SystemDir = filename:join(?config(priv_dir, Config), system), + UserDir = ?config(priv_dir, Config), + + CMiscOpt0 = [{connecect_timeout, 1000}, {ip_v6_disable, false}, {user_dir, UserDir}], + CMiscOpt1 = [{connecect_timeout, infinity}, {ip_v6_disable, true}, {user_dir, UserDir}], + SMiscOpt0 = [{ip_v6_disable, false}, {user_dir, UserDir}, {system_dir, SystemDir}], + SMiscOpt1 = [{ip_v6_disable, true}, {user_dir, UserDir}, {system_dir, SystemDir}], + + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + basic_test([{client_opts, CMiscOpt0 ++ ClientOpts}, {server_opts, SMiscOpt0 ++ ServerOpts}]), + basic_test([{client_opts, CMiscOpt1 ++ ClientOpts}, {server_opts, SMiscOpt1 ++ ServerOpts}]). +%%-------------------------------------------------------------------- exec(doc) -> ["Test api function ssh_connection:exec"]; @@ -149,7 +214,7 @@ exec(suite) -> exec(Config) when is_list(Config) -> process_flag(trap_exit, true), - SystemDir = ?config(data_dir, Config), + SystemDir = filename:join(?config(priv_dir, Config), system), UserDir = ?config(priv_dir, Config), {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, @@ -195,8 +260,8 @@ exec_compressed(suite) -> exec_compressed(Config) when is_list(Config) -> process_flag(trap_exit, true), - SystemDir = ?config(data_dir, Config), - UserDir = ?config(priv_dir, Config), + SystemDir = filename:join(?config(priv_dir, Config), system), + UserDir = ?config(priv_dir, Config), {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir}, {compression, zlib}, @@ -229,9 +294,9 @@ shell(suite) -> shell(Config) when is_list(Config) -> process_flag(trap_exit, true), - SystemDir = ?config(data_dir, Config), + SystemDir = filename:join(?config(priv_dir, Config), system), 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), @@ -239,9 +304,14 @@ shell(Config) when is_list(Config) -> IO = ssh_test_lib:start_io_server(), Shell = ssh_test_lib:start_shell(Port, IO, UserDir), receive + {'EXIT', _, _} -> + test_server:fail(no_ssh_connection); ErlShellStart -> - test_server:format("Erlang shell start: ~p~n", [ErlShellStart]) - end, + test_server:format("Erlang shell start: ~p~n", [ErlShellStart]), + do_shell(IO, Shell) + end. + +do_shell(IO, Shell) -> receive ErlPrompt0 -> test_server:format("Erlang prompt: ~p~n", [ErlPrompt0]) @@ -301,9 +371,13 @@ daemon_already_started(suite) -> daemon_already_started(Config) when is_list(Config) -> 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}]), {error, eaddrinuse} = ssh_test_lib:daemon(Port, [{system_dir, SystemDir}, + {user_dir, UserDir}, {failfun, fun ssh_test_lib:failfun/2}]), ssh:stop_daemon(Pid). @@ -314,10 +388,12 @@ server_password_option(doc) -> server_password_option(suite) -> []; server_password_option(Config) when is_list(Config) -> - UserDir = filename:join(?config(priv_dir, Config), nopubkey), % to make sure we don't use public-key-auth + PrivDir = ?config(priv_dir, Config), + UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth file:make_dir(UserDir), - SysDir = ?config(data_dir, Config), + SysDir = ?config(data_dir, Config), {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir}, + {user_dir, UserDir}, {password, "morot"}]), ConnectionRef = @@ -326,12 +402,15 @@ server_password_option(Config) when is_list(Config) -> {password, "morot"}, {user_interaction, false}, {user_dir, UserDir}]), + + Reason = "Unable to connect using the available authentication methods", + {error, Reason} = - ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true}, - {user, "vego"}, - {password, "foo"}, - {user_interaction, false}, - {user_dir, UserDir}]), + ssh:connect(Host, Port, [{silently_accept_hosts, true}, + {user, "vego"}, + {password, "foo"}, + {user_interaction, false}, + {user_dir, UserDir}]), test_server:format("Test of wrong password: Error msg: ~p ~n", [Reason]), @@ -345,10 +424,12 @@ server_userpassword_option(doc) -> server_userpassword_option(suite) -> []; server_userpassword_option(Config) when is_list(Config) -> - UserDir = filename:join(?config(priv_dir, Config), nopubkey), % to make sure we don't use public-key-auth + PrivDir = ?config(priv_dir, Config), + UserDir = filename:join(PrivDir, 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_dir, PrivDir}, {user_passwords, [{"vego", "morot"}]}]), ConnectionRef = @@ -359,25 +440,20 @@ server_userpassword_option(Config) when is_list(Config) -> {user_dir, UserDir}]), ssh:close(ConnectionRef), - {error, Reason0} = - ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true}, - {user, "foo"}, - {password, "morot"}, - {user_interaction, false}, - {user_dir, UserDir}]), - - test_server:format("Test of user foo that does not exist. " - "Error msg: ~p ~n", [Reason0]), + Reason = "Unable to connect using the available authentication methods", - {error, Reason1} = - ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true}, - {user, "vego"}, - {password, "foo"}, - {user_interaction, false}, - {user_dir, UserDir}]), - test_server:format("Test of wrong Password. " - "Error msg: ~p ~n", [Reason1]), - + {error, Reason} = + ssh:connect(Host, Port, [{silently_accept_hosts, true}, + {user, "foo"}, + {password, "morot"}, + {user_interaction, false}, + {user_dir, UserDir}]), + {error, Reason} = + ssh:connect(Host, Port, [{silently_accept_hosts, true}, + {user, "vego"}, + {password, "foo"}, + {user_interaction, false}, + {user_dir, UserDir}]), ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- @@ -386,17 +462,17 @@ known_hosts(doc) -> known_hosts(suite) -> []; known_hosts(Config) when is_list(Config) -> - DataDir = ?config(data_dir, Config), - UserDir = ?config(priv_dir, Config), + SystemDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), - {Pid, Host, Port} = ssh_test_lib:daemon([{user_dir, UserDir},{system_dir, DataDir}, + {Pid, Host, Port} = ssh_test_lib:daemon([{user_dir, PrivDir},{system_dir, SystemDir}, {failfun, fun ssh_test_lib:failfun/2}]), - KnownHosts = filename:join(UserDir, "known_hosts"), + KnownHosts = filename:join(PrivDir, "known_hosts"), file:delete(KnownHosts), {error, enoent} = file:read_file(KnownHosts), ConnectionRef = - ssh_test_lib:connect(Host, Port, [{user_dir, UserDir}, + ssh_test_lib:connect(Host, Port, [{user_dir, PrivDir}, {user_interaction, false}, silently_accept_hosts]), {ok, _Channel} = ssh_connection:session_channel(ConnectionRef, infinity), @@ -407,8 +483,91 @@ known_hosts(Config) when is_list(Config) -> [HostAndIp, Alg, _KeyData] = string:tokens(Line, " "), [Host, _Ip] = string:tokens(HostAndIp, ","), "ssh-" ++ _ = Alg, - ssh:stop_daemon(Pid). + ssh:stop_daemon(Pid). +%%-------------------------------------------------------------------- + +pass_phrase(doc) -> + ["Test that we can use keyes protected by pass phrases"]; + +pass_phrase(suite) -> + []; + +pass_phrase(Config) when is_list(Config) -> + process_flag(trap_exit, true), + SystemDir = filename:join(?config(priv_dir, Config), system), + UserDir = ?config(priv_dir, Config), + PhraseArg = ?config(pass_phrase, 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}, + PhraseArg, + {user_dir, UserDir}, + {user_interaction, false}]), + {ok, _ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity), + ssh:stop_daemon(Pid). + +%%-------------------------------------------------------------------- + +internal_error(doc) -> + ["Test that client does not hang if disconnects due to internal error"]; + +internal_error(suite) -> + []; + +internal_error(Config) when is_list(Config) -> + process_flag(trap_exit, true), + SystemDir = filename:join(?config(priv_dir, Config), system), + 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}]), + {error,"Internal error"} = + ssh:connect(Host, Port, [{silently_accept_hosts, true}, + {user_dir, UserDir}, + {user_interaction, false}]), + ssh:stop_daemon(Pid). + +%%-------------------------------------------------------------------- +close(doc) -> + ["Simulate that we try to close an already closed connection"]; + +close(suite) -> + []; + +close(Config) when is_list(Config) -> + SystemDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth + file:make_dir(UserDir), + + {_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, + {user_dir, UserDir}, + {user_passwords, [{"vego", "morot"}]}, + {failfun, fun ssh_test_lib:failfun/2}]), + {ok, CM} = ssh:connect(Host, Port, [{silently_accept_hosts, true}, + {user_dir, UserDir}, + {user, "vego"}, + {password, "morot"}, + {user_interaction, false}]), + + exit(CM, {shutdown, normal}), + ok = ssh:close(CM). + + %%-------------------------------------------------------------------- %% Internal functions %%-------------------------------------------------------------------- + +basic_test(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + + {Pid, Host, Port} = ssh_test_lib:daemon(ServerOpts), + {ok, CM} = ssh:connect(Host, Port, ClientOpts), + ok = ssh:close(CM), + ssh:stop_daemon(Pid). |