aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh/src')
-rw-r--r--lib/ssh/src/Makefile4
-rw-r--r--lib/ssh/src/ssh.appup.src24
-rw-r--r--lib/ssh/src/ssh.erl48
-rw-r--r--lib/ssh/src/ssh_client_key_api.erl2
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl14
-rw-r--r--lib/ssh/src/ssh_sftpd.erl77
-rw-r--r--lib/ssh/src/ssh_xfer.erl5
-rw-r--r--lib/ssh/src/ssh_xfer.hrl12
8 files changed, 80 insertions, 106 deletions
diff --git a/lib/ssh/src/Makefile b/lib/ssh/src/Makefile
index 323f0af191..27e43a88ed 100644
--- a/lib/ssh/src/Makefile
+++ b/lib/ssh/src/Makefile
@@ -120,10 +120,10 @@ clean:
rm -f errs core *~
$(APP_TARGET): $(APP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- sed -e 's;%VSN%;$(VSN);' $< > $@
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
docs:
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index 6ba32e018f..cbd8166bb9 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -19,29 +19,17 @@
{"%VSN%",
[
- {<<"2.1.1">>, [{restart_application, ssh}]},
- {<<"2.1">>, [{load_module, ssh_sftpd_file_api, soft_purge, soft_purge, []},
- {load_module, ssh_connection, soft_purge, soft_purge, []},
- {load_module, ssh_connection_manager, soft_purge, soft_purge, []},
- {load_module, ssh_auth, soft_purge, soft_purge, []},
- {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
- {load_module, ssh_channel, soft_purge, soft_purge, []},
- {load_module, ssh_file, soft_purge, soft_purge, []}]},
- {load_module, ssh, soft_purge, soft_purge, []}]},
+ {<<"2.1.2">>, [{restart_application, ssh}]},
+ {<<"2.1.1">>, [{restart_application, ssh}]},
+ {<<"2.1">>, [{restart_application, ssh}]},
{<<"2.0\\.*">>, [{restart_application, ssh}]},
{<<"1\\.*">>, [{restart_application, ssh}]}
],
[
+ {<<"2.1.2">>, [{restart_application, ssh}]},
{<<"2.1.1">>, [{restart_application, ssh}]},
- {<<"2.1">>,[{load_module, ssh_sftpd_file_api, soft_purge, soft_purge, []},
- {load_module, ssh_connection, soft_purge, soft_purge, []},
- {load_module, ssh_connection_manager, soft_purge, soft_purge, []},
- {load_module, ssh_auth, soft_purge, soft_purge, []},
- {load_module, ssh_connection_handler, soft_purge, soft_purge, []},
- {load_module, ssh_channel, soft_purge, soft_purge, []},
- {load_module, ssh_file, soft_purge, soft_purge, []}]},
- {load_module, ssh, soft_purge, soft_purge, []}]},
+ {<<"2.1">>,[{restart_application, ssh}]},
{<<"2.0\\.*">>, [{restart_application, ssh}]},
{<<"1\\.*">>, [{restart_application, ssh}]}
]
-}. \ No newline at end of file
+}.
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 3ef26b1678..193f877b98 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -31,11 +31,6 @@
stop_listener/1, stop_listener/2, stop_daemon/1, stop_daemon/2,
shell/1, shell/2, shell/3]).
--deprecated({sign_data, 2, next_major_release}).
--deprecated({verify_data, 3, next_major_release}).
-
--export([sign_data/2, verify_data/3]).
-
%%--------------------------------------------------------------------
%% Function: start([, Type]) -> ok
%%
@@ -278,7 +273,9 @@ do_start_daemon(Host, Port, Options, SocketOptions) ->
{ok, SysSup} ->
{ok, SysSup};
{error, {already_started, _}} ->
- {error, eaddrinuse}
+ {error, eaddrinuse};
+ {error, R} ->
+ {error, R}
catch
exit:{noproc, _} ->
{error, ssh_not_started}
@@ -392,8 +389,8 @@ handle_ssh_option({public_key_alg, Value} = Opt) when Value == 'ssh-rsa'; Value
Opt;
handle_ssh_option({pref_public_key_algs, Value} = Opt) when is_list(Value), length(Value) >= 1 ->
case handle_pref_algs(Value, []) of
- true ->
- Opt;
+ {true, NewOpts} ->
+ NewOpts;
_ ->
throw({error, {eoptions, Opt}})
end;
@@ -501,38 +498,3 @@ inetopt(false) ->
%%%
%% Deprecated
%%%
-
-%%--------------------------------------------------------------------
-%% Function: sign_data(Data, Algorithm) -> binary() |
-%% {error, Reason}
-%%
-%% Data = binary()
-%% Algorithm = "ssh-rsa"
-%%
-%% Description: Use SSH key to sign data.
-%%--------------------------------------------------------------------
-sign_data(Data, Algorithm) when is_binary(Data) ->
- case ssh_file:user_key(Algorithm,[]) of
- {ok, Key} when Algorithm == "ssh-rsa" ->
- public_key:sign(Data, sha, Key);
- Error ->
- Error
- end.
-
-%%--------------------------------------------------------------------
-%% Function: verify_data(Data, Signature, Algorithm) -> ok |
-%% {error, Reason}
-%%
-%% Data = binary()
-%% Signature = binary()
-%% Algorithm = "ssh-rsa"
-%%
-%% Description: Use SSH signature to verify data.
-%%--------------------------------------------------------------------
-verify_data(Data, Signature, Algorithm) when is_binary(Data), is_binary(Signature) ->
- case ssh_file:user_key(Algorithm, []) of
- {ok, #'RSAPrivateKey'{publicExponent = E, modulus = N}} when Algorithm == "ssh-rsa" ->
- public_key:verify(Data, sha, Signature, #'RSAPublicKey'{publicExponent = E, modulus = N});
- Error ->
- Error
- end.
diff --git a/lib/ssh/src/ssh_client_key_api.erl b/lib/ssh/src/ssh_client_key_api.erl
index eed0b85f47..58054a9fc5 100644
--- a/lib/ssh/src/ssh_client_key_api.erl
+++ b/lib/ssh/src/ssh_client_key_api.erl
@@ -26,7 +26,7 @@
Algorithm :: 'ssh-rsa'| 'ssh-dss'| atom(), ConnectOptions :: proplists:proplist()) ->
boolean().
--callback user_key(Algorithm :: 'ssh-rsa'| 'ssh-dss'| atom(), ConnectOptions :: proplists:proplists()) ->
+-callback user_key(Algorithm :: 'ssh-rsa'| 'ssh-dss'| atom(), ConnectOptions :: proplists:proplist()) ->
{ok, PrivateKey :: #'RSAPrivateKey'{}| #'DSAPrivateKey'{} | term()} | {error, string()}.
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 88b45111ff..9378686242 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -422,11 +422,15 @@ userauth(#ssh_msg_userauth_failure{authentications = Methodes},
#state{ssh_params = #ssh{role = client,
userauth_methods = none} = Ssh0} = State) ->
AuthMethods = string:tokens(Methodes, ","),
- {Msg, Ssh} = ssh_auth:userauth_request_msg(
- Ssh0#ssh{userauth_methods = AuthMethods}),
- send_msg(Msg, State),
- {next_state, userauth, next_packet(State#state{ssh_params = Ssh})};
-
+ Ssh1 = Ssh0#ssh{userauth_methods = AuthMethods},
+ case ssh_auth:userauth_request_msg(Ssh1) of
+ {disconnect, DisconnectMsg, {Msg, Ssh}} ->
+ send_msg(Msg, State),
+ handle_disconnect(DisconnectMsg, State#state{ssh_params = Ssh});
+ {Msg, Ssh} ->
+ send_msg(Msg, State),
+ {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
+ end;
%% The prefered authentication method failed try next method
userauth(#ssh_msg_userauth_failure{},
#state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index 6d6f4a0121..c7e8373840 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -119,9 +119,7 @@ init(Options) ->
{Root0, State0}
end,
MaxLength = proplists:get_value(max_files, Options, 0),
-
- Vsn = proplists:get_value(vsn, Options, 5),
-
+ Vsn = proplists:get_value(sftpd_vsn, Options, 5),
{ok, State#state{cwd = CWD, root = Root, max_files = MaxLength,
handles = [], pending = <<>>,
xf = #ssh_xfer{vsn = Vsn, ext = []}}}.
@@ -361,17 +359,21 @@ handle_op(?SSH_FXP_FSETSTAT, ReqId, <<?UINT32(HLen), BinHandle:HLen/binary,
State0
end;
handle_op(?SSH_FXP_REMOVE, ReqId, <<?UINT32(PLen), BPath:PLen/binary>>,
- State0 = #state{file_handler = FileMod, file_state = FS0}) ->
+ State0 = #state{file_handler = FileMod, file_state = FS0, xf = #ssh_xfer{vsn = Vsn}}) ->
Path = relate_file_name(BPath, State0),
- %% case FileMod:is_dir(Path) of %% This version 6 we still have ver 5
- %% true ->
- %% ssh_xfer:xf_send_status(State#state.xf, ReqId,
- %% ?SSH_FX_FILE_IS_A_DIRECTORY);
- %% false ->
- {Status, FS1} = FileMod:delete(Path, FS0),
- State1 = State0#state{file_state = FS1},
- send_status(Status, ReqId, State1);
- %%end;
+ {IsDir, _FS1} = FileMod:is_dir(Path, FS0),
+ case IsDir of %% This version 6 we still have ver 5
+ true when Vsn > 5 ->
+ ssh_xfer:xf_send_status(State0#state.xf, ReqId,
+ ?SSH_FX_FILE_IS_A_DIRECTORY, "File is a directory");
+ true ->
+ ssh_xfer:xf_send_status(State0#state.xf, ReqId,
+ ?SSH_FX_FAILURE, "File is a directory");
+ false ->
+ {Status, FS1} = FileMod:delete(Path, FS0),
+ State1 = State0#state{file_state = FS1},
+ send_status(Status, ReqId, State1)
+ end;
handle_op(?SSH_FXP_RMDIR, ReqId, <<?UINT32(PLen), BPath:PLen/binary>>,
State0 = #state{file_handler = FileMod, file_state = FS0}) ->
Path = relate_file_name(BPath, State0),
@@ -629,31 +631,34 @@ open(Vsn, ReqId, Data, State) when Vsn >= 4 ->
do_open(ReqId, State, Path, Flags).
do_open(ReqId, State0, Path, Flags) ->
- #state{file_handler = FileMod, file_state = FS0, root = Root} = State0,
+ #state{file_handler = FileMod, file_state = FS0, root = Root, xf = #ssh_xfer{vsn = Vsn}} = State0,
XF = State0#state.xf,
F = [binary | Flags],
- %% case FileMod:is_dir(Path) of %% This is version 6 we still have 5
- %% true ->
- %% ssh_xfer:xf_send_status(State#state.xf, ReqId,
- %% ?SSH_FX_FILE_IS_A_DIRECTORY);
- %% false ->
-
- AbsPath = case Root of
- "" ->
- Path;
- _ ->
- relate_file_name(Path, State0)
- end,
-
- {Res, FS1} = FileMod:open(AbsPath, F, FS0),
- State1 = State0#state{file_state = FS1},
- case Res of
- {ok, IoDevice} ->
- add_handle(State1, XF, ReqId, file, {Path,IoDevice});
- {error, Error} ->
- ssh_xfer:xf_send_status(State1#state.xf, ReqId,
- ssh_xfer:encode_erlang_status(Error)),
- State1
+ {IsDir, _FS1} = FileMod:is_dir(Path, FS0),
+ case IsDir of
+ true when Vsn > 5 ->
+ ssh_xfer:xf_send_status(State0#state.xf, ReqId,
+ ?SSH_FX_FILE_IS_A_DIRECTORY, "File is a directory");
+ true ->
+ ssh_xfer:xf_send_status(State0#state.xf, ReqId,
+ ?SSH_FX_FAILURE, "File is a directory");
+ false ->
+ AbsPath = case Root of
+ "" ->
+ Path;
+ _ ->
+ relate_file_name(Path, State0)
+ end,
+ {Res, FS1} = FileMod:open(AbsPath, F, FS0),
+ State1 = State0#state{file_state = FS1},
+ case Res of
+ {ok, IoDevice} ->
+ add_handle(State1, XF, ReqId, file, {Path,IoDevice});
+ {error, Error} ->
+ ssh_xfer:xf_send_status(State1#state.xf, ReqId,
+ ssh_xfer:encode_erlang_status(Error)),
+ State1
+ end
end.
%% resolve all symlinks in a path
diff --git a/lib/ssh/src/ssh_xfer.erl b/lib/ssh/src/ssh_xfer.erl
index d5b6dd03d1..4dfd9ed8b0 100644
--- a/lib/ssh/src/ssh_xfer.erl
+++ b/lib/ssh/src/ssh_xfer.erl
@@ -383,6 +383,8 @@ decode_status(Status) ->
?SSH_FX_UNKNOWN_PRINCIPLE -> unknown_principle;
?SSH_FX_LOCK_CONFlICT -> lock_conflict;
?SSH_FX_NOT_A_DIRECTORY -> not_a_directory;
+ ?SSH_FX_FILE_IS_A_DIRECTORY -> file_is_a_directory;
+ ?SSH_FX_CANNOT_DELETE -> cannot_delete;
_ -> {error,Status}
end.
@@ -392,6 +394,9 @@ encode_erlang_status(Status) ->
eof -> ?SSH_FX_EOF;
enoent -> ?SSH_FX_NO_SUCH_FILE;
eacces -> ?SSH_FX_PERMISSION_DENIED;
+ eisdir -> ?SSH_FX_FILE_IS_A_DIRECTORY;
+ eperm -> ?SSH_FX_CANNOT_DELETE;
+ eexist -> ?SSH_FX_FILE_ALREADY_EXISTS;
_ -> ?SSH_FX_FAILURE
end.
diff --git a/lib/ssh/src/ssh_xfer.hrl b/lib/ssh/src/ssh_xfer.hrl
index c13950eb6e..0d85cf2094 100644
--- a/lib/ssh/src/ssh_xfer.hrl
+++ b/lib/ssh/src/ssh_xfer.hrl
@@ -58,7 +58,6 @@
%%% # SSH_FX_xxx
%%% Description: Response packet types for file transfer protocol.
%%%----------------------------------------------------------------------
-
-define(SSH_FX_OK, 0).
-define(SSH_FX_EOF, 1).
-define(SSH_FX_NO_SUCH_FILE, 2).
@@ -79,7 +78,18 @@
-define(SSH_FX_LOCK_CONFlICT, 17).
-define(SSH_FX_DIR_NOT_EMPTY, 18).
-define(SSH_FX_NOT_A_DIRECTORY, 19).
+-define(SSH_FX_INVALID_FILENAME, 20).
+-define(SSH_FX_LINK_LOOP, 21).
+-define(SSH_FX_CANNOT_DELETE, 22).
+-define(SSH_FX_INVALID_PARAMETER, 23).
-define(SSH_FX_FILE_IS_A_DIRECTORY, 24).
+-define(SSH_FX_BYTE_RANGE_LOCK_CONFLICT,25).
+-define(SSH_FX_BYTE_RANGE_LOCK_REFUSED, 26).
+-define(SSH_FX_DELETE_PENDING, 27).
+-define(SSH_FX_FILE_CORRUPT, 28).
+-define(SSH_FX_OWNER_INVALID, 29).
+-define(SSH_FX_GROUP_INVALID, 30).
+-define(SSH_FX_NO_MATCHING_BYTE_RANGE_LOCK,31).
%%%----------------------------------------------------------------------
%%% # SSH_FILEXFER_xxx