[erlang-questions] SFTP

Karolis Petrauskas <>
Tue Feb 7 12:23:15 CET 2017


I created a pull request for the ssh application:
https://github.com/erlang/otp/pull/1331
It includes a test case and a fix for opening a file by a relative path.

Karolis


On Wed, Feb 1, 2017 at 4:06 PM, Karolis Petrauskas <>
wrote:

> In ssh_sftpd.erl (ssh application, version 4.4) there is condition for
> determining absolute file path when opening a file:
>
>             AbsPath = case Root of
>                           "" ->
>                               Path;
>                           _ ->
>                               relate_file_name(Path, State0)
>                       end,
>
> There is no such condition when listing directory or resolving real path.
> Root = "" by default, if root_dir is not specified by the user.
>
> Is this difference in resolving file names intended?
>
> Karolis
>
>
> On Wed, Feb 1, 2017 at 1:40 PM, Karolis Petrauskas <
> > wrote:
>
>> Hi,
>>
>> I made a smaller test program to reproduce the problem (shown bellow).
>> It reproduces the problem only partially, because it can't find the files
>> in
>> the Erlang sftp server by relative file names all the time. In my previous
>> experiments I the misbehaviour was unstable.
>>
>> -module(test_sftp).
>> -export([test/1]).
>>
>> make_files(DirName) ->
>>     lists:foreach(
>>         fun (FileName) -> ok = file:write_file(filename:join(DirName,
>> FileName), [FileName, " contents"]) end,
>>         ["some.txt", "other.txt", "none.txt", "yetanother.txt", "any.txt"]
>>     ),
>>     ok.
>>
>> start_server(Port, Cwd) ->
>>     {ok, Pid} = ssh:daemon(Port, [
>>         {system_dir, "test_sftp_data/sys"},
>>         {user_dir,   "test_sftp_data/usr"},
>>         {user_passwords, [{"test_sftp", "test_sftp"}]},
>>         {subsystems, [ssh_sftpd:subsystem_spec([{cwd, Cwd}])]}
>>     ]),
>>     {ok, Pid}.
>>
>> check_client(Port, User, Pass, DirName) ->
>>     {ok, ChannelPid, ConnectionRef} = ssh_sftp:start_channel("localhost",
>> Port, [{user, User}, {password, Pass}]),
>>     {ok, FileNames} = ssh_sftp:list_dir(ChannelPid, DirName),
>>     Result = lists:map(fun (FileName) ->
>>         {DirName, FileName, ssh_sftp:read_file(ChannelPid,
>> filename:join(DirName, FileName))}
>>     end, FileNames),
>>     ok = ssh_sftp:stop_channel(ChannelPid),
>>     ok = ssh:close(ConnectionRef),
>>     Result.
>>
>> test(Pass) ->
>>     ok = make_files("/home/karolis/temp/test_sftp"),
>>     {ok, Pid} = start_server(8022, "/home/karolis"),
>>     lists:foreach(fun (N) ->
>>         io:format("--------------- Test n=~p ---------------------~n",
>> [N]),
>>         io:format("Erlang-ABS: ~100p~n",  [check_client(8022,
>> "test_sftp", "test_sftp", "/home/karolis/temp/test_sftp")]),
>>         io:format("Erlang-REL: ~100p~n",  [check_client(8022,
>> "test_sftp", "test_sftp", "temp/test_sftp")]),
>>         io:format("OpenSSH-ABS: ~100p~n", [check_client(22,   "karolis",
>>   Pass,        "/home/karolis/temp/test_sftp")]),
>>         io:format("OpenSSH-REL: ~100p~n", [check_client(22,   "karolis",
>>   Pass,        "temp/test_sftp")])
>>     end, lists:seq(1, 10)),
>>     ok = ssh:stop_daemon(Pid),
>>     ok.
>>
>>
>> All the iterations printed the same results (only the output of the first
>> iteration is shown bellow):
>>
>> --------------- Test n=1 ---------------------
>> Erlang-ABS: [{"/home/karolis/temp/test_sftp","none.txt",{ok,<<"none.txt
>> contents">>}},
>>              {"/home/karolis/temp/test_sftp","any.txt",{ok,<<"any.txt
>> contents">>}},
>>              {"/home/karolis/temp/test_sftp","other.txt",{ok,<<"other.txt
>> contents">>}},
>>              {"/home/karolis/temp/test_sftp","yetanother.txt",{ok,<<"yetanother.txt
>> contents">>}},
>>              {"/home/karolis/temp/test_sftp","some.txt",{ok,<<"some.txt
>> contents">>}}]
>>
>>
>>
>>
>> *Erlang-REL: [{"temp/test_sftp","none.txt",{error,no_such_file}},
>>      {"temp/test_sftp","any.txt",{error,no_such_file}},
>>  {"temp/test_sftp","other.txt",{error,no_such_file}},
>>  {"temp/test_sftp","yetanother.txt",{error,no_such_file}},
>>  {"temp/test_sftp","some.txt",{error,no_such_file}}]*
>> OpenSSH-ABS: [{"/home/karolis/temp/test_sftp","..",{error,failure}},
>>               {"/home/karolis/temp/test_sftp","none.txt",{ok,<<"none.txt
>> contents">>}},
>>               {"/home/karolis/temp/test_sftp","any.txt",{ok,<<"any.txt
>> contents">>}},
>>               {"/home/karolis/temp/test_sftp","other.txt",{ok,<<"other.txt
>> contents">>}},
>>               {"/home/karolis/temp/test_sftp
>> ","yetanother.txt",{ok,<<"yetanother.txt contents">>}},
>>               {"/home/karolis/temp/test_sftp","some.txt",{ok,<<"some.txt
>> contents">>}},
>>               {"/home/karolis/temp/test_sftp",".",{error,failure}}]
>> OpenSSH-REL: [{"temp/test_sftp","..",{error,failure}},
>>               {"temp/test_sftp","none.txt",{ok,<<"none.txt contents">>}},
>>               {"temp/test_sftp","any.txt",{ok,<<"any.txt contents">>}},
>>               {"temp/test_sftp","other.txt",{ok,<<"other.txt
>> contents">>}},
>>               {"temp/test_sftp","yetanother.txt",{ok,<<"yetanother.txt
>> contents">>}},
>>               {"temp/test_sftp","some.txt",{ok,<<"some.txt contents">>}},
>>               {"temp/test_sftp",".",{error,failure}}]
>>
>>
>> I repeated the same test with the home dir (relative path = "."), and the
>> results were the same.
>> So it seems that the Erlang's sftp server can list directories, but can't
>> open the files by relative paths.
>>
>> Karolis
>>
>> On Mon, Jan 30, 2017 at 10:19 PM, Karolis Petrauskas <
>> > wrote:
>>
>>> I'm using "Erlang/OTP 19 [erts-8.2]", debian package from
>>> erlang-solutions, version 1:19.2-1.
>>>
>>> I'll check that with erlang client and sshd server. I was playing with
>>> ssh_sftpd server from a command line (sftp), and noticed no problems
>>> except the cwd problem when combined with root directory restriction.
>>>
>>> Karolis
>>>
>>> On Mon, Jan 30, 2017 at 8:01 PM, bengt <> wrote:
>>> > Greetings,
>>> >
>>> > Can you try with sshd, instead of ssh_sftpd ? As a way of halving the
>>> potential error sources. Also, which Erlang version are you on?
>>> >
>>> >
>>> > bengt
>>> >
>>> >> On 30 Jan 2017, at 13:55, Karolis Petrauskas <>
>>> wrote:
>>> >>
>>> >> Hello,
>>> >>
>>> >> I'm trying to use erlang's sftp server and client. In the example
>>> >> bellow, i use erlang for both: the server and the client. For some
>>> >> reason, i can't open some files.
>>> >>
>>> >>    43> ssh_sftp:list_dir(Ch, ".").
>>> >>    {ok,["other.txt","some.txt"]}
>>> >>
>>> >>    44> ssh_sftp:read_file(Ch, "some.txt").
>>> >>    {ok,<<"some.txt contents">>}
>>> >>
>>> >>    45> ssh_sftp:read_file(Ch, "other.txt").
>>> >>    {error,no_such_file}
>>> >>
>>> >> I was able to read both files with absolute file names specified, but
>>> >> in my case I should not depend on the absolute paths. I could use the
>>> >> absolute file names when opening files, if I could get the current
>>> >> working directory from the server, but I cant find any function for
>>> >> that.
>>> >>
>>> >> The server behaviour is also a unclear to me. I can't set the cwd, if
>>> >> the root option is used when starting the daemon. I have tried various
>>> >> combinations of root/cwd (cwd is relative to root, or absolute on the
>>> >> target file system), the sftp client always logins with / as its
>>> >> current working directory.
>>> >>
>>> >> In my case, I use the sftpd only for testing the sftp client in CT.
>>> >> I'm working on Erlang/OTP 19 [erts-8.2].
>>> >>
>>> >> Would be thankful for any pointers.
>>> >>
>>> >> Karolis
>>> >> _______________________________________________
>>> >> erlang-questions mailing list
>>> >> 
>>> >> http://erlang.org/mailman/listinfo/erlang-questions
>>> >
>>> > _______________________________________________
>>> > erlang-questions mailing list
>>> > 
>>> > http://erlang.org/mailman/listinfo/erlang-questions
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170207/07ba18d2/attachment.html>


More information about the erlang-questions mailing list