Skip to content

ssh: fix wrong_role2 flow in ssh_protocol_SUITE #9836

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 71 additions & 30 deletions lib/ssh/test/ssh_protocol_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
kex_strict_violation_key_exchange/1,
kex_strict_violation_new_keys/1,
kex_strict_violation/1,
kex_strict_violation_2/1,
kex_strict_msg_unknown/1,
gex_client_init_option_groups/1,
gex_client_init_option_groups_file/1,
Expand Down Expand Up @@ -103,6 +104,18 @@
[{client2server,Ciphs}, {server2client,Ciphs}]
end)()
).
-define(HARDCODED_KEXDH_REPLY,
#ssh_msg_kexdh_reply{
public_host_key = {{{'ECPoint',<<73,72,235,162,96,101,154,59,217,114,123,192,96,105,250,29,214,76,60,63,167,21,221,118,246,168,152,2,7,172,137,125>>},
{namedCurve,{1,3,101,112}}},
'ssh-ed25519'},
f = 18504393053016436370762156176197081926381112956345797067569792020930728564439992620494295053804030674742529174859108487694089045521619258420515443400605141150065440678508889060925968846155921972385560196703381004650914261218463420313738628465563288022895912907728767735629532940627575655703806353550720122093175255090704443612257683903495753071530605378193139909567971489952258218767352348904221407081210633467414579377014704081235998044497191940270966762124544755076128392259615566530695493013708460088312025006678879288856957348606386230195080105197251789635675011844976120745546472873505352732719507783227210178188,
h_sig = <<90,247,44,240,136,196,82,215,56,165,53,33,230,101,253,
34,112,201,21,131,162,169,10,129,174,14,69,25,39,174,
92,210,130,249,103,2,215,245,7,213,110,235,136,134,11,
124,248,139,79,17,225,77,125,182,204,84,137,167,99,186,
167,42,192,10>>}).

%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
Expand Down Expand Up @@ -147,6 +160,7 @@ groups() ->
kex_strict_violation_key_exchange,
kex_strict_violation_new_keys,
kex_strict_violation,
kex_strict_violation_2,
kex_strict_msg_unknown]},
{service_requests, [], [bad_service_name,
bad_long_service_name,
Expand Down Expand Up @@ -406,7 +420,7 @@ early_rce(Config) ->
DataReq = <<?STRING(<<"lists:seq(1,10).">>)>>,
SshMsgChannelRequest =
ssh_connection:channel_request_msg(Id, TypeReq, WantReply, DataReq),
{ok,_} =
{ok, _AfterKexState} =
ssh_trpt_test_lib:exec(
[{connect,
ssh_test_lib:server_host(Config),ssh_test_lib:server_port(Config),
Expand Down Expand Up @@ -1128,20 +1142,8 @@ kex_strict_violation_new_keys(Config) ->
%% Connect to an erlang server and inject unexpected SSH message
%% duplicated KEXINIT
kex_strict_violation(Config) ->
KexDhReply =
#ssh_msg_kexdh_reply{
public_host_key = {{{'ECPoint',<<73,72,235,162,96,101,154,59,217,114,123,192,96,105,250,29,214,76,60,63,167,21,221,118,246,168,152,2,7,172,137,125>>},
{namedCurve,{1,3,101,112}}},
'ssh-ed25519'},
f = 18504393053016436370762156176197081926381112956345797067569792020930728564439992620494295053804030674742529174859108487694089045521619258420515443400605141150065440678508889060925968846155921972385560196703381004650914261218463420313738628465563288022895912907728767735629532940627575655703806353550720122093175255090704443612257683903495753071530605378193139909567971489952258218767352348904221407081210633467414579377014704081235998044497191940270966762124544755076128392259615566530695493013708460088312025006678879288856957348606386230195080105197251789635675011844976120745546472873505352732719507783227210178188,
h_sig = <<90,247,44,240,136,196,82,215,56,165,53,33,230,101,253,
34,112,201,21,131,162,169,10,129,174,14,69,25,39,174,
92,210,130,249,103,2,215,245,7,213,110,235,136,134,11,
124,248,139,79,17,225,77,125,182,204,84,137,167,99,186,
167,42,192,10>>},
TestFlows =
[
{kexinit, "KEX strict violation",
[{kexinit, "KEX strict violation",
[receive_hello,
{send, hello},
{send, ssh_msg_kexinit},
Expand Down Expand Up @@ -1181,20 +1183,8 @@ kex_strict_violation(Config) ->
{send, ssh_msg_kexinit},
{match, #ssh_msg_kexinit{_='_'}, receive_msg},
%% client should not send message below
{send, KexDhReply},
{match, disconnect(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED), receive_msg}]},
{wrong_role2, "KEX strict violation",
[receive_hello,
{send, hello},
{send, ssh_msg_kexinit},
{match, #ssh_msg_kexinit{_='_'}, receive_msg},
{send, ssh_msg_kexdh_init},
{match,# ssh_msg_kexdh_reply{_='_'}, receive_msg},
%% client should not send message below
{send, KexDhReply},
{match, #ssh_msg_newkeys{_='_'}, receive_msg},
{match, disconnect(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED), receive_msg}]}
],
{send, ?HARDCODED_KEXDH_REPLY},
{match, disconnect(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED), receive_msg}]}],
TestProcedure =
fun({Msg, _, P}) ->
ct:log(
Expand All @@ -1207,6 +1197,58 @@ kex_strict_violation(Config) ->
ct:log("==== END ====="),
ok.

kex_strict_violation_2(Config) ->
ExpectedReason = "KEX strict violation",
{ok, TestRef} = ssh_test_lib:add_log_handler(),
Level = ssh_test_lib:get_log_level(),
ssh_test_lib:set_log_level(debug),
%% Connect and negotiate keys
{ok, InitialState} = ssh_trpt_test_lib:exec(
[{set_options, [print_ops, print_seqnums, print_messages]}]),
{ok, UpToUnexpectedKexDHReply} =
ssh_trpt_test_lib:exec(
[{connect,
ssh_test_lib:server_host(Config),ssh_test_lib:server_port(Config),
[{preferred_algorithms,[{kex,[?DEFAULT_KEX]},
{cipher,?DEFAULT_CIPHERS}
]},
{silently_accept_hosts, true},
{recv_ext_info, false},
{user_dir, user_dir(Config)},
{user_interaction, false}
| proplists:get_value(extra_options,Config,[])
]}] ++
[receive_hello,
{send, hello},
{send, ssh_msg_kexinit},
{match, #ssh_msg_kexinit{_='_'}, receive_msg},
{send, ssh_msg_kexdh_init},
{match, #ssh_msg_kexdh_reply{_='_'}, receive_msg},
%% client should not send message below
{send, ?HARDCODED_KEXDH_REPLY},
{match, {'or', [#ssh_msg_newkeys{_='_'},
disconnect(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED)]},
receive_msg}],
InitialState),
case ssh_trpt_test_lib:return_value(UpToUnexpectedKexDHReply) of
{ssh_msg_newkeys} ->
ct:log("1st flow - extra match for disconnect needed"),
ssh_trpt_test_lib:exec(
[{match, disconnect(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED), receive_msg}],
UpToUnexpectedKexDHReply);
_ ->
ct:log("2nd flow disconnect already received")
end,
ct:sleep(100),
{ok, Events} = ssh_test_lib:get_log_events(TestRef),
ssh_test_lib:rm_log_handler(),
ct:log("Events = ~p", [Events]),
true = ssh_test_lib:kex_strict_negotiated(client, Events),
true = ssh_test_lib:kex_strict_negotiated(server, Events),
true = ssh_test_lib:event_logged(server, Events, ExpectedReason),
ssh_test_lib:set_log_level(Level),
ok.

%% Connect to an erlang server and inject unexpected non-SSH binary
kex_strict_msg_unknown(Config) ->
ct:log("START: ~p~n=================================", [?FUNCTION_NAME]),
Expand All @@ -1228,8 +1270,7 @@ kex_strict_helper(Config, TestMessages, ExpectedReason) ->
ssh_test_lib:set_log_level(debug),
%% Connect and negotiate keys
{ok, InitialState} = ssh_trpt_test_lib:exec(
[{set_options, [print_ops, print_seqnums, print_messages]}]
),
[{set_options, [print_ops, print_seqnums, print_messages]}]),
{ok, _AfterKexState} =
ssh_trpt_test_lib:exec(
[{connect,
Expand Down
6 changes: 5 additions & 1 deletion lib/ssh/test/ssh_trpt_test_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
-export([exec/1, exec/2,
instantiate/2,
format_msg/1,
server_host_port/1
server_host_port/1,
return_value/1
]
).

Expand Down Expand Up @@ -816,3 +817,6 @@ opt(Flag, S, Fun) when is_function(Fun,1) ->

save_prints({Fmt,Args}, S) ->
S#s{prints = [{Fmt,Args}|S#s.prints]}.

return_value(#s{return_value = ReturnValue}) ->
ReturnValue.
Loading