Skip to content

Commit c5cea08

Browse files
committed
Merge branch 'kuba/ssh/tolerate_extra_ssh_msg_service_request/erlangGH-6463/OTP-19637' into maint
* kuba/ssh/tolerate_extra_ssh_msg_service_request/erlangGH-6463/OTP-19637: ssh: tolerate extra ssh_msg_service_request
2 parents 534af6f + 63aec63 commit c5cea08

2 files changed

Lines changed: 48 additions & 5 deletions

File tree

lib/ssh/src/ssh_connection_handler.erl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -688,9 +688,12 @@ handle_event(state_timeout, no_hello_received, {hello,_Role}=StateName, D0 = #da
688688
{stop, Shutdown, D};
689689

690690

691-
%%% ######## {service_request, client|server} ####
692-
693-
handle_event(internal, Msg = #ssh_msg_service_request{name=ServiceName}, StateName = {service_request,server}, D0) ->
691+
%%% ######## {service_request, client|server} #### StateName ==
692+
%% {userauth,server} guard added due to interoperability with clients
693+
%% sending extra ssh_msg_service_request (e.g. Paramiko for Python,
694+
%% see GH-6463)
695+
handle_event(internal, Msg = #ssh_msg_service_request{name=ServiceName}, StateName, D0)
696+
when StateName == {service_request,server}; StateName == {userauth,server} ->
694697
case ServiceName of
695698
"ssh-userauth" ->
696699
Ssh0 = #ssh{session_id=SessionId} = D0#data.ssh_params,

lib/ssh/test/ssh_protocol_SUITE.erl

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@
9292
service_name_length_too_large/1,
9393
service_name_length_too_short/1,
9494
client_close_after_hello/1,
95-
channel_close_timeout/1
95+
channel_close_timeout/1,
96+
extra_ssh_msg_service_request/1
9697
]).
9798

9899
-define(NEWLINE, <<"\r\n">>).
@@ -169,7 +170,8 @@ groups() ->
169170
bad_long_service_name,
170171
bad_very_long_service_name,
171172
empty_service_name,
172-
bad_service_name_then_correct
173+
bad_service_name_then_correct,
174+
extra_ssh_msg_service_request
173175
]},
174176
{authentication, [], [client_handles_keyboard_interactive_0_pwds,
175177
client_handles_banner_keyboard_interactive,
@@ -1452,6 +1454,44 @@ client_close_after_hello(Config0) ->
14521454
{fail, no_handshakers}
14531455
end.
14541456

1457+
%%% Connect to an erlang server and pretend client sending extra
1458+
%%% ssh_msg_service_request (Paramiko client behavior)
1459+
extra_ssh_msg_service_request(Config) ->
1460+
%% Connect and negotiate keys
1461+
{ok,InitialState} = ssh_trpt_test_lib:exec(
1462+
[{set_options, [print_ops, print_seqnums, print_messages]}]
1463+
),
1464+
{ok,AfterKexState} = connect_and_kex(Config, InitialState),
1465+
%% Do the authentcation
1466+
{User,Pwd} = server_user_password(Config),
1467+
UserAuthFlow =
1468+
fun(P) ->
1469+
[{send, #ssh_msg_service_request{name = "ssh-userauth"}},
1470+
{match, #ssh_msg_service_accept{name = "ssh-userauth"}, receive_msg},
1471+
{send, #ssh_msg_userauth_request{user = User,
1472+
service = "ssh-connection",
1473+
method = "password",
1474+
data = <<?BOOLEAN(?FALSE),
1475+
?STRING(unicode:characters_to_binary(P))>>
1476+
}}]
1477+
end,
1478+
{ok,EndState} =
1479+
ssh_trpt_test_lib:exec(
1480+
UserAuthFlow("WRONG") ++
1481+
[{match, #ssh_msg_userauth_failure{_='_'}, receive_msg}] ++
1482+
UserAuthFlow(Pwd) ++
1483+
[{match, #ssh_msg_userauth_success{_='_'}, receive_msg}],
1484+
AfterKexState),
1485+
%% Disconnect
1486+
{ok,_} =
1487+
ssh_trpt_test_lib:exec(
1488+
[{send, #ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
1489+
description = "End of the fun",
1490+
language = ""
1491+
}},
1492+
close_socket
1493+
], EndState),
1494+
ok.
14551495

14561496
%%%================================================================
14571497
%%%==== Internal functions ========================================

0 commit comments

Comments
 (0)