Prechádzať zdrojové kódy

Reply to global requests when want_reply is true (#1600)

We currently don't recognise any global requests from the server, but if one is
sent, then per RFC 4253 section 4 we still need to reply when the server expects
one. So send SSH_MSG_REQUEST_FAILURE in this case.
Rob Hague 8 mesiacov pred
rodič
commit
a0c6bac3a7

+ 4 - 6
src/Renci.SshNet/Session.cs

@@ -472,11 +472,6 @@ namespace Renci.SshNet
         /// </summary>
         internal event EventHandler<MessageEventArgs<SuccessMessage>> UserAuthenticationSuccessReceived;
 
-        /// <summary>
-        /// Occurs when <see cref="GlobalRequestMessage"/> message received
-        /// </summary>
-        internal event EventHandler<MessageEventArgs<GlobalRequestMessage>> GlobalRequestReceived;
-
         /// <summary>
         /// Occurs when <see cref="RequestSuccessMessage"/> message received
         /// </summary>
@@ -1681,7 +1676,10 @@ namespace Renci.SshNet
         /// <param name="message"><see cref="GlobalRequestMessage"/> message.</param>
         internal void OnGlobalRequestReceived(GlobalRequestMessage message)
         {
-            GlobalRequestReceived?.Invoke(this, new MessageEventArgs<GlobalRequestMessage>(message));
+            if (message.WantReply)
+            {
+                SendMessage(new RequestFailureMessage());
+            }
         }
 
         /// <summary>

+ 35 - 1
test/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs

@@ -1,5 +1,7 @@
 using System;
 using System.Linq;
+using System.Net.Sockets;
+using System.Text;
 using System.Text.RegularExpressions;
 using System.Threading;
 
@@ -7,6 +9,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
 
 using Moq;
 
+using Renci.SshNet.Messages.Connection;
 using Renci.SshNet.Messages.Transport;
 
 namespace Renci.SshNet.Tests.Classes
@@ -59,7 +62,7 @@ namespace Renci.SshNet.Tests.Classes
 
             ServerListener.BytesReceived += ServerListener_BytesReceived;
 
-            void ServerListener_BytesReceived(byte[] bytesReceived, System.Net.Sockets.Socket socket)
+            void ServerListener_BytesReceived(byte[] bytesReceived, Socket socket)
             {
                 if (bytesReceived.Length > 5 && bytesReceived[5] == 20)
                 {
@@ -106,6 +109,37 @@ namespace Renci.SshNet.Tests.Classes
             Assert.AreEqual(1, ServerBytesReceivedRegister.Count);
         }
 
+        [TestMethod]
+        [DataRow(true)]
+        [DataRow(false)]
+        public void UnknownGlobalRequestWithWantReply(bool wantReply)
+        {
+            Thread.Sleep(100);
+
+            ServerBytesReceivedRegister.Clear();
+
+            var globalRequest =
+                new GlobalRequestMessage(Encoding.ASCII.GetBytes("unknown-request"), wantReply).GetPacket(8, null);
+
+            ServerSocket.Send(globalRequest, 4, globalRequest.Length - 4, SocketFlags.None);
+
+            Thread.Sleep(100);
+
+            if (wantReply)
+            {
+                // Should have sent a failure reply.
+                Assert.AreEqual(1, ServerBytesReceivedRegister.Count);
+                Assert.AreEqual(82, ServerBytesReceivedRegister[0][5], "Expected to have sent SSH_MSG_REQUEST_FAILURE(82)");
+            }
+            else
+            {
+                // Should not have sent any reply.
+                Assert.AreEqual(0, ServerBytesReceivedRegister.Count);
+            }
+
+            Assert.AreEqual(0, ErrorOccurredRegister.Count);
+        }
+
         [TestMethod]
         public void SessionIdShouldReturnExchangeHashCalculatedFromKeyExchangeInitMessage()
         {