浏览代码

Merge remote-tracking branch 'refs/remotes/origin/develop'

Gert Driesen 9 年之前
父节点
当前提交
05cdb785ed
共有 51 个文件被更改,包括 1093 次插入946 次删除
  1. 1 119
      build/nuget/SSH.NET.nuspec
  2. 22 15
      src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Close_SessionIsConnectedAndChannelIsOpen_EofReceived.cs
  3. 25 10
      src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketSendShutdownImmediately.cs
  4. 5 1
      src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortStopped.cs
  5. 5 1
      src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Started.cs
  6. 64 8
      src/Renci.SshNet.Tests/Classes/Sftp/SftpDownloadAsyncResultTest.cs
  7. 1 1
      src/Renci.SshNet/AuthenticationMethod.cs
  8. 1 1
      src/Renci.SshNet/BaseClient.cs
  9. 5 3
      src/Renci.SshNet/Channels/ChannelDirectTcpip.cs
  10. 12 42
      src/Renci.SshNet/Common/ASCIIEncoding.cs
  11. 23 20
      src/Renci.SshNet/Common/AsyncResult.cs
  12. 2 2
      src/Renci.SshNet/Common/PipeStream.cs
  13. 2 2
      src/Renci.SshNet/Common/ProxyException.cs
  14. 11 11
      src/Renci.SshNet/Common/SshData.cs
  15. 6 6
      src/Renci.SshNet/Common/SshDataStream.cs
  16. 4 4
      src/Renci.SshNet/ConnectionInfo.cs
  17. 2 2
      src/Renci.SshNet/ExpectAction.cs
  18. 1 1
      src/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.cs
  19. 1 1
      src/Renci.SshNet/MessageEventArgs.cs
  20. 1 1
      src/Renci.SshNet/Messages/Connection/ChannelRequest/ExecRequestInfo.cs
  21. 15 14
      src/Renci.SshNet/NetConfClient.cs
  22. 2 2
      src/Renci.SshNet/NoneAuthenticationMethod.cs
  23. 5 5
      src/Renci.SshNet/PasswordAuthenticationMethod.cs
  24. 9 8
      src/Renci.SshNet/PasswordConnectionInfo.cs
  25. 1 1
      src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs
  26. 4 5
      src/Renci.SshNet/PrivateKeyFile.cs
  27. 7 7
      src/Renci.SshNet/ScpClient.NET.cs
  28. 21 17
      src/Renci.SshNet/ScpClient.cs
  29. 3 3
      src/Renci.SshNet/Security/CertificateHostAlgorithm.cs
  30. 1 1
      src/Renci.SshNet/Security/Cryptography/BlockCipher.cs
  31. 3 3
      src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.cs
  32. 1 1
      src/Renci.SshNet/Security/Cryptography/Ciphers/Arc4Cipher.cs
  33. 1 1
      src/Renci.SshNet/Security/Cryptography/Ciphers/BlowfishCipher.cs
  34. 1 1
      src/Renci.SshNet/Security/Cryptography/Ciphers/CastCipher.cs
  35. 464 467
      src/Renci.SshNet/Security/Cryptography/Ciphers/DesCipher.cs
  36. 1 1
      src/Renci.SshNet/Security/Cryptography/Ciphers/RsaCipher.cs
  37. 1 1
      src/Renci.SshNet/Security/Cryptography/Ciphers/SerpentCipher.cs
  38. 1 1
      src/Renci.SshNet/Security/Cryptography/Ciphers/TripleDesCipher.cs
  39. 1 1
      src/Renci.SshNet/Security/Cryptography/Ciphers/TwofishCipher.cs
  40. 3 3
      src/Renci.SshNet/Security/Cryptography/DsaDigitalSignature.cs
  41. 1 1
      src/Renci.SshNet/Security/Cryptography/StreamCipher.cs
  42. 1 1
      src/Renci.SshNet/Security/Cryptography/SymmetricCipher.cs
  43. 1 1
      src/Renci.SshNet/Sftp/SftpDownloadAsyncResult.cs
  44. 2 2
      src/Renci.SshNet/Sftp/SftpFile.cs
  45. 7 7
      src/Renci.SshNet/Sftp/SftpFileStream.cs
  46. 1 1
      src/Renci.SshNet/Sftp/SftpSession.cs
  47. 298 100
      src/Renci.SshNet/SftpClient.cs
  48. 9 6
      src/Renci.SshNet/ShellStream.cs
  49. 19 18
      src/Renci.SshNet/SshClient.cs
  50. 14 14
      src/Renci.SshNet/SshCommand.cs
  51. 1 1
      src/Renci.SshNet/SubsystemSession.cs

+ 1 - 119
build/nuget/SSH.NET.nuspec

@@ -10,125 +10,7 @@
         <projectUrl>https://github.com/sshnet/SSH.NET/</projectUrl>
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <description>SSH.NET is a Secure Shell (SSH) library for .NET, optimized for parallelism and with broad framework support.</description>
-        <releaseNotes>2016.0.0-beta3
-==============
-
-New Features:
-
-    * Added support for .NET Core 1.0 (.NETStandard 1.3)
-
-2016.0.0-beta2
-==============
-
-Changes:
-
-    * Improved performance of ScpClient (GitHub issue #21)
-
-Fixes:
-
-    * Terminal width (pixels) is not passed in pty-req
-    * Stopping ForwardedPortDynamic without ever having started would result in a NRE
-
-2016.0.0-beta1
-==============
-
-New Features:
-
-    * Added support for HMAC-SHA512 (hmac-sha2-512 and hmac-sha2-512-96)
-    * Added support for Universal Windows Platform 10 (UAP10.0)
-
-Changes:
-
-    * Overall performance improvements
-    * Relicensed code under MIT license, explicitly permitting reuse within proprietary software
-      provided all copies of the licensed software include a copy of the MIT License terms and the
-      copyright notice
-    * Separated our hash algorithms into SshNet.Security.Cryptography project and package
-    * When available, prefer hash algorithms and encodings from target framework
-    * Refactoring to prepare for upcoming .NET Core support
-
-Fixes:
-
-    * Partial reads from stream assume end (CodePlex issue #1516)
-    * Session.Disconnect() hangs forever (CodePlex issue #2591)
-    * SshData.ReadInt64() is broken (CodePlex issue #2579)
-    * Race condition when SSH_MSG_GLOBAL_REQUEST is received immediately after successful authentication (GitHub issue #8)
-
-2014.4.6-beta2
-==============
-
-New Features:
-
-    * Improved accuracy of IsConnected on .NET
-    * Added support for ssh.com (SSH-2) private keys (issue #1987)
-    * Support an acceptable group of up to 8192 bits for SHA-1 and SHA-256 Diffie-Hellman Group and Key Exchange (issues #1973 and #1777)
-
-Changes:
-
-    * Reduced default buffer size for SftpClient from 64 KB to 32 KB as some SSH servers apply a hard limit of 64 KB at the transport level.
-
-Fixes:
-
-    * SftpClient is throwing undocumented exceptions (issue #2148)
-    * Client channels are no longer closed on dispose (issue #1943)
-    * SftpClient.Exists(string) returns true for a path that does not exist (issues #1952, #1696 and #1574)
-    * ObjectDisposedException when channel is closing (issues #1942 and #1944)
-    * Stack overflow during authentication when server returns same allowed methods after partial success (issue #2399)
-    * SshCommand doesn't cleanup subscribed events (issue #2295)
-    * Lines before protocol identification string are not skipped (issue #1935 and #2223)
-    * ShellStream.ReadLine produces incorrect output when reading multi-byte characters (issue #2190)
-    * SftpClient constructor throws ArgumentException when host contains underscore (issue #1845)
-    * Signing key is missing from source download (issue #2455)
-    * Forwarded Port channels can get stuck waiting (issue #1558)
-    * NullReferenceException when SftpFileStream is finalized after dispose of session (issue #2013)
-    * BlockCipher.Encrypt fails if input message is not padded (issue #2547)
-    * ScpClient: Missing files when using DirectoryUpload (issue #1382)
-    * Dynamic port forwarding slows down to a crawl (issue #2010)
-    * SendKeepAlive causes SocketException when connection is dropped (issue #2029)
-    * SocketException on Dispose or Disconnect (issue #2400)
-    * Sending EOF on wrong channel number (issue #1877)
-    * ForwardedPortDynamic: Unhandled exception if client terminates socket (issue #1844)
-
-2014.4.6-beta1
-==============
-
-New Features:
-
-    * Added callbacks to UploadFile, DownloadFile and ListDirectory in SftpClient (issue #1324)
-    * Allow a given private key file to be used concurrently
-    * Performance improvements:
-        - optimization of payload size for both read and write operations (SftpClient only)
-        - increase window size from 1MB to 2MB
-        - increase buffer size from 16KB to 64KB for SftpClient
-        - take into account the maximum remote packet size of the channel for write operations
-        - increase maximum size of packets that we can receive from 32 KB to 64 KB
-    * Improve exception message for authentication failures
-
-Breaking changes:
-
-    * Assembly name is now Renci.SshNet for all supported frameworks
-    * The Renci.SshNet assemblies for .NET and Silverlight are now strong-named (issue #1802)
-
-Fixes:
-
-    * Incorrect copyright in assemblies (issue #1764)
-    * Remove linefeed from WriteLine method in Shellstream class (issue #1584)
-    * Disable logging of messages in release builds (issue #1767)
-    * Stuck loop on key exchange using arcfour encryption (issue #1922)
-    * Timeout sending data to server with low window size (issue #1706)
-    * No connection possible with the same auth method requested multiple times (issue #1930)
-    * Unobserved exception rethrown by finalizer thread (issue #1298 and #1587)
-    * Client cipher is used to decrypt server messages (issue #1917)
-    * Connection dropped by server due to invalid DSA signature (issue #1918)
-    * Correct casing of Security/Cryptography/HMAC.cs to fix build on Linux (issue #1505)
-    * HTTP proxy hangs (issue #1890)
-    * Wrong parameters to SetSocketOption leads to SocketException under Mono (issue #1799)
-    * Incorrect check for timeout values (issue #1620)
-    * Wrong PKCS7 padding in DES algorithm (issue #1580)
-    * OverflowException on empty server response (issue #1562)
-    * Event handle leak (issue #1761)
-    * SftpFileStream is very slow (issue #1919)
-    * Write access required for private key file</releaseNotes>
+        <releaseNotes>https://github.com/sshnet/SSH.NET/releases/tag/2016.0.0-beta3</releaseNotes>
         <summary>A Secure Shell (SSH) library for .NET, optimized for parallelism.</summary>
         <copyright>2012-2016, RENCI</copyright>
         <language>en-US</language>

+ 22 - 15
src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Close_SessionIsConnectedAndChannelIsOpen_EofReceived.cs

@@ -20,9 +20,9 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private uint _remoteWindowSize;
         private uint _remotePacketSize;
         private ChannelStub _channel;
-        private Stopwatch _closeTimer;
         private List<ChannelEventArgs> _channelClosedRegister;
         private IList<ExceptionEventArgs> _channelExceptionRegister;
+        private ManualResetEvent _channelClosedReceived;
 
         [TestInitialize]
         public void Initialize()
@@ -31,6 +31,16 @@ namespace Renci.SshNet.Tests.Classes.Channels
             Act();
         }
 
+        [TestCleanup]
+        public void TearDown()
+        {
+            if (_channelClosedReceived != null)
+            {
+                _channelClosedReceived.Dispose();
+                _channelClosedReceived = null;
+            }
+        }
+
         private void Arrange()
         {
             var random = new Random();
@@ -40,9 +50,9 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _remoteChannelNumber = (uint)random.Next(0, int.MaxValue);
             _remoteWindowSize = (uint)random.Next(0, int.MaxValue);
             _remotePacketSize = (uint)random.Next(0, int.MaxValue);
-            _closeTimer = new Stopwatch();
             _channelClosedRegister = new List<ChannelEventArgs>();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
+            _channelClosedReceived = new ManualResetEvent(false);
 
             _sessionMock = new Mock<ISession>(MockBehavior.Strict);
 
@@ -55,22 +65,19 @@ namespace Renci.SshNet.Tests.Classes.Channels
                         new Thread(() =>
                             {
                                 Thread.Sleep(100);
+                                // signal that the ChannelCloseMessage was received; we use this to verify whether we've actually
+                                // waited on the EventWaitHandle to be set
+                                _channelClosedReceived.Set();
                                 // raise ChannelCloseReceived event to set waithandle for receiving
                                 // SSH_MSG_CHANNEL_CLOSE message from server which is waited on after
                                 // sending the SSH_MSG_CHANNEL_CLOSE message to the server
-                                _sessionMock.Raise(s => s.ChannelCloseReceived += null,
-                                    new MessageEventArgs<ChannelCloseMessage>(
-                                        new ChannelCloseMessage(_localChannelNumber)));
+                                // 
+                                // we're mocking the wait on the ChannelCloseMessage, but we still want
+                                // to get the channel in the state that it would have after actually receiving
+                                // the ChannelCloseMessage
+                                _sessionMock.Raise(s => s.ChannelCloseReceived += null, new MessageEventArgs<ChannelCloseMessage>(new ChannelCloseMessage(_localChannelNumber)));
                             }).Start();
-                        _closeTimer.Start();
-                        try
-                        {
-                            w.WaitOne();
-                        }
-                        finally
-                        {
-                            _closeTimer.Stop();
-                        }
+                        w.WaitOne();
                     });
 
             _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
@@ -120,7 +127,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         [TestMethod]
         public void WaitOnHandleOnSessionShouldWaitForChannelCloseMessageToBeReceived()
         {
-            Assert.IsTrue(_closeTimer.ElapsedMilliseconds >= 100, "Elapsed milliseconds=" + _closeTimer.ElapsedMilliseconds);
+            Assert.IsTrue(_channelClosedReceived.WaitOne(0));
         }
 
         [TestMethod]

+ 25 - 10
src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketSendShutdownImmediately.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Net;
 using System.Net.Sockets;
 using System.Text;
+using System.Threading;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
@@ -21,6 +22,8 @@ namespace Renci.SshNet.Tests.Classes
         private IList<EventArgs> _closingRegister;
         private IList<ExceptionEventArgs> _exceptionRegister;
         private TimeSpan _connectionTimeout;
+        private ManualResetEvent _channelDisposed;
+        private IPEndPoint _forwardedPortEndPoint;
 
         [TestInitialize]
         public void Initialize()
@@ -38,6 +41,7 @@ namespace Renci.SshNet.Tests.Classes
                 _connectionInfoMock.Setup(p => p.Timeout).Returns(TimeSpan.FromSeconds(5));
                 _forwardedPort.Stop();
             }
+
             if (_client != null)
             {
                 if (_client.Connected)
@@ -47,6 +51,12 @@ namespace Renci.SshNet.Tests.Classes
                     _client = null;
                 }
             }
+
+            if (_channelDisposed != null)
+            {
+                _channelDisposed.Dispose();
+                _channelDisposed = null;
+            }
         }
 
         private void SetupData()
@@ -54,6 +64,15 @@ namespace Renci.SshNet.Tests.Classes
             _closingRegister = new List<EventArgs>();
             _exceptionRegister = new List<ExceptionEventArgs>();
             _connectionTimeout = TimeSpan.FromSeconds(5);
+            _channelDisposed = new ManualResetEvent(false);
+            _forwardedPortEndPoint = new IPEndPoint(IPAddress.Loopback, 8122);
+
+            _forwardedPort = new ForwardedPortDynamic((uint) _forwardedPortEndPoint.Port);
+            _forwardedPort.Closing += (sender, args) => _closingRegister.Add(args);
+            _forwardedPort.Exception += (sender, args) => _exceptionRegister.Add(args);
+            _forwardedPort.Session = _sessionMock.Object;
+
+            _client = new Socket(_forwardedPortEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
         }
 
         private void CreateMocks()
@@ -72,30 +91,26 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(seq).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
             _connectionInfoMock.InSequence(seq).Setup(p => p.Timeout).Returns(_connectionTimeout);
             _channelMock.InSequence(seq).Setup(p => p.Close());
-            _channelMock.InSequence(seq).Setup(p => p.Dispose());
+            _channelMock.InSequence(seq).Setup(p => p.Dispose()).Callback(() => _channelDisposed.Set());
         }
 
         private void Arrange()
         {
-            SetupData();
             CreateMocks();
+            SetupData();
             SetupMocks();
 
-            _forwardedPort = new ForwardedPortDynamic(8122);
-            _forwardedPort.Closing += (sender, args) => _closingRegister.Add(args);
-            _forwardedPort.Exception += (sender, args) => _exceptionRegister.Add(args);
-            _forwardedPort.Session = _sessionMock.Object;
             _forwardedPort.Start();
 
-            var endPoint = new IPEndPoint(IPAddress.Loopback, 8122);
-
-            _client = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
-            _client.Connect(endPoint);
+            _client.Connect(_forwardedPortEndPoint);
         }
 
         private void Act()
         {
             _client.Shutdown(SocketShutdown.Send);
+
+            // wait for channel to be disposed
+            _channelDisposed.WaitOne(TimeSpan.FromMilliseconds(200));
         }
 
         [TestMethod]

+ 5 - 1
src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortStopped.cs

@@ -121,6 +121,7 @@ namespace Renci.SshNet.Tests.Classes
             var originatorAddress = new Random().Next().ToString(CultureInfo.InvariantCulture);
             var originatorPort = (uint)new Random().Next(0, int.MaxValue);
             var channelMock = new Mock<IChannelForwardedTcpip>(MockBehavior.Strict);
+            var channelDiposed = new ManualResetEvent(false);
 
             _sessionMock.Setup(
                 p =>
@@ -132,7 +133,7 @@ namespace Renci.SshNet.Tests.Classes
                             ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port),
                         _forwardedPort));
             channelMock.Setup(p => p.Close());
-            channelMock.Setup(p => p.Dispose());
+            channelMock.Setup(p => p.Dispose()).Callback(() => channelDiposed.Set());
 
             _sessionMock.Raise(p => p.ChannelOpenReceived += null,
                 new MessageEventArgs<ChannelOpenMessage>(new ChannelOpenMessage(channelNumber, initialWindowSize,
@@ -140,6 +141,9 @@ namespace Renci.SshNet.Tests.Classes
                     new ForwardedTcpipChannelInfo(_forwardedPort.BoundHost, _forwardedPort.BoundPort, originatorAddress,
                         originatorPort))));
 
+            // wait for channel to be disposed
+            channelDiposed.WaitOne(TimeSpan.FromMilliseconds(200));
+
             _sessionMock.Verify(p => p.CreateChannelForwardedTcpip(channelNumber, initialWindowSize, maximumPacketSize), Times.Once);
             channelMock.Verify(p => p.Bind(It.Is<IPEndPoint>(ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port), _forwardedPort), Times.Once);
             channelMock.Verify(p => p.Close(), Times.Once);

+ 5 - 1
src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Started.cs

@@ -99,6 +99,7 @@ namespace Renci.SshNet.Tests.Classes
             var originatorAddress = new Random().Next().ToString(CultureInfo.InvariantCulture);
             var originatorPort = (uint) new Random().Next(0, int.MaxValue);
             var channelMock = new Mock<IChannelForwardedTcpip>(MockBehavior.Strict);
+            var channelDisposed = new ManualResetEvent(false);
 
             _sessionMock.Setup(
                 p =>
@@ -110,7 +111,7 @@ namespace Renci.SshNet.Tests.Classes
                             ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port),
                         _forwardedPort));
             channelMock.Setup(p => p.Close());
-            channelMock.Setup(p => p.Dispose());
+            channelMock.Setup(p => p.Dispose()).Callback(() => channelDisposed.Set());
 
             _sessionMock.Raise(p => p.ChannelOpenReceived += null,
                 new MessageEventArgs<ChannelOpenMessage>(new ChannelOpenMessage(channelNumber, initialWindowSize,
@@ -118,6 +119,9 @@ namespace Renci.SshNet.Tests.Classes
                     new ForwardedTcpipChannelInfo(_forwardedPort.BoundHost, _forwardedPort.BoundPort, originatorAddress,
                         originatorPort))));
 
+            // wait for channel to be disposed
+            channelDisposed.WaitOne(TimeSpan.FromMilliseconds(200));
+
             _sessionMock.Verify(p => p.CreateChannelForwardedTcpip(channelNumber, initialWindowSize, maximumPacketSize), Times.Once);
             channelMock.Verify(p => p.Bind(It.Is<IPEndPoint>(ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port), _forwardedPort), Times.Once);
             channelMock.Verify(p => p.Close(), Times.Once);

+ 64 - 8
src/Renci.SshNet.Tests/Classes/Sftp/SftpDownloadAsyncResultTest.cs

@@ -1,4 +1,6 @@
 using System;
+using System.IO;
+using System.Threading;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Renci.SshNet.Sftp;
 using Renci.SshNet.Tests.Common;
@@ -12,17 +14,71 @@ namespace Renci.SshNet.Tests.Classes.Sftp
     [TestClass]
     public class SftpDownloadAsyncResultTest : TestBase
     {
-        /// <summary>
-        ///A test for SftpDownloadAsyncResult Constructor
-        ///</summary>
         [TestMethod]
-        [Ignore] // placeholder
         public void SftpDownloadAsyncResultConstructorTest()
         {
-            AsyncCallback asyncCallback = null; // TODO: Initialize to an appropriate value
-            object state = null; // TODO: Initialize to an appropriate value
-            SftpDownloadAsyncResult target = new SftpDownloadAsyncResult(asyncCallback, state);
-            Assert.Inconclusive("TODO: Implement code to verify target");
+            const AsyncCallback asyncCallback = null;
+            var state = new object();
+            var target = new SftpDownloadAsyncResult(asyncCallback, state);
+
+            Assert.IsFalse(target.CompletedSynchronously);
+            Assert.IsFalse(target.EndInvokeCalled);
+            Assert.IsFalse(target.IsCompleted);
+            Assert.IsFalse(target.IsDownloadCanceled);
+            Assert.AreEqual(0UL, target.DownloadedBytes);
+            Assert.AreSame(state, target.AsyncState);
+        }
+
+        [TestMethod]
+        public void SetAsCompleted_Exception_CompletedSynchronously()
+        {
+            var downloadCompleted = new ManualResetEvent(false);
+            object state = "STATE";
+            Exception exception = new IOException();
+            IAsyncResult callbackResult = null;
+            var target = new SftpDownloadAsyncResult(asyncResult =>
+                {
+                    downloadCompleted.Set();
+                    callbackResult = asyncResult;
+                }, state);
+
+            target.SetAsCompleted(exception, true);
+
+            Assert.AreSame(target, callbackResult);
+            Assert.IsFalse(target.IsDownloadCanceled);
+            Assert.IsTrue(target.IsCompleted);
+            Assert.IsTrue(target.CompletedSynchronously);
+            Assert.IsTrue(downloadCompleted.WaitOne(TimeSpan.Zero));
+        }
+
+        [TestMethod]
+        public void EndInvoke_CompletedWithException()
+        {
+            object state = "STATE";
+            Exception exception = new IOException();
+            var target = new SftpDownloadAsyncResult(null, state);
+            target.SetAsCompleted(exception, true);
+
+            try
+            {
+                target.EndInvoke();
+                Assert.Fail();
+            }
+            catch (IOException ex)
+            {
+                Assert.AreSame(exception, ex);
+            }
+        }
+
+        [TestMethod]
+        public void Update()
+        {
+            var target = new SftpDownloadAsyncResult(null, null);
+
+            target.Update(123);
+            target.Update(431);
+
+            Assert.AreEqual(431UL, target.DownloadedBytes);
         }
     }
 }

+ 1 - 1
src/Renci.SshNet/AuthenticationMethod.cs

@@ -30,7 +30,7 @@ namespace Renci.SshNet
         /// Initializes a new instance of the <see cref="AuthenticationMethod"/> class.
         /// </summary>
         /// <param name="username">The username.</param>
-        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or <c>null</c>.</exception>
         protected AuthenticationMethod(string username)
         {
             if (username.IsNullOrWhiteSpace())

+ 1 - 1
src/Renci.SshNet/BaseClient.cs

@@ -139,7 +139,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="connectionInfo">The connection info.</param>
         /// <param name="ownsConnectionInfo">Specified whether this instance owns the connection info.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <c>null</c>.</exception>
         /// <remarks>
         /// If <paramref name="ownsConnectionInfo"/> is <c>true</c>, then the
         /// connection info will be disposed when this instance is disposed.

+ 5 - 3
src/Renci.SshNet/Channels/ChannelDirectTcpip.cs

@@ -68,11 +68,13 @@ namespace Renci.SshNet.Channels
         /// </summary>
         private void ForwardedPort_Closing(object sender, EventArgs eventArgs)
         {
-            // signal to the client that we will not send anything anymore; this will also interrupt the
+            // signal to the client that we will not send anything anymore; this should also interrupt the
             // blocking receive in Bind if the client sends FIN/ACK in time
-            //
-            // if the FIN/ACK is not sent in time, the socket will be closed in Close(bool)
             ShutdownSocket(SocketShutdown.Send);
+
+            // if the FIN/ACK is not sent in time by the remote client, then interrupt the blocking receive
+            // by closing the socket
+            CloseSocket();
         }
 
         /// <summary>

+ 12 - 42
src/Renci.SshNet/Common/ASCIIEncoding.cs

@@ -44,13 +44,8 @@ namespace Renci.SshNet.Common
         /// <returns>
         /// The number of bytes produced by encoding the specified characters.
         /// </returns>
-        /// <exception cref="T:System.ArgumentNullException">
-        ///   <paramref name="chars"/> is null. </exception>
-        ///   
-        /// <exception cref="T:System.ArgumentOutOfRangeException">
-        ///   <paramref name="index"/> or <paramref name="count"/> is less than zero.-or- <paramref name="index"/> and <paramref name="count"/> do not denote a valid range in <paramref name="chars"/>. </exception>
-        ///   
-        /// <exception cref="T:System.Text.EncoderFallbackException">A fallback occurred (see Understanding Encodings for complete explanation)-and-<see cref="P:System.Text.Encoding.EncoderFallback"/> is set to <see cref="T:System.Text.EncoderExceptionFallback"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="chars"/> is  <c>null</c>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> or <paramref name="count"/> is less than zero.-or- <paramref name="index"/> and <paramref name="count"/> do not denote a valid range in <paramref name="chars"/>.</exception>
         public override int GetByteCount(char[] chars, int index, int count)
         {
             return count;
@@ -67,16 +62,9 @@ namespace Renci.SshNet.Common
         /// <returns>
         /// The actual number of bytes written into <paramref name="bytes"/>.
         /// </returns>
-        /// <exception cref="T:System.ArgumentNullException">
-        ///   <paramref name="chars"/> is null.-or- <paramref name="bytes"/> is null. </exception>
-        ///   
-        /// <exception cref="T:System.ArgumentOutOfRangeException">
-        ///   <paramref name="charIndex"/> or <paramref name="charCount"/> or <paramref name="byteIndex"/> is less than zero.-or- <paramref name="charIndex"/> and <paramref name="charCount"/> do not denote a valid range in <paramref name="chars"/>.-or- <paramref name="byteIndex"/> is not a valid index in <paramref name="bytes"/>. </exception>
-        ///   
-        /// <exception cref="T:System.ArgumentException">
-        ///   <paramref name="bytes"/> does not have enough capacity from <paramref name="byteIndex"/> to the end of the array to accommodate the resulting bytes. </exception>
-        ///   
-        /// <exception cref="T:System.Text.EncoderFallbackException">A fallback occurred (see Understanding Encodings for complete explanation)-and-<see cref="P:System.Text.Encoding.EncoderFallback"/> is set to <see cref="T:System.Text.EncoderExceptionFallback"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="chars"/> is  <c>null</c>.-or- <paramref name="bytes"/> is  <c>null</c>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="charIndex"/> or <paramref name="charCount"/> or <paramref name="byteIndex"/> is less than zero.-or- <paramref name="charIndex"/> and <paramref name="charCount"/> do not denote a valid range in <paramref name="chars"/>.-or- <paramref name="byteIndex"/> is not a valid index in <paramref name="bytes"/>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="bytes"/> does not have enough capacity from <paramref name="byteIndex"/> to the end of the array to accommodate the resulting bytes.</exception>
         public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
         {
             for (var i = 0; i < charCount && i < chars.Length; i++)
@@ -100,13 +88,8 @@ namespace Renci.SshNet.Common
         /// <returns>
         /// The number of characters produced by decoding the specified sequence of bytes.
         /// </returns>
-        /// <exception cref="T:System.ArgumentNullException">
-        ///   <paramref name="bytes"/> is null. </exception>
-        ///   
-        /// <exception cref="T:System.ArgumentOutOfRangeException">
-        ///   <paramref name="index"/> or <paramref name="count"/> is less than zero.-or- <paramref name="index"/> and <paramref name="count"/> do not denote a valid range in <paramref name="bytes"/>. </exception>
-        ///   
-        /// <exception cref="T:System.Text.DecoderFallbackException">A fallback occurred (see Understanding Encodings for complete explanation)-and-<see cref="P:System.Text.Encoding.DecoderFallback"/> is set to <see cref="T:System.Text.DecoderExceptionFallback"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> or <paramref name="count"/> is less than zero.-or- <paramref name="index"/> and <paramref name="count"/> do not denote a valid range in <paramref name="bytes"/>.</exception>
         public override int GetCharCount(byte[] bytes, int index, int count)
         {
             return count;
@@ -123,16 +106,9 @@ namespace Renci.SshNet.Common
         /// <returns>
         /// The actual number of characters written into <paramref name="chars"/>.
         /// </returns>
-        /// <exception cref="T:System.ArgumentNullException">
-        ///   <paramref name="bytes"/> is null.-or- <paramref name="chars"/> is null. </exception>
-        ///   
-        /// <exception cref="T:System.ArgumentOutOfRangeException">
-        ///   <paramref name="byteIndex"/> or <paramref name="byteCount"/> or <paramref name="charIndex"/> is less than zero.-or- <paramref name="byteIndex"/> and <paramref name="byteCount"/> do not denote a valid range in <paramref name="bytes"/>.-or- <paramref name="charIndex"/> is not a valid index in <paramref name="chars"/>. </exception>
-        ///   
-        /// <exception cref="T:System.ArgumentException">
-        ///   <paramref name="chars"/> does not have enough capacity from <paramref name="charIndex"/> to the end of the array to accommodate the resulting characters. </exception>
-        ///   
-        /// <exception cref="T:System.Text.DecoderFallbackException">A fallback occurred (see Understanding Encodings for complete explanation)-and-<see cref="P:System.Text.Encoding.DecoderFallback"/> is set to <see cref="T:System.Text.DecoderExceptionFallback"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is  <c>null</c>.-or- <paramref name="chars"/> is  <c>null</c>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="byteIndex"/> or <paramref name="byteCount"/> or <paramref name="charIndex"/> is less than zero.-or- <paramref name="byteIndex"/> and <paramref name="byteCount"/> do not denote a valid range in <paramref name="bytes"/>.-or- <paramref name="charIndex"/> is not a valid index in <paramref name="chars"/>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="chars"/> does not have enough capacity from <paramref name="charIndex"/> to the end of the array to accommodate the resulting characters.</exception>
         public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
         {
             for (var i = 0; i < byteCount; i++)
@@ -161,10 +137,7 @@ namespace Renci.SshNet.Common
         /// <returns>
         /// The maximum number of bytes produced by encoding the specified number of characters.
         /// </returns>
-        /// <exception cref="T:System.ArgumentOutOfRangeException">
-        ///   <paramref name="charCount"/> is less than zero. </exception>
-        ///   
-        /// <exception cref="T:System.Text.EncoderFallbackException">A fallback occurred (see Understanding Encodings for complete explanation)-and-<see cref="P:System.Text.Encoding.EncoderFallback"/> is set to <see cref="T:System.Text.EncoderExceptionFallback"/>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="charCount"/> is less than zero.</exception>
         public override int GetMaxByteCount(int charCount)
         {
             if (charCount < 0)
@@ -180,10 +153,7 @@ namespace Renci.SshNet.Common
         /// <returns>
         /// The maximum number of characters produced by decoding the specified number of bytes.
         /// </returns>
-        /// <exception cref="T:System.ArgumentOutOfRangeException">
-        ///   <paramref name="byteCount"/> is less than zero. </exception>
-        ///   
-        /// <exception cref="T:System.Text.DecoderFallbackException">A fallback occurred (see Understanding Encodings for complete explanation)-and-<see cref="P:System.Text.Encoding.DecoderFallback"/> is set to <see cref="T:System.Text.DecoderExceptionFallback"/>.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="byteCount"/> is less than zero.</exception>
         public override int GetMaxCharCount(int byteCount)
         {
             if (byteCount < 0)

+ 23 - 20
src/Renci.SshNet/Common/AsyncResult.cs

@@ -11,16 +11,16 @@ namespace Renci.SshNet.Common
         // Fields set at construction which never change while operation is pending
         private readonly AsyncCallback _asyncCallback;
 
-        private readonly Object _asyncState;
+        private readonly object _asyncState;
 
         // Field set at construction which do change after operation completes
-        private const Int32 StatePending = 0;
+        private const int StatePending = 0;
 
-        private const Int32 StateCompletedSynchronously = 1;
+        private const int StateCompletedSynchronously = 1;
 
-        private const Int32 StateCompletedAsynchronously = 2;
+        private const int StateCompletedAsynchronously = 2;
 
-        private Int32 _completedState = StatePending;
+        private int _completedState = StatePending;
 
         // Field that may or may not get set depending on usage
         private ManualResetEvent _asyncWaitHandle;
@@ -32,7 +32,7 @@ namespace Renci.SshNet.Common
         /// Gets or sets a value indicating whether EndInvoke has been called on the current AsyncResult.
         /// </summary>
         /// <value>
-        /// 	<c>true</c> if EndInvoke has been called on the current AsyncResult; otherwise, <c>false</c>.
+        /// <c>true</c> if <see cref="EndInvoke()"/> has been called on the current <see cref="AsyncResult"/>; otherwise, <c>false</c>.
         /// </value>
         public bool EndInvokeCalled { get; private set; }
 
@@ -41,7 +41,7 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="asyncCallback">The async callback.</param>
         /// <param name="state">The state.</param>
-        protected AsyncResult(AsyncCallback asyncCallback, Object state)
+        protected AsyncResult(AsyncCallback asyncCallback, object state)
         {
             _asyncCallback = asyncCallback;
             _asyncState = state;
@@ -52,7 +52,7 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="exception">The exception.</param>
         /// <param name="completedSynchronously">if set to <c>true</c> [completed synchronously].</param>
-        public void SetAsCompleted(Exception exception, Boolean completedSynchronously)
+        public void SetAsCompleted(Exception exception, bool completedSynchronously)
         {
             // Passing null for exception means no error occurred; this is the common case
             _exception = exception;
@@ -90,7 +90,7 @@ namespace Renci.SshNet.Common
 
             // Operation is done: if an exception occurred, throw it
             if (_exception != null)
-                throw new SshException(_exception.Message, _exception);
+                throw _exception;
         }
 
         #region Implementation of IAsyncResult
@@ -99,21 +99,21 @@ namespace Renci.SshNet.Common
         /// Gets a user-defined object that qualifies or contains information about an asynchronous operation.
         /// </summary>
         /// <returns>A user-defined object that qualifies or contains information about an asynchronous operation.</returns>
-        public Object AsyncState { get { return _asyncState; } }
+        public object AsyncState { get { return _asyncState; } }
 
         /// <summary>
         /// Gets a value that indicates whether the asynchronous operation completed synchronously.
         /// </summary>
         /// <returns>true if the asynchronous operation completed synchronously; otherwise, false.</returns>
-        public Boolean CompletedSynchronously
+        public bool CompletedSynchronously
         {
             get { return _completedState == StateCompletedSynchronously; }
         }
 
         /// <summary>
-        /// Gets a <see cref="T:System.Threading.WaitHandle"/> that is used to wait for an asynchronous operation to complete.
+        /// Gets a <see cref="WaitHandle"/> that is used to wait for an asynchronous operation to complete.
         /// </summary>
-        /// <returns>A <see cref="T:System.Threading.WaitHandle"/> that is used to wait for an asynchronous operation to complete.</returns>
+        /// <returns>A <see cref="WaitHandle"/> that is used to wait for an asynchronous operation to complete.</returns>
         public WaitHandle AsyncWaitHandle
         {
             get
@@ -144,8 +144,9 @@ namespace Renci.SshNet.Common
         /// <summary>
         /// Gets a value that indicates whether the asynchronous operation has completed.
         /// </summary>
-        /// <returns>true if the operation is complete; otherwise, false.</returns>
-        public Boolean IsCompleted
+        /// <returns>
+        /// <c>true</c> if the operation is complete; otherwise, <c>false</c>.</returns>
+        public bool IsCompleted
         {
             get { return _completedState != StatePending; }
         }
@@ -162,11 +163,11 @@ namespace Renci.SshNet.Common
         private TResult _result;
 
         /// <summary>
-        /// Initializes a new instance of the <see cref="AsyncResult&lt;TResult&gt;"/> class.
+        /// Initializes a new instance of the <see cref="AsyncResult{TResult}"/> class.
         /// </summary>
         /// <param name="asyncCallback">The async callback.</param>
         /// <param name="state">The state.</param>
-        protected AsyncResult(AsyncCallback asyncCallback, Object state)
+        protected AsyncResult(AsyncCallback asyncCallback, object state)
             : base(asyncCallback, state)
         {
         }
@@ -176,19 +177,21 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="result">The result.</param>
         /// <param name="completedSynchronously">if set to <c>true</c> [completed synchronously].</param>
-        public void SetAsCompleted(TResult result, Boolean completedSynchronously)
+        public void SetAsCompleted(TResult result, bool completedSynchronously)
         {
             // Save the asynchronous operation's result
             _result = result;
 
             // Tell the base class that the operation completed successfully (no exception)
-            base.SetAsCompleted(null, completedSynchronously);
+            SetAsCompleted(null, completedSynchronously);
         }
 
         /// <summary>
         /// Waits until the asynchronous operation completes, and then returns the value generated by the asynchronous operation. 
         /// </summary>
-        /// <returns>Invocation result</returns>
+        /// <returns>
+        /// The invocation result.
+        /// </returns>
         public new TResult EndInvoke()
         {
             base.EndInvoke(); // Wait until operation has completed 

+ 2 - 2
src/Renci.SshNet/Common/PipeStream.cs

@@ -175,7 +175,7 @@
         ///<exception cref="ArgumentException">The sum of offset and count is larger than the buffer length.</exception>
         ///<exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
         ///<exception cref="NotSupportedException">The stream does not support reading.</exception>
-        ///<exception cref="ArgumentNullException">buffer is null.</exception>
+        ///<exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
         ///<exception cref="IOException">An I/O error occurs.</exception>
         ///<exception cref="ArgumentOutOfRangeException">offset or count is negative.</exception>
         public override int Read(byte[] buffer, int offset, int count)
@@ -242,7 +242,7 @@
         ///<exception cref="IOException">An I/O error occurs.</exception>
         ///<exception cref="NotSupportedException">The stream does not support writing.</exception>
         ///<exception cref="ObjectDisposedException">Methods were called after the stream was closed.</exception>
-        ///<exception cref="ArgumentNullException">buffer is null.</exception>
+        ///<exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
         ///<exception cref="ArgumentException">The sum of offset and count is greater than the buffer length.</exception>
         ///<exception cref="ArgumentOutOfRangeException">offset or count is negative.</exception>
         public override void Write(byte[] buffer, int offset, int count)

+ 2 - 2
src/Renci.SshNet/Common/ProxyException.cs

@@ -45,8 +45,8 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
         /// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
-        /// <exception cref="ArgumentNullException">The <paramref name="info"/> parameter is null. </exception>
-        /// <exception cref="SerializationException">The class name is null or <see cref="Exception.HResult"/> is zero (0). </exception>
+        /// <exception cref="ArgumentNullException">The <paramref name="info"/> parameter is <c>null</c>.</exception>
+        /// <exception cref="SerializationException">The class name is <c>null</c> or <see cref="Exception.HResult"/> is zero (0).</exception>
         protected ProxyException(SerializationInfo info, StreamingContext context)
             : base(info, context)
         {

+ 11 - 11
src/Renci.SshNet/Common/SshData.cs

@@ -108,7 +108,7 @@ namespace Renci.SshNet.Common
         /// Loads data from specified bytes.
         /// </summary>
         /// <param name="value">Bytes array.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="value"/> is <c>null</c>.</exception>
         public void Load(byte[] value)
         {
             Load(value, 0);
@@ -119,7 +119,7 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="value">Bytes array.</param>
         /// <param name="offset">The zero-based offset in <paramref name="value"/> at which to begin reading SSH data.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="value"/> is <c>null</c>.</exception>
         public void Load(byte[] value, int offset)
         {
             LoadBytes(value, offset);
@@ -140,7 +140,7 @@ namespace Renci.SshNet.Common
         /// Loads data bytes into internal buffer.
         /// </summary>
         /// <param name="bytes">The bytes.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is <c>null</c>.</exception>
         protected void LoadBytes(byte[] bytes)
         {
             LoadBytes(bytes, 0);
@@ -151,7 +151,7 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="bytes">The bytes.</param>
         /// <param name="offset">The zero-based offset in <paramref name="bytes"/> at which to begin reading SSH data.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is <c>null</c>.</exception>
         protected void LoadBytes(byte[] bytes, int offset)
         {
             if (bytes == null)
@@ -310,7 +310,7 @@ namespace Renci.SshNet.Common
         /// Writes bytes array data into internal buffer.
         /// </summary>
         /// <param name="data">Byte array data to write.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="data"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="data"/> is <c>null</c>.</exception>
         protected void Write(byte[] data)
         {
             _stream.Write(data);
@@ -323,7 +323,7 @@ namespace Renci.SshNet.Common
         /// <param name="buffer">An array of bytes. This method write <paramref name="count"/> bytes from buffer to the current SSH data stream.</param>
         /// <param name="offset">The zero-based offset in <paramref name="buffer"/> at which to begin writing bytes to the SSH data stream.</param>
         /// <param name="count">The number of bytes to be written to the current SSH data stream.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is greater than the buffer length.</exception>
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> or <paramref name="count"/> is negative.</exception>
         protected void Write(byte[] buffer, int offset, int count)
@@ -371,7 +371,7 @@ namespace Renci.SshNet.Common
         /// Writes <see cref="string"/> data into internal buffer using default encoding.
         /// </summary>
         /// <param name="data"><see cref="string"/> data to write.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="data"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="data"/> is <c>null</c>.</exception>
         protected void Write(string data)
         {
             Write(data, Utf8);
@@ -382,8 +382,8 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="data"><see cref="string"/> data to write.</param>
         /// <param name="encoding">The character encoding to use.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="data"/> is null.</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="encoding"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="data"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="encoding"/> is <c>null</c>.</exception>
         protected void Write(string data, Encoding encoding)
         {
             _stream.Write(data, encoding);
@@ -393,7 +393,7 @@ namespace Renci.SshNet.Common
         /// Writes data into internal buffer.
         /// </summary>
         /// <param name="buffer">The data to write.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
         protected void WriteBinaryString(byte[] buffer)
         {
             _stream.WriteBinary(buffer);
@@ -405,7 +405,7 @@ namespace Renci.SshNet.Common
         /// <param name="buffer">An array of bytes. This method write <paramref name="count"/> bytes from buffer to the current SSH data stream.</param>
         /// <param name="offset">The zero-based byte offset in <paramref name="buffer"/> at which to begin writing bytes to the SSH data stream.</param>
         /// <param name="count">The number of bytes to be written to the current SSH data stream.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is greater than the buffer length.</exception>
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> or <paramref name="count"/> is negative.</exception>
         protected void WriteBinary(byte[] buffer, int offset, int count)

+ 6 - 6
src/Renci.SshNet/Common/SshDataStream.cs

@@ -24,7 +24,7 @@ namespace Renci.SshNet.Common
         /// Initializes a new non-resizable instance of the <see cref="SshDataStream"/> class based on the specified byte array.
         /// </summary>
         /// <param name="buffer">The array of unsigned bytes from which to create the current stream.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null.</c></exception>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
         public SshDataStream(byte[] buffer)
             : base(buffer)
         {
@@ -78,7 +78,7 @@ namespace Renci.SshNet.Common
         /// Writes bytes array data into the SSH data stream.
         /// </summary>
         /// <param name="data">Byte array data to write.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="data"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="data"/> is <c>null</c>.</exception>
         public void Write(byte[] data)
         {
             if (data == null)
@@ -109,7 +109,7 @@ namespace Renci.SshNet.Common
         /// Writes a buffer preceded by its length into the SSH data stream.
         /// </summary>
         /// <param name="buffer">The data to write.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
         public void WriteBinary(byte[] buffer)
         {
             if (buffer == null)
@@ -124,7 +124,7 @@ namespace Renci.SshNet.Common
         /// <param name="buffer">An array of bytes. This method write <paramref name="count"/> bytes from buffer to the current SSH data stream.</param>
         /// <param name="offset">The zero-based byte offset in <paramref name="buffer"/> at which to begin writing bytes to the SSH data stream.</param>
         /// <param name="count">The number of bytes to be written to the current SSH data stream.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is greater than the buffer length.</exception>
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> or <paramref name="count"/> is negative.</exception>
         public void WriteBinary(byte[] buffer, int offset, int count)
@@ -138,8 +138,8 @@ namespace Renci.SshNet.Common
         /// </summary>
         /// <param name="s">The string data to write.</param>
         /// <param name="encoding">The character encoding to use.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="s"/> is null.</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="encoding"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="s"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="encoding"/> is <c>null</c>.</exception>
         public void Write(string s, Encoding encoding)
         {
             if (encoding == null)

+ 4 - 4
src/Renci.SshNet/ConnectionInfo.cs

@@ -218,7 +218,7 @@ namespace Renci.SshNet
         /// <param name="authenticationMethods">The authentication methods.</param>
         /// <exception cref="ArgumentNullException"><paramref name="host"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException"><paramref name="host"/> is a zero-length string.</exception>
-        /// <exception cref="ArgumentException"><paramref name="username" /> is null, a zero-length string or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentException"><paramref name="username" /> is <c>null</c>, a zero-length string or contains only whitespace characters.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="authenticationMethods"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">No <paramref name="authenticationMethods"/> specified.</exception>
         public ConnectionInfo(string host, string username, params AuthenticationMethod[] authenticationMethods)
@@ -234,7 +234,7 @@ namespace Renci.SshNet
         /// <param name="username">The username.</param>
         /// <param name="authenticationMethods">The authentication methods.</param>
         /// <exception cref="ArgumentNullException"><paramref name="host"/> is <c>null</c>.</exception>
-        /// <exception cref="ArgumentException"><paramref name="username" /> is null, a zero-length string or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentException"><paramref name="username" /> is <c>null</c>, a zero-length string or contains only whitespace characters.</exception>
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is not within <see cref="F:System.Net.IPEndPoint.MinPort" /> and <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="authenticationMethods"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">No <paramref name="authenticationMethods"/> specified.</exception>
@@ -256,7 +256,7 @@ namespace Renci.SshNet
         /// <param name="proxyPassword">The proxy password.</param>
         /// <param name="authenticationMethods">The authentication methods.</param>
         /// <exception cref="ArgumentNullException"><paramref name="host"/> is <c>null</c>.</exception>
-        /// <exception cref="ArgumentException"><paramref name="username" /> is null, a zero-length string or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentException"><paramref name="username" /> is <c>null</c>, a zero-length string or contains only whitespace characters.</exception>
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is not within <see cref="F:System.Net.IPEndPoint.MinPort" /> and <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="proxyType"/> is not <see cref="ProxyTypes.None"/> and <paramref name="proxyHost" /> is <c>null</c>.</exception>
         /// <exception cref="ArgumentOutOfRangeException"><paramref name="proxyType"/> is not <see cref="ProxyTypes.None"/> and <paramref name="proxyPort" /> is not within <see cref="F:System.Net.IPEndPoint.MinPort" /> and <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
@@ -401,7 +401,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="session">The session to be authenticated.</param>
         /// <param name="serviceFactory">The factory to use for creating new services.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="session"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="session"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentNullException"><paramref name="serviceFactory"/> is <c>null</c>.</exception>
         /// <exception cref="SshAuthenticationException">No suitable authentication method found to complete authentication, or permission denied.</exception>
         internal void Authenticate(ISession session, IServiceFactory serviceFactory)

+ 2 - 2
src/Renci.SshNet/ExpectAction.cs

@@ -23,7 +23,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="expect">The expect regular expression.</param>
         /// <param name="action">The action to perform.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="expect"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="expect"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public ExpectAction(Regex expect, Action<string> action)
         {
             if (expect == null)
@@ -41,7 +41,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="expect">The expect expression.</param>
         /// <param name="action">The action to perform.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="expect"/> or <paramref name="action"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="expect"/> or <paramref name="action"/> is <c>null</c>.</exception>
         public ExpectAction(string expect, Action<string> action)
         {
             if (expect == null)

+ 1 - 1
src/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.cs

@@ -37,7 +37,7 @@ namespace Renci.SshNet
         /// Initializes a new instance of the <see cref="KeyboardInteractiveAuthenticationMethod"/> class.
         /// </summary>
         /// <param name="username">The username.</param>
-        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or <c>null</c>.</exception>
         public KeyboardInteractiveAuthenticationMethod(string username)
             : base(username)
         {

+ 1 - 1
src/Renci.SshNet/MessageEventArgs.cs

@@ -17,7 +17,7 @@ namespace Renci.SshNet
         /// Initializes a new instance of the <see cref="MessageEventArgs&lt;T&gt;"/> class.
         /// </summary>
         /// <param name="message">The message.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="message"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="message"/> is <c>null</c>.</exception>
         public MessageEventArgs(T message)
         {
             if (message == null)

+ 1 - 1
src/Renci.SshNet/Messages/Connection/ChannelRequest/ExecRequestInfo.cs

@@ -75,7 +75,7 @@ namespace Renci.SshNet.Messages.Connection
         /// </summary>
         /// <param name="command">The command.</param>
         /// <param name="encoding">The character encoding to use.</param>
-        /// <exception cref="System.ArgumentNullException"><paramref name="command"/> or <paramref name="encoding"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="command"/> or <paramref name="encoding"/> is <c>null</c>.</exception>
         public ExecRequestInfo(string command, Encoding encoding)
             : this()
         {

+ 15 - 14
src/Renci.SshNet/NetConfClient.cs

@@ -3,6 +3,7 @@ using Renci.SshNet.Common;
 using Renci.SshNet.NetConf;
 using System.Xml;
 using System.Diagnostics.CodeAnalysis;
+using System.Net;
 
 namespace Renci.SshNet
 {
@@ -32,7 +33,7 @@ namespace Renci.SshNet
         /// Initializes a new instance of the <see cref="SftpClient"/> class.
         /// </summary>
         /// <param name="connectionInfo">The connection info.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <c>null</c>.</exception>
         public NetConfClient(ConnectionInfo connectionInfo)
             : this(connectionInfo, false)
         {
@@ -45,9 +46,9 @@ namespace Renci.SshNet
         /// <param name="port">Connection port.</param>
         /// <param name="username">Authentication username.</param>
         /// <param name="password">Authentication password.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="password"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="F:System.Net.IPEndPoint.MinPort"/> and <see cref="System.Net.IPEndPoint.MaxPort"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="password"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
         [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
         public NetConfClient(string host, int port, string username, string password)
             : this(new PasswordConnectionInfo(host, port, username, password), true)
@@ -60,8 +61,8 @@ namespace Renci.SshNet
         /// <param name="host">Connection host.</param>
         /// <param name="username">Authentication username.</param>
         /// <param name="password">Authentication password.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="password"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="password"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
         public NetConfClient(string host, string username, string password)
             : this(host, ConnectionInfo.DefaultPort, username, password)
         {
@@ -74,9 +75,9 @@ namespace Renci.SshNet
         /// <param name="port">Connection port.</param>
         /// <param name="username">Authentication username.</param>
         /// <param name="keyFiles">Authentication private key file(s) .</param>
-        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is null or contains whitespace characters.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="F:System.Net.IPEndPoint.MinPort"/> and <see cref="System.Net.IPEndPoint.MaxPort"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
         [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
         public NetConfClient(string host, int port, string username, params PrivateKeyFile[] keyFiles)
             : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true)
@@ -89,8 +90,8 @@ namespace Renci.SshNet
         /// <param name="host">Connection host.</param>
         /// <param name="username">Authentication username.</param>
         /// <param name="keyFiles">Authentication private key file(s) .</param>
-        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is null or contains whitespace characters.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
         public NetConfClient(string host, string username, params PrivateKeyFile[] keyFiles)
             : this(host, ConnectionInfo.DefaultPort, username, keyFiles)
         {
@@ -101,7 +102,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="connectionInfo">The connection info.</param>
         /// <param name="ownsConnectionInfo">Specified whether this instance owns the connection info.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <c>null</c>.</exception>
         /// <remarks>
         /// If <paramref name="ownsConnectionInfo"/> is <c>true</c>, then the
         /// connection info will be disposed when this instance is disposed.
@@ -117,8 +118,8 @@ namespace Renci.SshNet
         /// <param name="connectionInfo">The connection info.</param>
         /// <param name="ownsConnectionInfo">Specified whether this instance owns the connection info.</param>
         /// <param name="serviceFactory">The factory to use for creating new services.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is null.</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="serviceFactory"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="serviceFactory"/> is <c>null</c>.</exception>
         /// <remarks>
         /// If <paramref name="ownsConnectionInfo"/> is <c>true</c>, then the
         /// connection info will be disposed when this instance is disposed.

+ 2 - 2
src/Renci.SshNet/NoneAuthenticationMethod.cs

@@ -25,7 +25,7 @@ namespace Renci.SshNet
         /// Initializes a new instance of the <see cref="NoneAuthenticationMethod"/> class.
         /// </summary>
         /// <param name="username">The username.</param>
-        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or <c>null</c>.</exception>
         public NoneAuthenticationMethod(string username)
             : base(username)
         {
@@ -38,7 +38,7 @@ namespace Renci.SshNet
         /// <returns>
         /// Result of authentication  process.
         /// </returns>
-        /// <exception cref="System.ArgumentNullException"><paramref name="session" /> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="session" /> is <c>null</c>.</exception>
         public override AuthenticationResult Authenticate(Session session)
         {
             if (session == null)

+ 5 - 5
src/Renci.SshNet/PasswordAuthenticationMethod.cs

@@ -38,8 +38,8 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="username">The username.</param>
         /// <param name="password">The password.</param>
-        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="password"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="password"/> is <c>null</c>.</exception>
         public PasswordAuthenticationMethod(string username, string password)
             : this(username, Encoding.UTF8.GetBytes(password))
         {
@@ -50,8 +50,8 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="username">The username.</param>
         /// <param name="password">The password.</param>
-        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="password"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="password"/> is <c>null</c>.</exception>
         public PasswordAuthenticationMethod(string username, byte[] password)
             : base(username)
         {
@@ -69,7 +69,7 @@ namespace Renci.SshNet
         /// <returns>
         /// Result of authentication  process.
         /// </returns>
-        /// <exception cref="System.ArgumentNullException"><paramref name="session" /> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="session" /> is <c>null</c>.</exception>
         public override AuthenticationResult Authenticate(Session session)
         {
             if (session == null)

+ 9 - 8
src/Renci.SshNet/PasswordConnectionInfo.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Linq;
+using System.Net;
 using System.Text;
 using Renci.SshNet.Common;
 
@@ -32,8 +33,8 @@ namespace Renci.SshNet
         /// <example>
         ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\PasswordConnectionInfoTest.cs" region="Example PasswordConnectionInfo" language="C#" title="Connect using username and password" />
         /// </example>
-        /// <exception cref="ArgumentNullException"><paramref name="password"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="password"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
         public PasswordConnectionInfo(string host, string username, string password)
             : this(host, DefaultPort, username, Encoding.UTF8.GetBytes(password))
         {
@@ -46,9 +47,9 @@ namespace Renci.SshNet
         /// <param name="port">Connection port.</param>
         /// <param name="username">Connection username.</param>
         /// <param name="password">Connection password.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="password"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="F:System.Net.IPEndPoint.MinPort"/> and <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="password"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
         public PasswordConnectionInfo(string host, int port, string username, string password)
             : this(host, port, username, Encoding.UTF8.GetBytes(password), ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
         {
@@ -148,9 +149,9 @@ namespace Renci.SshNet
         /// <param name="port">Connection port.</param>
         /// <param name="username">Connection username.</param>
         /// <param name="password">Connection password.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="password" /> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host" /> is invalid, or <paramref name="username" /> is null or contains whitespace characters.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is not within <see cref="F:System.Net.IPEndPoint.MinPort" /> and <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="password" /> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host" /> is invalid, or <paramref name="username" /> is <c>null</c> or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is not within <see cref="IPEndPoint.MinPort" /> and <see cref="IPEndPoint.MaxPort" />.</exception>
         public PasswordConnectionInfo(string host, int port, string username, byte[] password)
             : this(host, port, username, password, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
         {

+ 1 - 1
src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs

@@ -35,7 +35,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="username">The username.</param>
         /// <param name="keyFiles">The key files.</param>
-        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or <c>null</c>.</exception>
         public PrivateKeyAuthenticationMethod(string username, params PrivateKeyFile[] keyFiles)
             : base(username)
         {

+ 4 - 5
src/Renci.SshNet/PrivateKeyFile.cs

@@ -77,7 +77,7 @@ namespace Renci.SshNet
         /// Initializes a new instance of the <see cref="PrivateKeyFile"/> class.
         /// </summary>
         /// <param name="fileName">Name of the file.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="fileName"/> is null or empty.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="fileName"/> is <c>null</c> or empty.</exception>
         /// <remarks>This method calls <see cref="System.IO.File.Open(string, System.IO.FileMode)"/> internally, this method does not catch exceptions from <see cref="System.IO.File.Open(string, System.IO.FileMode)"/>.</remarks>
         public PrivateKeyFile(string fileName)
             : this(fileName, null)
@@ -89,7 +89,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="fileName">Name of the file.</param>
         /// <param name="passPhrase">The pass phrase.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="fileName"/> is null or empty, or <paramref name="passPhrase"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="fileName"/> is <c>null</c> or empty, or <paramref name="passPhrase"/> is <c>null</c>.</exception>
         /// <remarks>This method calls <see cref="System.IO.File.Open(string, System.IO.FileMode)"/> internally, this method does not catch exceptions from <see cref="System.IO.File.Open(string, System.IO.FileMode)"/>.</remarks>
         public PrivateKeyFile(string fileName, string passPhrase)
         {
@@ -107,7 +107,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="privateKey">The private key.</param>
         /// <param name="passPhrase">The pass phrase.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="privateKey"/> or <paramref name="passPhrase"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="privateKey"/> or <paramref name="passPhrase"/> is <c>null</c>.</exception>
         public PrivateKeyFile(Stream privateKey, string passPhrase)
         {
             Open(privateKey, passPhrase);
@@ -304,8 +304,7 @@ namespace Renci.SshNet
         /// <param name="passPhrase">Decryption pass phrase.</param>
         /// <param name="binarySalt">Decryption binary salt.</param>
         /// <returns>Decrypted byte array.</returns>
-        /// <exception cref="System.ArgumentNullException">cipherInfo</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="cipherInfo" />, <paramref name="cipherData" />, <paramref name="passPhrase" /> or <paramref name="binarySalt" /> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="cipherInfo" />, <paramref name="cipherData" />, <paramref name="passPhrase" /> or <paramref name="binarySalt" /> is <c>null</c>.</exception>
         private static byte[] DecryptKey(CipherInfo cipherInfo, byte[] cipherData, string passPhrase, byte[] binarySalt)
         {
             if (cipherInfo == null)

+ 7 - 7
src/Renci.SshNet/ScpClient.NET.cs

@@ -19,8 +19,8 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="fileInfo">The file system info.</param>
         /// <param name="path">The path.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="fileInfo" /> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="path"/> is null or empty.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="fileInfo" /> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="path"/> is <c>null</c> or empty.</exception>
         public void Upload(FileInfo fileInfo, string path)
         {
             if (fileInfo == null)
@@ -51,7 +51,7 @@ namespace Renci.SshNet
         /// <param name="directoryInfo">The directory info.</param>
         /// <param name="path">The path.</param>
         /// <exception cref="ArgumentNullException">fileSystemInfo</exception>
-        /// <exception cref="ArgumentException"><paramref name="path"/> is null or empty.</exception>
+        /// <exception cref="ArgumentException"><paramref name="path"/> is <c>null</c> or empty.</exception>
         public void Upload(DirectoryInfo directoryInfo, string path)
         {
             if (directoryInfo == null)
@@ -87,8 +87,8 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="filename">Remote host file name.</param>
         /// <param name="fileInfo">Local file information.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="fileInfo"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="filename"/> is null or empty.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="fileInfo"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="filename"/> is <c>null</c> or empty.</exception>
         public void Download(string filename, FileInfo fileInfo)
         {
             if (string.IsNullOrEmpty(filename))
@@ -117,8 +117,8 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="directoryName">Remote host directory name.</param>
         /// <param name="directoryInfo">Local directory information.</param>
-        /// <exception cref="ArgumentException"><paramref name="directoryName"/> is null or empty.</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="directoryInfo"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="directoryName"/> is <c>null</c> or empty.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="directoryInfo"/> is <c>null</c>.</exception>
         public void Download(string directoryName, DirectoryInfo directoryInfo)
         {
             if (string.IsNullOrEmpty(directoryName))

+ 21 - 17
src/Renci.SshNet/ScpClient.cs

@@ -5,6 +5,7 @@ using System.IO;
 using Renci.SshNet.Common;
 using System.Text.RegularExpressions;
 using System.Diagnostics.CodeAnalysis;
+using System.Net;
 
 namespace Renci.SshNet
 {
@@ -49,7 +50,7 @@ namespace Renci.SshNet
         /// Initializes a new instance of the <see cref="SftpClient"/> class.
         /// </summary>
         /// <param name="connectionInfo">The connection info.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <c>null</c>.</exception>
         public ScpClient(ConnectionInfo connectionInfo)
             : this(connectionInfo, false)
         {
@@ -62,9 +63,9 @@ namespace Renci.SshNet
         /// <param name="port">Connection port.</param>
         /// <param name="username">Authentication username.</param>
         /// <param name="password">Authentication password.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="password"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="F:System.Net.IPEndPoint.MinPort"/> and <see cref="System.Net.IPEndPoint.MaxPort"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="password"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
         [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
         public ScpClient(string host, int port, string username, string password)
             : this(new PasswordConnectionInfo(host, port, username, password), true)
@@ -77,8 +78,8 @@ namespace Renci.SshNet
         /// <param name="host">Connection host.</param>
         /// <param name="username">Authentication username.</param>
         /// <param name="password">Authentication password.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="password"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="password"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
         public ScpClient(string host, string username, string password)
             : this(host, ConnectionInfo.DefaultPort, username, password)
         {
@@ -91,9 +92,9 @@ namespace Renci.SshNet
         /// <param name="port">Connection port.</param>
         /// <param name="username">Authentication username.</param>
         /// <param name="keyFiles">Authentication private key file(s) .</param>
-        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is null or contains whitespace characters.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="F:System.Net.IPEndPoint.MinPort"/> and <see cref="System.Net.IPEndPoint.MaxPort"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
         [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
         public ScpClient(string host, int port, string username, params PrivateKeyFile[] keyFiles)
             : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true)
@@ -106,8 +107,8 @@ namespace Renci.SshNet
         /// <param name="host">Connection host.</param>
         /// <param name="username">Authentication username.</param>
         /// <param name="keyFiles">Authentication private key file(s) .</param>
-        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is null or contains whitespace characters.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
         public ScpClient(string host, string username, params PrivateKeyFile[] keyFiles)
             : this(host, ConnectionInfo.DefaultPort, username, keyFiles)
         {
@@ -118,7 +119,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="connectionInfo">The connection info.</param>
         /// <param name="ownsConnectionInfo">Specified whether this instance owns the connection info.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <c>null</c>.</exception>
         /// <remarks>
         /// If <paramref name="ownsConnectionInfo"/> is <c>true</c>, then the
         /// connection info will be disposed when this instance is disposed.
@@ -134,8 +135,8 @@ namespace Renci.SshNet
         /// <param name="connectionInfo">The connection info.</param>
         /// <param name="ownsConnectionInfo">Specified whether this instance owns the connection info.</param>
         /// <param name="serviceFactory">The factory to use for creating new services.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is null.</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="serviceFactory"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="serviceFactory"/> is <c>null</c>.</exception>
         /// <remarks>
         /// If <paramref name="ownsConnectionInfo"/> is <c>true</c>, then the
         /// connection info will be disposed when this instance is disposed.
@@ -196,9 +197,12 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="filename">Remote host file name.</param>
         /// <param name="destination">The stream where to download remote file.</param>
-        /// <exception cref="ArgumentException"><paramref name="filename"/> is null or contains whitespace characters.</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="destination"/> is null.</exception>
-        /// <remarks>Method calls made by this method to <paramref name="destination"/>, may under certain conditions result in exceptions thrown by the stream.</remarks>
+        /// <exception cref="ArgumentException"><paramref name="filename"/> is <c>null</c> or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="destination"/> is <c>null</c>.</exception>
+        /// <remarks>
+        /// Method calls made by this method to <paramref name="destination"/>, may under certain conditions result
+        /// in exceptions thrown by the stream.
+        /// </remarks>
         public void Download(string filename, Stream destination)
         {
             if (filename.IsNullOrWhiteSpace())

+ 3 - 3
src/Renci.SshNet/Security/CertificateHostAlgorithm.cs

@@ -29,7 +29,7 @@ namespace Renci.SshNet.Security
         /// </summary>
         /// <param name="data">The data.</param>
         /// <returns>Signed data.</returns>
-        /// <exception cref="System.NotImplementedException"></exception>
+        /// <exception cref="NotImplementedException"></exception>
         public override byte[] Sign(byte[] data)
         {
             throw new NotImplementedException();
@@ -40,8 +40,8 @@ namespace Renci.SshNet.Security
         /// </summary>
         /// <param name="data">The data.</param>
         /// <param name="signature">The signature.</param>
-        /// <returns><c>True</c> if signature was successfully verified; otherwise <c>false</c>.</returns>
-        /// <exception cref="System.NotImplementedException"></exception>
+        /// <returns><c>true</c> if signature was successfully verified; otherwise <c>false</c>.</returns>
+        /// <exception cref="NotImplementedException"></exception>
         public override bool VerifySignature(byte[] data, byte[] signature)
         {
             throw new NotImplementedException();

+ 1 - 1
src/Renci.SshNet/Security/Cryptography/BlockCipher.cs

@@ -52,7 +52,7 @@ namespace Renci.SshNet.Security.Cryptography
         /// <param name="blockSize">Size of the block.</param>
         /// <param name="mode">Cipher mode.</param>
         /// <param name="padding">Cipher padding.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
         protected BlockCipher(byte[] key, byte blockSize, CipherMode mode, CipherPadding padding)
             : base(key)
         {

+ 3 - 3
src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.cs

@@ -561,7 +561,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
         /// <param name="key">The key.</param>
         /// <param name="mode">The mode.</param>
         /// <param name="padding">The padding.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">Keysize is not valid for this algorithm.</exception>
         public AesCipher(byte[] key, CipherMode mode, CipherPadding padding)
             : base(key, 16, mode, padding)
@@ -583,7 +583,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
         /// <returns>
         /// The number of bytes encrypted.
         /// </returns>
-        /// <exception cref="ArgumentNullException"><paramref name="inputBuffer"/> or <paramref name="outputBuffer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="inputBuffer"/> or <paramref name="outputBuffer"/> is <c>null</c>.</exception>
         /// <exception cref="IndexOutOfRangeException"><paramref name="inputBuffer"/> or <paramref name="outputBuffer"/> is too short.</exception>
         public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
         {
@@ -628,7 +628,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
         /// <returns>
         /// The number of bytes decrypted.
         /// </returns>
-        /// <exception cref="ArgumentNullException"><paramref name="inputBuffer"/> or <paramref name="outputBuffer"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="inputBuffer"/> or <paramref name="outputBuffer"/> is <c>null</c>.</exception>
         /// <exception cref="IndexOutOfRangeException"><paramref name="inputBuffer"/> or <paramref name="outputBuffer"/> is too short.</exception>
         public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
         {

+ 1 - 1
src/Renci.SshNet/Security/Cryptography/Ciphers/Arc4Cipher.cs

@@ -36,7 +36,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
         /// </summary>
         /// <param name="key">The key.</param>
         /// <param name="dischargeFirstBytes">if set to <c>true</c> will disharged first 1536 bytes.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="key" /> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="key" /> is <c>null</c>.</exception>
         public Arc4Cipher(byte[] key, bool dischargeFirstBytes)
             : base(key)
         {

+ 1 - 1
src/Renci.SshNet/Security/Cryptography/Ciphers/BlowfishCipher.cs

@@ -314,7 +314,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
         /// <param name="key">The key.</param>
         /// <param name="mode">The mode.</param>
         /// <param name="padding">The padding.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">Keysize is not valid for this algorithm.</exception>
         public BlowfishCipher(byte[] key, CipherMode mode, CipherPadding padding)
             : base(key, 8, mode, padding)

+ 1 - 1
src/Renci.SshNet/Security/Cryptography/Ciphers/CastCipher.cs

@@ -29,7 +29,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
         /// <param name="key">The key.</param>
         /// <param name="mode">The mode.</param>
         /// <param name="padding">The padding.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">Keysize is not valid for this algorithm.</exception>
         public CastCipher(byte[] key, CipherMode mode, CipherPadding padding)
             : base(key, 8, mode, padding)

+ 464 - 467
src/Renci.SshNet/Security/Cryptography/Ciphers/DesCipher.cs

@@ -2,288 +2,285 @@
 
 namespace Renci.SshNet.Security.Cryptography.Ciphers
 {
-	/// <summary>
-	/// Implements DES cipher algorithm.
-	/// </summary>
-	public class DesCipher : BlockCipher
-	{
-		private int[] _encryptionKey;
-
-		private int[] _decryptionKey;
-
-		#region Static tables
-
-		private static readonly short[] bytebit =
-		{
-			128, 64, 32, 16, 8, 4, 2, 1
-		};
-
-		private static readonly int[] bigbyte =
-		{
-			0x800000,	0x400000,	0x200000,	0x100000,
-			0x80000,	0x40000,	0x20000,	0x10000,
-			0x8000,		0x4000,		0x2000,		0x1000,
-			0x800,		0x400,		0x200,		0x100,
-			0x80,		0x40,		0x20,		0x10,
-			0x8,		0x4,		0x2,		0x1
-		};
-
-		/*
-		* Use the key schedule specified in the Standard (ANSI X3.92-1981).
-		*/
-		private static readonly byte[] pc1 =
-		{
-			56, 48, 40, 32, 24, 16,  8,   0, 57, 49, 41, 33, 25, 17,
-			9,  1, 58, 50, 42, 34, 26,  18, 10,  2, 59, 51, 43, 35,
-			62, 54, 46, 38, 30, 22, 14,   6, 61, 53, 45, 37, 29, 21,
-			13,  5, 60, 52, 44, 36, 28,  20, 12,  4, 27, 19, 11,  3
-		};
-
-		private static readonly byte[] totrot =
-		{
-			1, 2, 4, 6, 8, 10, 12, 14,
-			15, 17, 19, 21, 23, 25, 27, 28
-		};
-
-		private static readonly byte[] pc2 =
-		{
-			13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
-			22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
-			40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
-			43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
-		};
-
-		private static readonly uint[] SP1 =
-		{
-			0x01010400, 0x00000000, 0x00010000, 0x01010404,
-			0x01010004, 0x00010404, 0x00000004, 0x00010000,
-			0x00000400, 0x01010400, 0x01010404, 0x00000400,
-			0x01000404, 0x01010004, 0x01000000, 0x00000004,
-			0x00000404, 0x01000400, 0x01000400, 0x00010400,
-			0x00010400, 0x01010000, 0x01010000, 0x01000404,
-			0x00010004, 0x01000004, 0x01000004, 0x00010004,
-			0x00000000, 0x00000404, 0x00010404, 0x01000000,
-			0x00010000, 0x01010404, 0x00000004, 0x01010000,
-			0x01010400, 0x01000000, 0x01000000, 0x00000400,
-			0x01010004, 0x00010000, 0x00010400, 0x01000004,
-			0x00000400, 0x00000004, 0x01000404, 0x00010404,
-			0x01010404, 0x00010004, 0x01010000, 0x01000404,
-			0x01000004, 0x00000404, 0x00010404, 0x01010400,
-			0x00000404, 0x01000400, 0x01000400, 0x00000000,
-			0x00010004, 0x00010400, 0x00000000, 0x01010004
-		};
-
-		private static readonly uint[] SP2 =
-		{
-			0x80108020, 0x80008000, 0x00008000, 0x00108020,
-			0x00100000, 0x00000020, 0x80100020, 0x80008020,
-			0x80000020, 0x80108020, 0x80108000, 0x80000000,
-			0x80008000, 0x00100000, 0x00000020, 0x80100020,
-			0x00108000, 0x00100020, 0x80008020, 0x00000000,
-			0x80000000, 0x00008000, 0x00108020, 0x80100000,
-			0x00100020, 0x80000020, 0x00000000, 0x00108000,
-			0x00008020, 0x80108000, 0x80100000, 0x00008020,
-			0x00000000, 0x00108020, 0x80100020, 0x00100000,
-			0x80008020, 0x80100000, 0x80108000, 0x00008000,
-			0x80100000, 0x80008000, 0x00000020, 0x80108020,
-			0x00108020, 0x00000020, 0x00008000, 0x80000000,
-			0x00008020, 0x80108000, 0x00100000, 0x80000020,
-			0x00100020, 0x80008020, 0x80000020, 0x00100020,
-			0x00108000, 0x00000000, 0x80008000, 0x00008020,
-			0x80000000, 0x80100020, 0x80108020, 0x00108000
-		};
-
-		private static readonly uint[] SP3 =
-		{
-			0x00000208, 0x08020200, 0x00000000, 0x08020008,
-			0x08000200, 0x00000000, 0x00020208, 0x08000200,
-			0x00020008, 0x08000008, 0x08000008, 0x00020000,
-			0x08020208, 0x00020008, 0x08020000, 0x00000208,
-			0x08000000, 0x00000008, 0x08020200, 0x00000200,
-			0x00020200, 0x08020000, 0x08020008, 0x00020208,
-			0x08000208, 0x00020200, 0x00020000, 0x08000208,
-			0x00000008, 0x08020208, 0x00000200, 0x08000000,
-			0x08020200, 0x08000000, 0x00020008, 0x00000208,
-			0x00020000, 0x08020200, 0x08000200, 0x00000000,
-			0x00000200, 0x00020008, 0x08020208, 0x08000200,
-			0x08000008, 0x00000200, 0x00000000, 0x08020008,
-			0x08000208, 0x00020000, 0x08000000, 0x08020208,
-			0x00000008, 0x00020208, 0x00020200, 0x08000008,
-			0x08020000, 0x08000208, 0x00000208, 0x08020000,
-			0x00020208, 0x00000008, 0x08020008, 0x00020200
-		};
-
-		private static readonly uint[] SP4 =
-		{
-			0x00802001, 0x00002081, 0x00002081, 0x00000080,
-			0x00802080, 0x00800081, 0x00800001, 0x00002001,
-			0x00000000, 0x00802000, 0x00802000, 0x00802081,
-			0x00000081, 0x00000000, 0x00800080, 0x00800001,
-			0x00000001, 0x00002000, 0x00800000, 0x00802001,
-			0x00000080, 0x00800000, 0x00002001, 0x00002080,
-			0x00800081, 0x00000001, 0x00002080, 0x00800080,
-			0x00002000, 0x00802080, 0x00802081, 0x00000081,
-			0x00800080, 0x00800001, 0x00802000, 0x00802081,
-			0x00000081, 0x00000000, 0x00000000, 0x00802000,
-			0x00002080, 0x00800080, 0x00800081, 0x00000001,
-			0x00802001, 0x00002081, 0x00002081, 0x00000080,
-			0x00802081, 0x00000081, 0x00000001, 0x00002000,
-			0x00800001, 0x00002001, 0x00802080, 0x00800081,
-			0x00002001, 0x00002080, 0x00800000, 0x00802001,
-			0x00000080, 0x00800000, 0x00002000, 0x00802080
-		};
-
-		private static readonly uint[] SP5 =
-		{
-			0x00000100, 0x02080100, 0x02080000, 0x42000100,
-			0x00080000, 0x00000100, 0x40000000, 0x02080000,
-			0x40080100, 0x00080000, 0x02000100, 0x40080100,
-			0x42000100, 0x42080000, 0x00080100, 0x40000000,
-			0x02000000, 0x40080000, 0x40080000, 0x00000000,
-			0x40000100, 0x42080100, 0x42080100, 0x02000100,
-			0x42080000, 0x40000100, 0x00000000, 0x42000000,
-			0x02080100, 0x02000000, 0x42000000, 0x00080100,
-			0x00080000, 0x42000100, 0x00000100, 0x02000000,
-			0x40000000, 0x02080000, 0x42000100, 0x40080100,
-			0x02000100, 0x40000000, 0x42080000, 0x02080100,
-			0x40080100, 0x00000100, 0x02000000, 0x42080000,
-			0x42080100, 0x00080100, 0x42000000, 0x42080100,
-			0x02080000, 0x00000000, 0x40080000, 0x42000000,
-			0x00080100, 0x02000100, 0x40000100, 0x00080000,
-			0x00000000, 0x40080000, 0x02080100, 0x40000100
-		};
-
-		private static readonly uint[] SP6 =
-		{
-			0x20000010, 0x20400000, 0x00004000, 0x20404010,
-			0x20400000, 0x00000010, 0x20404010, 0x00400000,
-			0x20004000, 0x00404010, 0x00400000, 0x20000010,
-			0x00400010, 0x20004000, 0x20000000, 0x00004010,
-			0x00000000, 0x00400010, 0x20004010, 0x00004000,
-			0x00404000, 0x20004010, 0x00000010, 0x20400010,
-			0x20400010, 0x00000000, 0x00404010, 0x20404000,
-			0x00004010, 0x00404000, 0x20404000, 0x20000000,
-			0x20004000, 0x00000010, 0x20400010, 0x00404000,
-			0x20404010, 0x00400000, 0x00004010, 0x20000010,
-			0x00400000, 0x20004000, 0x20000000, 0x00004010,
-			0x20000010, 0x20404010, 0x00404000, 0x20400000,
-			0x00404010, 0x20404000, 0x00000000, 0x20400010,
-			0x00000010, 0x00004000, 0x20400000, 0x00404010,
-			0x00004000, 0x00400010, 0x20004010, 0x00000000,
-			0x20404000, 0x20000000, 0x00400010, 0x20004010
-		};
-
-		private static readonly uint[] SP7 =
-		{
-			0x00200000, 0x04200002, 0x04000802, 0x00000000,
-			0x00000800, 0x04000802, 0x00200802, 0x04200800,
-			0x04200802, 0x00200000, 0x00000000, 0x04000002,
-			0x00000002, 0x04000000, 0x04200002, 0x00000802,
-			0x04000800, 0x00200802, 0x00200002, 0x04000800,
-			0x04000002, 0x04200000, 0x04200800, 0x00200002,
-			0x04200000, 0x00000800, 0x00000802, 0x04200802,
-			0x00200800, 0x00000002, 0x04000000, 0x00200800,
-			0x04000000, 0x00200800, 0x00200000, 0x04000802,
-			0x04000802, 0x04200002, 0x04200002, 0x00000002,
-			0x00200002, 0x04000000, 0x04000800, 0x00200000,
-			0x04200800, 0x00000802, 0x00200802, 0x04200800,
-			0x00000802, 0x04000002, 0x04200802, 0x04200000,
-			0x00200800, 0x00000000, 0x00000002, 0x04200802,
-			0x00000000, 0x00200802, 0x04200000, 0x00000800,
-			0x04000002, 0x04000800, 0x00000800, 0x00200002
-		};
-
-		private static readonly uint[] SP8 =
-		{
-			0x10001040, 0x00001000, 0x00040000, 0x10041040,
-			0x10000000, 0x10001040, 0x00000040, 0x10000000,
-			0x00040040, 0x10040000, 0x10041040, 0x00041000,
-			0x10041000, 0x00041040, 0x00001000, 0x00000040,
-			0x10040000, 0x10000040, 0x10001000, 0x00001040,
-			0x00041000, 0x00040040, 0x10040040, 0x10041000,
-			0x00001040, 0x00000000, 0x00000000, 0x10040040,
-			0x10000040, 0x10001000, 0x00041040, 0x00040000,
-			0x00041040, 0x00040000, 0x10041000, 0x00001000,
-			0x00000040, 0x10040040, 0x00001000, 0x00041040,
-			0x10001000, 0x00000040, 0x10000040, 0x10040000,
-			0x10040040, 0x10000000, 0x00040000, 0x10001040,
-			0x00000000, 0x10041040, 0x00040040, 0x10000040,
-			0x10040000, 0x10001000, 0x10001040, 0x00000000,
-			0x10041040, 0x00041000, 0x00041000, 0x00001040,
-			0x00001040, 0x00040040, 0x10000000, 0x10041000
-		};
-
-		#endregion
-
-		/// <summary>
-		/// Initializes a new instance of the <see cref="DesCipher"/> class.
-		/// </summary>
-		/// <param name="key">The key.</param>
-		/// <param name="mode">The mode.</param>
-		/// <param name="padding">The padding.</param>
-		/// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
-		public DesCipher(byte[] key, CipherMode mode, CipherPadding padding)
-			: base(key, 8, mode, padding)
-		{
-		}
-
-		/// <summary>
-		/// Encrypts the specified region of the input byte array and copies the encrypted data to the specified region of the output byte array.
-		/// </summary>
-		/// <param name="inputBuffer">The input data to encrypt.</param>
-		/// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
-		/// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
-		/// <param name="outputBuffer">The output to which to write encrypted data.</param>
-		/// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
-		/// <returns>
-		/// The number of bytes encrypted.
-		/// </returns>
-		public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
-		{
-			if ((inputOffset + BlockSize) > inputBuffer.Length)
-				throw new IndexOutOfRangeException("input buffer too short");
-
-			if ((outputOffset + BlockSize) > outputBuffer.Length)
-				throw new IndexOutOfRangeException("output buffer too short");
-
-			if (_encryptionKey == null)
-			{
-				_encryptionKey = GenerateWorkingKey(true, Key);
-			}
-
-			DesFunc(_encryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
-
-			return BlockSize;
-		}
-
-		/// <summary>
-		/// Decrypts the specified region of the input byte array and copies the decrypted data to the specified region of the output byte array.
-		/// </summary>
-		/// <param name="inputBuffer">The input data to decrypt.</param>
-		/// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
-		/// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
-		/// <param name="outputBuffer">The output to which to write decrypted data.</param>
-		/// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
-		/// <returns>
-		/// The number of bytes decrypted.
-		/// </returns>
-		public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
-		{
-			if ((inputOffset + BlockSize) > inputBuffer.Length)
-				throw new IndexOutOfRangeException("input buffer too short");
-
-			if ((outputOffset + BlockSize) > outputBuffer.Length)
-				throw new IndexOutOfRangeException("output buffer too short");
-
-			if (_decryptionKey == null)
-			{
-				_decryptionKey = GenerateWorkingKey(false, Key);
-			}
-
-			DesFunc(_decryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
-
-			return BlockSize;
-		}
+    /// <summary>
+    /// Implements DES cipher algorithm.
+    /// </summary>
+    public class DesCipher : BlockCipher
+    {
+        private int[] _encryptionKey;
+
+        private int[] _decryptionKey;
+
+        #region Static tables
+
+        private static readonly short[] bytebit = {128, 64, 32, 16, 8, 4, 2, 1};
+
+        private static readonly int[] bigbyte =
+        {
+            0x800000,   0x400000,   0x200000,   0x100000,
+            0x80000,    0x40000,    0x20000,    0x10000,
+            0x8000,     0x4000,     0x2000,     0x1000,
+            0x800,      0x400,      0x200,      0x100,
+            0x80,       0x40,       0x20,       0x10,
+            0x8,        0x4,        0x2,        0x1
+        };
+
+        /*
+         * Use the key schedule specified in the Standard (ANSI X3.92-1981).
+         */
+        private static readonly byte[] pc1 =
+        {
+            56, 48, 40, 32, 24, 16,  8,   0, 57, 49, 41, 33, 25, 17,
+            9,  1, 58, 50, 42, 34, 26,  18, 10,  2, 59, 51, 43, 35,
+            62, 54, 46, 38, 30, 22, 14,   6, 61, 53, 45, 37, 29, 21,
+            13,  5, 60, 52, 44, 36, 28,  20, 12,  4, 27, 19, 11,  3
+        };
+
+        private static readonly byte[] totrot =
+        {
+            1, 2, 4, 6, 8, 10, 12, 14,
+            15, 17, 19, 21, 23, 25, 27, 28
+        };
+
+        private static readonly byte[] pc2 =
+        {
+            13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
+            22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
+            40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
+            43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
+        };
+
+        private static readonly uint[] SP1 =
+        {
+            0x01010400, 0x00000000, 0x00010000, 0x01010404,
+            0x01010004, 0x00010404, 0x00000004, 0x00010000,
+            0x00000400, 0x01010400, 0x01010404, 0x00000400,
+            0x01000404, 0x01010004, 0x01000000, 0x00000004,
+            0x00000404, 0x01000400, 0x01000400, 0x00010400,
+            0x00010400, 0x01010000, 0x01010000, 0x01000404,
+            0x00010004, 0x01000004, 0x01000004, 0x00010004,
+            0x00000000, 0x00000404, 0x00010404, 0x01000000,
+            0x00010000, 0x01010404, 0x00000004, 0x01010000,
+            0x01010400, 0x01000000, 0x01000000, 0x00000400,
+            0x01010004, 0x00010000, 0x00010400, 0x01000004,
+            0x00000400, 0x00000004, 0x01000404, 0x00010404,
+            0x01010404, 0x00010004, 0x01010000, 0x01000404,
+            0x01000004, 0x00000404, 0x00010404, 0x01010400,
+            0x00000404, 0x01000400, 0x01000400, 0x00000000,
+            0x00010004, 0x00010400, 0x00000000, 0x01010004
+        };
+
+        private static readonly uint[] SP2 =
+        {
+            0x80108020, 0x80008000, 0x00008000, 0x00108020,
+            0x00100000, 0x00000020, 0x80100020, 0x80008020,
+            0x80000020, 0x80108020, 0x80108000, 0x80000000,
+            0x80008000, 0x00100000, 0x00000020, 0x80100020,
+            0x00108000, 0x00100020, 0x80008020, 0x00000000,
+            0x80000000, 0x00008000, 0x00108020, 0x80100000,
+            0x00100020, 0x80000020, 0x00000000, 0x00108000,
+            0x00008020, 0x80108000, 0x80100000, 0x00008020,
+            0x00000000, 0x00108020, 0x80100020, 0x00100000,
+            0x80008020, 0x80100000, 0x80108000, 0x00008000,
+            0x80100000, 0x80008000, 0x00000020, 0x80108020,
+            0x00108020, 0x00000020, 0x00008000, 0x80000000,
+            0x00008020, 0x80108000, 0x00100000, 0x80000020,
+            0x00100020, 0x80008020, 0x80000020, 0x00100020,
+            0x00108000, 0x00000000, 0x80008000, 0x00008020,
+            0x80000000, 0x80100020, 0x80108020, 0x00108000
+        };
+
+        private static readonly uint[] SP3 =
+        {
+            0x00000208, 0x08020200, 0x00000000, 0x08020008,
+            0x08000200, 0x00000000, 0x00020208, 0x08000200,
+            0x00020008, 0x08000008, 0x08000008, 0x00020000,
+            0x08020208, 0x00020008, 0x08020000, 0x00000208,
+            0x08000000, 0x00000008, 0x08020200, 0x00000200,
+            0x00020200, 0x08020000, 0x08020008, 0x00020208,
+            0x08000208, 0x00020200, 0x00020000, 0x08000208,
+            0x00000008, 0x08020208, 0x00000200, 0x08000000,
+            0x08020200, 0x08000000, 0x00020008, 0x00000208,
+            0x00020000, 0x08020200, 0x08000200, 0x00000000,
+            0x00000200, 0x00020008, 0x08020208, 0x08000200,
+            0x08000008, 0x00000200, 0x00000000, 0x08020008,
+            0x08000208, 0x00020000, 0x08000000, 0x08020208,
+            0x00000008, 0x00020208, 0x00020200, 0x08000008,
+            0x08020000, 0x08000208, 0x00000208, 0x08020000,
+            0x00020208, 0x00000008, 0x08020008, 0x00020200
+        };
+
+        private static readonly uint[] SP4 =
+        {
+            0x00802001, 0x00002081, 0x00002081, 0x00000080,
+            0x00802080, 0x00800081, 0x00800001, 0x00002001,
+            0x00000000, 0x00802000, 0x00802000, 0x00802081,
+            0x00000081, 0x00000000, 0x00800080, 0x00800001,
+            0x00000001, 0x00002000, 0x00800000, 0x00802001,
+            0x00000080, 0x00800000, 0x00002001, 0x00002080,
+            0x00800081, 0x00000001, 0x00002080, 0x00800080,
+            0x00002000, 0x00802080, 0x00802081, 0x00000081,
+            0x00800080, 0x00800001, 0x00802000, 0x00802081,
+            0x00000081, 0x00000000, 0x00000000, 0x00802000,
+            0x00002080, 0x00800080, 0x00800081, 0x00000001,
+            0x00802001, 0x00002081, 0x00002081, 0x00000080,
+            0x00802081, 0x00000081, 0x00000001, 0x00002000,
+            0x00800001, 0x00002001, 0x00802080, 0x00800081,
+            0x00002001, 0x00002080, 0x00800000, 0x00802001,
+            0x00000080, 0x00800000, 0x00002000, 0x00802080
+        };
+
+        private static readonly uint[] SP5 =
+        {
+            0x00000100, 0x02080100, 0x02080000, 0x42000100,
+            0x00080000, 0x00000100, 0x40000000, 0x02080000,
+            0x40080100, 0x00080000, 0x02000100, 0x40080100,
+            0x42000100, 0x42080000, 0x00080100, 0x40000000,
+            0x02000000, 0x40080000, 0x40080000, 0x00000000,
+            0x40000100, 0x42080100, 0x42080100, 0x02000100,
+            0x42080000, 0x40000100, 0x00000000, 0x42000000,
+            0x02080100, 0x02000000, 0x42000000, 0x00080100,
+            0x00080000, 0x42000100, 0x00000100, 0x02000000,
+            0x40000000, 0x02080000, 0x42000100, 0x40080100,
+            0x02000100, 0x40000000, 0x42080000, 0x02080100,
+            0x40080100, 0x00000100, 0x02000000, 0x42080000,
+            0x42080100, 0x00080100, 0x42000000, 0x42080100,
+            0x02080000, 0x00000000, 0x40080000, 0x42000000,
+            0x00080100, 0x02000100, 0x40000100, 0x00080000,
+            0x00000000, 0x40080000, 0x02080100, 0x40000100
+        };
+
+        private static readonly uint[] SP6 =
+        {
+            0x20000010, 0x20400000, 0x00004000, 0x20404010,
+            0x20400000, 0x00000010, 0x20404010, 0x00400000,
+            0x20004000, 0x00404010, 0x00400000, 0x20000010,
+            0x00400010, 0x20004000, 0x20000000, 0x00004010,
+            0x00000000, 0x00400010, 0x20004010, 0x00004000,
+            0x00404000, 0x20004010, 0x00000010, 0x20400010,
+            0x20400010, 0x00000000, 0x00404010, 0x20404000,
+            0x00004010, 0x00404000, 0x20404000, 0x20000000,
+            0x20004000, 0x00000010, 0x20400010, 0x00404000,
+            0x20404010, 0x00400000, 0x00004010, 0x20000010,
+            0x00400000, 0x20004000, 0x20000000, 0x00004010,
+            0x20000010, 0x20404010, 0x00404000, 0x20400000,
+            0x00404010, 0x20404000, 0x00000000, 0x20400010,
+            0x00000010, 0x00004000, 0x20400000, 0x00404010,
+            0x00004000, 0x00400010, 0x20004010, 0x00000000,
+            0x20404000, 0x20000000, 0x00400010, 0x20004010
+        };
+
+        private static readonly uint[] SP7 =
+        {
+            0x00200000, 0x04200002, 0x04000802, 0x00000000,
+            0x00000800, 0x04000802, 0x00200802, 0x04200800,
+            0x04200802, 0x00200000, 0x00000000, 0x04000002,
+            0x00000002, 0x04000000, 0x04200002, 0x00000802,
+            0x04000800, 0x00200802, 0x00200002, 0x04000800,
+            0x04000002, 0x04200000, 0x04200800, 0x00200002,
+            0x04200000, 0x00000800, 0x00000802, 0x04200802,
+            0x00200800, 0x00000002, 0x04000000, 0x00200800,
+            0x04000000, 0x00200800, 0x00200000, 0x04000802,
+            0x04000802, 0x04200002, 0x04200002, 0x00000002,
+            0x00200002, 0x04000000, 0x04000800, 0x00200000,
+            0x04200800, 0x00000802, 0x00200802, 0x04200800,
+            0x00000802, 0x04000002, 0x04200802, 0x04200000,
+            0x00200800, 0x00000000, 0x00000002, 0x04200802,
+            0x00000000, 0x00200802, 0x04200000, 0x00000800,
+            0x04000002, 0x04000800, 0x00000800, 0x00200002
+        };
+
+        private static readonly uint[] SP8 =
+        {
+            0x10001040, 0x00001000, 0x00040000, 0x10041040,
+            0x10000000, 0x10001040, 0x00000040, 0x10000000,
+            0x00040040, 0x10040000, 0x10041040, 0x00041000,
+            0x10041000, 0x00041040, 0x00001000, 0x00000040,
+            0x10040000, 0x10000040, 0x10001000, 0x00001040,
+            0x00041000, 0x00040040, 0x10040040, 0x10041000,
+            0x00001040, 0x00000000, 0x00000000, 0x10040040,
+            0x10000040, 0x10001000, 0x00041040, 0x00040000,
+            0x00041040, 0x00040000, 0x10041000, 0x00001000,
+            0x00000040, 0x10040040, 0x00001000, 0x00041040,
+            0x10001000, 0x00000040, 0x10000040, 0x10040000,
+            0x10040040, 0x10000000, 0x00040000, 0x10001040,
+            0x00000000, 0x10041040, 0x00040040, 0x10000040,
+            0x10040000, 0x10001000, 0x10001040, 0x00000000,
+            0x10041040, 0x00041000, 0x00041000, 0x00001040,
+            0x00001040, 0x00040040, 0x10000000, 0x10041000
+        };
+
+        #endregion
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DesCipher"/> class.
+        /// </summary>
+        /// <param name="key">The key.</param>
+        /// <param name="mode">The mode.</param>
+        /// <param name="padding">The padding.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
+        public DesCipher(byte[] key, CipherMode mode, CipherPadding padding)
+            : base(key, 8, mode, padding)
+        {
+        }
+
+        /// <summary>
+        /// Encrypts the specified region of the input byte array and copies the encrypted data to the specified region of the output byte array.
+        /// </summary>
+        /// <param name="inputBuffer">The input data to encrypt.</param>
+        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
+        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
+        /// <param name="outputBuffer">The output to which to write encrypted data.</param>
+        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
+        /// <returns>
+        /// The number of bytes encrypted.
+        /// </returns>
+        public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+        {
+            if ((inputOffset + BlockSize) > inputBuffer.Length)
+                throw new IndexOutOfRangeException("input buffer too short");
+
+            if ((outputOffset + BlockSize) > outputBuffer.Length)
+                throw new IndexOutOfRangeException("output buffer too short");
+
+            if (_encryptionKey == null)
+            {
+                _encryptionKey = GenerateWorkingKey(true, Key);
+            }
+
+            DesFunc(_encryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
+
+            return BlockSize;
+        }
+
+        /// <summary>
+        /// Decrypts the specified region of the input byte array and copies the decrypted data to the specified region of the output byte array.
+        /// </summary>
+        /// <param name="inputBuffer">The input data to decrypt.</param>
+        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
+        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
+        /// <param name="outputBuffer">The output to which to write decrypted data.</param>
+        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
+        /// <returns>
+        /// The number of bytes decrypted.
+        /// </returns>
+        public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+        {
+            if ((inputOffset + BlockSize) > inputBuffer.Length)
+                throw new IndexOutOfRangeException("input buffer too short");
+
+            if ((outputOffset + BlockSize) > outputBuffer.Length)
+                throw new IndexOutOfRangeException("output buffer too short");
+
+            if (_decryptionKey == null)
+            {
+                _decryptionKey = GenerateWorkingKey(false, Key);
+            }
+
+            DesFunc(_decryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
+
+            return BlockSize;
+        }
 
         /// <summary>
         /// Generates the working key.
@@ -291,189 +288,189 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
         /// <param name="encrypting">if set to <c>true</c> [encrypting].</param>
         /// <param name="key">The key.</param>
         /// <returns>Generated working key.</returns>
-		protected int[] GenerateWorkingKey(bool encrypting, byte[] key)
-		{
-			ValidateKey();
-
-			int[] newKey = new int[32];
-			bool[] pc1m = new bool[56];
-			bool[] pcr = new bool[56];
-
-			for (int j = 0; j < 56; j++)
-			{
-				int l = pc1[j];
-
-				pc1m[j] = ((key[(uint)l >> 3] & bytebit[l & 07]) != 0);
-			}
-
-			for (int i = 0; i < 16; i++)
-			{
-				int l, m;
-
-				if (encrypting)
-				{
-					m = i << 1;
-				}
-				else
-				{
-					m = (15 - i) << 1;
-				}
-
-				var n = m + 1;
-				newKey[m] = newKey[n] = 0;
-
-				for (int j = 0; j < 28; j++)
-				{
-					l = j + totrot[i];
-					if (l < 28)
-					{
-						pcr[j] = pc1m[l];
-					}
-					else
-					{
-						pcr[j] = pc1m[l - 28];
-					}
-				}
-
-				for (int j = 28; j < 56; j++)
-				{
-					l = j + totrot[i];
-					if (l < 56)
-					{
-						pcr[j] = pc1m[l];
-					}
-					else
-					{
-						pcr[j] = pc1m[l - 28];
-					}
-				}
-
-				for (int j = 0; j < 24; j++)
-				{
-					if (pcr[pc2[j]])
-					{
-						newKey[m] |= bigbyte[j];
-					}
-
-					if (pcr[pc2[j + 24]])
-					{
-						newKey[n] |= bigbyte[j];
-					}
-				}
-			}
-
-			//
-			// store the processed key
-			//
-			for (int i = 0; i != 32; i += 2)
-			{
-			    var i1 = newKey[i];
-				var i2 = newKey[i + 1];
-
-				newKey[i] = (int)  ((uint)((i1 & 0x00fc0000) << 6) |
-									(uint)((i1 & 0x00000fc0) << 10) |
-									((uint)(i2 & 0x00fc0000) >> 10) |
-									((uint)(i2 & 0x00000fc0) >> 6));
-
-				newKey[i + 1] = (int)((uint)((i1 & 0x0003f000) << 12) |
-									  (uint)((i1 & 0x0000003f) << 16) |
-									  ((uint)(i2 & 0x0003f000) >> 4) |
-									   (uint)(i2 & 0x0000003f));
-			}
-
-			return newKey;
-		}
-
-		/// <summary>
-		/// Validates the key.
-		/// </summary>
-		protected virtual void ValidateKey()
-		{
-			var keySize = Key.Length * 8;
-			
-			if (keySize != 64)
-				throw new ArgumentException(string.Format("KeySize '{0}' is not valid for this algorithm.", keySize));
-		}
-
-		/// <summary>
-		/// Performs DES function.
-		/// </summary>
-		/// <param name="wKey">The w key.</param>
-		/// <param name="input">The input.</param>
-		/// <param name="inOff">The in off.</param>
-		/// <param name="outBytes">The out bytes.</param>
-		/// <param name="outOff">The out off.</param>
-		protected static void DesFunc(int[] wKey, byte[] input, int inOff, byte[] outBytes, int outOff)
-		{
-			uint left = BigEndianToUInt32(input, inOff);
-			uint right = BigEndianToUInt32(input, inOff + 4);
-
-		    var work = ((left >> 4) ^ right) & 0x0f0f0f0f;
-			right ^= work;
-			left ^= (work << 4);
-			work = ((left >> 16) ^ right) & 0x0000ffff;
-			right ^= work;
-			left ^= (work << 16);
-			work = ((right >> 2) ^ left) & 0x33333333;
-			left ^= work;
-			right ^= (work << 2);
-			work = ((right >> 8) ^ left) & 0x00ff00ff;
-			left ^= work;
-			right ^= (work << 8);
-			right = (right << 1) | (right >> 31);
-			work = (left ^ right) & 0xaaaaaaaa;
-			left ^= work;
-			right ^= work;
-			left = (left << 1) | (left >> 31);
-
-			for (int round = 0; round < 8; round++)
-			{
-			    work = (right << 28) | (right >> 4);
-				work ^= (uint)wKey[round * 4 + 0];
-				var fval = SP7[work & 0x3f];
-				fval |= SP5[(work >> 8) & 0x3f];
-				fval |= SP3[(work >> 16) & 0x3f];
-				fval |= SP1[(work >> 24) & 0x3f];
-				work = right ^ (uint)wKey[round * 4 + 1];
-				fval |= SP8[work & 0x3f];
-				fval |= SP6[(work >> 8) & 0x3f];
-				fval |= SP4[(work >> 16) & 0x3f];
-				fval |= SP2[(work >> 24) & 0x3f];
-				left ^= fval;
-				work = (left << 28) | (left >> 4);
-				work ^= (uint)wKey[round * 4 + 2];
-				fval = SP7[work & 0x3f];
-				fval |= SP5[(work >> 8) & 0x3f];
-				fval |= SP3[(work >> 16) & 0x3f];
-				fval |= SP1[(work >> 24) & 0x3f];
-				work = left ^ (uint)wKey[round * 4 + 3];
-				fval |= SP8[work & 0x3f];
-				fval |= SP6[(work >> 8) & 0x3f];
-				fval |= SP4[(work >> 16) & 0x3f];
-				fval |= SP2[(work >> 24) & 0x3f];
-				right ^= fval;
-			}
-
-			right = (right << 31) | (right >> 1);
-			work = (left ^ right) & 0xaaaaaaaa;
-			left ^= work;
-			right ^= work;
-			left = (left << 31) | (left >> 1);
-			work = ((left >> 8) ^ right) & 0x00ff00ff;
-			right ^= work;
-			left ^= (work << 8);
-			work = ((left >> 2) ^ right) & 0x33333333;
-			right ^= work;
-			left ^= (work << 2);
-			work = ((right >> 16) ^ left) & 0x0000ffff;
-			left ^= work;
-			right ^= (work << 16);
-			work = ((right >> 4) ^ left) & 0x0f0f0f0f;
-			left ^= work;
-			right ^= (work << 4);
-
-			UInt32ToBigEndian(right, outBytes, outOff);
-			UInt32ToBigEndian(left, outBytes, outOff + 4);
-		}
-	}
+        protected int[] GenerateWorkingKey(bool encrypting, byte[] key)
+        {
+            ValidateKey();
+
+            int[] newKey = new int[32];
+            bool[] pc1m = new bool[56];
+            bool[] pcr = new bool[56];
+
+            for (int j = 0; j < 56; j++)
+            {
+                int l = pc1[j];
+
+                pc1m[j] = ((key[(uint)l >> 3] & bytebit[l & 07]) != 0);
+            }
+
+            for (int i = 0; i < 16; i++)
+            {
+                int l, m;
+
+                if (encrypting)
+                {
+                    m = i << 1;
+                }
+                else
+                {
+                    m = (15 - i) << 1;
+                }
+
+                var n = m + 1;
+                newKey[m] = newKey[n] = 0;
+
+                for (int j = 0; j < 28; j++)
+                {
+                    l = j + totrot[i];
+                    if (l < 28)
+                    {
+                        pcr[j] = pc1m[l];
+                    }
+                    else
+                    {
+                        pcr[j] = pc1m[l - 28];
+                    }
+                }
+
+                for (int j = 28; j < 56; j++)
+                {
+                    l = j + totrot[i];
+                    if (l < 56)
+                    {
+                        pcr[j] = pc1m[l];
+                    }
+                    else
+                    {
+                        pcr[j] = pc1m[l - 28];
+                    }
+                }
+
+                for (int j = 0; j < 24; j++)
+                {
+                    if (pcr[pc2[j]])
+                    {
+                        newKey[m] |= bigbyte[j];
+                    }
+
+                    if (pcr[pc2[j + 24]])
+                    {
+                        newKey[n] |= bigbyte[j];
+                    }
+                }
+            }
+
+            //
+            // store the processed key
+            //
+            for (int i = 0; i != 32; i += 2)
+            {
+                var i1 = newKey[i];
+                var i2 = newKey[i + 1];
+
+                newKey[i] = (int)((uint)((i1 & 0x00fc0000) << 6) |
+                                    (uint)((i1 & 0x00000fc0) << 10) |
+                                    ((uint)(i2 & 0x00fc0000) >> 10) |
+                                    ((uint)(i2 & 0x00000fc0) >> 6));
+
+                newKey[i + 1] = (int)((uint)((i1 & 0x0003f000) << 12) |
+                                      (uint)((i1 & 0x0000003f) << 16) |
+                                      ((uint)(i2 & 0x0003f000) >> 4) |
+                                       (uint)(i2 & 0x0000003f));
+            }
+
+            return newKey;
+        }
+
+        /// <summary>
+        /// Validates the key.
+        /// </summary>
+        protected virtual void ValidateKey()
+        {
+            var keySize = Key.Length * 8;
+
+            if (keySize != 64)
+                throw new ArgumentException(string.Format("KeySize '{0}' is not valid for this algorithm.", keySize));
+        }
+
+        /// <summary>
+        /// Performs DES function.
+        /// </summary>
+        /// <param name="wKey">The w key.</param>
+        /// <param name="input">The input.</param>
+        /// <param name="inOff">The in off.</param>
+        /// <param name="outBytes">The out bytes.</param>
+        /// <param name="outOff">The out off.</param>
+        protected static void DesFunc(int[] wKey, byte[] input, int inOff, byte[] outBytes, int outOff)
+        {
+            uint left = BigEndianToUInt32(input, inOff);
+            uint right = BigEndianToUInt32(input, inOff + 4);
+
+            var work = ((left >> 4) ^ right) & 0x0f0f0f0f;
+            right ^= work;
+            left ^= (work << 4);
+            work = ((left >> 16) ^ right) & 0x0000ffff;
+            right ^= work;
+            left ^= (work << 16);
+            work = ((right >> 2) ^ left) & 0x33333333;
+            left ^= work;
+            right ^= (work << 2);
+            work = ((right >> 8) ^ left) & 0x00ff00ff;
+            left ^= work;
+            right ^= (work << 8);
+            right = (right << 1) | (right >> 31);
+            work = (left ^ right) & 0xaaaaaaaa;
+            left ^= work;
+            right ^= work;
+            left = (left << 1) | (left >> 31);
+
+            for (int round = 0; round < 8; round++)
+            {
+                work = (right << 28) | (right >> 4);
+                work ^= (uint)wKey[round * 4 + 0];
+                var fval = SP7[work & 0x3f];
+                fval |= SP5[(work >> 8) & 0x3f];
+                fval |= SP3[(work >> 16) & 0x3f];
+                fval |= SP1[(work >> 24) & 0x3f];
+                work = right ^ (uint)wKey[round * 4 + 1];
+                fval |= SP8[work & 0x3f];
+                fval |= SP6[(work >> 8) & 0x3f];
+                fval |= SP4[(work >> 16) & 0x3f];
+                fval |= SP2[(work >> 24) & 0x3f];
+                left ^= fval;
+                work = (left << 28) | (left >> 4);
+                work ^= (uint)wKey[round * 4 + 2];
+                fval = SP7[work & 0x3f];
+                fval |= SP5[(work >> 8) & 0x3f];
+                fval |= SP3[(work >> 16) & 0x3f];
+                fval |= SP1[(work >> 24) & 0x3f];
+                work = left ^ (uint)wKey[round * 4 + 3];
+                fval |= SP8[work & 0x3f];
+                fval |= SP6[(work >> 8) & 0x3f];
+                fval |= SP4[(work >> 16) & 0x3f];
+                fval |= SP2[(work >> 24) & 0x3f];
+                right ^= fval;
+            }
+
+            right = (right << 31) | (right >> 1);
+            work = (left ^ right) & 0xaaaaaaaa;
+            left ^= work;
+            right ^= work;
+            left = (left << 31) | (left >> 1);
+            work = ((left >> 8) ^ right) & 0x00ff00ff;
+            right ^= work;
+            left ^= (work << 8);
+            work = ((left >> 2) ^ right) & 0x33333333;
+            right ^= work;
+            left ^= (work << 2);
+            work = ((right >> 16) ^ left) & 0x0000ffff;
+            left ^= work;
+            right ^= (work << 16);
+            work = ((right >> 4) ^ left) & 0x0f0f0f0f;
+            left ^= work;
+            right ^= (work << 4);
+
+            UInt32ToBigEndian(right, outBytes, outOff);
+            UInt32ToBigEndian(left, outBytes, outOff + 4);
+        }
+    }
 }

+ 1 - 1
src/Renci.SshNet/Security/Cryptography/Ciphers/RsaCipher.cs

@@ -57,7 +57,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
         /// <returns>
         /// Decrypted data.
         /// </returns>
-        /// <exception cref="System.NotSupportedException">Only block type 01 or 02 are supported.</exception>
+        /// <exception cref="NotSupportedException">Only block type 01 or 02 are supported.</exception>
         /// <exception cref="NotSupportedException">Thrown when decrypted block type is not supported.</exception>
         public override byte[] Decrypt(byte[] data)
         {

+ 1 - 1
src/Renci.SshNet/Security/Cryptography/Ciphers/SerpentCipher.cs

@@ -19,7 +19,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
         /// <param name="key">The key.</param>
         /// <param name="mode">The mode.</param>
         /// <param name="padding">The padding.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">Keysize is not valid for this algorithm.</exception>
         public SerpentCipher(byte[] key, CipherMode mode, CipherPadding padding)
             : base(key, 16, mode, padding)

+ 1 - 1
src/Renci.SshNet/Security/Cryptography/Ciphers/TripleDesCipher.cs

@@ -20,7 +20,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
         /// <param name="key">The key.</param>
         /// <param name="mode">The mode.</param>
         /// <param name="padding">The padding.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
         public TripleDesCipher(byte[] key, CipherMode mode, CipherPadding padding)
             : base(key, mode, padding)
         {

+ 1 - 1
src/Renci.SshNet/Security/Cryptography/Ciphers/TwofishCipher.cs

@@ -13,7 +13,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
         /// <param name="key">The key.</param>
         /// <param name="mode">The mode.</param>
         /// <param name="padding">The padding.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
         /// <exception cref="ArgumentException">Keysize is not valid for this algorithm.</exception>
         public TwofishCipher(byte[] key, CipherMode mode, CipherPadding padding)
             : base(key, 16, mode, padding)

+ 3 - 3
src/Renci.SshNet/Security/Cryptography/DsaDigitalSignature.cs

@@ -18,7 +18,7 @@ namespace Renci.SshNet.Security.Cryptography
         /// Initializes a new instance of the <see cref="DsaDigitalSignature" /> class.
         /// </summary>
         /// <param name="key">The DSA key.</param>
-        /// <exception cref="System.ArgumentNullException">key</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
         public DsaDigitalSignature(DsaKey key)
         {
             if (key == null)
@@ -35,9 +35,9 @@ namespace Renci.SshNet.Security.Cryptography
         /// <param name="input">The input.</param>
         /// <param name="signature">The signature.</param>
         /// <returns>
-        ///   <c>True</c> if signature was successfully verified; otherwise <c>false</c>.
+        /// <c>true</c> if signature was successfully verified; otherwise <c>false</c>.
         /// </returns>
-        /// <exception cref="System.InvalidOperationException">Invalid signature.</exception>
+        /// <exception cref="InvalidOperationException">Invalid signature.</exception>
         public override bool Verify(byte[] input, byte[] signature)
         {
             var hashInput = _hash.ComputeHash(input);

+ 1 - 1
src/Renci.SshNet/Security/Cryptography/StreamCipher.cs

@@ -11,7 +11,7 @@ namespace Renci.SshNet.Security.Cryptography
         /// Initializes a new instance of the <see cref="StreamCipher"/> class.
         /// </summary>
         /// <param name="key">The key.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
         protected StreamCipher(byte[] key)
             : base(key)
         {

+ 1 - 1
src/Renci.SshNet/Security/Cryptography/SymmetricCipher.cs

@@ -16,7 +16,7 @@ namespace Renci.SshNet.Security.Cryptography
         /// Initializes a new instance of the <see cref="SymmetricCipher"/> class.
         /// </summary>
         /// <param name="key">The key.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="key"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
         protected SymmetricCipher(byte[] key)
         {
             if (key == null)

+ 1 - 1
src/Renci.SshNet/Sftp/SftpDownloadAsyncResult.cs

@@ -29,7 +29,7 @@ namespace Renci.SshNet.Sftp
         /// </summary>
         /// <param name="asyncCallback">The async callback.</param>
         /// <param name="state">The state.</param>
-        public SftpDownloadAsyncResult(AsyncCallback asyncCallback, Object state)
+        public SftpDownloadAsyncResult(AsyncCallback asyncCallback, object state)
             : base(asyncCallback, state)
         {
         }

+ 2 - 2
src/Renci.SshNet/Sftp/SftpFile.cs

@@ -22,7 +22,7 @@ namespace Renci.SshNet.Sftp
         /// <param name="sftpSession">The SFTP session.</param>
         /// <param name="fullName">Full path of the directory or file.</param>
         /// <param name="attributes">Attributes of the directory or file.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="sftpSession"/> or <paramref name="fullName"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="sftpSession"/> or <paramref name="fullName"/> is <c>null</c>.</exception>
         internal SftpFile(ISftpSession sftpSession, string fullName, SftpFileAttributes attributes)
         {
             if (sftpSession == null)
@@ -465,7 +465,7 @@ namespace Renci.SshNet.Sftp
         /// Moves a specified file to a new location on remote machine, providing the option to specify a new file name.
         /// </summary>
         /// <param name="destFileName">The path to move the file to, which can specify a different file name.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="destFileName"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="destFileName"/> is <c>null</c>.</exception>
         public void MoveTo(string destFileName)
         {
             if (destFileName == null)

+ 7 - 7
src/Renci.SshNet/Sftp/SftpFileStream.cs

@@ -323,8 +323,8 @@ namespace Renci.SshNet.Sftp
         /// <returns>
         /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
         /// </returns>
-        /// <exception cref="T:System.ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is larger than the buffer length. </exception>
-        /// <exception cref="T:System.ArgumentNullException"><paramref name="buffer"/> is null. </exception>
+        /// <exception cref="T:System.ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is larger than the buffer length.</exception>
+        /// <exception cref="T:System.ArgumentNullException"><paramref name="buffer"/> is <c>null</c>. </exception>
         /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="offset"/> or <paramref name="count"/> is negative.</exception>
         /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
         /// <exception cref="T:System.NotSupportedException">The stream does not support reading. </exception>
@@ -405,11 +405,11 @@ namespace Renci.SshNet.Sftp
         /// Reads a byte from the stream and advances the position within the stream by one byte, or returns -1 if at the end of the stream.
         /// </summary>
         /// <returns>
-        /// The unsigned byte cast to an Int32, or -1 if at the end of the stream.
+        /// The unsigned byte cast to an <see cref="int"/>, or -1 if at the end of the stream.
         /// </returns>
-        /// <exception cref="T:System.NotSupportedException">The stream does not support reading. </exception>
-        /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
-        /// <exception cref="System.IO.IOException">Read operation failed.</exception>
+        /// <exception cref="NotSupportedException">The stream does not support reading. </exception>
+        /// <exception cref="ObjectDisposedException">Methods were called after the stream was closed. </exception>
+        /// <exception cref="IOException">Read operation failed.</exception>
         public override int ReadByte()
         {
             // Lock down the file stream while we do this.
@@ -602,7 +602,7 @@ namespace Renci.SshNet.Sftp
         /// <param name="offset">The zero-based byte offset in <paramref name="buffer"/> at which to begin copying bytes to the current stream.</param>
         /// <param name="count">The number of bytes to be written to the current stream.</param>
         /// <exception cref="T:System.ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is greater than the buffer length.</exception>
-        /// <exception cref="T:System.ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="T:System.ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
         /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="offset"/> or <paramref name="count"/> is negative.</exception>
         /// <exception cref="T:System.IO.IOException">An I/O error occurs.</exception>
         /// <exception cref="T:System.NotSupportedException">The stream does not support writing.</exception>

+ 1 - 1
src/Renci.SshNet/Sftp/SftpSession.cs

@@ -980,7 +980,7 @@ namespace Renci.SshNet.Sftp
         /// <param name="handle">The file handle.</param>
         /// <param name="nullOnError">if set to <c>true</c> [null on error].</param>
         /// <returns></returns>
-        /// <exception cref="System.NotSupportedException"></exception>
+        /// <exception cref="NotSupportedException"></exception>
         internal SftpFileSytemInformation RequestFStatVfs(byte[] handle, bool nullOnError = false)
         {
             if (ProtocolVersion < 3)

文件差异内容过多而无法显示
+ 298 - 100
src/Renci.SshNet/SftpClient.cs


+ 9 - 6
src/Renci.SshNet/ShellStream.cs

@@ -162,7 +162,7 @@ namespace Renci.SshNet
         /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
         /// </returns>
         /// <exception cref="T:System.ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is larger than the buffer length. </exception>
-        /// <exception cref="T:System.ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="T:System.ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
         /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="offset"/> or <paramref name="count"/> is negative.</exception>
         /// <exception cref="T:System.IO.IOException">An I/O error occurs.</exception>   
         /// <exception cref="T:System.NotSupportedException">The stream does not support reading.</exception>   
@@ -217,7 +217,7 @@ namespace Renci.SshNet
         /// <param name="offset">The zero-based byte offset in <paramref name="buffer"/> at which to begin copying bytes to the current stream.</param>
         /// <param name="count">The number of bytes to be written to the current stream.</param>
         /// <exception cref="T:System.ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is greater than the buffer length.</exception>
-        /// <exception cref="T:System.ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="T:System.ArgumentNullException"><paramref name="buffer"/> is <c>null</c>.</exception>
         /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="offset"/> or <paramref name="count"/> is negative.</exception>
         /// <exception cref="T:System.IO.IOException">An I/O error occurs.</exception>
         /// <exception cref="T:System.NotSupportedException">The stream does not support writing.</exception>
@@ -443,7 +443,7 @@ namespace Renci.SshNet
         /// Ends the execute.
         /// </summary>
         /// <param name="asyncResult">The async result.</param>
-        /// <exception cref="System.ArgumentException">Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.</exception>
+        /// <exception cref="ArgumentException">Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.</exception>
         public string EndExpect(IAsyncResult asyncResult)
         {
             var ar = asyncResult as ExpectAsyncResult;
@@ -473,7 +473,7 @@ namespace Renci.SshNet
         /// <param name="text">The text to expect.</param>
         /// <param name="timeout">Time to wait for input.</param>
         /// <returns>
-        /// Text available in the shell that ends with expected text, if the specified time elapsed returns null.
+        /// The text available in the shell that ends with expected text, or <c>null</c> if the specified time has elapsed.
         /// </returns>
         public string Expect(string text, TimeSpan timeout)
         {
@@ -484,7 +484,9 @@ namespace Renci.SshNet
         /// Expects the expression specified by regular expression.
         /// </summary>
         /// <param name="regex">The regular expression to expect.</param>
-        /// <returns>Text available in the shell that contains all the text that ends with expected expression.</returns>
+        /// <returns>
+        /// The text available in the shell that contains all the text that ends with expected expression.
+        /// </returns>
         public string Expect(Regex regex)
         {
             return Expect(regex, TimeSpan.Zero);
@@ -496,7 +498,8 @@ namespace Renci.SshNet
         /// <param name="regex">The regular expression to expect.</param>
         /// <param name="timeout">Time to wait for input.</param>
         /// <returns>
-        /// Text available in the shell that contains all the text that ends with expected expression, if the specified time elapsed returns null.
+        /// The text available in the shell that contains all the text that ends with expected expression,
+        /// or <c>null</c> if the specified time has elapsed.
         /// </returns>
         public string Expect(Regex regex, TimeSpan timeout)
         {

+ 19 - 18
src/Renci.SshNet/SshClient.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.Text;
 using System.Diagnostics.CodeAnalysis;
+using System.Net;
 using Renci.SshNet.Common;
 
 namespace Renci.SshNet
@@ -50,7 +51,7 @@ namespace Renci.SshNet
         ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\PrivateKeyConnectionInfoTest.cs" region="Example PrivateKeyConnectionInfo PrivateKeyFile" language="C#" title="Connect using PrivateKeyConnectionInfo" />
         ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\SshClientTest.cs" region="Example SshClient Connect Timeout" language="C#" title="Specify connection timeout when connecting" />
         /// </example>
-        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <c>null</c>.</exception>
         public SshClient(ConnectionInfo connectionInfo)
             : this(connectionInfo, false)
         {
@@ -63,9 +64,9 @@ namespace Renci.SshNet
         /// <param name="port">Connection port.</param>
         /// <param name="username">Authentication username.</param>
         /// <param name="password">Authentication password.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="password"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="F:System.Net.IPEndPoint.MinPort"/> and <see cref="System.Net.IPEndPoint.MaxPort"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="password"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
         [SuppressMessage("Microsoft.Reliability", "C2A000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
         public SshClient(string host, int port, string username, string password)
             : this(new PasswordConnectionInfo(host, port, username, password), true)
@@ -81,8 +82,8 @@ namespace Renci.SshNet
         /// <example>
         ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\SshClientTest.cs" region="Example SshClient(host, username) Connect" language="C#" title="Connect using username and password" />
         /// </example>
-        /// <exception cref="ArgumentNullException"><paramref name="password"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is null or contains whitespace characters.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="password"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, or <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
         public SshClient(string host, string username, string password)
             : this(host, ConnectionInfo.DefaultPort, username, password)
         {
@@ -99,9 +100,9 @@ namespace Renci.SshNet
         ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\SshClientTest.cs" region="Example SshClient(host, username) Connect PrivateKeyFile" language="C#" title="Connect using username and private key" />
         ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\SshClientTest.cs" region="Example SshClient(host, username) Connect PrivateKeyFile PassPhrase" language="C#" title="Connect using username and private key and pass phrase" />
         /// </example>
-        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is null or contains whitespace characters.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="F:System.Net.IPEndPoint.MinPort"/> and <see cref="System.Net.IPEndPoint.MaxPort"/>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
         [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
         public SshClient(string host, int port, string username, params PrivateKeyFile[] keyFiles)
             : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true)
@@ -118,8 +119,8 @@ namespace Renci.SshNet
         ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\SshClientTest.cs" region="Example SshClient(host, username) Connect PrivateKeyFile" language="C#" title="Connect using private key" />
         ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\SshClientTest.cs" region="Example SshClient(host, username) Connect PrivateKeyFile PassPhrase" language="C#" title="Connect using private key and pass phrase" />
         /// </example>
-        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is null.</exception>
-        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is null or contains whitespace characters.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
         public SshClient(string host, string username, params PrivateKeyFile[] keyFiles)
             : this(host, ConnectionInfo.DefaultPort, username, keyFiles)
         {
@@ -130,7 +131,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="connectionInfo">The connection info.</param>
         /// <param name="ownsConnectionInfo">Specified whether this instance owns the connection info.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <c>null</c>.</exception>
         /// <remarks>
         /// If <paramref name="ownsConnectionInfo"/> is <c>true</c>, then the
         /// connection info will be disposed when this instance is disposed.
@@ -146,8 +147,8 @@ namespace Renci.SshNet
         /// <param name="connectionInfo">The connection info.</param>
         /// <param name="ownsConnectionInfo">Specified whether this instance owns the connection info.</param>
         /// <param name="serviceFactory">The factory to use for creating new services.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is null.</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="serviceFactory"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <c>null</c>.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="serviceFactory"/> is <c>null</c>.</exception>
         /// <remarks>
         /// If <paramref name="ownsConnectionInfo"/> is <c>true</c>, then the
         /// connection info will be disposed when this instance is disposed.
@@ -182,7 +183,7 @@ namespace Renci.SshNet
         ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\ForwardedPortLocalTest.cs" region="Example SshClient AddForwardedPort Start Stop ForwardedPortLocal" language="C#" title="Local port forwarding" />
         /// </example>
         /// <exception cref="InvalidOperationException">Forwarded port is already added to a different client.</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="port"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="port"/> is <c>null</c>.</exception>
         /// <exception cref="SshConnectionException">Client is not connected.</exception>
         public void AddForwardedPort(ForwardedPort port)
         {
@@ -198,7 +199,7 @@ namespace Renci.SshNet
         /// Stops and removes the forwarded port from the list.
         /// </summary>
         /// <param name="port">Forwarded port.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="port"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="port"/> is <c>null</c>.</exception>
         public void RemoveForwardedPort(ForwardedPort port)
         {
             if (port == null)
@@ -243,7 +244,7 @@ namespace Renci.SshNet
         /// <returns><see cref="SshCommand"/> object which uses specified encoding.</returns>
         /// <remarks>This method will change current default encoding.</remarks>
         /// <exception cref="SshConnectionException">Client is not connected.</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="commandText"/> or <paramref name="encoding"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="commandText"/> or <paramref name="encoding"/> is <c>null</c>.</exception>
         public SshCommand CreateCommand(string commandText, Encoding encoding)
         {
             EnsureSessionIsOpen();
@@ -266,7 +267,7 @@ namespace Renci.SshNet
         /// <exception cref="T:Renci.SshNet.Common.SshException">Invalid Operation - An existing channel was used to execute this command.</exception>
         /// <exception cref="InvalidOperationException">Asynchronous operation is already in progress.</exception>
         /// <exception cref="SshConnectionException">Client is not connected.</exception>
-        /// <exception cref="ArgumentNullException"><paramref name="commandText"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="commandText"/> is <c>null</c>.</exception>
         public SshCommand RunCommand(string commandText)
         {
             var cmd = CreateCommand(commandText);

+ 14 - 14
src/Renci.SshNet/SshCommand.cs

@@ -130,7 +130,7 @@ namespace Renci.SshNet
         /// <param name="session">The session.</param>
         /// <param name="commandText">The command text.</param>
         /// <param name="encoding">The encoding to use for the results.</param>
-        /// <exception cref="ArgumentNullException">Either <paramref name="session"/>, <paramref name="commandText"/> is null.</exception>
+        /// <exception cref="ArgumentNullException">Either <paramref name="session"/>, <paramref name="commandText"/> is <c>null</c>.</exception>
         internal SshCommand(ISession session, string commandText, Encoding encoding)
         {
             if (session == null)
@@ -159,11 +159,11 @@ namespace Renci.SshNet
         /// <example>
         ///     <code source="..\..\src\Renci.SshNet.Tests\Classes\SshCommandTest.cs" region="Example SshCommand CreateCommand BeginExecute IsCompleted EndExecute" language="C#" title="Asynchronous Command Execution" />
         /// </example>
-        /// <exception cref="System.InvalidOperationException">Asynchronous operation is already in progress.</exception>
+        /// <exception cref="InvalidOperationException">Asynchronous operation is already in progress.</exception>
         /// <exception cref="SshException">Invalid operation.</exception>
-        /// <exception cref="System.ArgumentException">CommandText property is empty.</exception>
-        /// <exception cref="Renci.SshNet.Common.SshConnectionException">Client is not connected.</exception>
-        /// <exception cref="Renci.SshNet.Common.SshOperationTimeoutException">Operation has timed out.</exception>
+        /// <exception cref="ArgumentException">CommandText property is empty.</exception>
+        /// <exception cref="SshConnectionException">Client is not connected.</exception>
+        /// <exception cref="SshOperationTimeoutException">Operation has timed out.</exception>
         /// <exception cref="InvalidOperationException">Asynchronous operation is already in progress.</exception>
         /// <exception cref="ArgumentException">CommandText property is empty.</exception>
         public IAsyncResult BeginExecute()
@@ -178,11 +178,11 @@ namespace Renci.SshNet
         /// <returns>
         /// An <see cref="System.IAsyncResult" /> that represents the asynchronous command execution, which could still be pending.
         /// </returns>
-        /// <exception cref="System.InvalidOperationException">Asynchronous operation is already in progress.</exception>
+        /// <exception cref="InvalidOperationException">Asynchronous operation is already in progress.</exception>
         /// <exception cref="SshException">Invalid operation.</exception>
-        /// <exception cref="System.ArgumentException">CommandText property is empty.</exception>
-        /// <exception cref="Renci.SshNet.Common.SshConnectionException">Client is not connected.</exception>
-        /// <exception cref="Renci.SshNet.Common.SshOperationTimeoutException">Operation has timed out.</exception>
+        /// <exception cref="ArgumentException">CommandText property is empty.</exception>
+        /// <exception cref="SshConnectionException">Client is not connected.</exception>
+        /// <exception cref="SshOperationTimeoutException">Operation has timed out.</exception>
         /// <exception cref="InvalidOperationException">Asynchronous operation is already in progress.</exception>
         /// <exception cref="ArgumentException">CommandText property is empty.</exception>
         public IAsyncResult BeginExecute(AsyncCallback callback)
@@ -196,13 +196,13 @@ namespace Renci.SshNet
         /// <param name="callback">An optional asynchronous callback, to be called when the command execution is complete.</param>
         /// <param name="state">A user-provided object that distinguishes this particular asynchronous read request from other requests.</param>
         /// <returns>
-        /// An <see cref="System.IAsyncResult" /> that represents the asynchronous command execution, which could still be pending.
+        /// An <see cref="IAsyncResult" /> that represents the asynchronous command execution, which could still be pending.
         /// </returns>
-        /// <exception cref="System.InvalidOperationException">Asynchronous operation is already in progress.</exception>
+        /// <exception cref="InvalidOperationException">Asynchronous operation is already in progress.</exception>
         /// <exception cref="SshException">Invalid operation.</exception>
-        /// <exception cref="System.ArgumentException">CommandText property is empty.</exception>
-        /// <exception cref="Renci.SshNet.Common.SshConnectionException">Client is not connected.</exception>
-        /// <exception cref="Renci.SshNet.Common.SshOperationTimeoutException">Operation has timed out.</exception>
+        /// <exception cref="ArgumentException">CommandText property is empty.</exception>
+        /// <exception cref="SshConnectionException">Client is not connected.</exception>
+        /// <exception cref="SshOperationTimeoutException">Operation has timed out.</exception>
         /// <exception cref="InvalidOperationException">Asynchronous operation is already in progress.</exception>
         /// <exception cref="ArgumentException">CommandText property is empty.</exception>
         public IAsyncResult BeginExecute(AsyncCallback callback, object state)

+ 1 - 1
src/Renci.SshNet/SubsystemSession.cs

@@ -74,7 +74,7 @@ namespace Renci.SshNet
         /// <param name="subsystemName">Name of the subsystem.</param>
         /// <param name="operationTimeout">The operation timeout.</param>
         /// <param name="encoding">The character encoding to use.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="session" /> or <paramref name="subsystemName" /> or <paramref name="encoding"/>is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="session" /> or <paramref name="subsystemName" /> or <paramref name="encoding"/> is <c>null</c>.</exception>
         protected SubsystemSession(ISession session, string subsystemName, TimeSpan operationTimeout, Encoding encoding)
         {
             if (session == null)

部分文件因为文件数量过多而无法显示