[erlang-questions] SFTP

Karolis Petrauskas <>
Wed Feb 1 15:06:16 CET 2017


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/20170201/ef84a045/attachment.html>


More information about the erlang-questions mailing list