Skip to content

Commit de06f12

Browse files
committed
Allow for easier troubleshooting of protocol version exchange.
Fixes #751.
1 parent eefcd8f commit de06f12

15 files changed

+1402
-81
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Renci.SshNet.Common;
3+
using System;
4+
5+
namespace Renci.SshNet.Tests.Classes.Common
6+
{
7+
[TestClass]
8+
public class PacketDumpTest
9+
{
10+
[TestMethod]
11+
public void Create_ByteArrayAndIndentLevel_DataIsNull()
12+
{
13+
const byte[] data = null;
14+
15+
try
16+
{
17+
PacketDump.Create(data, 0);
18+
Assert.Fail();
19+
}
20+
catch (ArgumentNullException ex)
21+
{
22+
Assert.IsNull(ex.InnerException);
23+
Assert.AreEqual("data", ex.ParamName);
24+
}
25+
}
26+
27+
[TestMethod]
28+
public void Create_ByteArrayAndIndentLevel_IndentLevelLessThanZero()
29+
{
30+
var data = new byte[0];
31+
32+
try
33+
{
34+
PacketDump.Create(data, -1);
35+
Assert.Fail();
36+
}
37+
catch (ArgumentOutOfRangeException ex)
38+
{
39+
Assert.IsNull(ex.InnerException);
40+
Assert.AreEqual(string.Format("Cannot be less than zero.{0}Parameter name: {1}", Environment.NewLine, ex.ParamName), ex.Message);
41+
Assert.AreEqual("indentLevel", ex.ParamName);
42+
}
43+
}
44+
45+
[TestMethod]
46+
public void Create_ByteArrayAndIndentLevel_DataIsEmpty()
47+
{
48+
var data = new byte[0];
49+
50+
var actual = PacketDump.Create(data, 2);
51+
52+
Assert.AreEqual(string.Empty, actual);
53+
}
54+
55+
[TestMethod]
56+
public void Create_ByteArrayAndIndentLevel_DataIsMultipleOfLineWidth_IndentLevelTwo()
57+
{
58+
var data = new byte[]
59+
{
60+
0x07, 0x00, 0x1f, 0x65, 0x20, 0x62, 0x09, 0x44, 0x7f, 0x0d, 0x0a, 0x36, 0x80, 0x53, 0x53, 0x48,
61+
0x2e, 0x4e, 0x45, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30, 0x20, 0xf6, 0x7a, 0x32, 0x7f, 0x1f, 0x7e
62+
};
63+
var expected = " 00000000 07 00 1F 65 20 62 09 44 7F 0D 0A 36 80 53 53 48 ...e b.D...6.SSH" +
64+
Environment.NewLine +
65+
" 00000010 2E 4E 45 54 20 32 30 32 30 20 F6 7A 32 7F 1F 7E .NET 2020 .z2..~";
66+
67+
var actual = PacketDump.Create(data, 2);
68+
69+
Assert.AreEqual(expected, actual);
70+
}
71+
72+
[TestMethod]
73+
public void Create_ByteArrayAndIndentLevel_DataIsMultipleOfLineWidth_IndentLevelZero()
74+
{
75+
var data = new byte[]
76+
{
77+
0x07, 0x00, 0x1f, 0x65, 0x20, 0x62, 0x09, 0x44, 0x7f, 0x0d, 0x0a, 0x36, 0x80, 0x53, 0x53, 0x48,
78+
0x2e, 0x4e, 0x45, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30, 0x20, 0xf6, 0x7a, 0x32, 0x7f, 0x1f, 0x7e
79+
};
80+
var expected = "00000000 07 00 1F 65 20 62 09 44 7F 0D 0A 36 80 53 53 48 ...e b.D...6.SSH" +
81+
Environment.NewLine +
82+
"00000010 2E 4E 45 54 20 32 30 32 30 20 F6 7A 32 7F 1F 7E .NET 2020 .z2..~";
83+
84+
var actual = PacketDump.Create(data, 0);
85+
86+
Assert.AreEqual(expected, actual);
87+
}
88+
89+
[TestMethod]
90+
public void Create_ByteArrayAndIndentLevel_DataIsLineWith()
91+
{
92+
var data = new byte[]
93+
{
94+
0x07, 0x00, 0x1f, 0x65, 0x20, 0x62, 0x09, 0x44, 0x7f, 0x0d, 0x0a, 0x36, 0x80, 0x53, 0x53, 0x48
95+
};
96+
var expected = " 00000000 07 00 1F 65 20 62 09 44 7F 0D 0A 36 80 53 53 48 ...e b.D...6.SSH";
97+
98+
var actual = PacketDump.Create(data, 2);
99+
100+
Assert.AreEqual(expected, actual);
101+
}
102+
103+
[TestMethod]
104+
public void Create_ByteArrayAndIndentLevel_DataIsLessThanLineWith()
105+
{
106+
var data = new byte[]
107+
{
108+
0x07, 0x00, 0x1f, 0x65, 0x20, 0x62, 0x09, 0x44, 0x7f, 0x0d, 0x0a, 0x36, 0x80, 0x53
109+
};
110+
var expected = " 00000000 07 00 1F 65 20 62 09 44 7F 0D 0A 36 80 53 ...e b.D...6.S";
111+
112+
var actual = PacketDump.Create(data, 2);
113+
114+
Assert.AreEqual(expected, actual);
115+
}
116+
117+
[TestMethod]
118+
public void Create_ByteArrayAndIndentLevel_DataIsGreaterThanLineWidthButLessThanMultipleOfLineWidth()
119+
{
120+
var data = new byte[]
121+
{
122+
0x07, 0x00, 0x1f, 0x65, 0x20, 0x62, 0x09, 0x44, 0x7f, 0x0d, 0x0a, 0x36, 0x80, 0x53, 0x53, 0x48,
123+
0x2e, 0x4e, 0x45, 0x54
124+
};
125+
var expected = " 00000000 07 00 1F 65 20 62 09 44 7F 0D 0A 36 80 53 53 48 ...e b.D...6.SSH" +
126+
Environment.NewLine +
127+
" 00000010 2E 4E 45 54 .NET";
128+
129+
var actual = PacketDump.Create(data, 2);
130+
131+
Assert.AreEqual(expected, actual);
132+
}
133+
134+
[TestMethod]
135+
public void Create_ByteArrayAndIndentLevel_DataIsGreaterThanMultipleOfLineWidth()
136+
{
137+
var data = new byte[]
138+
{
139+
0x07, 0x00, 0x1f, 0x65, 0x20, 0x62, 0x09, 0x44, 0x7f, 0x0d, 0x0a, 0x36, 0x80, 0x53, 0x53, 0x48,
140+
0x2e, 0x4e, 0x45, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30, 0x20, 0xf6, 0x7a, 0x32, 0x7f, 0x1f, 0x7e,
141+
0x78, 0x54, 0x00, 0x52
142+
};
143+
var expected = " 00000000 07 00 1F 65 20 62 09 44 7F 0D 0A 36 80 53 53 48 ...e b.D...6.SSH" +
144+
Environment.NewLine +
145+
" 00000010 2E 4E 45 54 20 32 30 32 30 20 F6 7A 32 7F 1F 7E .NET 2020 .z2..~" +
146+
Environment.NewLine +
147+
" 00000020 78 54 00 52 xT.R";
148+
149+
var actual = PacketDump.Create(data, 2);
150+
151+
Assert.AreEqual(expected, actual);
152+
153+
}
154+
}
155+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Renci.SshNet.Common;
3+
using Renci.SshNet.Connection;
4+
using Renci.SshNet.Tests.Common;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Net;
8+
using System.Net.Sockets;
9+
10+
namespace Renci.SshNet.Tests.Classes
11+
{
12+
[TestClass]
13+
public class ProtocolVersionExchangeTest_ConnectionClosedByServer_NoDataSentByServer
14+
{
15+
private AsyncSocketListener _server;
16+
private ProtocolVersionExchange _protocolVersionExchange;
17+
private string _clientVersion;
18+
private TimeSpan _timeout;
19+
private IPEndPoint _serverEndPoint;
20+
private List<byte> _dataReceivedByServer;
21+
private bool _clientDisconnected;
22+
private Socket _client;
23+
private SshConnectionException _actualException;
24+
25+
[TestInitialize]
26+
public void Setup()
27+
{
28+
Arrange();
29+
Act();
30+
}
31+
32+
[TestCleanup]
33+
public void Cleanup()
34+
{
35+
if (_server != null)
36+
{
37+
_server.Dispose();
38+
_server = null;
39+
}
40+
41+
if (_client != null)
42+
{
43+
_client.Shutdown(SocketShutdown.Both);
44+
_client.Close();
45+
_client = null;
46+
}
47+
}
48+
49+
protected void Arrange()
50+
{
51+
_clientVersion = "\uD55C";
52+
_timeout = TimeSpan.FromSeconds(5);
53+
_serverEndPoint = new IPEndPoint(IPAddress.Loopback, 8122);
54+
_dataReceivedByServer = new List<byte>();
55+
56+
_server = new AsyncSocketListener(_serverEndPoint);
57+
_server.Start();
58+
_server.BytesReceived += (bytes, socket) =>
59+
{
60+
_dataReceivedByServer.AddRange(bytes);
61+
socket.Shutdown(SocketShutdown.Both);
62+
};
63+
_server.Disconnected += (socket) => _clientDisconnected = true;
64+
65+
_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
66+
_client.Connect(_serverEndPoint);
67+
68+
_protocolVersionExchange = new ProtocolVersionExchange();
69+
}
70+
71+
protected void Act()
72+
{
73+
try
74+
{
75+
_protocolVersionExchange.Start(_clientVersion, _client, _timeout);
76+
Assert.Fail();
77+
}
78+
catch (SshConnectionException ex)
79+
{
80+
_actualException = ex;
81+
}
82+
}
83+
84+
[TestMethod]
85+
public void StartShouldHaveThrownSshConnectionException()
86+
{
87+
Assert.IsNotNull(_actualException);
88+
Assert.IsNull(_actualException.InnerException);
89+
Assert.AreEqual("Server response does not contain SSH protocol identification. Connection to remote server was closed before any data was received.", _actualException.Message);
90+
}
91+
92+
[TestMethod]
93+
public void ClientIdentificationWasSentToServer()
94+
{
95+
Assert.AreEqual(5, _dataReceivedByServer.Count);
96+
97+
Assert.AreEqual(0xed, _dataReceivedByServer[0]);
98+
Assert.AreEqual(0x95, _dataReceivedByServer[1]);
99+
Assert.AreEqual(0x9c, _dataReceivedByServer[2]);
100+
Assert.AreEqual(0x0d, _dataReceivedByServer[3]);
101+
Assert.AreEqual(0x0a, _dataReceivedByServer[4]);
102+
}
103+
104+
[TestMethod]
105+
public void ConnectionIsClosedByServer()
106+
{
107+
Assert.IsTrue(_client.Connected);
108+
Assert.IsFalse(_clientDisconnected);
109+
110+
var bytesReceived = _client.Receive(new byte[1]);
111+
Assert.AreEqual(0, bytesReceived);
112+
113+
Assert.IsTrue(_client.Connected);
114+
Assert.IsFalse(_clientDisconnected);
115+
}
116+
}
117+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Renci.SshNet.Common;
3+
using Renci.SshNet.Connection;
4+
using Renci.SshNet.Tests.Common;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
using System.Net;
9+
using System.Net.Sockets;
10+
using System.Text;
11+
using System.Threading;
12+
13+
namespace Renci.SshNet.Tests.Classes
14+
{
15+
[TestClass]
16+
public class ProtocolVersionExchangeTest_ServerDoesNotRespondWithIdentificationStringBeforeTimeout
17+
{
18+
private AsyncSocketListener _server;
19+
private ProtocolVersionExchange _protocolVersionExchange;
20+
private string _clientVersion;
21+
private TimeSpan _timeout;
22+
private IPEndPoint _serverEndPoint;
23+
private List<byte> _dataReceivedByServer;
24+
private byte[] _serverIdentification;
25+
private bool _clientDisconnected;
26+
private Socket _client;
27+
private SshIdentification _actual;
28+
private SshOperationTimeoutException _actualException;
29+
30+
[TestInitialize]
31+
public void Setup()
32+
{
33+
Arrange();
34+
Act();
35+
}
36+
37+
[TestCleanup]
38+
public void Cleanup()
39+
{
40+
if (_server != null)
41+
{
42+
_server.Dispose();
43+
_server = null;
44+
}
45+
46+
if (_client != null)
47+
{
48+
_client.Shutdown(SocketShutdown.Both);
49+
_client.Close();
50+
_client = null;
51+
}
52+
}
53+
54+
protected void Arrange()
55+
{
56+
_clientVersion = "SSH-2.0-Renci.SshNet.SshClient.0.0.1";
57+
_timeout = TimeSpan.FromMilliseconds(200);
58+
_serverEndPoint = new IPEndPoint(IPAddress.Loopback, 8122);
59+
_dataReceivedByServer = new List<byte>();
60+
_serverIdentification = Encoding.UTF8.GetBytes("SSH-Zero-OurSSHAppliance\r\n!");
61+
62+
_server = new AsyncSocketListener(_serverEndPoint);
63+
_server.Start();
64+
_server.BytesReceived += (bytes, socket) =>
65+
{
66+
_dataReceivedByServer.AddRange(bytes);
67+
socket.Send(Encoding.UTF8.GetBytes("Welcome!\r\n"));
68+
Thread.Sleep(_timeout.Add(TimeSpan.FromMilliseconds(50)));
69+
socket.Shutdown(SocketShutdown.Both);
70+
};
71+
_server.Disconnected += (socket) => _clientDisconnected = true;
72+
73+
_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
74+
_client.Connect(_serverEndPoint);
75+
76+
_protocolVersionExchange = new ProtocolVersionExchange();
77+
}
78+
79+
protected void Act()
80+
{
81+
try
82+
{
83+
_protocolVersionExchange.Start(_clientVersion, _client, _timeout);
84+
Assert.Fail();
85+
}
86+
catch (SshOperationTimeoutException ex)
87+
{
88+
_actualException = ex;
89+
}
90+
}
91+
92+
[TestMethod]
93+
public void StartShouldHaveThrownSshOperationTimeoutException()
94+
{
95+
Assert.IsNotNull(_actualException);
96+
Assert.IsNull(_actualException.InnerException);
97+
Assert.AreEqual(string.Format("Socket read operation has timed out after {0} milliseconds.", _timeout.TotalMilliseconds), _actualException.Message);
98+
}
99+
100+
[TestMethod]
101+
public void ClientIdentificationWasSentToServer()
102+
{
103+
var expected = Encoding.UTF8.GetBytes(_clientVersion);
104+
105+
Assert.AreEqual(expected.Length + 2, _dataReceivedByServer.Count);
106+
107+
Assert.IsTrue(expected.SequenceEqual(_dataReceivedByServer.Take(expected.Length)));
108+
Assert.AreEqual(Session.CarriageReturn, _dataReceivedByServer[_dataReceivedByServer.Count - 2]);
109+
Assert.AreEqual(Session.LineFeed, _dataReceivedByServer[_dataReceivedByServer.Count - 1]);
110+
}
111+
112+
[TestMethod]
113+
public void ConnectionIsClosedByServer()
114+
{
115+
Assert.IsTrue(_client.Connected);
116+
Assert.IsFalse(_clientDisconnected);
117+
118+
var bytesReceived = _client.Receive(new byte[1]);
119+
Assert.AreEqual(0, bytesReceived);
120+
121+
Assert.IsTrue(_client.Connected);
122+
Assert.IsFalse(_clientDisconnected);
123+
}
124+
}
125+
}

0 commit comments

Comments
 (0)