summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Nilsson <hans@erlang.org>2020-06-16 11:45:27 +0200
committerHans Nilsson <hans@erlang.org>2020-06-16 11:45:27 +0200
commitaa8131beb68d1c59f43385b51a98ddf2cf716301 (patch)
tree4dd4732529d967a5f47cd4af01aa003ec40533ca
parent8dc293bb5a7e0d12e681422c5d672c8554441e0c (diff)
parentca05d05684a93884c80c1b67da1908009fc801fc (diff)
downloaderlang-aa8131beb68d1c59f43385b51a98ddf2cf716301.tar.gz
Merge branch 'hans/ssh/inc_test_coverage/OTP-14106' into maint
* hans/ssh/inc_test_coverage/OTP-14106: ssh: Minor shell option coverage fix ssh: Make encode_pty_opts/decode_pty_opts testable ssh: Better coverage of dbg of authentication ssh: Better coverage of ssh_options ssh: Reneg dbg cover improvments ssh: Increase coverage on ssh_dbg code ssh: Make version handling more efficient ssh: Exclude some more modules from coverage ssh: Two new cover specs
-rw-r--r--lib/ssh/src/ssh_auth.erl10
-rw-r--r--lib/ssh/src/ssh_client_channel.erl6
-rw-r--r--lib/ssh/src/ssh_connection.erl3
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl41
-rw-r--r--lib/ssh/src/ssh_dbg.erl73
-rw-r--r--lib/ssh/src/ssh_options.erl77
-rw-r--r--lib/ssh/src/ssh_transport.erl23
-rw-r--r--lib/ssh/test/ssh.cover20
-rw-r--r--lib/ssh/test/ssh_all.cover1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl8
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE.erl149
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_dsa12
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_dsa.pub1
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa3846
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa5217
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_ed255197
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_ed25519.pub1
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_ed44810
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_ed448.pub1
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_rsa27
-rw-r--r--lib/ssh/test/ssh_dbg_SUITE_data/id_rsa.pub1
-rw-r--r--lib/ssh/test/ssh_limited.cover22
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE.erl5
27 files changed, 372 insertions, 147 deletions
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl
index 19df20c9f1..943e824de8 100644
--- a/lib/ssh/src/ssh_auth.erl
+++ b/lib/ssh/src/ssh_auth.erl
@@ -693,6 +693,16 @@ ssh_dbg_format(authentication, {return_from, {?MODULE,handle_userauth_request,3}
fmt_req(Req, Ssh)],
Stack};
+ssh_dbg_format(authentication, {return_from, {?MODULE,handle_userauth_request,3},
+ {not_authorized,{User,_X},
+ {#ssh_msg_userauth_info_request{},_Ssh}}},
+ [{#ssh_msg_userauth_request{method="keyboard-interactive"
+ } = Req,Ssh}|Stack]) ->
+ {["AUTH srvr: Ask peer client for password\n",
+ io_lib:format("user = ~p~n", [User]),
+ fmt_req(Req, Ssh)],
+ Stack};
+
ssh_dbg_format(authentication, {call, {?MODULE,ssh_msg_userauth_result,[success]}},
Stack) ->
diff --git a/lib/ssh/src/ssh_client_channel.erl b/lib/ssh/src/ssh_client_channel.erl
index 5ffdf49e9b..bb16d878fa 100644
--- a/lib/ssh/src/ssh_client_channel.erl
+++ b/lib/ssh/src/ssh_client_channel.erl
@@ -436,7 +436,7 @@ ssh_dbg_format(channel_events, {call, {?MODULE,handle_call, [Call,From,State]}})
];
ssh_dbg_format(channel_events, {return_from, {?MODULE,handle_call,3}, Ret}) ->
["Server Channel call returned:\n",
- io_lib:format("~p~n", [ssh_dbg:reduce_state(Ret)])
+ io_lib:format("~p~n", [ssh_dbg:reduce_state(Ret,#state{})])
];
ssh_dbg_format(channel_events, {call, {?MODULE,handle_cast, [Cast,State]}}) ->
@@ -445,7 +445,7 @@ ssh_dbg_format(channel_events, {call, {?MODULE,handle_cast, [Cast,State]}}) ->
];
ssh_dbg_format(channel_events, {return_from, {?MODULE,handle_cast,2}, Ret}) ->
["Server Channel cast returned:\n",
- io_lib:format("~p~n", [ssh_dbg:reduce_state(Ret)])
+ io_lib:format("~p~n", [ssh_dbg:reduce_state(Ret,#state{})])
];
ssh_dbg_format(channel_events, {call, {?MODULE,handle_info, [Info,State]}}) ->
@@ -454,7 +454,7 @@ ssh_dbg_format(channel_events, {call, {?MODULE,handle_info, [Info,State]}}) ->
];
ssh_dbg_format(channel_events, {return_from, {?MODULE,handle_info,2}, Ret}) ->
["Server Channel info returned:\n",
- io_lib:format("~p~n", [ssh_dbg:reduce_state(Ret)])
+ io_lib:format("~p~n", [ssh_dbg:reduce_state(Ret,#state{})])
].
hdr(Title, S) ->
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl
index 07b5fd3854..9b9d66aaa8 100644
--- a/lib/ssh/src/ssh_connection.erl
+++ b/lib/ssh/src/ssh_connection.erl
@@ -66,6 +66,9 @@
encode_ip/1
]).
+%% For testing only
+-export([encode_pty_opts/1, decode_pty_opts/1]).
+
-type connection_ref() :: ssh:connection_ref().
-type channel_id() :: ssh:channel_id().
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 5e5ed9b79a..48f07584ca 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -414,7 +414,8 @@ alg(ConnectionHandler) ->
| undefined,
auth_user :: string()
| undefined,
- connection_state :: #connection{},
+ connection_state :: #connection{}
+ | undefined,
latest_channel_id = 0 :: non_neg_integer()
| undefined,
transport_protocol :: atom()
@@ -2567,7 +2568,7 @@ ssh_dbg_format(connection_events, {call, {?MODULE,handle_event, [EventType, Even
];
ssh_dbg_format(connection_events, {return_from, {?MODULE,handle_event,4}, Ret}) ->
["Connection event result\n",
- io_lib:format("~p~n", [event_handler_result(Ret)])
+ io_lib:format("~p~n", [ssh_dbg:reduce_state(Ret, #data{})])
];
ssh_dbg_format(renegotiation, {call, {?MODULE,init_renegotiate_timers,[OldState,NewState,D]}}) ->
@@ -2659,39 +2660,3 @@ ssh_dbg_format(disconnect, {call,{?MODULE,send_disconnect,
ssh_dbg_format(renegotiation, {return_from, {?MODULE,send_disconnect,7}, _Ret}) ->
skip.
-
-event_handler_result({next_state, NextState, _NewData}) ->
- {next_state, NextState, "#data{}"};
-event_handler_result({next_state, NextState, _NewData, Actions}) ->
- {next_state, NextState, "#data{}", Actions};
-event_handler_result(R) ->
- state_callback_result(R).
-
-state_callback_result({keep_state, _NewData}) ->
- {keep_state, "#data{}"};
-state_callback_result({keep_state, _NewData, Actions}) ->
- {keep_state, "#data{}", Actions};
-state_callback_result(keep_state_and_data) ->
- keep_state_and_data;
-state_callback_result({keep_state_and_data, Actions}) ->
- {keep_state_and_data, Actions};
-state_callback_result({repeat_state, _NewData}) ->
- {repeat_state, "#data{}"};
-state_callback_result({repeat_state, _NewData, Actions}) ->
- {repeat_state, "#data{}", Actions};
-state_callback_result(repeat_state_and_data) ->
- repeat_state_and_data;
-state_callback_result({repeat_state_and_data, Actions}) ->
- {repeat_state_and_data, Actions};
-state_callback_result(stop) ->
- stop;
-state_callback_result({stop, Reason}) ->
- {stop, Reason};
-state_callback_result({stop, Reason, _NewData}) ->
- {stop, Reason, "#data{}"};
-state_callback_result({stop_and_reply, Reason, Replies}) ->
- {stop_and_reply, Reason, Replies};
-state_callback_result({stop_and_reply, Reason, Replies, _NewData}) ->
- {stop_and_reply, Reason, Replies, "#data{}"};
-state_callback_result(R) ->
- R.
diff --git a/lib/ssh/src/ssh_dbg.erl b/lib/ssh/src/ssh_dbg.erl
index f8391224f8..f8750dc070 100644
--- a/lib/ssh/src/ssh_dbg.erl
+++ b/lib/ssh/src/ssh_dbg.erl
@@ -67,7 +67,7 @@
]).
-export([shrink_bin/1,
- reduce_state/1,
+ reduce_state/2, reduce_state/3,
wr_record/3]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
@@ -167,17 +167,22 @@ shrink_bin(T) when is_tuple(T) -> list_to_tuple(shrink_bin(tuple_to_list(T)));
shrink_bin(X) -> X.
%%%----------------------------------------------------------------
-%% Replace last element (the state) with "#<state-name>{}"
-reduce_state(T) ->
- try
- erlang:setelement(size(T),
- T,
- lists:concat(['#',element(1,element(size(T),T)),'{}'])
- )
- catch
- _:_ ->
- T
- end.
+%% Replace any occurence of {Name,...}, with "#Name{}"
+reduce_state(T, RecordExample) ->
+ Name = element(1, RecordExample),
+ Arity = size(RecordExample),
+ reduce_state(T, Name, Arity).
+
+%% Replace any occurence of {Name,...}, with "#Name{}"
+reduce_state(T, Name, Arity) when element(1,T) == Name,
+ size(T) == Arity ->
+ lists:concat(['#',Name,'{}']);
+reduce_state(L, Name, Arity) when is_list(L) ->
+ [reduce_state(E,Name,Arity) || E <- L];
+reduce_state(T, Name, Arity) when is_tuple(T) ->
+ list_to_tuple( reduce_state(tuple_to_list(T),Name,Arity) );
+reduce_state(X, _, _) ->
+ X.
%%%================================================================
-record(data, {
@@ -341,34 +346,22 @@ switch(X, Types) when is_list(Types) ->
%%% {send,Msg,To}
%%% {'receive',Msg}
-trace_pid({trace,Pid,_}) -> Pid;
-trace_pid({trace,Pid,_,_}) -> Pid;
-trace_pid({trace,Pid,_,_,_}) -> Pid;
-trace_pid({trace,Pid,_,_,_,_}) -> Pid;
-trace_pid({trace,Pid,_,_,_,_,_}) -> Pid;
-trace_pid({trace_ts,Pid,_,_TS}) -> Pid;
-trace_pid({trace_ts,Pid,_,_,_TS}) -> Pid;
-trace_pid({trace_ts,Pid,_,_,_,_TS}) -> Pid;
-trace_pid({trace_ts,Pid,_,_,_,_,_TS}) -> Pid;
-trace_pid({trace_ts,Pid,_,_,_,_,_,_TS}) -> Pid.
-
-trace_ts({trace_ts,_Pid,_,TS}) -> ts(TS);
-trace_ts({trace_ts,_Pid,_,_,TS}) -> ts(TS);
-trace_ts({trace_ts,_Pid,_,_,_,TS}) -> ts(TS);
-trace_ts({trace_ts,_Pid,_,_,_,_,TS}) -> ts(TS);
-trace_ts({trace_ts,_Pid,_,_,_,_,_,TS}) -> ts(TS);
-trace_ts(_) -> "-".
-
-trace_info({trace,_Pid,A}) -> A;
-trace_info({trace,_Pid,A,B}) -> {A,B};
-trace_info({trace,_Pid,A,B,C}) -> {A,B,C};
-trace_info({trace,_Pid,A,B,C,D}) -> {A,B,C,D};
-trace_info({trace,_Pid,A,B,C,D,E}) -> {A,B,C,D,E};
-trace_info({trace_ts,_Pid,A,_TS}) -> A;
-trace_info({trace_ts,_Pid,A,B,_TS}) -> {A,B};
-trace_info({trace_ts,_Pid,A,B,C,_TS}) -> {A,B,C};
-trace_info({trace_ts,_Pid,A,B,C,D,_TS}) -> {A,B,C,D};
-trace_info({trace_ts,_Pid,A,B,C,D,E,_TS}) -> {A,B,C,D,E}.
+%% Pick 2nd element, the Pid
+trace_pid(T) when element(1,T)==trace
+ ; element(1,T)==trace_ts ->
+ element(2,T).
+
+%% Pick last element, the Time Stamp, and format it
+trace_ts(T) when element(1,T)==trace_ts ->
+ ts( element(size(T), T) ).
+
+%% Make a tuple of all elements but the 1st, 2nd and last
+trace_info(T) ->
+ case tuple_to_list(T) of
+ [trace,_Pid | Info] -> list_to_tuple(Info);
+ [trace_ts,_Pid | InfoTS] -> list_to_tuple(
+ lists:droplast(InfoTS))
+ end.
try_all_types_in_all_modules(TypesOn, Arg, WriteFun, Acc0) ->
diff --git a/lib/ssh/src/ssh_options.erl b/lib/ssh/src/ssh_options.erl
index 306eb86c23..06ce9a5f79 100644
--- a/lib/ssh/src/ssh_options.erl
+++ b/lib/ssh/src/ssh_options.erl
@@ -377,7 +377,8 @@ default(server) ->
#{default => ?DEFAULT_SHELL,
chk => fun({M,F,A}) -> is_atom(M) andalso is_atom(F) andalso is_list(A);
(disabled) -> true;
- (V) -> check_function1(V) orelse check_function2(V)
+ (V) -> check_function1(V) orelse
+ check_function2(V)
end,
class => user_option
},
@@ -403,13 +404,13 @@ default(server) ->
tcpip_tunnel_out =>
#{default => false,
- chk => fun erlang:is_boolean/1,
+ chk => fun(V) -> erlang:is_boolean(V) end,
class => user_option
},
tcpip_tunnel_in =>
#{default => false,
- chk => fun erlang:is_boolean/1,
+ chk => fun(V) -> erlang:is_boolean(V) end,
class => user_option
},
@@ -447,13 +448,13 @@ default(server) ->
password =>
#{default => undefined,
- chk => fun check_string/1,
+ chk => fun(V) -> check_string(V) end,
class => user_option
},
dh_gex_groups =>
#{default => undefined,
- chk => fun check_dh_gex_groups/1,
+ chk => fun(V) -> check_dh_gex_groups(V) end,
class => user_option
},
@@ -477,31 +478,31 @@ default(server) ->
negotiation_timeout =>
#{default => 2*60*1000,
- chk => fun check_timeout/1,
+ chk => fun(V) -> check_timeout(V) end,
class => user_option
},
max_sessions =>
#{default => infinity,
- chk => fun check_pos_integer/1,
+ chk => fun(V) -> check_pos_integer(V) end,
class => user_option
},
max_channels =>
#{default => infinity,
- chk => fun check_pos_integer/1,
+ chk => fun(V) -> check_pos_integer(V) end,
class => user_option
},
parallel_login =>
#{default => false,
- chk => fun erlang:is_boolean/1,
+ chk => fun(V) -> erlang:is_boolean(V) end,
class => user_option
},
minimal_remote_max_packet_size =>
#{default => 0,
- chk => fun check_pos_integer/1,
+ chk => fun(V) -> check_pos_integer(V) end,
class => user_option
},
@@ -515,7 +516,7 @@ default(server) ->
connectfun =>
#{default => fun(_,_,_) -> void end,
- chk => fun check_function3/1,
+ chk => fun(V) -> check_function3(V) end,
class => user_option
},
@@ -534,49 +535,49 @@ default(client) ->
#{
dsa_pass_phrase =>
#{default => undefined,
- chk => fun check_string/1,
+ chk => fun(V) -> check_string(V) end,
class => user_option
},
rsa_pass_phrase =>
#{default => undefined,
- chk => fun check_string/1,
+ chk => fun(V) -> check_string(V) end,
class => user_option
},
ecdsa_pass_phrase =>
#{default => undefined,
- chk => fun check_string/1,
+ chk => fun(V) -> check_string(V) end,
class => user_option
},
%%% Not yet implemented ed25519_pass_phrase =>
%%% Not yet implemented #{default => undefined,
-%%% Not yet implemented chk => fun check_string/1,
+%%% Not yet implemented chk => fun(V) -> check_string(V) end,
%%% Not yet implemented class => user_option
%%% Not yet implemented },
%%% Not yet implemented
%%% Not yet implemented ed448_pass_phrase =>
%%% Not yet implemented #{default => undefined,
-%%% Not yet implemented chk => fun check_string/1,
+%%% Not yet implemented chk => fun(V) -> check_string(V) end,
%%% Not yet implemented class => user_option
%%% Not yet implemented },
%%% Not yet implemented
silently_accept_hosts =>
#{default => false,
- chk => fun check_silently_accept_hosts/1,
+ chk => fun(V) -> check_silently_accept_hosts(V) end,
class => user_option
},
user_interaction =>
#{default => true,
- chk => fun erlang:is_boolean/1,
+ chk => fun(V) -> erlang:is_boolean(V) end,
class => user_option
},
save_accepted_host =>
#{default => true,
- chk => fun erlang:is_boolean/1,
+ chk => fun(V) -> erlang:is_boolean(V) end,
class => user_option
},
@@ -592,7 +593,7 @@ default(client) ->
connect_timeout =>
#{default => infinity,
- chk => fun check_timeout/1,
+ chk => fun(V) -> check_timeout(V) end,
class => user_option
},
@@ -613,26 +614,26 @@ default(client) ->
User
end
end,
- chk => fun check_string/1,
+ chk => fun(V) -> check_string(V) end,
class => user_option
},
password =>
#{default => undefined,
- chk => fun check_string/1,
+ chk => fun(V) -> check_string(V) end,
class => user_option
},
quiet_mode =>
#{default => false,
- chk => fun erlang:is_boolean/1,
+ chk => fun(V) -> erlang:is_boolean(V) end,
class => user_option
},
%%%%% Undocumented
keyboard_interact_fun =>
#{default => undefined,
- chk => fun check_function3/1,
+ chk => fun(V) -> check_function3(V) end,
class => undoc_user_option
}
};
@@ -650,13 +651,13 @@ default(common) ->
%% this option's default values is set.
pref_public_key_algs =>
#{default => undefined,
- chk => fun check_pref_public_key_algs/1,
+ chk => fun(V) -> check_pref_public_key_algs(V) end,
class => user_option
},
preferred_algorithms =>
#{default => ssh:default_algorithms(),
- chk => fun check_preferred_algorithms/1,
+ chk => fun(V) -> check_preferred_algorithms(V) end,
class => user_option
},
@@ -665,12 +666,16 @@ default(common) ->
%% The preferred_algorithms is the one to use in the rest of the ssh application!
modify_algorithms =>
#{default => undefined, % signals error if unsupported algo in preferred_algorithms :(
- chk => fun check_modify_algorithms/1,
+ chk => fun(V) -> check_modify_algorithms(V) end,
class => user_option
},
id_string =>
- #{default => undefined, % FIXME: see ssh_transport:ssh_vsn/0
+ #{default => try {ok, [_|_] = VSN} = application:get_key(ssh, vsn),
+ "Erlang/" ++ VSN
+ catch
+ _:_ -> ""
+ end,
chk => fun(random) ->
{true, {random,2,5}}; % 2 - 5 random characters
({random,I1,I2}) ->
@@ -695,31 +700,31 @@ default(common) ->
profile =>
#{default => ?DEFAULT_PROFILE,
- chk => fun erlang:is_atom/1,
+ chk => fun(V) -> erlang:is_atom(V) end,
class => user_option
},
idle_time =>
#{default => infinity,
- chk => fun check_timeout/1,
+ chk => fun(V) -> check_timeout(V) end,
class => user_option
},
disconnectfun =>
#{default => fun(_) -> void end,
- chk => fun check_function1/1,
+ chk => fun(V) -> check_function1(V) end,
class => user_option
},
unexpectedfun =>
#{default => fun(_,_) -> report end,
- chk => fun check_function2/1,
+ chk => fun(V) -> check_function2(V) end,
class => user_option
},
ssh_msg_debug_fun =>
#{default => fun(_,_,_,_) -> void end,
- chk => fun check_function4/1,
+ chk => fun(V) -> check_function4(V) end,
class => user_option
},
@@ -790,19 +795,19 @@ default(common) ->
tstflg =>
#{default => [],
- chk => fun erlang:is_list/1,
+ chk => fun(V) -> erlang:is_list(V) end,
class => undoc_user_option
},
user_dir_fun =>
#{default => undefined,
- chk => fun check_function1/1,
+ chk => fun(V) -> check_function1(V) end,
class => undoc_user_option
},
max_random_length_padding =>
#{default => ?MAX_RND_PADDING_LEN,
- chk => fun check_non_neg_integer/1,
+ chk => fun(V) -> check_non_neg_integer(V) end,
class => undoc_user_option
}
}.
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index bd901c99e0..8147f17e05 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -255,27 +255,19 @@ versions(server, Options) ->
Vsn = ?GET_INTERNAL_OPT(vsn, Options, ?DEFAULT_SERVER_VERSION),
{Vsn, format_version(Vsn, software_version(Options))}.
+format_version({Major,Minor}, "") ->
+ lists:concat(["SSH-",Major,".",Minor]);
+format_version({Major,Minor}, SoftwareVersion) ->
+ lists:concat(["SSH-",Major,".",Minor,"-",SoftwareVersion]).
+
software_version(Options) ->
case ?GET_OPT(id_string, Options) of
- undefined ->
- "Erlang"++ssh_vsn();
{random,Nlo,Nup} ->
random_id(Nlo,Nup);
ID ->
ID
end.
-ssh_vsn() ->
- try {ok,L} = application:get_all_key(ssh),
- proplists:get_value(vsn, L, "")
- of
- "" -> "";
- VSN when is_list(VSN) -> "/" ++ VSN;
- _ -> ""
- catch
- _:_ -> ""
- end.
-
random_id(Nlo, Nup) ->
[$a + rand:uniform($z-$a+1) - 1 || _<- lists:duplicate(Nlo + rand:uniform(Nup-Nlo+1) - 1, x)].
@@ -285,17 +277,12 @@ hello_version_msg(Data) ->
next_seqnum(SeqNum) ->
(SeqNum + 1) band 16#ffffffff.
-
is_valid_mac(_, _ , #ssh{recv_mac_size = 0}) ->
true;
is_valid_mac(Mac, Data, #ssh{recv_mac = Algorithm,
recv_mac_key = Key, recv_sequence = SeqNum}) ->
crypto:equal_const_time(Mac, mac(Algorithm, Key, SeqNum, Data)).
-format_version({Major,Minor}, SoftwareVersion) ->
- "SSH-" ++ integer_to_list(Major) ++ "." ++
- integer_to_list(Minor) ++ "-" ++ SoftwareVersion.
-
handle_hello_version(Version) ->
try
StrVersion = trim_tail(Version),
diff --git a/lib/ssh/test/ssh.cover b/lib/ssh/test/ssh.cover
index 69d2a1c4f8..aa0da36c75 100644
--- a/lib/ssh/test/ssh.cover
+++ b/lib/ssh/test/ssh.cover
@@ -1,3 +1,21 @@
{incl_app,ssh,details}.
-{excl_mods, ssh, [ssh_dbg, ssh_info, ssh_server_key_api, ssh_sftpd_file_api]}. \ No newline at end of file
+{excl_mods, ssh,
+ [
+ %% App
+ ssh_app,
+
+ %% %% Supervisors
+ %% ssh_acceptor_sup, ssh_channel_sup, ssh_connection_sup,
+ %% sshc_sup, sshd_sup, ssh_subsystem_sup, ssh_sup,
+ %% ssh_system_sup, ssh_tcpip_forward_acceptor_sup,
+
+ %% Test and/or info modules:
+ ssh_dbg, ssh_info,
+
+ %% API modules (behaviours):
+ ssh_server_key_api, ssh_client_key_api,
+ ssh_sftpd_file_api,
+ ssh_channel, ssh_client_channel, ssh_daemon_channel, ssh_server_channel
+ ]}.
+
diff --git a/lib/ssh/test/ssh_all.cover b/lib/ssh/test/ssh_all.cover
new file mode 100644
index 0000000000..6b2d375589
--- /dev/null
+++ b/lib/ssh/test/ssh_all.cover
@@ -0,0 +1 @@
+{incl_app,ssh,details}.
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index 1269ab393e..d1713ae608 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -1218,11 +1218,10 @@ shell_exit_status(Config) when is_list(Config) ->
SystemDir = proplists:get_value(data_dir, Config),
UserDir = proplists:get_value(priv_dir, Config),
- ShellFun = fun (_User) -> spawn(fun() -> ok end) end,
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
{user_dir, UserDir},
{user_passwords, [{"vego", "morot"}]},
- {shell, ShellFun},
+ {shell, {?MODULE,always_ok,[]}},
{failfun, fun ssh_test_lib:failfun/2}]),
ConnectionRef =
ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
@@ -1236,14 +1235,15 @@ shell_exit_status(Config) when is_list(Config) ->
ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
ssh:stop_daemon(Pid).
-
+always_ok(_) -> ok.
+
%%----------------------------------------------------------------------------
setopts_getopts(Config) ->
process_flag(trap_exit, true),
SystemDir = proplists:get_value(data_dir, Config),
UserDir = proplists:get_value(priv_dir, Config),
- ShellFun = fun (_User) -> spawn(fun() -> ok end) end,
+ ShellFun = fun (_User, _Peer) -> spawn(fun() -> ok end) end,
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
{user_dir, UserDir},
{user_passwords, [{"vego", "morot"}]},
diff --git a/lib/ssh/test/ssh_dbg_SUITE.erl b/lib/ssh/test/ssh_dbg_SUITE.erl
index 8df9c8093a..2320bd4be9 100644
--- a/lib/ssh/test/ssh_dbg_SUITE.erl
+++ b/lib/ssh/test/ssh_dbg_SUITE.erl
@@ -47,7 +47,9 @@ groups() ->
dbg_alg_terminate,
dbg_ssh_messages,
dbg_connections,
- dbg_channels]},
+ dbg_channels,
+ dbg_authentication,
+ all_dbg]},
{circ_buf, [], [cb_basic,
cb_print,
cb_macros_print
@@ -58,7 +60,7 @@ groups() ->
init_per_suite(Config) ->
?CHECK_CRYPTO(begin
ssh:start(),
- Config
+ setup_dirs(Config)
end).
end_per_suite(_Config) ->
@@ -193,6 +195,84 @@ dbg_connections(Config) ->
stop_and_fail_if_unhandled_dbg_msgs(Ref, [C,D], Pid).
%%--------------------------------------------------------------------
+dbg_authentication(Config) ->
+ Ref = ssh_dbg_start(),
+ {ok,[authentication]} = ssh_dbg:on([authentication]),
+
+ Parent = self(),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, system_dir(Config)},
+ {user_dir, user_dir(Config)},
+ {user_passwords, [{?USR,?PWD}]},
+ {connectfun, fun(_,_,_) ->
+ Parent ! {daemon_c,Ref,self()}
+ end},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ %% ---- Check password ----
+ Cpwd = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user,?USR},
+ {password,?PWD},
+ {auth_methods,"password"},
+ {user_interaction, false}]),
+ Cpwd_d = daemon_connection_ref(Ref, Cpwd),
+
+ ?DBG_RECEIVE("AUTH client: Service ssh-userauth accepted", Ref, Cpwd, Pid),
+ ?DBG_RECEIVE("AUTH client: Query for accepted methods", Ref, Cpwd, Pid),
+ ?DBG_RECEIVE("AUTH srvr: Peer queries auth methods", Ref, Cpwd_d, Pid),
+ ?DBG_RECEIVE("AUTH client: Server supports", Ref, Cpwd, Pid),
+ ?DBG_RECEIVE("AUTH client: Try auth with", Ref, Cpwd, Pid),
+ ?DBG_RECEIVE("AUTH srvr: Peer client authorized", Ref, Cpwd_d, Pid),
+ ?DBG_RECEIVE("AUTH client: Success", Ref, Cpwd, Pid),
+ ssh:close(Cpwd),
+ fail_if_unhandled_dbg_msgs(Ref, [Cpwd,Cpwd_d]),
+
+ %% ---- Check keyboard-interactive ----
+ Ckbi = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user,?USR},
+ {password,?PWD},
+ {auth_methods,"keyboard-interactive"},
+ {user_interaction, false}]),
+ Ckbi_d = daemon_connection_ref(Ref, Ckbi),
+
+ ?DBG_RECEIVE("AUTH client: Service ssh-userauth accepted", Ref, Ckbi, Pid),
+ ?DBG_RECEIVE("AUTH client: Query for accepted methods", Ref, Ckbi, Pid),
+ ?DBG_RECEIVE("AUTH srvr: Peer queries auth methods", Ref, Ckbi_d, Pid),
+ ?DBG_RECEIVE("AUTH client: Server supports", Ref, Ckbi, Pid),
+ ?DBG_RECEIVE("AUTH client: Try auth with", Ref, Ckbi, Pid),
+ ?DBG_RECEIVE("AUTH srvr: Ask peer client for password", Ref, Ckbi_d, Pid),
+ ?DBG_RECEIVE("AUTH client: Success", Ref, Ckbi, Pid),
+ ssh:close(Ckbi),
+ fail_if_unhandled_dbg_msgs(Ref, [Ckbi,Ckbi_d]),
+
+ %% ---- Check publickey ----
+ Cpkey = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {auth_methods,"publickey"},
+ {user_interaction, false}]),
+ Cpkey_d = daemon_connection_ref(Ref, Cpkey),
+
+ ?DBG_RECEIVE("AUTH client: Service ssh-userauth accepted", Ref, Cpkey, Pid),
+ ?DBG_RECEIVE("AUTH client: Query for accepted methods", Ref, Cpkey, Pid),
+ ?DBG_RECEIVE("AUTH srvr: Peer queries auth methods", Ref, Cpkey_d, Pid),
+ ?DBG_RECEIVE("AUTH client: Server supports", Ref, Cpkey, Pid),
+ ?DBG_RECEIVE("AUTH client: Try auth with", Ref, Cpkey, Pid),
+ ?DBG_RECEIVE("AUTH srvr: Peer client authorized", Ref, Cpkey_d, Pid),
+ ?DBG_RECEIVE("AUTH client: Success", Ref, Cpkey, Pid),
+ ssh:close(Cpkey),
+ stop_and_fail_if_unhandled_dbg_msgs(Ref, [Cpkey,Cpkey_d], Pid).
+
+
+daemon_connection_ref(Ref,C) ->
+ D =
+ receive
+ {daemon_c,Ref,D0} -> D0
+ end,
+ ct:log("~p:~p~nC = ~p, D=~p",[?MODULE,?LINE, C, D]),
+ D.
+
+%%--------------------------------------------------------------------
dbg_ssh_messages(Config) ->
SystemDir = proplists:get_value(data_dir, Config),
UserDir = proplists:get_value(priv_dir, Config),
@@ -353,6 +433,37 @@ dbg_channels(Config) ->
stop_and_fail_if_unhandled_dbg_msgs(Ref, [C,D], Pid).
%%--------------------------------------------------------------------
+all_dbg(Config) ->
+ SystemDir = proplists:get_value(data_dir, Config),
+ UserDir = proplists:get_value(priv_dir, Config),
+
+ Dir0 = filename:join(proplists:get_value(priv_dir,Config), ssh_test_lib:random_chars(10)),
+ file:make_dir(Dir0),
+ Dir = w2l(Config, Dir0),
+ ct:log("~p:~p created the directory~nsDir0 = ~p~nDir = ~p", [?MODULE,?LINE,Dir0,Dir]),
+
+ AllTags = ssh_dbg:start(),
+ {ok,AllTags} = ssh_dbg:on(AllTags),
+
+ {_, Host, Port} =
+ ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {user_passwords, [{?USR,?PWD}]}
+ ]),
+
+ {ok, ChPid, _C} =
+ ssh_sftp:start_channel(Host, Port,
+ [{user_dir, UserDir},
+ {user,?USR},
+ {password,?PWD},
+ {user_interaction, false},
+ {silently_accept_hosts, true}
+ ]),
+
+ {ok, _Files} = ssh_sftp:list_dir(ChPid, Dir).
+
+
+%%--------------------------------------------------------------------
cb_basic(_Config) ->
%% Check that the circular buffer is disabled at start:
[] = ssh_dbg:cbuf_list(),
@@ -414,6 +525,16 @@ ssh_dbg_start(Ref) ->
Ref.
%%--------------------------------------------------------------------
+setup_dirs(Config) ->
+ ct:log("Pub keys setup for: ~p",
+ [ssh_test_lib:setup_all_user_host_keys(Config)]),
+ Config.
+
+system_dir(Config) -> filename:join(proplists:get_value(priv_dir, Config), system).
+
+user_dir(Config) -> proplists:get_value(priv_dir, Config).
+
+%%--------------------------------------------------------------------
queued_msgs(Ref, Conns) ->
queued_msgs(Ref, Conns, []).
@@ -431,11 +552,10 @@ queued_msgs(Ref, Conns, Acc) ->
end.
%%--------------------------------------------------------------------
-stop_and_fail_if_unhandled_dbg_msgs(Ref, Conns, DaemonPid) ->
- stop_and_fail_if_unhandled_dbg_msgs(queued_msgs(Ref,Conns), Ref, Conns, DaemonPid).
+fail_if_unhandled_dbg_msgs(Ref, Conns) ->
+ fail_if_unhandled_dbg_msgs(queued_msgs(Ref,Conns), Ref, Conns).
-stop_and_fail_if_unhandled_dbg_msgs(Msgs, _Ref, _Conns, DaemonPid) ->
- ssh:stop_daemon(DaemonPid),
+fail_if_unhandled_dbg_msgs(Msgs, _Ref, _Conns) ->
case Msgs of
[] ->
ok;
@@ -445,6 +565,15 @@ stop_and_fail_if_unhandled_dbg_msgs(Msgs, _Ref, _Conns, DaemonPid) ->
end.
%%--------------------------------------------------------------------
+stop_and_fail_if_unhandled_dbg_msgs(Ref, Conns, DaemonPid) ->
+ stop_and_fail_if_unhandled_dbg_msgs(queued_msgs(Ref,Conns), Ref, Conns, DaemonPid).
+
+stop_and_fail_if_unhandled_dbg_msgs(Msgs, Ref, Conns, DaemonPid) ->
+ ssh:stop_daemon(DaemonPid),
+ fail_if_unhandled_dbg_msgs(Msgs, Ref, Conns).
+
+
+%%--------------------------------------------------------------------
dbg_SKIP(Ref, Prefixes) ->
dbg_SKIP(Ref, Prefixes, []).
@@ -470,3 +599,11 @@ dbg_SKIP(Ref, Prefixes, UnexpectedAcc) ->
lists:reverse(UnexpectedAcc)
end.
+%%%----------------------------------------------------------------
+w2l(P) ->
+ ssh_test_lib:winpath_to_linuxpath(P).
+
+w2l(Config, P) ->
+ W2L = proplists:get_value(w2l, Config, fun(X) -> X end),
+ W2L(P).
+
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_dsa b/lib/ssh/test/ssh_dbg_SUITE_data/id_dsa
new file mode 100644
index 0000000000..24628e071b
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_dsa
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQDIywHurUpOq6kZuMn+XlRzR4hAxF6qwSkuEqkV7iHnLQ0kIwf3
+uAmjFDhuEsQ8653SLxGVvTNp+KFFgDXiLqgM7TPUwDnpbvzEZHPAU+/zPt4sdY2D
+txBfJwT2SFlK6HPOxOcxdDuD+/a59sh8hk/YVOU7ZTcBVsVG8Got4UcF5QIVAPGd
+CPDQKSTlPiM9OwBB1+9p11k5AoGARLxw4l17mET9cU0uf4Ppe5nsCbODJv44ZrSs
+picvypGVLrLcN5KWbm3vjRFCQ5LFunAG3FwLC2Sh0CH6TemoIfRPsRHR7wvpBGdr
+c693UlMOis/mcmvNMQAzuQNW9WrxdzsvWR/r5s6NEHWqKUJGXSPi2d+Ijq/mCOmI
+hzLzyiACgYEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4
+cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+C
+ROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNgCFEjA7wTC
+sQCY/I35vb6GUJn9tEdP
+-----END DSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_dsa.pub b/lib/ssh/test/ssh_dbg_SUITE_data/id_dsa.pub
new file mode 100644
index 0000000000..018ef6f537
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_dsa.pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAMjLAe6tSk6rqRm4yf5eVHNHiEDEXqrBKS4SqRXuIectDSQjB/e4CaMUOG4SxDzrndIvEZW9M2n4oUWANeIuqAztM9TAOelu/MRkc8BT7/M+3ix1jYO3EF8nBPZIWUroc87E5zF0O4P79rn2yHyGT9hU5TtlNwFWxUbwai3hRwXlAAAAFQDxnQjw0Ckk5T4jPTsAQdfvaddZOQAAAIBEvHDiXXuYRP1xTS5/g+l7mewJs4Mm/jhmtKymJy/KkZUustw3kpZube+NEUJDksW6cAbcXAsLZKHQIfpN6agh9E+xEdHvC+kEZ2tzr3dSUw6Kz+Zya80xADO5A1b1avF3Oy9ZH+vmzo0QdaopQkZdI+LZ34iOr+YI6YiHMvPKIAAAAIEAsTRcHZqZlamr0PM7jKt2edCpcd8rEFGtWuescebc6Ga5JGSv7Ue4cdYKpAjT10Mns1WYaU9t6ZR+6ARP7DkzzDmS1elwkRu21T+b81PmeZwaEJxgqr+CROQVHgzpqMqEx8ic3c/juxZpRrCAlRCjCWSJLDMobBQvtfyG0qsleNg= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa384
new file mode 100644
index 0000000000..4e8aa40959
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCYXb6OSAZyXRfLXOtMo43za197Hdc/T0YKjgQQjwDt6rlRwqTh7v7S
+PV2kXwNGdWigBwYFK4EEACKhZANiAARN2khlJUOOIiwsWHEALwDieeZR96qL4pUd
+ci7aeGaczdUK5jOA9D9zmBZtSYTfO8Cr7ekVghDlcWAIJ/BXcswgQwSEQ6wyfaTF
+8FYfyr4l3u9IirsnyaFzeIgeoNis8Gw=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa384.pub
new file mode 100644
index 0000000000..41e722e545
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE3aSGUlQ44iLCxYcQAvAOJ55lH3qovilR1yLtp4ZpzN1QrmM4D0P3OYFm1JhN87wKvt6RWCEOVxYAgn8FdyzCBDBIRDrDJ9pMXwVh/KviXe70iKuyfJoXN4iB6g2KzwbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa521
new file mode 100644
index 0000000000..7196f46e97
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEFMadoz4ckEcClfqXa2tiUuYkJdDfwq+/iFQcpt8ESuEd26IY/vm47Q
+9UzbPkO4ou8xkNsQ3WvCRQBBWtn5O2kUU6AHBgUrgQQAI6GBiQOBhgAEAde5BRu5
+01/jS0jRk212xsb2DxPrxNpgp6IMCV8TA4Eps+8bSqHB091nLiBcP422HXYfuCd7
+XDjSs8ihcmhp0hCRASLqZR9EzW9W/SOt876May1Huj5X+WSO6RLe7vPn9vmf7kHf
+pip6m7M7qp2qGgQ3q2vRwS2K/O6156ohiOlmuuFs
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa521.pub
new file mode 100644
index 0000000000..8f059120bc
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHXuQUbudNf40tI0ZNtdsbG9g8T68TaYKeiDAlfEwOBKbPvG0qhwdPdZy4gXD+Nth12H7gne1w40rPIoXJoadIQkQEi6mUfRM1vVv0jrfO+jGstR7o+V/lkjukS3u7z5/b5n+5B36YqepuzO6qdqhoEN6tr0cEtivzuteeqIYjpZrrhbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_ed25519 b/lib/ssh/test/ssh_dbg_SUITE_data/id_ed25519
new file mode 100644
index 0000000000..401a3e4a9a
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_ed25519
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACDm9P8/gC0IOKmwHLSvkmEtS2Xx0RRqUDqC6wY6UgDVnwAAAJg3+6xpN/us
+aQAAAAtzc2gtZWQyNTUxOQAAACDm9P8/gC0IOKmwHLSvkmEtS2Xx0RRqUDqC6wY6UgDVnw
+AAAEBzC/Z2WGJhZ3l3tIBnUc6DCbp+lXY2yc2RRpWQTdf8sub0/z+ALQg4qbActK+SYS1L
+ZfHRFGpQOoLrBjpSANWfAAAAE3VhYmhuaWxAZWx4YWRsajNxMzIBAg==
+-----END OPENSSH PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_ed25519.pub b/lib/ssh/test/ssh_dbg_SUITE_data/id_ed25519.pub
new file mode 100644
index 0000000000..a5c03b19c1
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_ed25519.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOb0/z+ALQg4qbActK+SYS1LZfHRFGpQOoLrBjpSANWf uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_ed448 b/lib/ssh/test/ssh_dbg_SUITE_data/id_ed448
new file mode 100644
index 0000000000..8ecfd710dc
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_ed448
@@ -0,0 +1,10 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlz
+c2gtZWQ0NDgAAAA53OqeePNaG/NJmoMbELhskKrAHNhLZ6AQm1WjbpMoseNl/OFh
+1xznExpUPqTLX36fHYsAaWRHABQAAAAA0AAAEREAABERAAAACXNzaC1lZDQ0OAAA
+ADnc6p5481ob80magxsQuGyQqsAc2EtnoBCbVaNukyix42X84WHXHOcTGlQ+pMtf
+fp8diwBpZEcAFAAAAAByzSPST3FCdOdENDI3uTKQ9RH2Ql+Y5kRZ/yA+iYUIP/32
+BQBVOrwOBc0CGEvbicTM1n4YeVEmfrMo3OqeePNaG/NJmoMbELhskKrAHNhLZ6AQ
+m1WjbpMoseNl/OFh1xznExpUPqTLX36fHYsAaWRHABQAAAAAAAECAwQ=
+-----END OPENSSH PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_ed448.pub b/lib/ssh/test/ssh_dbg_SUITE_data/id_ed448.pub
new file mode 100644
index 0000000000..cec0765a5d
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_ed448.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADnc6p5481ob80magxsQuGyQqsAc2EtnoBCbVaNukyix42X84WHXHOcTGlQ+pMtffp8diwBpZEcAFAA= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_rsa b/lib/ssh/test/ssh_dbg_SUITE_data/id_rsa
new file mode 100644
index 0000000000..2202c2ead8
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_rsa
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAztjiyj2tdfkji0fewWS0kABg0IABgG20NvL1PnHJLr98we7w
+W7f3j27EGjW/ApuycsWXXKi0L82q8uDicoHHb3JI2JkT70oi0yG1Dx/zwPN+dkA7
+LBT1J3UK2hJTFPhp855CwY/ss9xpBsd1Fv3zuHifEqNGljeg1PjmQ3pNhxA/M0aZ
+cLnfIUdZ5Hr+t+4es3zaWo4tLBKmZu6BkVGQKPGXeMkIAMtJlG24l7qKDRkR5TYA
+ZT7P8Vn7hnuFuCNbrJSm686GawBxTQXom23dg9UcWxoHB7UiHFoR6j0bQAX+4R7b
+IwculRDcvzrgCu6u06oFILwY7MlsxpX9hGTl1wIDAQABAoIBAFeP6pmQeICrYceR
+OhQGLIWVE2bP+VLDnflw6i5v/qlieE6kdm1tOEgorK0nuV9CR81cJdIcvIJL/yTn
+3BR7KdDcwUenrY+rg4h7CWmIrigtK4ilciccDBeS7XAZN8B11GxDv6Cu65XMJU2w
+W7nK8URTE4vRQI1QqS3e26MPAAi/LVOt3ZPI6zg/GHEwnq0IVSQAOndLBr/IWZk5
+SANrkfwX8WS7/UxZgDptT9dyUQ5Pnj5mieTlIvBwyczdhZ7RDa8HdCSHW3xF83V1
+A0pkn6+TRojumYyr4RrPQj6htE64Hgx9w1Dv/UINjPXl5mGlbxQHMWGzlqD/qpyI
+wg7RakECgYEA+9ARZpHfEFz+EEFi8l9J+BtJDo00WaKCOZHh5UJ8W+NreqSd8nSx
+5u6wYwMJjRX2Hwv+FBEhxGbo1+ff6p++cYmiSlDtN2XRCDkBWvvGlxu55BDULrhx
+f8lqaV3XGmOy2rQusp8hiHmkmPJCSVj3oJqQnbqJ2zahXAx1rTPwHqECgYEA0kln
+4h+ZkZ+aldOMGF0d0txTcTqZvsSVKiFTSD9of/fiSDqb6xtLT2+ys6FZoFL9lyK8
+gtqH642CDQ+3WT6Nmn4kMF5HNVpEuCeRDeRhiquWeKaAQDyvZ5ym1+Cn3GhsO7Di
+d2LJKV5hOoN77loVY5nwnUVIJ0h+WLf0T7DTCXcCgYEAiNT7X50MdTvS4splFgcp
+jqRlAn9AXySrVtUqxwVlxhjCIpapLUK0GSTCvEq+OeghIaXGnujgTHUPOaNKTZgY
+SGHdyjxHar7s42b2kZYWx63NSVzLr8eSBTpRlIflhvV+DtGyPmWyNxLCmkmqM2kg
+xii3RL5EgtYgwIAUwdVjOYECgYBRPlsMWfkS8f7fc+PkZdVn6gey71kHAxw+MrHi
+b90H09Vw4nPq2Zi3EAiSrfvanTWsdpcuVw+8See89B16NViwH5wLs+D/E+kI3QCF
+xX6J/NEdu/ZA2zFJbpRnQzyXQyDNzwEv7tKZUQVvfe0boWIyIP99Q48k3jUyQZ/6
+Se6+8QKBgQCXl8H2K3CsZxoujKLb2qoEOPbxJQ2hxoMTS5XuQECReIVsNuptWrur
+DF8WJi/B6AqwRX1P3l56RNwqB1yDBqv0QVLpU7vU/FmWqLWTn0r3AvM74qftvfAE
+oa31wcYoCqPJoKgCG7TThLhNt2v5hL7sVgZNO0ueAiHhJbFLaf7ceg==
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_dbg_SUITE_data/id_rsa.pub b/lib/ssh/test/ssh_dbg_SUITE_data/id_rsa.pub
new file mode 100644
index 0000000000..b4084d320a
--- /dev/null
+++ b/lib/ssh/test/ssh_dbg_SUITE_data/id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDO2OLKPa11+SOLR97BZLSQAGDQgAGAbbQ28vU+cckuv3zB7vBbt/ePbsQaNb8Cm7JyxZdcqLQvzary4OJygcdvckjYmRPvSiLTIbUPH/PA8352QDssFPUndQraElMU+GnznkLBj+yz3GkGx3UW/fO4eJ8So0aWN6DU+OZDek2HED8zRplwud8hR1nkev637h6zfNpaji0sEqZm7oGRUZAo8Zd4yQgAy0mUbbiXuooNGRHlNgBlPs/xWfuGe4W4I1uslKbrzoZrAHFNBeibbd2D1RxbGgcHtSIcWhHqPRtABf7hHtsjBy6VENy/OuAK7q7TqgUgvBjsyWzGlf2EZOXX uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_limited.cover b/lib/ssh/test/ssh_limited.cover
new file mode 100644
index 0000000000..2b0fcf5bf6
--- /dev/null
+++ b/lib/ssh/test/ssh_limited.cover
@@ -0,0 +1,22 @@
+%% -*- erlang -*-
+
+{incl_app,ssh,details}.
+
+{excl_mods, ssh,
+ [
+ %% App
+ ssh_app,
+
+ %% Supervisors
+ ssh_acceptor_sup, ssh_channel_sup, ssh_connection_sup,
+ sshc_sup, sshd_sup, ssh_subsystem_sup, ssh_sup,
+ ssh_system_sup, ssh_tcpip_forward_acceptor_sup,
+
+ %% Test and/or info modules:
+ ssh_dbg, ssh_info,
+
+ %% API modules (behaviours):
+ ssh_server_key_api, ssh_client_key_api,
+ ssh_sftpd_file_api,
+ ssh_channel, ssh_client_channel, ssh_daemon_channel, ssh_server_channel
+ ]}.
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE.erl b/lib/ssh/test/ssh_renegotiate_SUITE.erl
index b08a5ab1eb..5eff2fe7ac 100644
--- a/lib/ssh/test/ssh_renegotiate_SUITE.erl
+++ b/lib/ssh/test/ssh_renegotiate_SUITE.erl
@@ -87,7 +87,10 @@ rekey2() -> [{timetrap,{seconds,120}}].
rekey3() -> [{timetrap,{seconds,120}}].
rekey4() -> [{timetrap,{seconds,120}}].
-rekey0(Config) -> rekey_chk(Config, 0, 0).
+rekey0(Config) -> ssh_dbg:start(), ssh_dbg:on(renegotiation),
+ R = rekey_chk(Config, 0, 0),
+ ssh_dbg:stop(),
+ R.
rekey1(Config) -> rekey_chk(Config, infinity, 0).
rekey2(Config) -> rekey_chk(Config, {infinity,infinity}, 0).
rekey3(Config) -> rekey_chk(Config, 0, infinity).