diff options
Diffstat (limited to 'lib/ssh/src')
-rw-r--r-- | lib/ssh/src/ssh.appup.src | 24 | ||||
-rw-r--r-- | lib/ssh/src/ssh.erl | 35 | ||||
-rw-r--r-- | lib/ssh/src/ssh_connection.erl | 16 | ||||
-rw-r--r-- | lib/ssh/src/ssh_connection_sup.erl | 10 | ||||
-rw-r--r-- | lib/ssh/src/ssh_file.erl | 11 | ||||
-rw-r--r-- | lib/ssh/src/ssh_sftpd_file_api.erl | 62 |
6 files changed, 80 insertions, 78 deletions
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src index 0542054596..d08dbafc32 100644 --- a/lib/ssh/src/ssh.appup.src +++ b/lib/ssh/src/ssh.appup.src @@ -18,12 +18,26 @@ %% {"%VSN%", - [ - {<<"2\\.*">>, [{restart_application, ssh}]}, - {<<"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_channel, soft_purge, soft_purge, []}, + {load_module, ssh_file, soft_purge, soft_purge, []}]}, + {load_module, ssh, soft_purge, soft_purge, []}]}, + {<<"2.0\\.*">>, [{restart_application, ssh}]}, + {<<"1\\.*">>, [{restart_application, ssh}]} ], [ - {<<"2\\.*">>, [{restart_application, ssh}]}, - {<<"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_channel, soft_purge, soft_purge, []}, + {load_module, ssh_file, soft_purge, soft_purge, []}]}, + {load_module, ssh, soft_purge, soft_purge, []}]}, + {<<"2.0\\.*">>, [{restart_application, ssh}]}, + {<<"1\\.*">>, [{restart_application, ssh}]} ] }. diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl index f4a40c81a4..3395f73884 100644 --- a/lib/ssh/src/ssh.erl +++ b/lib/ssh/src/ssh.erl @@ -91,10 +91,8 @@ do_connect(Host, Port, SocketOptions, SshOptions, Timeout, DisableIpv6) -> {ok, ConnectionSup} -> {ok, Manager} = ssh_connection_sup:connection_manager(ConnectionSup), - MRef = erlang:monitor(process, Manager), receive {Manager, is_connected} -> - do_demonitor(MRef, Manager), {ok, Manager}; %% When the connection fails %% ssh_connection_sup:connection_manager @@ -102,30 +100,13 @@ do_connect(Host, Port, SocketOptions, SshOptions, Timeout, DisableIpv6) -> %% could allready have terminated, so we will not %% match the Manager in this case {_, not_connected, {error, econnrefused}} when DisableIpv6 == false -> - do_demonitor(MRef, Manager), do_connect(Host, Port, proplists:delete(inet6, SocketOptions), SshOptions, Timeout, true); {_, not_connected, {error, Reason}} -> - do_demonitor(MRef, Manager), {error, Reason}; {_, not_connected, Other} -> - do_demonitor(MRef, Manager), - {error, Other}; - {'DOWN', MRef, _, Manager, Reason} when is_pid(Manager) -> - error_logger:warning_report([{ssh, connect}, - {diagnose, - "Connection was closed before properly set up."}, - {host, Host}, - {port, Port}, - {reason, Reason}]), - receive %% Clear EXIT message from queue - {'EXIT', Manager, _What} -> - {error, channel_closed} - after 0 -> - {error, channel_closed} - end + {error, Other} after Timeout -> - do_demonitor(MRef, Manager), ssh_connection_manager:stop(Manager), {error, timeout} end @@ -134,16 +115,6 @@ do_connect(Host, Port, SocketOptions, SshOptions, Timeout, DisableIpv6) -> {error, ssh_not_started} end. -do_demonitor(MRef, Manager) -> - erlang:demonitor(MRef), - receive - {'DOWN', MRef, _, Manager, _} -> - ok - after 0 -> - ok - end. - - %%-------------------------------------------------------------------- %% Function: close(ConnectionRef) -> ok %% @@ -369,6 +340,8 @@ handle_option([{shell, _} = Opt | Rest], SocketOptions, SshOptions) -> handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); handle_option([{exec, _} = Opt | Rest], SocketOptions, SshOptions) -> handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); +handle_option([{auth_methods, _} = Opt | Rest], SocketOptions, SshOptions) -> + handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); handle_option([Opt | Rest], SocketOptions, SshOptions) -> handle_option(Rest, [handle_inet_option(Opt) | SocketOptions], SshOptions). @@ -408,6 +381,8 @@ handle_ssh_option({exec, {Module, Function, _}} = Opt) when is_atom(Module), is_atom(Function) -> Opt; +handle_ssh_option({auth_methods, Value} = Opt) when is_list(Value) -> + Opt; handle_ssh_option({infofun, Value} = Opt) when is_function(Value) -> Opt; handle_ssh_option({connectfun, Value} = Opt) when is_function(Value) -> diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl index c46f799b6d..c2a7c63cbe 100644 --- a/lib/ssh/src/ssh_connection.erl +++ b/lib/ssh/src/ssh_connection.erl @@ -436,32 +436,32 @@ handle_msg(#ssh_msg_channel_window_adjust{recipient_channel = ChannelId, #connection{channel_cache = Cache} = Connection, ConnectionPid, _) -> - #channel{send_window_size = Size} = + #channel{send_window_size = Size, remote_id = RemoteId} = Channel0 = ssh_channel:cache_lookup(Cache, ChannelId), - + {SendList, Channel} = %% TODO: Datatype 0 ? update_send_window(Channel0#channel{send_window_size = Size + Add}, 0, <<>>, Connection), Replies = lists:map(fun({Type, Data}) -> {connection_reply, ConnectionPid, - channel_data_msg(ChannelId, Type, Data)} + channel_data_msg(RemoteId, Type, Data)} end, SendList), FlowCtrlMsgs = flow_control(Channel, Cache), {{replies, Replies ++ FlowCtrlMsgs}, Connection}; handle_msg(#ssh_msg_channel_open{channel_type = "session" = Type, - sender_channel = ChannelId, + sender_channel = RemoteId, initial_window_size = WindowSz, maximum_packet_size = PacketSz}, Connection0, ConnectionPid, server) -> - try setup_session(Connection0, ConnectionPid, ChannelId, + try setup_session(Connection0, ConnectionPid, RemoteId, Type, WindowSz, PacketSz) of Result -> Result catch _:_ -> - FailMsg = channel_open_failure_msg(ChannelId, + FailMsg = channel_open_failure_msg(RemoteId, ?SSH_OPEN_CONNECT_FAILED, "Connection refused", "en"), {{replies, [{connection_reply, ConnectionPid, FailMsg}]}, @@ -532,9 +532,9 @@ handle_msg(#ssh_msg_channel_open{channel_type = "forwarded-tcpip", {{replies, [{connection_reply, ConnectionPid, FailMsg}]}, Connection}; -handle_msg(#ssh_msg_channel_open{sender_channel = ChannelId}, Connection, +handle_msg(#ssh_msg_channel_open{sender_channel = RemoteId}, Connection, ConnectionPid, _) -> - FailMsg = channel_open_failure_msg(ChannelId, + FailMsg = channel_open_failure_msg(RemoteId, ?SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, "Not allowed", "en"), {{replies, [{connection_reply, ConnectionPid, FailMsg}]}, Connection}; diff --git a/lib/ssh/src/ssh_connection_sup.erl b/lib/ssh/src/ssh_connection_sup.erl index e3544af1c6..b620056310 100644 --- a/lib/ssh/src/ssh_connection_sup.erl +++ b/lib/ssh/src/ssh_connection_sup.erl @@ -48,8 +48,12 @@ start_manager_child(Sup, Args) -> supervisor:start_child(Sup, Spec). connection_manager(SupPid) -> - Children = supervisor:which_children(SupPid), - {ok, ssh_connection_manager(Children)}. + try supervisor:which_children(SupPid) of + Children -> + {ok, ssh_connection_manager(Children)} + catch exit:{noproc,_} -> + {ok, undefined} + end. %%%========================================================================= %%% Supervisor callback @@ -107,6 +111,8 @@ handler_spec([Role, Socket, Opts]) -> Type = worker, {Name, StartFunc, Restart, Shutdown, Type, Modules}. +ssh_connection_manager([]) -> + undefined; ssh_connection_manager([{_, Child, _, [ssh_connection_manager]} | _]) -> Child; ssh_connection_manager([_ | Rest]) -> diff --git a/lib/ssh/src/ssh_file.erl b/lib/ssh/src/ssh_file.erl index d05fa8e09a..a6b82a7a13 100644 --- a/lib/ssh/src/ssh_file.erl +++ b/lib/ssh/src/ssh_file.erl @@ -232,7 +232,7 @@ lookup_host_key_fd(Fd, Host, KeyType) -> eof -> {error, not_found}; Line -> - case public_key:ssh_decode(Line, known_hosts) of + case ssh_decode_line(Line, known_hosts) of [{Key, Attributes}] -> handle_host(Fd, Host, proplists:get_value(hostnames, Attributes), Key, KeyType); [] -> @@ -240,6 +240,13 @@ lookup_host_key_fd(Fd, Host, KeyType) -> end end. +ssh_decode_line(Line, Type) -> + try + public_key:ssh_decode(Line, Type) + catch _:_ -> + [] + end. + handle_host(Fd, Host, HostList, Key, KeyType) -> Host1 = host_name(Host), case lists:member(Host1, HostList) and key_match(Key, KeyType) of @@ -285,7 +292,7 @@ lookup_user_key_fd(Fd, Key) -> eof -> {error, not_found}; Line -> - case public_key:ssh_decode(Line, auth_keys) of + case ssh_decode_line(Line, auth_keys) of [{AuthKey, _}] -> case is_auth_key(Key, AuthKey) of true -> diff --git a/lib/ssh/src/ssh_sftpd_file_api.erl b/lib/ssh/src/ssh_sftpd_file_api.erl index 38371f809d..83d90907f5 100644 --- a/lib/ssh/src/ssh_sftpd_file_api.erl +++ b/lib/ssh/src/ssh_sftpd_file_api.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2012. 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 @@ -22,40 +22,40 @@ -module(ssh_sftpd_file_api). %% To be further specified later --callback close(IoDevice::term(), State::term()) -> - ok | {error, Reason::term()}. --callback delete(Path::term(), State::term()) -> - ok | {error, Reason::term()}. --callback del_dir(Path::term(), State::term()) -> - ok | {error, Reason::term()}. +-callback close(file:io_device(), State::term()) -> + {ok, State::term()} | {{error, Reason::term()}, State::term()}. +-callback delete(file:name(), State::term()) -> + {ok, State::term()} | {{error, Reason::term()}, State::term()}. +-callback del_dir(file:name(), State::term()) -> + {ok, State::term()} | {{error, Reason::term()}, State::term()}. -callback get_cwd(State::term()) -> - {ok, Dir::term()} | {error, Reason::term()}. --callback is_dir(AbsPath::term(), State::term()) -> - boolean(). --callback list_dir(AbsPath::term(), State::term()) -> - {ok, Filenames::term()} | {error, Reason::term()}. + {{ok, Dir::term()}, State::term()} | {{error, Reason::term()}, State::term()}. +-callback is_dir(file:name(), State::term()) -> + {boolean(), State::term()}. +-callback list_dir(file:name(), State::term()) -> + {{ok, Filenames::term()}, State::term()} | {{error, Reason::term()}, State::term()}. -callback make_dir(Dir::term(), State::term()) -> - ok | {error, Reason::term()}. + {{ok, State::term()},State::term()} | {{error, Reason::term()}, State::term()}. -callback make_symlink(Path2::term(), Path::term(), State::term()) -> - ok | {error, Reason::term()}. + {ok, State::term()} | {{error, Reason::term()}, State::term()}. -callback open(Path::term(), Flags::term(), State::term()) -> - {ok, IoDevice::term()} | {error, Reason::term()}. --callback position(IoDevice::term(), Offs::term(), State::term()) -> - {ok, NewPosition::term()} | {error, Reason::term()}. --callback read(IoDevice::term(), Len::term(), State::term()) -> - {ok, Data::term()} | eof | {error, Reason::term()}. --callback read_link(Path::term(), State::term()) -> - {ok, FileName::term()} | {error, Reason::term()}. --callback read_link_info(Path::term(), State::term()) -> - {ok, FileInfo::term()} | {error, Reason::term()}. --callback read_file_info(Path::term(), State::term()) -> - {ok, FileInfo::term()} | {error, Reason::term()}. --callback rename(Path::term(), Path2::term(), State::term()) -> - ok | {error, Reason::term()}. --callback write(IoDevice::term(), Data::term(), State::term()) -> - ok | {error, Reason::term()}. --callback write_file_info(Path::term(),Info::term(), State::term()) -> - ok | {error, Reason::term()}. + {{ok, IoDevice::term()}, State::term()} | {{error, Reason::term()}, State::term()}. +-callback position(file:io_device(), Offs::term(), State::term()) -> + {{ok, NewPosition::term()}, State::term()} | {{error, Reason::term()}, State::term()}. +-callback read(file:io_device(), Len::term(), State::term()) -> + {{ok, Data::term()},State::term()} | {eof, State::term()} | {{error, Reason::term()}, State::term()}. +-callback read_link(file:name(), State::term()) -> + {{ok, FileName::term()}, State::term()} | {{error, Reason::term()}, State::term()}. +-callback read_link_info(file:name(), State::term()) -> + {{ok, FileInfo::term()}, State::term()} | {{error, Reason::term()}, State::term()}. +-callback read_file_info(file:name(), State::term()) -> + {{ok, FileInfo::term()}, State::term()} | {{error, Reason::term()},State::term()}. +-callback rename(file:name(), file:name(), State::term()) -> + {ok, State::term()} | {{error, Reason::term()}, State::term()}. +-callback write(file:io_device(), Data::term(), State::term()) -> + {ok, State::term()} | {{error, Reason::term()}, State::term()}. +-callback write_file_info(file:name(),Info::term(), State::term()) -> + {ok, State::term()} | {{error, Reason::term()}, State::term()}. |