aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2018-05-03 13:48:39 +0200
committerHans Nilsson <[email protected]>2018-05-04 13:27:36 +0200
commit79e3c477f8d0d8ea397820847c576e0a0aaa5323 (patch)
treedb37dab735633c1c7c2b2ee5154e5e89eaa7b0d3 /lib/ssh/src
parenta8ede33f9a51c1566ccb38df0056c3e1f092b970 (diff)
downloadotp-79e3c477f8d0d8ea397820847c576e0a0aaa5323.tar.gz
otp-79e3c477f8d0d8ea397820847c576e0a0aaa5323.tar.bz2
otp-79e3c477f8d0d8ea397820847c576e0a0aaa5323.zip
ssh: Extend rekey_limit to also take an optional time
Diffstat (limited to 'lib/ssh/src')
-rw-r--r--lib/ssh/src/ssh.hrl5
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl17
-rw-r--r--lib/ssh/src/ssh_options.erl16
3 files changed, 26 insertions, 12 deletions
diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl
index a3d9a1b1cb..fc0a3786ac 100644
--- a/lib/ssh/src/ssh.hrl
+++ b/lib/ssh/src/ssh.hrl
@@ -29,7 +29,6 @@
-define(SSH_DEFAULT_PORT, 22).
-define(SSH_MAX_PACKET_SIZE, (256*1024)).
--define(REKEY_TIMOUT, 3600000).
-define(REKEY_DATA_TIMOUT, 60000).
-define(DEFAULT_PROFILE, default).
@@ -192,7 +191,9 @@
-type user_dir_common_option() :: {user_dir, false | string()}.
-type profile_common_option() :: {profile, atom() }.
-type max_idle_time_common_option() :: {idle_time, timeout()}.
--type rekey_limit_common_option() :: {rekey_limit, non_neg_integer() }.
+-type rekey_limit_common_option() :: {rekey_limit, Bytes::non_neg_integer() |
+ {Minutes::non_neg_integer(), Bytes::non_neg_integer()}
+ }.
-type key_cb_common_option() :: {key_cb, Module::atom() | {Module::atom(),Opts::[term()]} } .
-type disconnectfun_common_option() ::
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 57641cf74c..b21c0337ad 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -429,9 +429,6 @@ init([Role,Socket,Opts]) ->
},
D = case Role of
client ->
- %% Start the renegotiation timers
- timer:apply_after(?REKEY_TIMOUT, gen_statem, cast, [self(), renegotiate]),
- timer:apply_after(?REKEY_DATA_TIMOUT, gen_statem, cast, [self(), data_size]),
cache_init_idle_timer(D0);
server ->
Sups = ?GET_INTERNAL_OPT(supervisors, Opts),
@@ -444,6 +441,10 @@ init([Role,Socket,Opts]) ->
connection_supervisor = proplists:get_value(connection_sup, Sups)
}})
end,
+ %% Start the renegotiation timers
+ {RekeyTimeout,_MaxSent} = ?GET_OPT(rekey_limit, (D#data.ssh_params)#ssh.opts),
+ timer:apply_after(RekeyTimeout, gen_statem, cast, [self(), renegotiate]),
+ timer:apply_after(?REKEY_DATA_TIMOUT, gen_statem, cast, [self(), data_size]),
{ok, {hello,Role}, D};
{error,Error} ->
@@ -1066,7 +1067,8 @@ handle_event(internal, Msg=#ssh_msg_channel_failure{}, StateName, D) -
handle_event(cast, renegotiate, {connected,Role}, D) ->
{KeyInitMsg, SshPacket, Ssh} = ssh_transport:key_exchange_init_msg(D#data.ssh_params),
send_bytes(SshPacket, D),
- timer:apply_after(?REKEY_TIMOUT, gen_statem, cast, [self(), renegotiate]),
+ {RekeyTimeout,_MaxSent} = ?GET_OPT(rekey_limit, Ssh#ssh.opts),
+ timer:apply_after(RekeyTimeout, gen_statem, cast, [self(), renegotiate]),
{next_state, {kexinit,Role,renegotiate}, D#data{ssh_params = Ssh,
key_exchange_init_msg = KeyInitMsg}};
@@ -1074,9 +1076,10 @@ handle_event({call,From}, get_alg, _, D) ->
#ssh{algorithms=Algs} = D#data.ssh_params,
{keep_state_and_data, [{reply,From,Algs}]};
-handle_event(cast, renegotiate, _, _) ->
+handle_event(cast, renegotiate, _, D) ->
%% Already in key-exchange so safe to ignore
- timer:apply_after(?REKEY_TIMOUT, gen_statem, cast, [self(), renegotiate]), % FIXME: not here in original
+ {RekeyTimeout,_MaxSent} = ?GET_OPT(rekey_limit, (D#data.ssh_params)#ssh.opts),
+ timer:apply_after(RekeyTimeout, gen_statem, cast, [self(), renegotiate]),
keep_state_and_data;
@@ -1084,7 +1087,7 @@ handle_event(cast, renegotiate, _, _) ->
handle_event(cast, data_size, {connected,Role}, D) ->
{ok, [{send_oct,Sent0}]} = inet:getstat(D#data.socket, [send_oct]),
Sent = Sent0 - D#data.last_size_rekey,
- MaxSent = ?GET_OPT(rekey_limit, (D#data.ssh_params)#ssh.opts),
+ {_RekeyTimeout,MaxSent} = ?GET_OPT(rekey_limit, (D#data.ssh_params)#ssh.opts),
timer:apply_after(?REKEY_DATA_TIMOUT, gen_statem, cast, [self(), data_size]),
case Sent >= MaxSent of
true ->
diff --git a/lib/ssh/src/ssh_options.erl b/lib/ssh/src/ssh_options.erl
index 4dd9082250..73287e464a 100644
--- a/lib/ssh/src/ssh_options.erl
+++ b/lib/ssh/src/ssh_options.erl
@@ -599,9 +599,19 @@ default(common) ->
class => user_options
},
- {rekey_limit, def} => % FIXME: Why not common?
- #{default => 1024000000,
- chk => fun check_non_neg_integer/1,
+ {rekey_limit, def} =>
+ #{default => {3600000, 1024000000}, % {1 hour, 1 GB}
+ chk => fun({TimeMins, SizBytes}) when is_integer(TimeMins) andalso TimeMins>=0,
+ is_integer(SizBytes) andalso SizBytes>=0 ->
+ %% New (>= 21) format
+ {true, {TimeMins * 60*1000, % To ms
+ SizBytes}};
+ (SizBytes) when is_integer(SizBytes) andalso SizBytes>=0 ->
+ %% Old (< 21) format
+ {true, {3600000, SizBytes}};
+ (_) ->
+ false
+ end,
class => user_options
},