aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src/ssh_options.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh/src/ssh_options.erl')
-rw-r--r--lib/ssh/src/ssh_options.erl84
1 files changed, 39 insertions, 45 deletions
diff --git a/lib/ssh/src/ssh_options.erl b/lib/ssh/src/ssh_options.erl
index 395be6b220..ee3cdbb8a0 100644
--- a/lib/ssh/src/ssh_options.erl
+++ b/lib/ssh/src/ssh_options.erl
@@ -28,6 +28,7 @@
-export([default/1,
get_value/5, get_value/6,
put_value/5,
+ delete_key/5,
handle_options/2
]).
@@ -37,16 +38,6 @@
%%%================================================================
%%% Types
--type options() :: #{socket_options := socket_options(),
- internal_options := internal_options(),
- option_key() => any()
- }.
-
--type socket_options() :: proplists:proplist().
--type internal_options() :: #{option_key() => any()}.
-
--type option_key() :: atom().
-
-type option_in() :: proplists:property() | proplists:proplist() .
-type option_class() :: internal_options | socket_options | user_options .
@@ -75,22 +66,23 @@ get_value(Class, Key, Opts, _CallerMod, _CallerLine) when is_map(Opts) ->
user_options -> maps:get(Key, Opts)
end;
get_value(Class, Key, Opts, _CallerMod, _CallerLine) ->
- io:format("*** Bad Opts GET OPT ~p ~p:~p Key=~p,~n Opts=~p~n",[Class,_CallerMod,_CallerLine,Key,Opts]),
error({bad_options,Class, Key, Opts, _CallerMod, _CallerLine}).
--spec get_value(option_class(), option_key(), options(), any(),
+-spec get_value(option_class(), option_key(), options(), fun(() -> any()),
atom(), non_neg_integer()) -> any() | no_return().
-get_value(socket_options, Key, Opts, Def, _CallerMod, _CallerLine) when is_map(Opts) ->
- proplists:get_value(Key, maps:get(socket_options,Opts), Def);
-get_value(Class, Key, Opts, Def, CallerMod, CallerLine) when is_map(Opts) ->
+get_value(socket_options, Key, Opts, DefFun, _CallerMod, _CallerLine) when is_map(Opts) ->
+ proplists:get_value(Key, maps:get(socket_options,Opts), DefFun);
+get_value(Class, Key, Opts, DefFun, CallerMod, CallerLine) when is_map(Opts) ->
try get_value(Class, Key, Opts, CallerMod, CallerLine)
+ of
+ undefined -> DefFun();
+ Value -> Value
catch
- error:{badkey,Key} -> Def
+ error:{badkey,Key} -> DefFun()
end;
-get_value(Class, Key, Opts, _Def, _CallerMod, _CallerLine) ->
- io:format("*** Bad Opts GET OPT ~p ~p:~p Key=~p,~n Opts=~p~n",[Class,_CallerMod,_CallerLine,Key,Opts]),
+get_value(Class, Key, Opts, _DefFun, _CallerMod, _CallerLine) ->
error({bad_options,Class, Key, Opts, _CallerMod, _CallerLine}).
@@ -136,6 +128,19 @@ put_socket_value(A, SockOpts) when is_atom(A) ->
%%%================================================================
%%%
+%%% Delete an option
+%%%
+
+-spec delete_key(option_class(), option_key(), options(),
+ atom(), non_neg_integer()) -> options().
+
+delete_key(internal_options, Key, Opts, _CallerMod, _CallerLine) when is_map(Opts) ->
+ InternalOpts = maps:get(internal_options,Opts),
+ Opts#{internal_options := maps:remove(Key, InternalOpts)}.
+
+
+%%%================================================================
+%%%
%%% Initialize the options
%%%
@@ -200,17 +205,6 @@ save({K,V}, _, _) when K == reuseaddr ;
save({allow_user_interaction,V}, Opts, Vals) ->
save({user_interaction,V}, Opts, Vals);
-save({public_key_alg,V}, Defs, Vals) -> % To remove in OTP-20
- New = case V of
- 'ssh-rsa' -> ['ssh-rsa', 'ssh-dss'];
- ssh_rsa -> ['ssh-rsa', 'ssh-dss'];
- 'ssh-dss' -> ['ssh-dss', 'ssh-rsa'];
- ssh_dsa -> ['ssh-dss', 'ssh-rsa'];
- _ -> error({eoptions, {public_key_alg,V},
- "Unknown algorithm, try pref_public_key_algs instead"})
- end,
- save({pref_public_key_algs,New}, Defs, Vals);
-
%% Special case for socket options 'inet' and 'inet6'
save(Inet, Defs, OptMap) when Inet==inet ; Inet==inet6 ->
save({inet,Inet}, Defs, OptMap);
@@ -501,12 +495,6 @@ default(client) ->
class => user_options
},
- {idle_time, def} =>
- #{default => infinity,
- chk => fun check_timeout/1,
- class => user_options
- },
-
%%%%% Undocumented
{keyboard_interact_fun, def} =>
#{default => undefined,
@@ -559,6 +547,12 @@ default(common) ->
class => user_options
},
+ {idle_time, def} =>
+ #{default => infinity,
+ chk => fun check_timeout/1,
+ class => user_options
+ },
+
%% This is a "SocketOption"...
%% {fd, def} =>
%% #{default => undefined,
@@ -803,18 +797,17 @@ read_moduli_file(D, I, Acc) ->
check_silently_accept_hosts(B) when is_boolean(B) -> true;
check_silently_accept_hosts(F) when is_function(F,2) -> true;
-check_silently_accept_hosts({S,F}) when is_atom(S),
- is_function(F,2) ->
- lists:member(S, ?SHAs) andalso
- lists:member(S, proplists:get_value(hashs,crypto:supports()));
-check_silently_accept_hosts({L,F}) when is_list(L),
- is_function(F,2) ->
- lists:all(fun(S) ->
- lists:member(S, ?SHAs) andalso
- lists:member(S, proplists:get_value(hashs,crypto:supports()))
- end, L);
+check_silently_accept_hosts({false,S}) when is_atom(S) -> valid_hash(S);
+check_silently_accept_hosts({S,F}) when is_function(F,2) -> valid_hash(S);
check_silently_accept_hosts(_) -> false.
+
+valid_hash(S) -> valid_hash(S, proplists:get_value(hashs,crypto:supports())).
+
+valid_hash(S, Ss) when is_atom(S) -> lists:member(S, ?SHAs) andalso lists:member(S, Ss);
+valid_hash(L, Ss) when is_list(L) -> lists:all(fun(S) -> valid_hash(S,Ss) end, L);
+valid_hash(X, _) -> error_in_check(X, "Expect atom or list in fingerprint spec").
+
%%%----------------------------------------------------------------
check_preferred_algorithms(Algs) ->
try alg_duplicates(Algs, [], [])
@@ -882,6 +875,7 @@ handle_pref_alg(Key, Vs, _) ->
chk_alg_vs(OptKey, Values, SupportedValues) ->
case (Values -- SupportedValues) of
[] -> Values;
+ [none] -> [none]; % for testing only
Bad -> error_in_check({OptKey,Bad}, "Unsupported value(s) found")
end.