From 3f671b2da7634f2f5c53c6622abb0eb6bf9938fb Mon Sep 17 00:00:00 2001
From: Fredrik Gustafsson
Date: Wed, 21 Nov 2012 16:07:27 +0100
Subject: Renegotiating every hour and every gb sent, can be decreased with
option {rekey_limit, integer()}
---
lib/ssh/src/ssh.erl | 4 ++++
lib/ssh/src/ssh_connection_handler.erl | 22 ++++++++++++++++++++--
lib/ssh/src/ssh_connection_manager.erl | 22 ++++++++++++++++++----
3 files changed, 42 insertions(+), 6 deletions(-)
(limited to 'lib')
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 719c97e940..de52913194 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -364,6 +364,8 @@ handle_option([{quiet_mode, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{idle_time, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{rekey_limit, _} = 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).
@@ -440,6 +442,8 @@ handle_ssh_option({quiet_mode, Value} = Opt) when Value == true;
Opt;
handle_ssh_option({idle_time, Value} = Opt) when is_integer(Value), Value > 0 ->
Opt;
+handle_ssh_option({rekey_limit, Value} = Opt) when is_integer(Value) ->
+ Opt;
handle_ssh_option(Opt) ->
throw({error, {eoptions, Opt}}).
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index d8950a7b67..e429d3e835 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}).
@@ -500,7 +503,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),
diff --git a/lib/ssh/src/ssh_connection_manager.erl b/lib/ssh/src/ssh_connection_manager.erl
index 0c1eee5186..94a9ed505f 100644
--- a/lib/ssh/src/ssh_connection_manager.erl
+++ b/lib/ssh/src/ssh_connection_manager.erl
@@ -125,7 +125,8 @@ info(ConnectionManager, ChannelProcess) ->
%% or amount of data sent counter!
renegotiate(ConnectionManager) ->
cast(ConnectionManager, renegotiate).
-
+renegotiate_data(ConnectionManager) ->
+ cast(ConnectionManager, renegotiate_data).
connection_info(ConnectionManager, Options) ->
call(ConnectionManager, {connection_info, Options}).
@@ -481,7 +482,9 @@ handle_cast({global_request, _, _, _, _} = Request, State0) ->
handle_cast(renegotiate, #state{connection = Pid} = State) ->
ssh_connection_handler:renegotiate(Pid),
{noreply, State};
-
+handle_cast(renegotiate_data, #state{connection = Pid} = State) ->
+ ssh_connection_handler:renegotiate_data(Pid),
+ {noreply, State};
handle_cast({adjust_window, ChannelId, Bytes},
#state{connection = Pid, connection_state =
#connection{channel_cache = Cache}} = State) ->
@@ -520,6 +523,8 @@ handle_info({start_connection, server,
Exec = proplists:get_value(exec, Options),
CliSpec = proplists:get_value(ssh_cli, Options, {ssh_cli, [Shell]}),
ssh_connection_handler:send_event(Connection, socket_control),
+ erlang:send_after(3600000, self(), rekey),
+ erlang:send_after(60000, self(), rekey_data),
{noreply, State#state{connection = Connection,
connection_state =
CState#connection{address = Address,
@@ -536,6 +541,8 @@ handle_info({start_connection, client,
case (catch ssh_transport:connect(Parent, Address,
Port, SocketOpts, Options)) of
{ok, Connection} ->
+ erlang:send_after(60000, self(), rekey_data),
+ erlang:send_after(3600000, self(), rekey),
{noreply, State#state{connection = Connection}};
Reason ->
Pid ! {self(), not_connected, Reason},
@@ -568,8 +575,15 @@ handle_info({'DOWN', _Ref, process, ChannelPid, _Reason}, State) ->
%%% So that terminate will be run when supervisor is shutdown
handle_info({'EXIT', _Sup, Reason}, State) ->
- {stop, Reason, State}.
-
+ {stop, Reason, State};
+handle_info(rekey, State) ->
+ renegotiate(self()),
+ erlang:send_after(3600000, self(), rekey),
+ {noreply, State};
+handle_info(rekey_data, State) ->
+ renegotiate_data(self()),
+ erlang:send_after(60000, self(), rekey_data),
+ {noreply, State}.
handle_password(Opts) ->
handle_rsa_password(handle_dsa_password(handle_normal_password(Opts))).
handle_normal_password(Opts) ->
--
cgit v1.2.3
From e02e94b034c6407aadcbac42846c9b2e1a54d49e Mon Sep 17 00:00:00 2001
From: Fredrik Gustafsson
Date: Thu, 22 Nov 2012 11:01:08 +0100
Subject: Added doc for rekey_limit option
---
lib/ssh/doc/src/ssh.xml | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
(limited to 'lib')
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index aac4b462a2..fb68a13648 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -193,10 +193,13 @@
(simply passed on to the transport protocol).
-
-
Determines if SSH shall use IPv6 or not.
-
+ Determines if SSH shall use IPv6 or not.
+
+
-
-
Sets a timeout on connection when no channels are active, default is infinity
+ Provide, in bytes, when rekeying should be initiated,
+ defaults to one time each GB and one time per hour.
+
--
cgit v1.2.3
From fadf861ed01ea4c54ceeb4b83830389ee7dc7b93 Mon Sep 17 00:00:00 2001
From: Fredrik Gustafsson
Date: Fri, 23 Nov 2012 14:58:02 +0100
Subject: Added test for rekeying
---
lib/ssh/test/ssh_basic_SUITE.erl | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
(limited to 'lib')
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index 5fec7f0cd7..16f759f974 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -43,14 +43,15 @@ all() ->
{group, rsa_pass_key},
{group, internal_error},
{group, idle_time},
+ {group, rekey},
daemon_already_started,
server_password_option,
server_userpassword_option,
close].
groups() ->
- [{dsa_key, [], [send, exec, exec_compressed, shell, known_hosts, idle_time]},
- {rsa_key, [], [send, exec, exec_compressed, shell, known_hosts, idle_time]},
+ [{dsa_key, [], [send, exec, exec_compressed, shell, known_hosts, idle_time, rekey]},
+ {rsa_key, [], [send, exec, exec_compressed, shell, known_hosts, idle_time, rekey]},
{dsa_pass_key, [], [pass_phrase]},
{rsa_pass_key, [], [pass_phrase]},
{internal_error, [], [internal_error]}
@@ -256,6 +257,28 @@ idle_time(Config) ->
end,
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
+rekey(doc) ->
+ ["Idle timeout test"];
+rekey(Config) ->
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {rekey_limit, 0}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {rekey_limit, 0}]),
+ receive
+ after 15000 ->
+ %%By this time rekeying would have been done
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid)
+ end.
+%%--------------------------------------------------------------------
shell(doc) ->
["Test that ssh:shell/2 works"];
shell(Config) when is_list(Config) ->
--
cgit v1.2.3
From 26dffbeec17226a25c00d4072cb0f5c29ed48cea Mon Sep 17 00:00:00 2001
From: Fredrik Gustafsson
Date: Fri, 30 Nov 2012 10:05:57 +0100
Subject: Modifications to idle_time testcase
---
lib/ssh/test/ssh_basic_SUITE.erl | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'lib')
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index 5fec7f0cd7..0b62c46ff9 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -42,7 +42,6 @@ all() ->
{group, dsa_pass_key},
{group, rsa_pass_key},
{group, internal_error},
- {group, idle_time},
daemon_already_started,
server_password_option,
server_userpassword_option,
@@ -247,7 +246,8 @@ idle_time(Config) ->
ConnectionRef =
ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
{user_dir, UserDir},
- {user_interaction, false}]),
+ {user_interaction, false},
+ {idle_time, 2000}]),
{ok, Id} = ssh_connection:session_channel(ConnectionRef, 1000),
ssh_connection:close(ConnectionRef, Id),
receive
--
cgit v1.2.3
From f78daeeccbf6de61b9e5dae4dd70f12fba03a2ff Mon Sep 17 00:00:00 2001
From: Fredrik Gustafsson
Date: Fri, 30 Nov 2012 10:13:44 +0100
Subject: ssh_basic_SUITE rekey test modifications
---
lib/ssh/test/ssh_basic_SUITE.erl | 1 -
1 file changed, 1 deletion(-)
(limited to 'lib')
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index 16f759f974..e1949daba2 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -43,7 +43,6 @@ all() ->
{group, rsa_pass_key},
{group, internal_error},
{group, idle_time},
- {group, rekey},
daemon_already_started,
server_password_option,
server_userpassword_option,
--
cgit v1.2.3