Origin: https://github.com/erlang/otp/commit/c9e4b22bc4b1faffef07c94ef8e4751b1a36870d
Reviewed-by: Sylvain Beucler <beuc@debian.org>
Last-Update: 2025-04-22

From c9e4b22bc4b1faffef07c94ef8e4751b1a36870d Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Thu, 14 Jan 2021 17:25:39 +0100
Subject: [PATCH] ssh: Add 4th argument (#ssh) to ssh_connection:handl_msg

to be able to use the hello-string whens settting pty options.
---
 lib/ssh/src/ssh_connection.erl         | 76 +++++++++++++-------------
 lib/ssh/src/ssh_connection_handler.erl |  4 +-
 2 files changed, 40 insertions(+), 40 deletions(-)

Index: erlang-22.2.7+dfsg/lib/ssh/src/ssh_connection.erl
===================================================================
--- erlang-22.2.7+dfsg.orig/lib/ssh/src/ssh_connection.erl
+++ erlang-22.2.7+dfsg/lib/ssh/src/ssh_connection.erl
@@ -42,7 +42,7 @@
 
 %% Internal SSH application API
 -export([channel_data/5,
-         handle_msg/3,
+         handle_msg/4,
          handle_stop/1,
 
 	 channel_adjust_window_msg/2,
@@ -450,7 +450,7 @@ handle_msg(#ssh_msg_channel_open_confirm
 					      sender_channel = RemoteId,
 					      initial_window_size = WindowSz,
 					      maximum_packet_size = PacketSz}, 
-	   #connection{channel_cache = Cache} = Connection0, _) ->
+	   #connection{channel_cache = Cache} = Connection0, _, _SSH) ->
     
     #channel{remote_id = undefined} = Channel =
 	ssh_client_channel:cache_lookup(Cache, ChannelId), 
@@ -468,22 +468,22 @@ handle_msg(#ssh_msg_channel_open_failure
 					 reason = Reason,
 					 description = Descr,
 					 lang = Lang},  
-	   #connection{channel_cache = Cache} = Connection0, _) ->
+	   #connection{channel_cache = Cache} = Connection0, _, _SSH) ->
     Channel = ssh_client_channel:cache_lookup(Cache, ChannelId), 
     ssh_client_channel:cache_delete(Cache, ChannelId),
     reply_msg(Channel, Connection0, {open_error, Reason, Descr, Lang});
 
-handle_msg(#ssh_msg_channel_success{recipient_channel = ChannelId}, Connection, _) ->
+handle_msg(#ssh_msg_channel_success{recipient_channel = ChannelId}, Connection, _, _SSH) ->
     reply_msg(ChannelId, Connection, success);
 
-handle_msg(#ssh_msg_channel_failure{recipient_channel = ChannelId}, Connection, _) ->
+handle_msg(#ssh_msg_channel_failure{recipient_channel = ChannelId}, Connection, _, _SSH) ->
     reply_msg(ChannelId, Connection, failure);
 
-handle_msg(#ssh_msg_channel_eof{recipient_channel = ChannelId}, Connection, _) ->
+handle_msg(#ssh_msg_channel_eof{recipient_channel = ChannelId}, Connection, _, _SSH) ->
     reply_msg(ChannelId, Connection, {eof, ChannelId});
    
 handle_msg(#ssh_msg_channel_close{recipient_channel = ChannelId},   
-	   #connection{channel_cache = Cache} = Connection0, _) ->
+	   #connection{channel_cache = Cache} = Connection0, _, _SSH) ->
 
 	case ssh_client_channel:cache_lookup(Cache, ChannelId) of
 		#channel{sent_close = Closed, remote_id = RemoteId,
@@ -516,18 +516,18 @@ handle_msg(#ssh_msg_channel_close{recipi
 
 handle_msg(#ssh_msg_channel_data{recipient_channel = ChannelId,
 				 data = Data}, 
-	   Connection, _) ->
+	   Connection, _, _SSH) ->
     channel_data_reply_msg(ChannelId, Connection, 0, Data);
 
 handle_msg(#ssh_msg_channel_extended_data{recipient_channel = ChannelId,
 					  data_type_code = DataType,
 					  data = Data}, 
-	   Connection, _) ->
+	   Connection, _, _SSH) ->
     channel_data_reply_msg(ChannelId, Connection, DataType, Data);
 
 handle_msg(#ssh_msg_channel_window_adjust{recipient_channel = ChannelId,
 					  bytes_to_add = Add}, 
-	   #connection{channel_cache = Cache} = Connection, _) ->
+	   #connection{channel_cache = Cache} = Connection, _, _SSH) ->
     #channel{send_window_size = Size, remote_id = RemoteId} = 
 	Channel0 = ssh_client_channel:cache_lookup(Cache, ChannelId), 
     
@@ -546,7 +546,7 @@ handle_msg(#ssh_msg_channel_open{channel
 				 initial_window_size = WindowSz,
 				 maximum_packet_size = PacketSz}, 
 	   #connection{options = SSHopts} = Connection0,
-	   server) ->
+	   server, _SSH) ->
     MinAcceptedPackSz =
         ?GET_OPT(minimal_remote_max_packet_size, SSHopts),
     
@@ -574,7 +574,7 @@ handle_msg(#ssh_msg_channel_open{channel
 handle_msg(#ssh_msg_channel_open{channel_type = "session",
 				 sender_channel = RemoteId}, 
 	   Connection,
-	   client) ->
+	   client, _SSH) ->
     %% Client implementations SHOULD reject any session channel open
     %% requests to make it more difficult for a corrupt server to attack the
     %% client. See See RFC 4254 6.1.
@@ -583,7 +583,7 @@ handle_msg(#ssh_msg_channel_open{channel
 				       "Connection refused", "en"),
     {[{connection_reply, FailMsg}], Connection};
 
-handle_msg(#ssh_msg_channel_open{sender_channel = RemoteId}, Connection, _) ->
+handle_msg(#ssh_msg_channel_open{sender_channel = RemoteId}, Connection, _, _SSH) ->
     FailMsg = channel_open_failure_msg(RemoteId, 
 				       ?SSH_OPEN_ADMINISTRATIVELY_PROHIBITED,
 				       "Not allowed", "en"),
@@ -592,7 +592,7 @@ handle_msg(#ssh_msg_channel_open{sender_
 handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId,
 				    request_type = "exit-status",
 				    data = Data},
-           Connection, _) ->
+           Connection, _, _SSH) ->
     <<?UINT32(Status)>> = Data,
     reply_msg(ChannelId, Connection, {exit_status, ChannelId, Status});
 
@@ -600,7 +600,7 @@ handle_msg(#ssh_msg_channel_request{reci
 				    request_type = "exit-signal",
 				    want_reply = false,
 				    data = Data},  
-           #connection{channel_cache = Cache} = Connection0, _) ->
+           #connection{channel_cache = Cache} = Connection0, _, _SSH) ->
     <<?DEC_BIN(SigName, _SigLen),
       ?BOOLEAN(_Core), 
       ?DEC_BIN(Err, _ErrLen),
@@ -619,7 +619,7 @@ handle_msg(#ssh_msg_channel_request{reci
 				    request_type = "xon-xoff",
 				    want_reply = false,
 				    data = Data},
-           Connection, _) ->
+           Connection, _, _SSH) ->
     <<?BOOLEAN(CDo)>> = Data,
     reply_msg(ChannelId, Connection, {xon_xoff, ChannelId, CDo=/= 0});
 
@@ -627,7 +627,7 @@ handle_msg(#ssh_msg_channel_request{reci
 				    request_type = "window-change",
 				    want_reply = false,
 				    data = Data}, 
-           Connection0, _) ->
+           Connection0, _, _SSH) ->
     <<?UINT32(Width),?UINT32(Height),
       ?UINT32(PixWidth), ?UINT32(PixHeight)>> = Data,
     reply_msg(ChannelId, Connection0, {window_change, ChannelId,
@@ -637,7 +637,7 @@ handle_msg(#ssh_msg_channel_request{reci
 handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId,
 				    request_type = "signal",
 				    data = Data}, 
-           Connection0, _) ->
+           Connection0, _, _SSH) ->
     <<?DEC_BIN(SigName, _SigLen)>> = Data,
     reply_msg(ChannelId, Connection0, {signal, ChannelId,
                                        binary_to_list(SigName)});
@@ -646,7 +646,7 @@ handle_msg(#ssh_msg_channel_request{reci
 				    request_type = "subsystem",
 				    want_reply = WantReply,
 				    data = Data},
-	   #connection{channel_cache = Cache} = Connection, server) ->
+	   #connection{channel_cache = Cache} = Connection, server, _SSH) ->
     <<?DEC_BIN(SsName,_SsLen)>> = Data,
     #channel{remote_id=RemoteId} = Channel = 
 	ssh_client_channel:cache_lookup(Cache, ChannelId), 
@@ -668,7 +668,7 @@ handle_msg(#ssh_msg_channel_request{reci
     {[{connection_reply,Reply}], Connection};
 
 handle_msg(#ssh_msg_channel_request{request_type = "subsystem"},
-	   Connection, client) ->
+	   Connection, client, _SSH) ->
     %% The client SHOULD ignore subsystem requests. See RFC 4254 6.5.
     {[], Connection};
 
@@ -676,7 +676,7 @@ handle_msg(#ssh_msg_channel_request{reci
 				    request_type = "pty-req",
 				    want_reply = WantReply,
 				    data = Data},
-	   Connection, server) ->
+	   Connection, server, _SSH) ->
     <<?DEC_BIN(BTermName,_TermLen),
       ?UINT32(Width),?UINT32(Height),
       ?UINT32(PixWidth), ?UINT32(PixHeight),
@@ -688,19 +688,19 @@ handle_msg(#ssh_msg_channel_request{reci
 		   {pty, ChannelId, WantReply, PtyRequest});
 
 handle_msg(#ssh_msg_channel_request{request_type = "pty-req"},
-	   Connection, client) ->
+	   Connection, client, _SSH) ->
     %% The client SHOULD ignore pty requests. See RFC 4254 6.2.
     {[], Connection};
 
 handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId,
 				    request_type = "shell",
 				    want_reply = WantReply},
-	   Connection, server) ->
+	   Connection, server, _SSH) ->
     handle_cli_msg(Connection, ChannelId,
 		   {shell, ChannelId, WantReply});
  
 handle_msg(#ssh_msg_channel_request{request_type = "shell"},
-	   Connection, client) ->
+	   Connection, client, _SSH) ->
     %% The client SHOULD ignore shell requests. See RFC 4254 6.5.
     {[], Connection};
 
@@ -708,13 +708,13 @@ handle_msg(#ssh_msg_channel_request{reci
 				    request_type = "exec",
 				    want_reply = WantReply,
 				    data = Data},
-	   Connection, server) ->
+	   Connection, server, _SSH) ->
     <<?DEC_BIN(Command, _Len)>> = Data,
     handle_cli_msg(Connection, ChannelId,
 		   {exec, ChannelId, WantReply, binary_to_list(Command)});
 	
 handle_msg(#ssh_msg_channel_request{request_type = "exec"},
-	   Connection, client) ->
+	   Connection, client, _SSH) ->
     %% The client SHOULD ignore exec requests. See RFC 4254 6.5.
     {[], Connection};
 
@@ -722,20 +722,20 @@ handle_msg(#ssh_msg_channel_request{reci
   				    request_type = "env",
   				    want_reply = WantReply,
   				    data = Data}, 
-	   Connection, server) ->
+	   Connection, server, _SSH) ->
     <<?DEC_BIN(Var,_VarLen), ?DEC_BIN(Value,_ValLen)>> = Data,
     handle_cli_msg(Connection, ChannelId,
  		   {env, ChannelId, WantReply, Var, Value});
 
 handle_msg(#ssh_msg_channel_request{request_type = "env"},
-	   Connection, client) ->
+	   Connection, client, _SSH) ->
     %% The client SHOULD ignore env requests. 
     {[], Connection};
 
 handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId,
 				    request_type = _Other,
 				    want_reply = WantReply},
-	   #connection{channel_cache = Cache} = Connection, _) ->
+	   #connection{channel_cache = Cache} = Connection, _, _SSH) ->
     if WantReply == true ->
 		case ssh_client_channel:cache_lookup(Cache, ChannelId) of
 		    #channel{remote_id = RemoteId}  -> 
@@ -750,7 +750,7 @@ handle_msg(#ssh_msg_channel_request{reci
 
 handle_msg(#ssh_msg_global_request{name = _Type,
 				   want_reply = WantReply,
-				   data = _Data}, Connection, _) ->
+				   data = _Data}, Connection, _, _SSH) ->
     if WantReply == true ->
 	    FailMsg = request_failure_msg(),
 	    {[{connection_reply, FailMsg}], Connection};
@@ -759,18 +759,18 @@ handle_msg(#ssh_msg_global_request{name
     end;
 
 handle_msg(#ssh_msg_request_failure{},
-	   #connection{requests = [{_, From} | Rest]} = Connection, _) ->
+	   #connection{requests = [{_, From} | Rest]} = Connection, _, _SSH) ->
     {[{channel_request_reply, From, {failure, <<>>}}],
      Connection#connection{requests = Rest}};
 
 handle_msg(#ssh_msg_request_success{data = Data},
-	   #connection{requests = [{_, From} | Rest]} = Connection, _) ->
+	   #connection{requests = [{_, From} | Rest]} = Connection, _, _SSH) ->
     {[{channel_request_reply, From, {success, Data}}],
      Connection#connection{requests = Rest}};
 
 handle_msg(#ssh_msg_disconnect{code = Code,
 			       description = Description},
-	   Connection, _) ->
+	   Connection, _, _SSH) ->
     {disconnect, {Code, Description}, handle_stop(Connection)}.
 
 
Index: erlang-22.2.7+dfsg/lib/ssh/src/ssh_connection_handler.erl
===================================================================
--- erlang-22.2.7+dfsg.orig/lib/ssh/src/ssh_connection_handler.erl
+++ erlang-22.2.7+dfsg/lib/ssh/src/ssh_connection_handler.erl
@@ -1006,7 +1006,7 @@ handle_event(_, {#ssh_msg_kexinit{},_},
 
 handle_event(_, #ssh_msg_disconnect{description=Desc} = Msg, StateName, D0) ->
     {disconnect, _, RepliesCon} =
-	ssh_connection:handle_msg(Msg, D0#data.connection_state, role(StateName)),
+	ssh_connection:handle_msg(Msg, D0#data.connection_state, role(StateName), D0#data.ssh_params),
     {Actions,D} = send_replies(RepliesCon, D0),
     disconnect_fun("Received disconnect: "++Desc, D),
     {stop_and_reply, {shutdown,Desc}, Actions, D};
@@ -1036,7 +1036,7 @@ handle_event(internal, {conn_msg,Msg}, S
                                                         event_queue = Qev0} = D0) ->
     Role = role(StateName),
     Rengotation = renegotiation(StateName),
-    try ssh_connection:handle_msg(Msg, Connection0, Role) of
+    try ssh_connection:handle_msg(Msg, Connection0, Role, D0#data.ssh_params) of
 	{disconnect, Reason0, RepliesConn} ->
             {Repls, D} = send_replies(RepliesConn, D0),
             case {Reason0,Role} of
