aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh/src')
-rw-r--r--lib/ssh/src/ssh_auth.erl2
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl106
-rw-r--r--lib/ssh/src/ssh_transport.erl5
3 files changed, 69 insertions, 44 deletions
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl
index fdbb5c152a..b71bed033a 100644
--- a/lib/ssh/src/ssh_auth.erl
+++ b/lib/ssh/src/ssh_auth.erl
@@ -477,7 +477,7 @@ keyboard_interact_get_responses(_, undefined, Password, _, _, _, _, _,
1) when Password =/= undefined ->
[Password]; %% Password auth implemented with keyboard-interaction and passwd is known
keyboard_interact_get_responses(_, _, _, _, _, _, _, _, 0) ->
- [""];
+ [];
keyboard_interact_get_responses(false, undefined, undefined, _, _, _, [Prompt|_], Opts, _) ->
ssh_no_io:read_line(Prompt, Opts); %% Throws error as keyboard interaction is not allowed
keyboard_interact_get_responses(true, undefined, _,IoCb, Name, Instr, PromptInfos, Opts, _) ->
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 516a09bf6a..ce1931e4f4 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -648,10 +648,12 @@ userauth_keyboard_interactive(Msg = #ssh_msg_userauth_failure{},
userauth_keyboard_interactive_info_response(Msg=#ssh_msg_userauth_failure{},
#state{ssh_params = #ssh{role = client}} = State) ->
userauth(Msg, State);
-
userauth_keyboard_interactive_info_response(Msg=#ssh_msg_userauth_success{},
#state{ssh_params = #ssh{role = client}} = State) ->
- userauth(Msg, State).
+ userauth(Msg, State);
+userauth_keyboard_interactive_info_response(Msg=#ssh_msg_userauth_info_request{},
+ #state{ssh_params = #ssh{role = client}} = State) ->
+ userauth_keyboard_interactive(Msg, State).
%%--------------------------------------------------------------------
-spec connected({#ssh_msg_kexinit{}, binary()}, %%| %% #ssh_msg_kexdh_init{},
@@ -999,7 +1001,8 @@ handle_info({Protocol, Socket, Data}, StateName,
encoded_data_buffer = EncData0,
undecoded_packet_length = RemainingSshPacketLen0} = State0) ->
Encoded = <<EncData0/binary, Data/binary>>,
- case ssh_transport:handle_packet_part(DecData0, Encoded, RemainingSshPacketLen0, Ssh0) of
+ try ssh_transport:handle_packet_part(DecData0, Encoded, RemainingSshPacketLen0, Ssh0)
+ of
{get_more, DecBytes, EncDataRest, RemainingSshPacketLen, Ssh1} ->
{next_state, StateName,
next_packet(State0#state{encoded_data_buffer = EncDataRest,
@@ -1021,7 +1024,22 @@ handle_info({Protocol, Socket, Data}, StateName,
#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
description = "Bad mac",
language = ""},
- handle_disconnect(DisconnectMsg, State0#state{ssh_params=Ssh1})
+ handle_disconnect(DisconnectMsg, State0#state{ssh_params=Ssh1});
+
+ {error, {exceeds_max_size,PacketLen}} ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad packet length "
+ ++ integer_to_list(PacketLen),
+ language = ""},
+ handle_disconnect(DisconnectMsg, State0)
+ catch
+ _:_ ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad packet",
+ language = ""},
+ handle_disconnect(DisconnectMsg, State0)
end;
handle_info({CloseTag, _Socket}, _StateName,
@@ -1392,44 +1410,54 @@ generate_event(<<?BYTE(Byte), _/binary>> = Msg, StateName,
Byte == ?SSH_MSG_CHANNEL_REQUEST;
Byte == ?SSH_MSG_CHANNEL_SUCCESS;
Byte == ?SSH_MSG_CHANNEL_FAILURE ->
- ConnectionMsg = ssh_message:decode(Msg),
- State1 = generate_event_new_state(State0, EncData),
- try ssh_connection:handle_msg(ConnectionMsg, Connection0, Role) of
- {{replies, Replies0}, Connection} ->
- if StateName == connected ->
- Replies = Replies0,
- State2 = State1;
- true ->
- {ConnReplies, Replies} =
- lists:splitwith(fun not_connected_filter/1, Replies0),
- Q = State1#state.event_queue ++ ConnReplies,
- State2 = State1#state{ event_queue = Q }
- end,
- State = send_replies(Replies, State2#state{connection_state = Connection}),
- {next_state, StateName, next_packet(State)};
- {noreply, Connection} ->
- {next_state, StateName, next_packet(State1#state{connection_state = Connection})};
- {disconnect, {_, Reason}, {{replies, Replies}, Connection}} when
- Role == client andalso ((StateName =/= connected) and (not Renegotiation)) ->
- State = send_replies(Replies, State1#state{connection_state = Connection}),
- User ! {self(), not_connected, Reason},
- {stop, {shutdown, normal},
- next_packet(State#state{connection_state = Connection})};
- {disconnect, _Reason, {{replies, Replies}, Connection}} ->
- State = send_replies(Replies, State1#state{connection_state = Connection}),
- {stop, {shutdown, normal}, State#state{connection_state = Connection}}
+ try
+ ssh_message:decode(Msg)
+ of
+ ConnectionMsg ->
+ State1 = generate_event_new_state(State0, EncData),
+ try ssh_connection:handle_msg(ConnectionMsg, Connection0, Role) of
+ {{replies, Replies0}, Connection} ->
+ if StateName == connected ->
+ Replies = Replies0,
+ State2 = State1;
+ true ->
+ {ConnReplies, Replies} =
+ lists:splitwith(fun not_connected_filter/1, Replies0),
+ Q = State1#state.event_queue ++ ConnReplies,
+ State2 = State1#state{ event_queue = Q }
+ end,
+ State = send_replies(Replies, State2#state{connection_state = Connection}),
+ {next_state, StateName, next_packet(State)};
+ {noreply, Connection} ->
+ {next_state, StateName, next_packet(State1#state{connection_state = Connection})};
+ {disconnect, {_, Reason}, {{replies, Replies}, Connection}} when
+ Role == client andalso ((StateName =/= connected) and (not Renegotiation)) ->
+ State = send_replies(Replies, State1#state{connection_state = Connection}),
+ User ! {self(), not_connected, Reason},
+ {stop, {shutdown, normal},
+ next_packet(State#state{connection_state = Connection})};
+ {disconnect, _Reason, {{replies, Replies}, Connection}} ->
+ State = send_replies(Replies, State1#state{connection_state = Connection}),
+ {stop, {shutdown, normal}, State#state{connection_state = Connection}}
+ catch
+ _:Error ->
+ {disconnect, _Reason, {{replies, Replies}, Connection}} =
+ ssh_connection:handle_msg(
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
+ description = "Internal error",
+ language = "en"}, Connection0, Role),
+ State = send_replies(Replies, State1#state{connection_state = Connection}),
+ {stop, {shutdown, Error}, State#state{connection_state = Connection}}
+ end
+
catch
- _:Error ->
- {disconnect, _Reason, {{replies, Replies}, Connection}} =
- ssh_connection:handle_msg(
- #ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
- description = "Internal error",
- language = "en"}, Connection0, Role),
- State = send_replies(Replies, State1#state{connection_state = Connection}),
- {stop, {shutdown, Error}, State#state{connection_state = Connection}}
+ _:_ ->
+ handle_disconnect(
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad packet received",
+ language = ""}, State0)
end;
-
generate_event(Msg, StateName, State0, EncData) ->
try
Event = ssh_message:decode(set_prefix_if_trouble(Msg,State0)),
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 67a0d29bb8..18037b8461 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -1004,10 +1004,7 @@ handle_packet_part(<<>>, Encrypted0, undefined, #ssh{decrypt = CryptoAlg} = Ssh0
{ok, PacketLen, _, _, _} when PacketLen > ?SSH_MAX_PACKET_SIZE ->
%% far too long message than expected
- throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad packet length "
- ++ integer_to_list(PacketLen),
- language = ""});
+ {error, {exceeds_max_size,PacketLen}};
{ok, PacketLen, Decrypted, Encrypted1,
#ssh{recv_mac_size = MacSize} = Ssh1} ->