aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src/ssh_connection_handler.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh/src/ssh_connection_handler.erl')
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl64
1 files changed, 54 insertions, 10 deletions
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 5b3d1b8a1b..9378686242 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -35,7 +35,8 @@
-export([start_link/4, send/2, renegotiate/1, send_event/2,
connection_info/3,
- peer_address/1]).
+ peer_address/1,
+ renegotiate_data/1]).
%% gen_fsm callbacks
-export([hello/2, kexinit/2, key_exchange/2, new_keys/2,
@@ -85,6 +86,8 @@ send(ConnectionHandler, Data) ->
renegotiate(ConnectionHandler) ->
send_all_state_event(ConnectionHandler, renegotiate).
+renegotiate_data(ConnectionHandler) ->
+ send_all_state_event(ConnectionHandler, data_size).
connection_info(ConnectionHandler, From, Options) ->
send_all_state_event(ConnectionHandler, {info, From, Options}).
@@ -419,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) ->
@@ -500,7 +507,22 @@ handle_event(renegotiate, StateName, State) ->
handle_event({info, From, Options}, StateName, #state{ssh_params = Ssh} = State) ->
spawn(?MODULE, ssh_info_handler, [Options, Ssh, From]),
{next_state, StateName, State};
-
+handle_event(data_size, connected, #state{ssh_params = Ssh0} = State) ->
+ Sent = inet:getstat(State#state.socket, [send_oct]),
+ MaxSent = proplists:get_value(rekey_limit, State#state.opts, 1024000000),
+ case Sent >= MaxSent of
+ true ->
+ {KeyInitMsg, SshPacket, Ssh} = ssh_transport:key_exchange_init_msg(Ssh0),
+ send_msg(SshPacket, State),
+ {next_state, connected,
+ next_packet(State#state{ssh_params = Ssh,
+ key_exchange_init_msg = KeyInitMsg,
+ renegotiate = true})};
+ _ ->
+ {next_state, connected, next_packet(State)}
+ end;
+handle_event(data_size, StateName, State) ->
+ {next_state, StateName, State};
handle_event({unknown, Data}, StateName, State) ->
Msg = #ssh_msg_unimplemented{sequence = Data},
send_msg(Msg, State),
@@ -718,8 +740,18 @@ init_ssh(server = Role, Vsn, Version, Options, Socket) ->
available_host_keys = supported_host_keys(Role, KeyCb, Options)
}.
-supported_host_keys(client, _, _) ->
- ["ssh-rsa", "ssh-dss"];
+supported_host_keys(client, _, Options) ->
+ try
+ case extract_algs(proplists:get_value(pref_public_key_algs, Options, false), []) of
+ false ->
+ ["ssh-rsa", "ssh-dss"];
+ Algs ->
+ Algs
+ end
+ catch
+ exit:Reason ->
+ {stop, {shutdown, Reason}}
+ end;
supported_host_keys(server, KeyCb, Options) ->
lists:foldl(fun(Type, Acc) ->
case available_host_key(KeyCb, Type, Options) of
@@ -731,7 +763,19 @@ supported_host_keys(server, KeyCb, Options) ->
end, [],
%% Prefered alg last so no need to reverse
["ssh-dss", "ssh-rsa"]).
-
+extract_algs(false, _) ->
+ false;
+extract_algs([],[]) ->
+ false;
+extract_algs([], NewList) ->
+ lists:reverse(NewList);
+extract_algs([H|T], NewList) ->
+ case H of
+ 'ssh-dss' ->
+ extract_algs(T, ["ssh-dss"|NewList]);
+ 'ssh-rsa' ->
+ extract_algs(T, ["ssh-rsa"|NewList])
+ end.
available_host_key(KeyCb, "ssh-dss"= Alg, Opts) ->
case KeyCb:host_key('ssh-dss', Opts) of
{ok, _} ->