mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 01:05:42 +00:00
Immediately sent identification string when connection is established.
Fixes #689.
This commit is contained in:
@@ -3,9 +3,11 @@ using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using Renci.SshNet.Common;
|
||||
using Renci.SshNet.Messages.Transport;
|
||||
using Renci.SshNet.Tests.Common;
|
||||
using Renci.SshNet.Tests.Properties;
|
||||
|
||||
@@ -98,6 +100,53 @@ namespace Renci.SshNet.Tests.Classes
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ConnectShouldImmediatelySendIdentificationStringWhenConnectionHasBeenEstablised()
|
||||
{
|
||||
var serverEndPoint = new IPEndPoint(IPAddress.Loopback, 8122);
|
||||
var connectionInfo = CreateConnectionInfo(serverEndPoint, TimeSpan.FromSeconds(5));
|
||||
|
||||
using (var serverStub = new AsyncSocketListener(serverEndPoint))
|
||||
{
|
||||
serverStub.Connected += socket =>
|
||||
{
|
||||
var identificationBytes = new byte[2048];
|
||||
var bytesReceived = socket.Receive(identificationBytes);
|
||||
|
||||
if (bytesReceived > 0)
|
||||
{
|
||||
var identificationSttring = Encoding.ASCII.GetString(identificationBytes, 0, bytesReceived);
|
||||
Console.WriteLine("STRING=" + identificationSttring);
|
||||
Console.WriteLine("DONE");
|
||||
|
||||
socket.Send(Encoding.ASCII.GetBytes("\r\n"));
|
||||
socket.Send(Encoding.ASCII.GetBytes("WELCOME banner\r\n"));
|
||||
socket.Send(Encoding.ASCII.GetBytes("SSH-666-SshStub\r\n"));
|
||||
}
|
||||
|
||||
socket.Shutdown(SocketShutdown.Send);
|
||||
};
|
||||
serverStub.Start();
|
||||
|
||||
using (var session = new Session(connectionInfo, _serviceFactoryMock.Object))
|
||||
{
|
||||
try
|
||||
{
|
||||
session.Connect();
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (SshConnectionException ex)
|
||||
{
|
||||
Assert.IsNull(ex.InnerException);
|
||||
Assert.AreEqual("Server version '666' is not supported.", ex.Message);
|
||||
|
||||
Assert.AreEqual("SSH-666-SshStub", connectionInfo.ServerVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void ConnectShouldSupportProtocolIdentificationStringThatDoesNotEndWithCrlf()
|
||||
{
|
||||
|
||||
+22
-18
@@ -577,14 +577,14 @@ namespace Renci.SshNet
|
||||
|
||||
lock (this)
|
||||
{
|
||||
// If connected don't connect again
|
||||
// If connected don't connect again
|
||||
if (IsConnected)
|
||||
return;
|
||||
|
||||
// reset connection specific information
|
||||
// Reset connection specific information
|
||||
Reset();
|
||||
|
||||
// Build list of available messages while connecting
|
||||
// Build list of available messages while connecting
|
||||
_sshMessageFactory = new SshMessageFactory();
|
||||
|
||||
switch (ConnectionInfo.ProxyType)
|
||||
@@ -606,10 +606,14 @@ namespace Renci.SshNet
|
||||
break;
|
||||
}
|
||||
|
||||
// Immediately send the identification string since the spec states both sides MUST send an identification string
|
||||
// when the connection has been established
|
||||
SocketAbstraction.Send(_socket, Encoding.UTF8.GetBytes(string.Format(CultureInfo.InvariantCulture, "{0}\x0D\x0A", ClientVersion)));
|
||||
|
||||
Match versionMatch;
|
||||
|
||||
// Get server version from the server,
|
||||
// ignore text lines which are sent before if any
|
||||
// Get server version from the server,
|
||||
// ignore text lines which are sent before if any
|
||||
while (true)
|
||||
{
|
||||
var serverVersion = SocketReadLine(_socket, ConnectionInfo.Timeout);
|
||||
@@ -623,11 +627,11 @@ namespace Renci.SshNet
|
||||
}
|
||||
}
|
||||
|
||||
// Set connection versions
|
||||
// Set connection versions
|
||||
ConnectionInfo.ServerVersion = ServerVersion;
|
||||
ConnectionInfo.ClientVersion = ClientVersion;
|
||||
|
||||
// Get server SSH version
|
||||
// Get server SSH version
|
||||
var version = versionMatch.Result("${protoversion}");
|
||||
|
||||
var softwareName = versionMatch.Result("${softwareversion}");
|
||||
@@ -639,9 +643,7 @@ namespace Renci.SshNet
|
||||
throw new SshConnectionException(string.Format(CultureInfo.CurrentCulture, "Server version '{0}' is not supported.", version), DisconnectReason.ProtocolVersionNotSupported);
|
||||
}
|
||||
|
||||
SocketAbstraction.Send(_socket, Encoding.UTF8.GetBytes(string.Format(CultureInfo.InvariantCulture, "{0}\x0D\x0A", ClientVersion)));
|
||||
|
||||
// Register Transport response messages
|
||||
// Register Transport response messages
|
||||
RegisterMessage("SSH_MSG_DISCONNECT");
|
||||
RegisterMessage("SSH_MSG_IGNORE");
|
||||
RegisterMessage("SSH_MSG_UNIMPLEMENTED");
|
||||
@@ -650,29 +652,29 @@ namespace Renci.SshNet
|
||||
RegisterMessage("SSH_MSG_KEXINIT");
|
||||
RegisterMessage("SSH_MSG_NEWKEYS");
|
||||
|
||||
// Some server implementations might sent this message first, prior establishing encryption algorithm
|
||||
// Some server implementations might sent this message first, prior to establishing encryption algorithm
|
||||
RegisterMessage("SSH_MSG_USERAUTH_BANNER");
|
||||
|
||||
// mark the message listener threads as started
|
||||
// Mark the message listener threads as started
|
||||
_messageListenerCompleted.Reset();
|
||||
|
||||
// Start incoming request listener
|
||||
// Start incoming request listener
|
||||
ThreadAbstraction.ExecuteThread(() => MessageListener());
|
||||
|
||||
// Wait for key exchange to be completed
|
||||
// Wait for key exchange to be completed
|
||||
WaitOnHandle(_keyExchangeCompletedWaitHandle);
|
||||
|
||||
// If sessionId is not set then its not connected
|
||||
// If sessionId is not set then its not connected
|
||||
if (SessionId == null)
|
||||
{
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
// Request user authorization service
|
||||
// Request user authorization service
|
||||
SendMessage(new ServiceRequestMessage(ServiceName.UserAuthentication));
|
||||
|
||||
// Wait for service to be accepted
|
||||
// Wait for service to be accepted
|
||||
WaitOnHandle(_serviceAccepted);
|
||||
|
||||
if (string.IsNullOrEmpty(ConnectionInfo.Username))
|
||||
@@ -687,7 +689,7 @@ namespace Renci.SshNet
|
||||
ConnectionInfo.Authenticate(this, _serviceFactory);
|
||||
_isAuthenticated = true;
|
||||
|
||||
// Register Connection messages
|
||||
// Register Connection messages
|
||||
RegisterMessage("SSH_MSG_REQUEST_SUCCESS");
|
||||
RegisterMessage("SSH_MSG_REQUEST_FAILURE");
|
||||
RegisterMessage("SSH_MSG_CHANNEL_OPEN_CONFIRMATION");
|
||||
@@ -2003,6 +2005,8 @@ namespace Renci.SshNet
|
||||
break;
|
||||
}
|
||||
|
||||
Console.WriteLine("RECEIVED MESSAGe " + message.GetType());
|
||||
|
||||
// process message
|
||||
message.Process(this);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user