From bb1a28deb139c34e2425e08e11f55480f5de6526 Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Mon, 7 Dec 2015 19:39:28 +0100
Subject: ssh: fix error for data fields errors

---
 lib/ssh/src/ssh_connection_handler.erl | 80 +++++++++++++++++++---------------
 1 file changed, 45 insertions(+), 35 deletions(-)

(limited to 'lib')

diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 0eaeba26a9..f082db136c 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1408,44 +1408,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)),
-- 
cgit v1.2.3