ProtocolVersionExchangeTest_ServerResponseContainsNullCharacter.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Text;
  7. using System.Threading;
  8. using Microsoft.VisualStudio.TestTools.UnitTesting;
  9. using Renci.SshNet.Common;
  10. using Renci.SshNet.Connection;
  11. using Renci.SshNet.Tests.Common;
  12. namespace Renci.SshNet.Tests.Classes.Connection
  13. {
  14. [TestClass]
  15. public class ProtocolVersionExchangeTest_ServerResponseContainsNullCharacter
  16. {
  17. private AsyncSocketListener _server;
  18. private ProtocolVersionExchange _protocolVersionExchange;
  19. private string _clientVersion;
  20. private TimeSpan _timeout;
  21. private IPEndPoint _serverEndPoint;
  22. private List<byte> _dataReceivedByServer;
  23. private byte[] _serverIdentification;
  24. private bool _clientDisconnected;
  25. private Socket _client;
  26. private SshConnectionException _actualException;
  27. [TestInitialize]
  28. public void Setup()
  29. {
  30. Arrange();
  31. Act();
  32. }
  33. [TestCleanup]
  34. public void Cleanup()
  35. {
  36. if (_server != null)
  37. {
  38. _server.Dispose();
  39. _server = null;
  40. }
  41. if (_client != null)
  42. {
  43. _client.Shutdown(SocketShutdown.Both);
  44. _client.Close();
  45. _client = null;
  46. }
  47. }
  48. protected void Arrange()
  49. {
  50. _clientVersion = "SSH-2.0-Renci.SshNet.SshClient.0.0.1";
  51. _timeout = TimeSpan.FromSeconds(5);
  52. _serverEndPoint = new IPEndPoint(IPAddress.Loopback, 8122);
  53. _dataReceivedByServer = new List<byte>();
  54. _serverIdentification = Encoding.UTF8.GetBytes("\uD55C!\0\uD55CSSH -2.0-Renci.SshNet.SshClient.0.0.1");
  55. _server = new AsyncSocketListener(_serverEndPoint);
  56. _server.Start();
  57. _server.Connected += socket => socket.Send(_serverIdentification);
  58. _server.BytesReceived += (bytes, socket) =>
  59. {
  60. _dataReceivedByServer.AddRange(bytes);
  61. };
  62. _server.Disconnected += (socket) => _clientDisconnected = true;
  63. _client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  64. _client.Connect(_serverEndPoint);
  65. _protocolVersionExchange = new ProtocolVersionExchange();
  66. }
  67. protected void Act()
  68. {
  69. try
  70. {
  71. _protocolVersionExchange.Start(_clientVersion, _client, _timeout);
  72. Assert.Fail();
  73. }
  74. catch (SshConnectionException ex)
  75. {
  76. _actualException = ex;
  77. }
  78. // Give some time to process all messages
  79. Thread.Sleep(200);
  80. }
  81. [TestMethod]
  82. public void StartShouldHaveThrownSshConnectionException()
  83. {
  84. var expectedMessage = string.Format("The server response contains a null character at position 0x00000005:{0}{0}" +
  85. " 00000000 ED 95 9C 21 00 ...!.{0}{0}" +
  86. "A server must not send a null character before the Protocol Version Exchange is complete.{0}{0}" +
  87. "More information is available here:{0}" +
  88. "https://tools.ietf.org/html/rfc4253#section-4.2",
  89. Environment.NewLine);
  90. Assert.IsNotNull(_actualException);
  91. Assert.IsNull(_actualException.InnerException);
  92. Assert.AreEqual(expectedMessage, _actualException.Message);
  93. }
  94. [TestMethod]
  95. public void ClientIdentificationWasSentToServer()
  96. {
  97. var expected = Encoding.UTF8.GetBytes(_clientVersion);
  98. Assert.AreEqual(expected.Length + 2, _dataReceivedByServer.Count);
  99. Assert.IsTrue(expected.SequenceEqual(_dataReceivedByServer.Take(expected.Length)));
  100. Assert.AreEqual(Session.CarriageReturn, _dataReceivedByServer[_dataReceivedByServer.Count - 2]);
  101. Assert.AreEqual(Session.LineFeed, _dataReceivedByServer[_dataReceivedByServer.Count - 1]);
  102. }
  103. [TestMethod]
  104. public void ClientRemainsConnected()
  105. {
  106. Assert.IsTrue(_client.Connected);
  107. Assert.IsFalse(_clientDisconnected);
  108. }
  109. [TestMethod]
  110. public void ClientHasNotReadPastNullCharacter()
  111. {
  112. var buffer = new byte[1];
  113. var bytesReceived = _client.Receive(buffer);
  114. Assert.AreEqual(1, bytesReceived);
  115. Assert.AreEqual(0xed, buffer[0]);
  116. }
  117. }
  118. }