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