aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh/src')
-rw-r--r--lib/ssh/src/ssh.erl3
-rw-r--r--lib/ssh/src/ssh.hrl2
-rw-r--r--lib/ssh/src/ssh_cli.erl17
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl46
-rw-r--r--lib/ssh/src/ssh_options.erl2
5 files changed, 50 insertions, 20 deletions
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 032d87bdad..25d537c624 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -184,7 +184,6 @@ channel_info(ConnectionRef, ChannelId, Options) ->
daemon(Port) ->
daemon(Port, []).
-
daemon(Socket, UserOptions) when is_port(Socket) ->
try
#{} = Options = ssh_options:handle_options(server, UserOptions),
@@ -267,8 +266,6 @@ daemon(Host0, Port0, UserOptions0) when 0 =< Port0, Port0 =< 65535,
daemon(_, _, _) ->
{error, badarg}.
-
-
%%--------------------------------------------------------------------
-spec daemon_info(daemon_ref()) -> ok_error( [{atom(), term()}] ).
diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl
index 3dee1c5521..4711f54fb5 100644
--- a/lib/ssh/src/ssh.hrl
+++ b/lib/ssh/src/ssh.hrl
@@ -35,6 +35,8 @@
-define(DEFAULT_TRANSPORT, {tcp, gen_tcp, tcp_closed} ).
+-define(DEFAULT_SHELL, {shell, start, []} ).
+
-define(MAX_RND_PADDING_LEN, 15).
-define(SUPPORTED_AUTH_METHODS, "publickey,keyboard-interactive,password").
diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl
index 62854346b0..958c342f5f 100644
--- a/lib/ssh/src/ssh_cli.erl
+++ b/lib/ssh/src/ssh_cli.erl
@@ -127,7 +127,8 @@ handle_ssh_msg({ssh_cm, ConnectionHandler,
cm = ConnectionHandler}};
handle_ssh_msg({ssh_cm, ConnectionHandler,
- {exec, ChannelId, WantReply, Cmd}}, #state{exec=undefined} = State) ->
+ {exec, ChannelId, WantReply, Cmd}}, #state{exec=undefined,
+ shell=?DEFAULT_SHELL} = State) ->
{Reply, Status} = exec(Cmd),
write_chars(ConnectionHandler,
ChannelId, io_lib:format("~p\n", [Reply])),
@@ -136,6 +137,15 @@ handle_ssh_msg({ssh_cm, ConnectionHandler,
ssh_connection:exit_status(ConnectionHandler, ChannelId, Status),
ssh_connection:send_eof(ConnectionHandler, ChannelId),
{stop, ChannelId, State#state{channel = ChannelId, cm = ConnectionHandler}};
+
+handle_ssh_msg({ssh_cm, ConnectionHandler,
+ {exec, ChannelId, WantReply, _Cmd}}, #state{exec = undefined} = State) ->
+ write_chars(ConnectionHandler, ChannelId, 1, "Prohibited.\n"),
+ ssh_connection:reply_request(ConnectionHandler, WantReply, success, ChannelId),
+ ssh_connection:exit_status(ConnectionHandler, ChannelId, 255),
+ ssh_connection:send_eof(ConnectionHandler, ChannelId),
+ {stop, ChannelId, State#state{channel = ChannelId, cm = ConnectionHandler}};
+
handle_ssh_msg({ssh_cm, ConnectionHandler,
{exec, ChannelId, WantReply, Cmd}}, State) ->
NewState = start_shell(ConnectionHandler, Cmd, State),
@@ -453,11 +463,14 @@ move_cursor(From, To, #ssh_pty{width=Width, term=Type}) ->
%% %%% make sure that there is data to send
%% %%% before calling ssh_connection:send
write_chars(ConnectionHandler, ChannelId, Chars) ->
+ write_chars(ConnectionHandler, ChannelId, ?SSH_EXTENDED_DATA_DEFAULT, Chars).
+
+write_chars(ConnectionHandler, ChannelId, Type, Chars) ->
case has_chars(Chars) of
false -> ok;
true -> ssh_connection:send(ConnectionHandler,
ChannelId,
- ?SSH_EXTENDED_DATA_DEFAULT,
+ Type,
Chars)
end.
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index c8ac3a9c04..e11d3adee4 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1174,17 +1174,25 @@ handle_event({call,_}, _, StateName, _) when not ?CONNECTED(StateName) ->
handle_event({call,From}, {request, ChannelPid, ChannelId, Type, Data, Timeout}, StateName, D0)
when ?CONNECTED(StateName) ->
- D = handle_request(ChannelPid, ChannelId, Type, Data, true, From, D0),
- %% Note reply to channel will happen later when reply is recived from peer on the socket
- start_channel_request_timer(ChannelId, From, Timeout),
- {keep_state, cache_request_idle_timer_check(D)};
+ case handle_request(ChannelPid, ChannelId, Type, Data, true, From, D0) of
+ {error,Error} ->
+ {keep_state, D0, {reply,From,{error,Error}}};
+ D ->
+ %% Note reply to channel will happen later when reply is recived from peer on the socket
+ start_channel_request_timer(ChannelId, From, Timeout),
+ {keep_state, cache_request_idle_timer_check(D)}
+ end;
handle_event({call,From}, {request, ChannelId, Type, Data, Timeout}, StateName, D0)
when ?CONNECTED(StateName) ->
- D = handle_request(ChannelId, Type, Data, true, From, D0),
- %% Note reply to channel will happen later when reply is recived from peer on the socket
- start_channel_request_timer(ChannelId, From, Timeout),
- {keep_state, cache_request_idle_timer_check(D)};
+ case handle_request(ChannelId, Type, Data, true, From, D0) of
+ {error,Error} ->
+ {keep_state, D0, {reply,From,{error,Error}}};
+ D ->
+ %% Note reply to channel will happen later when reply is recived from peer on the socket
+ start_channel_request_timer(ChannelId, From, Timeout),
+ {keep_state, cache_request_idle_timer_check(D)}
+ end;
handle_event({call,From}, {data, ChannelId, Type, Data, Timeout}, StateName, D0)
when ?CONNECTED(StateName) ->
@@ -1773,21 +1781,31 @@ is_usable_user_pubkey(A, Ssh) ->
%%%----------------------------------------------------------------
handle_request(ChannelPid, ChannelId, Type, Data, WantReply, From, D) ->
case ssh_channel:cache_lookup(cache(D), ChannelId) of
- #channel{remote_id = Id} = Channel ->
+ #channel{remote_id = Id,
+ sent_close = false} = Channel ->
update_sys(cache(D), Channel, Type, ChannelPid),
send_msg(ssh_connection:channel_request_msg(Id, Type, WantReply, Data),
add_request(WantReply, ChannelId, From, D));
- undefined ->
- D
+
+ _ when WantReply==true ->
+ {error,closed};
+
+ _ ->
+ D
end.
handle_request(ChannelId, Type, Data, WantReply, From, D) ->
case ssh_channel:cache_lookup(cache(D), ChannelId) of
- #channel{remote_id = Id} ->
+ #channel{remote_id = Id,
+ sent_close = false} ->
send_msg(ssh_connection:channel_request_msg(Id, Type, WantReply, Data),
add_request(WantReply, ChannelId, From, D));
- undefined ->
- D
+
+ _ when WantReply==true ->
+ {error,closed};
+
+ _ ->
+ D
end.
%%%----------------------------------------------------------------
diff --git a/lib/ssh/src/ssh_options.erl b/lib/ssh/src/ssh_options.erl
index cf1534bd78..1e10f72956 100644
--- a/lib/ssh/src/ssh_options.erl
+++ b/lib/ssh/src/ssh_options.erl
@@ -268,7 +268,7 @@ default(server) ->
},
{shell, def} =>
- #{default => {shell, start, []},
+ #{default => ?DEFAULT_SHELL,
chk => fun({M,F,A}) -> is_atom(M) andalso is_atom(F) andalso is_list(A);
(V) -> check_function1(V) orelse check_function2(V)
end,