From b3069dbb63bcdba437157911763073cbd62d40eb Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Wed, 21 Jan 2015 15:33:36 +0100 Subject: ssh: Add handling of sftp v3 flags --- lib/ssh/src/ssh_sftpd.erl | 20 ++++++++++++++--- lib/ssh/test/ssh_sftpd_SUITE.erl | 48 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl index 52665635f0..5410bd1925 100644 --- a/lib/ssh/src/ssh_sftpd.erl +++ b/lib/ssh/src/ssh_sftpd.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2013. All Rights Reserved. +%% Copyright Ericsson AB 2005-2015. 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 @@ -558,7 +558,20 @@ stat(ReqId, RelPath, State0=#state{file_handler=FileMod, {error, E} -> send_status({error, E}, ReqId, State1) end. - +%% sftp v3 +decode_4_open_flag(read) -> + [read]; +decode_4_open_flag(write) -> + [write]; +decode_4_open_flag(append) -> + [append]; +decode_4_open_flag(creat) -> + [write]; +decode_4_open_flag(trunc) -> + [write]; +decode_4_open_flag(excl) -> + [read]; +%% sftp newer decode_4_open_flag(create_new) -> [write]; decode_4_open_flag(create_truncate) -> @@ -608,7 +621,8 @@ open(Vsn, ReqId, Data, State) when Vsn =< 3 -> <> = Data, Path = unicode:characters_to_list(BPath), - Flags = ssh_xfer:decode_open_flags(Vsn, PFlags), + FlagBits = ssh_xfer:decode_open_flags(Vsn, PFlags), + Flags = lists:append(lists:umerge([[decode_4_flags(FlagBits)]])), do_open(ReqId, State, Path, Flags); open(Vsn, ReqId, Data, State) when Vsn >= 4 -> < retrieve_attributes, set_attributes, links, - ver3_rename, + ver3_rename, + ver3_open_flags, relpath, sshd_read_file, ver6_basic]. @@ -193,6 +194,39 @@ open_close_file(Config) when is_list(Config) -> ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES, ?SSH_FXF_OPEN_EXISTING). +ver3_open_flags() -> + [{doc, "Test open flags"}]. +ver3_open_flags(Config) when is_list(Config) -> + PrivDir = ?config(priv_dir, Config), + FileName = filename:join(PrivDir, "not_exist.txt"), + {Cm, Channel} = ?config(sftp, Config), + ReqId = 0, + + {ok, <>, _} = + open_file_v3(FileName, Cm, Channel, ReqId, + ?SSH_FXF_CREAT bor ?SSH_FXF_TRUNC), + {ok, <>, _} = close(Handle, ReqId, + Cm, Channel), + + NewFileName = filename:join(PrivDir, "not_exist2.txt"), + NewReqId = ReqId + 1, + {ok, <>, _} = + open_file_v3(NewFileName, Cm, Channel, NewReqId, + ?SSH_FXF_CREAT bor ?SSH_FXF_EXCL), + {ok, <>, _} = close(NewHandle, NewReqId, + Cm, Channel), + + NewFileName1 = filename:join(PrivDir, "test.txt"), + NewReqId1 = NewReqId + 1, + {ok, <>, _} = + open_file_v3(NewFileName1, Cm, Channel, NewReqId1, + ?SSH_FXF_READ bor ?SSH_FXF_WRITE bor ?SSH_FXF_APPEND), + {ok, <>, _} = close(NewHandle1, NewReqId1, + Cm, Channel). + %%-------------------------------------------------------------------- open_close_dir() -> [{doc,"Test SSH_FXP_OPENDIR and SSH_FXP_CLOSE commands"}]. @@ -662,6 +696,16 @@ open_file(File, Cm, Channel, ReqId, Access, Flags) -> ?SSH_FXP_OPEN, Data/binary>>), reply(Cm, Channel). +open_file_v3(File, Cm, Channel, ReqId, Flags) -> + + Data = list_to_binary([?uint32(ReqId), + ?binary(list_to_binary(File)), + ?uint32(Flags), + ?REG_ATTERS]), + Size = 1 + size(Data), + ssh_connection:send(Cm, Channel, <>), + reply(Cm, Channel). close(Handle, ReqId, Cm , Channel) -> -- cgit v1.2.3 From ec6583db02ec4b629c6b6b06119d324daea42225 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Thu, 22 Jan 2015 11:57:14 +0100 Subject: ssh: Correct Sftp flag handling Function name was somewhat confusing and when trying to find a better name for it we realised it did not work as intended. --- lib/ssh/src/ssh_sftpd.erl | 120 +++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 61 deletions(-) (limited to 'lib') diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl index 5410bd1925..a4e3e46ca3 100644 --- a/lib/ssh/src/ssh_sftpd.erl +++ b/lib/ssh/src/ssh_sftpd.erl @@ -558,71 +558,70 @@ stat(ReqId, RelPath, State0=#state{file_handler=FileMod, {error, E} -> send_status({error, E}, ReqId, State1) end. -%% sftp v3 -decode_4_open_flag(read) -> - [read]; -decode_4_open_flag(write) -> - [write]; -decode_4_open_flag(append) -> - [append]; -decode_4_open_flag(creat) -> - [write]; -decode_4_open_flag(trunc) -> - [write]; -decode_4_open_flag(excl) -> - [read]; -%% sftp newer -decode_4_open_flag(create_new) -> - [write]; -decode_4_open_flag(create_truncate) -> - [write]; -decode_4_open_flag(truncate_existing) -> - [write]; -decode_4_open_flag(open_existing) -> - [read]. - -decode_4_flags([OpenFlag | Flags]) -> - decode_4_flags(Flags, decode_4_open_flag(OpenFlag)). - -decode_4_flags([], Flags) -> - Flags; -decode_4_flags([append_data|R], _Flags) -> - decode_4_flags(R, [append]); -decode_4_flags([append_data_atomic|R], _Flags) -> - decode_4_flags(R, [append]); -decode_4_flags([_|R], Flags) -> - decode_4_flags(R, Flags). - -decode_4_access_flag(read_data) -> - [read]; -decode_4_access_flag(list_directory) -> - [read]; -decode_4_access_flag(write_data) -> - [write]; -decode_4_access_flag(add_file) -> - [write]; -decode_4_access_flag(add_subdirectory) -> - [read]; -decode_4_access_flag(append_data) -> - [append]; -decode_4_access_flag(write_attributes) -> - [write]; -decode_4_access_flag(_) -> - [read]. - -decode_4_acess([_ | _] = Flags) -> + +sftp_to_erlang_flag(read, Vsn) when Vsn == 3; + Vsn == 4 -> + read; +sftp_to_erlang_flag(write, Vsn) when Vsn == 3; + Vsn == 4 -> + write; +sftp_to_erlang_flag(append, Vsn) when Vsn == 3; + Vsn == 4 -> + append; +sftp_to_erlang_flag(creat, Vsn) when Vsn == 3; + Vsn == 4 -> + write; +sftp_to_erlang_flag(trunc, Vsn) when Vsn == 3; + Vsn == 4 -> + write; +sftp_to_erlang_flag(excl, Vsn) when Vsn == 3; + Vsn == 4 -> + read; +sftp_to_erlang_flag(append_data, Vsn) when Vsn > 4 -> + append; +sftp_to_erlang_flag(append_data_atomic, Vsn) when Vsn > 4 -> + append; +sftp_to_erlang_flag(create_new, Vsn) when Vsn > 4 -> + write; +sftp_to_erlang_flag(create_truncate, Vsn) when Vsn > 4 -> + write; +sftp_to_erlang_flag(truncate_existing, Vsn) when Vsn > 4 -> + write; +sftp_to_erlang_flag(open_existing, Vsn) when Vsn > 4 -> + read. + +sftp_to_erlang_flags(Flags, Vsn) -> + lists:map(fun(Flag) -> + sftp_to_erlang_flag(Flag, Vsn) + end, Flags). + +sftp_to_erlang_access_flag(read_data, _) -> + read; +sftp_to_erlang_access_flag(list_directory, _) -> + read; +sftp_to_erlang_access_flag(write_data, _) -> + write; +sftp_to_erlang_access_flag(add_file, _) -> + write; +sftp_to_erlang_access_flag(add_subdirectory, _) -> + read; +sftp_to_erlang_access_flag(append_data, _) -> + append; +sftp_to_erlang_access_flag(write_attributes, _) -> + write; +sftp_to_erlang_access_flag(_, _) -> + read. +sftp_to_erlang_access_flags(Flags, Vsn) -> lists:map(fun(Flag) -> - [decode_4_access_flag(Flag)] - end, Flags); -decode_4_acess([]) -> - []. + sftp_to_erlang_access_flag(Flag, Vsn) + end, Flags). open(Vsn, ReqId, Data, State) when Vsn =< 3 -> <> = Data, Path = unicode:characters_to_list(BPath), FlagBits = ssh_xfer:decode_open_flags(Vsn, PFlags), - Flags = lists:append(lists:umerge([[decode_4_flags(FlagBits)]])), + Flags = lists:usort(sftp_to_erlang_flags(FlagBits, Vsn)), do_open(ReqId, State, Path, Flags); open(Vsn, ReqId, Data, State) when Vsn >= 4 -> <= 4 -> %% it works better than when the Access flags where totally ignored. %% A better solution may need some code refactoring that we do %% not have time for right now. - AcessFlags = decode_4_acess(AcessBits), - Flags = lists:append(lists:umerge( - [[decode_4_flags(FlagBits)] | AcessFlags])), + AcessFlags = sftp_to_erlang_access_flags(AcessBits, Vsn), + Flags = lists:usort(sftp_to_erlang_flags(FlagBits, Vsn) ++ AcessFlags), do_open(ReqId, State, Path, Flags). do_open(ReqId, State0, Path, Flags) -> -- cgit v1.2.3 From 5c1a83668b14ef4288adaf181140f7f325ca407f Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Fri, 23 Jan 2015 09:41:05 +0100 Subject: ssh: Add some more flags --- lib/ssh/src/ssh_sftpd.erl | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl index a4e3e46ca3..04ae6b11e2 100644 --- a/lib/ssh/src/ssh_sftpd.erl +++ b/lib/ssh/src/ssh_sftpd.erl @@ -577,17 +577,21 @@ sftp_to_erlang_flag(trunc, Vsn) when Vsn == 3; sftp_to_erlang_flag(excl, Vsn) when Vsn == 3; Vsn == 4 -> read; -sftp_to_erlang_flag(append_data, Vsn) when Vsn > 4 -> - append; -sftp_to_erlang_flag(append_data_atomic, Vsn) when Vsn > 4 -> - append; sftp_to_erlang_flag(create_new, Vsn) when Vsn > 4 -> write; sftp_to_erlang_flag(create_truncate, Vsn) when Vsn > 4 -> write; +sftp_to_erlang_flag(open_existing, Vsn) when Vsn > 4 -> + read; +sftp_to_erlang_flag(open_or_create, Vsn) when Vsn > 4 -> + write; sftp_to_erlang_flag(truncate_existing, Vsn) when Vsn > 4 -> write; -sftp_to_erlang_flag(open_existing, Vsn) when Vsn > 4 -> +sftp_to_erlang_flag(append_data, Vsn) when Vsn > 4 -> + append; +sftp_to_erlang_flag(append_data_atomic, Vsn) when Vsn > 4 -> + append; +sftp_to_erlang_flag(_, _) -> read. sftp_to_erlang_flags(Flags, Vsn) -> @@ -601,12 +605,12 @@ sftp_to_erlang_access_flag(list_directory, _) -> read; sftp_to_erlang_access_flag(write_data, _) -> write; -sftp_to_erlang_access_flag(add_file, _) -> - write; -sftp_to_erlang_access_flag(add_subdirectory, _) -> - read; sftp_to_erlang_access_flag(append_data, _) -> append; +sftp_to_erlang_access_flag(add_subdirectory, _) -> + read; +sftp_to_erlang_access_flag(add_file, _) -> + write; sftp_to_erlang_access_flag(write_attributes, _) -> write; sftp_to_erlang_access_flag(_, _) -> @@ -629,12 +633,10 @@ open(Vsn, ReqId, Data, State) when Vsn >= 4 -> Path = unicode:characters_to_list(BPath), FlagBits = ssh_xfer:decode_open_flags(Vsn, PFlags), AcessBits = ssh_xfer:decode_ace_mask(Access), - %% TODO: This is to make sure the Access flags are not ignored - %% but this should be thought through better. This solution should - %% be considered a hack in order to buy some time. At least - %% it works better than when the Access flags where totally ignored. - %% A better solution may need some code refactoring that we do - %% not have time for right now. + %% TODO: There are still flags that are not + %% fully handled as SSH_FXF_ACCESS_TEXT_MODE and + %% a lot a ACE flags, the later we may not need + %% to understand as they are NFS flags AcessFlags = sftp_to_erlang_access_flags(AcessBits, Vsn), Flags = lists:usort(sftp_to_erlang_flags(FlagBits, Vsn) ++ AcessFlags), do_open(ReqId, State, Path, Flags). -- cgit v1.2.3