Skip to content

Commit a0c6bac

Browse files
authored
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.
1 parent 429f750 commit a0c6bac

File tree

2 files changed

+39
-7
lines changed

2 files changed

+39
-7
lines changed

src/Renci.SshNet/Session.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -472,11 +472,6 @@ public string ClientVersion
472472
/// </summary>
473473
internal event EventHandler<MessageEventArgs<SuccessMessage>> UserAuthenticationSuccessReceived;
474474

475-
/// <summary>
476-
/// Occurs when <see cref="GlobalRequestMessage"/> message received
477-
/// </summary>
478-
internal event EventHandler<MessageEventArgs<GlobalRequestMessage>> GlobalRequestReceived;
479-
480475
/// <summary>
481476
/// Occurs when <see cref="RequestSuccessMessage"/> message received
482477
/// </summary>
@@ -1681,7 +1676,10 @@ internal void OnUserAuthenticationPublicKeyReceived(PublicKeyMessage message)
16811676
/// <param name="message"><see cref="GlobalRequestMessage"/> message.</param>
16821677
internal void OnGlobalRequestReceived(GlobalRequestMessage message)
16831678
{
1684-
GlobalRequestReceived?.Invoke(this, new MessageEventArgs<GlobalRequestMessage>(message));
1679+
if (message.WantReply)
1680+
{
1681+
SendMessage(new RequestFailureMessage());
1682+
}
16851683
}
16861684

16871685
/// <summary>

test/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
using System;
22
using System.Linq;
3+
using System.Net.Sockets;
4+
using System.Text;
35
using System.Text.RegularExpressions;
46
using System.Threading;
57

68
using Microsoft.VisualStudio.TestTools.UnitTesting;
79

810
using Moq;
911

12+
using Renci.SshNet.Messages.Connection;
1013
using Renci.SshNet.Messages.Transport;
1114

1215
namespace Renci.SshNet.Tests.Classes
@@ -59,7 +62,7 @@ public void ShouldNotIncludeStrictKexPseudoAlgorithmInSubsequentKex()
5962

6063
ServerListener.BytesReceived += ServerListener_BytesReceived;
6164

62-
void ServerListener_BytesReceived(byte[] bytesReceived, System.Net.Sockets.Socket socket)
65+
void ServerListener_BytesReceived(byte[] bytesReceived, Socket socket)
6366
{
6467
if (bytesReceived.Length > 5 && bytesReceived[5] == 20)
6568
{
@@ -106,6 +109,37 @@ public void SendMessageShouldSendPacketToServer()
106109
Assert.AreEqual(1, ServerBytesReceivedRegister.Count);
107110
}
108111

112+
[TestMethod]
113+
[DataRow(true)]
114+
[DataRow(false)]
115+
public void UnknownGlobalRequestWithWantReply(bool wantReply)
116+
{
117+
Thread.Sleep(100);
118+
119+
ServerBytesReceivedRegister.Clear();
120+
121+
var globalRequest =
122+
new GlobalRequestMessage(Encoding.ASCII.GetBytes("unknown-request"), wantReply).GetPacket(8, null);
123+
124+
ServerSocket.Send(globalRequest, 4, globalRequest.Length - 4, SocketFlags.None);
125+
126+
Thread.Sleep(100);
127+
128+
if (wantReply)
129+
{
130+
// Should have sent a failure reply.
131+
Assert.AreEqual(1, ServerBytesReceivedRegister.Count);
132+
Assert.AreEqual(82, ServerBytesReceivedRegister[0][5], "Expected to have sent SSH_MSG_REQUEST_FAILURE(82)");
133+
}
134+
else
135+
{
136+
// Should not have sent any reply.
137+
Assert.AreEqual(0, ServerBytesReceivedRegister.Count);
138+
}
139+
140+
Assert.AreEqual(0, ErrorOccurredRegister.Count);
141+
}
142+
109143
[TestMethod]
110144
public void SessionIdShouldReturnExchangeHashCalculatedFromKeyExchangeInitMessage()
111145
{

0 commit comments

Comments
 (0)