Переглянути джерело

Project reorganization and renaming to Renci.SshNet

olegkap_cp 14 роки тому
батько
коміт
5ede55515a
100 змінених файлів з 5161 додано та 23 видалено
  1. 18 0
      Renci.SshClient/Renci.SshClient.Tests/ConnectionData.cs
  2. 11 0
      Renci.SshClient/Renci.SshClient.Tests/SftpClientTests/SftpClientTest.cs
  3. 244 0
      Renci.SshClient/Renci.SshClient.Tests/ShellTest.cs
  4. 11 0
      Renci.SshClient/Renci.SshClient/ChannelOpeningEventArgs.cs
  5. 219 0
      Renci.SshClient/Renci.SshClient/Channels/ChannelSessionExec.cs
  6. 580 0
      Renci.SshClient/Renci.SshClient/Channels/ChannelSessionSftp.cs
  7. 99 0
      Renci.SshClient/Renci.SshClient/Channels/ChannelSessionShell.cs
  8. 158 0
      Renci.SshClient/Renci.SshClient/Common/BlockingStack.cs
  9. 54 0
      Renci.SshClient/Renci.SshClient/Common/ConnectingEventArgs.cs
  10. 14 0
      Renci.SshClient/Renci.SshClient/Common/DataReceivedEventArgs.cs
  11. 29 0
      Renci.SshClient/Renci.SshClient/Common/FtpFileInfo.cs
  12. 15 0
      Renci.SshClient/Renci.SshClient/Common/MessageReceivedEventArgs.cs
  13. 96 0
      Renci.SshClient/Renci.SshClient/Connection.cs
  14. 96 0
      Renci.SshClient/Renci.SshClient/Documentation/Content/Extensibility.AddAuthenticationMethod.aml
  15. 96 0
      Renci.SshClient/Renci.SshClient/Documentation/Content/Extensibility.AddEncryption.aml
  16. 96 0
      Renci.SshClient/Renci.SshClient/Documentation/Content/Extensibility.AddHashAlgorithm.aml
  17. 21 0
      Renci.SshClient/Renci.SshClient/Documentation/Content/Extensibility.aml
  18. 50 0
      Renci.SshClient/Renci.SshClient/Documentation/Content/HowTo.Sftp.aml
  19. 68 0
      Renci.SshClient/Renci.SshClient/Documentation/Content/HowTo.SshCommand.Run.aml
  20. 50 0
      Renci.SshClient/Renci.SshClient/Documentation/Content/HowTo.SshCommand.aml
  21. 50 0
      Renci.SshClient/Renci.SshClient/Documentation/Content/HowTo.aml
  22. 48 0
      Renci.SshClient/Renci.SshClient/Documentation/Content/Introduction.aml
  23. 10 0
      Renci.SshClient/Renci.SshClient/Messages/Authentication/Methods.cs
  24. 33 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelOpenDirectTcpIPMessage.cs
  25. 30 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestEnvironmentVariableMessage.cs
  26. 26 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestExecMessage.cs
  27. 38 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestExitSignalMessage.cs
  28. 23 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestExitStatusMessage.cs
  29. 44 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestPseudoTerminalMessage.cs
  30. 19 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestShellMessage.cs
  31. 26 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestSignalMessage.cs
  32. 26 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestSubsystemMessage.cs
  33. 38 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestWindowChangeMessage.cs
  34. 38 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestX11ForwardingMessage.cs
  35. 26 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestXonXoffMessage.cs
  36. 50 0
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequestNames.cs
  37. 161 0
      Renci.SshClient/Renci.SshClient/Messages/MessageTypes.cs
  38. 9 0
      Renci.SshClient/Renci.SshClient/RequestSuccessEventArgs.cs
  39. 124 0
      Renci.SshClient/Renci.SshClient/Security/CipherAES128.cs
  40. 8 0
      Renci.SshClient/Renci.SshClient/Security/KeyExchangeCompletedEventArgs.cs
  41. 14 0
      Renci.SshClient/Renci.SshClient/Security/KeyExchangeFailedEventArgs.cs
  42. 15 0
      Renci.SshClient/Renci.SshClient/Security/KeyExchangeSendMessageEventArgs.cs
  43. 39 0
      Renci.SshClient/Renci.SshClient/Security/PrivateKey.cs
  44. 192 0
      Renci.SshClient/Renci.SshClient/Security/PrivateKeyDsa.cs
  45. 197 0
      Renci.SshClient/Renci.SshClient/Security/PrivateKeyRsa.cs
  46. 16 0
      Renci.SshClient/Renci.SshClient/Security/Signature.cs
  47. 91 0
      Renci.SshClient/Renci.SshClient/Security/SignatureDss.cs
  48. 81 0
      Renci.SshClient/Renci.SshClient/Security/SignatureRsa.cs
  49. 94 0
      Renci.SshClient/Renci.SshClient/Security/UserAuthentication.cs
  50. 18 0
      Renci.SshClient/Renci.SshClient/Security/UserAuthenticationHost.cs
  51. 127 0
      Renci.SshClient/Renci.SshClient/Security/UserAuthenticationKeyboardInteractive.cs
  52. 82 0
      Renci.SshClient/Renci.SshClient/Security/UserAuthenticationNone.cs
  53. 128 0
      Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPassword.cs
  54. 177 0
      Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPublicKey.cs
  55. 19 0
      Renci.SshClient/Renci.SshClient/Services/ConnectionService.cs
  56. 22 0
      Renci.SshClient/Renci.SshClient/Services/Service.cs
  57. 155 0
      Renci.SshClient/Renci.SshClient/Services/UserAuthenticationService.cs
  58. 72 0
      Renci.SshClient/Renci.SshClient/SessionInfo.cs
  59. 199 0
      Renci.SshClient/Renci.SshClient/SessionSSHv2.cs
  60. 69 0
      Renci.SshClient/Renci.SshClient/Settings.cs
  61. 273 0
      Renci.SshClient/Renci.SshClient/Sftp.cs
  62. 35 0
      Renci.SshClient/Renci.SshClient/Sftp/FileStatusCommand.cs
  63. 29 0
      Renci.SshClient/Renci.SshClient/Sftp/Messages/FSetStat.cs
  64. 7 0
      Renci.SshClient/Renci.SshClient/Sftp/SftpFileAttributes.cs
  65. 58 0
      Renci.SshClient/Renci.SshClient/SftpAsyncResult.cs
  66. 69 0
      Renci.SshClient/Renci.SshClient/SshBase.cs
  67. 20 0
      Renci.SshClient/Renci.SshClient/UserAuthentication.cs
  68. 0 0
      Renci.SshClient/Renci.SshNet.Tests/ConnectionTest.cs
  69. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Properties/AssemblyInfo.cs
  70. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Properties/Resources.Designer.cs
  71. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Properties/Resources.resx
  72. 3 3
      Renci.SshClient/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj
  73. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj.vspscc
  74. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Security/Cryptography/TestAes.cs
  75. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Security/Cryptography/TestBlowfish.cs
  76. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Security/Cryptography/TestCast.cs
  77. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Security/TestCipher.cs
  78. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Security/TestCryptoKey.cs
  79. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Security/TestHMac.cs
  80. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Security/TestHostKey.cs
  81. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Security/TestKeyExchange.cs
  82. 0 0
      Renci.SshClient/Renci.SshNet.Tests/Security/TestPrivateKeyFile.cs
  83. 0 0
      Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/CreateDirectoryTest.cs
  84. 0 0
      Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/DeleteDirectoryTest.cs
  85. 0 0
      Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/DeleteFileTest.cs
  86. 0 0
      Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/GetTest.cs
  87. 0 0
      Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/ListDirectoryTest.cs
  88. 0 0
      Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/RenameFileTest.cs
  89. 0 0
      Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/UploadDownloadFileTest.cs
  90. 0 0
      Renci.SshClient/Renci.SshNet.Tests/SshClientTests/TestPortForwarding.cs
  91. 0 0
      Renci.SshClient/Renci.SshNet.Tests/SshClientTests/TestShell.cs
  92. 0 0
      Renci.SshClient/Renci.SshNet.Tests/SshClientTests/TestSshCommand.cs
  93. 8 20
      Renci.SshClient/Renci.SshNet.sln
  94. 0 0
      Renci.SshClient/Renci.SshNet.vssscc
  95. 0 0
      Renci.SshClient/Renci.SshNet/BaseClient.cs
  96. 0 0
      Renci.SshClient/Renci.SshNet/ChannelAsyncResult.cs
  97. 0 0
      Renci.SshClient/Renci.SshNet/Channels/Channel.cs
  98. 0 0
      Renci.SshClient/Renci.SshNet/Channels/ChannelDirectTcpip.cs
  99. 0 0
      Renci.SshClient/Renci.SshNet/Channels/ChannelForwardedTcpip.cs
  100. 0 0
      Renci.SshClient/Renci.SshNet/Channels/ChannelSession.cs

+ 18 - 0
Renci.SshClient/Renci.SshClient.Tests/ConnectionData.cs

@@ -0,0 +1,18 @@
+
+namespace Renci.SshClient.Tests
+{
+    public static class ConnectionData
+    {
+        public static string Host { get { return "oleg-centos.edc.renci.org"; } }
+
+        public static int Port { get { return 22; } }
+
+        public static string Username { get { return "tester"; } }
+
+        public static string Password { get { return "tester"; } }
+
+        public static string RsaKeyFilePath { get { return @"RSA key path"; } }
+
+        public static string DssKeyFilePath { get { return @"DSS key path"; } }
+    }
+}

+ 11 - 0
Renci.SshClient/Renci.SshClient.Tests/SftpClientTests/SftpClientTest.cs

@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Renci.SshClient.Tests
+{
+    class SftpClientTest
+    {
+    }
+}

+ 244 - 0
Renci.SshClient/Renci.SshClient.Tests/ShellTest.cs

@@ -0,0 +1,244 @@
+using System;
+using System.Diagnostics;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Renci.SshClient.Tests
+{
+    /// <summary>
+    /// Summary description for UnitTest1
+    /// </summary>
+    [TestClass]
+    public class ShellTest
+    {
+        public ShellTest()
+        {
+            //
+            // TODO: Add constructor logic here
+            //
+        }
+
+        private TestContext testContextInstance;
+
+        /// <summary>
+        ///Gets or sets the test context which provides
+        ///information about and functionality for the current test run.
+        ///</summary>
+        public TestContext TestContext
+        {
+            get
+            {
+                return testContextInstance;
+            }
+            set
+            {
+                testContextInstance = value;
+            }
+        }
+
+        #region Additional test attributes
+        //
+        // You can use the following additional attributes as you write your tests:
+        //
+        // Use ClassInitialize to run code before running the first test in the class
+        // [ClassInitialize()]
+        // public static void MyClassInitialize(TestContext testContext) { }
+        //
+        // Use ClassCleanup to run code after all tests in a class have run
+        // [ClassCleanup()]
+        // public static void MyClassCleanup() { }
+        //
+        // Use TestInitialize to run code before running each test 
+        // [TestInitialize()]
+        // public void MyTestInitialize() { }
+        //
+        // Use TestCleanup to run code after each test has run
+        // [TestCleanup()]
+        // public void MyTestCleanup() { }
+        //
+        #endregion
+
+        [TestMethod]
+        public void TestConnectUsingPassword()
+        {
+            var s = CreateShellUsingPassword();
+            s.Connect();
+            s.Disconnect();
+        }
+
+        [TestMethod]
+        public void TestExecuteSingleCommand()
+        {
+            var s = CreateShellUsingPassword();
+            s.Connect();
+            var result = ExecuteTestCommand(s);
+            s.Disconnect();
+
+            Assert.IsTrue(result);
+        }
+
+        [TestMethod]
+        public void TestReconnecting()
+        {
+            var s = CreateShellUsingPassword();
+            s.Connect();
+            var result = ExecuteTestCommand(s);
+            s.Disconnect();
+
+            Assert.IsTrue(result);
+
+            s.Connect();
+            result = ExecuteTestCommand(s);
+            s.Disconnect();
+
+            Assert.IsTrue(result);
+        }
+
+        [TestMethod]
+        public void TestMultipleThreadMultipleSessions_10000()
+        {
+            var s = CreateShellUsingPassword();
+            s.Connect();
+            System.Threading.Tasks.Parallel.For(0, 10000,
+                (counter) =>
+                {
+                    var result = ExecuteTestCommand(s);
+                    Debug.WriteLine(string.Format("TestMultipleThreadMultipleConnections #{0}", counter));
+                    Assert.IsTrue(result);
+                }
+            );
+
+            s.Disconnect();
+        }
+
+        [TestMethod]
+        public void TestMultipleThreadMultipleConnections_10000()
+        {
+            try
+            {
+                System.Threading.Tasks.Parallel.For(0, 10000,
+                    () =>
+                    {
+                        var s = CreateShellUsingPassword();
+                        s.Connect();
+                        return s;
+                    },
+                    (int counter, ParallelLoopState pls, SshClient s) =>
+                    {
+                        var result = ExecuteTestCommand(s);
+                        Debug.WriteLine(string.Format("TestMultipleThreadMultipleConnections #{0}", counter));
+                        Assert.IsTrue(result);
+                        return s;
+                    },
+                    (SshClient s) =>
+                    {
+                        s.Disconnect();
+                    }
+                );
+            }
+            catch (Exception exp)
+            {
+                Assert.Fail(exp.ToString());
+            }
+        }
+
+        [TestMethod]
+        public void TestExtendedOutput()
+        {
+            var s = CreateShellUsingPassword();
+            s.Connect();
+            var cmd = s.CreateCommand("echo 12345; echo 654321 >&2");
+            cmd.Execute();
+            var extendedData = Encoding.ASCII.GetString(cmd.ExtendedOutputStream.ToArray());
+            s.Disconnect();
+
+            Assert.AreEqual("12345\n", cmd.Result);
+            Assert.AreEqual("654321\n", extendedData);
+        }
+
+        [TestMethod]
+        public void TestInvalidCommandExecution()
+        {
+            var s = CreateShellUsingPassword();
+            s.Connect();
+
+            var cmd = s.CreateCommand(";");
+            cmd.Execute();
+            if (string.IsNullOrEmpty(cmd.Error))
+            {
+                Assert.Fail("Operation should fail");
+            }
+            Assert.IsTrue(cmd.ExitStatus > 0);
+
+            s.Disconnect();
+        }
+
+        [TestMethod]
+        public void TestInvalidCommandThenValidCommandExecution()
+        {
+            var s = CreateShellUsingPassword();
+            s.Connect();
+            var cmd = s.CreateCommand(";");
+            cmd.Execute();
+            if (string.IsNullOrEmpty(cmd.Error))
+            {
+                Assert.Fail("Operation should fail");
+            }
+            Assert.IsTrue(cmd.ExitStatus > 0);
+
+            var result = ExecuteTestCommand(s);
+            s.Disconnect();
+
+            Assert.IsTrue(result);
+        }
+
+        [TestMethod]
+        public void TestRsaKeyConnection()
+        {
+            var s = CreateShellUsingRSAKey();
+            s.Connect();
+            var result = ExecuteTestCommand(s);
+            s.Disconnect();
+            Assert.IsTrue(result);
+        }
+
+        [TestMethod]
+        public void TestDssKeyConnection()
+        {
+            var s = CreateShellUsingRSAKey();
+            s.Connect();
+            var result = ExecuteTestCommand(s);
+            s.Disconnect();
+            Assert.IsTrue(result);
+        }
+
+        private static SshClient CreateShellUsingPassword()
+        {
+            return new SshClient(ConnectionData.Host, ConnectionData.Port, ConnectionData.Username, ConnectionData.Password);
+        }
+
+        private static SshClient CreateShellUsingRSAKey()
+        {
+            return new SshClient(ConnectionData.Host, ConnectionData.Port, ConnectionData.Username, new PrivateKeyFile(ConnectionData.RsaKeyFilePath));
+        }
+
+        private static SshClient CreateShellUsingDSSKey()
+        {
+            return new SshClient(ConnectionData.Host, ConnectionData.Port, ConnectionData.Username, new PrivateKeyFile(ConnectionData.DssKeyFilePath));
+        }
+
+        private static bool ExecuteTestCommand(SshClient s)
+        {
+            var testValue = Guid.NewGuid().ToString();
+            var command = string.Format("echo {0}", testValue);
+            //var command = string.Format("echo {0};sleep 2s", testValue);
+            var cmd = s.CreateCommand(command);
+            var result = cmd.Execute();
+            result = result.Substring(0, result.Length - 1);    //  Remove \n chararacter returned by command
+            return result.Equals(testValue);
+        }
+
+
+    }
+}

+ 11 - 0
Renci.SshClient/Renci.SshClient/ChannelOpeningEventArgs.cs

@@ -0,0 +1,11 @@
+using System;
+using Renci.SshClient.Messages.Connection;
+
+namespace Renci.SshClient
+{
+    internal class ChannelOpeningEventArgs : EventArgs
+    {
+        public ChannelOpenMessage Message { get; set; }
+
+    }
+}

+ 219 - 0
Renci.SshClient/Renci.SshClient/Channels/ChannelSessionExec.cs

@@ -0,0 +1,219 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using Renci.SshClient.Messages;
+using Renci.SshClient.Messages.Connection;
+
+namespace Renci.SshClient.Channels
+{
+    internal class ChannelSessionExec : ChannelSession
+    {
+        /// <summary>
+        /// Holds channel data stream
+        /// </summary>
+        private Stream _channelData;
+
+        /// <summary>
+        /// Holds channel extended data stream
+        /// </summary>
+        private Stream _channelExtendedData;
+
+        private ChannelAsyncResult _asyncResult;
+
+        private AsyncCallback _callback;
+
+        /// <summary>
+        /// Gets or sets a value indicating whether this channel has error.
+        /// </summary>
+        /// <value><c>true</c> if this instance has error; otherwise, <c>false</c>.</value>
+        public bool HasError { get; set; }
+
+        /// <summary>
+        /// Gets or sets the exit status.
+        /// </summary>
+        /// <value>The exit status.</value>
+        public uint ExitStatus { get; private set; }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ChannelSessionExec"/> class.
+        /// </summary>
+        public ChannelSessionExec()
+            : base()
+        {
+
+        }
+
+        /// <summary>
+        /// Begins the execute.
+        /// </summary>
+        /// <param name="command">The command.</param>
+        /// <param name="output">The output.</param>
+        /// <param name="extendedOutput">The extended output.</param>
+        /// <param name="callback">The callback.</param>
+        /// <param name="state">The state.</param>
+        /// <returns></returns>
+        internal ChannelAsyncResult BeginExecute(string command, Stream output, Stream extendedOutput, AsyncCallback callback, object state)
+        {
+            //  Prevent from executing BeginExecute before calling EndExecute
+            if (this._asyncResult != null)
+            {
+                throw new InvalidOperationException("");
+            }
+
+            //  Create new AsyncResult object
+            this._asyncResult = new ChannelAsyncResult(this)
+            {
+                AsyncWaitHandle = new EventWaitHandle(false, EventResetMode.ManualReset),
+                IsCompleted = false,
+                AsyncState = state,
+            };
+
+            this._callback = callback;
+            this._channelData = output;
+            this._channelExtendedData = extendedOutput;
+
+            this.Open();
+
+            //  Send channel command request
+            this.SendExecRequest(command);
+
+            return _asyncResult;
+        }
+
+        /// <summary>
+        /// Ends the execute.
+        /// </summary>
+        /// <param name="result">The result.</param>
+        internal void EndExecute(IAsyncResult result)
+        {
+            ChannelAsyncResult channelAsyncResult = result as ChannelAsyncResult;
+
+            if (channelAsyncResult.Channel != this)
+            {
+                throw new InvalidOperationException("Invalid IAsyncResult parameter");
+            }
+
+            //  Make sure that operation completed if not wait for it to finish
+            this.WaitHandle(this._asyncResult.AsyncWaitHandle);
+
+            this.Close();
+
+            this._asyncResult = null;
+        }
+
+        /// <summary>
+        /// Called when channel is closed
+        /// </summary>
+        protected override void OnClose()
+        {
+            base.OnClose();
+
+            if (this._channelData != null)
+            {
+                this._channelData.Flush();
+            }
+
+            if (this._channelExtendedData != null)
+            {
+                this._channelExtendedData.Flush();
+            }
+
+            this._asyncResult.IsCompleted = true;
+            if (this._callback != null)
+            {
+                //  TODO:   Execute this method on different thread since it will be run on message listener
+                this._callback(this._asyncResult);
+            }
+            ((EventWaitHandle)_asyncResult.AsyncWaitHandle).Set();
+        }
+
+        /// <summary>
+        /// Called when channel receives data.
+        /// </summary>
+        /// <param name="data">The data.</param>
+        protected override void OnData(string data)
+        {
+            base.OnData(data);
+
+            if (this._channelData != null)
+            {
+                foreach (var b in data)
+                {
+                    this._channelData.WriteByte((byte)b);
+                }
+            }
+
+            if (this._asyncResult != null)
+            {
+                this._asyncResult.BytesReceived += data.Length;
+            }
+        }
+
+        /// <summary>
+        /// Called when channel receives extended data.
+        /// </summary>
+        /// <param name="data">The data.</param>
+        /// <param name="dataTypeCode">The data type code.</param>
+        protected override void OnExtendedData(string data, uint dataTypeCode)
+        {
+            base.OnExtendedData(data, dataTypeCode);
+
+            if (this._channelExtendedData != null)
+            {
+                this._channelExtendedData.Write(data.GetSshBytes().ToArray(), 0, data.Length);
+                //foreach (var b in data)
+                //{
+                //    this._channelExtendedData.WriteByte((byte)b);
+                //}
+            }
+
+            if (dataTypeCode == 1)
+            {
+                this.HasError = true;
+            }
+        }
+
+        /// <summary>
+        /// Called when channel request command is called.
+        /// </summary>
+        /// <param name="requestName">Name of the request.</param>
+        /// <param name="wantReply">if set to <c>true</c> then need to send reply to server.</param>
+        /// <param name="command">The command.</param>
+        /// <param name="subsystemName">Name of the subsystem.</param>
+        /// <param name="exitStatus">The exit status.</param>
+        protected override void OnRequest(RequestInfo info)
+        {
+            base.OnRequest(info);
+
+            Message replyMessage = new ChannelFailureMessage()
+            {
+                LocalChannelNumber = this.LocalChannelNumber,
+            };
+
+            if (info is ExitStatusRequestInfo)
+            {
+                ExitStatusRequestInfo exitStatusInfo = info as ExitStatusRequestInfo;
+
+                this.ExitStatus = exitStatusInfo.ExitStatus;
+
+                replyMessage = new ChannelSuccessMessage()
+                {
+                    LocalChannelNumber = this.LocalChannelNumber,
+                };
+            }
+
+            if (info.WantReply)
+            {
+                this.SendMessage(replyMessage);
+            }
+        }
+
+        /// <summary>
+        /// Called when object is being disposed.
+        /// </summary>
+        protected override void OnDisposing()
+        {
+        }
+    }
+}

+ 580 - 0
Renci.SshClient/Renci.SshClient/Channels/ChannelSessionSftp.cs

@@ -0,0 +1,580 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using Renci.SshClient.Common;
+using Renci.SshClient.Messages.Sftp;
+
+namespace Renci.SshClient.Channels
+{
+    //  TODO:   Add Begin* and End* methods for async calls
+
+    internal class ChannelSessionSftp : ChannelSession
+    {
+        private EventWaitHandle _channelRequestSuccessWaitHandle = new AutoResetEvent(false);
+
+        private EventWaitHandle _responseMessageReceivedWaitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
+
+        private uint _requestId;
+
+        private SftpMessage _responseMessage;
+
+        private string _remoteCurrentDir;
+
+        private string _localCurentDir;
+
+        private StringBuilder _packetData;
+
+        //  TODO:   Repalce with SFTP specific async class if needed
+        private CommandAsyncResult _asyncResult;
+
+        public ChannelSessionSftp()
+            : base()
+        {
+
+        }
+
+        public override void Open()
+        {
+            base.Open();
+
+            //  Send channel command request
+            this.SendSubsystemRequest("sftp");
+
+            this.WaitHandle(this._channelRequestSuccessWaitHandle);
+
+            this.SendMessage(new InitMessage
+            {
+                Version = 3,
+            });
+
+            var versionMessage = this.ReceiveMessage<VersionMessage>();
+
+            if (versionMessage == null)
+            {
+                throw new InvalidOperationException("Version message expected.");
+            }
+
+            if (versionMessage.Version != 3)
+            {
+                throw new NotSupportedException(string.Format("Server SFTP version {0} is not supported.", versionMessage.Version));
+            }
+
+            //  Get default current directories
+            var files = this.GetRealPath(".");
+
+            this._remoteCurrentDir = files.First().Name;
+            this._localCurentDir = Directory.GetCurrentDirectory();
+        }
+
+        public void UploadFile(Stream source, string destination)
+        {
+            this.Open();
+
+            string handle = string.Empty;
+
+            try
+            {
+                handle = this.OpenRemoteFile(destination, Flags.Write | Flags.CreateNewOrOpen | Flags.Truncate);
+
+                var buffer = new byte[1024];
+                ulong offset = 0;
+                var bytesRead = 0;
+                while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
+                {
+                    this.RemoteWrite(handle, offset, buffer.Take(bytesRead).GetSshString());
+                    offset += (ulong)buffer.Length;
+                }
+            }
+            finally
+            {
+                if (!string.IsNullOrEmpty(handle))
+                    this.CloseRemoteHandle(handle);
+            }
+
+            this.Close();
+        }
+
+        internal void DownloadFile(string fileName, Stream destination)
+        {
+            this.Open();
+
+            string handle = string.Empty;
+
+            try
+            {
+                handle = this.OpenRemoteFile(fileName, Flags.Read);
+
+                ulong offset = 0;
+                uint bufferSize = 1024;
+                string data;
+
+                while ((data = this.RemoteRead(handle, offset, bufferSize)) != null)
+                {
+                    var fileData = data.GetSshBytes().ToArray();
+                    destination.Write(fileData, 0, fileData.Length);
+                    destination.Flush();
+                    offset += (ulong)fileData.Length;
+                }
+
+            }
+            finally
+            {
+                if (!string.IsNullOrEmpty(handle))
+                    this.CloseRemoteHandle(handle);
+            }
+
+            this.Close();
+        }
+
+        public void CreateDirectory(string directoryName)
+        {
+            this.Open();
+
+            this.CreateRemoteDirectory(directoryName);
+
+            this.Close();
+        }
+
+        public void RemoveDirectory(string directoryName)
+        {
+            this.Open();
+
+            this.RemoveRemoteDirectory(directoryName);
+
+            this.Close();
+        }
+
+        public void RemoveFile(string fileName)
+        {
+            this.Open();
+
+            this.RemoveRemoteFile(fileName);
+
+            this.Close();
+        }
+
+        public void RenameFile(string oldFileName, string newFileName)
+        {
+            this.Open();
+
+            this.RenameRemoteFile(oldFileName, newFileName);
+
+            this.Close();
+        }
+
+        public IEnumerable<FtpFileInfo> ListDirectory(string path)
+        {
+            //  Open channel
+            this.Open();
+
+            string handle = string.Empty;
+            IEnumerable<FtpFileInfo> files = null;
+
+            try
+            {
+                //  Open directory
+                handle = this.OpenRemoteDirectory(path);
+
+                //  Read directory data
+                files = this.ReadRemoteDirectory(handle);
+            }
+            finally
+            {
+                //  Close directory
+                if (!string.IsNullOrEmpty(handle))
+                    this.CloseRemoteHandle(handle);
+            }
+
+            //  Read directory
+            this.Close();
+
+            return files;
+
+        }
+
+        protected override void OnSuccess()
+        {
+            base.OnSuccess();
+
+            this._channelRequestSuccessWaitHandle.Set();
+        }
+
+
+        protected override void OnData(string data)
+        {
+            base.OnData(data);
+
+            if (this._packetData == null)
+            {
+                var packetLength = (uint)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]);
+
+                this._packetData = new StringBuilder((int)packetLength, (int)packetLength);
+                this._packetData.Append(data.GetSshBytes().Skip(4).GetSshString());
+            }
+            else
+            {
+                this._packetData.Append(data);
+            }
+
+            if (this._packetData.Length < this._packetData.MaxCapacity)
+            {
+                //  Wait for more packet data
+                return;
+            }
+
+
+            dynamic sftpMessage = SftpMessage.Load(this._packetData.ToString().GetSshBytes());
+
+            this._packetData = null;
+
+            if (sftpMessage.RequestId != null)
+            {
+                if (sftpMessage.RequestId != this._requestId)
+                {
+                    throw new InvalidOperationException("Invalid request id.");
+                }
+
+                this._requestId++;
+            }
+
+            this._responseMessage = sftpMessage;
+
+            this._responseMessageReceivedWaitHandle.Set();
+        }
+
+        private T ReceiveMessage<T>() where T : SftpMessage
+        {
+            var message = this.ReceiveMessage() as T;
+
+            if (message == null)
+            {
+                throw new InvalidOperationException(string.Format("Message of type '{0}' expected in this context.", typeof(T).Name));
+            }
+            return message;
+
+        }
+
+        private SftpMessage ReceiveMessage()
+        {
+            this.WaitHandle(this._responseMessageReceivedWaitHandle);
+
+            var statusMessage = this._responseMessage as StatusMessage;
+
+            if (statusMessage != null)
+            {
+                //  Handle error status messages
+                switch (statusMessage.StatusCode)
+                {
+                    case StatusCodes.Ok:
+                        break;
+                    case StatusCodes.Eof:
+                        break;
+                    case StatusCodes.NoSuchFile:
+                        throw new FileNotFoundException("File or directory not found on the remote server.");
+                    case StatusCodes.PermissionDenied:
+                        throw new NotImplementedException();
+                    case StatusCodes.Failure:
+                        throw new InvalidOperationException("Operation failed.");
+                    case StatusCodes.BadMessage:
+                        throw new NotImplementedException();
+                    case StatusCodes.NoConnection:
+                        throw new NotImplementedException();
+                    case StatusCodes.ConnectionLost:
+                        throw new NotImplementedException();
+                    case StatusCodes.OperationUnsupported:
+                        throw new NotSupportedException("Operation is not supported.");
+                    default:
+                        break;
+                }
+            }
+
+            return this._responseMessage;
+        }
+
+        private void SendMessage(SftpMessage sftpMessage)
+        {
+            sftpMessage.RequestId = this._requestId;
+            var message = new SftpDataMessage
+            {
+                LocalChannelNumber = this.RemoteChannelNumber,
+                Message = sftpMessage,
+            };
+
+            this.SendMessage(message);
+
+            this._responseMessageReceivedWaitHandle.Reset();
+        }
+
+        private string OpenRemoteFile(string fileName, Flags flags)
+        {
+            this.SendMessage(new OpenMessage
+            {
+                Filename = fileName,
+                Flags = flags,
+            });
+
+            var handleMessage = this.ReceiveMessage<HandleMessage>();
+
+            return handleMessage.Handle;
+        }
+
+        private string RemoteRead(string handle, ulong offset, uint length)
+        {
+            this.SendMessage(new ReadMessage
+            {
+                Handle = handle,
+                Offset = offset,
+                Length = length,
+            });
+
+            var message = this.ReceiveMessage();
+
+            var statusMessage = message as StatusMessage;
+            var dataMessage = message as DataMessage;
+
+            if (statusMessage != null)
+            {
+                if (statusMessage.StatusCode == StatusCodes.Eof)
+                {
+                    return null;
+                }
+
+                throw new InvalidOperationException("Invalid status code.");
+            }
+            else if (dataMessage != null)
+            {
+                if (this._asyncResult != null)
+                {
+                    this._asyncResult.BytesReceived += dataMessage.Data.Length;
+                }
+                return dataMessage.Data;
+            }
+            else
+            {
+                throw new InvalidOperationException(string.Format("Message type '{0}' is not valid in this context.", message.SftpMessageType));
+            }
+        }
+
+        private void RemoteWrite(string handle, ulong offset, string data)
+        {
+            this.SendMessage(new WriteMessage
+            {
+                Handle = handle,
+                Offset = offset,
+                Data = data,
+            });
+
+            var message = this.ReceiveMessage<StatusMessage>();
+
+            this.EnsureStatusCode(message, StatusCodes.Ok);
+
+            if (this._asyncResult != null)
+            {
+                this._asyncResult.BytesSent += data.Length;
+            }
+
+        }
+
+        private void RemoveRemoteFile(string fileName)
+        {
+            this.SendMessage(new RemoveMessage
+            {
+                Filename = fileName,
+            });
+
+            var message = this.ReceiveMessage<StatusMessage>();
+
+            this.EnsureStatusCode(message, StatusCodes.Ok);
+        }
+
+        private void RenameRemoteFile(string oldFileName, string newFileName)
+        {
+            this.SendMessage(new RenameMessage
+            {
+                OldPath = oldFileName,
+                NewPath = newFileName,
+            });
+
+            var message = this.ReceiveMessage<StatusMessage>();
+
+            this.EnsureStatusCode(message, StatusCodes.Ok);
+        }
+
+        private void CreateRemoteDirectory(string directoryName)
+        {
+            this.SendMessage(new MkDirMessage
+            {
+                Path = directoryName,
+            });
+
+            var message = this.ReceiveMessage<StatusMessage>();
+
+            this.EnsureStatusCode(message, StatusCodes.Ok);
+        }
+
+        private void RemoveRemoteDirectory(string directoryName)
+        {
+            this.SendMessage(new RmDirMessage
+            {
+                Path = directoryName,
+            });
+
+            var message = this.ReceiveMessage<StatusMessage>();
+
+            this.EnsureStatusCode(message, StatusCodes.Ok);
+        }
+
+        private string OpenRemoteDirectory(string path)
+        {
+            this.SendMessage(new OpenDirMessage
+            {
+                Path = path,
+            });
+
+            var handleMessage = this.ReceiveMessage<HandleMessage>();
+
+            return handleMessage.Handle;
+        }
+
+        private IEnumerable<FtpFileInfo> ReadRemoteDirectory(string handle)
+        {
+            this.SendMessage(new ReadDirMessage
+            {
+                Handle = handle,
+            });
+
+            var message = this.ReceiveMessage<NameMessage>();
+
+            return message.Files;
+        }
+
+        private void CloseRemoteHandle(string handle)
+        {
+            this.SendMessage(new CloseMessage
+            {
+                Handle = handle,
+            });
+
+            var status = this.ReceiveMessage<StatusMessage>();
+            var attempts = 0;
+            //  If close fails wait a litle a try to close it again, in case server flushed data into the file during close
+            while (status.StatusCode != StatusCodes.Ok && attempts++ < this.ConnectionInfo.RetryAttempts)
+            {
+                Thread.Sleep(50);
+                status = this.ReceiveMessage<StatusMessage>();
+            }
+
+            if (status.StatusCode != StatusCodes.Ok)
+            {
+                throw new InvalidOperationException(string.Format("File handle cannot be closed after {0} attempts.", attempts));
+            }
+        }
+
+        private Attributes GetRemoteFileAttributes(string filename)
+        {
+            this.SendMessage(new StatMessage
+            {
+                Path = filename,
+            });
+
+            var message = this.ReceiveMessage<AttrsMessage>();
+
+            return message.Attributes;
+        }
+
+        private Attributes GetRemoteLinkFileAttributes(string filename)
+        {
+            this.SendMessage(new LStatMessage
+            {
+                Path = filename,
+            });
+
+            var message = this.ReceiveMessage<AttrsMessage>();
+
+            return message.Attributes;
+        }
+
+        private Attributes GetRemoteOpenFileAttributes(string handle)
+        {
+            this.SendMessage(new FStatMessage
+            {
+                Handle = handle,
+            });
+
+            var message = this.ReceiveMessage<AttrsMessage>();
+
+            return message.Attributes;
+        }
+
+        private void SetRemoteFileAttributes(string filename, Attributes attributes)
+        {
+            this.SendMessage(new SetStatMessage
+            {
+                Path = filename,
+                Attributes = attributes
+            });
+
+            var message = this.ReceiveMessage<StatusMessage>();
+
+            this.EnsureStatusCode(message, StatusCodes.Ok);
+        }
+
+        private void SetRemoteOpenFileAttributes(string handle, Attributes attributes)
+        {
+            this.SendMessage(new FSetStatMessage
+            {
+                Handle = handle,
+                Attributes = attributes
+            });
+
+            var message = this.ReceiveMessage<StatusMessage>();
+
+            this.EnsureStatusCode(message, StatusCodes.Ok);
+        }
+
+        private IEnumerable<FtpFileInfo> GetRealPath(string path)
+        {
+            this.SendMessage(new RealPathMessage
+            {
+                Path = path,
+            });
+
+            var message = this.ReceiveMessage<NameMessage>();
+
+            return message.Files;
+
+        }
+
+        private void EnsureStatusCode(StatusMessage message, StatusCodes code)
+        {
+            if (message.StatusCode == code)
+            {
+                return;
+            }
+            else
+            {
+                throw new InvalidOperationException("Invalid status code.");
+            }
+        }
+
+        #region IDisposable Members
+
+        protected override void OnDisposing()
+        {
+            // Dispose managed resources.
+            if (this._channelRequestSuccessWaitHandle != null)
+            {
+                this._channelRequestSuccessWaitHandle.Dispose();
+            }
+            if (this._responseMessageReceivedWaitHandle != null)
+            {
+                this._responseMessageReceivedWaitHandle.Dispose();
+            }
+        }
+
+        #endregion
+    }
+}

+ 99 - 0
Renci.SshClient/Renci.SshClient/Channels/ChannelSessionShell.cs

@@ -0,0 +1,99 @@
+using System.IO;
+using System.Linq;
+using System.Threading;
+using Renci.SshClient.Messages.Connection;
+
+namespace Renci.SshClient.Channels
+{
+    internal class ChannelSessionShell : ChannelSession
+    {
+
+        private EventWaitHandle _success = new AutoResetEvent(false);
+
+        /// <summary>
+        /// Holds channel data stream
+        /// </summary>
+        private Stream _channelData;
+
+        /// <summary>
+        /// Holds channel extended data stream
+        /// </summary>
+        private Stream _channelExtendedData;
+
+        public void Start(Stream output, Stream extendedOutput)
+        {
+            this.Open();
+
+            this._channelData = output;
+            this._channelExtendedData = extendedOutput;
+
+            this.SendPseudoTerminalRequest("xterm", 80, 24, 640, 240, "");
+
+            _success.WaitOne();
+
+            this.SendShellRequest();
+        }
+
+        public void Stop()
+        {
+            //  Close channel
+            this.Close();
+        }
+
+        protected override void OnSuccess()
+        {
+            base.OnSuccess();
+
+            _success.Set();
+        }
+
+        protected override void OnFailure()
+        {
+            base.OnFailure();
+        }
+
+        protected override void OnData(string data)
+        {
+            base.OnData(data);
+
+            this._channelData.Write(data.GetSshBytes().ToArray(), 0, data.Length);
+            this._channelData.Flush();
+        }
+
+        protected override void OnExtendedData(string data, uint dataTypeCode)
+        {
+            base.OnExtendedData(data, dataTypeCode);
+
+            //  TODO:   dataTypeCode is not handled
+            this._channelExtendedData.Write(data.GetSshBytes().ToArray(), 0, data.Length);
+            this._channelExtendedData.Flush();
+        }
+
+        public void Send(string data)
+        {
+            this.SendMessage(new ChannelDataMessage
+            {
+                LocalChannelNumber = this.RemoteChannelNumber,
+                Data = data,
+            });
+        }
+
+        public class ShellStream : MemoryStream
+        {
+            public ShellStream()
+            {
+
+            }
+
+            public override void Write(byte[] buffer, int offset, int count)
+            {
+                base.Write(buffer, offset, count);
+            }
+
+            public override void WriteByte(byte value)
+            {
+                base.WriteByte(value);
+            }
+        }
+    }
+}

+ 158 - 0
Renci.SshClient/Renci.SshClient/Common/BlockingStack.cs

@@ -0,0 +1,158 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace Renci.SshClient.Common
+{
+    public class BlockingStack<T> : IEnumerable<T>, ICollection, IEnumerable
+    {
+        private Stack<T> _stack;
+
+        public BlockingStack()
+        {
+            this._stack = new Stack<T>();
+        }
+
+        public BlockingStack(IEnumerable<T> collection)
+        {
+            this._stack = new Stack<T>(collection);
+        }
+
+        public BlockingStack(int capacity)
+        {
+            this._stack = new Stack<T>(capacity);
+        }
+
+        // Summary:
+        //     Gets the number of elements contained in the System.Collections.Generic.Stack<T>.
+        //
+        // Returns:
+        //     The number of elements contained in the System.Collections.Generic.Stack<T>.
+        public int Count
+        {
+            get
+            {
+                return this._stack.Count;
+            }
+        }
+
+        public void Clear()
+        {
+            lock (this)
+            {
+                this._stack.Clear();
+                Monitor.PulseAll(this);
+            }
+        }
+
+        public bool Contains(T item)
+        {
+            return this._stack.Contains(item);
+        }
+
+        public void CopyTo(T[] array, int arrayIndex)
+        {
+            lock (this)
+            {
+                this._stack.CopyTo(array, arrayIndex);
+                Monitor.PulseAll(this);
+            }
+        }
+
+        public T Peek()
+        {
+            return this._stack.Peek();
+        }
+
+        public T Pop()
+        {
+            lock (this)
+            {
+                var result = this._stack.Pop();
+                Monitor.PulseAll(this);
+                return result;
+            }
+        }
+
+        public T WaitAndPop()
+        {
+            lock (this)
+            {
+                //  Wait for item to be added to the stack
+                while (this._stack.Count == 0)
+                {
+                    Monitor.Wait(this);
+                }
+                var result = this._stack.Pop();
+                Monitor.PulseAll(this);
+                return result;
+            }
+        }
+
+        public void Push(T item)
+        {
+            lock (this)
+            {
+                this._stack.Push(item);
+                Monitor.PulseAll(this);
+            }
+        }
+
+        public T[] ToArray()
+        {
+            lock (this)
+            {
+                var result = this._stack.ToArray();
+                Monitor.PulseAll(this);
+                return result;
+            }
+        }
+
+        public void TrimExcess()
+        {
+            lock (this)
+            {
+                this._stack.TrimExcess();
+                Monitor.PulseAll(this);
+            }
+        }
+
+        #region ICollection Members
+
+        public void CopyTo(System.Array array, int index)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public bool IsSynchronized
+        {
+            get { return true; }
+        }
+
+        public object SyncRoot
+        {
+            get { return this; }
+        }
+
+        #endregion
+
+
+        #region IEnumerable<T> Members
+
+        public IEnumerator<T> GetEnumerator()
+        {
+            return this._stack.GetEnumerator();
+        }
+
+        #endregion
+
+        #region IEnumerable Members
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return this._stack.GetEnumerator();
+        }
+
+        #endregion
+    }
+}

+ 54 - 0
Renci.SshClient/Renci.SshClient/Common/ConnectingEventArgs.cs

@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Renci.SshClient.Common
+{
+    public class ConnectingEventArgs : EventArgs
+    {
+        public IDictionary<string, string> KeyExchangeAlgorithms { get; private set; }
+
+        public IDictionary<string, string> Encryptions { get; private set; }
+
+        public IDictionary<string, string> HmacAlgorithms { get; private set; }
+
+        public IDictionary<string, string> HostKeyAlgorithms { get; private set; }
+
+        public IDictionary<string, string> SupportedAuthenticationMethods { get; private set; }
+
+        public IDictionary<string, string> CompressionAlgorithms { get; private set; }
+
+        public string Host { get; set; }
+
+        public int Port { get; set; }
+
+        public string Username { get; set; }
+
+        public string Password { get; set; }
+
+        public ICollection<PrivateKeyFile> KeyFiles { get; set; }
+
+        public TimeSpan Timeout { get; set; }
+
+        public int RetryAttempts { get; set; }
+
+        public int MaxSessions { get; set; }
+
+        public ConnectingEventArgs(
+            IDictionary<string, string> keyExchangeAlgorithms,
+            IDictionary<string, string> encryptions,
+            IDictionary<string, string> hmacAlgorithms,
+            IDictionary<string, string> hostKeyAlgorithms,
+            IDictionary<string, string> supportedAuthenticationMethods,
+            IDictionary<string, string> compressionAlgorithms)
+        {
+            this.KeyExchangeAlgorithms = keyExchangeAlgorithms;
+            this.Encryptions = encryptions;
+            this.HmacAlgorithms = hmacAlgorithms;
+            this.HostKeyAlgorithms = hostKeyAlgorithms;
+            this.SupportedAuthenticationMethods = supportedAuthenticationMethods;
+            this.CompressionAlgorithms = compressionAlgorithms;
+        }
+    }
+}

+ 14 - 0
Renci.SshClient/Renci.SshClient/Common/DataReceivedEventArgs.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace Renci.SshClient.Common
+{
+    internal class DataReceivedEventArgs : EventArgs
+    {
+        public string Data { get; private set; }
+
+        public DataReceivedEventArgs(string data)
+        {
+            this.Data = data;
+        }
+    }
+}

+ 29 - 0
Renci.SshClient/Renci.SshClient/Common/FtpFileInfo.cs

@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+
+namespace Renci.SshClient.Common
+{
+    public class FtpFileInfo
+    {
+        public string Name { get; set; }
+
+        public string FullName { get; set; }
+
+        public DateTime? CreationTime { get; set; }
+
+        public DateTime? LastAccessTime { get; set; }
+
+        public DateTime? LastModifyTime { get; set; }
+
+        public ulong? Size { get; set; }
+
+        public uint? UserId { get; set; }
+
+        public uint? GroupId { get; set; }
+
+        public uint? Permissions { get; set; }
+
+        public IDictionary<string, string> Extentions { get; set; }
+
+    }
+}

+ 15 - 0
Renci.SshClient/Renci.SshClient/Common/MessageReceivedEventArgs.cs

@@ -0,0 +1,15 @@
+using System;
+using Renci.SshClient.Messages;
+
+namespace Renci.SshClient.Common
+{
+    internal class MessageReceivedEventArgs : EventArgs
+    {
+        public Message Message { get; private set; }
+
+        public MessageReceivedEventArgs(Message message)
+        {
+            this.Message = message;
+        }
+    }
+}

+ 96 - 0
Renci.SshClient/Renci.SshClient/Connection.cs

@@ -0,0 +1,96 @@
+namespace Renci.SshClient
+{
+    public class Connection
+    {
+        private Session _session;
+
+        public ConnectionInfo ConnectionInfo { get; private set; }
+
+        private Shell _shell;
+        public Shell Shell
+        {
+            get
+            {
+                if (this._shell == null)
+                {
+                    this._shell = new Shell(this._session);
+                }
+                return this._shell;
+            }
+        }
+
+        private Sftp _sftp;
+
+        public Sftp Sftp
+        {
+            get
+            {
+                if (this._sftp == null)
+                {
+                    this._sftp = new Sftp(this._session);
+                }
+                return this._sftp;
+            }
+        }
+
+
+        public Connection(ConnectionInfo connectionInfo)
+        {
+            this.ConnectionInfo = connectionInfo;
+            this._session = Session.CreateSession(this.ConnectionInfo);
+        }
+
+        public Connection(string host, int port, string username, string password)
+            : this(new ConnectionInfo
+            {
+                Host = host,
+                Port = port,
+                Username = username,
+                Password = password,
+            })
+        {
+        }
+
+        public Connection(string host, string username, string password)
+            : this(new ConnectionInfo
+            {
+                Host = host,
+                Username = username,
+                Password = password,
+            })
+        {
+        }
+
+        public Connection(string host, int port, string username, PrivateKeyFile keyFile)
+            : this(new ConnectionInfo
+            {
+                Host = host,
+                Port = port,
+                Username = username,
+                KeyFile = keyFile,
+            })
+        {
+        }
+
+        public Connection(string host, string username, PrivateKeyFile keyFile)
+            : this(new ConnectionInfo
+            {
+                Host = host,
+                Username = username,
+                KeyFile = keyFile,
+            })
+        {
+        }
+
+
+        public void Connect()
+        {
+            this._session.Connect();
+        }
+
+        public void Disconnect()
+        {
+            this._session.Disconnect();
+        }
+    }
+}

+ 96 - 0
Renci.SshClient/Renci.SshClient/Documentation/Content/Extensibility.AddAuthenticationMethod.aml

@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<topic id="ec6dd28e-c788-4812-89ae-53a26420e50b" revisionNumber="1">
+  <developerWalkthroughDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!--
+    <summary>
+      <para>Optional summary abstract</para>
+    </summary>
+    -->
+    <introduction>
+      <!-- Uncomment this to generate an outline of the section and sub-section
+           titles.  Specify a numeric value as the inner text to limit it to
+           a specific number of sub-topics when creating the outline.  Specify
+           zero (0) to limit it to top-level sections only.  -->
+      <!-- <autoOutline /> -->
+      <para>Required introduction</para>
+    </introduction>
+    <!-- <prerequisites><content>Optional prerequisites info</content></prerequisites> -->
+    <!-- One or more procedure or section with procedure -->
+    <procedure>
+      <title>Procedure title</title>
+      <steps class="ordered">
+        <step>
+          <content>
+            <para>First step</para>
+          </content>
+        </step>
+        <step>
+          <content>
+            <para>Second step</para>
+          </content>
+        </step>
+      </steps>
+      <!-- <conclusion>Optional conclusion</conclusion> -->
+    </procedure>
+    <!-- Optional additional procedure or section with procedure -->
+    <section address="Section1">
+      <title>Optional section title</title>
+      <content>
+        <procedure>
+          <title>Procedure #2</title>
+          <steps class="ordered">
+            <step>
+              <content>
+                <para>First step</para>
+              </content>
+            </step>
+            <step>
+              <content>
+                <para>Second step</para>
+              </content>
+            </step>
+          </steps>
+          <!-- <conclusion>Optional conclusion</conclusion> -->
+        </procedure>
+      </content>
+    </section>
+    <!-- Optional next steps info
+    <nextSteps>
+      <content><para>Next steps info goes here</para></content>
+    </nextSteps>
+    -->
+    <relatedTopics>
+      <!-- One or more of the following:
+           - A local link
+           - An external link
+           - A code entity reference
+
+      <link xlink:href="Other Topic's ID">Link text</link>
+      <externalLink>
+          <linkText>Link text</linkText>
+          <linkAlternateText>Optional alternate link text</linkAlternateText>
+          <linkUri>URI</linkUri>
+      </externalLink>
+      <codeEntityReference>API member ID</codeEntityReference>
+
+      Examples:
+
+      <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8278">Some other topic</link>
+
+      <externalLink>
+          <linkText>SHFB on CodePlex</linkText>
+          <linkAlternateText>Go to CodePlex</linkAlternateText>
+          <linkUri>http://shfb.codeplex.com</linkUri>
+      </externalLink>
+
+      <codeEntityReference>T:TestDoc.TestClass</codeEntityReference>
+      <codeEntityReference>P:TestDoc.TestClass.SomeProperty</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor(System.String,System.Int32)</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.ToString</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.FirstMethod</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.SecondMethod(System.Int32,System.String)</codeEntityReference>
+      -->
+    </relatedTopics>
+  </developerWalkthroughDocument>
+</topic>

+ 96 - 0
Renci.SshClient/Renci.SshClient/Documentation/Content/Extensibility.AddEncryption.aml

@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<topic id="2c568137-b080-45b0-86d0-cd157e9d0604" revisionNumber="1">
+  <developerWalkthroughDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!--
+    <summary>
+      <para>Optional summary abstract</para>
+    </summary>
+    -->
+    <introduction>
+      <!-- Uncomment this to generate an outline of the section and sub-section
+           titles.  Specify a numeric value as the inner text to limit it to
+           a specific number of sub-topics when creating the outline.  Specify
+           zero (0) to limit it to top-level sections only.  -->
+      <!-- <autoOutline /> -->
+      <para>Required introduction</para>
+    </introduction>
+    <!-- <prerequisites><content>Optional prerequisites info</content></prerequisites> -->
+    <!-- One or more procedure or section with procedure -->
+    <procedure>
+      <title>Procedure title</title>
+      <steps class="ordered">
+        <step>
+          <content>
+            <para>First step</para>
+          </content>
+        </step>
+        <step>
+          <content>
+            <para>Second step</para>
+          </content>
+        </step>
+      </steps>
+      <!-- <conclusion>Optional conclusion</conclusion> -->
+    </procedure>
+    <!-- Optional additional procedure or section with procedure -->
+    <section address="Section1">
+      <title>Optional section title</title>
+      <content>
+        <procedure>
+          <title>Procedure #2</title>
+          <steps class="ordered">
+            <step>
+              <content>
+                <para>First step</para>
+              </content>
+            </step>
+            <step>
+              <content>
+                <para>Second step</para>
+              </content>
+            </step>
+          </steps>
+          <!-- <conclusion>Optional conclusion</conclusion> -->
+        </procedure>
+      </content>
+    </section>
+    <!-- Optional next steps info
+    <nextSteps>
+      <content><para>Next steps info goes here</para></content>
+    </nextSteps>
+    -->
+    <relatedTopics>
+      <!-- One or more of the following:
+           - A local link
+           - An external link
+           - A code entity reference
+
+      <link xlink:href="Other Topic's ID">Link text</link>
+      <externalLink>
+          <linkText>Link text</linkText>
+          <linkAlternateText>Optional alternate link text</linkAlternateText>
+          <linkUri>URI</linkUri>
+      </externalLink>
+      <codeEntityReference>API member ID</codeEntityReference>
+
+      Examples:
+
+      <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8278">Some other topic</link>
+
+      <externalLink>
+          <linkText>SHFB on CodePlex</linkText>
+          <linkAlternateText>Go to CodePlex</linkAlternateText>
+          <linkUri>http://shfb.codeplex.com</linkUri>
+      </externalLink>
+
+      <codeEntityReference>T:TestDoc.TestClass</codeEntityReference>
+      <codeEntityReference>P:TestDoc.TestClass.SomeProperty</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor(System.String,System.Int32)</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.ToString</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.FirstMethod</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.SecondMethod(System.Int32,System.String)</codeEntityReference>
+      -->
+    </relatedTopics>
+  </developerWalkthroughDocument>
+</topic>

+ 96 - 0
Renci.SshClient/Renci.SshClient/Documentation/Content/Extensibility.AddHashAlgorithm.aml

@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<topic id="ea611b0c-8312-433b-88b1-d64a7222566b" revisionNumber="1">
+  <developerWalkthroughDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!--
+    <summary>
+      <para>Optional summary abstract</para>
+    </summary>
+    -->
+    <introduction>
+      <!-- Uncomment this to generate an outline of the section and sub-section
+           titles.  Specify a numeric value as the inner text to limit it to
+           a specific number of sub-topics when creating the outline.  Specify
+           zero (0) to limit it to top-level sections only.  -->
+      <!-- <autoOutline /> -->
+      <para>Required introduction</para>
+    </introduction>
+    <!-- <prerequisites><content>Optional prerequisites info</content></prerequisites> -->
+    <!-- One or more procedure or section with procedure -->
+    <procedure>
+      <title>Procedure title</title>
+      <steps class="ordered">
+        <step>
+          <content>
+            <para>First step</para>
+          </content>
+        </step>
+        <step>
+          <content>
+            <para>Second step</para>
+          </content>
+        </step>
+      </steps>
+      <!-- <conclusion>Optional conclusion</conclusion> -->
+    </procedure>
+    <!-- Optional additional procedure or section with procedure -->
+    <section address="Section1">
+      <title>Optional section title</title>
+      <content>
+        <procedure>
+          <title>Procedure #2</title>
+          <steps class="ordered">
+            <step>
+              <content>
+                <para>First step</para>
+              </content>
+            </step>
+            <step>
+              <content>
+                <para>Second step</para>
+              </content>
+            </step>
+          </steps>
+          <!-- <conclusion>Optional conclusion</conclusion> -->
+        </procedure>
+      </content>
+    </section>
+    <!-- Optional next steps info
+    <nextSteps>
+      <content><para>Next steps info goes here</para></content>
+    </nextSteps>
+    -->
+    <relatedTopics>
+      <!-- One or more of the following:
+           - A local link
+           - An external link
+           - A code entity reference
+
+      <link xlink:href="Other Topic's ID">Link text</link>
+      <externalLink>
+          <linkText>Link text</linkText>
+          <linkAlternateText>Optional alternate link text</linkAlternateText>
+          <linkUri>URI</linkUri>
+      </externalLink>
+      <codeEntityReference>API member ID</codeEntityReference>
+
+      Examples:
+
+      <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8278">Some other topic</link>
+
+      <externalLink>
+          <linkText>SHFB on CodePlex</linkText>
+          <linkAlternateText>Go to CodePlex</linkAlternateText>
+          <linkUri>http://shfb.codeplex.com</linkUri>
+      </externalLink>
+
+      <codeEntityReference>T:TestDoc.TestClass</codeEntityReference>
+      <codeEntityReference>P:TestDoc.TestClass.SomeProperty</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor(System.String,System.Int32)</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.ToString</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.FirstMethod</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.SecondMethod(System.Int32,System.String)</codeEntityReference>
+      -->
+    </relatedTopics>
+  </developerWalkthroughDocument>
+</topic>

+ 21 - 0
Renci.SshClient/Renci.SshClient/Documentation/Content/Extensibility.aml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<topic id="96a68c17-9f73-4c26-816e-bfce16366094" revisionNumber="1">
+  <developerSDKTechnologyOverviewOrientationDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!--
+    <summary>
+      <para>Optional summary abstract</para>
+    </summary>
+    -->
+    <introduction>
+      <para>Required introduction</para>
+    </introduction>
+    <inThisSection>
+      <content>
+        <para>"In This Section" info</para>
+      </content>
+    </inThisSection>
+    <!-- <reference>Optional reference info</reference> -->
+    <!-- <relatedSections>Optional related sections info</relatedSections> -->
+    <!-- <externalResources>Optional external resources info</externalResources> -->
+  </developerSDKTechnologyOverviewOrientationDocument>
+</topic>

+ 50 - 0
Renci.SshClient/Renci.SshClient/Documentation/Content/HowTo.Sftp.aml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<topic id="e9b8aa39-6ebc-4b75-83a5-497a280d77b7" revisionNumber="1">
+  <developerOrientationDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!--
+    <summary>
+      <para>Optional summary abstract</para>
+    </summary>
+    -->
+    <introduction>
+      <para>Required introduction</para>
+    </introduction>
+    <!-- <inThisSection>Optional description of content in this section</inThisSection> -->
+    <!-- <reference>Optional reference section</reference> -->
+    <!-- <relatedSections>Optional related sections info</relatedSections> -->
+    <!-- <externalResources>Optional external resources section</externalResources> -->
+    <relatedTopics>
+      <!-- One or more of the following:
+           - A local link
+           - An external link
+           - A code entity reference
+
+      <link xlink:href="Other Topic's ID">Link text</link>
+      <externalLink>
+          <linkText>Link text</linkText>
+          <linkAlternateText>Optional alternate link text</linkAlternateText>
+          <linkUri>URI</linkUri>
+      </externalLink>
+      <codeEntityReference>API member ID</codeEntityReference>
+
+      Examples:
+
+      <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8278">Some other topic</link>
+
+      <externalLink>
+          <linkText>SHFB on CodePlex</linkText>
+          <linkAlternateText>Go to CodePlex</linkAlternateText>
+          <linkUri>http://shfb.codeplex.com</linkUri>
+      </externalLink>
+
+      <codeEntityReference>T:TestDoc.TestClass</codeEntityReference>
+      <codeEntityReference>P:TestDoc.TestClass.SomeProperty</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor(System.String,System.Int32)</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.ToString</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.FirstMethod</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.SecondMethod(System.Int32,System.String)</codeEntityReference>
+      -->
+    </relatedTopics>
+  </developerOrientationDocument>
+</topic>

+ 68 - 0
Renci.SshClient/Renci.SshClient/Documentation/Content/HowTo.SshCommand.Run.aml

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<topic id="41498c7b-6dcb-46d5-88f5-0b156c08516d" revisionNumber="1">
+  <developerHowToDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <summary>
+      <para>Optional summary abstract</para>
+    </summary>
+    <introduction>
+      <para>Required introduction</para>
+    </introduction>
+    <!-- Optional procedures followed by optional code example but must have
+         at least one procedure or code example -->
+    <procedure>
+      <title>Procedure title</title>
+      <steps class="ordered">
+        <step>
+          <content>
+            <para>First step</para>
+          </content>
+        </step>
+        <step>
+          <content>
+            <para>Second step</para>
+          </content>
+        </step>
+      </steps>
+      <conclusion>Optional conclusion</conclusion>
+    </procedure>
+    <codeExample>Optional code example</codeExample>
+    <!-- <buildInstructions>Optional instructions for building a
+         code example.</buildInstructions> -->
+    <robustProgramming>Optional discussion of error handling and other
+         issues related to writing solid code.</robustProgramming>
+    <security>Optional discussion of security issues.</security>
+    <relatedTopics>
+      <!-- One or more of the following:
+           - A local link
+           - An external link
+           - A code entity reference
+
+      <link xlink:href="Other Topic's ID">Link text</link>
+      <externalLink>
+          <linkText>Link text</linkText>
+          <linkAlternateText>Optional alternate link text</linkAlternateText>
+          <linkUri>URI</linkUri>
+      </externalLink>
+      <codeEntityReference>API member ID</codeEntityReference>
+
+      Examples:
+
+      <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8278">Some other topic</link>
+
+      <externalLink>
+          <linkText>SHFB on CodePlex</linkText>
+          <linkAlternateText>Go to CodePlex</linkAlternateText>
+          <linkUri>http://shfb.codeplex.com</linkUri>
+      </externalLink>
+
+      <codeEntityReference>T:TestDoc.TestClass</codeEntityReference>
+      <codeEntityReference>P:TestDoc.TestClass.SomeProperty</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor(System.String,System.Int32)</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.ToString</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.FirstMethod</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.SecondMethod(System.Int32,System.String)</codeEntityReference>
+      -->
+    </relatedTopics>
+  </developerHowToDocument>
+</topic>

+ 50 - 0
Renci.SshClient/Renci.SshClient/Documentation/Content/HowTo.SshCommand.aml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<topic id="43c9b2df-fd0c-4041-9680-54dc908324db" revisionNumber="1">
+  <developerOrientationDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!--
+    <summary>
+      <para>Optional summary abstract</para>
+    </summary>
+    -->
+    <introduction>
+      <para>Required introduction</para>
+    </introduction>
+    <!-- <inThisSection>Optional description of content in this section</inThisSection> -->
+    <!-- <reference>Optional reference section</reference> -->
+    <!-- <relatedSections>Optional related sections info</relatedSections> -->
+    <!-- <externalResources>Optional external resources section</externalResources> -->
+    <relatedTopics>
+      <!-- One or more of the following:
+           - A local link
+           - An external link
+           - A code entity reference
+
+      <link xlink:href="Other Topic's ID">Link text</link>
+      <externalLink>
+          <linkText>Link text</linkText>
+          <linkAlternateText>Optional alternate link text</linkAlternateText>
+          <linkUri>URI</linkUri>
+      </externalLink>
+      <codeEntityReference>API member ID</codeEntityReference>
+
+      Examples:
+
+      <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8278">Some other topic</link>
+
+      <externalLink>
+          <linkText>SHFB on CodePlex</linkText>
+          <linkAlternateText>Go to CodePlex</linkAlternateText>
+          <linkUri>http://shfb.codeplex.com</linkUri>
+      </externalLink>
+
+      <codeEntityReference>T:TestDoc.TestClass</codeEntityReference>
+      <codeEntityReference>P:TestDoc.TestClass.SomeProperty</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor(System.String,System.Int32)</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.ToString</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.FirstMethod</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.SecondMethod(System.Int32,System.String)</codeEntityReference>
+      -->
+    </relatedTopics>
+  </developerOrientationDocument>
+</topic>

+ 50 - 0
Renci.SshClient/Renci.SshClient/Documentation/Content/HowTo.aml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<topic id="a07c9037-64e3-4e09-b460-8a68d95c1131" revisionNumber="1">
+  <developerOrientationDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!--
+    <summary>
+      <para>Optional summary abstract</para>
+    </summary>
+    -->
+    <introduction>
+      <para>Required introduction</para>
+    </introduction>
+    <!-- <inThisSection>Optional description of content in this section</inThisSection> -->
+    <!-- <reference>Optional reference section</reference> -->
+    <!-- <relatedSections>Optional related sections info</relatedSections> -->
+    <!-- <externalResources>Optional external resources section</externalResources> -->
+    <relatedTopics>
+      <!-- One or more of the following:
+           - A local link
+           - An external link
+           - A code entity reference
+
+      <link xlink:href="Other Topic's ID">Link text</link>
+      <externalLink>
+          <linkText>Link text</linkText>
+          <linkAlternateText>Optional alternate link text</linkAlternateText>
+          <linkUri>URI</linkUri>
+      </externalLink>
+      <codeEntityReference>API member ID</codeEntityReference>
+
+      Examples:
+
+      <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8278">Some other topic</link>
+
+      <externalLink>
+          <linkText>SHFB on CodePlex</linkText>
+          <linkAlternateText>Go to CodePlex</linkAlternateText>
+          <linkUri>http://shfb.codeplex.com</linkUri>
+      </externalLink>
+
+      <codeEntityReference>T:TestDoc.TestClass</codeEntityReference>
+      <codeEntityReference>P:TestDoc.TestClass.SomeProperty</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor(System.String,System.Int32)</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.ToString</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.FirstMethod</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.SecondMethod(System.Int32,System.String)</codeEntityReference>
+      -->
+    </relatedTopics>
+  </developerOrientationDocument>
+</topic>

+ 48 - 0
Renci.SshClient/Renci.SshClient/Documentation/Content/Introduction.aml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<topic id="af377286-3f01-4c15-8b79-66aac14561f7" revisionNumber="1">
+  <developerOrientationDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <summary>
+      <para>Optional summary abstract</para>
+    </summary>
+    <introduction>
+      <para>Required introduction</para>
+    </introduction>
+    <inThisSection>Optional description of content in this section</inThisSection>
+    <!-- <reference>Optional reference section</reference> -->
+    <!-- <relatedSections>Optional related sections info</relatedSections> -->
+    <externalResources>Optional external resources section</externalResources>
+    <relatedTopics>
+      <!-- One or more of the following:
+           - A local link
+           - An external link
+           - A code entity reference
+
+      <link xlink:href="Other Topic's ID">Link text</link>
+      <externalLink>
+          <linkText>Link text</linkText>
+          <linkAlternateText>Optional alternate link text</linkAlternateText>
+          <linkUri>URI</linkUri>
+      </externalLink>
+      <codeEntityReference>API member ID</codeEntityReference>
+
+      Examples:
+
+      <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8278">Some other topic</link>
+
+      <externalLink>
+          <linkText>SHFB on CodePlex</linkText>
+          <linkAlternateText>Go to CodePlex</linkAlternateText>
+          <linkUri>http://shfb.codeplex.com</linkUri>
+      </externalLink>
+
+      <codeEntityReference>T:TestDoc.TestClass</codeEntityReference>
+      <codeEntityReference>P:TestDoc.TestClass.SomeProperty</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.#ctor(System.String,System.Int32)</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.ToString</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.FirstMethod</codeEntityReference>
+      <codeEntityReference>M:TestDoc.TestClass.SecondMethod(System.Int32,System.String)</codeEntityReference>
+      -->
+    </relatedTopics>
+  </developerOrientationDocument>
+</topic>

+ 10 - 0
Renci.SshClient/Renci.SshClient/Messages/Authentication/Methods.cs

@@ -0,0 +1,10 @@
+namespace Renci.SshClient.Messages.Authentication
+{
+    public enum Methods
+    {
+        None,
+        PublicKey,
+        Password,
+        Hostbased
+    }
+}

+ 33 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelOpenDirectTcpIPMessage.cs

@@ -0,0 +1,33 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelOpenDirectTcpIPMessage : ChannelOpenMessage
+    {
+        public string HostToConnect { get; private set; }
+
+        public uint PortToConnect { get; private set; }
+
+        public string OriginatorIP { get; private set; }
+
+        public uint OriginatorPort { get; private set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+            this.HostToConnect = this.ReadString();
+            this.PortToConnect = this.ReadUInt32();
+            this.OriginatorIP = this.ReadString();
+            this.OriginatorPort = this.ReadUInt32();
+        }
+
+        protected override void SaveData()
+        {
+            base.SaveData();
+            this.Write(this.HostToConnect);
+            this.Write(this.PortToConnect);
+            this.Write(this.OriginatorIP);
+            this.Write(this.OriginatorPort);
+
+        }
+    }
+}

+ 30 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestEnvironmentVariableMessage.cs

@@ -0,0 +1,30 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelRequestEnvironmentVariableMessage : ChannelRequestMessage
+    {
+        public const string REQUEST_NAME = "env";
+
+        public string VariableName { get; set; }
+
+        public string VariableValue { get; set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+
+            this.VariableName = this.ReadString();
+            this.VariableValue = this.ReadString();
+        }
+
+        protected override void SaveData()
+        {
+            this.RequestName = REQUEST_NAME;
+
+            base.SaveData();
+
+            this.Write(this.VariableName);
+            this.Write(this.VariableValue);
+        }
+    }
+}

+ 26 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestExecMessage.cs

@@ -0,0 +1,26 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelRequestExecMessage : ChannelRequestMessage
+    {
+        public const string REQUEST_NAME = "exec";
+
+        public string Command { get; set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+
+            this.Command = this.ReadString();
+        }
+
+        protected override void SaveData()
+        {
+            this.RequestName = REQUEST_NAME;
+
+            base.SaveData();
+
+            this.Write(this.Command);
+        }
+    }
+}

+ 38 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestExitSignalMessage.cs

@@ -0,0 +1,38 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelRequestExitSignalMessage : ChannelRequestMessage
+    {
+        public const string REQUEST_NAME = "exit-signal";
+
+        public string SignalName { get; set; }
+
+        public bool CoreDumped { get; set; }
+
+        public string ErrorMessage { get; set; }
+
+        public string Language { get; set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+
+            this.SignalName = this.ReadString();
+            this.CoreDumped = this.ReadBoolean();
+            this.ErrorMessage = this.ReadString();
+            this.Language = this.ReadString();
+        }
+
+        protected override void SaveData()
+        {
+            this.RequestName = REQUEST_NAME;
+
+            base.SaveData();
+
+            this.Write(this.SignalName);
+            this.Write(this.CoreDumped);
+            this.Write(this.ErrorMessage);
+            this.Write(this.Language);
+        }
+    }
+}

+ 23 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestExitStatusMessage.cs

@@ -0,0 +1,23 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelRequestExitStatusMessage : ChannelRequestMessage
+    {
+        public const string REQUEST_NAME = "exit-status";
+
+        public uint ExitStatus { get; set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+            this.ExitStatus = this.ReadUInt32();
+        }
+
+        protected override void SaveData()
+        {
+            this.RequestName = REQUEST_NAME;
+            base.SaveData();
+            this.Write(this.ExitStatus);
+        }
+    }
+}

+ 44 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestPseudoTerminalMessage.cs

@@ -0,0 +1,44 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelRequestPseudoTerminalMessage : ChannelRequestMessage
+    {
+        public const string REQUEST_NAME = "pty-req";
+
+        public string EnvironmentVariable { get; set; }
+
+        public uint Columns { get; set; }
+
+        public uint Rows { get; set; }
+
+        public uint PixelWidth { get; set; }
+
+        public uint PixelHeight { get; set; }
+
+        public string TerminalMode { get; set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+            this.EnvironmentVariable = this.ReadString();
+            this.Columns = this.ReadUInt32();
+            this.Rows = this.ReadUInt32();
+            this.PixelWidth = this.ReadUInt32();
+            this.PixelHeight = this.ReadUInt32();
+            this.TerminalMode = this.ReadString();
+        }
+
+        protected override void SaveData()
+        {
+            this.RequestName = REQUEST_NAME;
+            base.SaveData();
+            this.Write(this.EnvironmentVariable);
+            this.Write(this.Columns);
+            this.Write(this.Rows);
+            this.Write(this.Rows);
+            this.Write(this.PixelHeight);
+            this.Write(this.TerminalMode);
+
+        }
+    }
+}

+ 19 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestShellMessage.cs

@@ -0,0 +1,19 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelRequestShellMessage : ChannelRequestMessage
+    {
+        public const string REQUEST_NAME = "shell";
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+        }
+
+        protected override void SaveData()
+        {
+            this.RequestName = REQUEST_NAME;
+            base.SaveData();
+        }
+    }
+}

+ 26 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestSignalMessage.cs

@@ -0,0 +1,26 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelRequestSignalMessage : ChannelRequestMessage
+    {
+        public const string REQUEST_NAME = "signal";
+
+        public string SignalName { get; set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+
+            this.SignalName = this.ReadString();
+        }
+
+        protected override void SaveData()
+        {
+            this.RequestName = REQUEST_NAME;
+
+            base.SaveData();
+
+            this.Write(this.SignalName);
+        }
+    }
+}

+ 26 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestSubsystemMessage.cs

@@ -0,0 +1,26 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelRequestSubsystemMessage : ChannelRequestMessage
+    {
+        public const string REQUEST_NAME = "subsystem";
+
+        public string SubsystemName { get; set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+
+            this.SubsystemName = this.ReadString();
+        }
+
+        protected override void SaveData()
+        {
+            this.RequestName = REQUEST_NAME;
+
+            base.SaveData();
+
+            this.Write(this.SubsystemName);
+        }
+    }
+}

+ 38 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestWindowChangeMessage.cs

@@ -0,0 +1,38 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelRequestWindowChangeMessage : ChannelRequestMessage
+    {
+        public const string REQUEST_NAME = "window-change";
+
+        public uint Columns { get; set; }
+
+        public uint Rows { get; set; }
+
+        public uint Width { get; set; }
+
+        public uint Height { get; set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+
+            this.Columns = this.ReadUInt32();
+            this.Rows = this.ReadUInt32();
+            this.Width = this.ReadUInt32();
+            this.Height = this.ReadUInt32();
+        }
+
+        protected override void SaveData()
+        {
+            this.RequestName = REQUEST_NAME;
+
+            base.SaveData();
+
+            this.Write(this.Columns);
+            this.Write(this.Rows);
+            this.Write(this.Width);
+            this.Write(this.Height);
+        }
+    }
+}

+ 38 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestX11ForwardingMessage.cs

@@ -0,0 +1,38 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelRequestX11ForwardingMessage : ChannelRequestMessage
+    {
+        public const string REQUEST_NAME = "x11-req";
+
+        public bool IsSingleConnection { get; set; }
+
+        public string AuthenticationProtocol { get; set; }
+
+        public string AuthenticationCookie { get; set; }
+
+        public uint ScreenNumber { get; set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+
+            this.IsSingleConnection = this.ReadBoolean();
+            this.AuthenticationProtocol = this.ReadString();
+            this.AuthenticationCookie = this.ReadString();
+            this.ScreenNumber = this.ReadUInt32();
+        }
+
+        protected override void SaveData()
+        {
+            this.RequestName = REQUEST_NAME;
+
+            base.SaveData();
+
+            this.Write(this.IsSingleConnection);
+            this.Write(this.AuthenticationProtocol);
+            this.Write(this.AuthenticationCookie);
+            this.Write(this.ScreenNumber);
+        }
+    }
+}

+ 26 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestXonXoffMessage.cs

@@ -0,0 +1,26 @@
+
+namespace Renci.SshClient.Messages.Connection
+{
+    internal class ChannelRequestXonXoffMessage : ChannelRequestMessage
+    {
+        public const string REQUEST_NAME = "xon-xoff";
+
+        public bool ClientCanDo { get; set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+
+            this.ClientCanDo = this.ReadBoolean();
+        }
+
+        protected override void SaveData()
+        {
+            this.RequestName = REQUEST_NAME;
+
+            base.SaveData();
+
+            this.Write(this.ClientCanDo);
+        }
+    }
+}

+ 50 - 0
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequestNames.cs

@@ -0,0 +1,50 @@
+namespace Renci.SshClient.Messages.Connection
+{
+    internal enum ChannelRequestNames
+    {
+        /// <summary>
+        /// pty-req
+        /// </summary>
+        PseudoTerminal,
+        /// <summary>
+        /// x11-req
+        /// </summary>
+        X11Forwarding,
+        /// <summary>
+        /// env
+        /// </summary>
+        EnvironmentVariable,
+        /// <summary>
+        /// shell
+        /// </summary>
+        Shell,
+        /// <summary>
+        /// exec
+        /// </summary>
+        Exec,
+        /// <summary>
+        /// subsystem
+        /// </summary>
+        Subsystem,
+        /// <summary>
+        /// window-change
+        /// </summary>
+        WindowChange,
+        /// <summary>
+        /// xon-xoff
+        /// </summary>
+        XonXoff,
+        /// <summary>
+        /// signal
+        /// </summary>
+        Signal,
+        /// <summary>
+        /// exit-status
+        /// </summary>
+        ExitStatus,
+        /// <summary>
+        /// exit-signal
+        /// </summary>
+        ExitSignal
+    }
+}

+ 161 - 0
Renci.SshClient/Renci.SshClient/Messages/MessageTypes.cs

@@ -0,0 +1,161 @@
+namespace Renci.SshClient.Messages
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    public enum MessageTypes : byte
+    {
+        /// <summary>
+        /// {35A90EBF-F421-44A3-BE3A-47C72AFE47FE}
+        /// </summary>
+        None = 0,
+        /// <summary>
+        /// SSH_MSG_DISCONNECT
+        /// </summary>
+        Disconnect = 1,
+        /// <summary>
+        /// SSH_MSG_IGNORE
+        /// </summary>
+        Ignore = 2,
+        /// <summary>
+        /// SSH_MSG_UNIMPLEMENTED
+        /// </summary>
+        Unimplemented = 3,
+        /// <summary>
+        /// SSH_MSG_DEBUG
+        /// </summary>
+        Debug = 4,
+        /// <summary>
+        /// SSH_MSG_SERVICE_REQUEST
+        /// </summary>
+        ServiceRequest = 5,
+        /// <summary>
+        /// SSH_MSG_SERVICE_ACCEPT
+        /// </summary>
+        ServiceAcceptRequest = 6,
+
+        /// <summary>
+        /// SSH_MSG_KEXINIT
+        /// </summary>
+        KeyExchangeInit = 20,
+        /// <summary>
+        /// SSH_MSG_NEWKEYS
+        /// </summary>
+        NewKeys = 21,
+        /// <summary>
+        /// SSH_MSG_KEXDH_INIT
+        /// </summary>
+        DiffieHellmanKeyExchangeInit = 30,
+        /// <summary>
+        /// SSH_MSG_KEXDH_REPLY
+        /// </summary>
+        KeyExchangeDhReply = 31,
+        /// <summary>
+        /// SSH_MSG_KEX_DH_GEX_GROUP
+        /// </summary>
+        KeyExchangeDhGroupExchangeGroup = 31,
+        /// <summary>
+        /// SSH_MSG_KEX_DH_GEX_INIT
+        /// </summary>
+        KeyExchangeDhGroupExchangeInit = 32,
+        /// <summary>
+        /// SSH_MSG_KEX_DH_GEX_REPLY
+        /// </summary>
+        KeyExchangeDhGroupExchangeReply = 33,
+        /// <summary>
+        /// SSH_MSG_KEX_DH_GEX_REQUEST
+        /// </summary>
+        KeyExchangeDhGroupExchangeRequest = 34,
+
+        /// <summary>
+        /// SSH_MSG_USERAUTH_REQUEST
+        /// </summary>
+        UserAuthenticationRequest = 50,
+        /// <summary>
+        /// SSH_MSG_USERAUTH_FAILURE
+        /// </summary>
+        UserAuthenticationFailure = 51,
+        /// <summary>
+        /// SSH_MSG_USERAUTH_SUCCESS
+        /// </summary>
+        UserAuthenticationSuccess = 52,
+        /// <summary>
+        /// SSH_MSG_USERAUTH_BANNER
+        /// </summary>
+        UserAuthenticationBanner = 53,
+        /// <summary>
+        /// SSH_MSG_USERAUTH_INFO_REQUEST
+        /// </summary>
+        UserAuthenticationInformationRequest = 60,
+        /// <summary>
+        /// SSH_MSG_USERAUTH_INFO_RESPONSE
+        /// </summary>
+        UserAuthenticationInformationResponse = 61,
+        /// <summary>
+        /// SSH_MSG_USERAUTH_PK_OK
+        /// </summary>
+        UserAuthenticationPublicKey = 60,
+        /// <summary>
+        /// SSH_MSG_USERAUTH_PASSWD_CHANGEREQ
+        /// </summary>
+        UserAuthenticationPasswordChangeRequired = 60,
+
+
+        /// <summary>
+        /// SSH_MSG_GLOBAL_REQUEST
+        /// </summary>
+        GlobalRequest = 80,
+        /// <summary>
+        /// SSH_MSG_REQUEST_SUCCESS
+        /// </summary>
+        RequestSuccess = 81,
+        /// <summary>
+        /// SSH_MSG_REQUEST_FAILURE
+        /// </summary>
+        RequestFailure = 82,
+        /// <summary>
+        /// SSH_MSG_CHANNEL_OPEN
+        /// </summary>
+        ChannelOpen = 90,
+        /// <summary>
+        /// SSH_MSG_CHANNEL_OPEN_CONFIRMATION
+        /// </summary>
+        ChannelOpenConfirmation = 91,
+        /// <summary>
+        /// SSH_MSG_CHANNEL_OPEN_FAILURE
+        /// </summary>
+        ChannelOpenFailure = 92,
+        /// <summary>
+        /// SSH_MSG_CHANNEL_WINDOW_ADJUST
+        /// </summary>
+        ChannelWindowAdjust = 93,
+        /// <summary>
+        /// SSH_MSG_CHANNEL_DATA
+        /// </summary>
+        ChannelData = 94,
+        /// <summary>
+        /// SSH_MSG_CHANNEL_EXTENDED_DATA
+        /// </summary>
+        ChannelExtendedData = 95,
+        /// <summary>
+        /// SSH_MSG_CHANNEL_EOF
+        /// </summary>
+        ChannelEof = 96,
+        /// <summary>
+        /// SSH_MSG_CHANNEL_CLOSE
+        /// </summary>
+        ChannelClose = 97,
+        /// <summary>
+        /// SSH_MSG_CHANNEL_REQUEST
+        /// </summary>
+        ChannelRequest = 98,
+        /// <summary>
+        /// SSH_MSG_CHANNEL_SUCCESS
+        /// </summary>
+        ChannelSuccess = 99,
+        /// <summary>
+        /// SSH_MSG_CHANNEL_FAILURE
+        /// </summary>
+        ChannelFailure = 100,
+    }
+}

+ 9 - 0
Renci.SshClient/Renci.SshClient/RequestSuccessEventArgs.cs

@@ -0,0 +1,9 @@
+using System;
+
+namespace Renci.SshClient
+{
+    internal class RequestSuccessEventArgs : EventArgs
+    {
+        public uint BoundPort { get; set; }
+    }
+}

+ 124 - 0
Renci.SshClient/Renci.SshClient/Security/CipherAES128.cs

@@ -0,0 +1,124 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+
+namespace Renci.SshClient.Security
+{
+    internal class CipherAES128 : Cipher, IDisposable
+    {
+        private SymmetricAlgorithm _algorithm;
+
+        private ICryptoTransform _encryptor;
+
+        private ICryptoTransform _decryptor;
+
+        public override string Name
+        {
+            get { return "aes128-cbc"; }
+        }
+
+        public override int KeySize
+        {
+            get
+            {
+                return this._algorithm.KeySize;
+            }
+        }
+
+        public override int BlockSize
+        {
+            get
+            {
+                return this._algorithm.BlockSize / 8;
+            }
+        }
+
+        public CipherAES128()
+        {
+            this._algorithm = new System.Security.Cryptography.RijndaelManaged();
+            this._algorithm.Mode = System.Security.Cryptography.CipherMode.CBC;
+            this._algorithm.Padding = System.Security.Cryptography.PaddingMode.None;
+        }
+
+        public override IEnumerable<byte> Encrypt(IEnumerable<byte> data)
+        {
+            if (this._encryptor == null)
+            {
+                this._encryptor = this._algorithm.CreateEncryptor(this.Key.Take(this.KeySize / 8).ToArray(), this.Vector.Take(this.BlockSize).ToArray());
+            }
+
+            var input = data.ToArray();
+            var output = new byte[input.Length];
+            var writtenBytes = this._encryptor.TransformBlock(input, 0, input.Length, output, 0);
+
+            if (writtenBytes < input.Length)
+            {
+                throw new InvalidOperationException("Encryption error.");
+            }
+
+            return output;
+        }
+
+        public override IEnumerable<byte> Decrypt(IEnumerable<byte> data)
+        {
+            if (this._decryptor == null)
+            {
+                this._decryptor = this._algorithm.CreateDecryptor(this.Key.Take(this.KeySize / 8).ToArray(), this.Vector.Take(this.BlockSize).ToArray());
+            }
+
+            var input = data.ToArray();
+            var output = new byte[input.Length];
+            var writtenBytes = this._decryptor.TransformBlock(input, 0, input.Length, output, 0);
+
+            if (writtenBytes < input.Length)
+            {
+                throw new InvalidOperationException("Encryption error.");
+            }
+
+            return output;
+        }
+
+        #region IDisposable Members
+
+        private bool disposed = false;
+
+        public void Dispose()
+        {
+            Dispose(true);
+
+            GC.SuppressFinalize(this);
+        }
+
+        private void Dispose(bool disposing)
+        {
+            // Check to see if Dispose has already been called.
+            if (!this.disposed)
+            {
+                // If disposing equals true, dispose all managed
+                // and unmanaged resources.
+                if (disposing)
+                {
+                    // Dispose managed resources.
+                    if (this._algorithm != null)
+                    {
+                        this._algorithm.Dispose();
+                    }
+                }
+
+                // Note disposing has been done.
+                disposed = true;
+            }
+        }
+
+        ~CipherAES128()
+        {
+            // Do not re-create Dispose clean-up code here.
+            // Calling Dispose(false) is optimal in terms of
+            // readability and maintainability.
+            Dispose(false);
+        }
+
+        #endregion
+    }
+}

+ 8 - 0
Renci.SshClient/Renci.SshClient/Security/KeyExchangeCompletedEventArgs.cs

@@ -0,0 +1,8 @@
+using System;
+
+namespace Renci.SshClient.Security
+{
+    internal class KeyExchangeCompletedEventArgs : EventArgs
+    {
+    }
+}

+ 14 - 0
Renci.SshClient/Renci.SshClient/Security/KeyExchangeFailedEventArgs.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace Renci.SshClient.Security
+{
+    internal class KeyExchangeFailedEventArgs : EventArgs
+    {
+        public string Message { get; private set; }
+
+        public KeyExchangeFailedEventArgs(string message)
+        {
+            this.Message = message;
+        }
+    }
+}

+ 15 - 0
Renci.SshClient/Renci.SshClient/Security/KeyExchangeSendMessageEventArgs.cs

@@ -0,0 +1,15 @@
+using System;
+using Renci.SshClient.Messages;
+
+namespace Renci.SshClient.Security
+{
+    internal class KeyExchangeSendMessageEventArgs : EventArgs
+    {
+        public KeyExchangeSendMessageEventArgs(Message message)
+        {
+            this.Message = message;
+        }
+
+        public Message Message { get; private set; }
+    }
+}

+ 39 - 0
Renci.SshClient/Renci.SshClient/Security/PrivateKey.cs

@@ -0,0 +1,39 @@
+using System.Collections.Generic;
+using Renci.SshClient.Common;
+
+namespace Renci.SshClient.Security
+{
+    internal abstract class PrivateKey
+    {
+        public abstract string AlgorithmName { get; }
+
+        protected IEnumerable<byte> Data { get; private set; }
+
+        public abstract IEnumerable<byte> PublicKey { get; }
+
+        public PrivateKey(IEnumerable<byte> data)
+        {
+            this.Data = data;
+        }
+
+        public abstract IEnumerable<byte> GetSignature(IEnumerable<byte> sessionId);
+
+        protected class SignatureKeyData : SshData
+        {
+            public string AlgorithmName { get; set; }
+
+            public IEnumerable<byte> Signature { get; set; }
+
+            protected override void LoadData()
+            {
+            }
+
+            protected override void SaveData()
+            {
+                this.Write(this.AlgorithmName);
+                this.Write(this.Signature.GetSshString());
+            }
+        }
+
+    }
+}

+ 192 - 0
Renci.SshClient/Renci.SshClient/Security/PrivateKeyDsa.cs

@@ -0,0 +1,192 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+using Renci.SshClient.Common;
+
+namespace Renci.SshClient.Security
+{
+    internal class PrivateKeyDsa : PrivateKey
+    {
+        private byte[] _pValue;
+
+        private byte[] _qValue;
+
+        private byte[] _gValue;
+
+        private byte[] _publicKeyValue;
+
+        private byte[] _privateKeyValue;
+
+        private IEnumerable<byte> _publicKey;
+        /// <summary>
+        /// Gets the public key.
+        /// </summary>
+        /// <value>The public key.</value>
+        public override IEnumerable<byte> PublicKey
+        {
+            get
+            {
+                if (this._publicKey == null)
+                {
+                    this._publicKey = new DsaPublicKeyData
+                    {
+                        P = this._pValue,
+                        Q = this._qValue,
+                        G = this._gValue,
+                        Public = this._publicKeyValue,
+                    }.GetBytes();
+
+                }
+                return this._publicKey;
+            }
+        }
+
+        public override string AlgorithmName
+        {
+            get { return "ssh-dss"; }
+        }
+
+
+        public PrivateKeyDsa(IEnumerable<byte> data)
+            : base(data)
+        {
+            if (!this.ParseDSAPrivateKey())
+            {
+                throw new InvalidDataException("DSA Key is not valid");
+            }
+        }
+
+        public override IEnumerable<byte> GetSignature(IEnumerable<byte> sessionId)
+        {
+            var data = sessionId.ToArray();
+            using (var sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider())
+            using (var cs = new System.Security.Cryptography.CryptoStream(System.IO.Stream.Null, sha1, System.Security.Cryptography.CryptoStreamMode.Write))
+            {
+                DSAParameters DSAKeyInfo = new DSAParameters();
+
+                DSAKeyInfo.X = this._privateKeyValue.TrimLeadinZero().ToArray();
+                DSAKeyInfo.P = this._pValue.TrimLeadinZero().ToArray();
+                DSAKeyInfo.Q = this._qValue.TrimLeadinZero().ToArray();
+                DSAKeyInfo.G = this._gValue.TrimLeadinZero().ToArray();
+
+                cs.Write(data, 0, data.Length);
+
+                cs.Close();
+
+                var DSA = new System.Security.Cryptography.DSACryptoServiceProvider();
+                DSA.ImportParameters(DSAKeyInfo);
+                var DSAFormatter = new RSAPKCS1SignatureFormatter(DSA);
+                DSAFormatter.SetHashAlgorithm("SHA1");
+
+                var signature = DSAFormatter.CreateSignature(sha1);
+
+                return new SignatureKeyData
+                {
+                    AlgorithmName = this.AlgorithmName,
+                    Signature = signature,
+                }.GetBytes();
+            }
+
+        }
+
+        private bool ParseDSAPrivateKey()
+        {
+            // ---------  Set up stream to decode the asn.1 encoded RSA private key  ------
+            using (var ms = new MemoryStream(this.Data.ToArray()))
+            using (var binr = new BinaryReader(ms)) //wrap Memory Stream with BinaryReader for easy reading
+            {
+                byte bt = 0;
+                ushort twobytes = 0;
+                int elems = 0;
+
+                twobytes = binr.ReadUInt16();
+                if (twobytes == 0x8130)	//data read as little endian order (actual data order for Sequence is 30 81)
+                    binr.ReadByte();	//advance 1 byte
+                else if (twobytes == 0x8230)
+                    binr.ReadInt16();	//advance 2 bytes
+                else
+                    return false;
+
+                twobytes = binr.ReadUInt16();
+                if (twobytes != 0x0102)	//version number
+                    return false;
+                bt = binr.ReadByte();
+                if (bt != 0x00)
+                    return false;
+
+                //------  all private key components are Integer sequences ----
+                elems = GetIntegerSize(binr);
+                this._pValue = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                this._qValue = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                this._gValue = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                this._publicKeyValue = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                this._privateKeyValue = binr.ReadBytes(elems);
+            }
+
+            return true;
+        }
+
+        private static int GetIntegerSize(BinaryReader binr)
+        {
+            byte bt = 0;
+            byte lowbyte = 0x00;
+            byte highbyte = 0x00;
+            int count = 0;
+            bt = binr.ReadByte();
+            if (bt != 0x02)		//expect integer
+                return 0;
+            bt = binr.ReadByte();
+
+            if (bt == 0x81)
+                count = binr.ReadByte();	// data size in next byte
+            else
+                if (bt == 0x82)
+                {
+                    highbyte = binr.ReadByte();	// data size in next 2 bytes
+                    lowbyte = binr.ReadByte();
+                    byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
+                    count = BitConverter.ToInt32(modint, 0);
+                }
+                else
+                {
+                    count = bt;		// we already have the data size
+                }
+
+            return count;
+        }
+
+        private class DsaPublicKeyData : SshData
+        {
+            public IEnumerable<byte> P { get; set; }
+
+            public IEnumerable<byte> Q { get; set; }
+
+            public IEnumerable<byte> G { get; set; }
+
+            public IEnumerable<byte> Public { get; set; }
+
+            protected override void LoadData()
+            {
+            }
+
+            protected override void SaveData()
+            {
+                this.Write("ssh-dss");
+                this.Write(this.P.GetSshString());
+                this.Write(this.Q.GetSshString());
+                this.Write(this.G.GetSshString());
+                this.Write(this.Public.GetSshString());
+            }
+        }
+    }
+}

+ 197 - 0
Renci.SshClient/Renci.SshClient/Security/PrivateKeyRsa.cs

@@ -0,0 +1,197 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+using Renci.SshClient.Common;
+
+namespace Renci.SshClient.Security
+{
+    internal class PrivateKeyRsa : PrivateKey
+    {
+        private byte[] _modulus;
+        private byte[] _eValue;
+        private byte[] _dValue;
+        private byte[] _pValue;
+        private byte[] _qValue;
+        private byte[] _dpValue;
+        private byte[] _dqValue;
+        private byte[] _iqValue;
+
+        private IEnumerable<byte> _publicKey;
+        /// <summary>
+        /// Gets the public key.
+        /// </summary>
+        /// <value>The public key.</value>
+        public override IEnumerable<byte> PublicKey
+        {
+            get
+            {
+                if (this._publicKey == null)
+                {
+                    this._publicKey = new RsaPublicKeyData
+                    {
+                        E = this._eValue,
+                        Modulus = this._modulus,
+                    }.GetBytes();
+
+                }
+                return this._publicKey;
+            }
+        }
+
+        public override string AlgorithmName
+        {
+            get { return "ssh-rsa"; }
+        }
+
+
+        public PrivateKeyRsa(IEnumerable<byte> data)
+            : base(data)
+        {
+            if (!this.ParseRSAPrivateKey())
+            {
+                throw new InvalidDataException("RSA Key is not valid");
+            }
+        }
+
+        public override IEnumerable<byte> GetSignature(IEnumerable<byte> sessionId)
+        {
+            var data = sessionId.ToArray();
+            using (var sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider())
+            using (var cs = new System.Security.Cryptography.CryptoStream(System.IO.Stream.Null, sha1, System.Security.Cryptography.CryptoStreamMode.Write))
+            {
+                RSAParameters RSAKeyInfo = new RSAParameters();
+
+                RSAKeyInfo.Exponent = _eValue.TrimLeadinZero().ToArray();
+                RSAKeyInfo.D = _dValue.TrimLeadinZero().ToArray();
+                RSAKeyInfo.Modulus = _modulus.TrimLeadinZero().ToArray();
+                RSAKeyInfo.P = _pValue.TrimLeadinZero().ToArray();
+                RSAKeyInfo.Q = _qValue.TrimLeadinZero().ToArray();
+                RSAKeyInfo.DP = _dpValue.TrimLeadinZero().ToArray();
+                RSAKeyInfo.DQ = _dqValue.TrimLeadinZero().ToArray();
+                RSAKeyInfo.InverseQ = _iqValue.TrimLeadinZero().ToArray();
+
+                cs.Write(data, 0, data.Length);
+
+                cs.Close();
+
+                var RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
+                RSA.ImportParameters(RSAKeyInfo);
+                var RSAFormatter = new RSAPKCS1SignatureFormatter(RSA);
+                RSAFormatter.SetHashAlgorithm("SHA1");
+
+                var signature = RSAFormatter.CreateSignature(sha1);
+
+                return new SignatureKeyData
+                {
+                    AlgorithmName = this.AlgorithmName,
+                    Signature = signature,
+                }.GetBytes();
+            }
+
+        }
+
+        private bool ParseRSAPrivateKey()
+        {
+            // ---------  Set up stream to decode the asn.1 encoded RSA private key  ------
+            using (var ms = new MemoryStream(this.Data.ToArray()))
+            using (var binr = new BinaryReader(ms)) //wrap Memory Stream with BinaryReader for easy reading
+            {
+                byte bt = 0;
+                ushort twobytes = 0;
+                int elems = 0;
+
+                twobytes = binr.ReadUInt16();
+                if (twobytes == 0x8130)	//data read as little endian order (actual data order for Sequence is 30 81)
+                    binr.ReadByte();	//advance 1 byte
+                else if (twobytes == 0x8230)
+                    binr.ReadInt16();	//advance 2 bytes
+                else
+                    return false;
+
+                twobytes = binr.ReadUInt16();
+                if (twobytes != 0x0102)	//version number
+                    return false;
+                bt = binr.ReadByte();
+                if (bt != 0x00)
+                    return false;
+
+
+                //------  all private key components are Integer sequences ----
+                elems = GetIntegerSize(binr);
+                this._modulus = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                this._eValue = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                this._dValue = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                this._pValue = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                this._qValue = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                this._dpValue = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                this._dqValue = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                this._iqValue = binr.ReadBytes(elems);
+
+                return true;
+            }
+        }
+
+        private static int GetIntegerSize(BinaryReader binr)
+        {
+            byte bt = 0;
+            byte lowbyte = 0x00;
+            byte highbyte = 0x00;
+            int count = 0;
+            bt = binr.ReadByte();
+            if (bt != 0x02)		//expect integer
+                return 0;
+            bt = binr.ReadByte();
+
+            if (bt == 0x81)
+                count = binr.ReadByte();	// data size in next byte
+            else
+                if (bt == 0x82)
+                {
+                    highbyte = binr.ReadByte();	// data size in next 2 bytes
+                    lowbyte = binr.ReadByte();
+                    byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
+                    count = BitConverter.ToInt32(modint, 0);
+                }
+                else
+                {
+                    count = bt;		// we already have the data size
+                }
+
+            return count;
+        }
+
+        private class RsaPublicKeyData : SshData
+        {
+            public IEnumerable<byte> Modulus { get; set; }
+
+            public IEnumerable<byte> E { get; set; }
+
+            protected override void LoadData()
+            {
+            }
+
+            protected override void SaveData()
+            {
+                this.Write("ssh-rsa");
+                this.Write(this.E.GetSshString());
+                this.Write(this.Modulus.GetSshString());
+            }
+        }
+    }
+}

+ 16 - 0
Renci.SshClient/Renci.SshClient/Security/Signature.cs

@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace Renci.SshClient.Security
+{
+    internal abstract class Signature : Algorithm
+    {
+        protected IEnumerable<byte> Data { get; private set; }
+
+        public Signature(IEnumerable<byte> data)
+        {
+            this.Data = data;
+        }
+
+        public abstract bool ValidateSignature(IEnumerable<byte> hash, IEnumerable<byte> signature);
+    }
+}

+ 91 - 0
Renci.SshClient/Renci.SshClient/Security/SignatureDss.cs

@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+
+namespace Renci.SshClient.Security
+{
+    internal class SignatureDss : Signature
+    {
+        public override string Name
+        {
+            get { return "ssh-dss"; }
+        }
+
+        public SignatureDss(IEnumerable<byte> data)
+            : base(data)
+        {
+
+        }
+
+        public override bool ValidateSignature(IEnumerable<byte> hash, IEnumerable<byte> signature)
+        {
+            var pLength = BitConverter.ToUInt32(this.Data.Take(4).Reverse().ToArray(), 0);
+
+            var pData = this.Data.Skip(4).Take((int)pLength).ToArray();
+
+            var qLength = BitConverter.ToUInt32(this.Data.Skip(4 + (int)pLength).Take(4).Reverse().ToArray(), 0);
+
+            var qData = this.Data.Skip(4 + (int)pLength + 4).Take((int)qLength).ToArray();
+
+            var gLength = BitConverter.ToUInt32(this.Data.Skip(4 + (int)pLength + 4 + (int)qLength).Take(4).Reverse().ToArray(), 0);
+
+            var gData = this.Data.Skip(4 + (int)pLength + 4 + (int)qLength + 4).Take((int)gLength).ToArray();
+
+            var xLength = BitConverter.ToUInt32(this.Data.Skip(4 + (int)pLength + 4 + (int)qLength + 4 + (int)gLength).Take(4).Reverse().ToArray(), 0);
+
+            var xData = this.Data.Skip(4 + (int)pLength + 4 + (int)qLength + 4 + (int)xLength + 4).Take((int)xLength).ToArray();
+
+            using (var sha1 = new SHA1CryptoServiceProvider())
+            {
+                using (var cs = new CryptoStream(System.IO.Stream.Null, sha1, CryptoStreamMode.Write))
+                {
+                    var data = hash.ToArray();
+                    cs.Write(data, 0, data.Length);
+                    cs.Close();
+                }
+
+                using (var dsa = new DSACryptoServiceProvider())
+                {
+                    dsa.ImportParameters(new DSAParameters
+                    {
+                        X = xData.TrimLeadinZero().ToArray(),
+                        P = pData.TrimLeadinZero().ToArray(),
+                        Q = qData.TrimLeadinZero().ToArray(),
+                        G = gData.TrimLeadinZero().ToArray(),
+                    });
+                    var dsaDeformatter = new DSASignatureDeformatter(dsa);
+                    dsaDeformatter.SetHashAlgorithm("SHA1");
+
+                    long i = 0;
+                    long j = 0;
+                    byte[] tmp;
+
+                    var sig = signature.ToArray();
+                    if (sig[0] == 0 && sig[1] == 0 && sig[2] == 0)
+                    {
+                        long i1 = (sig[i++] << 24) & 0xff000000;
+                        long i2 = (sig[i++] << 16) & 0x00ff0000;
+                        long i3 = (sig[i++] << 8) & 0x0000ff00;
+                        long i4 = (sig[i++]) & 0x000000ff;
+                        j = i1 | i2 | i3 | i4;
+
+                        i += j;
+
+                        i1 = (sig[i++] << 24) & 0xff000000;
+                        i2 = (sig[i++] << 16) & 0x00ff0000;
+                        i3 = (sig[i++] << 8) & 0x0000ff00;
+                        i4 = (sig[i++]) & 0x000000ff;
+                        j = i1 | i2 | i3 | i4;
+
+                        tmp = new byte[j];
+                        Array.Copy(sig, i, tmp, 0, j);
+                        sig = tmp;
+                    }
+
+                    return dsaDeformatter.VerifySignature(sha1, sig);
+                }
+            }
+        }
+    }
+}

+ 81 - 0
Renci.SshClient/Renci.SshClient/Security/SignatureRsa.cs

@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+
+namespace Renci.SshClient.Security
+{
+    internal class SignatureRsa : Signature
+    {
+        public override string Name
+        {
+            get { return "ssh-rsa"; }
+        }
+
+        public SignatureRsa(IEnumerable<byte> data)
+            : base(data)
+        {
+
+        }
+
+        public override bool ValidateSignature(IEnumerable<byte> hash, IEnumerable<byte> signature)
+        {
+            var exponentLength = BitConverter.ToUInt32(this.Data.Take(4).Reverse().ToArray(), 0);
+
+            var exponentData = this.Data.Skip(4).Take((int)exponentLength).ToArray();
+
+            var modulusLength = BitConverter.ToUInt32(this.Data.Skip(4 + (int)exponentLength).Take(4).Reverse().ToArray(), 0);
+
+            var modulusData = this.Data.Skip(4 + (int)exponentLength + 4).Take((int)modulusLength).ToArray();
+
+            using (var sha1 = new SHA1CryptoServiceProvider())
+            {
+                using (var cs = new CryptoStream(System.IO.Stream.Null, sha1, CryptoStreamMode.Write))
+                {
+                    var data = hash.ToArray();
+                    cs.Write(data, 0, data.Length);
+                    cs.Close();
+                }
+
+                using (var rsa = new RSACryptoServiceProvider())
+                {
+                    rsa.ImportParameters(new RSAParameters
+                    {
+                        Exponent = exponentData,
+                        Modulus = modulusData.TrimLeadinZero().ToArray(),
+                    });
+                    var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
+                    rsaDeformatter.SetHashAlgorithm("SHA1");
+
+                    long i = 0;
+                    long j = 0;
+                    byte[] tmp;
+
+                    var sig = signature.ToArray();
+                    if (sig[0] == 0 && sig[1] == 0 && sig[2] == 0)
+                    {
+                        long i1 = (sig[i++] << 24) & 0xff000000;
+                        long i2 = (sig[i++] << 16) & 0x00ff0000;
+                        long i3 = (sig[i++] << 8) & 0x0000ff00;
+                        long i4 = (sig[i++]) & 0x000000ff;
+                        j = i1 | i2 | i3 | i4;
+
+                        i += j;
+
+                        i1 = (sig[i++] << 24) & 0xff000000;
+                        i2 = (sig[i++] << 16) & 0x00ff0000;
+                        i3 = (sig[i++] << 8) & 0x0000ff00;
+                        i4 = (sig[i++]) & 0x000000ff;
+                        j = i1 | i2 | i3 | i4;
+
+                        tmp = new byte[j];
+                        Array.Copy(sig, i, tmp, 0, j);
+                        sig = tmp;
+                    }
+
+                    return rsaDeformatter.VerifySignature(sha1, sig);
+                }
+            }
+        }
+    }
+}

+ 94 - 0
Renci.SshClient/Renci.SshClient/Security/UserAuthentication.cs

@@ -0,0 +1,94 @@
+using Renci.SshClient.Messages;
+using Renci.SshClient.Messages.Authentication;
+using System;
+using Renci.SshClient.Common;
+using System.Threading;
+
+namespace Renci.SshClient.Security
+{
+    internal abstract class UserAuthentication
+    {
+        public abstract string Name { get; }
+
+        public bool IsAuthenticated { get; private set; }
+
+        public string ErrorMessage { get; private set; }
+
+        public event EventHandler<AuthenticationEventArgs> Authenticating;
+
+        protected Session Session { get; private set; }
+
+        protected string Username { get; private set; }
+
+        public bool Authenticate(string username, Session session)
+        {
+            this.Username = username;
+            this.Session = session;
+
+            this.Session.RegisterMessageType<FailureMessage>(MessageTypes.UserAuthenticationFailure);
+            this.Session.RegisterMessageType<SuccessMessage>(MessageTypes.UserAuthenticationSuccess);
+            this.Session.RegisterMessageType<BannerMessage>(MessageTypes.UserAuthenticationBanner);
+
+            this.Session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived;
+            this.Session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessMessageReceived;
+            this.Session.UserAuthenticationBannerReceived += Session_UserAuthenticationBannerMessageReceived;
+            this.Session.MessageReceived += Session_MessageReceived;
+
+            this.OnAuthenticate();
+
+            this.Session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
+            this.Session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessMessageReceived;
+            this.Session.UserAuthenticationBannerReceived -= Session_UserAuthenticationBannerMessageReceived;
+            this.Session.MessageReceived -= Session_MessageReceived;
+
+            this.Session.UnRegisterMessageType(MessageTypes.UserAuthenticationFailure);
+            this.Session.UnRegisterMessageType(MessageTypes.UserAuthenticationSuccess);
+            this.Session.UnRegisterMessageType(MessageTypes.UserAuthenticationBanner);
+
+            return this.IsAuthenticated;
+        }
+
+        protected abstract void OnAuthenticate();
+
+        protected virtual void Session_UserAuthenticationFailureReceived(object sender, MessageEventArgs<FailureMessage> e)
+        {
+            this.ErrorMessage = e.Message.Message;
+            this.IsAuthenticated = false;
+        }
+
+        protected virtual void Session_UserAuthenticationSuccessMessageReceived(object sender, MessageEventArgs<SuccessMessage> e)
+        {
+            this.IsAuthenticated = true;
+        }
+
+        protected virtual void Session_UserAuthenticationBannerMessageReceived(object sender, MessageEventArgs<BannerMessage> e)
+        {
+            RaiseAuthenticating(new AuthenticationBannerEventArgs(this.Username, e.Message.Message, e.Message.Language));
+        }
+
+        protected void RaiseAuthenticating(AuthenticationEventArgs args)
+        {
+            if (this.Authenticating != null)
+            {
+                this.Authenticating(this, args);
+            }
+        }
+
+        protected void SendMessage(Message message)
+        {
+            this.Session.SendMessage(message);
+        }
+
+        protected void WaitHandle(WaitHandle eventWaitHandle)
+        {
+            this.Session.WaitHandle(eventWaitHandle);
+        }
+
+
+
+        protected virtual void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
+        {
+        }
+        
+    }
+}

+ 18 - 0
Renci.SshClient/Renci.SshClient/Security/UserAuthenticationHost.cs

@@ -0,0 +1,18 @@
+namespace Renci.SshClient.Security
+{
+    internal class UserAuthenticationHost : UserAuthentication
+    {
+        public override string Name
+        {
+            get
+            {
+                return "hostbased";
+            }
+        }
+
+        protected override bool Run()
+        {
+            throw new System.NotImplementedException();
+        }
+    }
+}

+ 127 - 0
Renci.SshClient/Renci.SshClient/Security/UserAuthenticationKeyboardInteractive.cs

@@ -0,0 +1,127 @@
+using System;
+using System.Linq;
+using System.Threading;
+using Renci.SshClient.Messages;
+using Renci.SshClient.Messages.Authentication;
+using Renci.SshClient.Common;
+using System.Threading.Tasks;
+
+namespace Renci.SshClient.Security
+{
+    internal class UserAuthenticationKeyboardInteractive : UserAuthentication, IDisposable
+    {
+        private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false);
+
+        private Exception _exception;
+
+        public override string Name
+        {
+            get
+            {
+                return "keyboard-interactive";
+            }
+        }
+
+        protected override void OnAuthenticate()
+        {
+            this.Session.RegisterMessageType<InformationRequestMessage>(MessageTypes.UserAuthenticationInformationRequest);
+
+            this.Session.SendMessage(new RequestMessageKeyboardInteractive(ServiceNames.Connection, this.Session.ConnectionInfo.Username));
+
+            this.WaitHandle(this._authenticationCompleted);
+
+            this.Session.UnRegisterMessageType(MessageTypes.UserAuthenticationInformationRequest);
+
+            if (this._exception != null)
+            {
+                throw this._exception;
+            }
+        }
+
+        protected override void Session_UserAuthenticationSuccessMessageReceived(object sender, MessageEventArgs<SuccessMessage> e)
+        {
+            base.Session_UserAuthenticationSuccessMessageReceived(sender, e);
+            this._authenticationCompleted.Set();
+        }
+
+        protected override void Session_UserAuthenticationFailureReceived(object sender, MessageEventArgs<FailureMessage> e)
+        {
+            base.Session_UserAuthenticationFailureReceived(sender, e);
+            this._authenticationCompleted.Set();
+        }
+
+        protected override void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
+        {
+            var informationRequestMessage = e.Message as InformationRequestMessage;
+            if (informationRequestMessage != null)
+            {
+                var eventArgs = new AuthenticationPromptEventArgs(this.Username, informationRequestMessage.Instruction, informationRequestMessage.Language, informationRequestMessage.Prompts);
+
+                var eventTask = Task.Factory.StartNew(() =>
+                {
+                    try
+                    {
+                        this.RaiseAuthenticating(eventArgs);
+
+                        var informationResponse = new InformationResponseMessage();
+
+                        foreach (var response in from r in eventArgs.Prompts orderby r.Id ascending select r.Response)
+                        {
+                            informationResponse.Responses.Add(response);
+                        }
+
+                        //  Send information response message
+                        this.SendMessage(informationResponse);
+                    }
+                    catch (Exception exp)
+                    {
+                        this._exception = exp;
+                        this._authenticationCompleted.Set();
+                    }
+                });
+            }
+        }
+
+        #region IDisposable Members
+
+        private bool isDisposed = false;
+
+        public void Dispose()
+        {
+            Dispose(true);
+
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            // Check to see if Dispose has already been called.
+            if (!this.isDisposed)
+            {
+                // If disposing equals true, dispose all managed
+                // and unmanaged resources.
+                if (disposing)
+                {
+                    // Dispose managed resources.
+                    if (this._authenticationCompleted != null)
+                    {
+                        this._authenticationCompleted.Dispose();
+                    }
+                }
+
+                // Note disposing has been done.
+                isDisposed = true;
+            }
+        }
+
+        ~UserAuthenticationKeyboardInteractive()
+        {
+            // Do not re-create Dispose clean-up code here.
+            // Calling Dispose(false) is optimal in terms of
+            // readability and maintainability.
+            Dispose(false);
+        }
+
+        #endregion
+    }
+}

+ 82 - 0
Renci.SshClient/Renci.SshClient/Security/UserAuthenticationNone.cs

@@ -0,0 +1,82 @@
+using System;
+using System.Threading;
+using Renci.SshClient.Messages;
+using Renci.SshClient.Messages.Authentication;
+using System.Collections.Generic;
+
+namespace Renci.SshClient.Security
+{
+    internal class UserAuthenticationNone : UserAuthentication, IDisposable
+    {
+        private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false);
+
+        public override string Name
+        {
+            get { return "none"; }
+        }
+
+        public IEnumerable<string> Methods { get; private set; }
+
+        protected override void OnAuthenticate()
+        {
+            this.SendMessage(new RequestMessage(ServiceNames.Connection, this.Username));
+
+            this.WaitHandle(this._authenticationCompleted);
+        }
+
+        protected override void Session_UserAuthenticationSuccessMessageReceived(object sender, MessageEventArgs<SuccessMessage> e)
+        {
+            base.Session_UserAuthenticationSuccessMessageReceived(sender, e);
+            this._authenticationCompleted.Set();
+        }
+
+        protected override void Session_UserAuthenticationFailureReceived(object sender, MessageEventArgs<FailureMessage> e)
+        {
+            base.Session_UserAuthenticationFailureReceived(sender, e);
+            this.Methods = e.Message.AllowedAuthentications;
+            this._authenticationCompleted.Set();
+        }
+
+        #region IDisposable Members
+
+        private bool _isDisposed = false;
+
+        public void Dispose()
+        {
+            Dispose(true);
+
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            // Check to see if Dispose has already been called.
+            if (!this._isDisposed)
+            {
+                // If disposing equals true, dispose all managed
+                // and unmanaged resources.
+                if (disposing)
+                {
+                    // Dispose managed resources.
+                    if (this._authenticationCompleted != null)
+                    {
+                        this._authenticationCompleted.Dispose();
+                    }
+                }
+
+                // Note disposing has been done.
+                _isDisposed = true;
+            }
+        }
+
+        ~UserAuthenticationNone()
+        {
+            // Do not re-create Dispose clean-up code here.
+            // Calling Dispose(false) is optimal in terms of
+            // readability and maintainability.
+            Dispose(false);
+        }
+
+        #endregion
+    }
+}

+ 128 - 0
Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPassword.cs

@@ -0,0 +1,128 @@
+using System;
+using System.Threading;
+using Renci.SshClient.Messages;
+using Renci.SshClient.Messages.Authentication;
+using System.Threading.Tasks;
+using Renci.SshClient.Common;
+
+namespace Renci.SshClient.Security
+{
+    internal class UserAuthenticationPassword : UserAuthentication, IDisposable
+    {
+        private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false);
+
+        private Exception _exception;
+
+        private PasswordConnectionInfo _connectionInfo;
+
+        public override string Name
+        {
+            get
+            {
+                return "password";
+            }
+        }
+
+        protected override void OnAuthenticate()
+        {
+            this._connectionInfo = this.Session.ConnectionInfo as PasswordConnectionInfo;
+
+            if (this._connectionInfo == null)
+                return;
+
+            this.Session.RegisterMessageType<PasswordChangeRequiredMessage>(MessageTypes.UserAuthenticationPasswordChangeRequired);
+
+            this.SendMessage(new RequestMessagePassword(ServiceNames.Connection, this.Username, this._connectionInfo.Password));
+
+            this.WaitHandle(this._authenticationCompleted);
+
+            if (this._exception != null)
+            {
+                throw this._exception;
+            }
+        }
+
+        protected override void Session_UserAuthenticationSuccessMessageReceived(object sender, MessageEventArgs<SuccessMessage> e)
+        {
+            base.Session_UserAuthenticationSuccessMessageReceived(sender, e);
+            this._authenticationCompleted.Set();
+        }
+
+        protected override void Session_UserAuthenticationFailureReceived(object sender, MessageEventArgs<FailureMessage> e)
+        {
+            base.Session_UserAuthenticationFailureReceived(sender, e);
+            this._authenticationCompleted.Set();
+        }
+
+        protected override void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
+        {
+            base.Session_MessageReceived(sender, e);
+
+            if (e.Message is PasswordChangeRequiredMessage)
+            {
+                this.Session.UnRegisterMessageType(MessageTypes.UserAuthenticationPasswordChangeRequired);
+
+                var eventTask = Task.Factory.StartNew(() =>
+                {
+                    try
+                    {
+                        var eventArgs = new AuthenticationPasswordChangeEventArgs(this.Username);
+
+                        //  Raise an event to allow user to supply a new password
+                        this.RaiseAuthenticating(eventArgs);
+
+                        //  Send new authentication request with new password
+                        this.SendMessage(new RequestMessagePassword(ServiceNames.Connection, this.Username, this._connectionInfo.Password, eventArgs.NewPassword));
+                    }
+                    catch (Exception exp)
+                    {
+                        this._exception = exp;
+                        this._authenticationCompleted.Set();
+                    }
+                });
+            }
+        }
+
+        #region IDisposable Members
+
+        private bool isDisposed = false;
+
+        public void Dispose()
+        {
+            Dispose(true);
+
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            // Check to see if Dispose has already been called.
+            if (!this.isDisposed)
+            {
+                // If disposing equals true, dispose all managed
+                // and unmanaged resources.
+                if (disposing)
+                {
+                    // Dispose managed resources.
+                    if (this._authenticationCompleted != null)
+                    {
+                        this._authenticationCompleted.Dispose();
+                    }
+                }
+
+                // Note disposing has been done.
+                isDisposed = true;
+            }
+        }
+
+        ~UserAuthenticationPassword()
+        {
+            // Do not re-create Dispose clean-up code here.
+            // Calling Dispose(false) is optimal in terms of
+            // readability and maintainability.
+            Dispose(false);
+        }
+
+        #endregion
+    }
+}

+ 177 - 0
Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPublicKey.cs

@@ -0,0 +1,177 @@
+using System;
+using System.Threading;
+using Renci.SshClient.Common;
+using Renci.SshClient.Messages;
+using Renci.SshClient.Messages.Authentication;
+
+namespace Renci.SshClient.Security
+{
+    internal class UserAuthenticationPublicKey : UserAuthentication, IDisposable
+    {
+        private EventWaitHandle _publicKeyRequestMessageResponseWaitHandle = new ManualResetEvent(false);
+
+        private bool _isSignatureRequired;
+
+        public override string Name
+        {
+            get
+            {
+                return "publickey";
+            }
+        }
+
+        protected override void OnAuthenticate()
+        {
+            var privateKeyConnectionInfo = this.Session.ConnectionInfo as PrivateKeyConnectionInfo;
+
+            if (privateKeyConnectionInfo == null)
+                return;
+
+            if (privateKeyConnectionInfo.KeyFiles == null)
+                return;
+
+            this.Session.RegisterMessageType<PublicKeyMessage>(MessageTypes.UserAuthenticationPublicKey);
+
+            foreach (var keyFile in privateKeyConnectionInfo.KeyFiles)
+            {
+                this._publicKeyRequestMessageResponseWaitHandle.Reset();
+                this._isSignatureRequired = false;
+
+                var message = new RequestMessagePublicKey(ServiceNames.Connection,this.Username, keyFile.AlgorithmName, keyFile.PublicKey);
+
+                if (privateKeyConnectionInfo.KeyFiles.Count < 2)
+                {
+                    //  If only one key file provided then send signature for very first request
+                    var signatureData = new SignatureData(message, this.Session.SessionId.GetSshString()).GetBytes();
+
+                    message.Signature = keyFile.GetSignature(signatureData);
+                }
+
+                //  Send public key authentication request
+                this.SendMessage(message);
+
+                this.WaitHandle(this._publicKeyRequestMessageResponseWaitHandle);
+
+                if (this._isSignatureRequired)
+                {
+                    this._publicKeyRequestMessageResponseWaitHandle.Reset();
+
+                    var signatureMessage = new RequestMessagePublicKey(ServiceNames.Connection, this.Session.ConnectionInfo.Username, keyFile.AlgorithmName, keyFile.PublicKey);
+
+                    var signatureData = new SignatureData(message, this.Session.SessionId.GetSshString()).GetBytes();
+
+                    signatureMessage.Signature = keyFile.GetSignature(signatureData);
+                    
+                    //  Send public key authentication request with signature
+                    this.SendMessage(signatureMessage); 
+                }
+
+                this.WaitHandle(this._publicKeyRequestMessageResponseWaitHandle);
+
+                if (this.IsAuthenticated)
+                {
+                    break;
+                }            
+            }
+
+            this.Session.UnRegisterMessageType(MessageTypes.UserAuthenticationPublicKey);
+        }
+
+        protected override void Session_UserAuthenticationSuccessMessageReceived(object sender, MessageEventArgs<SuccessMessage> e)
+        {
+            base.Session_UserAuthenticationSuccessMessageReceived(sender, e);
+
+            this._publicKeyRequestMessageResponseWaitHandle.Set();
+        }
+
+        protected override void Session_UserAuthenticationFailureReceived(object sender, MessageEventArgs<FailureMessage> e)
+        {
+            base.Session_UserAuthenticationFailureReceived(sender, e);
+            this._publicKeyRequestMessageResponseWaitHandle.Set();
+        }
+
+        protected override void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
+        {
+            base.Session_MessageReceived(sender, e);
+
+            var publicKeyMessage = e.Message as PublicKeyMessage;
+            if (publicKeyMessage != null)
+            {
+                this._isSignatureRequired = true;
+                this._publicKeyRequestMessageResponseWaitHandle.Set();
+            }        
+        }
+
+        private class SignatureData : SshData
+        {
+            private RequestMessagePublicKey _message;
+
+            private string _sessionId;
+
+            public SignatureData(RequestMessagePublicKey message, string sessionId)
+            {
+                this._message = message;
+                this._sessionId = sessionId;
+            }
+
+            protected override void LoadData()
+            {
+                throw new System.NotImplementedException();
+            }
+
+            protected override void SaveData()
+            {
+                this.Write(this._sessionId);
+                this.Write((byte)this._message.MessageType);
+                this.Write(this._message.Username);
+                this.Write("ssh-connection");
+                this.Write("publickey");
+                this.Write((byte)1);
+                this.Write(this._message.PublicKeyAlgorithmName);
+                this.Write(this._message.PublicKeyData.GetSshString());
+            }
+        }
+
+        #region IDisposable Members
+
+        private bool _isDisposed = false;
+
+        public void Dispose()
+        {
+            Dispose(true);
+
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            // Check to see if Dispose has already been called.
+            if (!this._isDisposed)
+            {
+                // If disposing equals true, dispose all managed
+                // and unmanaged resources.
+                if (disposing)
+                {
+                    // Dispose managed resources.
+                    if (this._publicKeyRequestMessageResponseWaitHandle != null)
+                    {
+                        this._publicKeyRequestMessageResponseWaitHandle.Dispose();
+                    }
+                }
+
+                // Note disposing has been done.
+                _isDisposed = true;
+            }
+        }
+
+        ~UserAuthenticationPublicKey()
+        {
+            // Do not re-create Dispose clean-up code here.
+            // Calling Dispose(false) is optimal in terms of
+            // readability and maintainability.
+            Dispose(false);
+        }
+
+        #endregion
+    }
+}

+ 19 - 0
Renci.SshClient/Renci.SshClient/Services/ConnectionService.cs

@@ -0,0 +1,19 @@
+using System;
+using Renci.SshClient.Messages;
+
+namespace Renci.SshClient.Services
+{
+    internal class ConnectionService : Service
+    {
+        public override ServiceNames ServiceName
+        {
+            get { throw new NotImplementedException(); }
+        }
+
+        public ConnectionService(Session session)
+            : base(session)
+        {
+
+        }
+    }
+}

+ 22 - 0
Renci.SshClient/Renci.SshClient/Services/Service.cs

@@ -0,0 +1,22 @@
+using Renci.SshClient.Messages;
+
+namespace Renci.SshClient.Services
+{
+    internal abstract class Service
+    {
+        public abstract ServiceNames ServiceName { get; }
+
+        protected Session Session { get; private set; }
+
+        public Service(Session session)
+        {
+            this.Session = session;
+        }
+
+        protected void SendMessage(Message message)
+        {
+            this.Session.SendMessage(message);
+        }
+
+    }
+}

+ 155 - 0
Renci.SshClient/Renci.SshClient/Services/UserAuthenticationService.cs

@@ -0,0 +1,155 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using Renci.SshClient.Common;
+using Renci.SshClient.Messages;
+using Renci.SshClient.Messages.Authentication;
+using Renci.SshClient.Messages.Transport;
+using Renci.SshClient.Security;
+
+namespace Renci.SshClient.Services
+{
+    internal class UserAuthenticationService : Service
+    {
+        private IList<string> _executedMethods = new List<string>();
+
+        private EventWaitHandle _serviceAccepted = new AutoResetEvent(false);
+
+        private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false);
+
+        public override ServiceNames ServiceName
+        {
+            get { return ServiceNames.UserAuthentication; }
+        }
+
+        public EventWaitHandle AuthenticationCompletedHandle { get; private set; }
+
+        public string ErrorMessage { get; private set; }
+
+        public bool IsAuthenticated { get; private set; }
+
+        public UserAuthenticationService(Session session)
+            : base(session)
+        {
+            this.AuthenticationCompletedHandle = new AutoResetEvent(false);
+        }
+
+        public void AuthenticateUser()
+        {
+            //  Register Authentication response messages
+            Message.RegisterMessageType<FailureMessage>(MessageTypes.UserAuthenticationFailure);
+            Message.RegisterMessageType<SuccessMessage>(MessageTypes.UserAuthenticationSuccess);
+            Message.RegisterMessageType<BannerMessage>(MessageTypes.UserAuthenticationBanner);
+
+            //  Attach event handlers to handle messages
+            this.Session.MessageReceived += SessionInfo_MessageReceived;
+
+            //  Request user authorization service
+            this.SendMessage(new ServiceRequestMessage
+            {
+                ServiceName = ServiceNames.UserAuthentication,
+            });
+
+            //  Wait for service to be accepted
+            this.Session.WaitHandle(this._serviceAccepted);
+
+            //  Start by quering supported authentication methods
+            this.SendMessage(new RequestMessage
+            {
+                Username = this.Session.ConnectionInfo.Username,
+                ServiceName = ServiceNames.Connection,
+            });
+
+            //  Wait for authentication to be completed
+            this.Session.WaitHandle(this._authenticationCompleted);
+
+            this.Session.MessageReceived -= SessionInfo_MessageReceived;
+
+            Message.UnRegisterMessageType(MessageTypes.UserAuthenticationFailure);
+            Message.UnRegisterMessageType(MessageTypes.UserAuthenticationSuccess);
+            Message.UnRegisterMessageType(MessageTypes.UserAuthenticationBanner);
+        }
+
+        private void SessionInfo_MessageReceived(object sender, MessageReceivedEventArgs e)
+        {
+            this.HandleMessage((dynamic)e.Message);
+        }
+
+        private void HandleMessage<T>(T message)
+        {
+            //  Ignore messages that cannot be handled by this module
+        }
+
+        private void HandleMessage(ServiceAcceptMessage message)
+        {
+            if (message.ServiceName == ServiceNames.UserAuthentication)
+            {
+                this._serviceAccepted.Set();
+            }
+        }
+
+        private void HandleMessage(SuccessMessage message)
+        {
+            this.AuthenticationSucceded();
+        }
+
+        private void HandleMessage(FailureMessage message)
+        {
+            if (message.PartialSuccess)
+            {
+                this.AuthenticationFailed(message.Message);
+                return;
+            }
+
+            //  Get method that was not executed yet
+            var methodsToTry = message.AllowedAuthentications.Except(this._executedMethods);
+
+            if (methodsToTry.Count() == 0)
+            {
+                this.AuthenticationFailed(string.Format("User '{0}' cannot be authorized.", this.Session.ConnectionInfo.Username));
+                return;
+            }
+
+            //  Execute authentication method
+            foreach (var methodName in methodsToTry)
+            {
+                UserAuthentication userAuthentication = null;
+
+                if (methodName == "publickey")
+                {
+                    userAuthentication = new UserAuthenticationPublicKey(this.Session);
+                }
+                else if (methodName == "password")
+                {
+                    userAuthentication = new UserAuthenticationPassword(this.Session);
+                }
+                this._executedMethods.Add(methodName);
+                if (userAuthentication != null)
+                {
+                    if (userAuthentication.Start())
+                        break;
+                }
+            }
+        }
+
+        private void HandleMessage(BannerMessage message)
+        {
+        }
+
+        private void AuthenticationFailed(string message)
+        {
+            this.IsAuthenticated = false;
+            this.ErrorMessage = message;
+            this._authenticationCompleted.Set();
+        }
+
+        private void AuthenticationSucceded()
+        {
+            this.IsAuthenticated = true;
+            this._authenticationCompleted.Set();
+        }
+
+
+
+    }
+}

+ 72 - 0
Renci.SshClient/Renci.SshClient/SessionInfo.cs

@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using Renci.SshClient.Common;
+using Renci.SshClient.Messages;
+
+namespace Renci.SshClient
+{
+    public delegate void SendMessage(Message message);
+
+    internal class SessionInfo
+    {
+        private SendMessage _sendMessage;
+
+        private EventWaitHandle _disconnectWaitHandle = new AutoResetEvent(false);
+
+        private int _waitTimeout;
+
+        public ConnectionInfo ConnectionInfo { get; private set; }
+
+        public IEnumerable<byte> SessionId { get; set; }
+
+        public string ServerVersion { get; set; }
+
+        public string ClientVersion { get; set; }
+
+        public SessionInfo(SendMessage sendMessage, ConnectionInfo connectionInfo, int waitTimeout)
+        {
+            this._sendMessage = sendMessage;
+            this._waitTimeout = waitTimeout;
+            this.ConnectionInfo = connectionInfo;
+        }
+
+        public event EventHandler<MessageReceivedEventArgs> MessageReceived;
+
+        public void RaiseMessageReceived(object sender, MessageReceivedEventArgs args)
+        {
+            if (this.MessageReceived != null)
+            {
+                this.MessageReceived(sender, args);
+            }
+        }
+
+        public void SendMessage(Message message)
+        {
+            this._sendMessage(message);
+        }
+
+        public void Disconnect()
+        {
+            this._disconnectWaitHandle.Set();
+        }
+
+        public void WaitHandle(EventWaitHandle waitHandle)
+        {
+            var waitHandles = new EventWaitHandle[]
+                {
+                    this._disconnectWaitHandle,
+                    waitHandle,
+                };
+            var index = EventWaitHandle.WaitAny(waitHandles);
+
+            //var index = EventWaitHandle.WaitAny(waitHandles, this._waitTimeout);
+
+            //if (index > waitHandles.Length)
+            //{
+            //  //  TODO:   Issue timeout disconnect message if approapriate
+            //    throw new TimeoutException();
+            //}
+        }
+    }
+}

+ 199 - 0
Renci.SshClient/Renci.SshClient/SessionSSHv2.cs

@@ -0,0 +1,199 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Security.Cryptography;
+using Renci.SshClient.Messages;
+
+namespace Renci.SshClient
+{
+    internal class SessionSSHv2 : Session
+    {
+        private static RNGCryptoServiceProvider _randomizer = new System.Security.Cryptography.RNGCryptoServiceProvider();
+
+        private UInt32 _outboundPacketSequence = 0;
+        private UInt32 _inboundPacketSequence = 0;
+
+        internal SessionSSHv2(ConnectionInfo connectionInfo, Socket socket, string serverVersion)
+            : base(connectionInfo, socket, serverVersion)
+        {
+        }
+
+        internal override void SendMessage(Message message)
+        {
+            if (!this.IsConnected)
+                return;
+
+            //  TODO:  Refactor so we lock only _outboundPacketSequence and _inboundPacketSequence relevant operations
+
+            //  Messages can be sent by different thread so we need to synchronize it
+            lock (this) //  Lock on session
+            {
+                var paddingMultiplier = this.ClientCipher == null ? (byte)8 : (byte)this.ClientCipher.BlockSize;    //    Should be recalculate base on cipher min lenght if sipher specified
+
+                //  TODO:   Maximum uncomporessed payload 32768
+                //  TOOO:   If compression specified then compress only payload
+
+                var messageData = message.GetBytes();
+
+                var packetLength = messageData.Count() + 4 + 1; //  add length bytes and padding byte
+                byte paddingLength = (byte)((-packetLength) & (paddingMultiplier - 1));
+                if (paddingLength < paddingMultiplier)
+                {
+                    paddingLength += paddingMultiplier;
+                }
+
+                //  Build Packet data
+                var packetData = new List<byte>();
+
+                //  Add packet padding length
+                packetData.Add(paddingLength);
+
+                //  Add packet payload
+                packetData.AddRange(messageData);
+
+                //  Add random padding
+                var paddingBytes = new byte[paddingLength];
+                _randomizer.GetBytes(paddingBytes);
+                packetData.AddRange(paddingBytes);
+
+                //  Insert packet length
+                packetData.InsertRange(0, BitConverter.GetBytes((uint)(packetData.Count())).Reverse());
+
+                //  Calculate packet hash
+                var hashData = new List<byte>();
+                hashData.AddRange(BitConverter.GetBytes((this._outboundPacketSequence)).Reverse());
+                hashData.AddRange(packetData);
+
+                //  Encrypt packet data
+                var encryptedData = packetData.ToList();
+                if (this.ClientCipher != null)
+                {
+                    //encryptedData = new List<byte>(this.Encrypt(packetData));
+                    encryptedData = new List<byte>(this.ClientCipher.Encrypt(packetData));
+                }
+
+                //  Add message authentication code (MAC)
+                if (this.ClientMac != null)
+                {
+                    var hash = this.ClientMac.ComputeHash(hashData.ToArray());
+
+                    encryptedData.AddRange(hash);
+                }
+
+                if (encryptedData.Count > Session.MAXIMUM_PACKET_SIZE)
+                {
+                    throw new InvalidOperationException("Packet is too big. Maximum packet size is 35000 bytes.");
+                }
+
+                this.Write(encryptedData.ToArray());
+
+                this._outboundPacketSequence++;
+            }
+        }
+
+        protected override Message ReceiveMessage()
+        {
+            if (!this.IsConnected)
+                return null;
+
+            //  No lock needed since all messages read by only one thread
+
+            List<byte> decryptedData;
+
+            //var blockSize = this.Decryption == null ? (byte)8 : (byte)this.Decryption.InputBlockSize;
+            var blockSize = this.ServerCipher == null ? (byte)8 : (byte)this.ServerCipher.BlockSize;
+
+            //  Read packet lenght first
+            var data = new List<byte>(this.Read(blockSize));
+
+            if (this.ServerCipher == null)
+            {
+                decryptedData = data.ToList();
+            }
+            else
+            {
+                //decryptedData = new List<byte>(this.Decrypt(data));
+                decryptedData = new List<byte>(this.ServerCipher.Decrypt(data));
+            }
+
+            var packetLength = BitConverter.ToUInt32(decryptedData.Take(4).Reverse().ToArray(), 0);
+
+            //  Test packet minimum and maximum boundaries
+            if (packetLength < Math.Max((byte)16, blockSize) - 4 || packetLength > Session.MAXIMUM_PACKET_SIZE - 4)
+                throw new InvalidOperationException(string.Format("Bad packet length {0}", packetLength));
+
+            //  Read rest of the packet data
+            int bytesToRead = (int)(packetLength - (blockSize - 4));
+
+            while (bytesToRead > 0)
+            {
+                data = new List<byte>(this.Read(blockSize));
+
+                if (this.ServerCipher == null)
+                {
+                    decryptedData.AddRange(data);
+                }
+                else
+                {
+                    //decryptedData.AddRange(this.Decrypt(data));
+                    decryptedData.AddRange(this.ServerCipher.Decrypt(data));
+                }
+                bytesToRead -= blockSize;
+            }
+
+            //  Validate message against MAC
+            if (this.ServerMac != null)
+            {
+                var serverHash = this.Read(this.ServerMac.HashSize / 8);
+
+                var clientHashData = new List<byte>();
+                clientHashData.AddRange(BitConverter.GetBytes(this._inboundPacketSequence).Reverse());
+                clientHashData.AddRange(decryptedData);
+
+                //  Calculate packet hash
+                var clientHash = this.ServerMac.ComputeHash(clientHashData.ToArray());
+
+                if (!serverHash.IsEqualTo(clientHash))
+                {
+                    throw new InvalidOperationException("MAC error");
+                }
+            }
+
+            //  TODO:   Issue new keys after x number of packets
+            this._inboundPacketSequence++;
+
+            var paddingLength = decryptedData[4];
+
+            return this.LoadMessage(decryptedData.Skip(5).Take((int)(packetLength - paddingLength - 1)));
+        }
+
+        private bool ValidateHash(List<byte> decryptedData, byte[] serverHash, uint packetSequence)
+        {
+            var clientHashData = new List<byte>();
+            clientHashData.AddRange(BitConverter.GetBytes(packetSequence).Reverse());
+            clientHashData.AddRange(decryptedData);
+
+            var clientHash = this.ServerMac.ComputeHash(clientHashData.ToArray());
+            if (!serverHash.IsEqualTo(clientHash))
+            {
+                return false;
+            }
+            return true;
+        }
+
+        //private IEnumerable<byte> Encrypt(List<byte> data)
+        //{
+        //    var temp = new byte[data.Count];
+        //    this.Encryption.TransformBlock(data.ToArray(), 0, data.Count, temp, 0);
+        //    return temp;
+        //}
+
+        //private IEnumerable<byte> Decrypt(List<byte> data)
+        //{
+        //    var temp = new byte[data.Count];
+        //    this.Decryption.TransformBlock(data.ToArray(), 0, data.Count, temp, 0);
+        //    return temp;
+        //}
+    }
+}

+ 69 - 0
Renci.SshClient/Renci.SshClient/Settings.cs

@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using Renci.SshClient.Compression;
+using Renci.SshClient.Security;
+
+namespace Renci.SshClient
+{
+    internal static class Settings
+    {
+        //public static IDictionary<string, Func<KeyExchangeAlgorithm>> KeyExchangeAlgorithms { get; private set; }
+
+        //public static IDictionary<string, Func<Cipher>> Encryptions { get; private set; }
+
+        //public static IDictionary<string, Func<IEnumerable<byte>, HMAC>> HmacAlgorithms { get; private set; }
+
+        //public static IDictionary<string, Func<Session, Compressor>> CompressionAlgorithms { get; private set; }
+
+        //public static IDictionary<string, Func<CryptoPublicKey>> HostKeyAlgorithms { get; private set; }
+
+        //public static IDictionary<string, Func<Session, UserAuthentication>> SupportedAuthenticationMethods { get; private set; }
+
+        static Settings()
+        {
+            //Settings.KeyExchangeAlgorithms = new Dictionary<string, Func<KeyExchangeAlgorithm>>()
+            //{
+            //    {"diffie-hellman-group1-sha1", () => { return new KeyExchangeDiffieHellman();}}
+            //    //"diffie-hellman-group-exchange-sha1"
+            //};
+
+            //Settings.Encryptions = new Dictionary<string, Func<Cipher>>()
+            //{
+            //    {"3des-cbc", () => { return new CipherTripleDES();}},
+            //    {"aes128-cbc", () => { return new CipherAES128CBC();}},
+            //    {"aes192-cbc", () => { return new CipherAES192CBC();}},
+            //    {"aes256-cbc", () => { return new CipherAES256CBC();}},
+            //};
+
+
+            //Settings.HmacAlgorithms = new Dictionary<string, Func<IEnumerable<byte>, HMAC>>()
+            //{
+            //    {"hmac-md5", (key) => { return new System.Security.Cryptography.HMACMD5(key.Take(16).ToArray());}},
+            //    {"hmac-sha1", (key) => { return new System.Security.Cryptography.HMACSHA1(key.Take(20).ToArray());}},
+            //};
+
+            //Settings.HostKeyAlgorithms = new Dictionary<string, Func<CryptoPublicKey>>()
+            //{
+            //    {"ssh-rsa", () => { return new CryptoPublicKeyRsa();}},
+            //    {"ssh-dsa", () => { return new CryptoPublicKeyDss();}}, //  TODO:   Need to be tested
+            //};
+
+            //Settings.SupportedAuthenticationMethods = new Dictionary<string, Func<Session, UserAuthentication>>()
+            //{
+            //    {"none", (session)=> {return new UserAuthenticationNone(session);}},
+            //    {"publickey", (session)=> {return new UserAuthenticationPublicKey(session);}},
+            //    {"password", (session)=> {return new UserAuthenticationPassword(session);}},
+            //};
+
+            //Settings.CompressionAlgorithms = new Dictionary<string, Func<Session, Compressor>>()
+            //{
+            //    {"none", (session) => { return null;}}, 
+            //    {"zlib", (session) => { return new Zlib(session);}}, 
+            //    {"zlib@openssh.com", (session) => { return new ZlibOpenSsh(session);}}, 
+            //};
+
+        }
+    }
+}

+ 273 - 0
Renci.SshClient/Renci.SshClient/Sftp.cs

@@ -0,0 +1,273 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using Renci.SshClient.Channels;
+using Renci.SshClient.Common;
+using Renci.SshClient.Messages.Sftp;
+
+namespace Renci.SshClient
+{
+    public class Sftp
+    {
+        private readonly ChannelSession _channel;
+
+        private readonly Session _session;
+
+        private StringBuilder _packetData;
+
+        private uint _requestId;
+
+        private Exception _exception;
+
+        private EventWaitHandle _sftpVersionConfirmed = new AutoResetEvent(false);
+
+        private EventWaitHandle _sessionErrorOccuredWaitHandle = new AutoResetEvent(false);
+
+        private IDictionary<uint, Action<SftpRequestMessage>> _requestActions;
+
+        private string _remoteCurrentDir;
+
+        public int OperationTimeout { get; set; }
+
+        internal Sftp(Session session)
+        {
+            this.OperationTimeout = -1;
+            this._requestActions = new Dictionary<uint, Action<SftpRequestMessage>>();
+            this._session = session;
+            this._session.ErrorOccured += Session_ErrorOccured;
+            this._session.Disconnected += Session_Disconnected;
+            this._channel = session.CreateChannel<ChannelSession>();
+            this._channel.DataReceived += Channel_DataReceived;
+            this._channel.Open();
+            this._channel.SendSubsystemRequest("sftp");
+
+            this.SendMessage(new InitMessage
+            {
+                Version = 3,
+            });
+
+            this.WaitHandle(this._sftpVersionConfirmed);
+
+            this.SendMessage(new RealPathMessage
+            {
+                Path = ".",
+            }, (m) =>
+            {
+                var nameMessage = m as NameMessage;
+                if (nameMessage != null)
+                {
+                    this._remoteCurrentDir = nameMessage.Files.First().Name;
+                }
+                else
+                {
+                    throw new InvalidOperationException("");
+                }
+            });
+        }
+
+        public IAsyncResult BeginListDirectory(string path, AsyncCallback callback, object state)
+        {
+            var asyncResult = new SftpAsyncResult(this._channel, callback, state);
+
+            this.SendMessage(new OpenDirMessage(path), (m) =>
+                {
+                    var message = m as HandleMessage;
+                    if (message == null)
+                        throw new InvalidOperationException("Handle message is not expected.");
+
+                    this.SendMessage(new ReadDirMessage(message.Handle), (m1) =>
+                    {
+                        var message1 = m1 as NameMessage;
+                        if (message1 == null)
+                            throw new InvalidOperationException("Handle message is not expected.");
+                        asyncResult.Names = message1.Files;
+                        asyncResult.IsCompleted = true;
+                    });
+                });
+
+            return asyncResult;
+
+
+        }
+
+        public IEnumerable<FtpFileInfo> EndListDirectory(IAsyncResult result)
+        {
+            var r = result as SftpAsyncResult;
+            if (r == null)
+            {
+                throw new ArgumentException("Invalid IAsyncResult parameter.");
+            }
+
+            r.AsyncWaitHandle.WaitOne();
+
+            return r.Names;
+        }
+
+
+        private void Channel_DataReceived(object sender, Common.ChannelDataEventArgs e)
+        {
+            if (this._packetData == null)
+            {
+                var packetLength = (uint)(e.Data[0] << 24 | e.Data[1] << 16 | e.Data[2] << 8 | e.Data[3]);
+
+                this._packetData = new StringBuilder((int)packetLength, (int)packetLength);
+                this._packetData.Append(e.Data.GetSshBytes().Skip(4).GetSshString());
+            }
+            else
+            {
+                this._packetData.Append(e.Data);
+            }
+
+            if (this._packetData.Length < this._packetData.MaxCapacity)
+            {
+                //  Wait for more packet data
+                return;
+            }
+
+            dynamic sftpMessage = SftpMessage.Load(this._packetData.ToString().GetSshBytes());
+
+            this._packetData = null;
+
+            this.HandleMessage(sftpMessage);
+        }
+
+        private void HandleMessage(InitMessage message)
+        {
+            throw new InvalidOperationException("Init message should not be received by client.");
+        }
+
+        private void HandleMessage(VersionMessage message)
+        {
+            if (message.Version == 3)
+            {
+                this._sftpVersionConfirmed.Set();
+            }
+            else
+            {
+                throw new NotSupportedException(string.Format("Server SFTP version {0} is not supported.", message.Version));
+            }
+        }
+
+        private void HandleMessage(SftpRequestMessage message)
+        {
+            if (this._requestActions.ContainsKey(message.RequestId))
+            {
+                var action = this._requestActions[message.RequestId];
+                action(message);
+                this._requestActions.Remove(message.RequestId);
+            }
+            else
+            {
+                throw new InvalidOperationException(string.Format("Request #{0} is invalid.", message.RequestId));
+            }
+        }
+
+        private void Session_Disconnected(object sender, EventArgs e)
+        {
+        }
+
+        private void Session_ErrorOccured(object sender, ErrorEventArgs e)
+        {
+            this._exception = e.GetException();
+
+            this._sessionErrorOccuredWaitHandle.Set();
+        }
+
+        private void SendMessage(SftpMessage sftpMessage)
+        {
+            var message = new SftpDataMessage
+            {
+                LocalChannelNumber = this._channel.RemoteChannelNumber,
+                Message = sftpMessage,
+            };
+
+            this._session.SendMessage(message);
+        }
+
+        private void SendMessage(SftpRequestMessage sftpMessage, Action<SftpRequestMessage> action)
+        {
+            sftpMessage.RequestId = this._requestId++;
+
+            var message = new SftpDataMessage
+            {
+                LocalChannelNumber = this._channel.RemoteChannelNumber,
+                Message = sftpMessage,
+            };
+
+            this._session.SendMessage(message);
+
+            this._requestActions.Add(sftpMessage.RequestId, action);
+        }
+
+        private void WaitHandle(WaitHandle waitHandle)
+        {
+            var waitHandles = new WaitHandle[]
+                {
+                    this._sessionErrorOccuredWaitHandle,
+                    waitHandle,
+                };
+
+            var index = EventWaitHandle.WaitAny(waitHandles, this.OperationTimeout);
+
+            if (index < 1)
+            {
+                throw this._exception;
+            }
+            else if (index > 1)
+            {
+                //  throw time out error
+                throw new SshOperationTimeoutException(string.Format("Sftp operation has timed out."));
+            }
+        }
+
+
+        //public void UploadFile(Stream source, string fileName)
+        //{
+        //    this.Channel.UploadFile(source, fileName);
+        //}
+
+        //public void UploadFile(string source, string fileName)
+        //{
+        //    using (var sourceFile = File.OpenRead(source))
+        //    {
+        //        this.Channel.UploadFile(sourceFile, fileName);
+        //    }
+        //}
+
+        //public void DownloadFile(string fileName, Stream destination)
+        //{
+        //    this.Channel.DownloadFile(fileName, destination);
+        //}
+
+        //public void DownloadFile(string fileName, string destination)
+        //{
+        //    using (var destinationFile = File.Create(destination))
+        //    {
+        //        this.Channel.DownloadFile(fileName, destinationFile);
+        //    }
+        //}
+
+        //public void RemoveFile(string fileName)
+        //{
+        //    this.Channel.RemoveFile(fileName);
+        //}
+
+        //public void RenameFile(string oldFileName, string newFileName)
+        //{
+        //    this.Channel.RenameFile(oldFileName, newFileName);
+        //}
+
+        //public void CreateDirectory(string directoryName)
+        //{
+        //    this.Channel.CreateDirectory(directoryName);
+        //}
+
+        //public void RemoveDirectory(string directoryName)
+        //{
+        //    this.Channel.RemoveDirectory(directoryName);
+        //}
+    }
+}

+ 35 - 0
Renci.SshClient/Renci.SshClient/Sftp/FileStatusCommand.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Renci.SshClient.Sftp.Messages;
+
+namespace Renci.SshClient.Sftp
+{
+    internal class FileStatusCommand : SftpCommand
+    {
+        private string _path;
+
+        public SftpFile SftpFile { get; private set; }
+
+        public FileStatusCommand(SftpSession sftpSession, string path)
+            : base(sftpSession)
+        {
+            this._path = path;
+        }
+
+        protected override void OnExecute()
+        {
+            this.SendStatMessage(this._path);
+        }
+
+        protected override void OnAttributes(Attributes attributes)
+        {
+            base.OnAttributes(attributes);
+
+            this.SftpFile = new SftpFile(this._path, attributes);
+
+            this.CompleteExecution();
+        }
+    }
+}

+ 29 - 0
Renci.SshClient/Renci.SshClient/Sftp/Messages/FSetStat.cs

@@ -0,0 +1,29 @@
+
+namespace Renci.SshClient.Sftp.Messages
+{
+    internal class FSetStat : SftpRequestMessage
+    {
+        public override SftpMessageTypes SftpMessageType
+        {
+            get { return SftpMessageTypes.FSetStat; }
+        }
+
+        public string Handle { get; set; }
+
+        public SftpFileAttributes Attributes { get; set; }
+
+        protected override void LoadData()
+        {
+            base.LoadData();
+            this.Handle = this.ReadString();
+            this.Attributes = this.ReadAttributes();
+        }
+
+        protected override void SaveData()
+        {
+            base.SaveData();
+            this.Write(this.Handle);
+            this.Write(this.Attributes);
+        }
+    }
+}

+ 7 - 0
Renci.SshClient/Renci.SshClient/Sftp/SftpFileAttributes.cs

@@ -0,0 +1,7 @@
+
+namespace Renci.SshClient.Sftp
+{
+    public class SftpFileAttributes
+    {
+    }
+}

+ 58 - 0
Renci.SshClient/Renci.SshClient/SftpAsyncResult.cs

@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using Renci.SshClient.Common;
+
+namespace Renci.SshClient
+{
+    public class SftpAsyncResult : IAsyncResult
+    {
+        private bool _isCompleted;
+
+        private Channels.ChannelSession _channelSession;
+
+        private AsyncCallback _callback;
+
+        private EventWaitHandle _completedWaitHandle = new ManualResetEvent(false);
+
+        public IList<FtpFileInfo> Names { get; internal set; }
+
+        internal SftpAsyncResult(Channels.ChannelSession channelSession, AsyncCallback callback, object state)
+        {
+            this._channelSession = channelSession;
+            this._callback = callback;
+            this.AsyncState = state;
+            this.AsyncWaitHandle = _completedWaitHandle;
+        }
+
+        #region IAsyncResult Members
+
+        public object AsyncState { get; private set; }
+
+        public WaitHandle AsyncWaitHandle { get; private set; }
+
+        public bool CompletedSynchronously { get; private set; }
+
+        public bool IsCompleted
+        {
+            get
+            {
+                return this._isCompleted;
+            }
+            internal set
+            {
+                this._isCompleted = value;
+                if (value)
+                {
+                    if (this._callback != null)
+                    {
+                        this._callback(this);
+                    }
+                    this._completedWaitHandle.Set();
+                }
+            }
+        }
+
+        #endregion
+    }
+}

+ 69 - 0
Renci.SshClient/Renci.SshClient/SshBase.cs

@@ -0,0 +1,69 @@
+
+namespace Renci.SshClient
+{
+    public abstract class SshBase
+    {
+        public ConnectionInfo ConnectionInfo { get; private set; }
+
+        internal Session Session { get; private set; }
+
+        public SshBase(ConnectionInfo connectionInfo)
+        {
+            this.ConnectionInfo = connectionInfo;
+            this.Session = new Session(this.ConnectionInfo);
+        }
+
+        public SshBase(string host, int port, string username, string password)
+            : this(new ConnectionInfo
+            {
+                Host = host,
+                Port = port,
+                Username = username,
+                Password = password,
+            })
+        {
+        }
+
+        public SshBase(string host, string username, string password)
+            : this(new ConnectionInfo
+            {
+                Host = host,
+                Username = username,
+                Password = password,
+            })
+        {
+        }
+
+        public SshBase(string host, int port, string username, PrivateKeyFile keyFile)
+            : this(new ConnectionInfo
+            {
+                Host = host,
+                Port = port,
+                Username = username,
+                KeyFile = keyFile,
+            })
+        {
+        }
+
+        public SshBase(string host, string username, PrivateKeyFile keyFile)
+            : this(new ConnectionInfo
+            {
+                Host = host,
+                Username = username,
+                KeyFile = keyFile,
+            })
+        {
+        }
+
+        public void Connect()
+        {
+            this.Session.Connect();
+        }
+
+        public virtual void Disconnect()
+        {
+            this.Session.Disconnect();
+        }
+
+    }
+}

+ 20 - 0
Renci.SshClient/Renci.SshClient/UserAuthentication.cs

@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Renci.SshClient
+{
+    public class UserAuthentication2
+    {
+        private Session _session;
+
+        public string Username { get; set; }
+
+        internal UserAuthentication2(Session session)
+        {
+            this._session = session;
+            this.Username = session.ConnectionInfo.Username;
+        }
+    }
+}

+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/ConnectionTest.cs → Renci.SshClient/Renci.SshNet.Tests/ConnectionTest.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Properties/AssemblyInfo.cs → Renci.SshClient/Renci.SshNet.Tests/Properties/AssemblyInfo.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Properties/Resources.Designer.cs → Renci.SshClient/Renci.SshNet.Tests/Properties/Resources.Designer.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Properties/Resources.resx → Renci.SshClient/Renci.SshNet.Tests/Properties/Resources.resx


+ 3 - 3
Renci.SshClient/Renci.SshClient.Tests/Renci.SshClient.Tests.csproj → Renci.SshClient/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj

@@ -9,8 +9,8 @@
     <ProjectGuid>{C45379B9-17B1-4E89-BC2E-6D41726413E8}</ProjectGuid>
     <OutputType>Library</OutputType>
     <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Renci.SshClient.Tests</RootNamespace>
-    <AssemblyName>Renci.SshClient.Tests</AssemblyName>
+    <RootNamespace>Renci.SshNet.Tests</RootNamespace>
+    <AssemblyName>Renci.SshNet.Tests</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
@@ -81,7 +81,7 @@
     <Compile Include="SshClientTests\TestSshCommand.cs" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\Renci.SshClient\Renci.SshClient.csproj">
+    <ProjectReference Include="..\Renci.SshNet\Renci.SshNet.csproj">
       <Project>{2F5F8C90-0BD1-424F-997C-7BC6280919D1}</Project>
       <Name>Renci.SshClient</Name>
     </ProjectReference>

+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Renci.SshClient.Tests.csproj.vspscc → Renci.SshClient/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj.vspscc


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Security/Cryptography/TestAes.cs → Renci.SshClient/Renci.SshNet.Tests/Security/Cryptography/TestAes.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Security/Cryptography/TestBlowfish.cs → Renci.SshClient/Renci.SshNet.Tests/Security/Cryptography/TestBlowfish.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Security/Cryptography/TestCast.cs → Renci.SshClient/Renci.SshNet.Tests/Security/Cryptography/TestCast.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Security/TestCipher.cs → Renci.SshClient/Renci.SshNet.Tests/Security/TestCipher.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Security/TestCryptoKey.cs → Renci.SshClient/Renci.SshNet.Tests/Security/TestCryptoKey.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Security/TestHMac.cs → Renci.SshClient/Renci.SshNet.Tests/Security/TestHMac.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Security/TestHostKey.cs → Renci.SshClient/Renci.SshNet.Tests/Security/TestHostKey.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Security/TestKeyExchange.cs → Renci.SshClient/Renci.SshNet.Tests/Security/TestKeyExchange.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/Security/TestPrivateKeyFile.cs → Renci.SshClient/Renci.SshNet.Tests/Security/TestPrivateKeyFile.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/SftpClientTests/CreateDirectoryTest.cs → Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/CreateDirectoryTest.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/SftpClientTests/DeleteDirectoryTest.cs → Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/DeleteDirectoryTest.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/SftpClientTests/DeleteFileTest.cs → Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/DeleteFileTest.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/SftpClientTests/GetTest.cs → Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/GetTest.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/SftpClientTests/ListDirectoryTest.cs → Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/ListDirectoryTest.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/SftpClientTests/RenameFileTest.cs → Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/RenameFileTest.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/SftpClientTests/UploadDownloadFileTest.cs → Renci.SshClient/Renci.SshNet.Tests/SftpClientTests/UploadDownloadFileTest.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestPortForwarding.cs → Renci.SshClient/Renci.SshNet.Tests/SshClientTests/TestPortForwarding.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestShell.cs → Renci.SshClient/Renci.SshNet.Tests/SshClientTests/TestShell.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestSshCommand.cs → Renci.SshClient/Renci.SshNet.Tests/SshClientTests/TestSshCommand.cs


+ 8 - 20
Renci.SshClient/Renci.SshClient.sln → Renci.SshClient/Renci.SshNet.sln

@@ -1,13 +1,11 @@
 
 Microsoft Visual Studio Solution File, Format Version 11.00
 # Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Renci.SshClient", "Renci.SshClient\Renci.SshClient.csproj", "{2F5F8C90-0BD1-424F-997C-7BC6280919D1}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Renci.SshNet", "Renci.SshNet\Renci.SshNet.csproj", "{2F5F8C90-0BD1-424F-997C-7BC6280919D1}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A3063E62-89D5-43FF-AB1A-FFBECB4A1850}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Renci.SshClient.Tests", "Renci.SshClient.Tests\Renci.SshClient.Tests.csproj", "{C45379B9-17B1-4E89-BC2E-6D41726413E8}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{E53AE1B6-5EE8-4B56-B59F-0E7370C8B886}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Renci.SshNet.Tests", "Renci.SshNet.Tests\Renci.SshNet.Tests.csproj", "{C45379B9-17B1-4E89-BC2E-6D41726413E8}"
 EndProject
 Global
 	GlobalSection(TeamFoundationVersionControl) = preSolution
@@ -15,12 +13,12 @@ Global
 		SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
 		SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs11
 		SccLocalPath0 = .
-		SccProjectUniqueName1 = Renci.SshClient\\Renci.SshClient.csproj
-		SccProjectName1 = Renci.SshClient
-		SccLocalPath1 = Renci.SshClient
-		SccProjectUniqueName2 = Renci.SshClient.Tests\\Renci.SshClient.Tests.csproj
-		SccProjectName2 = Renci.SshClient.Tests
-		SccLocalPath2 = Renci.SshClient.Tests
+		SccProjectUniqueName1 = Renci.SshNet\\Renci.SshNet.csproj
+		SccProjectName1 = Renci.SshNet
+		SccLocalPath1 = Renci.SshNet
+		SccProjectUniqueName2 = Renci.SshNet.Tests\\Renci.SshNet.Tests.csproj
+		SccProjectName2 = Renci.SshNet.Tests
+		SccLocalPath2 = Renci.SshNet.Tests
 	EndGlobalSection
 	GlobalSection(TestCaseManagementSettings) = postSolution
 		CategoryFile = Renci.SshClient1.vsmdi
@@ -54,16 +52,6 @@ Global
 		{C45379B9-17B1-4E89-BC2E-6D41726413E8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
 		{C45379B9-17B1-4E89-BC2E-6D41726413E8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 		{C45379B9-17B1-4E89-BC2E-6D41726413E8}.Release|x86.ActiveCfg = Release|Any CPU
-		{E53AE1B6-5EE8-4B56-B59F-0E7370C8B886}.Debug|Any CPU.ActiveCfg = Debug|x86
-		{E53AE1B6-5EE8-4B56-B59F-0E7370C8B886}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
-		{E53AE1B6-5EE8-4B56-B59F-0E7370C8B886}.Debug|Mixed Platforms.Build.0 = Debug|x86
-		{E53AE1B6-5EE8-4B56-B59F-0E7370C8B886}.Debug|x86.ActiveCfg = Debug|x86
-		{E53AE1B6-5EE8-4B56-B59F-0E7370C8B886}.Debug|x86.Build.0 = Debug|x86
-		{E53AE1B6-5EE8-4B56-B59F-0E7370C8B886}.Release|Any CPU.ActiveCfg = Release|x86
-		{E53AE1B6-5EE8-4B56-B59F-0E7370C8B886}.Release|Mixed Platforms.ActiveCfg = Release|x86
-		{E53AE1B6-5EE8-4B56-B59F-0E7370C8B886}.Release|Mixed Platforms.Build.0 = Release|x86
-		{E53AE1B6-5EE8-4B56-B59F-0E7370C8B886}.Release|x86.ActiveCfg = Release|x86
-		{E53AE1B6-5EE8-4B56-B59F-0E7370C8B886}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 0 - 0
Renci.SshClient/Renci.SshClient.vssscc → Renci.SshClient/Renci.SshNet.vssscc


+ 0 - 0
Renci.SshClient/Renci.SshClient/BaseClient.cs → Renci.SshClient/Renci.SshNet/BaseClient.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient/ChannelAsyncResult.cs → Renci.SshClient/Renci.SshNet/ChannelAsyncResult.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient/Channels/Channel.cs → Renci.SshClient/Renci.SshNet/Channels/Channel.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient/Channels/ChannelDirectTcpip.cs → Renci.SshClient/Renci.SshNet/Channels/ChannelDirectTcpip.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient/Channels/ChannelForwardedTcpip.cs → Renci.SshClient/Renci.SshNet/Channels/ChannelForwardedTcpip.cs


+ 0 - 0
Renci.SshClient/Renci.SshClient/Channels/ChannelSession.cs → Renci.SshClient/Renci.SshNet/Channels/ChannelSession.cs


Деякі файли не було показано, через те що забагато файлів було змінено