diff options
Diffstat (limited to 'lib/ssh/test/ssh_sftp_SUITE.erl')
-rw-r--r-- | lib/ssh/test/ssh_sftp_SUITE.erl | 473 |
1 files changed, 300 insertions, 173 deletions
diff --git a/lib/ssh/test/ssh_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl index c2b04d7a05..7aa3d8a00a 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-2014. All Rights Reserved. +%% Copyright Ericsson AB 2005-2017. 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. @@ -26,7 +26,7 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("kernel/include/file.hrl"). - +-include("ssh_test_lib.hrl"). % Default timetrap timeout -define(default_timeout, ?t:minutes(1)). @@ -36,8 +36,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap,{minutes,2}}]. - + {timetrap,{seconds,40}}]. all() -> [{group, not_unicode}, @@ -46,10 +45,13 @@ all() -> init_per_suite(Config) -> - ct:log("file:native_name_encoding() = ~p,~nio:getopts() = ~p", - [file:native_name_encoding(),io:getopts()]), - ssh:start(), - Config. + ?CHECK_CRYPTO( + begin + ct:log("file:native_name_encoding() = ~p,~nio:getopts() = ~p", + [file:native_name_encoding(),io:getopts()]), + ssh:start(), + Config + end). end_per_suite(_onfig) -> ssh:stop(). @@ -58,12 +60,16 @@ end_per_suite(_onfig) -> groups() -> [{not_unicode, [], [{group,erlang_server}, {group,openssh_server}, + {group,big_recvpkt_size}, sftp_nonexistent_subsystem]}, {unicode, [], [{group,erlang_server}, {group,openssh_server}, sftp_nonexistent_subsystem]}, + {big_recvpkt_size, [], [{group,erlang_server}, + {group,openssh_server}]}, + {erlang_server, [], [{group,write_read_tests}, version_option, {group,remote_tar}]}, @@ -86,43 +92,44 @@ groups() -> {write_read_tests, [], [open_close_file, open_close_dir, read_file, read_dir, write_file, write_file_iolist, write_big_file, sftp_read_big_file, rename_file, mk_rm_dir, remove_file, links, - retrieve_attributes, set_attributes, async_read, - async_write, position, pos_read, pos_write + retrieve_attributes, set_attributes, file_owner_access, async_read, + async_write, position, pos_read, pos_write, + start_channel_sock ]} ]. init_per_group(not_unicode, Config) -> ct:comment("Begin ~p",[grps(Config)]), - DataDir = ?config(data_dir, Config), - PrivDir = ?config(priv_dir, Config), + DataDir = proplists:get_value(data_dir, Config), [{user, "Alladin"}, {passwd, "Sesame"}, {data, <<"Hello world!">>}, - {filename, filename:join(PrivDir, "sftp.txt")}, - {testfile, filename:join(PrivDir, "test.txt")}, - {linktest, filename:join(PrivDir, "link_test.txt")}, - {tar_filename, filename:join(PrivDir, "sftp_tar_test.tar")}, - {tar_F1_txt, "f1.txt"}, + {filename, "sftp.txt"}, + {testfile, "test.txt"}, + {linktest, "link_test.txt"}, + {tar_filename, "sftp_tar_test.tar"}, + {tar_F1_txt, "f1.txt"}, {datadir_tar, filename:join(DataDir,"sftp_tar_test_data")} | Config]; init_per_group(unicode, Config) -> - case file:native_name_encoding() of - utf8 -> + case (file:native_name_encoding() == utf8) + andalso ("四" == [22235]) + of + true -> ct:comment("Begin ~p",[grps(Config)]), - DataDir = ?config(data_dir, Config), - PrivDir = ?config(priv_dir, Config), + DataDir = proplists:get_value(data_dir, Config), NewConfig = [{user, "åke高兴"}, {passwd, "ärlig日本じん"}, {data, <<"foobar å 一二三四いちにさんち">>}, - {filename, filename:join(PrivDir, "sftp瑞点.txt")}, - {testfile, filename:join(PrivDir, "testハンス.txt")}, - {linktest, filename:join(PrivDir, "link_test語.txt")}, - {tar_filename, filename:join(PrivDir, "sftp_tar_test一二三.tar")}, - {tar_F1_txt, "F一.txt"}, - {tar_F3_txt, "f3.txt"}, - {tar_F4_txt, "g四.txt"}, + {filename, "sftp瑞点.txt"}, + {testfile, "testハンス.txt"}, + {linktest, "link_test語.txt"}, + {tar_filename, "sftp_tar_test一二三.tar"}, + {tar_F1_txt, "F一.txt"}, + {tar_F3_txt, "f3.txt"}, + {tar_F4_txt, "g四.txt"}, {datadir_tar, filename:join(DataDir,"sftp_tar_test_data_高兴")} | lists:foldl(fun(K,Cf) -> lists:keydelete(K,1,Cf) end, Config, @@ -132,7 +139,7 @@ init_per_group(unicode, Config) -> ] ) ], - FN = fn(?config(tar_F1_txt,NewConfig), NewConfig), + FN = fn(proplists:get_value(tar_F1_txt,NewConfig), NewConfig), case catch file:read_file(FN) of {ok,FN_contents} -> ct:log("Readable file:read_file(~tp) ->~n~tp",[FN,FN_contents]), @@ -146,12 +153,15 @@ init_per_group(unicode, Config) -> {skip, "Not unicode file encoding"} end; +init_per_group(big_recvpkt_size, Config) -> + [{pkt_sz,123456} | Config]; + init_per_group(erlang_server, Config) -> ct:comment("Begin ~p",[grps(Config)]), - PrivDir = ?config(priv_dir, Config), - SysDir = ?config(data_dir, Config), - User = ?config(user, Config), - Passwd = ?config(passwd, Config), + PrivDir = proplists:get_value(priv_dir, Config), + SysDir = proplists:get_value(data_dir, Config), + User = proplists:get_value(user, Config), + Passwd = proplists:get_value(passwd, Config), Sftpd = {_, HostX, PortX} = ssh_test_lib:daemon([{system_dir, SysDir}, {user_dir, PrivDir}, @@ -177,12 +187,12 @@ init_per_group(openssh_server, Config) -> init_per_group(remote_tar, Config) -> ct:comment("Begin ~p",[grps(Config)]), - {Host,Port} = ?config(peer, Config), - ct:log("Server (~p) at ~p:~p",[?config(group,Config),Host,Port]), - User = ?config(user, Config), - Passwd = ?config(passwd, Config), + {Host,Port} = proplists:get_value(peer, Config), + ct:log("Server (~p) at ~p:~p",[proplists:get_value(group,Config),Host,Port]), + User = proplists:get_value(user, Config), + Passwd = proplists:get_value(passwd, Config), {ok, Connection} = - case ?config(group, Config) of + case proplists:get_value(group, Config) of erlang_server -> ssh:connect(Host, Port, [{user, User}, @@ -217,10 +227,10 @@ end_per_group(_, Config) -> %%-------------------------------------------------------------------- init_per_testcase(sftp_nonexistent_subsystem, Config) -> - PrivDir = ?config(priv_dir, Config), - SysDir = ?config(data_dir, Config), - User = ?config(user, Config), - Passwd = ?config(passwd, Config), + PrivDir = proplists:get_value(priv_dir, Config), + SysDir = proplists:get_value(data_dir, Config), + User = proplists:get_value(user, Config), + Passwd = proplists:get_value(passwd, Config), Sftpd = ssh_test_lib:daemon([{system_dir, SysDir}, {user_dir, PrivDir}, {subsystems, []}, @@ -229,14 +239,14 @@ init_per_testcase(sftp_nonexistent_subsystem, Config) -> ]), [{sftpd, Sftpd} | Config]; -init_per_testcase(version_option, Config) -> - prep(Config), +init_per_testcase(version_option, Config0) -> + Config = prepare(Config0), TmpConfig0 = lists:keydelete(watchdog, 1, Config), TmpConfig = lists:keydelete(sftp, 1, TmpConfig0), Dog = ct:timetrap(?default_timeout), - {_,Host, Port} = ?config(sftpd, Config), - User = ?config(user, Config), - Passwd = ?config(passwd, Config), + {_,Host, Port} = proplists:get_value(sftpd, Config), + User = proplists:get_value(user, Config), + Passwd = proplists:get_value(passwd, Config), {ok, ChannelPid, Connection} = ssh_sftp:start_channel(Host, Port, [{sftp_vsn, 3}, @@ -247,24 +257,29 @@ init_per_testcase(version_option, Config) -> Sftp = {ChannelPid, Connection}, [{sftp,Sftp}, {watchdog, Dog} | TmpConfig]; -init_per_testcase(Case, Config0) -> - prep(Config0), +init_per_testcase(Case, Config00) -> + Config0 = prepare(Config00), Config1 = lists:keydelete(watchdog, 1, Config0), Config2 = lists:keydelete(sftp, 1, Config1), Dog = ct:timetrap(2 * ?default_timeout), - User = ?config(user, Config0), - Passwd = ?config(passwd, Config0), - + User = proplists:get_value(user, Config0), + Passwd = proplists:get_value(passwd, Config0), + PktSzOpt = case proplists:get_value(pkt_sz, Config0) of + undefined -> []; + Sz -> [{packet_size,Sz}] + end, Config = - case ?config(group,Config2) of + case proplists:get_value(group,Config2) of erlang_server -> - {_,Host, Port} = ?config(sftpd, Config2), + {_,Host, Port} = proplists:get_value(sftpd, Config2), {ok, ChannelPid, Connection} = ssh_sftp:start_channel(Host, Port, [{user, User}, {password, Passwd}, {user_interaction, false}, - {silently_accept_hosts, true}] + {silently_accept_hosts, true} + | PktSzOpt + ] ), Sftp = {ChannelPid, Connection}, [{sftp, Sftp}, {watchdog, Dog} | Config2]; @@ -275,16 +290,18 @@ init_per_testcase(Case, Config0) -> {ok, ChannelPid, Connection} = ssh_sftp:start_channel(Host, [{user_interaction, false}, - {silently_accept_hosts, true}]), + {silently_accept_hosts, true} + | PktSzOpt + ]), Sftp = {ChannelPid, Connection}, [{sftp, Sftp}, {watchdog, Dog} | Config2] end, - case catch ?config(remote_tar,Config) of + case catch proplists:get_value(remote_tar,Config) of %% The 'catch' is for the case of Config={skip,...} true -> %% Provide a ChannelPid independent of the sftp-channel already opened. - {ok,ChPid2} = ssh_sftp:start_channel(?config(connection,Config)), + {ok,ChPid2} = ssh_sftp:start_channel(proplists:get_value(connection,Config)), [{channel_pid2,ChPid2} | Config]; _ -> Config @@ -293,17 +310,17 @@ init_per_testcase(Case, Config0) -> end_per_testcase(sftp_nonexistent_subsystem, Config) -> Config; end_per_testcase(rename_file, Config) -> - NewFileName = ?config(testfile, Config), + NewFileName = proplists:get_value(testfile, Config), file:delete(NewFileName), end_per_testcase(Config); end_per_testcase(_, Config) -> end_per_testcase(Config). end_per_testcase(Config) -> - {Sftp, Connection} = ?config(sftp, Config), - ssh_sftp:stop_channel(Sftp), - catch ssh_sftp:stop_channel(?config(channel_pid2, Config)), - ssh:close(Connection). + {Sftp, Connection} = proplists:get_value(sftp, Config), + ok = ssh_sftp:stop_channel(Sftp), + catch ssh_sftp:stop_channel(proplists:get_value(channel_pid2, Config)), + ok = ssh:close(Connection). %%-------------------------------------------------------------------- %% Test Cases -------------------------------------------------------- @@ -311,9 +328,9 @@ end_per_testcase(Config) -> open_close_file() -> [{doc, "Test API functions open/3 and close/2"}]. open_close_file(Config) when is_list(Config) -> - FileName = ?config(filename, Config), + FileName = proplists:get_value(filename, Config), - {Sftp, _} = ?config(sftp, Config), + {Sftp, _} = proplists:get_value(sftp, Config), ok = open_close_file(Sftp, FileName, [read]), ok = open_close_file(Sftp, FileName, [write]), @@ -330,9 +347,9 @@ open_close_file(Server, File, Mode) -> open_close_dir() -> [{doc, "Test API functions opendir/2 and close/2"}]. open_close_dir(Config) when is_list(Config) -> - PrivDir = ?config(priv_dir, Config), - {Sftp, _} = ?config(sftp, Config), - FileName = ?config(filename, Config), + PrivDir = proplists:get_value(sftp_priv_dir, Config), + {Sftp, _} = proplists:get_value(sftp, Config), + FileName = proplists:get_value(filename, Config), {ok, Handle} = ssh_sftp:opendir(Sftp, PrivDir), ok = ssh_sftp:close(Sftp, Handle), @@ -342,8 +359,8 @@ open_close_dir(Config) when is_list(Config) -> read_file() -> [{doc, "Test API funtion read_file/2"}]. read_file(Config) when is_list(Config) -> - FileName = ?config(filename, Config), - {Sftp, _} = ?config(sftp, Config), + FileName = proplists:get_value(filename, Config), + {Sftp, _} = proplists:get_value(sftp, Config), {ok, Data} = ssh_sftp:read_file(Sftp, FileName), {ok, Data} = ssh_sftp:read_file(Sftp, FileName), {ok, Data} = file:read_file(FileName). @@ -352,8 +369,8 @@ read_file(Config) when is_list(Config) -> read_dir() -> [{doc,"Test API function list_dir/2"}]. read_dir(Config) when is_list(Config) -> - PrivDir = ?config(priv_dir, Config), - {Sftp, _} = ?config(sftp, Config), + PrivDir = proplists:get_value(sftp_priv_dir, Config), + {Sftp, _} = proplists:get_value(sftp, Config), {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir), ct:log("sftp list dir: ~p~n", [Files]). @@ -361,24 +378,24 @@ read_dir(Config) when is_list(Config) -> write_file() -> [{doc, "Test API function write_file/2"}]. write_file(Config) when is_list(Config) -> - FileName = ?config(filename, Config), - {Sftp, _} = ?config(sftp, Config), + FileName = proplists:get_value(filename, Config), + {Sftp, _} = proplists:get_value(sftp, Config), Data = list_to_binary("Hej hopp!"), - ssh_sftp:write_file(Sftp, FileName, [Data]), + ok = ssh_sftp:write_file(Sftp, FileName, [Data]), {ok, Data} = file:read_file(FileName). %%-------------------------------------------------------------------- write_file_iolist() -> [{doc, "Test API function write_file/2 with iolists"}]. write_file_iolist(Config) when is_list(Config) -> - FileName = ?config(filename, Config), - {Sftp, _} = ?config(sftp, Config), + FileName = proplists:get_value(filename, Config), + {Sftp, _} = proplists:get_value(sftp, Config), Data = list_to_binary("Hej hopp!"), lists:foreach( fun(D) -> - ssh_sftp:write_file(Sftp, FileName, [D]), + ok = ssh_sftp:write_file(Sftp, FileName, [D]), Expected = if is_binary(D) -> D; is_list(D) -> list_to_binary(D) end, @@ -393,48 +410,48 @@ write_file_iolist(Config) when is_list(Config) -> write_big_file() -> [{doc, "Test API function write_file/2 with big data"}]. write_big_file(Config) when is_list(Config) -> - FileName = ?config(filename, Config), - {Sftp, _} = ?config(sftp, Config), + FileName = proplists:get_value(filename, Config), + {Sftp, _} = proplists:get_value(sftp, Config), Data = list_to_binary(lists:duplicate(750000,"a")), - ssh_sftp:write_file(Sftp, FileName, [Data]), + ok = ssh_sftp:write_file(Sftp, FileName, [Data]), {ok, Data} = file:read_file(FileName). %%-------------------------------------------------------------------- sftp_read_big_file() -> [{doc, "Test API function read_file/2 with big data"}]. sftp_read_big_file(Config) when is_list(Config) -> - FileName = ?config(filename, Config), - {Sftp, _} = ?config(sftp, Config), + FileName = proplists:get_value(filename, Config), + {Sftp, _} = proplists:get_value(sftp, Config), Data = list_to_binary(lists:duplicate(750000,"a")), ct:log("Data size to write is ~p bytes",[size(Data)]), - ssh_sftp:write_file(Sftp, FileName, [Data]), + ok = ssh_sftp:write_file(Sftp, FileName, [Data]), {ok, Data} = ssh_sftp:read_file(Sftp, FileName). %%-------------------------------------------------------------------- remove_file() -> [{doc,"Test API function delete/2"}]. remove_file(Config) when is_list(Config) -> - PrivDir = ?config(priv_dir, Config), - FileName = ?config(filename, Config), - {Sftp, _} = ?config(sftp, Config), + PrivDir = proplists:get_value(sftp_priv_dir, Config), + FileName = proplists:get_value(filename, Config), + {Sftp, _} = proplists:get_value(sftp, Config), {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir), true = lists:member(filename:basename(FileName), Files), ok = ssh_sftp:delete(Sftp, FileName), {ok, NewFiles} = ssh_sftp:list_dir(Sftp, PrivDir), false = lists:member(filename:basename(FileName), NewFiles), - {error, _} = ssh_sftp:delete(Sftp, FileName). + {error, no_such_file} = ssh_sftp:delete(Sftp, FileName). %%-------------------------------------------------------------------- rename_file() -> [{doc, "Test API function rename_file/2"}]. rename_file(Config) when is_list(Config) -> - PrivDir = ?config(priv_dir, Config), - FileName = ?config(filename, Config), - NewFileName = ?config(testfile, Config), + PrivDir = proplists:get_value(sftp_priv_dir, Config), + FileName = proplists:get_value(filename, Config), + NewFileName = proplists:get_value(testfile, Config), - {Sftp, _} = ?config(sftp, Config), + {Sftp, _} = proplists:get_value(sftp, Config), {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir), ct:log("FileName: ~p, Files: ~p~n", [FileName, Files]), true = lists:member(filename:basename(FileName), Files), @@ -450,8 +467,8 @@ rename_file(Config) when is_list(Config) -> mk_rm_dir() -> [{doc,"Test API functions make_dir/2, del_dir/2"}]. mk_rm_dir(Config) when is_list(Config) -> - PrivDir = ?config(priv_dir, Config), - {Sftp, _} = ?config(sftp, Config), + PrivDir = proplists:get_value(sftp_priv_dir, Config), + {Sftp, _} = proplists:get_value(sftp, Config), DirName = filename:join(PrivDir, "test"), ok = ssh_sftp:make_dir(Sftp, DirName), @@ -468,9 +485,9 @@ links(Config) when is_list(Config) -> {win32, _} -> {skip, "Links are not fully supported by windows"}; _ -> - {Sftp, _} = ?config(sftp, Config), - FileName = ?config(filename, Config), - LinkFileName = ?config(linktest, Config), + {Sftp, _} = proplists:get_value(sftp, Config), + FileName = proplists:get_value(filename, Config), + LinkFileName = proplists:get_value(linktest, Config), ok = ssh_sftp:make_symlink(Sftp, LinkFileName, FileName), {ok, FileName} = ssh_sftp:read_link(Sftp, LinkFileName) @@ -480,9 +497,9 @@ links(Config) when is_list(Config) -> retrieve_attributes() -> [{doc, "Test API function read_file_info/3"}]. retrieve_attributes(Config) when is_list(Config) -> - FileName = ?config(filename, Config), + FileName = proplists:get_value(filename, Config), - {Sftp, _} = ?config(sftp, Config), + {Sftp, _} = proplists:get_value(sftp, Config), {ok, FileInfo} = ssh_sftp:read_file_info(Sftp, FileName), {ok, NewFileInfo} = file:read_file_info(FileName), @@ -493,24 +510,53 @@ retrieve_attributes(Config) when is_list(Config) -> set_attributes() -> [{doc,"Test API function write_file_info/3"}]. set_attributes(Config) when is_list(Config) -> - FileName = ?config(testfile, Config), + FileName = proplists:get_value(testfile, Config), - {Sftp, _} = ?config(sftp, Config), + {Sftp, _} = proplists:get_value(sftp, Config), {ok,Fd} = file:open(FileName, write), io:put_chars(Fd,"foo"), ok = ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#400}), {error, eacces} = file:write_file(FileName, "hello again"), - ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#600}), + ok = ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#600}), ok = file:write_file(FileName, "hello again"). %%-------------------------------------------------------------------- +file_owner_access() -> + [{doc,"Test file user access validity"}]. +file_owner_access(Config) when is_list(Config) -> + case os:type() of + {win32, _} -> + {skip, "Not a relevant test on Windows"}; + _ -> + FileName = proplists:get_value(filename, Config), + {Sftp, _} = proplists:get_value(sftp, Config), + + {ok, #file_info{mode = InitialMode}} = ssh_sftp:read_file_info(Sftp, FileName), + + ok = ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#000}), + {ok, #file_info{access = none}} = ssh_sftp:read_file_info(Sftp, FileName), + + ok = ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#400}), + {ok, #file_info{access = read}} = ssh_sftp:read_file_info(Sftp, FileName), + + ok = ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#200}), + {ok, #file_info{access = write}} = ssh_sftp:read_file_info(Sftp, FileName), + ok = ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#600}), + {ok, #file_info{access = read_write}} = ssh_sftp:read_file_info(Sftp, FileName), + + ok = ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=InitialMode}), + + ok + end. + +%%-------------------------------------------------------------------- async_read() -> [{doc,"Test API aread/3"}]. async_read(Config) when is_list(Config) -> - {Sftp, _} = ?config(sftp, Config), + {Sftp, _} = proplists:get_value(sftp, Config), - FileName = ?config(filename, Config), + FileName = proplists:get_value(filename, Config), {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]), {async, Ref} = ssh_sftp:aread(Sftp, Handle, 20), @@ -527,8 +573,8 @@ async_read(Config) when is_list(Config) -> async_write() -> [{doc,"Test API awrite/3"}]. async_write(Config) when is_list(Config) -> - {Sftp, _} = ?config(sftp, Config), - FileName = ?config(testfile, Config), + {Sftp, _} = proplists:get_value(sftp, Config), + FileName = proplists:get_value(testfile, Config), {ok, Handle} = ssh_sftp:open(Sftp, FileName, [write]), Data = list_to_binary("foobar"), {async, Ref} = ssh_sftp:awrite(Sftp, Handle, Data), @@ -545,11 +591,11 @@ async_write(Config) when is_list(Config) -> position() -> [{doc, "Test API functions position/3"}]. position(Config) when is_list(Config) -> - FileName = ?config(testfile, Config), - {Sftp, _} = ?config(sftp, Config), + FileName = proplists:get_value(testfile, Config), + {Sftp, _} = proplists:get_value(sftp, Config), Data = list_to_binary("1234567890"), - ssh_sftp:write_file(Sftp, FileName, [Data]), + ok = ssh_sftp:write_file(Sftp, FileName, [Data]), {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]), {ok, 3} = ssh_sftp:position(Sftp, Handle, {bof, 3}), @@ -574,10 +620,10 @@ position(Config) when is_list(Config) -> pos_read() -> [{doc,"Test API functions pread/3 and apread/3"}]. pos_read(Config) when is_list(Config) -> - FileName = ?config(testfile, Config), - {Sftp, _} = ?config(sftp, Config), + FileName = proplists:get_value(testfile, Config), + {Sftp, _} = proplists:get_value(sftp, Config), Data = list_to_binary("Hej hopp!"), - ssh_sftp:write_file(Sftp, FileName, [Data]), + ok = ssh_sftp:write_file(Sftp, FileName, [Data]), {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]), {async, Ref} = ssh_sftp:apread(Sftp, Handle, {bof, 5}, 4), @@ -601,13 +647,13 @@ pos_read(Config) when is_list(Config) -> pos_write() -> [{doc,"Test API functions pwrite/4 and apwrite/4"}]. pos_write(Config) when is_list(Config) -> - FileName = ?config(testfile, Config), - {Sftp, _} = ?config(sftp, Config), + FileName = proplists:get_value(testfile, Config), + {Sftp, _} = proplists:get_value(sftp, Config), {ok, Handle} = ssh_sftp:open(Sftp, FileName, [write]), Data = list_to_binary("Bye,"), - ssh_sftp:write_file(Sftp, FileName, [Data]), + ok = ssh_sftp:write_file(Sftp, FileName, [Data]), NewData = list_to_binary(" see you tomorrow"), {async, Ref} = ssh_sftp:apwrite(Sftp, Handle, {bof, 4}, NewData), @@ -626,12 +672,65 @@ pos_write(Config) when is_list(Config) -> {ok, NewData1} = ssh_sftp:read_file(Sftp, FileName). %%-------------------------------------------------------------------- +start_channel_sock(Config) -> + LoginOpts = + case proplists:get_value(group,Config) of + erlang_server -> + [{user, proplists:get_value(user, Config)}, + {password, proplists:get_value(passwd, Config)}]; + openssh_server -> + [] % Use public key + end, + + Opts = [{user_interaction, false}, + {silently_accept_hosts, true} + | LoginOpts], + + {Host,Port} = proplists:get_value(peer, Config), + + %% Get a tcp socket + {ok, Sock} = ssh_test_lib:gen_tcp_connect(Host, Port, [{active,false}]), + + %% and open one channel on one new Connection + {ok, ChPid1, Conn} = ssh_sftp:start_channel(Sock, Opts), + + %% Test that the channel is usable + FileName = proplists:get_value(filename, Config), + ok = open_close_file(ChPid1, FileName, [read]), + ok = open_close_file(ChPid1, FileName, [write]), + + %% Try to open a second channel on the Connection + {ok, ChPid2} = ssh_sftp:start_channel(Conn, Opts), + ok = open_close_file(ChPid1, FileName, [read]), + ok = open_close_file(ChPid2, FileName, [read]), + + %% Test that the second channel still works after closing the first one + ok = ssh_sftp:stop_channel(ChPid1), + ok = open_close_file(ChPid2, FileName, [write]), + + %% Test the Connection survives that all channels are closed + ok = ssh_sftp:stop_channel(ChPid2), + {ok, ChPid3} = ssh_sftp:start_channel(Conn, Opts), + ok = open_close_file(ChPid3, FileName, [write]), + + %% Test that a closed channel really is closed + {error, closed} = ssh_sftp:open(ChPid2, FileName, [write]), + ok = ssh_sftp:stop_channel(ChPid3), + + %% Test that the socket is closed when the Connection closes + ok = ssh:close(Conn), + timer:sleep(400), %% Until the stop sequence is fixed + {error,einval} = inet:getopts(Sock, [active]), + + ok. + +%%-------------------------------------------------------------------- sftp_nonexistent_subsystem() -> [{doc, "Try to execute sftp subsystem on a server that does not support it"}]. sftp_nonexistent_subsystem(Config) when is_list(Config) -> - {_,Host, Port} = ?config(sftpd, Config), - User = ?config(user, Config), - Passwd = ?config(passwd, Config), + {_,Host, Port} = proplists:get_value(sftpd, Config), + User = proplists:get_value(user, Config), + Passwd = proplists:get_value(passwd, Config), {error,"server failed to start sftp subsystem"} = ssh_sftp:start_channel(Host, Port, [{user_interaction, false}, @@ -647,20 +746,20 @@ version_option(Config) when is_list(Config) -> %%-------------------------------------------------------------------- create_empty_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), - TarFileName = ?config(tar_filename, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]), erl_tar:close(Handle), - {ChPid,_} = ?config(sftp,Config), + {ChPid,_} = proplists:get_value(sftp,Config), {ok, #file_info{type=regular}} = ssh_sftp:read_file_info(ChPid, TarFileName). %%-------------------------------------------------------------------- files_to_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), - TarFileName = ?config(tar_filename, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]), - F1 = ?config(tar_F1_txt, Config), + F1 = proplists:get_value(tar_F1_txt, Config), ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose]), ok = erl_tar:add(Handle, fn("f2.txt",Config), "f2.txt", [verbose]), ok = erl_tar:close(Handle), @@ -668,8 +767,8 @@ files_to_tar(Config) -> %%-------------------------------------------------------------------- ascii_filename_ascii_contents_to_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), - TarFileName = ?config(tar_filename, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]), ok = erl_tar:add(Handle, fn("f2.txt",Config), "f2.txt", [verbose]), ok = erl_tar:close(Handle), @@ -677,12 +776,12 @@ ascii_filename_ascii_contents_to_tar(Config) -> %%-------------------------------------------------------------------- ascii_filename_unicode_contents_to_tar(Config) -> - case ?config(tar_F3_txt, Config) of + case proplists:get_value(tar_F3_txt, Config) of undefined -> {skip, "Unicode test"}; Fn -> - ChPid2 = ?config(channel_pid2, Config), - TarFileName = ?config(tar_filename, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]), ok = erl_tar:add(Handle, fn(Fn,Config), Fn, [verbose]), ok = erl_tar:close(Handle), @@ -691,12 +790,12 @@ ascii_filename_unicode_contents_to_tar(Config) -> %%-------------------------------------------------------------------- unicode_filename_ascii_contents_to_tar(Config) -> - case ?config(tar_F4_txt, Config) of + case proplists:get_value(tar_F4_txt, Config) of undefined -> {skip, "Unicode test"}; Fn -> - ChPid2 = ?config(channel_pid2, Config), - TarFileName = ?config(tar_filename, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]), ok = erl_tar:add(Handle, fn(Fn,Config), Fn, [verbose]), ok = erl_tar:close(Handle), @@ -705,8 +804,8 @@ unicode_filename_ascii_contents_to_tar(Config) -> %%-------------------------------------------------------------------- big_file_to_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), - TarFileName = ?config(tar_filename, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]), ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose]), ok = erl_tar:close(Handle), @@ -715,18 +814,18 @@ big_file_to_tar(Config) -> %%-------------------------------------------------------------------- files_chunked_to_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), - TarFileName = ?config(tar_filename, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]), - F1 = ?config(tar_F1_txt, Config), + F1 = proplists:get_value(tar_F1_txt, Config), ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]), ok = erl_tar:close(Handle), chk_tar([F1], Config). %%-------------------------------------------------------------------- directory_to_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), - TarFileName = ?config(tar_filename, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]), ok = erl_tar:add(Handle, fn("d1",Config), "d1", [verbose]), ok = erl_tar:close(Handle), @@ -734,8 +833,8 @@ directory_to_tar(Config) -> %%-------------------------------------------------------------------- binaries_to_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), - TarFileName = ?config(tar_filename, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]), Bin = <<"A binary">>, ok = erl_tar:add(Handle, Bin, "b1", [verbose]), @@ -744,15 +843,15 @@ binaries_to_tar(Config) -> %%-------------------------------------------------------------------- null_crypto_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), Cinit = fun() -> {ok, no_state, _SendSize=5} end, Cenc = fun(Bin,CState) -> {ok,Bin,CState,_SendSize=5} end, Cend = fun(Bin,_CState) -> {ok,Bin} end, C = {Cinit,Cenc,Cend}, - TarFileName = ?config(tar_filename, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,C}]), Bin = <<"A binary">>, - F1 = ?config(tar_F1_txt, Config), + F1 = proplists:get_value(tar_F1_txt, Config), ok = erl_tar:add(Handle, Bin, "b1", [verbose]), ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]), ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose,{chunks,15000}]), @@ -761,16 +860,16 @@ null_crypto_tar(Config) -> %%-------------------------------------------------------------------- simple_crypto_tar_small(Config) -> - ChPid2 = ?config(channel_pid2, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), Cinit = fun() -> {ok, no_state, _Size=6} end, Cenc = fun(Bin,CState) -> {ok,stuff(Bin),CState,_SendSize=5} end, Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_Size=4} end, Cend = fun(Bin,_CState) -> {ok,stuff(Bin)} end, C = {Cinit,Cenc,Cend}, - TarFileName = ?config(tar_filename, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,C}]), Bin = <<"A binary">>, - F1 = ?config(tar_F1_txt, Config), + F1 = proplists:get_value(tar_F1_txt, Config), ok = erl_tar:add(Handle, Bin, "b1", [verbose]), ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]), ok = erl_tar:close(Handle), @@ -778,16 +877,16 @@ simple_crypto_tar_small(Config) -> %%-------------------------------------------------------------------- simple_crypto_tar_big(Config) -> - ChPid2 = ?config(channel_pid2, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), Cinit = fun() -> {ok, no_state, _SendSize=6} end, Cenc = fun(Bin,CState) -> {ok,stuff(Bin),CState,_SendSize=5} end, Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_SendSize=4} end, Cend = fun(Bin,_CState) -> {ok,stuff(Bin)} end, C = {Cinit,Cenc,Cend}, - TarFileName = ?config(tar_filename, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,C}]), Bin = <<"A binary">>, - F1 = ?config(tar_F1_txt, Config), + F1 = proplists:get_value(tar_F1_txt, Config), ok = erl_tar:add(Handle, Bin, "b1", [verbose]), ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]), ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose,{chunks,15000}]), @@ -800,12 +899,12 @@ unstuff(Bin) -> << <<C>> || <<C,C>> <= Bin >>. %%-------------------------------------------------------------------- read_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), NameBins = lists:sort( [{"b1",<<"A binary">>}, {"b2",list_to_binary(lists:duplicate(750000,"a"))} ]), - TarFileName = ?config(tar_filename, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]), [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins], @@ -815,7 +914,7 @@ read_tar(Config) -> %%-------------------------------------------------------------------- read_null_crypto_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), NameBins = lists:sort( [{"b1",<<"A binary">>}, {"b2",list_to_binary(lists:duplicate(750000,"a"))} @@ -828,7 +927,7 @@ read_null_crypto_tar(Config) -> Cw = {Cinitw,Cenc,Cendw}, Cr = {Cinitr,Cdec}, - TarFileName = ?config(tar_filename, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]), [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins], @@ -838,7 +937,7 @@ read_null_crypto_tar(Config) -> %%-------------------------------------------------------------------- read_crypto_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), NameBins = lists:sort( [{"b1",<<"A binary">>}, {"b2",list_to_binary(lists:duplicate(750000,"a"))} @@ -852,7 +951,7 @@ read_crypto_tar(Config) -> Cw = {Cinitw,Cenc,Cendw}, Cr = {Cinitr,Cdec}, - TarFileName = ?config(tar_filename, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]), [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins], @@ -862,14 +961,14 @@ read_crypto_tar(Config) -> %%-------------------------------------------------------------------- aes_cbc256_crypto_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), NameBins = lists:sort( [{"b1",<<"A binary">>}, {"b2",list_to_binary(lists:duplicate(750000,"a"))}, {"d1",fn("d1",Config)} % Dir ]), Key = <<"This is a 256 bit key. Boring...">>, - Ivec0 = crypto:rand_bytes(16), + Ivec0 = crypto:strong_rand_bytes(16), DataSize = 1024, % data_size rem 16 = 0 for aes_cbc Cinitw = fun() -> {ok, Ivec0, DataSize} end, @@ -892,7 +991,7 @@ aes_cbc256_crypto_tar(Config) -> end, Cw = {Cinitw,Cenc,Cendw}, - TarFileName = ?config(tar_filename, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]), [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins], ok = erl_tar:close(HandleWrite), @@ -907,14 +1006,14 @@ pad(BlockSize, Bin) -> %%-------------------------------------------------------------------- aes_ctr_stream_crypto_tar(Config) -> - ChPid2 = ?config(channel_pid2, Config), + ChPid2 = proplists:get_value(channel_pid2, Config), NameBins = lists:sort( [{"b1",<<"A binary">>}, {"b2",list_to_binary(lists:duplicate(750000,"a"))}, {"d1",fn("d1",Config)} % Dir ]), Key = <<"This is a 256 bit key. Boring...">>, - Ivec0 = crypto:rand_bytes(16), + Ivec0 = crypto:strong_rand_bytes(16), Cinitw = Cinitr = fun() -> {ok, crypto:stream_init(aes_ctr,Key,Ivec0)} end, @@ -935,7 +1034,7 @@ aes_ctr_stream_crypto_tar(Config) -> end, Cw = {Cinitw,Cenc,Cendw}, - TarFileName = ?config(tar_filename, Config), + TarFileName = proplists:get_value(tar_filename, Config), {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]), [ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins], ok = erl_tar:close(HandleWrite), @@ -946,12 +1045,12 @@ aes_ctr_stream_crypto_tar(Config) -> %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- -prep(Config) -> - DataDir = ?config(data_dir, Config), - TestFile = ?config(filename, Config), - TestFile1 = ?config(testfile, Config), - TestLink = ?config(linktest, Config), - TarFileName = ?config(tar_filename, Config), +oldprep(Config) -> + DataDir = proplists:get_value(data_dir, Config), + TestFile = proplists:get_value(filename, Config), + TestFile1 = proplists:get_value(testfile, Config), + TestLink = proplists:get_value(linktest, Config), + TarFileName = proplists:get_value(tar_filename, Config), file:delete(TestFile), file:delete(TestFile1), @@ -966,16 +1065,44 @@ prep(Config) -> ok = file:write_file_info(TestFile, FileInfo#file_info{mode = Mode}). +prepare(Config0) -> + PrivDir = proplists:get_value(priv_dir, Config0), + Dir = filename:join(PrivDir, ssh_test_lib:random_chars(10)), + file:make_dir(Dir), + Keys = [filename, + testfile, + linktest, + tar_filename], + Config1 = foldl_keydelete(Keys, Config0), + Config2 = lists:foldl(fun({Key,Name}, ConfAcc) -> + [{Key, filename:join(Dir,Name)} | ConfAcc] + end, + Config1, + lists:zip(Keys, [proplists:get_value(K,Config0) || K<-Keys])), + + DataDir = proplists:get_value(data_dir, Config2), + FilenameSrc = filename:join(DataDir, "sftp.txt"), + FilenameDst = proplists:get_value(filename, Config2), + {ok,_} = file:copy(FilenameSrc, FilenameDst), + [{sftp_priv_dir,Dir} | Config2]. + + +foldl_keydelete(Keys, L) -> + lists:foldl(fun(K,E) -> lists:keydelete(K,1,E) end, + L, + Keys). + + chk_tar(Items, Config) -> chk_tar(Items, Config, []). chk_tar(Items, Config, Opts) -> - TarFileName = ?config(tar_filename, Config), + TarFileName = proplists:get_value(tar_filename, Config), chk_tar(Items, TarFileName, Config, Opts). chk_tar(Items, TarFileName, Config, Opts) when is_list(Opts) -> tar_size(TarFileName, Config), - {ChPid,_} = ?config(sftp,Config), + {ChPid,_} = proplists:get_value(sftp,Config), {ok,HandleRead} = ssh_sftp:open_tar(ChPid, TarFileName, [read|Opts]), {ok,NameValueList} = erl_tar:extract(HandleRead,[memory,verbose]), ok = erl_tar:close(HandleRead), @@ -1017,7 +1144,7 @@ analyze_report([], []) -> "". tar_size(TarFileName, Config) -> - {ChPid,_} = ?config(sftp,Config), + {ChPid,_} = proplists:get_value(sftp,Config), {ok,Data} = ssh_sftp:read_file(ChPid, TarFileName), io:format('Tar file ~p is~n ~p bytes.~n',[TarFileName, size(Data)]). @@ -1044,7 +1171,7 @@ read_item_contents(ItemName, FileName) -> end. fn(Name, Config) -> - Dir = ?config(datadir_tar, Config), + Dir = proplists:get_value(datadir_tar, Config), filename:join(Dir,Name). fmt_host({A,B,C,D}) -> lists:concat([A,".",B,".",C,".",D]); |